[
  {
    "path": ".babelrc",
    "content": "{\n    \"presets\": [\n        [\"es2015\"]\n    ]\n}"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n    \"env\": {\n        \"browser\": true,\n        \"commonjs\": true,\n        \"es6\": true,\n        \"node\": true\n    },\n    \"parserOptions\": {\n        \"ecmaFeatures\": {\n            \"jsx\": false\n        },\n        \"sourceType\": \"module\"\n    },\n    \"rules\": {\n        \"no-const-assign\": \"warn\",\n        \"no-this-before-super\": \"warn\",\n        \"no-undef\": \"warn\",\n        \"no-unreachable\": \"warn\",\n        \"no-unused-vars\": \"warn\",\n        \"constructor-super\": \"warn\",\n        \"valid-typeof\": \"warn\"\n    }\n}"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules/\ndist/app/\ndist/*/report.html\nnpm-debug.log.*\n*.log\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "// Place your settings in this file to overwrite default and user settings.\n{\n    \"eslint.enable\": true\n}"
  },
  {
    "path": "build/app.js",
    "content": "// Import Vue and Vue plugins\nimport Vue from \"vue\";\nimport VueRouter from \"vue-router\";\nimport Vuetiful from \"../src/main\";\n\nimport views from \"../src/views/views\";\n\nfunction registerPlugins() {\n    Vue.use(Vuetiful);\n    Vue.use(VueRouter);\n}\n\nfunction buildRoutes() {\n    let routes = [];\n\n    for (let directoryName in views) {\n        let directory = views[directoryName];\n\n        for (let viewName in directory) {\n            let view = directory[viewName];\n\n            let path = `/${directoryName}/${viewName}`;\n\n            if (view.params) {\n                path += \"/:\" + view.params.join(\"/:\");\n            }\n\n            routes.push({\n                path: path,\n                component: view.component\n            });\n        }\n    }\n\n    return routes;\n}\n\nfunction buildRootInstance() {\n    let routes = buildRoutes();\n\n    let menuItems = [\n        {\n            name: \"Buttons\",\n            route: \"/components/buttons\"\n        },\n        {\n            name: \"Datatables\",\n            route: \"/components/datatables\"\n        },\n        {\n            name: \"Modals\",\n            route: \"/components/modals\"\n        },\n        {\n            name: \"Paginators\",\n            route: \"/components/paginators\"\n        },\n        {\n            name: \"Panels\",\n            route: \"/components/panels\"\n        },\n        {\n            name: \"Tab Controls\",\n            route: \"/components/tabcontrols\"\n        },\n        {\n            name: \"Toggles\",\n            route: \"/components/toggles\"\n        },\n        {\n            name: \"Typography\",\n            route: \"/components/typography\"\n        }\n    ];\n\n    new Vue({\n        el: '#app',\n        \n        data() {\n            return {\n                menuItems: menuItems\n            }\n        },\n\n        router: new VueRouter({\n            routes: routes\n        })\n    });\n}\n\nfunction bootstrap() {\n    registerPlugins();\n    buildRootInstance();\n}\n\nbootstrap();\n\nmodule.exports = Vuetiful;"
  },
  {
    "path": "build/components.js",
    "content": "import Vuetiful from \"../src/main\";\n\nif (typeof window !== 'undefined' && window.Vue) {\n    window.Vue.use(Vuetiful);\n}\n\nmodule.exports = Vuetiful;"
  },
  {
    "path": "dist/components/app.style.css",
    "content": "html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}[layout]{display:-ms-flexbox;display:-webkit-box;display:flex}[layout*=column],[layout*=row]{width:100%;max-width:100%}[layout^=row]{-ms-flex-direction:row;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row}[layout^=column]{-ms-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}[layout*=row][layout*=reverse]{-ms-flex-direction:row-reverse;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;flex-direction:row-reverse}[layout*=column][layout*=reverse]{-ms-flex-direction:column-reverse;-webkit-box-orient:vertical;-webkit-box-direction:reverse;flex-direction:column-reverse}[layout*=columns],[layout*=rows]{-ms-flex-wrap:wrap;flex-wrap:wrap}[layout=none]{-ms-flex:none;-webkit-box-flex:0;flex:none}[layout*=column][layout*=top-],[layout*=row][layout*=-left]{-ms-flex-pack:start;-webkit-box-pack:start;justify-content:flex-start}[layout*=column][layout*=center-],[layout*=row][layout*=-center],[layout~=centered]{-ms-flex-pack:center;-webkit-box-pack:center;justify-content:center}[layout*=column][layout*=bottom-],[layout*=row][layout*=-right]{-ms-flex-pack:end;-webkit-box-pack:end;justify-content:flex-end}[layout*=column][layout*=spread-],[layout*=row][layout*=-spread]{-ms-flex-pack:distribute;justify-content:space-around}[layout*=column][layout*=justify-],[layout*=row][layout*=-justify]{-ms-flex-pack:justify;-webkit-box-pack:justify;justify-content:space-between}[layout*=column][layout*=-left],[layout*=row][layout*=top-]{-ms-flex-align:start;-ms-grid-row-align:flex-start;-webkit-box-align:start;align-items:flex-start}[layout*=column][layout*=-center],[layout*=row][layout*=center-],[layout~=centered]{-ms-flex-align:center;-ms-grid-row-align:center;-webkit-box-align:center;align-items:center}[layout*=column][layout*=-right],[layout*=row][layout*=bottom-]{-ms-flex-align:end;-ms-grid-row-align:flex-end;-webkit-box-align:end;align-items:flex-end}[layout*=column][layout*=-stretch],[layout*=row][layout*=stretch-]{-ms-flex-align:stretch;-ms-grid-row-align:stretch;-webkit-box-align:stretch;align-items:stretch}[layout*=columns][layout*=-left],[layout*=rows][layout*=top-]{-ms-flex-line-pack:start;align-content:flex-start}[layout*=columns][layout*=-right],[layout*=rows][layout*=bottom-]{-ms-flex-line-pack:end;align-content:flex-end}[layout*=columns][layout*=-center],[layout*=rows][layout*=center-]{-ms-flex-line-pack:center;align-content:center}[layout*=columns][layout*=-justify],[layout*=rows][layout*=justify-]{-ms-flex-line-pack:justify;align-content:space-between}[layout*=columns][layout*=-spread],[layout*=rows][layout*=spread-]{-ms-flex-line-pack:distribute;align-content:space-around}[layout*=columns][layout*=-stretch],[layout*=rows][layout*=stretch-]{-ms-flex-line-pack:stretch;align-content:stretch}@media (-ms-high-contrast:none),screen and (-ms-high-contrast:active){[layout*=column]:not([layout*=row])>*{max-width:auto}[layout*=column][self*=top]{height:auto!important}[self~=size-]>*{height:auto}}[layout*=column]:not([layout*=row]) [self*=left],[layout*=row]:not([layout*=column]) [self*=top]{-ms-flex-item-align:start;align-self:flex-start}[self~=center]{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}[layout*=column]:not([layout*=row]) [self*=right],[layout*=row]:not([layout*=column]) [self*=bottom]{-ms-flex-item-align:end;align-self:flex-end}[self*=stretch]{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}[layout][self*=center]{margin-left:auto;margin-right:auto}[layout][self*=right]{margin-right:0}[layout][self*=left]{margin-left:0}[layout*=column] [self*=bottom]{margin-top:auto}[layout*=column] [self*=top]{margin-bottom:auto}[layout*=row] [self*=left]{margin-right:auto}[layout*=row] [self*=right]{margin-left:auto}[self~=size-1of5]{width:20%}[self~=size-1of4]{width:25%}[self~=size-1of3]{width:33.33333%}[self~=size-2of5]{width:40%}[self~=size-1of2]{width:50%}[self~=size-3of5]{width:60%}[self~=size-2of3]{width:66.6666%}[self~=size-3of4]{width:75%}[self~=size-4of5]{width:80%}[self~=size-1of1]{width:100%}[layout*=column][layout*=stretch-]>:not([self*=size-]),[layout*=row][layout*=-stretch]>:not([self*=size-]),[self~=size-x1]{-ms-flex:1 0 0%!important;-webkit-box-flex:1!important;flex:1 0 0%!important}[self~=size-x2]{-ms-flex:2 0 0%!important;-webkit-box-flex:2!important;flex:2 0 0%!important}[self~=size-x3]{-ms-flex:3 0 0%!important;-webkit-box-flex:3!important;flex:3 0 0%!important}[self~=size-x4]{-ms-flex:4 0 0%!important;-webkit-box-flex:4!important;flex:4 0 0%!important}[self~=size-x5]{-ms-flex:5 0 0%!important;-webkit-box-flex:5!important;flex:5 0 0%!important}[self~=size-x6]{-ms-flex:6 0 0%!important;-webkit-box-flex:6!important;flex:6 0 0%!important}[self~=size-x7]{-ms-flex:7 0 0%!important;-webkit-box-flex:7!important;flex:7 0 0%!important}[self~=size-x8]{-ms-flex:8 0 0%!important;-webkit-box-flex:8!important;flex:8 0 0%!important}[self~=size-x9]{-ms-flex:9 0 0%!important;-webkit-box-flex:9!important;flex:9 0 0%!important}[self*=size-auto]{-ms-flex:1 1 auto;-webkit-box-flex:1;flex:1 1 auto}[self*=size-x0]{-ms-flex:0 0 auto;-webkit-box-flex:0;flex:0 0 auto}[self~=size-xxlarge]{max-width:1440px;width:100%}[self~=size-xlarge]{max-width:1200px;width:100%}[self~=size-large]{max-width:960px;width:100%}[self~=size-larger]{max-width:840px;width:100%}[self~=size-medium]{max-width:720px;width:100%}[self~=size-smaller]{max-width:600px;width:100%}[self~=size-small]{max-width:480px;width:100%}[self~=size-xsmall]{max-width:360px;width:100%}[self~=size-xxsmall]{max-width:240px;width:100%}[self*=size-x]:not([self*=small]):not([self*=large]){-ms-flex-negative:1;flex-shrink:1}[self~=first]{-ms-flex-order:-1;-webkit-box-ordinal-group:0;order:-1}[self~=order-1]{-ms-flex-order:1;-webkit-box-ordinal-group:2;order:1}[self~=order-2]{-ms-flex-order:2;-webkit-box-ordinal-group:3;order:2}[self~=order-3]{-ms-flex-order:3;-webkit-box-ordinal-group:4;order:3}[self~=last]{-ms-flex-order:999;-webkit-box-ordinal-group:1000;order:999}[layout*=column]:not([layout*=row])>*{-ms-flex-negative:0;flex-shrink:0;-ms-flex-preferred-size:auto;flex-basis:auto}@media screen and (max-width:64em){[layout*=lg-row]{-ms-flex-direction:row;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row}[layout*=lg-column]{-ms-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}[layout*=lg-columns],[layout*=lg-rows]{-ms-flex-wrap:wrap;flex-wrap:wrap}}@media screen and (max-width:52em){[layout*=md-row]{-ms-flex-direction:row;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row}[layout*=md-column]{-ms-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}[layout*=md-columns],[layout*=md-rows]{-ms-flex-wrap:wrap;flex-wrap:wrap}}@media screen and (max-width:40em){[layout*=sm-row]{-ms-flex-direction:row;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row}[layout*=sm-column]{-ms-flex-direction:column;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}[layout*=sm-columns],[layout*=sm-rows]{-ms-flex-wrap:wrap;flex-wrap:wrap}}@media screen and (max-width:64em){[self*=lg-full]{-ms-flex:1 1 100%!important;-webkit-box-flex:1!important;flex:1 1 100%!important;width:100%;max-width:100%}[self*=lg-half]{-ms-flex:1 1 50%!important;-webkit-box-flex:1!important;flex:1 1 50%!important;width:50%;max-width:50%}[self~=lg-first]{-ms-flex-order:-1;-webkit-box-ordinal-group:0;order:-1}[self~=lg-last]{-ms-flex-order:999;-webkit-box-ordinal-group:1000;order:999}[self~=lg-hide]{display:none}[self~=lg-show]{display:inherit}}@media screen and (max-width:52em){[self*=md-full]{-ms-flex:1 1 100%!important;-webkit-box-flex:1!important;flex:1 1 100%!important;width:100%;max-width:100%}[self*=md-half]{-ms-flex:1 1 50%!important;-webkit-box-flex:1!important;flex:1 1 50%!important;width:50%;max-width:50%}[self~=md-first]{-ms-flex-order:-1;-webkit-box-ordinal-group:0;order:-1}[self~=md-last]{-ms-flex-order:999;-webkit-box-ordinal-group:1000;order:999}[self~=md-hide]{display:none}[self~=md-show]{display:inherit}}@media screen and (max-width:40em){[self*=sm-full]{-ms-flex:1 1 100%!important;-webkit-box-flex:1!important;flex:1 1 100%!important;width:100%;max-width:100%}[self*=sm-half]{-ms-flex:1 1 50%!important;-webkit-box-flex:1!important;flex:1 1 50%!important;width:50%;max-width:50%}[self~=sm-first]{-ms-flex-order:-1;-webkit-box-ordinal-group:0;order:-1}[self~=sm-last]{-ms-flex-order:999;-webkit-box-ordinal-group:1000;order:999}[self~=sm-hide]{display:none}[self~=sm-show]{display:inherit}}body,html{width:100%;height:100%;margin:0;padding:0}html{font-size:16px;box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{font-family:Open Sans,sans-serif;font-weight:400;line-height:1.5em;color:#32394f;background-color:#fff}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}h1,h2,h3,h4,h5,h6{margin-top:1em;margin-bottom:.25em;font-weight:600;line-height:1.5em;color:#32394f}h1{font-size:3.15733em}h2{font-size:2.36859em}h3{font-size:1.77689em}h4{font-size:1.333em}h5{font-size:1em}h6{font-size:.75019em}p{margin:.75em 0}small{font-size:.75019em}strong{font-weight:600}em{font-style:italic}a{color:#2196f3;text-decoration:none}a:hover{color:#0c7cd5}a.escape-link,a.escape-link:hover{color:inherit}label{font-size:.75019em}blockquote,label{display:block;font-weight:600}blockquote{margin:1em 0;padding:0 1em;color:#888;border-left:4px solid #2196f3}code{display:block;margin:1em 0;padding:1em;font-family:monospace;white-space:pre;background-color:#fafafa;border:1px solid #dde;border-radius:2px}.container{width:100%;max-width:1170px;margin:0 auto}.grid-row{margin-left:-.5rem;margin-right:-.5rem}.grid-row+.grid-row{margin-top:1rem}.grid-cell{padding-left:.5rem;padding-right:.5rem}.button{display:inline-block;margin:0;padding:.75rem 1.5rem;font-weight:600;line-height:inherit;text-align:center;color:#fff;background-color:#2196f3;border:none;border-radius:2px;outline:none;cursor:pointer}.button:active,.button:hover{color:#fff;background-color:#0c7cd5}.button-blue{background-color:#2196f3}.button-blue:active,.button-blue:hover{color:#fff;background-color:#0c7cd5}.button-green{background-color:#00b378}.button-green:active,.button-green:hover{color:#fff;background-color:#008056}.button-red{background-color:#f44336}.button-red:active,.button-red:hover{color:#fff;background-color:#ea1c0d}.button-#ff0{background-color:#ffc107}.button-#ff0:active,.button-#ff0:hover{color:#fff;background-color:#d39e00}.button-orange{background-color:#ff9800}.button-orange:active,.button-orange:hover{color:#fff;background-color:#cc7a00}.button-purple{background-color:#673ab7}.button-purple:active,.button-purple:hover{color:#fff;background-color:#512e90}input[type=date],input[type=datetime],input[type=password],input[type=search],input[type=text],input[type=time],select{display:inline-block;width:250px;height:3rem;padding:0 .75rem;background-color:#fff;border:1px solid #dde;border-radius:2px;outline:none}input[type=date]:active,input[type=date]:focus,input[type=datetime]:active,input[type=datetime]:focus,input[type=password]:active,input[type=password]:focus,input[type=search]:active,input[type=search]:focus,input[type=text]:active,input[type=text]:focus,input[type=time]:active,input[type=time]:focus,select:active,select:focus{border-color:#2196f3}.label{display:inline-block;min-width:1.9995em;padding:0 .5em;font-size:.75019em;font-weight:600;line-height:inherit;text-align:center;color:#32394f;background-color:#fafafc;border-radius:2px}.label-blue,.label-primary{color:#fff;background-color:#2196f3}.label-green{color:#fff;background-color:#00b378}.label-red{color:#fff;background-color:#f44336}.label-#ff0{color:#fff;background-color:#ffc107}.label-orange{color:#fff;background-color:#ff9800}.label-purple{color:#fff;background-color:#673ab7}.menu-group:not(:last-child){margin-bottom:1.5rem}.menu-group-title,.menu-item{padding-left:1rem;padding-right:1rem}.menu-group-title{display:block;font-weight:600;margin-bottom:.5rem}.menu-item{padding-top:.25rem;padding-bottom:.25rem}.menu-item:hover{background-color:#fafafc}.table-wrapper{display:block;width:100%;border:1px solid #dde;border-radius:2px}.table-wrapper table{border:none}table{table-layout:fixed;width:100%;background-color:#fff;border-collapse:collapse;border:1px solid #dde}.table-striped tr:nth-child(2n)>td{background-color:#fafafa}td,th{text-align:left}td:last-of-type,th:last-of-type{border-right:none}th{padding:.75rem 1rem;font-weight:600;background-color:#fafafc;border-right:1px solid #dde;border-bottom:1px solid #dde}td{padding:.5rem 1rem;border-right:1px solid #eee;border-bottom:1px solid #eee;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}tbody:last-of-type tr:last-of-type>td,tfoot:last-of-type tr:last-of-type>td{border-bottom:none}tfoot td{font-weight:600}tfoot tr:first-of-type td{border-top:1px solid #dde}.fade-enter-active,.fade-leave-active{transition:opacity .25s ease-out}.fade-enter,.fade-leave{opacity:0}.checkbox{display:inline-block;margin-right:1rem;vertical-align:baseline}.checkbox label{position:relative;display:inline-block;width:1.25rem;height:1.25rem;margin-right:.25rem;background-color:#fff;border:1px solid #dde;border-radius:2px;vertical-align:text-bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox label:after{position:absolute;display:block;content:\" \";width:.375rem;height:.75rem;top:.125rem;left:.4rem;border-right:.2rem solid #fff;border-bottom:.2rem solid #fff;opacity:0;-webkit-transform:rotate(45deg);transform:rotate(45deg);transition:opacity .15s ease-out}.checkbox input[type=checkbox]{display:none!important}.checkbox input[type=checkbox]:checked+label{background-color:#2196f3;border-color:#2196f3}.checkbox input[type=checkbox]:checked+label:after{opacity:1}.checkbox input[type=checkbox]:disabled+label{background-color:#fafafa;cursor:not-allowed}.chip{display:inline-block;min-width:1.9995em;text-align:left;color:#32394f;background-color:#fafafc;border-radius:2px}.chip-body,.chip-footer{padding:.25rem .5rem}.chip-footer{background-color:#f2f2f7}.chip-close-button{position:relative;width:1.25rem;height:1.25rem;border-radius:2px;cursor:pointer}.chip-close-button:hover{background-color:#dadae9}.chip-close-button:after,.chip-close-button:before{display:block;position:absolute;content:\" \";top:50%;left:10%;width:80%;height:2px;margin-top:-1px;background-color:currentColor;-webkit-transform-origin:center center;transform-origin:center center}.chip-close-button:before{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.chip-close-button:after{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.datatable th{padding:0}.datatable-linenumber-cell,.datatable-linenumber-column{text-align:center}.datatable-aggregate-cell,.datatable-linenumber-cell{font-weight:600;background-color:#fafafc!important;border-right-color:#dde}.datatable-group-chip{margin-right:.5rem}.datatable-collection .datatable-collection .datatable-resultset{border-top:1px solid #dde}.datatable-group{padding:0;background-color:#fff}.datatable-group,.datatable-groups-header{border-bottom:1px solid #dde}.datatable-group-header{padding:.5rem 1rem;background-color:#fafafc}.datatable-grouping-over{box-shadow:0 0 0 2px #2196f3}.datatable-row-indent{display:inline-block;width:1.5rem;height:1em}.datatable-group-label{font-weight:600}.datatable-info-cell{text-align:center;font-weight:600}.datatable-aggregators .datatable-info-cell{border-bottom:1px solid #dde}.datatable-options{padding:.75rem 1rem;background-color:#fafafc;border-top:1px solid #dde}.datatable-editable .datatable-cell{position:relative;padding:0!important;overflow:visible}.datatable-editable .datatable-cell input,.datatable-editable .datatable-cell select{display:block;width:100%;height:auto;padding:.5rem 1rem;background-color:transparent;border:none;border-radius:0}.datatable-editable .datatable-cell input:active,.datatable-editable .datatable-cell input:focus,.datatable-editable .datatable-cell select:active,.datatable-editable .datatable-cell select:focus{box-shadow:0 0 0 2px #2196f3}.datatable-column{padding:.75rem 1rem;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datatable-sort-arrow{width:0;height:0;border:.375rem solid transparent}.datatable-sort-arrow-asc{border-bottom-color:currentColor;-webkit-transform:translateY(-.1875rem);transform:translateY(-.1875rem)}.datatable-sort-arrow-desc{border-top-color:currentColor;-webkit-transform:translateY(.1875rem);transform:translateY(.1875rem)}.float{display:inline-block;position:relative}.float-panel{display:block;position:absolute;top:100%;left:0;min-width:250px;min-height:50px;margin-top:5px;background-color:#fff;border-radius:2px;box-shadow:0 2px 3px 0 rgba(0,0,0,.2);z-index:10;-webkit-transform-origin:top left;transform-origin:top left}.float-enter,.float-leave-active{opacity:0;-webkit-transform:scale(0);transform:scale(0)}.float-enter-active,.float-leave-active{transition:opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .3s cubic-bezier(.4,0,.2,1);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .3s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1)}.modal-transition-enter-active,.modal-transition-leave-active{transition:opacity .2s ease-out}.modal-transition-enter-active .modal,.modal-transition-leave-active .modal{transition:-webkit-transform .2s ease-out;transition:transform .2s ease-out;transition:transform .2s ease-out,-webkit-transform .2s ease-out}.modal-transition-enter,.modal-transition-leave{opacity:0}.modal-transition-enter .modal,.modal-transition-leave .modal{-webkit-transform:scale(.8);transform:scale(.8)}.modal-shade{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.3);z-index:1000}.modal{width:640px;background-color:#fff;border-radius:2px;box-shadow:0 0 1px 2px rgba(0,0,0,.1);overflow:hidden}.modal-body,.modal-footer,.modal-header{padding:1rem}.modal-footer{background-color:#fafafc;border-top:1px solid #eee}.modal-title{font-weight:600}.paginator{border:1px solid #dde;border-radius:2px}.paginator-footer{padding:1rem;background-color:#fafafc;border-top:1px solid #dde}.paginator-button{display:inline-block;min-width:1.5em;padding:0 .5rem;font-weight:600;background-color:#dde;border-radius:2px;cursor:pointer}.paginator-button.active{color:#fff;background-color:#2196f3}.paginator-page-number{margin:0 .25rem}.panel{width:100%;min-height:150px;background-color:#fff;border:1px solid #dde;border-radius:2px}.panel-body,.panel-footer,.panel-header{padding:.75rem 1rem}.panel-footer,.panel-header{background-color:#fafafc}.panel-header{border-bottom:1px solid #dde}.panel-footer{border-top:1px solid #dde}.panel-title{font-weight:600}.radio{display:inline-block;margin-right:1rem;vertical-align:baseline}.radio label{position:relative;display:inline-block;width:1.25rem;height:1.25rem;background-color:#fff;border:1px solid #dde;border-radius:50%;vertical-align:text-bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio label:after{position:absolute;display:block;content:\" \";width:.5rem;height:.5rem;top:50%;left:50%;margin-top:-.25rem;margin-left:-.25rem;background-color:#fff;border-radius:50%}.radio input[type=radio]{display:none!important}.radio input[type=radio]:checked+label{background-color:#2196f3;border-color:#2196f3}.radio input[type=radio]:disabled+label{background-color:#fafafa;cursor:not-allowed}.tab-control{display:block;border:1px solid #dde;border-radius:2px}.tabs-list{background-color:#fafafa;border-bottom:1px solid #dde}.tab-item{position:relative;padding:.75rem 1rem;font-weight:600;border-right:1px solid #dde;cursor:pointer}.tab-item:after{position:absolute;display:none;content:\" \";bottom:-1px;left:0;width:100%;height:1px}.tab-item.active,.tab-item:after{background-color:#fff}.tab-item.active:after{display:block}.tab-pane{min-height:2rem;padding:1rem}.toggle{display:inline-block;margin-right:1rem;vertical-align:baseline}.toggle label{position:relative;display:inline-block;width:2.15rem;height:1.25rem;background-color:#fff;border:1px solid #dde;border-radius:.625rem;vertical-align:text-bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.toggle label:after{position:absolute;display:block;content:\" \";width:.8rem;height:.8rem;top:50%;left:.25rem;background-color:#dde;border-radius:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);transition:-webkit-transform .15s ease-out;transition:transform .15s ease-out;transition:transform .15s ease-out,-webkit-transform .15s ease-out}.toggle input[type=checkbox]{display:none!important}.toggle input[type=checkbox]:checked+label{background-color:#2196f3;border-color:#2196f3}.toggle input[type=checkbox]:checked+label:after{background-color:#fff;-webkit-transform:translate(.75rem,-50%);transform:translate(.75rem,-50%)}.toggle input[type=checkbox]:disabled+label{background-color:#fafafa;cursor:not-allowed}\n/*# sourceMappingURL=app.style.css.map*/"
  },
  {
    "path": "dist/components/components.bundle.js",
    "content": "var vuetiful=function(t){function e(r){if(n[r])return n[r].exports;var a=n[r]={i:r,l:!1,exports:{}};return t[r].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,\"a\",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p=\"/dist/\",e(e.s=64)}([function(t,e){t.exports=function(t,e,n,r){var a,o=t=t||{},u=typeof t.default;\"object\"!==u&&\"function\"!==u||(a=t,o=t.default);var i=\"function\"==typeof o?o.options:o;if(e&&(i.render=e.render,i.staticRenderFns=e.staticRenderFns),n&&(i._scopeId=n),r){var s=Object.create(i.computed||null);Object.keys(r).forEach(function(t){var e=r[t];s[t]=function(){return e}}),i.computed=s}return{esModule:a,exports:o,options:i}}},function(t,e,n){function r(t,e){if(c(t))return new Date(t.getTime());if(\"string\"!=typeof t)return new Date(t);var n=e||{},r=n.additionalDigits;r=null==r?p:Number(r);var l=a(t),f=o(l.date,r),v=f.year,g=f.restDateString,h=u(g,v);if(h){var m,y=h.getTime(),b=0;return l.time&&(b=i(l.time)),l.timezone?m=s(l.timezone):(m=new Date(y+b).getTimezoneOffset(),m=new Date(y+b+m*d).getTimezoneOffset()),new Date(y+b+m*d)}return new Date(t)}function a(t){var e,n={},r=t.split(v);if(g.test(r[0])?(n.date=null,e=r[0]):(n.date=r[0],e=r[1]),e){var a=P.exec(e);a?(n.time=e.replace(a[1],\"\"),n.timezone=a[1]):n.time=e}return n}function o(t,e){var n,r=m[e],a=b[e];if(n=y.exec(t)||a.exec(t)){var o=n[1];return{year:parseInt(o,10),restDateString:t.slice(o.length)}}if(n=h.exec(t)||r.exec(t)){var u=n[1];return{year:100*parseInt(u,10),restDateString:t.slice(u.length)}}return{year:null}}function u(t,e){if(null===e)return null;var n,r,a,o;if(0===t.length)return r=new Date(0),r.setUTCFullYear(e),r;if(n=_.exec(t))return r=new Date(0),a=parseInt(n[1],10)-1,r.setUTCFullYear(e,a),r;if(n=x.exec(t)){r=new Date(0);var u=parseInt(n[1],10);return r.setUTCFullYear(e,0,u),r}if(n=M.exec(t)){r=new Date(0),a=parseInt(n[1],10)-1;var i=parseInt(n[2],10);return r.setUTCFullYear(e,a,i),r}if(n=D.exec(t))return o=parseInt(n[1],10)-1,l(e,o);if(n=w.exec(t)){o=parseInt(n[1],10)-1;return l(e,o,parseInt(n[2],10)-1)}return null}function i(t){var e,n,r;if(e=S.exec(t))return(n=parseFloat(e[1].replace(\",\",\".\")))%24*f;if(e=O.exec(t))return n=parseInt(e[1],10),r=parseFloat(e[2].replace(\",\",\".\")),n%24*f+r*d;if(e=C.exec(t)){n=parseInt(e[1],10),r=parseInt(e[2],10);var a=parseFloat(e[3].replace(\",\",\".\"));return n%24*f+r*d+1e3*a}return null}function s(t){var e,n;return(e=j.exec(t))?0:(e=N.exec(t))?(n=60*parseInt(e[2],10),\"+\"===e[1]?-n:n):(e=T.exec(t),e?(n=60*parseInt(e[2],10)+parseInt(e[3],10),\"+\"===e[1]?-n:n):0)}function l(t,e,n){e=e||0,n=n||0;var r=new Date(0);r.setUTCFullYear(t,0,4);var a=r.getUTCDay()||7,o=7*e+n+1-a;return r.setUTCDate(r.getUTCDate()+o),r}var c=n(60),f=36e5,d=6e4,p=2,v=/[T ]/,g=/:/,h=/^(\\d{2})$/,m=[/^([+-]\\d{2})$/,/^([+-]\\d{3})$/,/^([+-]\\d{4})$/],y=/^(\\d{4})/,b=[/^([+-]\\d{4})/,/^([+-]\\d{5})/,/^([+-]\\d{6})/],_=/^-(\\d{2})$/,x=/^-?(\\d{3})$/,M=/^-?(\\d{2})-?(\\d{2})$/,D=/^-?W(\\d{2})$/,w=/^-?W(\\d{2})-?(\\d{1})$/,S=/^(\\d{2}([.,]\\d*)?)$/,O=/^(\\d{2}):?(\\d{2}([.,]\\d*)?)$/,C=/^(\\d{2}):?(\\d{2}):?(\\d{2}([.,]\\d*)?)$/,P=/([Z+-].*)$/,j=/^(Z)$/,N=/^([+-])(\\d{2})$/,T=/^([+-])(\\d{2}):?(\\d{2})$/;t.exports=r},function(t,e,n){var r=n(29)(\"wks\"),a=n(12),o=n(3).Symbol,u=\"function\"==typeof o;(t.exports=function(t){return r[t]||(r[t]=u&&o[t]||(u?o:a)(\"Symbol.\"+t))}).store=r},function(t,e){var n=t.exports=\"undefined\"!=typeof window&&window.Math==Math?window:\"undefined\"!=typeof self&&self.Math==Math?self:Function(\"return this\")();\"number\"==typeof __g&&(__g=n)},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var r=n(8),a=n(17);t.exports=n(7)?function(t,e,n){return r.f(t,e,a(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(48),a=n(21);t.exports=function(t){return r(a(t))}},function(t,e,n){t.exports=!n(15)(function(){return 7!=Object.defineProperty({},\"a\",{get:function(){return 7}}).a})},function(t,e,n){var r=n(14),a=n(47),o=n(31),u=Object.defineProperty;e.f=n(7)?Object.defineProperty:function(t,e,n){if(r(t),e=o(e,!0),r(n),a)try{return u(t,e,n)}catch(t){}if(\"get\"in n||\"set\"in n)throw TypeError(\"Accessors not supported!\");return\"value\"in n&&(t[e]=n.value),t}},function(t,e){var n=t.exports={version:\"2.4.0\"};\"number\"==typeof __e&&(__e=n)},function(t,e){t.exports=function(t){return\"object\"==typeof t?null!==t:\"function\"==typeof t}},function(t,e,n){var r=n(3),a=n(5),o=n(4),u=n(12)(\"src\"),i=Function.toString,s=(\"\"+i).split(\"toString\");n(9).inspectSource=function(t){return i.call(t)},(t.exports=function(t,e,n,i){var l=\"function\"==typeof n;l&&(o(n,\"name\")||a(n,\"name\",e)),t[e]!==n&&(l&&(o(n,u)||a(n,u,t[e]?\"\"+t[e]:s.join(String(e)))),t===r?t[e]=n:i?t[e]?t[e]=n:a(t,e,n):(delete t[e],a(t,e,n)))})(Function.prototype,\"toString\",function(){return\"function\"==typeof this&&this[u]||i.call(this)})},function(t,e){var n=0,r=Math.random();t.exports=function(t){return\"Symbol(\".concat(void 0===t?\"\":t,\")_\",(++n+r).toString(36))}},function(t,e,n){\"use strict\";function r(t,e,n){var r=n||0,a=!0,o=!1,u=void 0;try{for(var i,s=t[Symbol.iterator]();!(a=(i=s.next()).done);a=!0){var l=i.value,c=e.call(this,r,l,t);if(!1===c)return!1;r=c}}catch(t){o=!0,u=t}finally{try{!a&&s.return&&s.return()}finally{if(o)throw u}}return r}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r},function(t,e,n){var r=n(10);t.exports=function(t){if(!r(t))throw TypeError(t+\" is not an object!\");return t}},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){var r=n(54),a=n(22);t.exports=Object.keys||function(t){return r(t,a)}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){\"use strict\";function r(t,e){return(0,a.format)(t,e)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(62)},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={model:{prop:\"source\",event:\"change\"},props:{id:{type:String,required:!0},source:{required:!0},value:{required:!1},disabled:{type:Boolean,default:!1}},data:function(){return{proxy:!1}},computed:{checked:{get:function(){return this.source},set:function(t){this.proxy=t,this.$emit(\"change\",this.proxy)}}}}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError(\"Can't call method on  \"+t);return t}},function(t,e){t.exports=\"constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf\".split(\",\")},function(t,e,n){var r=n(3),a=n(9),o=n(5),u=n(11),i=n(45),s=function(t,e,n){var l,c,f,d,p=t&s.F,v=t&s.G,g=t&s.S,h=t&s.P,m=t&s.B,y=v?r:g?r[e]||(r[e]={}):(r[e]||{}).prototype,b=v?a:a[e]||(a[e]={}),_=b.prototype||(b.prototype={});v&&(n=e);for(l in n)c=!p&&y&&void 0!==y[l],f=(c?y:n)[l],d=m&&c?i(f,r):h&&\"function\"==typeof f?i(Function.call,f):f,y&&u(y,l,f,t&s.U),b[l]!=f&&o(b,l,d),h&&_[l]!=f&&(_[l]=f)};r.core=a,s.F=1,s.G=2,s.S=4,s.P=8,s.B=16,s.W=32,s.U=64,s.R=128,t.exports=s},function(t,e){t.exports={}},function(t,e){t.exports=!1},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var r=n(8).f,a=n(4),o=n(2)(\"toStringTag\");t.exports=function(t,e,n){t&&!a(t=n?t:t.prototype,o)&&r(t,o,{configurable:!0,value:e})}},function(t,e,n){var r=n(29)(\"keys\"),a=n(12);t.exports=function(t){return r[t]||(r[t]=a(t))}},function(t,e,n){var r=n(3),a=r[\"__core-js_shared__\"]||(r[\"__core-js_shared__\"]={});t.exports=function(t){return a[t]||(a[t]={})}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(10);t.exports=function(t,e){if(!r(t))return t;var n,a;if(e&&\"function\"==typeof(n=t.toString)&&!r(a=n.call(t)))return a;if(\"function\"==typeof(n=t.valueOf)&&!r(a=n.call(t)))return a;if(!e&&\"function\"==typeof(n=t.toString)&&!r(a=n.call(t)))return a;throw TypeError(\"Can't convert object to primitive value\")}},function(t,e,n){var r=n(3),a=n(9),o=n(25),u=n(33),i=n(8).f;t.exports=function(t){var e=a.Symbol||(a.Symbol=o?{}:r.Symbol||{});\"_\"==t.charAt(0)||t in e||i(e,t,{value:u.f(t)})}},function(t,e,n){e.f=n(2)},function(t,e,n){function r(t){return a(t,{weekStartsOn:1})}var a=n(153);t.exports=r},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={AED:\"د.إ\",AFN:\"؋\",ALL:\"L\",ANG:\"ƒ\",AOA:\"Kz\",ARS:\"$\",AUD:\"$\",AWG:\"ƒ\",AZN:\"₼\",BAM:\"KM\",BBD:\"$\",BDT:\"৳\",BGN:\"лв\",BHD:\".د.ب\",BIF:\"FBu\",BMD:\"$\",BND:\"$\",BOB:\"Bs.\",BRL:\"R$\",BSD:\"$\",BTN:\"Nu.\",BWP:\"P\",BYR:\"p.\",BZD:\"BZ$\",CAD:\"$\",CDF:\"FC\",CHF:\"Fr.\",CLP:\"$\",CNY:\"¥\",COP:\"$\",CRC:\"₡\",CUC:\"$\",CUP:\"₱\",CVE:\"$\",CZK:\"Kč\",DJF:\"Fdj\",DKK:\"kr\",DOP:\"RD$\",DZD:\"دج\",EEK:\"kr\",EGP:\"£\",ERN:\"Nfk\",ETB:\"Br\",EUR:\"€\",FJD:\"$\",FKP:\"£\",GBP:\"£\",GEL:\"₾\",GGP:\"£\",GHC:\"₵\",GHS:\"GH₵\",GIP:\"£\",GMD:\"D\",GNF:\"FG\",GTQ:\"Q\",GYD:\"$\",HKD:\"$\",HNL:\"L\",HRK:\"kn\",HTG:\"G\",HUF:\"Ft\",IDR:\"Rp\",ILS:\"₪\",IMP:\"£\",INR:\"₹\",IQD:\"ع.د\",IRR:\"﷼\",ISK:\"kr\",JEP:\"£\",JMD:\"J$\",JPY:\"¥\",KES:\"KSh\",KGS:\"лв\",KHR:\"៛\",KMF:\"CF\",KPW:\"₩\",KRW:\"₩\",KYD:\"$\",KZT:\"₸\",LAK:\"₭\",LBP:\"£\",LKR:\"₨\",LRD:\"$\",LSL:\"M\",LTL:\"Lt\",LVL:\"Ls\",MAD:\"MAD\",MDL:\"lei\",MGA:\"Ar\",MKD:\"ден\",MMK:\"K\",MNT:\"₮\",MOP:\"MOP$\",MUR:\"₨\",MVR:\"Rf\",MWK:\"MK\",MXN:\"$\",MYR:\"RM\",MZN:\"MT\",NAD:\"$\",NGN:\"₦\",NIO:\"C$\",NOK:\"kr\",NPR:\"₨\",NZD:\"$\",OMR:\"﷼\",PAB:\"B/.\",PEN:\"S/.\",PGK:\"K\",PHP:\"₱\",PKR:\"₨\",PLN:\"zł\",PYG:\"Gs\",QAR:\"﷼\",RMB:\"￥\",RON:\"lei\",RSD:\"Дин.\",RUB:\"₽\",RWF:\"R₣\",SAR:\"﷼\",SBD:\"$\",SCR:\"₨\",SDG:\"ج.س.\",SEK:\"kr\",SGD:\"$\",SHP:\"£\",SLL:\"Le\",SOS:\"S\",SRD:\"$\",SSP:\"£\",STD:\"Db\",SVC:\"$\",SYP:\"£\",SZL:\"E\",THB:\"฿\",TJS:\"SM\",TMT:\"T\",TND:\"د.ت\",TOP:\"T$\",TRL:\"₤\",TRY:\"₺\",TTD:\"TT$\",TVD:\"$\",TWD:\"NT$\",TZS:\"TSh\",UAH:\"₴\",UGX:\"USh\",USD:\"$\",UYU:\"$U\",UZS:\"лв\",VEF:\"Bs\",VND:\"₫\",VUV:\"VT\",WST:\"WS$\",XAF:\"FCFA\",XBT:\"Ƀ\",XCD:\"$\",XOF:\"CFA\",XPF:\"₣\",YER:\"﷼\",ZAR:\"R\",ZWD:\"Z$\",BTC:\"฿\"}},function(t,e,n){\"use strict\";function r(t,e){var n=(0,o.default)(t,e);return!!n&&n/t.length}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(42),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){\"use strict\";function r(t){var e=!0,n=!1,r=void 0;try{for(var a,o=i[Symbol.iterator]();!(e=(a=o.next()).done);e=!0){var u=a.value;if(u.test(t))return u.toNumber}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}return function(t){return t}}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(38),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}(a),u=/^(\\-|\\+)?([0-9]+(\\.[0-9]+)?|Infinity)$/,i=[{test:function(t){return!!o.isNumber(t)||u.test(t)},toNumber:parseFloat},{test:function(t){if(o.isDate(t))return!0;var e=new Date(t);return o.isDate(e)},toNumber:function(t){return new Date(t).getTime()}}]},function(t,e,n){\"use strict\";function r(t,e){return e===Object.prototype.toString.call(t)}function a(t){for(var e=!1,n=0,r=arguments.length,a=Array(r>1?r-1:0),o=1;o<r;o++)a[o-1]=arguments[o];for(;!e&&n<a.length;)e=a[n].call(this,t),n++;return e}function o(t){return r(t,g.array)}function u(t){return r(t,g.boolean)}function i(t){return r(t,g.date)&&!isNaN(t.getTime())}function s(t){return r(t,g.null)}function l(t){return r(t,g.number)}function c(t){return r(t,g.object)}function f(t){return r(t,g.string)}function d(t){return r(t,g.undefined)}function p(t){return!a(t,o,i,c)}function v(t){return a(t,o,c)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.isAny=a,e.isArray=o,e.isBoolean=u,e.isDate=i,e.isNull=s,e.isNumber=l,e.isObject=c,e.isString=f,e.isUndefined=d,e.isPrimitive=p,e.isCollection=v;var g={array:\"[object Array]\",boolean:\"[object Boolean]\",date:\"[object Date]\",null:\"[object Null]\",number:\"[object Number]\",object:\"[object Object]\",string:\"[object String]\",undefined:\"[object Undefined]\"}},function(t,e,n){\"use strict\";function r(t,e){if(!e)return t;for(var n=[],r=0;r<t.length;r++){var u=t[r];for(var i in u){var s=u[i];if(!(o.indexOf(void 0===s?\"undefined\":a(s))<0)){if(s.toString().toLowerCase().indexOf(e.toLowerCase())>-1){n.push(u);break}}}}return n}Object.defineProperty(e,\"__esModule\",{value:!0});var a=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&\"function\"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?\"symbol\":typeof t};e.default=r;var o=[\"string\",\"number\",\"boolean\"]},function(t,e,n){\"use strict\";function r(t,e){e=e||function(t){return t};var n={},r=!0,a=!1,o=void 0;try{for(var u,i=t[Symbol.iterator]();!(r=(u=i.next()).done);r=!0){var s=u.value,l=e.call(t,s);n.hasOwnProperty(l)||(n[l]=[]),n[l].push(s)}}catch(t){a=!0,o=t}finally{try{!r&&i.return&&i.return()}finally{if(a)throw o}}return n}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r},function(t,e,n){\"use strict\";function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)}function a(t,e,n){if(n=n||1,e=e||function(t){return t},1!==Math.abs(n))throw new Error(\"Sort direction must be either 1 (ascending) or -1 (descending)\");var a=[].concat(r(t));return a.sort(function(r,a){var o=e.call(t,r),u=e.call(t,a);return(o<u?-1:o>u?1:0)*n}),a}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=a},function(t,e,n){\"use strict\";function r(t,e){var n=parseFloat(e);return!isNaN(n)&&t+n}function a(t,e){return e=e||function(t){return t},(0,u.default)(t,function(t,n,a){var o=e.call(a,n);return r.call(a,t,o)})}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=a;var o=n(13),u=function(t){return t&&t.__esModule?t:{default:t}}(o)},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}function a(t,e){var n=t.length,r=(0,s.default)(t,e),a=(0,u.default)(t,function(t,n,a){var o=e.call(a,n);return t+Math.pow(o-r,2)});return!!a&&a/n}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=a;var o=n(13),u=r(o),i=n(36),s=r(i)},function(t,e,n){var r=n(2)(\"unscopables\"),a=Array.prototype;void 0==a[r]&&n(5)(a,r,{}),t.exports=function(t){a[r][t]=!0}},function(t,e,n){var r=n(112);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,a){return t.call(e,n,r,a)}}return function(){return t.apply(e,arguments)}}},function(t,e,n){var r=n(10),a=n(3).document,o=r(a)&&r(a.createElement);t.exports=function(t){return o?a.createElement(t):{}}},function(t,e,n){t.exports=!n(7)&&!n(15)(function(){return 7!=Object.defineProperty(n(46)(\"div\"),\"a\",{get:function(){return 7}}).a})},function(t,e,n){var r=n(20);t.exports=Object(\"z\").propertyIsEnumerable(0)?Object:function(t){return\"String\"==r(t)?t.split(\"\"):Object(t)}},function(t,e,n){var r=n(20);t.exports=Array.isArray||function(t){return\"Array\"==r(t)}},function(t,e,n){\"use strict\";var r=n(25),a=n(23),o=n(11),u=n(5),i=n(4),s=n(24),l=n(120),c=n(27),f=n(127),d=n(2)(\"iterator\"),p=!([].keys&&\"next\"in[].keys()),v=function(){return this};t.exports=function(t,e,n,g,h,m,y){l(n,e,g);var b,_,x,M=function(t){if(!p&&t in O)return O[t];switch(t){case\"keys\":case\"values\":return function(){return new n(this,t)}}return function(){return new n(this,t)}},D=e+\" Iterator\",w=\"values\"==h,S=!1,O=t.prototype,C=O[d]||O[\"@@iterator\"]||h&&O[h],P=C||M(h),j=h?w?M(\"entries\"):P:void 0,N=\"Array\"==e?O.entries||C:C;if(N&&(x=f(N.call(new t)))!==Object.prototype&&(c(x,D,!0),r||i(x,d)||u(x,d,v)),w&&C&&\"values\"!==C.name&&(S=!0,P=function(){return C.call(this)}),r&&!y||!p&&!S&&O[d]||u(O,d,P),s[e]=P,s[D]=v,h)if(b={values:w?P:M(\"values\"),keys:m?P:M(\"keys\"),entries:j},y)for(_ in b)_ in O||o(O,_,b[_]);else a(a.P+a.F*(p||S),e,b);return b}},function(t,e,n){var r=n(14),a=n(124),o=n(22),u=n(28)(\"IE_PROTO\"),i=function(){},s=function(){var t,e=n(46)(\"iframe\"),r=o.length;for(e.style.display=\"none\",n(119).appendChild(e),e.src=\"javascript:\",t=e.contentWindow.document,t.open(),t.write(\"<script>document.F=Object<\\/script>\"),t.close(),s=t.F;r--;)delete s.prototype[o[r]];return s()};t.exports=Object.create||function(t,e){var n;return null!==t?(i.prototype=r(t),n=new i,i.prototype=null,n[u]=t):n=s(),void 0===e?n:a(n,e)}},function(t,e,n){var r=n(54),a=n(22).concat(\"length\",\"prototype\");e.f=Object.getOwnPropertyNames||function(t){return r(t,a)}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var r=n(4),a=n(6),o=n(113)(!1),u=n(28)(\"IE_PROTO\");t.exports=function(t,e){var n,i=a(t),s=0,l=[];for(n in i)n!=u&&r(i,n)&&l.push(n);for(;e.length>s;)r(i,n=e[s++])&&(~o(l,n)||l.push(n));return l}},function(t,e,n){var r=n(30),a=Math.min;t.exports=function(t){return t>0?a(r(t),9007199254740991):0}},function(t,e,n){var r=n(21);t.exports=function(t){return Object(r(t))}},function(t,e,n){function r(t,e){var n=a(t),r=Number(e),u=n.getMonth()+r,i=new Date(0);i.setFullYear(n.getFullYear(),u,1),i.setHours(0,0,0,0);var s=o(i);return n.setMonth(u,Math.min(s,n.getDate())),n}var a=n(1),o=n(58);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=e.getFullYear(),r=e.getMonth(),o=new Date(0);return o.setFullYear(n,r+1,0),o.setHours(0,0,0,0),o.getDate()}var a=n(1);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=e.getFullYear(),r=new Date(0);r.setFullYear(n+1,0,4),r.setHours(0,0,0,0);var u=o(r),i=new Date(0);i.setFullYear(n,0,4),i.setHours(0,0,0,0);var s=o(i);return e.getTime()>=u.getTime()?n+1:e.getTime()>=s.getTime()?n:n-1}var a=n(1),o=n(34);t.exports=r},function(t,e){function n(t){return t instanceof Date}t.exports=n},function(t,e,n){function r(t){if(a(t))return!isNaN(t);throw new TypeError(toString.call(t)+\" is not an instance of Date\")}var a=n(60);t.exports=r},function(t,e){t.exports=dateFns},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}function a(t){for(var e in i.default){var n=i.default[e];t.component(e,n)}}function o(t){for(var e in l.default){var n=l.default[e];t.directive(e,n)}}Object.defineProperty(e,\"__esModule\",{value:!0}),n(99),n(156),n(157);var u=n(89),i=r(u),s=n(92),l=r(s),c=n(80),f=r(c),d=n(97),p=r(d),v=n(98),g=r(v);e.default={install:function(t){a(t),o(t)},aggregators:f.default,formatters:p.default,maps:g.default}},function(t,e,n){\"use strict\";var r=n(63),a=function(t){return t&&t.__esModule?t:{default:t}}(r);\"undefined\"!=typeof window&&window.Vue&&window.Vue.use(a.default),t.exports=a.default},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(100),o=r(a),u=n(141),i=r(u);e.default={data:function(){return{calendar:new o.default}},methods:{previous:function(){this.calendar.previousMonth()},next:function(){this.calendar.nextMonth()}},filters:{date:function(t,e){return(0,i.default)(t,e)}}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={props:{removable:{type:Boolean,default:!0}},methods:{remove:function(){this.$emit(\"remove\",this)}}}},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(90),o=r(a),u=n(40),i=r(u);e.default={name:\"datatable-collection\",props:{rows:{type:Array,required:!0},columns:{type:Array,required:!0},groupingColumns:{type:Array},groupingIndex:{type:Number,default:0},striped:{type:Boolean,default:!0},editable:{type:Boolean,default:!1},lineNumbers:{type:Boolean,default:!1},aggregated:{type:Boolean,default:!1},margin:{type:String,default:\"1.5em\"},collectionIndex:{type:Number,default:0},optimize:{type:Boolean,default:!1},message:{type:String,default:\"No results\",required:!1}},computed:{groupable:function(){return this.groupingIndex<this.groupingColumns.length},groupingColumn:function(){var t=this.groupingColumns[this.groupingIndex];return this.columns.find(function(e){return e.id===t})},groups:function(){var t=this.groupingColumn.id;return(0,i.default)(this.rows,function(e){return e[t]})},columnSpan:function(){return this.columns.length+(this.lineNumbers?1:0)},indentStyle:function(){return{\"margin-left\":1.5*this.groupingIndex+\"rem\"}}},components:{datatableCell:o.default}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=[\"left\",\"center\",\"right\",\"auto\"],a={1:\"asc\",\"-1\":\"desc\"};e.default={props:{id:{type:String,required:!0},label:{type:String},width:{type:[Number,String]},alignment:{type:String,default:\"left\",validator:function(t){return r.indexOf(t)>-1}},formatter:{type:Function},sortable:{type:Boolean,default:!0},groupable:{type:Boolean,default:!0},aggregators:{type:Array}},data:function(){return{sortingDirection:1}},computed:{sorting:{get:function(){return this.$parent.sortingId===this.id&&this.sortable},set:function(t){t&&this.sortable&&(this.$parent.sortingId=this.id)}},grouping:{get:function(){return this.$parent.groupingColumnIds.indexOf(this.id)>-1}},columnWidth:function(){if(this.width){var t=isNaN(this.width)?\"\":\"%\";return this.width+t}},columnLayout:function(){return(\"right\"!==this.alignment?\"row\":\"row-reverse\")+\" center-justify\"},columnStyles:function(){var t=\"left\"===this.alignment?null:this.alignment;return{width:this.columnWidth,textAlign:t}},sortArrowClass:function(){return\"datatable-sort-arrow-\"+a[this.sortingDirection]},template:function(){return this.$parent.$scopedSlots[this.id]}},methods:{sort:function(){if(this.sorting)return void(this.sortingDirection*=-1);this.sorting=!0},formatData:function(t){return this.formatter?this.formatter(t):t},dragStart:function(t){t.stopPropagation(),t.dataTransfer.dropEffect=\"copy\",t.dataTransfer.setData(\"text\",this.id)}},created:function(){var t=this.$parent.addColumn;if(!t)return void console.warn(\"A datatable-column must be registered within a datatable component.\");t(this)},destroyed:function(){this.$parent.removeColumn(this)}}},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(172),o=r(a),u=n(39),i=r(u),s=n(41),l=r(s),c=n(38);e.default={props:{fixed:{type:Boolean,default:!0},striped:{type:Boolean,default:!0},source:{type:Array,default:function(){return[]}},editable:{type:Boolean,default:!1},filterable:{type:Boolean,default:!0},lineNumbers:{type:Boolean,default:!1},threshold:{type:Number,default:50},message:{type:String,default:\"No results\"}},data:function(){return{columns:[],filter:null,sortingId:null,groupingColumnIds:[],groupingDropzoneActive:!1}},computed:{sortingColumn:function(){var t=this;return this.columns.find(function(e){return e.id===t.sortingId})},groupingColumns:function(){var t=this;return this.groupingColumnIds.map(function(e){return t.columns.find(function(t){return t.id===e})})},tableClasses:function(){return{\"datatable-editable\":this.editable,\"table-fixed\":this.fixed}},groupableColumns:function(){return this.columns.filter(function(t){return t.groupable})},rows:function(){var t=this,e=this.source;return this.filter&&(e=(0,i.default)(e,this.filter)),this.sortingColumn&&(e=(0,l.default)(e,function(e){return e[t.sortingColumn.id]},this.sortingColumn.sortingDirection)),e},columnSpan:function(){var t=this.columns.length;return this.lineNumbers&&t++,this.aggregated&&t++,t},lineColumnWidth:function(){return this.source.length.toString().length+2+\"em\"},aggregators:function(){var t=[],e=!0,n=!1,r=void 0;try{for(var a,o=this.columns[Symbol.iterator]();!(e=(a=o.next()).done);e=!0){var u=a.value;u.aggregators&&(t=t.concat(u.aggregators))}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}return t.filter(function(t,e,n){return e===n.indexOf(t)})},aggregated:function(){return this.aggregators&&this.aggregators.length>0},optimize:function(){return this.source.length>=this.threshold}},methods:{addColumn:function(t){this.columns.push(t)},removeColumn:function(t){var e=this.columns.indexOf(t);this.columns.splice(e,1)},groupColumn:function(t){this.groupingColumnIds.push(t.id)},degroupColumn:function(t){var e=this.groupingColumnIds.indexOf(t.id);this.groupingColumnIds.splice(e,1)},aggregate:function(t,e){if(!t.aggregators||-1===t.aggregators.indexOf(e))return\" \";var n=e.callback.call(t,this.rows,function(e){return e[t.id]});return!n||(0,c.isCollection)(n)?\" \":e.format?t.formatData(n):n},dragDrop:function(t){t.preventDefault();var e=t.dataTransfer.getData(\"text\"),n=this.groupableColumns.find(function(t){return t.id===e});n&&!n.grouping&&this.groupColumn(n)},dragOver:function(t){t.preventDefault()},dragEnter:function(t){t.preventDefault(),this.groupingDropzoneActive=!0},dragLeave:function(t){t.preventDefault(),this.groupingDropzoneActive=!1}},components:{datatableCollection:o.default}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(62),a=new Date(-864e13),o=new Date(864e13);e.default={props:{value:{required:!0},type:{type:String,default:\"date\"},format:{type:String,default:\"DD-MM-YYYY\"},minDate:{type:Date,default:function(){return a}},maxDate:{type:Date,default:function(){return o}},minHour:{type:Number,default:0},maxHour:{type:Number,default:23},minMinute:{type:Number,default:0},maxMinute:{type:Number,default:59}},data:function(){return{visible:!1}},computed:{formattedValue:function(){return this.value&&(0,r.isValid)(this.value)?(0,r.format)(this.value,this.format):null}},methods:{updateValue:function(t){this.$emit(\"input\",t)},show:function(){var t=this;this.visible=!0;var e=function e(n){n.stopPropagation(),t.$el.contains(n.target)||(t.visible=!1,document.removeEventListener(\"click\",e))};document.addEventListener(\"click\",e)}}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={props:{visible:{type:Boolean,default:!1},position:{type:String,default:\"bottom left\"},showArrow:{type:Boolean,default:!1}}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={props:{title:{type:String,required:!0}},data:function(){return{showing:!1}},methods:{open:function(){this.showing=!0,this.$emit(\"open\",this)},close:function(){this.showing=!1,this.$emit(\"close\",this)}}}},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(39),o=r(a),u=n(107),i=r(u);e.default={props:{source:{type:Array,default:function(){return[]}},pageSize:{type:Number,default:25},filter:{type:String}},data:function(){return{index:0}},computed:{pages:function(){var t=this.source;this.filter&&(t=(0,o.default)(t,this.filter));var e=(0,i.default)(t,this.pageSize);return this.pageNumber>e.length&&(this.pageNumber=1),e},pageNumber:{get:function(){return this.index+1},set:function(t){this.index=t-1,this.$emit(\"page-changed\",t)}},data:function(){return this.pages[this.index]}},methods:{movePrevious:function(){this.pageNumber-=this.pageNumber>1?1:0},moveNext:function(){this.pageNumber+=this.pageNumber!=this.pages.length?1:0},moveTo:function(t){t>0&&t<=this.pages.length&&(this.pageNumber=t)}}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={props:{title:{type:String,required:!0}}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={data:function(){return{tabs:[],selectedTabId:null}},computed:{selectedTab:function(){var t=this;return this.tabs.find(function(e){return e.id===t.selectedTabId})}},methods:{addTab:function(t){this.tabs.push(t)},removeTab:function(t){var e=this.tabs.indexOf(t);this.tabs.splice(e,1)},selectTab:function(t){this.selectedTabId=t.id,this.$emit(\"tab-change\",t)}},mounted:function(){this.tabs.length>0&&(this.selectedTabId=this.tabs[0].id)}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={props:{id:{type:String,required:!0},label:{type:String,required:!0}},computed:{selected:function(){return this.$parent.selectedTab===this}},created:function(){var t=this.$parent.addTab;if(!t)return void console.warn(\"A tab-pane must be registered in a tab-control.\");t(this)},destroyed:function(){this.$parent.removeTab(this)}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(19),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={mixins:[a.default]}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(19),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={mixins:[a.default]}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(19),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={mixins:[a.default]}},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(85),o=r(a),u=n(83),i=r(u),s=n(82),l=r(s),c=n(81),f=r(c),d=n(87),p=r(d),v=n(88),g=r(v),h=n(86),m=r(h),y=n(84),b=r(y);e.default={min:o.default,max:i.default,count:l.default,average:f.default,total:p.default,variance:g.default,standardDeviation:m.default,median:b.default}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(36),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Average\",callback:a.default,format:!0}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={label:\"Count\",callback:function(t){return t.length}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(103),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Maximum\",callback:a.default,format:!0}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(104),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Median\",callback:a.default}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(105),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Minimum\",callback:a.default,format:!0}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(108),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Standard Deviation\",callback:a.default}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(42),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Total\",callback:a.default,format:!0}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(43),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={label:\"Variance\",callback:a.default}},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(170),o=r(a),u=n(182),i=r(u),s=n(171),l=r(s),c=n(174),f=r(c),d=n(173),p=r(d),v=n(175),g=r(v),h=n(91),m=r(h),y=n(176),b=r(y),_=n(177),x=r(_),M=n(178),D=r(M),w=n(179),S=r(w),O=n(183),C=r(O),P=n(180),j=r(P),N=n(181),T=r(N),k=n(184),F=r(k);e.default={calendar:o.default,checkbox:i.default,chip:l.default,datatable:f.default,datatableColumn:p.default,datetimePicker:g.default,dynamic:m.default,floatingPanel:b.default,modal:x.default,paginator:D.default,panel:S.default,radio:C.default,toggle:F.default,tabControl:j.default,tabPane:T.default}},function(t,e,n){\"use strict\";function r(t,e){var n={template:a,props:[\"row\",\"column\"]};return t&&(n.template=e?u:o),n}Object.defineProperty(e,\"__esModule\",{value:!0});var a=\"<span>{{ column.formatData(row[column.id]) }}</span>\",o='<input type=\"text\" v-model=\"row[column.id]\"/>',u='<input type=\"text\" v-model.lazy=\"row[column.id]\"/>';e.default={functional:!0,name:\"datatable-cell\",props:{row:Object,column:Object,editable:{type:Boolean,default:!1},optimize:{type:Boolean,default:!1}},render:function(t,e){var n=e.props.row,a=e.props.column,o={class:{\"datatable-cell\":!0},style:a.columnStyles};if(a.template){return t(\"td\",o,[a.template({row:n,column:a,value:n[a.id]})])}return t(\"td\",o,[t(r(e.props.editable,e.props.optimize),{props:{row:n,column:a}})])}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.default={functional:!0,props:{component:{type:Object,required:!0}},render:function(t,e){var n=e.props.component;if(!n.node)return void console.warn(\"Dynamic element not rendered. No node name specified.\");var r={attrs:n.attrs,props:n.props,domProps:n.domProps,on:n.on};if(!n.children)return t(n.node,r);var a=n.children.map(function(e){return t(\"dynamic\",{props:{component:e}})});return t(n.node,r,a)}}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(93),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={drag:a.default}},function(t,e,n){\"use strict\";function r(t){}Object.defineProperty(e,\"__esModule\",{value:!0});var a={start:{eventName:\"dragstart\",draggable:!0,callback:r},drag:{eventName:\"drag\",draggable:!0,callback:r},enter:{eventName:\"dragenter\",callback:r},leave:{eventName:\"dragleave\",callback:r},over:{eventName:\"dragover\",callback:r},drop:{eventName:\"drop\",callback:r},end:{eventName:\"dragend\",draggable:!0,callback:r}};e.default={bind:function(t,e,n){var r=e.arg.toLowerCase();if(!(r in a))return void console.warn(\"Event not supported\");var o=a[r];o.draggable&&t.setAttribute(\"draggable\",!0);var u=e.value;\"function\"!=typeof u&&(u=function(t){}),t.addEventListener(o.eventName,function(e){return o.callback.call(t,e),u.call(t,e),!1},!1)}}},function(t,e,n){\"use strict\";function r(t,e,n){e=e||2;var r=parseFloat(t);return isNaN(r)?t:(n?o.default[n.toUpperCase()]:o.default.USD)+r.toFixed(e).replace(/(\\d)(?=(\\d{3})+\\.)/g,\"$1,\")}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(35),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){\"use strict\";function r(t){return(0,o.default)(t,\"D MMMM YYYY\")}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(18),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){\"use strict\";function r(t){return(0,o.default)(t,\"DD/MM/YYYY\")}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(18),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var a=n(94),o=r(a),u=n(18),i=r(u),s=n(96),l=r(s),c=n(95),f=r(c);e.default={currency:o.default,datetime:i.default,dateShort:l.default,dateLong:f.default}},function(t,e,n){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=n(35),a=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={currencies:a.default}},function(t,e,n){\"use strict\";n(110),n(111),n(109)},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}function a(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}function o(t){return(0,s.default)(t)?t:new Date}Object.defineProperty(e,\"__esModule\",{value:!0});var u=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=n(61),s=r(i),l=n(144),c=r(l),f=n(152),d=r(f),p=n(140),v=r(p),g=n(139),h=r(g),m=n(57),y=r(m),b=n(155),_=r(b),x=n(149),M=r(x),D=n(106),w=r(D),S=n(101),O=r(S),C=n(102),P=r(C),j=new Date(-864e13),N=new Date(864e13),T=[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],k=function(){function t(e,n,r){a(this,t),this.minDate=n||j,this.maxDate=r||N,this.startDate=e||new Date,this.generate()}return u(t,[{key:\"generate\",value:function(){var t=(0,d.default)(this.startDate),e=(0,v.default)(this.startDate),n=(0,h.default)(t,e);return this.weeks=(0,w.default)(n,function(t){var e=t.getDay()+1,n=t.getDate(),r=(13-e+n)/7;return Math.floor(r)}),this.weeks}},{key:\"previousMonth\",value:function(){return this.startDate=(0,_.default)(this.startDate,1),this.generate()}},{key:\"nextMonth\",value:function(){return this.startDate=(0,y.default)(this.startDate,1),this.generate()}},{key:\"goToMonth\",value:function(t){return this.startDate=(0,M.default)(this.startDate,t),this.generate()}},{key:\"weekdays\",get:function(){return T}},{key:\"minDate\",get:function(){return this._minDate},set:function(t){this._minDate=o(t)}},{key:\"maxDate\",get:function(){return this._maxDate},set:function(t){this._maxDate=o(t)}},{key:\"startDate\",get:function(){return this._startDate},set:function(t){this._startDate=o(t),(0,c.default)(this._startDate,this._minDate,this._maxDate)||(this._startDate=this.minDate)}},{key:\"paddingStart\",get:function(){var t=(0,O.default)(this.weeks);return(0,O.default)(t).getDay()}},{key:\"paddingEnd\",get:function(){var t=this.weeks,e=(0,P.default)(t);return 6-(0,P.default)(e).getDay()}}]),t}();e.default=k},function(t,e,n){\"use strict\";function r(t){if(t.length&&!(t.length<1))return t[0]}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r},function(t,e,n){\"use strict\";function r(t){if(t.length&&!(t.length<1))return t[t.length-1]}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}function a(t,e,n){var r=n(e);return!isNaN(r)&&Math.max(t,r)}function o(t,e){e=e||function(t){return t};var n=e.call(t,t[0]),r=(0,l.default)(n);return(0,i.default)(t,function(t,n,o){return a(t,e.call(o,n),r)},-1/0)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=o;var u=n(13),i=r(u),s=n(37),l=r(s)},function(t,e,n){\"use strict\";function r(t,e){return e.call(this,t)}function a(t,e){var n=(0,u.default)(t,e),a=n.length,o=Math.floor(a/2),i=r(n[o],e);return a%2?i:(i+r(n[o-1],e))/2}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=a;var o=n(41),u=function(t){return t&&t.__esModule?t:{default:t}}(o)},function(t,e,n){\"use strict\";function r(t){return t&&t.__esModule?t:{default:t}}function a(t,e,n){var r=n(e);return!isNaN(r)&&Math.min(t,r)}function o(t,e){e=e||function(t){return t};var n=e.call(t,t[0]),r=(0,l.default)(n);return(0,i.default)(t,function(t,n,o){return a(t,e.call(o,n),r)},1/0)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=o;var u=n(13),i=r(u),s=n(37),l=r(s)},function(t,e,n){\"use strict\";function r(t,e){var n=(0,o.default)(t,e),r=[];for(var a in n)r.push(n[a]);return r}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(40),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){\"use strict\";function r(t,e){for(var n=[],r=0,a=t.length;r<a;){var o=r+e;a-r<e&&(o=r+(a-r));var u=t.slice(r,o);n.push(u),r+=e}return n}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r},function(t,e,n){\"use strict\";function r(t,e){var n=(0,o.default)(t,e);return!!n&&Math.sqrt(n)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.default=r;var a=n(43),o=function(t){return t&&t.__esModule?t:{default:t}}(a)},function(t,e,n){n(130),t.exports=n(9).Array.find},function(t,e,n){n(134),n(132),n(135),n(136),t.exports=n(9).Symbol},function(t,e,n){n(133),n(137),t.exports=n(33).f(\"iterator\")},function(t,e){t.exports=function(t){if(\"function\"!=typeof t)throw TypeError(t+\" is not a function!\");return t}},function(t,e,n){var r=n(6),a=n(55),o=n(129);t.exports=function(t){return function(e,n,u){var i,s=r(e),l=a(s.length),c=o(u,l);if(t&&n!=n){for(;l>c;)if((i=s[c++])!=i)return!0}else for(;l>c;c++)if((t||c in s)&&s[c]===n)return t||c||0;return!t&&-1}}},function(t,e,n){var r=n(45),a=n(48),o=n(56),u=n(55),i=n(116);t.exports=function(t,e){var n=1==t,s=2==t,l=3==t,c=4==t,f=6==t,d=5==t||f,p=e||i;return function(e,i,v){for(var g,h,m=o(e),y=a(m),b=r(i,v,3),_=u(y.length),x=0,M=n?p(e,_):s?p(e,0):void 0;_>x;x++)if((d||x in y)&&(g=y[x],h=b(g,x,m),t))if(n)M[x]=h;else if(h)switch(t){case 3:return!0;case 5:return g;case 6:return x;case 2:M.push(g)}else if(c)return!1;return f?-1:l||c?c:M}}},function(t,e,n){var r=n(10),a=n(49),o=n(2)(\"species\");t.exports=function(t){var e;return a(t)&&(e=t.constructor,\"function\"!=typeof e||e!==Array&&!a(e.prototype)||(e=void 0),r(e)&&null===(e=e[o])&&(e=void 0)),void 0===e?Array:e}},function(t,e,n){var r=n(115);t.exports=function(t,e){return new(r(t))(e)}},function(t,e,n){var r=n(20),a=n(2)(\"toStringTag\"),o=\"Arguments\"==r(function(){return arguments}()),u=function(t,e){try{return t[e]}catch(t){}};t.exports=function(t){var e,n,i;return void 0===t?\"Undefined\":null===t?\"Null\":\"string\"==typeof(n=u(e=Object(t),a))?n:o?r(e):\"Object\"==(i=r(e))&&\"function\"==typeof e.callee?\"Arguments\":i}},function(t,e,n){var r=n(16),a=n(53),o=n(26);t.exports=function(t){var e=r(t),n=a.f;if(n)for(var u,i=n(t),s=o.f,l=0;i.length>l;)s.call(t,u=i[l++])&&e.push(u);return e}},function(t,e,n){t.exports=n(3).document&&document.documentElement},function(t,e,n){\"use strict\";var r=n(51),a=n(17),o=n(27),u={};n(5)(u,n(2)(\"iterator\"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(u,{next:a(1,n)}),o(t,e+\" Iterator\")}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){var r=n(16),a=n(6);t.exports=function(t,e){for(var n,o=a(t),u=r(o),i=u.length,s=0;i>s;)if(o[n=u[s++]]===e)return n}},function(t,e,n){var r=n(12)(\"meta\"),a=n(10),o=n(4),u=n(8).f,i=0,s=Object.isExtensible||function(){return!0},l=!n(15)(function(){return s(Object.preventExtensions({}))}),c=function(t){u(t,r,{value:{i:\"O\"+ ++i,w:{}}})},f=function(t,e){if(!a(t))return\"symbol\"==typeof t?t:(\"string\"==typeof t?\"S\":\"P\")+t;if(!o(t,r)){if(!s(t))return\"F\";if(!e)return\"E\";c(t)}return t[r].i},d=function(t,e){if(!o(t,r)){if(!s(t))return!0;if(!e)return!1;c(t)}return t[r].w},p=function(t){return l&&v.NEED&&s(t)&&!o(t,r)&&c(t),t},v=t.exports={KEY:r,NEED:!1,fastKey:f,getWeak:d,onFreeze:p}},function(t,e,n){var r=n(8),a=n(14),o=n(16);t.exports=n(7)?Object.defineProperties:function(t,e){a(t);for(var n,u=o(e),i=u.length,s=0;i>s;)r.f(t,n=u[s++],e[n]);return t}},function(t,e,n){var r=n(26),a=n(17),o=n(6),u=n(31),i=n(4),s=n(47),l=Object.getOwnPropertyDescriptor;e.f=n(7)?l:function(t,e){if(t=o(t),e=u(e,!0),s)try{return l(t,e)}catch(t){}if(i(t,e))return a(!r.f.call(t,e),t[e])}},function(t,e,n){var r=n(6),a=n(52).f,o={}.toString,u=\"object\"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],i=function(t){try{return a(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&\"[object Window]\"==o.call(t)?i(t):a(r(t))}},function(t,e,n){var r=n(4),a=n(56),o=n(28)(\"IE_PROTO\"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=a(t),r(t,o)?t[o]:\"function\"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,e,n){var r=n(30),a=n(21);t.exports=function(t){return function(e,n){var o,u,i=String(a(e)),s=r(n),l=i.length;return s<0||s>=l?t?\"\":void 0:(o=i.charCodeAt(s),o<55296||o>56319||s+1===l||(u=i.charCodeAt(s+1))<56320||u>57343?t?i.charAt(s):o:t?i.slice(s,s+2):u-56320+(o-55296<<10)+65536)}}},function(t,e,n){var r=n(30),a=Math.max,o=Math.min;t.exports=function(t,e){return t=r(t),t<0?a(t+e,0):o(t,e)}},function(t,e,n){\"use strict\";var r=n(23),a=n(114)(5),o=!0;\"find\"in[]&&Array(1).find(function(){o=!1}),r(r.P+r.F*o,\"Array\",{find:function(t){return a(this,t,arguments.length>1?arguments[1]:void 0)}}),n(44)(\"find\")},function(t,e,n){\"use strict\";var r=n(44),a=n(121),o=n(24),u=n(6);t.exports=n(50)(Array,\"Array\",function(t,e){this._t=u(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,a(1)):\"keys\"==e?a(0,n):\"values\"==e?a(0,t[n]):a(0,[n,t[n]])},\"values\"),o.Arguments=o.Array,r(\"keys\"),r(\"values\"),r(\"entries\")},function(t,e,n){\"use strict\";var r=n(117),a={};a[n(2)(\"toStringTag\")]=\"z\",a+\"\"!=\"[object z]\"&&n(11)(Object.prototype,\"toString\",function(){return\"[object \"+r(this)+\"]\"},!0)},function(t,e,n){\"use strict\";var r=n(128)(!0);n(50)(String,\"String\",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){\"use strict\";var r=n(3),a=n(4),o=n(7),u=n(23),i=n(11),s=n(123).KEY,l=n(15),c=n(29),f=n(27),d=n(12),p=n(2),v=n(33),g=n(32),h=n(122),m=n(118),y=n(49),b=n(14),_=n(6),x=n(31),M=n(17),D=n(51),w=n(126),S=n(125),O=n(8),C=n(16),P=S.f,j=O.f,N=w.f,T=r.Symbol,k=r.JSON,F=k&&k.stringify,$=p(\"_hidden\"),A=p(\"toPrimitive\"),E={}.propertyIsEnumerable,Y=c(\"symbol-registry\"),R=c(\"symbols\"),I=c(\"op-symbols\"),B=Object.prototype,H=\"function\"==typeof T,L=r.QObject,G=!L||!L.prototype||!L.prototype.findChild,z=o&&l(function(){return 7!=D(j({},\"a\",{get:function(){return j(this,\"a\",{value:7}).a}})).a})?function(t,e,n){var r=P(B,e);r&&delete B[e],j(t,e,n),r&&t!==B&&j(B,e,r)}:j,K=function(t){var e=R[t]=D(T.prototype);return e._k=t,e},W=H&&\"symbol\"==typeof T.iterator?function(t){return\"symbol\"==typeof t}:function(t){return t instanceof T},U=function(t,e,n){return t===B&&U(I,e,n),b(t),e=x(e,!0),b(n),a(R,e)?(n.enumerable?(a(t,$)&&t[$][e]&&(t[$][e]=!1),n=D(n,{enumerable:M(0,!1)})):(a(t,$)||j(t,$,M(1,{})),t[$][e]=!0),z(t,e,n)):j(t,e,n)},Z=function(t,e){b(t);for(var n,r=m(e=_(e)),a=0,o=r.length;o>a;)U(t,n=r[a++],e[n]);return t},V=function(t,e){return void 0===e?D(t):Z(D(t),e)},J=function(t){var e=E.call(this,t=x(t,!0));return!(this===B&&a(R,t)&&!a(I,t))&&(!(e||!a(this,t)||!a(R,t)||a(this,$)&&this[$][t])||e)},X=function(t,e){if(t=_(t),e=x(e,!0),t!==B||!a(R,e)||a(I,e)){var n=P(t,e);return!n||!a(R,e)||a(t,$)&&t[$][e]||(n.enumerable=!0),n}},q=function(t){for(var e,n=N(_(t)),r=[],o=0;n.length>o;)a(R,e=n[o++])||e==$||e==s||r.push(e);return r},Q=function(t){for(var e,n=t===B,r=N(n?I:_(t)),o=[],u=0;r.length>u;)!a(R,e=r[u++])||n&&!a(B,e)||o.push(R[e]);return o};H||(T=function(){if(this instanceof T)throw TypeError(\"Symbol is not a constructor!\");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===B&&e.call(I,n),a(this,$)&&a(this[$],t)&&(this[$][t]=!1),z(this,t,M(1,n))};return o&&G&&z(B,t,{configurable:!0,set:e}),K(t)},i(T.prototype,\"toString\",function(){return this._k}),S.f=X,O.f=U,n(52).f=w.f=q,n(26).f=J,n(53).f=Q,o&&!n(25)&&i(B,\"propertyIsEnumerable\",J,!0),v.f=function(t){return K(p(t))}),u(u.G+u.W+u.F*!H,{Symbol:T});for(var tt=\"hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables\".split(\",\"),et=0;tt.length>et;)p(tt[et++]);for(var tt=C(p.store),et=0;tt.length>et;)g(tt[et++]);u(u.S+u.F*!H,\"Symbol\",{for:function(t){return a(Y,t+=\"\")?Y[t]:Y[t]=T(t)},keyFor:function(t){if(W(t))return h(Y,t);throw TypeError(t+\" is not a symbol!\")},useSetter:function(){G=!0},useSimple:function(){G=!1}}),u(u.S+u.F*!H,\"Object\",{create:V,defineProperty:U,defineProperties:Z,getOwnPropertyDescriptor:X,getOwnPropertyNames:q,getOwnPropertySymbols:Q}),k&&u(u.S+u.F*(!H||l(function(){var t=T();return\"[null]\"!=F([t])||\"{}\"!=F({a:t})||\"{}\"!=F(Object(t))})),\"JSON\",{stringify:function(t){if(void 0!==t&&!W(t)){for(var e,n,r=[t],a=1;arguments.length>a;)r.push(arguments[a++]);return e=r[1],\"function\"==typeof e&&(n=e),!n&&y(e)||(e=function(t,e){if(n&&(e=n.call(this,t,e)),!W(e))return e}),r[1]=e,F.apply(k,r)}}}),T.prototype[A]||n(5)(T.prototype,A,T.prototype.valueOf),f(T,\"Symbol\"),f(Math,\"Math\",!0),f(r.JSON,\"JSON\",!0)},function(t,e,n){n(32)(\"asyncIterator\")},function(t,e,n){n(32)(\"observable\")},function(t,e,n){for(var r=n(131),a=n(11),o=n(3),u=n(5),i=n(24),s=n(2),l=s(\"iterator\"),c=s(\"toStringTag\"),f=i.Array,d=[\"NodeList\",\"DOMTokenList\",\"MediaList\",\"StyleSheetList\",\"CSSRuleList\"],p=0;p<5;p++){var v,g=d[p],h=o[g],m=h&&h.prototype;if(m){m[l]||u(m,l,f),m[c]||u(m,c,g),i[g]=f;for(v in r)m[v]||a(m,v,r[v],!0)}}},function(t,e,n){function r(t,e){var n=a(t),r=a(e),i=n.getTime()-n.getTimezoneOffset()*o,s=r.getTime()-r.getTimezoneOffset()*o;return Math.round((i-s)/u)}var a=n(150),o=6e4,u=864e5;t.exports=r},function(t,e,n){function r(t,e){var n=a(t),r=a(e),o=r.getTime();if(n.getTime()>o)throw new Error(\"The first date cannot be after the second date\");var u=[],i=n;for(i.setHours(0,0,0,0);i.getTime()<=o;)u.push(a(i)),i.setDate(i.getDate()+1);return u}var a=n(1);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=e.getMonth();return e.setFullYear(e.getFullYear(),n+1,0),e.setHours(23,59,59,999),e}var a=n(1);t.exports=r},function(t,e,n){function r(t,e,n){var r=e?String(e):\"YYYY-MM-DDTHH:mm:ss.SSSZ\",o=n||{},u=o.locale,i=p.format.formatters,s=p.format.formattingTokensRegExp;u&&u.format&&u.format.formatters&&(i=u.format.formatters,u.format.formattingTokensRegExp&&(s=u.format.formattingTokensRegExp));var l=f(t);return d(l)?a(r,i,s)(l):\"Invalid Date\"}function a(t,e,n){var r,a,u=t.match(n),i=u.length;for(r=0;r<i;r++)a=e[u[r]]||v[u[r]],u[r]=a||o(u[r]);return function(t){for(var e=\"\",n=0;n<i;n++)u[n]instanceof Function?e+=u[n](t,v):e+=u[n];return e}}function o(t){return t.match(/\\[[\\s\\S]/)?t.replace(/^\\[|]$/g,\"\"):t.replace(/\\\\/g,\"\")}function u(t,e){e=e||\"\";var n=t>0?\"-\":\"+\",r=Math.abs(t),a=Math.floor(r/60),o=r%60;return n+i(a,2)+e+i(o,2)}function i(t,e){for(var n=Math.abs(t).toString();n.length<e;)n=\"0\"+n;return n}var s=n(142),l=n(143),c=n(59),f=n(1),d=n(61),p=n(148),v={M:function(t){return t.getMonth()+1},MM:function(t){return i(t.getMonth()+1,2)},Q:function(t){return Math.ceil((t.getMonth()+1)/3)},D:function(t){return t.getDate()},DD:function(t){return i(t.getDate(),2)},DDD:function(t){return s(t)},DDDD:function(t){return i(s(t),3)},d:function(t){return t.getDay()},E:function(t){return t.getDay()||7},W:function(t){return l(t)},WW:function(t){return i(l(t),2)},YY:function(t){return i(t.getFullYear(),4).substr(2)},YYYY:function(t){return i(t.getFullYear(),4)},GG:function(t){return String(c(t)).substr(2)},GGGG:function(t){return c(t)},H:function(t){return t.getHours()},HH:function(t){return i(t.getHours(),2)},h:function(t){var e=t.getHours();return 0===e?12:e>12?e%12:e},hh:function(t){return i(v.h(t),2)},m:function(t){return t.getMinutes()},mm:function(t){return i(t.getMinutes(),2)},s:function(t){return t.getSeconds()},ss:function(t){return i(t.getSeconds(),2)},S:function(t){return Math.floor(t.getMilliseconds()/100)},SS:function(t){return i(Math.floor(t.getMilliseconds()/10),2)},SSS:function(t){return i(t.getMilliseconds(),3)},Z:function(t){return u(t.getTimezoneOffset(),\":\")},ZZ:function(t){return u(t.getTimezoneOffset())},X:function(t){return Math.floor(t.getTime()/1e3)},x:function(t){return t.getTime()}};t.exports=r},function(t,e,n){function r(t){var e=a(t);return u(e,o(e))+1}var a=n(1),o=n(154),u=n(138);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=o(e).getTime()-u(e).getTime();return Math.round(n/i)+1}var a=n(1),o=n(34),u=n(151),i=6048e5;t.exports=r},function(t,e,n){function r(t,e,n){var r=a(t).getTime(),o=a(e).getTime(),u=a(n).getTime();if(o>u)throw new Error(\"The start of the range cannot be after the end of the range\");return r>=o&&r<=u}var a=n(1);t.exports=r},function(t,e){function n(t){var e=[];for(var n in t)t.hasOwnProperty(n)&&e.push(n);var a=r.concat(e).sort().reverse();return new RegExp(\"(\\\\[[^\\\\[]*\\\\])|(\\\\\\\\)?(\"+a.join(\"|\")+\"|.)\",\"g\")}var r=[\"M\",\"MM\",\"Q\",\"D\",\"DD\",\"DDD\",\"DDDD\",\"d\",\"E\",\"W\",\"WW\",\"YY\",\"YYYY\",\"GG\",\"GGGG\",\"H\",\"HH\",\"h\",\"hh\",\"m\",\"mm\",\"s\",\"ss\",\"S\",\"SS\",\"SSS\",\"Z\",\"ZZ\",\"X\",\"x\"];t.exports=n},function(t,e){function n(){function t(t,n,r){r=r||{};var a;return a=\"string\"==typeof e[t]?e[t]:1===n?e[t].one:e[t].other.replace(\"{{count}}\",n),r.addSuffix?r.comparison>0?\"in \"+a:a+\" ago\":a}var e={lessThanXSeconds:{one:\"less than a second\",other:\"less than {{count}} seconds\"},xSeconds:{one:\"1 second\",other:\"{{count}} seconds\"},halfAMinute:\"half a minute\",lessThanXMinutes:{one:\"less than a minute\",other:\"less than {{count}} minutes\"},xMinutes:{one:\"1 minute\",other:\"{{count}} minutes\"},aboutXHours:{one:\"about 1 hour\",other:\"about {{count}} hours\"},xHours:{one:\"1 hour\",other:\"{{count}} hours\"},xDays:{one:\"1 day\",other:\"{{count}} days\"},aboutXMonths:{one:\"about 1 month\",other:\"about {{count}} months\"},xMonths:{one:\"1 month\",other:\"{{count}} months\"},aboutXYears:{one:\"about 1 year\",other:\"about {{count}} years\"},xYears:{one:\"1 year\",other:\"{{count}} years\"},overXYears:{one:\"over 1 year\",other:\"over {{count}} years\"},almostXYears:{one:\"almost 1 year\",other:\"almost {{count}} years\"}};return{localize:t}}t.exports=n},function(t,e,n){function r(){var t=[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],e=[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],n=[\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"],r=[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],u=[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],i=[\"AM\",\"PM\"],s=[\"am\",\"pm\"],l=[\"a.m.\",\"p.m.\"],c={MMM:function(e){return t[e.getMonth()]},MMMM:function(t){return e[t.getMonth()]},dd:function(t){return n[t.getDay()]},ddd:function(t){return r[t.getDay()]},dddd:function(t){return u[t.getDay()]},A:function(t){return t.getHours()/12>=1?i[1]:i[0]},a:function(t){return t.getHours()/12>=1?s[1]:s[0]},aa:function(t){return t.getHours()/12>=1?l[1]:l[0]}};return[\"M\",\"D\",\"DDD\",\"d\",\"Q\",\"W\"].forEach(function(t){c[t+\"o\"]=function(e,n){return a(n[t](e))}}),{formatters:c,formattingTokensRegExp:o(c)}}function a(t){var e=t%100;if(e>20||e<10)switch(e%10){case 1:return t+\"st\";case 2:return t+\"nd\";case 3:return t+\"rd\"}return t+\"th\"}var o=n(145);t.exports=r},function(t,e,n){var r=n(146),a=n(147);t.exports={distanceInWords:r(),format:a()}},function(t,e,n){function r(t,e){var n=a(t),r=Number(e),u=n.getFullYear(),i=n.getDate(),s=new Date(0);s.setFullYear(u,r,15),s.setHours(0,0,0,0);var l=o(s);return n.setMonth(r,Math.min(i,l)),n}var a=n(1),o=n(58);t.exports=r},function(t,e,n){function r(t){var e=a(t);return e.setHours(0,0,0,0),e}var a=n(1);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=new Date(0);return n.setFullYear(e,0,4),n.setHours(0,0,0,0),o(n)}var a=n(59),o=n(34);t.exports=r},function(t,e,n){function r(t){var e=a(t);return e.setDate(1),e.setHours(0,0,0,0),e}var a=n(1);t.exports=r},function(t,e,n){function r(t,e){var n=e?Number(e.weekStartsOn)||0:0,r=a(t),o=r.getDay(),u=(o<n?7:0)+o-n;return r.setDate(r.getDate()-u),r.setHours(0,0,0,0),r}var a=n(1);t.exports=r},function(t,e,n){function r(t){var e=a(t),n=new Date(0);return n.setFullYear(e.getFullYear(),0,1),n.setHours(0,0,0,0),n}var a=n(1);t.exports=r},function(t,e,n){function r(t,e){var n=Number(e);return a(t,-n)}var a=n(57);t.exports=r},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e){},function(t,e,n){var r=n(0)(n(65),n(191),null,null);t.exports=r.exports},function(t,e,n){n(161);var r=n(0)(n(66),n(188),null,null);t.exports=r.exports},function(t,e,n){var r=n(0)(n(67),n(190),null,null);t.exports=r.exports},function(t,e,n){n(164);var r=n(0)(n(68),n(193),null,null);t.exports=r.exports},function(t,e,n){n(160);var r=n(0)(n(69),n(187),null,null);t.exports=r.exports},function(t,e,n){var r=n(0)(n(70),n(199),null,null);t.exports=r.exports},function(t,e,n){n(167);var r=n(0)(n(71),n(196),null,null);t.exports=r.exports},function(t,e,n){n(166);var r=n(0)(n(72),n(195),null,null);t.exports=r.exports},function(t,e,n){n(168);var r=n(0)(n(73),n(197),null,null);t.exports=r.exports},function(t,e,n){n(159);var r=n(0)(n(74),n(186),null,null);t.exports=r.exports},function(t,e,n){n(162);var r=n(0)(n(75),n(189),null,null);t.exports=r.exports},function(t,e,n){n(169);var r=n(0)(n(76),n(198),null,null);t.exports=r.exports},function(t,e,n){n(165);var r=n(0)(n(77),n(194),null,null);t.exports=r.exports},function(t,e,n){n(158);var r=n(0)(n(78),n(185),null,null);t.exports=r.exports},function(t,e,n){n(163);var r=n(0)(n(79),n(192),null,null);t.exports=r.exports},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"radio\"},[n(\"input\",{directives:[{name:\"model\",rawName:\"v-model\",value:t.checked,expression:\"checked\"}],attrs:{type:\"radio\",id:t.id,name:t.id,disabled:t.disabled},domProps:{value:t.value,checked:t._q(t.checked,t.value)},on:{__c:function(e){t.checked=t.value}}}),t._v(\" \"),n(\"label\",{attrs:{for:t.id}}),t._v(\" \"),t._t(\"default\")],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"panel\"},[n(\"div\",{staticClass:\"panel-header\"},[n(\"div\",{attrs:{layout:\"row center-justify\"}},[n(\"span\",{staticClass:\"panel-title\",attrs:{self:\"size-x1\"}},[t._v(t._s(t.title))]),t._v(\" \"),n(\"div\",[t._t(\"panel-header\")],2)])]),t._v(\" \"),n(\"div\",{staticClass:\"panel-body\"},[t._t(\"default\")],2),t._v(\" \"),t.$slots.panelFooter?n(\"div\",{staticClass:\"panel-footer\"},[t._t(\"panel-footer\")],2):t._e()])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"datatable table-wrapper\",class:t.tableClasses},[n(\"table\",[n(\"thead\",{staticClass:\"datatable-columns\"},[n(\"tr\",[t.lineNumbers?n(\"th\",{style:{width:t.lineColumnWidth}},[n(\"div\",{staticClass:\"datatable-column datatable-linenumber-column\"},[t._v(\"#\")])]):t._e(),t._v(\" \"),t.aggregated?n(\"th\",[n(\"div\",{staticClass:\"datatable-column datatable-aggregate-column\"},[t._v(\"Aggregate\")])]):t._e(),t._v(\" \"),t._t(\"default\")],2)]),t._v(\" \"),t.groupingColumnIds.length>0?n(\"tbody\",{staticClass:\"datatable-groups\"},[n(\"tr\",[n(\"td\",{staticClass:\"datatable-groups-header\",attrs:{colspan:t.columnSpan}},t._l(t.groupingColumns,function(e,r){return n(\"chip\",{key:e.id,staticClass:\"datatable-group-chip\",on:{remove:function(n){t.degroupColumn(e)}}},[n(\"div\",[n(\"small\",[n(\"strong\",[t._v(t._s(0==r?\"Grouping By:\":\"Then:\"))])])]),t._v(\" \"),n(\"div\",[t._v(t._s(e.label))])])}))])]):t._e(),t._v(\" \"),n(\"tbody\",{directives:[{name:\"drag\",rawName:\"v-drag:enter\",value:t.dragEnter,expression:\"dragEnter\",arg:\"enter\"},{name:\"drag\",rawName:\"v-drag:leave\",value:t.dragLeave,expression:\"dragLeave\",arg:\"leave\"},{name:\"drag\",rawName:\"v-drag:over\",value:t.dragOver,expression:\"dragOver\",arg:\"over\"},{name:\"drag\",rawName:\"v-drag:drop\",value:t.dragDrop,expression:\"dragDrop\",arg:\"drop\"}],staticClass:\"datatable-collections\"},[n(\"tr\",[n(\"td\",{staticClass:\"datatable-group\",attrs:{colspan:t.columnSpan}},[n(\"datatable-collection\",{attrs:{rows:t.rows,columns:t.columns,striped:t.striped,editable:t.editable,\"line-numbers\":t.lineNumbers,aggregated:t.aggregated,\"grouping-columns\":t.groupingColumnIds,margin:t.lineColumnWidth,message:t.message}})],1)])]),t._v(\" \"),t.aggregated?n(\"tfoot\",{staticClass:\"datatable-aggregators\"},[n(\"tr\",[n(\"td\",{staticClass:\"datatable-info-cell\",attrs:{colspan:t.columnSpan}},[t._v(\" \")])]),t._v(\" \"),t._l(t.aggregators,function(e,r){return n(\"tr\",{key:e.label},[t.lineNumbers?n(\"td\",{staticClass:\"datatable-linenumber-cell\"},[t._v(t._s(r+1))]):t._e(),t._v(\" \"),t.aggregated?n(\"td\",{staticClass:\"datatable-aggregate-cell\"},[t._v(t._s(e.label))]):t._e(),t._v(\" \"),t._l(t.columns,function(r){return n(\"td\",{style:r.columnStyles},[t._v(t._s(t.aggregate(r,e)))])})],2)})],2):t._e()],1),t._v(\" \"),t.filterable?n(\"div\",{staticClass:\"datatable-options\",attrs:{layout:\"row center-justify\"}},[t.optimize?n(\"input\",{directives:[{name:\"model\",rawName:\"v-model.lazy\",value:t.filter,expression:\"filter\",modifiers:{lazy:!0}}],attrs:{type:\"text\",placeholder:\"Filter this dataset. Press enter to search...\",self:\"size-x1\"},domProps:{value:t.filter},on:{change:function(e){t.filter=e.target.value}}}):n(\"input\",{directives:[{name:\"model\",rawName:\"v-model\",value:t.filter,expression:\"filter\"}],attrs:{type:\"text\",placeholder:\"Filter this dataset...\",self:\"size-x1\"},domProps:{value:t.filter},on:{input:function(e){e.target.composing||(t.filter=e.target.value)}}})]):t._e()])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"chip\"},[n(\"div\",{attrs:{layout:\"row stretch-justify\"}},[n(\"div\",{staticClass:\"chip-body\"},[t._t(\"default\")],2),t._v(\" \"),t.removable?n(\"div\",{staticClass:\"chip-footer\",attrs:{layout:\"row center-center\"}},[n(\"div\",{staticClass:\"chip-close-button\",attrs:{title:\"Click to remove\"},on:{click:t.remove}})]):t._e()])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"tab-control\"},[n(\"div\",{staticClass:\"tabs-list\",attrs:{layout:\"row center-justify\"}},[n(\"div\",{attrs:{self:\"size-x1\",layout:\"row center-left\"}},t._l(t.tabs,function(e){return n(\"div\",{staticClass:\"tab-item\",class:{active:e.selected},on:{click:function(n){t.selectTab(e)}}},[t._t(e.id,[n(\"span\",[t._v(t._s(e.label))])],{value:e})],2)})),t._v(\" \"),n(\"div\",[t._t(\"tabs-extra\")],2)]),t._v(\" \"),t._t(\"default\")],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"datatable-collection\"},[t.groupable?n(\"table\",{class:{\"table-striped\":t.striped}},t._l(t.groups,function(e,r,a){return n(\"tr\",[n(\"td\",{staticClass:\"datatable-group\",attrs:{colspan:t.columnSpan}},[n(\"div\",{staticClass:\"datatable-group-header\",attrs:{layout:\"row center-justify\"}},[n(\"div\",{attrs:{self:\"size-x1\"}},[n(\"span\",{staticClass:\"datatable-group-label\",style:t.indentStyle},[t._v(t._s(t.groupingColumn.formatData(r)))])]),t._v(\" \"),e.length>1?n(\"span\",{staticClass:\"label label-primary datatable-row-count\"},[t._v(t._s(e.length))]):t._e()]),t._v(\" \"),n(\"datatable-collection\",{attrs:{rows:e,columns:t.columns,striped:t.striped,editable:t.editable,\"line-numbers\":t.lineNumbers,aggregated:t.aggregated,margin:t.margin,\"grouping-columns\":t.groupingColumns,\"grouping-index\":t.groupingIndex+1,\"collection-index\":t.collectionIndex*a,optimize:t.optimize,message:t.message}})],1)])})):n(\"table\",{staticClass:\"datatable-resultset\",class:{\"table-striped\":t.striped}},[t.rows.length<1?n(\"tr\",[n(\"td\",{staticClass:\"datatable-info-cell\",attrs:{colspan:t.columnSpan}},[t._v(t._s(t.message))])]):t._e(),t._v(\" \"),t._l(t.rows,function(e,r){return n(\"tr\",[t.lineNumbers?n(\"td\",{staticClass:\"datatable-cell datatable-linenumber-cell\",style:{width:t.margin}},[t._v(t._s(t.collectionIndex+r+1))]):t._e(),t._v(\" \"),t.aggregated?n(\"td\",{staticClass:\"datatable-cell datatable-aggregate-cell\"},[t._v(\" \")]):t._e(),t._v(\" \"),t._l(t.columns,function(r){return n(\"datatable-cell\",{key:r.id,attrs:{column:r,row:e,editable:t.editable,optimize:t.optimize}})})],2)})],2)])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"calendar table-wrapper\"},[n(\"div\",{staticClass:\"calendar-header\",attrs:{layout:\"row center-justify\"}},[n(\"button\",{staticClass:\"button\",on:{click:t.previous}},[t._v(\"Previous\")]),t._v(\" \"),n(\"div\",{staticClass:\"calendar-month-name\"},[t._v(t._s(t._f(\"date\")(t.calendar.startDate,\"MMMM YYYY\")))]),t._v(\" \"),n(\"button\",{staticClass:\"button\",on:{click:t.next}},[t._v(\"Next\")])]),t._v(\" \"),n(\"table\",[n(\"thead\",[n(\"tr\",t._l(t.calendar.weekdays,function(e){return n(\"td\",[t._v(t._s(e))])}))]),t._v(\" \"),n(\"tbody\",t._l(t.calendar.weeks,function(e,r){return n(\"tr\",{staticClass:\"calendar-week\"},[0==r?t._l(t.calendar.paddingStart,function(t){return n(\"td\",{staticClass:\"calendar-day\"})}):t._e(),t._v(\" \"),t._l(e,function(e){return n(\"td\",{staticClass:\"calendar-day\"},[n(\"div\",[t._v(t._s(e.getDate()))])])}),t._v(\" \"),r+1==t.calendar.weeks.length?t._l(t.calendar.paddingEnd,function(t){return n(\"td\",{staticClass:\"calendar-day\"})}):t._e()],2)}))])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"toggle\"},[n(\"input\",{directives:[{name:\"model\",rawName:\"v-model\",value:t.checked,expression:\"checked\"}],attrs:{type:\"checkbox\",id:t.id,name:t.id,disabled:t.disabled},domProps:{value:t.value,checked:Array.isArray(t.checked)?t._i(t.checked,t.value)>-1:t.checked},on:{__c:function(e){var n=t.checked,r=e.target,a=!!r.checked;if(Array.isArray(n)){var o=t.value,u=t._i(n,o);a?u<0&&(t.checked=n.concat(o)):u>-1&&(t.checked=n.slice(0,u).concat(n.slice(u+1)))}else t.checked=a}}}),t._v(\" \"),n(\"label\",{attrs:{for:t.id}}),t._v(\" \"),t._t(\"default\")],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"th\",{directives:[{name:\"drag\",rawName:\"v-drag:start\",value:t.dragStart,expression:\"dragStart\",arg:\"start\"}],style:t.columnStyles,attrs:{title:\"Click to sort. Drag to center to group.\"},on:{click:t.sort}},[n(\"div\",{staticClass:\"datatable-column\",attrs:{layout:t.columnLayout}},[n(\"div\",[t._t(\"default\",[t._v(t._s(t.label||t.id))])],2),t._v(\" \"),n(\"div\",{directives:[{name:\"show\",rawName:\"v-show\",value:t.sorting,expression:\"sorting\"}],staticClass:\"datatable-sort-arrow\",class:t.sortArrowClass})])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"checkbox\"},[n(\"input\",{directives:[{name:\"model\",rawName:\"v-model\",value:t.checked,expression:\"checked\"}],attrs:{type:\"checkbox\",id:t.id,name:t.id,disabled:t.disabled},domProps:{value:t.value,checked:Array.isArray(t.checked)?t._i(t.checked,t.value)>-1:t.checked},on:{__c:function(e){var n=t.checked,r=e.target,a=!!r.checked;if(Array.isArray(n)){var o=t.value,u=t._i(n,o);a?u<0&&(t.checked=n.concat(o)):u>-1&&(t.checked=n.slice(0,u).concat(n.slice(u+1)))}else t.checked=a}}}),t._v(\" \"),n(\"label\",{attrs:{for:t.id}}),t._v(\" \"),t._t(\"default\")],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"transition\",{attrs:{name:\"modal-transition\"}},[n(\"div\",{directives:[{name:\"show\",rawName:\"v-show\",value:t.showing,expression:\"showing\"}],staticClass:\"modal-shade\",attrs:{layout:\"row center-center\"}},[n(\"div\",{staticClass:\"modal\"},[n(\"div\",{staticClass:\"modal-header\"},[n(\"div\",{attrs:{layout:\"row center-justify\"}},[n(\"span\",{staticClass:\"modal-title\",attrs:{self:\"size-x1\"}},[t._v(t._s(t.title))]),t._v(\" \"),n(\"div\",[t._t(\"modal-header\"),t._v(\" \"),n(\"div\",{staticClass:\"modal-close-button\"})],2)])]),t._v(\" \"),n(\"div\",{staticClass:\"modal-body\"},[t._t(\"default\")],2),t._v(\" \"),n(\"div\",{staticClass:\"modal-footer\"},[t._t(\"modal-footer\")],2)])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"float\"},[t._t(\"host\"),t._v(\" \"),n(\"transition\",{attrs:{name:\"float\"}},[n(\"div\",{directives:[{name:\"show\",rawName:\"v-show\",value:t.visible,expression:\"visible\"}],staticClass:\"float-panel\"},[t._t(\"content\")],2)])],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"div\",{staticClass:\"paginator\"},[n(\"div\",{staticClass:\"paginator-body\"},[t._t(\"default\",null,{data:t.data,pageNumber:t.pageNumber})],2),t._v(\" \"),n(\"div\",{staticClass:\"paginator-footer\",attrs:{layout:\"row center-justify\"}},[n(\"div\",{staticClass:\"paginator-button paginator-page-previous\",on:{click:t.movePrevious}},[n(\"span\",[t._v(\"Prev\")])]),t._v(\" \"),n(\"div\",{staticClass:\"paginator-page-numbers\"},t._l(t.pages.length,function(e){return n(\"div\",{staticClass:\"paginator-button paginator-page-number\",class:{active:e===t.pageNumber},on:{click:function(n){t.moveTo(e)}}},[n(\"span\",[t._v(t._s(e))])])})),t._v(\" \"),n(\"div\",{staticClass:\"paginator-button paginator-page-next\",on:{click:t.moveNext}},[n(\"span\",[t._v(\"Next\")])])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.selected?n(\"div\",{staticClass:\"tab-pane\"},[t._t(\"default\")],2):t._e()},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n(\"floating-panel\",{staticClass:\"date-picker\",attrs:{visible:t.visible}},[n(\"input\",{directives:[{name:\"model\",rawName:\"v-model\",value:t.formattedValue,expression:\"formattedValue\"}],attrs:{type:\"text\",readonly:\"\"},domProps:{value:t.formattedValue},on:{focus:function(e){t.show()},input:function(e){e.target.composing||(t.formattedValue=e.target.value)}},slot:\"host\"}),t._v(\" \"),n(\"p\",{on:{click:function(e){t.updateValue(new Date)}},slot:\"content\"},[t._v(\"Hello\")])])},staticRenderFns:[]}}]);\n//# sourceMappingURL=components.bundle.js.map"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <title>Vuetiful Component Framework</title>\n    <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,700\">\n    <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/icon?family=Material+Icons\">\n    <link rel=\"stylesheet\" href=\"/dist/app.style.css\">\n    <style>\n        body {\n            overflow: hidden;\n        }\n        \n        #app {\n            width: 100%;\n            height: 100%;\n        }\n        \n        #topbar {\n            border-bottom: 1px solid #DDDDEE;\n            z-index: 1000;\n        }\n        \n        #topbar-sidebar,\n        #content-sidebar {\n            border-right: 1px solid;\n        }\n        \n        #topbar-sidebar {\n            background-color: #2196F3;\n            border-right-color: #2196F3;\n        }\n        \n        #app-title {\n            margin: 1rem 0;\n            padding: 0 2rem;\n            color: #FFFFFF;\n        }\n        \n        #content-sidebar {\n            border-right-color: #DDDDEE;\n        }\n        \n        #content-sidebar,\n        #content-page {\n            padding: 1rem;\n            overflow-y: auto;\n        }\n        \n        #content-sidebar .menu-item {}\n    </style>\n</head>\n\n<body>\n    <div id=\"app\" layout=\"column\">\n        <div id=\"topbar\" layout=\"row center-stretch\">\n            <div id=\"topbar-sidebar\" self=\"size-xxsmall\">\n                <h3 id=\"app-title\">Vuetiful</h3>\n            </div>\n            <div id=\"topbar-page\" self=\"size-x1\"></div>\n        </div>\n        <div id=\"content\" self=\"size-x1\" layout=\"row stretch-stretch\">\n            <div id=\"content-sidebar\" self=\"size-xxsmall\">\n                <div class=\"menu\">\n                    <div class=\"menu-group\">\n                        <span class=\"menu-group-title\">Components</span>\n                        <div class=\"menu-item\" v-for=\"menu in menuItems\">\n                            <router-link :to=\"menu.route\" class=\"escape-link\">{{ menu.name }}</router-link>\n                        </div>\n                    </div>\n                </div>\n            </div>\n            <div id=\"content-page\" self=\"size-x1\">\n                <div class=\"container\">\n                    <keep-alive>\n                        <router-view></router-view>\n                    </keep-alive>\n                </div>\n            </div>\n        </div>\n    </div>\n    <script src=\"/dist/app.bundle.js\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "license.txt",
    "content": "MIT License\n\nCopyright (c) 2017 Andrew Courtice\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"vuetiful\",\n  \"description\": \"Component framework written on top of the Vue reactive library\",\n  \"version\": \"0.1.0\",\n  \"author\": \"Andrew Courtice\",\n  \"repository\": \"https://github.com/andrewcourtice/vuetiful.git\",\n  \"license\": \"MIT\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"cross-env NODE_ENV=development webpack-dev-server --open --inline --hot\",\n    \"build:components\": \"cross-env NODE_ENV=production SCOPE=components webpack --progress --hide-modules\",\n    \"build:app\": \"cross-env NODE_ENV=production SCOPE=app webpack --progress --hide-modules\",\n    \"start\": \"npm run dev\",\n    \"test\": \"mocha\"\n  },\n  \"dependencies\": {\n    \"core-js\": \"^2.4.1\",\n    \"date-fns\": \"^1.28.2\",\n    \"flex-layout-attribute\": \"^1.0.3\",\n    \"vue\": \"^2.2.6\",\n    \"vue-router\": \"^2.3.1\"\n  },\n  \"devDependencies\": {\n    \"babel-core\": \"^6.24.0\",\n    \"babel-loader\": \"^6.4.1\",\n    \"babel-polyfill\": \"^6.23.0\",\n    \"babel-preset-es2015\": \"^6.24.0\",\n    \"chai\": \"^3.5.0\",\n    \"cross-env\": \"^3.0.0\",\n    \"css-loader\": \"^0.27.3\",\n    \"extract-text-webpack-plugin\": \"^2.0.0\",\n    \"file-loader\": \"^0.10.1\",\n    \"mocha\": \"^3.2.0\",\n    \"node-sass\": \"^4.5.2\",\n    \"postcss-loader\": \"^1.3.3\",\n    \"sass-loader\": \"^6.0.3\",\n    \"style-loader\": \"^0.16.1\",\n    \"vue-loader\": \"^11.3.4\",\n    \"vue-template-compiler\": \"^2.2.6\",\n    \"webpack\": \"^2.3.2\",\n    \"webpack-bundle-analyzer\": \"^2.2.0\",\n    \"webpack-dev-server\": \"^2.4.2\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "\nmodule.exports = {\n    plugins: [\n        require(\"autoprefixer\")\n    ]\n};"
  },
  {
    "path": "readme.md",
    "content": "# Vuetiful\n\nVuetiful is a component framework written on top of the Vue reactive library. It is primarily designed for creating business/administration applications where the displaying of data is paramount. Although targeted primarily at business applications, Vuetiful is extremely flexible and easily themed making it trivial to integrate into any website.\n\n**Update:** *Due to time limitations this project has been discontinued. Please feel free to use or distribute any of the code in this repo as per the license below.*\n\n## Getting started\nThis project is still very much in the early days of development so it is not currently available on npm (but will be soon). \n\nTo use the components simply download the `components.bundle.js` and `app.style.css` files from the `/dist` directory and link to them in your html.\n\nAlternatively, if you would like to see a demo of the current set of components and styles you can clone this repo and build it to see a demo application. After cloning the repo run:\n\n```bash\nnpm install\nnpm start\n```\n\nA browser window will automatically open and load the demo app.\n\n\n## License\nMIT License\n\nCopyright (c) 2017 Andrew Courtice\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "src/aggregators/aggregators.js",
    "content": "import min from \"./min\";\nimport max from \"./max\";\nimport count from \"./count\";\nimport average from \"./average\";\nimport total from \"./total\";\nimport variance from \"./variance\";\nimport standardDeviation from \"./standard-deviation\";\nimport median from \"./median\";\n\nexport default {\n    min,\n    max,\n    count,\n    average,\n    total,\n    variance,\n    standardDeviation,\n    median\n}"
  },
  {
    "path": "src/aggregators/average.js",
    "content": "import averageOf from \"../utilities/average-of\";\n\nexport default {\n    label: \"Average\",\n    callback: averageOf,\n    format: true\n}"
  },
  {
    "path": "src/aggregators/count.js",
    "content": "\nexport default {\n    label: \"Count\",\n    callback: (array) => array.length\n}"
  },
  {
    "path": "src/aggregators/max.js",
    "content": "import maxOf from \"../utilities/max-of\";\n\nexport default {\n    label: \"Maximum\",\n    callback: maxOf,\n    format: true\n}"
  },
  {
    "path": "src/aggregators/median.js",
    "content": "import medianOf from \"../utilities/median-of\";\n\nexport default {\n    label: \"Median\",\n    callback: medianOf\n}"
  },
  {
    "path": "src/aggregators/min.js",
    "content": "import minOf from \"../utilities/min-of\";\n\nexport default {\n    label: \"Minimum\",\n    callback: minOf,\n    format: true\n}"
  },
  {
    "path": "src/aggregators/standard-deviation.js",
    "content": "import standardDeviationOf from \"../utilities/standard-deviation-of\";\n\nexport default {\n    label: \"Standard Deviation\",\n    callback: standardDeviationOf\n}"
  },
  {
    "path": "src/aggregators/total.js",
    "content": "import totalOf from \"../utilities/total-of\";\n\nexport default {\n    label: \"Total\",\n    callback: totalOf,\n    format: true\n}"
  },
  {
    "path": "src/aggregators/variance.js",
    "content": "import varianceOf from \"../utilities/variance-of\";\n\nexport default {\n    label: \"Variance\",\n    callback: varianceOf\n}"
  },
  {
    "path": "src/assets/styles/abstract/_functions.scss",
    "content": "\n@function pow($base, $exponent: 2) {\n    $value: $base;\n\n    @for $i from 1 through ($exponent - 1) {\n        $value: ($value * $base);\n    }\n\n    @return $value;\n}"
  },
  {
    "path": "src/assets/styles/abstract/_mixins.scss",
    "content": "\n@mixin truncate-text {\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}"
  },
  {
    "path": "src/assets/styles/abstract/_variables.scss",
    "content": "\n$base-point-size: 8px;\n\n$typography-ratio: 1.333;\n$font-size: 16px;\n$line-height: 1.5em;\n\n$colour-font: #32394F;\n$colour-font-negative: #FFFFFF;\n$colour-background: #FFFFFF;\n$colour-background-medium: #FAFAFC;\n$colour-border: #DDDDEE;\n$colour-border-light: #EEEEEE;\n\n$colour-primary: #2196F3;\n$colour-accents: (\n    blue: #2196F3,\n    green: #00B378,\n    red: #F44336,\n    yellow: #FFC107,\n    orange: #FF9800,\n    purple: #673AB7\n);\n\n$colour-variation: 10%;\n\n$border-radius: 2px;"
  },
  {
    "path": "src/assets/styles/core/_animations.scss",
    "content": "\n.fade {\n\n    &-enter-active,\n    &-leave-active {\n        transition: opacity 250ms ease-out;\n    }\n\n    &-enter,\n    &-leave {\n        opacity: 0;\n    }\n}"
  },
  {
    "path": "src/assets/styles/core/_base.scss",
    "content": "\nhtml,\nbody {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n    padding: 0;\n}\n\nhtml {\n    font-size: $font-size;\n    box-sizing: border-box;\n}\n\n*,\n*:before,\n*:after {\n    box-sizing: inherit;\n}\n\nbody {\n    font-family: \"Open Sans\", sans-serif;\n    font-weight: 400;\n    line-height: $line-height;\n    color: $colour-font;\n    background-color: $colour-background;\n}\n\nbutton, \ninput, \ntextarea,\nselect,\noptgroup {\n    color: inherit;\n    font: inherit;\n    margin: 0;\n}"
  },
  {
    "path": "src/assets/styles/core/_buttons.scss",
    "content": "\n.button {\n    display: inline-block;\n    margin: 0;\n    padding: 0.75rem 1.5rem;\n    font-weight: 600;\n    line-height: inherit;\n    text-align: center;\n    color: $colour-font-negative;\n    background-color: $colour-primary;\n    border: none;\n    border-radius: $border-radius;\n    outline: none;\n    cursor: pointer;\n\n    &:hover,\n    &:active {\n        color: $colour-font-negative;\n        background-color: darken($colour-primary, $colour-variation);\n    }\n}\n\n@each $name, $colour in $colour-accents {\n\n    .button-#{ $name } {\n        background-color: $colour;\n\n        &:hover,\n        &:active {\n            color: $colour-font-negative;\n            background-color: darken($colour, $colour-variation);\n        }\n    }\n\n} "
  },
  {
    "path": "src/assets/styles/core/_inputs.scss",
    "content": "\ninput[type=\"text\"],\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime\"],\ninput[type=\"password\"],\ninput[type=\"search\"],\nselect {\n    display: inline-block;\n    width: 250px;\n    height: 3rem;\n    padding: 0 0.75rem;\n    background-color: $colour-background;\n    border: 1px solid $colour-border;\n    border-radius: 2px;\n    outline: none;\n\n    &:focus,\n    &:active {\n        border-color: $colour-primary;\n    }\n}"
  },
  {
    "path": "src/assets/styles/core/_labels.scss",
    "content": "\n.label {\n    display: inline-block;\n    min-width: 1.5em * $typography-ratio;\n    padding: 0 0.5em;\n    font-size: 1em/$typography-ratio;\n    font-weight: 600;\n    line-height: inherit;\n    text-align: center;\n    color: $colour-font;\n    background-color: $colour-background-medium;\n    border-radius: $border-radius;\n}\n\n.label-primary {\n    color: $colour-font-negative;\n    background-color: $colour-primary;\n}\n\n@each $name, $colour in $colour-accents {\n\n    .label-#{ $name } {\n        color: $colour-font-negative;\n        background-color: $colour;\n    }\n\n} "
  },
  {
    "path": "src/assets/styles/core/_layout.scss",
    "content": "\n.container {\n    width: 100%;\n    max-width: 1170px;\n    margin: 0 auto;\n}\n\n.grid-row {\n    margin-left: -0.5rem;\n    margin-right: -0.5rem;\n\n    & + .grid-row {\n        margin-top: 1rem;\n    }\n}\n\n.grid-cell {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n}"
  },
  {
    "path": "src/assets/styles/core/_menus.scss",
    "content": "\n.menu {\n\n}\n\n.menu-group {\n\n    &:not(:last-child) {\n        margin-bottom: 1.5rem;\n    }\n}\n\n.menu-group-title,\n.menu-item {\n    padding-left: 1rem;\n    padding-right: 1rem;\n}\n\n.menu-group-title {\n    display: block;\n    font-weight: 600;\n    margin-bottom: 0.5rem;\n}\n\n.menu-item {\n    padding-top: 0.25rem;\n    padding-bottom: 0.25rem;\n\n    &:hover {\n        background-color: $colour-background-medium;\n    } \n}"
  },
  {
    "path": "src/assets/styles/core/_tables.scss",
    "content": "\n$color-table-row-alt: #FAFAFA;\n\n.table-wrapper {\n    display: block;\n    width: 100%;\n    border: 1px solid $colour-border;\n    border-radius: 2px;\n\n    & table {\n        border: none;\n    }\n}\n\ntable {\n    table-layout: fixed;\n    width: 100%;\n    background-color: $colour-background;\n    border-collapse: collapse;\n    border: 1px solid $colour-border;\n}\n\n.table-striped {\n\n    & tr {\n\n        &:nth-child(even) {\n\n            & > td {\n                background-color: $color-table-row-alt;\n            }\n        }\n    }\n}\n\nth,\ntd {\n    text-align: left;\n\n    &:last-of-type {\n        border-right: none;\n    }\n}\n\nth {\n    padding: 0.75rem 1rem;\n    font-weight: 600;\n    background-color: $colour-background-medium;\n    border-right: 1px solid $colour-border;\n    border-bottom: 1px solid $colour-border;\n}\n\ntd {\n    padding: 0.5rem 1rem;\n    border-right: 1px solid $colour-border-light;\n    border-bottom: 1px solid $colour-border-light;\n    @include truncate-text;\n}\n\ntbody,\ntfoot {\n\n    &:last-of-type {\n\n        & tr {\n\n            &:last-of-type {\n\n                & > td {\n                    border-bottom: none;\n                }\n            }\n        }\n    }\n}\n\ntfoot {\n\n    & td {\n        font-weight: 600;\n    }\n\n    & tr {\n\n        &:first-of-type {\n\n            & td {\n                border-top: 1px solid $colour-border;\n            }\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "src/assets/styles/core/_typography.scss",
    "content": "\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n    margin-top: 1em;\n    margin-bottom: 0.25em;\n    font-weight: 600;\n    line-height: $line-height;\n    color: $colour-font;\n}\n\nh1 {\n    font-size: #{ pow($typography-ratio, 4) }em;\n}\n\nh2 {\n    font-size: #{ pow($typography-ratio, 3) }em;\n}\n\nh3 {\n    font-size: #{ pow($typography-ratio) }em;\n}\n\nh4 {\n    font-size: $typography-ratio * 1em;\n}\n\nh5 {\n    font-size: 1em;\n}\n\nh6 {\n    font-size: 1em/$typography-ratio;\n}\n\np {\n    margin: 0.75em 0;\n}\n\nsmall {\n    font-size: 1em/$typography-ratio;\n}\n\nstrong {\n    font-weight: 600;\n}\n\nem {\n    font-style: italic;\n}\n\na {\n    color: $colour-primary;\n    text-decoration: none;\n\n    &:hover {\n        color: darken($colour-primary, $colour-variation);\n    }\n\n    &.escape-link {\n        color: inherit;\n\n        &:hover {\n            color: inherit;\n        }\n    }\n}\n\nlabel {\n    display: block;\n    font-weight: 600;\n    font-size: 1em/$typography-ratio;\n}\n\nblockquote {\n    display: block;\n    margin: 1em 0;\n    padding: 0 1em;\n    color: #888;\n    font-weight: 600;\n    border-left: 4px solid #2196F3;\n}\n\ncode {\n    display: block;\n    margin: 1em 0;\n    padding: 1em;\n    font-family: monospace;\n    white-space: pre;\n    background-color: #FAFAFA;\n    border: 1px solid $colour-border;\n    border-radius: $border-radius;\n}"
  },
  {
    "path": "src/assets/styles/site.scss",
    "content": "\n@import \"./abstract/_variables.scss\";\n@import \"./abstract/_functions.scss\";\n@import \"./abstract/_mixins.scss\";\n\n@import \"./core/_base.scss\";\n@import \"./core/_typography.scss\";\n@import \"./core/_layout.scss\";\n@import \"./core/_buttons.scss\";\n@import \"./core/_inputs.scss\";\n@import \"./core/_labels.scss\";\n@import \"./core/_menus.scss\";\n@import \"./core/_tables.scss\";\n@import \"./core/_animations.scss\";\n\n\n\n"
  },
  {
    "path": "src/components/calendar/calendar.vue",
    "content": "<template>\n    <div class=\"calendar table-wrapper\">\n        <div class=\"calendar-header\" layout=\"row center-justify\">\n            <button class=\"button\" @click=\"previous\">Previous</button>\n            <div class=\"calendar-month-name\">{{ calendar.startDate | date(\"MMMM YYYY\") }}</div>\n            <button class=\"button\" @click=\"next\">Next</button>\n        </div>\n        <table>\n            <thead>\n                <tr>\n                    <td v-for=\"weekday in calendar.weekdays\">{{ weekday }}</td>\n                </tr>\n            </thead>\n            <tbody>\n                <tr class=\"calendar-week\" v-for=\"(week, index) in calendar.weeks\">\n                    <template v-if=\"index == 0\">\n                        <td class=\"calendar-day\" v-for=\"spacer in calendar.paddingStart\"></td>\n                    </template>\n                    <td class=\"calendar-day\" v-for=\"day in week\">\n                        <div>{{ day.getDate() }}</div>\n                    </td>\n                    <template v-if=\"(index + 1) == calendar.weeks.length\">\n                        <td class=\"calendar-day\" v-for=\"spacer in calendar.paddingEnd\"></td>\n                    </template>\n                </tr>\n            </tbody>\n        </table>\n    </div>\n</template>\n\n<script>\n    import CalendarMonth from \"../../services/calendar.js\";\n    import format from \"date-fns/format\";\n\n    export default {\n\n        data() {\n            return {\n                calendar: new CalendarMonth()\n            };\n        },\n\n        methods: {\n\n            previous() {\n                this.calendar.previousMonth();\n            },\n\n            next() {\n                this.calendar.nextMonth();\n            }\n\n        },\n\n        filters: {\n\n            date(value, pattern) {\n                return format(value, pattern);\n            }\n\n        }\n\n    }\n</script>"
  },
  {
    "path": "src/components/chip/chip.vue",
    "content": "<template>\n    <div class=\"chip\">\n        <div layout=\"row stretch-justify\">\n            <div class=\"chip-body\">\n                <slot></slot>\n            </div>\n            <div class=\"chip-footer\" layout=\"row center-center\" v-if=\"removable\">\n                <div class=\"chip-close-button\" @click=\"remove\" title=\"Click to remove\"></div>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        props: {\n\n            removable: {\n                type: Boolean,\n                default: true\n            }\n\n        },\n\n        methods: {\n\n            remove() {\n                this.$emit(\"remove\", this);\n            }\n\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .chip {\n        display: inline-block;\n        min-width: 1.5em * $typography-ratio;\n        text-align: left;\n        color: $colour-font;\n        background-color: $colour-background-medium;\n        border-radius: $border-radius;\n    }\n\n    .chip-body,\n    .chip-footer {\n        padding: 0.25rem 0.5rem;\n    }\n\n    .chip-footer {\n        background-color: darken($colour-background-medium, 2.5%);\n    }\n\n    .chip-close-button {\n        position: relative;\n        width: 1.25rem;\n        height: 1.25rem;\n        border-radius: $border-radius;\n        cursor: pointer;\n\n        &:hover {\n            background-color: darken($colour-background-medium, $colour-variation);\n        }\n\n        &:before,\n        &:after {\n            display: block;\n            position: absolute;\n            content: \" \";\n            top: 50%;\n            left: 10%;\n            width: 80%;\n            height: 2px;\n            margin-top: -1px;\n            background-color: currentColor;\n            transform-origin: center center;\n        }\n\n        &:before {\n            transform: rotate(-45deg);\n        }\n\n        &:after {\n            transform: rotate(45deg);\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/components/components.js",
    "content": "\nimport Calendar from \"./calendar/calendar.vue\";\nimport Checkbox from \"./toggles/checkbox.vue\";\nimport Chip from \"./chip/chip.vue\";\nimport DataTable from \"./datatable/datatable.vue\";\nimport DataTableColumn from \"./datatable/datatable-column.vue\";\nimport DateTimePicker from \"./datetime-picker/datetime-picker.vue\";\nimport Dynamic from \"./dynamic/dynamic\";\nimport FloatingPanel from \"./floating-panel/floating-panel.vue\";\nimport Modal from \"./modal/modal.vue\";\nimport Paginator from \"./paginator/paginator.vue\";\nimport Panel from \"./panel/panel.vue\";\nimport Radio from \"./toggles/radio.vue\";\nimport TabControl from \"./tab-control/tab-control.vue\";\nimport TabPane from \"./tab-control/tab-pane.vue\";\nimport Toggle from \"./toggles/toggle.vue\";\n\nexport default {\n    calendar: Calendar,\n    checkbox: Checkbox,\n    chip: Chip,\n    datatable: DataTable,\n    datatableColumn: DataTableColumn,\n    datetimePicker: DateTimePicker,\n    dynamic: Dynamic,\n    floatingPanel: FloatingPanel,\n    modal: Modal,\n    paginator: Paginator,\n    panel: Panel,\n    radio: Radio,\n    toggle: Toggle,\n    tabControl: TabControl,\n    tabPane: TabPane\n}"
  },
  {
    "path": "src/components/datatable/datatable-cell.js",
    "content": "const defaultTemplate = \"<span>{{ column.formatData(row[column.id]) }}</span>\";\nconst editableTemplate = '<input type=\"text\" v-model=\"row[column.id]\"/>';\nconst optimizedEditableTemplate = '<input type=\"text\" v-model.lazy=\"row[column.id]\"/>';\n\nfunction getChildComponent(editable, optimize) {\n\n    let component = {\n        template: defaultTemplate,\n        props: [\"row\", \"column\"]\n    };\n\n    if (editable) {\n        component.template = optimize ? optimizedEditableTemplate : editableTemplate;\n    }\n\n    return component;\n}\n\nexport default {\n    functional: true,\n\n    name: \"datatable-cell\",\n\n    props: {\n\n        row: Object,\n        column: Object,\n\n        editable: {\n            type: Boolean,\n            default: false\n        },\n\n        optimize: {\n            type: Boolean,\n            default: false\n        }\n\n    },\n\n    render(createElement, context) {\n        let row = context.props.row;\n        let column = context.props.column;\n\n        let cell = \"td\";\n        let cellProps = {\n            class: {\n                \"datatable-cell\": true\n            },\n            style: column.columnStyles\n        };\n\n        if (column.template) {\n\n            let vNode = column.template({\n                row,\n                column,\n                value: row[column.id]\n            });\n\n            return createElement(cell, cellProps, [vNode]);\n        }\n\n        let child = getChildComponent(context.props.editable, context.props.optimize);\n\n        let childProps = {\n            props: {\n                row,\n                column\n            }\n        };\n\n        return createElement(cell, cellProps, [\n            createElement(child, childProps)\n        ]);\n    }\n}"
  },
  {
    "path": "src/components/datatable/datatable-collection.vue",
    "content": "<template>\n    <div class=\"datatable-collection\">\n        <table v-if=\"groupable\" :class=\"{ 'table-striped': striped }\">\n            <tr v-for=\"(data, group, index) in groups\">\n                <td class=\"datatable-group\" :colspan=\"columnSpan\">\n                    <div class=\"datatable-group-header\" layout=\"row center-justify\">\n                        <div self=\"size-x1\">\n                            <span class=\"datatable-group-label\" :style=\"indentStyle\">{{ groupingColumn.formatData(group) }}</span>\n                        </div> \n                        <span class=\"label label-primary datatable-row-count\" v-if=\"data.length > 1\">{{ data.length }}</span>\n                    </div>\n                    <datatable-collection \n                        :rows=\"data\" \n                        :columns=\"columns\" \n                        :striped=\"striped\"\n                        :editable=\"editable\" \n                        :line-numbers=\"lineNumbers\"\n                        :aggregated=\"aggregated\"\n                        :margin=\"margin\" \n                        :grouping-columns=\"groupingColumns\"\n                        :grouping-index=\"groupingIndex + 1\"\n                        :collection-index=\"collectionIndex * index\"\n                        :optimize=\"optimize\"\n                        :message=\"message\">\n                    </datatable-collection>\n                </td>\n            </tr>\n        </table>\n        <table v-else class=\"datatable-resultset\" :class=\"{ 'table-striped': striped }\">\n            <tr v-if=\"rows.length < 1\">\n                <td class=\"datatable-info-cell\" :colspan=\"columnSpan\">{{ message }}</td>\n            </tr>\n            <tr v-for=\"(row, index) in rows\">\n                <td v-if=\"lineNumbers\" class=\"datatable-cell datatable-linenumber-cell\" :style=\"{ width: margin }\">{{ collectionIndex + index + 1 }}</td>\n                <td v-if=\"aggregated\" class=\"datatable-cell datatable-aggregate-cell\">&nbsp;</td>\n                <datatable-cell v-for=\"column in columns\" :key=\"column.id\" :column=\"column\" :row=\"row\" :editable=\"editable\" :optimize=\"optimize\"></datatable-cell>\n            </tr>\n        </table>\n    </div>\n</template>\n\n<script>\n    import DatatableCell from \"./datatable-cell.js\";\n    import groupBy from \"../../utilities/group-by.js\";\n\n    export default {\n        name: \"datatable-collection\",\n\n        props: {\n\n            rows: {\n                type: Array,\n                required: true\n            },\n\n            columns: {\n                type: Array,\n                required: true\n            },\n\n            groupingColumns: {\n                type: Array\n            },\n\n            groupingIndex: {\n                type: Number,\n                default: 0\n            },\n\n            striped: {\n                type: Boolean,\n                default: true\n            },\n\n            editable: {\n                type: Boolean,\n                default: false\n            },\n\n            lineNumbers: {\n                type: Boolean,\n                default: false\n            },\n\n            aggregated: {\n                type: Boolean,\n                default: false\n            },\n\n            margin: {\n                type: String,\n                default: \"1.5em\"\n            },\n\n            collectionIndex: {\n                type: Number,\n                default: 0\n            },\n\n            optimize: {\n                type: Boolean,\n                default: false\n            },\n\n            message: {\n                type: String,\n                default: \"No results\",\n                required: false\n            }\n\n        },\n\n        computed: {\n\n            groupable() {\n                return this.groupingIndex < this.groupingColumns.length;\n            },\n\n            groupingColumn() {\n                let columnId = this.groupingColumns[this.groupingIndex];\n                return this.columns.find(column => column.id === columnId);\n            },\n\n            groups() {\n                let columnId = this.groupingColumn.id;\n                return groupBy(this.rows, row => row[columnId]);\n            },\n\n            columnSpan() {\n                return this.columns.length + (this.lineNumbers ? 1 : 0);\n            },\n\n            indentStyle() {\n                let margin = this.groupingIndex * 1.5;\n\n                return { \n                    \"margin-left\": margin + \"rem\"\n                };\n            }\n\n        },\n\n        components: {\n            datatableCell: DatatableCell\n        }\n\n    }\n</script>\n"
  },
  {
    "path": "src/components/datatable/datatable-column.vue",
    "content": "<template>\n    <th :style=\"columnStyles\" title=\"Click to sort. Drag to center to group.\" @click=\"sort\" v-drag:start=\"dragStart\">\n        <div class=\"datatable-column\" :layout=\"columnLayout\">\n            <div>\n                <slot>{{ label || id }}</slot>\n            </div>\n            <div class=\"datatable-sort-arrow\" :class=\"sortArrowClass\" v-show=\"sorting\"></div>\n        </div>\n    </th>\n</template>\n\n<script>\n\n    const alignments = [\n        \"left\",\n        \"center\",\n        \"right\",\n        \"auto\"\n    ];\n\n    const sortClassMap = {\n        \"1\": \"asc\",\n        \"-1\": \"desc\"\n    };\n\n    export default {\n\n        props: {\n\n            id: {\n                type: String,\n                required: true\n            },\n\n            label: {\n                type: String\n            },\n\n            width: {\n                type: [ Number, String ]\n            },\n\n            alignment: {\n                type: String,\n                default: \"left\",\n                validator: value => {\n                    return alignments.indexOf(value) > -1;\n                }\n            },\n\n            formatter: {\n                type: Function\n            },\n\n            sortable: {\n                type: Boolean,\n                default: true\n            },\n\n            groupable: {\n                type: Boolean,\n                default: true\n            },\n\n            aggregators: {\n                type: Array\n            }\n\n        },\n\n        data() {\n            return {\n                sortingDirection: 1\n            };\n        },\n\n        computed: {\n\n            sorting: {\n                get() {\n                    return (this.$parent.sortingId === this.id && this.sortable);\n                },\n                set(value) {\n                    if (value && this.sortable) {\n                        this.$parent.sortingId = this.id;\n                    }\n                }\n            },\n\n            grouping: {\n                get() {\n                    return (this.$parent.groupingColumnIds.indexOf(this.id) > -1);\n                }\n            },\n\n            columnWidth() {\n                if (!this.width) {\n                    return;\n                }\n\n                let suffix = isNaN(this.width) ? \"\" : \"%\";\n                \n                return this.width + suffix;\n            },\n\n            columnLayout() {\n                let direction = this.alignment !== \"right\" ? \"row\" : \"row-reverse\";\n\n                return direction + \" center-justify\";\n            },\n\n            columnStyles() {\n                let alignment = this.alignment === \"left\" ? null : this.alignment;\n\n                return {\n                    width: this.columnWidth,\n                    textAlign: alignment\n                };\n            },\n\n            sortArrowClass() {\n                let direction = sortClassMap[this.sortingDirection];\n                return \"datatable-sort-arrow-\" + direction;\n            },\n\n            template() {\n                return this.$parent.$scopedSlots[this.id];\n            }\n\n        },\n\n        methods: {\n\n            sort() {              \n                if (this.sorting) {\n                    this.sortingDirection *= -1;\n                    return;\n                }\n\n                this.sorting = true;\n            },\n\n            formatData(value) {\n                if (!this.formatter) {\n                    return value;\n                }\n\n                return this.formatter(value);\n            },\n\n            dragStart(event) {\n                event.stopPropagation();\n                event.dataTransfer.dropEffect = \"copy\";\n                event.dataTransfer.setData(\"text\", this.id);\n            }\n\n        },\n\n        created() {\n            let addColumn = this.$parent.addColumn;\n\n            if (!addColumn) {\n                console.warn(\"A datatable-column must be registered within a datatable component.\");\n                return;\n            }\n\n            addColumn(this);\n        },\n\n        destroyed() {\n            this.$parent.removeColumn(this);\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    $sort-arrow-size: 0.375rem;\n    $sort-arrow-offset: $sort-arrow-size / 2;\n\n    .datatable-column {\n        padding: 0.75rem 1rem;\n        cursor: pointer;\n        user-select: none;\n    }\n\n    .datatable-sort-arrow {\n        width: 0;\n        height: 0;\n        border: $sort-arrow-size solid transparent;\n    }\n\n    .datatable-sort-arrow-asc {\n        border-bottom-color: currentColor;\n        transform: translate(0, -$sort-arrow-offset);\n    }\n\n    .datatable-sort-arrow-desc {\n        border-top-color: currentColor;\n        transform: translate(0, $sort-arrow-offset);\n    }\n\n</style>"
  },
  {
    "path": "src/components/datatable/datatable.vue",
    "content": "<template>\n    <div class=\"datatable table-wrapper\" :class=\"tableClasses\">\n        <table>\n            <thead class=\"datatable-columns\">\n                <tr>\n                    <th v-if=\"lineNumbers\" :style=\"{ width: lineColumnWidth }\">\n                        <div class=\"datatable-column datatable-linenumber-column\">#</div>\n                    </th>\n                    <th v-if=\"aggregated\">\n                        <div class=\"datatable-column datatable-aggregate-column\">Aggregate</div>\n                    </th>\n                    <slot></slot>\n                </tr>\n            </thead>\n            <tbody class=\"datatable-groups\" v-if=\"groupingColumnIds.length > 0\">\n                <tr>\n                    <td class=\"datatable-groups-header\" :colspan=\"columnSpan\">\n                        <chip class=\"datatable-group-chip\" v-for=\"(column, index) in groupingColumns\" :key=\"column.id\" @remove=\"degroupColumn(column)\">\n                            <div>\n                                <small>\n                                    <strong>{{ index == 0 ? \"Grouping By:\" : \"Then:\" }}</strong>\n                                </small>\n                            </div>\n                            <div>{{ column.label }}</div>\n                        </chip>\n                    </td>\n                </tr>\n            </tbody>\n            <tbody class=\"datatable-collections\" v-drag:enter=\"dragEnter\" v-drag:leave=\"dragLeave\" v-drag:over=\"dragOver\" v-drag:drop=\"dragDrop\">\n                <tr>\n                    <td class=\"datatable-group\" :colspan=\"columnSpan\">\n                        <datatable-collection \n                            :rows=\"rows\" \n                            :columns=\"columns\" \n                            :striped=\"striped\"\n                            :editable=\"editable\"\n                            :line-numbers=\"lineNumbers\"\n                            :aggregated=\"aggregated\"\n                            :grouping-columns=\"groupingColumnIds\"\n                            :margin=\"lineColumnWidth\"\n                            :message=\"message\">\n                        </datatable-collection>\n                    </td>\n                </tr>\n            </tbody>\n            <tfoot class=\"datatable-aggregators\" v-if=\"aggregated\">\n                <tr>\n                    <td class=\"datatable-info-cell\" :colspan=\"columnSpan\">&nbsp;</td>\n                </tr>\n                <tr v-for=\"(aggregator, index) in aggregators\" :key=\"aggregator.label\">\n                    <td v-if=\"lineNumbers\" class=\"datatable-linenumber-cell\">{{ index + 1 }}</td>\n                    <td v-if=\"aggregated\" class=\"datatable-aggregate-cell\">{{ aggregator.label }}</td>\n                    <td v-for=\"column in columns\" :style=\"column.columnStyles\">{{ aggregate(column, aggregator) }}</td>\n                </tr>\n            </tfoot>\n        </table>\n        <div class=\"datatable-options\" layout=\"row center-justify\" v-if=\"filterable\">\n            <input type=\"text\" placeholder=\"Filter this dataset. Press enter to search...\" v-model.lazy=\"filter\" self=\"size-x1\" v-if=\"optimize\">\n            <input type=\"text\" placeholder=\"Filter this dataset...\" v-model=\"filter\" self=\"size-x1\" v-else>\n        </div>\n    </div>\n</template>\n\n<script>\n    import DatatableCollection from \"./datatable-collection.vue\"; \n    import filterBy from \"../../utilities/filter-by.js\";\n    import sortBy from \"../../utilities/sort-by.js\";\n    import { isCollection } from \"../../utilities/base/type-validator.js\";\n\n    export default {\n\n        props: {\n\n            fixed: {\n                type: Boolean,\n                default: true\n            },\n\n            striped: {\n                type: Boolean,\n                default: true\n            },\n\n            source: {\n                type: Array,\n                default: () => []\n            },\n\n            editable: {\n                type: Boolean,\n                default: false\n            },\n\n            filterable: {\n                type: Boolean,\n                default: true\n            },\n\n            lineNumbers: {\n                type: Boolean,\n                default: false\n            },\n\n            threshold: {\n                type: Number,\n                default: 50\n            },\n\n            message: {\n                type: String,\n                default: \"No results\"\n            }\n\n        },\n\n        data() {\n            return {\n                columns: [],\n                filter: null,\n                sortingId: null,\n                groupingColumnIds: [],\n                groupingDropzoneActive: false\n            };\n        },\n\n        computed: {\n\n            sortingColumn() {\n                return this.columns.find(column => column.id === this.sortingId);\n            },\n\n            groupingColumns() {\n                return this.groupingColumnIds.map(columnId => {\n                    return this.columns.find(column => column.id === columnId);\n                });\n            },\n\n            tableClasses() {\n                return {\n                    \"datatable-editable\": this.editable,\n                    \"table-fixed\": this.fixed\n                };\n            },\n\n            groupableColumns() {\n                return this.columns.filter(column => column.groupable);\n            },\n\n            rows() {\n\n                let rows = this.source;\n\n                // Filter the rows first to reduce the set (if a filter is supplied) we need to sort\n                if (this.filter) {\n                    rows = filterBy(rows, this.filter);\n                }\n\n                // Sort the filtered set\n                if (this.sortingColumn) {\n                    rows = sortBy(rows, row => row[this.sortingColumn.id], this.sortingColumn.sortingDirection);\n                }\n\n                return rows;\n            },\n\n            columnSpan() {\n                let columnSpan = this.columns.length;\n\n                if (this.lineNumbers) {\n                    columnSpan++\n                }\n\n                if (this.aggregated) {\n                    columnSpan ++\n                }\n\n                return columnSpan;\n            },\n\n            lineColumnWidth() {\n                let count = this.source.length;\n                return count.toString().length + 2 + \"em\";\n            },\n\n            aggregators() {\n                let aggregators = [];\n\n                for (let column of this.columns) {\n                    if (!column.aggregators) {\n                        continue;\n                    }\n\n                    aggregators = aggregators.concat(column.aggregators);\n                }\n                \n                return aggregators.filter((item, index, arr) => {\n                    return index === arr.indexOf(item);\n                });\n            },\n\n            aggregated() {\n                return this.aggregators && this.aggregators.length > 0;\n            },\n\n            optimize() {\n                return this.source.length >= this.threshold;\n            }\n\n        },\n\n        methods: {\n\n            addColumn(column) {\n                this.columns.push(column);\n            },\n\n            removeColumn(column) {\n                let index = this.columns.indexOf(column);\n                this.columns.splice(index, 1);\n            },\n\n            groupColumn(column) {\n                this.groupingColumnIds.push(column.id);\n            },\n\n            degroupColumn(column) {\n                let index = this.groupingColumnIds.indexOf(column.id);\n                this.groupingColumnIds.splice(index, 1);\n            },\n\n            aggregate(column, aggregator) {\n                const noResult = \" \";\n\n                if (!column.aggregators || column.aggregators.indexOf(aggregator) === -1) {\n                    return noResult;\n                }\n\n                let result = aggregator.callback.call(column, this.rows, row => row[column.id]);\n                \n                if (!result || isCollection(result)) {\n                    return noResult;\n                }\n\n                return aggregator.format ? column.formatData(result) : result;\n            },\n\n            dragDrop(event) {\n                event.preventDefault();\n\n                let columnId = event.dataTransfer.getData(\"text\");\n\n                let column = this.groupableColumns.find(item => {\n                    return item.id === columnId;\n                });\n\n                if (column && !column.grouping) {\n                    this.groupColumn(column);\n                }\n            },\n\n            dragOver(event) {\n                event.preventDefault();\n            },\n\n            dragEnter(event) {\n                event.preventDefault();\n                this.groupingDropzoneActive = true;\n            },\n\n            dragLeave(event) {\n                event.preventDefault();\n                this.groupingDropzoneActive = false;\n            }\n \n        },\n\n        components: {\n            datatableCollection: DatatableCollection\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .datatable {\n\n        & th {\n            padding: 0;\n        }\n    }\n\n    .datatable-linenumber-column,\n    .datatable-linenumber-cell {\n        text-align: center;\n    }\n\n    .datatable-linenumber-cell,\n    .datatable-aggregate-cell {\n        font-weight: 600; \n        background-color: $colour-background-medium !important;\n        border-right-color: $colour-border;\n    }\n\n    .datatable-group-chip {\n        margin-right: 0.5rem;\n    }\n\n    .datatable-collection {\n\n        & .datatable-collection {\n\n            & .datatable-resultset {\n                border-top: 1px solid $colour-border;\n            }\n        }\n    }\n\n    .datatable-group {\n        padding: 0;\n        background-color: $colour-background;\n        border-bottom: 1px solid $colour-border;\n    }\n\n    .datatable-groups-header {\n        border-bottom: 1px solid $colour-border;\n    }\n\n    .datatable-group-header {\n        padding: 0.5rem 1rem;\n        background-color: $colour-background-medium;\n    }\n\n    .datatable-grouping-over {\n        box-shadow: 0 0 0 2px $colour-primary;\n    }\n\n    .datatable-row-indent {\n        display: inline-block;\n        width: 1.5rem;\n        height: 1em;\n    }\n\n    .datatable-group-label {\n        font-weight: 600;\n    }\n\n    .datatable-info-cell {\n        text-align: center;\n        font-weight: 600;\n    }\n\n    .datatable-aggregators {\n\n        & .datatable-info-cell  {\n            border-bottom: 1px solid $colour-border;\n        }\n    }\n\n    .datatable-options {\n        padding: 0.75rem 1rem;\n        background-color: $colour-background-medium;\n        border-top: 1px solid $colour-border;\n    }\n\n    .datatable-editable {\n\n        & .datatable-cell {\n            position: relative;\n            padding: 0 !important;\n            overflow: visible;\n\n            & input,\n            & select {\n                display: block;\n                width: 100%;\n                height: auto;\n                padding: 0.5rem 1rem;\n                background-color: transparent;\n                border: none;\n                border-radius: 0;\n\n                &:focus,\n                &:active {\n                    box-shadow: 0 0 0 2px $colour-primary;\n                }\n            }          \n        }\n    }\n\n\n</style>\n"
  },
  {
    "path": "src/components/datatable/readme.md",
    "content": "# Datatable\n\nThe datatable component is essentially a \"glorified table\" designed to efficiently display dense data. Datatables aren't a heavily used component but they are fundamental to business applications - particularly ones displaying financial data or dashboards. A good datatable is hard to come by these days. Often they are too bulky, poorly designed, rigid, lack features or have too many dependencies on other frameworks. I have aimed to mitigate most of these problems with the Vuetiful datatable but I expect there will be features lacking that you need. \n\nIf you would like a feature added to the datatable or if you find a bug, please open an issue on this repo.\n\n**Note:** The line numbering is a little bit quirky in multi-group mode. I'll hopefully have it fixed soon. \n\nTo see a demo of this component in action check out this codepen example: [http://codepen.io/andrewcourtice/full/woQzpa](http://codepen.io/andrewcourtice/full/woQzpa).\n\n![General](https://cloud.githubusercontent.com/assets/11718453/24491089/f2641d34-1568-11e7-8b84-dd4fd53ed0ff.png)\n\n- [Getting Started](#getting-started)\n- [Props](#props)\n\t- [Datatable](#datatable-1)\n\t- [Datatable Column](#datatable-column)\n- [Formatting Data](#formatting-data)\n- [Sorting Data](#sorting-data)\n- [Grouping Data](#grouping-data)\n- [Editing Data](#editing-data)\n- [Customizing the Datatable](#customizing-the-datatable)\n\t- [Header Templates](#header-templates)\n\t- [Cell Templates](#cell-templates)\n\t\t- [View Mode](#view-mode)\n\t\t- [Edit Mode](#edit-mode)\n- [Aggregation](#aggregation)\n- [Pagination](#pagination)\n- [Optimization](#optimization)\n\n## Getting Started\n\nUsing the datatable is trivial. Just drop a `datatable` element in your html and start defining some `datatable-columns`. Refer to the **props** section below to see what props you can use with this component. I'll also talk about customizing cell and header templates using slots later. Here's a basic example:\n\n```html\n<datatable>\n    <datatable-column id=\"datatable-column-1\" label=\"Column 1\"></datatable-column>\n    <datatable-column id=\"datatable-column-2\" label=\"Column 2\"></datatable-column>\n    <datatable-column id=\"datatable-column-3\" label=\"Column 3\"></datatable-column>\n</datatable>\n```\n\nYou can also use Vue's list rendering features to define columns in your viewmodel.\n\n```javascript\nnew Vue({\n\n    el: \"#app\",\n\n    data: function() {\n        return {\n            columns: [\n                { id: \"datatable-column-1\", label: \"Column 1\" },\n                { id: \"datatable-column-2\", label: \"Column 2\" },\n                { id: \"datatable-column-3\", label: \"Column 3\" }\n            ]\n        };\n    }\n});\n```\n\n```html\n<datatable>\n    <datatable-column v-for=\"column in columns\" :id=\"column.id\" :label=\"column.label\"></datatable-column>\n</datatable>\n```\n\n\n## Props\n\n### Datatable\n\n```html\n<datatable \n    :source=\"customers.data\"\n    :striped=\"customers.striped\"\n    :filterable=\"customers.filterable\"\n    :editable=\"customers.editable\"\n    :line-numbers=\"customers.lineNumbers\">\n\n    <!-- datatable-column -->\n</datatable>\n```\n\n| Prop | Type | Required | Default | Description |\n| ---- | ---- | :------: | ------- | ----------- |\n| source | array[object] | no | [] | An array of objects to display in the table. a.k.a. - the data. This is often JSON fetched from your application and parsed |\n| striped | boolean | no | true | Whether the table should display alternate row coloring |\n| filterable | boolean | no | true | Whether the table should display a textbox in the footer for filtering the current dataset |\n| editable | boolean | no | false | Whether the table should be displayed in edit mode. See [Editing Data](#editing-data) |\n| line-numbers | boolean | no | true | Whether the table should display line numbers on the left of each row |\n| threshold | number | no | 50 | The maximum number of rows before the datatable enables performance optimizations. See [Optimization](#optimization). |\n\n**Note:** For specifying literal true values on props you can use a shorthand version. eg. instead of writing `editable=\"true\"` you can just use the existence of the prop to define it's value eg. `editable`.\n\n### Datatable Column\n\n```html\n<datatable-column \n    :id=\"column.id\" \n    :label=\"column.label\"\n    :width=\"column.width\"\n    :sortable=\"column.sortable\"\n    :groupable=\"column.groupable\"\n    :aggregators=\"column.aggregators\"\n    :formatter=\"column.formatter\">\n</datatable-column>\n```\n\n| Prop | Type | Required | Default | Description |\n| ---- | ---- | :------: | ------- | ----------- |\n| id | string | yes |  | The uniqie id of this column. The id must correspond to a property on the objects in your data source |\n| label | string | no | this.id | The label of this column to display in the header of the table. If none is specified, the id of this column will be used |\n| width | string or number | no | | The width of the column. If a number is supplied the component will assume a percentage (eg. 25 = 25%). If a string is supplied the component will interpret it literally (eg. 3px, 3.5rem, 4em etc.) |\n| sortable | boolean | no | true | Whether this row can be used for sorting |\n| groupable | boolean | no | true | Whether this row can be used for grouping |\n| aggregators | array | no | | A set of aggregate functions the column should use to process data in this column. See [Aggregators](#aggregators) for more information |\n| formatter | function | no | | A function used to format the data in this column before it is displayed. This is particularly useful for dates and numeric value. See [Formatting Data](#formatting-data) |\n\n\n## Formatting Data\n\nMore often than not you will likely run into a situation where you need to display data in a different format than it's raw form. This is common for dates and numbers. As seen above, each column has a `formatter` prop which allows you to specify a function that formats the data for that cell. There are several ways you could do this but using our basic example above, let's take a look at one way how you would implement a custom formatter:\n\n```javascript\nnew Vue({\n\n    el: \"#app\",\n\n    data: function() {\n        return {\n            /* replace with real data */\n            data: []\n        };\n    },\n\n    methods: {\n\n        formatCurrency: function(value) {\n            var currency = parseFloat(value);\n\n            if (isNaN(currency)) {\n                return value;\n            }\n\n            return \"$\" + currency.toFixed(2).replace(/(\\d)(?=(\\d{3})+\\.)/g, \"$1,\");\n        }\n\n    }\n});\n```\n\n```html\n<datatable>\n    <datatable-column id=\"datatable-column-1\" label=\"Column 1\"></datatable-column>\n    <datatable-column id=\"datatable-column-2\" label=\"Column 2\"></datatable-column>\n    <datatable-column id=\"datatable-column-3\" label=\"Column 3\" :formatter=\"formatCurrency\"></datatable-column>\n</datatable>\n```\n\nThe format function signature expects one parameter which will be the value of the cell. Vuetiful comes with a few formatters already built in such as **currency**, **datetime**, **dateShort**, **dateLong**, **datetimeShort**, **datetimeLong**.\n\n**Note:** The **datetime** formatter requires a format string parameter (eg. \"DD MMM YYYY hh:mm\"). Because the datatable only sends one parameter through to the formatter function you would have to wrap the formatter in a function before being bound to a column. eg:\n\n```javascript\nvar formatters = vuteiful.formatters;\n\nnew Vue({\n\n    el: \"#app\",\n\n    data: function() {\n        return {\n            /* replace with real data */\n            data: []\n        };\n    },\n\n    methods: {\n\n        /* \n        We need to wrap the datetime formatter in a function that just expects \n        the value parameter. This way we can tell the datetime formatter which format \n        we'd like the data displayed in.\n        */\n        customDatetimeFormatter: function(value) {\n            return formatters.datetime(value, \"DD MMMM YYYY h:mm a\");\n        }\n\n    }\n});\n```\n\n\n## Sorting Data\n\nThe datatable allows you to easily sort your data. To sort by a particular column, click the column header at the top of the table. The data will be displayed in ascending order by default. Clicking the same column header again will reverse the sort order (descending).\n\n\n## Grouping Data\n\nIn addition to sorting, the datatable allows you to group your data by multiple columns. \n\nThis probably best illustrated with an example. Let's say you have an online T-Shirt business and want to see specific profiles for purchases. Your purchases dataset may have the following columns: **Name**, **Email**, **Product Name**, **Quantity**, **Purchase Date**. Now that you have your data you may want to know which customers bought more than one of a particular T-Shirt on any given day. The process for this would be to group the data by **Purchase Date**, then group those groups by **Product Name**, then finally group the resulting group by **Quantity**. This can be repeated for as many columns as you have in any order.\n\nTo group by a particular column, simply drag the column header from the top of the table into the middle of the table. Keep repeating this step for each subsequent column you would like to group by. The columns being grouped on will be displayed at the top of the table under the headers.\n\nTo remove a column from the grouping, click the **x** button on the corresponding group at the top of the table.\n\n![Grouping](https://cloud.githubusercontent.com/assets/11718453/24491151/52d4ef22-1569-11e7-9f62-9f2235467cf4.png)\n\n## Editing Data\n\nA quick note on editing data. When `editable` is set to true on the datatable, the default bahaviour of the table is to convert all the cells into textboxes and remove data formatting. In other words the user will be able to edit the raw data. Typing into the textbox will mutate (change) the data in the array bound to the `source` prop. \n\n\n## Customizing the Datatable\n\nThe datatable is very flexible with customizing how your users interact with the component. One of the ways you can change the component to suit your requirements is templating. This component makes use of Vue's scoped templates to allow you to define your own markup (and custom components) for column headers and cells.\n\n### Header Templates\n\nThe default slot on the `datatable-column` component allows you to easily customize the content displayed in the column header. Let's look at an example where we want to have a column to allow users to select rows using a checkbox.\n\n```html\n<datatable-column id=\"select-all\" width=\"3.25rem\" :sortable=\"false\" :groupable=\"false\">\n    <checkbox id=\"select-all-checkbox\" v-model=\"selectAll\"></checkbox>\n</datatable-column>\n```\n\n**Note:** The `checkbox` component used in the example above is also part of the Vuetiful component framework. Refer to **components/toggles** for how to use `checkbox`, `radio` and `toggle` components.\n\n### Cell Templates\n\nHere is where the flexibility of this component really comes in handy. Sometimes you may want to go beyond just using the default cell template and a custom formatter. Custom cell templates allow you to define specific types of markup or custom components to be used for a particular column instead of the default one built into the component. By default, each cell gets a different template for view and edit modes respectively. Here's what gets rendered into each cell by default:\n\n#### View Mode\n```html\n<span>{{ column.formatData(row[column.id]) }}</span>\n```\n\n#### Edit Mode\n```html\n<input type=\"text\" v-model=\"row[column.id]\" />\n```\n\nTo override this all we have to do is define a template in our datatable and tell it to slot into the column we want. Here's an example extending on the custom header template example above:\n\n```html\n<datatable :source=\"customers.data\" :editable=\"customers.editable\">\n    <datatable-column id=\"select-all\" width=\"3.25rem\" :sortable=\"false\" :groupable=\"false\">\n        <checkbox id=\"select-all-checkbox\" v-model=\"selectAll\"></checkbox>\n    </datatable-column>\n\n    <!-- Define the rest of our columns here -->\n\n    <template slot=\"sel\" scope=\"cell\">\n        <div class=\"checkable-column\">\n            <checkbox :id=\"cell.row.id\" :val=\"cell.row\" v-model=\"customers.selected\"></checkbox>\n        </div>\n    </template>\n</datatable>\n```\n\nNotice how the `slot=\"select-all\"` prop on the `template` matches the `id=\"select-all\"` prop of the column we want to define a custom template for. Within your custom template a `cell` variable will be available for binding. Here's an outline of the properties available on the `cell` variable:\n\n| Property | Type | Description |\n| -------- | ---- | ----------- |\n| row | object | The current object that represents this row. This object will have all the properties on it as defined in your data source. This is handy for accessing values for other columns in the current row. |\n| column | datatable-column | This is the viewmodel of the current column that the repeater is using to get the value in the row. Calling `formatData(value)` on the column will call the formatter function defined in your `datatable-column`. |\n| value | any | This is just some sugar to simplify getting the value for the cell. It is equivalent to calling `row[column.id]` | \n\nAt this point you may be wondering how to define a different template for when the datatable is in edit mode. The short answer is: you don't have to. Just use Vue's `v-if` and `v-else` conditional bindings to change the content of the cell. Using this approach means you are in complete control over what gets rendered for the cell. You could even change the components based on the type of value that is in the current cell. Let's see what conditional rendering based on the datatables `editable` prop would look like:\n\n```html\n<template slot=\"sel\" scope=\"cell\">\n    <div v-if=\"customers.editable\">\n        <!-- Put your custom edit template here -->\n    </div>\n    <div v-else>\n        <!-- Put your custom view template here -->\n    </div>\n</template>\n```\n\n## Aggregation\nThe datatable component supports aggregate functions out-of-the-box. The aggregate functions included are listed below.\n\n| Function | Supported Types | Formatted Output |\n| -------- | --------------- | ----------- |\n| min | number, date | yes |\n| max | number, date | yes |\n| count | n/a | no |\n| average (mean) | number | yes |\n| median | number | yes |\n| total | number | yes |\n| variance | number | no |\n| standard deviation | number | no |\n\n**Note:** *Formatted Output tells the aggregator to format the result for the current column before rendering it in the view.*\n\nIf an aggregate function is applied to a column with an unsupported type in it, a null value will be displayed. \n\nTo apply aggregation to a column(s) you simply bind an array of aggregators to each column you want to aggregate. Here's how you would use some of the built-in aggregate functions to calculate the **min**, **max** and **total**. \n\n```javascript\nvar aggregators = vuetiful.aggregators;\n\nnew Vue({\n\n    el: \"#app\",\n\n    data: function() {\n        return {\n            /* ... */\n            aggregators: [\n                aggregators.min,\n                aggregators.max,\n                aggregators.total\n            ]\n        };\n    }\n});\n```\n\nThen in your view you would bind `:aggregators=\"aggregators\"` like so on any column you would like to apply these aggregate functions to. Of course you can apply different combinations of aggregation to different columns.\n\n![Aggregation](https://cloud.githubusercontent.com/assets/11718453/24491113/0b46ad26-1569-11e7-9eeb-706b3539f770.png)\n\n\n## Pagination\n\nPagination is particularly useful for when you need to display a large set of data but don't want to take up large amounts of screen real-estate displaying it all. It also means our datatable has to do less work by rendering smaller chunks of data at a time. \n\nYou may have noticed that there is no option on the datatable for pagination. This is because pagination is not built into the datatable component. The `paginator` is actually a standalone component that allows you to paginate data and inject any child component into it's scope. Given that the `paginator` is a separate component I won't go into too much detail here on how to use it but I will show you a simple example of bundling it with the `datatable`. To see how the `paginator` component works in detail, check out the **components/paginator** folder.\n\nHere's a basic example of using the paginator with the `datatable`:\n\n```html\n<paginator :source=\"customers.data\" :page-size=\"5\">\n    <template scope=\"page\">\n        <!-- Notice here how we bind the datatable source to the data property exposed from the paginator -->\n        <!-- this ensures that the only data the datatable is aware of is the current page -->\n        <datatable id=\"data-table-main\" :source=\"page.data\">\n            <!-- Datatable columns & templates -->\n        </datatable>\n    </template>\n</paginator>\n```\n\nAll we've done here is bound the `paginator` to the root data source instead of the `datatable`. The `datatable` source is then bound to the data exposed by the current page.\n\n\n## Optimization\n\nBecause the datatable component is designed to display large amounts of complex data it wouldn't make sense to have everything running in real-time on large sets of data. Doing so would result in a noticable impact on performance. For this reason you can provide a `threshold` value on the datatable. The threshold tells the datatable to enable performace optimizations as soon as the number of rows in the dataset exceeds the threshold value. Once the threshold is exceeded a few things will happen:\n\n1. Typing in the filter box at the bottom of the table will no longer filter the data in real-time. The filter won't be applied until the enter key is pressed or the textbox loses focus.\n2. Typing in an editable cell will no longer edit data in real-time. Changes won;t be applied to the data until the enter key is pressed or the cell loses focus.\n\n"
  },
  {
    "path": "src/components/datetime-picker/datetime-picker.vue",
    "content": "<template>\n    <floating-panel class=\"date-picker\" :visible=\"visible\">\n        <input type=\"text\" slot=\"host\" v-model=\"formattedValue\" @focus=\"show()\" readonly>\n        <p slot=\"content\" @click=\"updateValue(new Date())\">Hello</p>\n    </floating-panel>\n</template>\n\n<script>\n    import { isValid, format } from \"date-fns\";\n\n    const EPOCH_MIN = new Date(-8640000000000000);\n    const EPOCH_MAX = new Date(8640000000000000);\n\n    export default {\n        props: {\n\n            value: {\n                required: true\n            },\n\n            type: {\n                type: String,\n                default: \"date\"\n            },\n\n            format: {\n                type: String,\n                default: \"DD-MM-YYYY\"\n            },\n\n            minDate: {\n                type: Date,\n                default: () => EPOCH_MIN\n            },\n\n            maxDate: {\n                type: Date,\n                default: () => EPOCH_MAX\n            },\n\n            minHour: {\n                type: Number,\n                default: 0\n            },\n\n            maxHour: {\n                type: Number,\n                default: 23\n            },\n\n            minMinute: {\n                type: Number,\n                default: 0\n            },\n\n            maxMinute: {\n                type: Number,\n                default: 59\n            }\n\n        },\n\n        data() {\n            return {\n                visible: false\n            }\n        },\n\n        computed: {\n            formattedValue() {\n                return this.value && isValid(this.value) ? format(this.value, this.format) : null;\n            }\n        },\n\n        methods: {\n\n            updateValue(value) {\n                this.$emit(\"input\", value);                \n            },\n\n            show() {\n                this.visible = true;\n\n                let listener = (event) => {\n                    event.stopPropagation();\n\n                    if (!this.$el.contains(event.target)) {\n                        this.visible = false;\n                        document.removeEventListener(\"click\", listener);\n                    }\n                };\n\n                document.addEventListener(\"click\", listener);\n            }\n        }\n    }\n</script>"
  },
  {
    "path": "src/components/dynamic/dynamic.js",
    "content": "export default {\n    functional: true,\n\n    props: {\n        component: {\n            type: Object,\n            required: true\n        }\n    },\n\n    render: (createElement, context) => {\n        let component = context.props.component;\n\n        if (!component.node) {\n            console.warn(\"Dynamic element not rendered. No node name specified.\");\n            return;\n        }\n\n        let definition = {\n            attrs: component.attrs,\n            props: component.props,\n            domProps: component.domProps,\n            on: component.on\n        };\n\n        if (!component.children) {\n            return createElement(component.node, definition);\n        }\n\n        let children = component.children.map(child => {\n            return createElement(\"dynamic\", {\n                props: {\n                    component: child\n                }\n            });\n        });\n\n        return createElement(component.node, definition, children);\n    }\n}"
  },
  {
    "path": "src/components/floating-panel/floating-panel.vue",
    "content": "<template>\n    <div class=\"float\">\n        <slot name=\"host\"></slot>\n        <transition name=\"float\">\n            <div class=\"float-panel\" v-show=\"visible\">\n                <slot name=\"content\"></slot>\n            </div>\n        </transition>\n    </div>\n</template>\n\n<script>\n    export default {\n        props: {\n\n            visible: {\n                type: Boolean,\n                default: false\n            },\n\n            position: {\n                type: String,\n                default: \"bottom left\"\n            },\n\n            showArrow: {\n                type: Boolean,\n                default: false\n            }\n            \n        }\n    }\n</script>\n\n<style lang=\"scss\">\n\n    .float {\n        display: inline-block;\n        position: relative;\n    }\n\n    .float-panel {\n        display: block;\n        position: absolute;\n        top: 100%;\n        left: 0;\n        min-width: 250px;\n        min-height: 50px;\n        margin-top: 5px;\n        background-color: #FFFFFF;\n        border-radius: 2px;\n        box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.2);\n        z-index: 10;\n        transform-origin: top left;\n    }\n\n    .float-enter,\n    .float-leave-active {\n        opacity: 0;\n        transform: scale(0, 0);    \n    }\n\n    .float-enter-active,\n    .float-leave-active {\n        transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n    }\n\n</style>"
  },
  {
    "path": "src/components/modal/modal.vue",
    "content": "<template>\n    <transition name=\"modal-transition\">\n        <div class=\"modal-shade\" layout=\"row center-center\" v-show=\"showing\">\n            <div class=\"modal\">\n                <div class=\"modal-header\">\n                    <div layout=\"row center-justify\">\n                        <span class=\"modal-title\" self=\"size-x1\">{{ title }}</span>\n                        <div>\n                            <slot name=\"modal-header\"></slot>\n                            <div class=\"modal-close-button\"></div>\n                        </div>\n                    </div>\n                </div>\n                <div class=\"modal-body\">\n                    <slot></slot>\n                </div>\n                <div class=\"modal-footer\">\n                    <slot name=\"modal-footer\"></slot>\n                </div>\n            </div>\n        </div>\n    </transition>\n</template>\n\n<script>\n    export default {\n\n        props: {\n\n            title: {\n                type: String,\n                required: true\n            }\n\n        },\n\n        data() {\n            return {\n                showing: false\n            };\n        },\n\n        methods: {\n\n            open() {\n                this.showing = true;\n                this.$emit(\"open\", this);\n            },\n\n            close() {\n                this.showing = false;\n                this.$emit(\"close\", this);\n            }\n\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .modal-transition {\n\n        &-enter-active,\n        &-leave-active {\n            transition: opacity 200ms ease-out;\n\n            & .modal {\n                transition: transform 200ms ease-out;\n            }\n        }\n\n        &-enter,\n        &-leave {\n            opacity: 0;\n\n            & .modal {\n                transform: scale(0.8, 0.8);\n            }\n        }\n    }\n\n    .modal-shade {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background-color: rgba(0, 0, 0, 0.3);\n        z-index: 1000;\n    }\n\n    .modal {\n        width: 640px;\n        background-color: $colour-background;\n        border-radius: $border-radius;\n        box-shadow: 0 0 1px 2px rgba(0, 0, 0, 0.1);\n        overflow: hidden;\n    }\n\n    .modal-header,\n    .modal-body,\n    .modal-footer {\n        padding: 1rem;\n    }\n\n    .modal-footer {\n        background-color: $colour-background-medium;\n        border-top: 1px solid $colour-border-light;\n    }\n\n    .modal-body {\n\n    }\n\n    .modal-title {\n        font-weight: 600;\n    }\n\n</style>"
  },
  {
    "path": "src/components/paginator/paginator.vue",
    "content": "<template>\n    <div class=\"paginator\">\n        <div class=\"paginator-body\">\n            <slot :data=\"data\" :page-number=\"pageNumber\"></slot>\n        </div>\n        <div class=\"paginator-footer\" layout=\"row center-justify\">\n            <div class=\"paginator-button paginator-page-previous\" @click=\"movePrevious\">\n                <span>Prev</span>\n            </div>\n            <div class=\"paginator-page-numbers\">\n                <div class=\"paginator-button paginator-page-number\" :class=\"{ 'active': num === pageNumber }\" v-for=\"num in pages.length\" @click=\"moveTo(num)\">\n                    <span>{{ num }}</span>\n                </div>\n            </div>\n            <div class=\"paginator-button paginator-page-next\" @click=\"moveNext\">\n                <span>Next</span>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    import filterBy from \"../../utilities/filter-by.js\";\n    import page from \"../../utilities/page.js\";\n\n    export default {\n\n        props: {\n\n            source: {\n                type: Array,\n                default: () => []\n            },\n\n            pageSize: {\n                type: Number,\n                default: 25\n            },\n\n            filter: {\n                type: String\n            }\n\n        },\n\n        data() {\n            return {\n                index: 0\n            };\n        },\n\n        computed: {\n\n            pages() {\n                let data = this.source;\n\n                if (this.filter) {\n                    data = filterBy(data, this.filter);\n                }\n\n                let pages = page(data, this.pageSize);\n\n                // need to reset the page number if the data length changes\n                // otherwise the index will be outside the bounds of the data\n                if (this.pageNumber > pages.length) {\n                    this.pageNumber = 1;\n                }\n\n                return pages;\n            },\n\n            pageNumber: {\n                get() {\n                    return this.index + 1;\n                },\n                set(value) {\n                    this.index = value - 1;\n                    this.$emit(\"page-changed\", value);\n                }\n            },\n\n            data() {\n                return this.pages[this.index];\n            }\n\n        },\n\n        methods: {\n\n            movePrevious() {\n                this.pageNumber -= this.pageNumber > 1 ? 1 : 0;\n            },\n\n            moveNext() {\n                this.pageNumber += (this.pageNumber != this.pages.length) ? 1 : 0;\n            },\n\n            moveTo(pageNumber) {\n                if (pageNumber > 0 && pageNumber <= this.pages.length) {\n                    this.pageNumber = pageNumber;\n                }\n            }\n\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .paginator {\n        border: 1px solid $colour-border;\n        border-radius: $border-radius;\n    }\n\n    .paginator-footer {\n        padding: 1rem;\n        background-color: $colour-background-medium;\n        border-top: 1px solid $colour-border;\n    }\n\n    .paginator-button {\n        display: inline-block;\n        min-width: 1.5em;\n        padding: 0 0.5rem;\n        font-weight: 600;\n        background-color: $colour-border;\n        border-radius: $border-radius;\n        cursor: pointer;\n\n        &.active {\n            color: $colour-font-negative;\n            background-color: $colour-primary;\n        }\n    }\n\n    .paginator-page-number {\n        margin: 0 0.25rem;\n    }\n\n</style>"
  },
  {
    "path": "src/components/paginator/readme.md",
    "content": ""
  },
  {
    "path": "src/components/panel/panel.vue",
    "content": "<template>\n    <div class=\"panel\">\n        <div class=\"panel-header\">\n            <div layout=\"row center-justify\">\n                <span class=\"panel-title\" self=\"size-x1\">{{ title }}</span>\n                <div>\n                    <slot name=\"panel-header\"></slot>\n                </div>\n            </div>\n        </div>\n        <div class=\"panel-body\">\n            <slot></slot>\n        </div>\n        <div class=\"panel-footer\" v-if=\"$slots.panelFooter\">\n            <slot name=\"panel-footer\"></slot>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        props: {\n\n            title: {\n                type: String,\n                required: true\n            }\n\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .panel {\n        width: 100%;\n        min-height: 150px;\n        background-color: $colour-background;\n        border: 1px solid $colour-border;\n        border-radius: $border-radius;\n    }\n\n    .panel-header,\n    .panel-body,\n    .panel-footer {\n        padding: 0.75rem 1rem;\n    }\n\n    .panel-header,\n    .panel-footer {\n        background-color: $colour-background-medium;\n    }\n\n    .panel-header {\n        border-bottom: 1px solid $colour-border;\n    }\n\n    .panel-footer {\n        border-top: 1px solid $colour-border;\n    }\n\n    .panel-body {\n\n    }\n\n    .panel-title {\n        font-weight: 600;\n    }\n\n</style>"
  },
  {
    "path": "src/components/tab-control/tab-control.vue",
    "content": "<template>\n    <div class=\"tab-control\">\n        <div class=\"tabs-list\" layout=\"row center-justify\">\n            <div self=\"size-x1\" layout=\"row center-left\">\n                <div v-for=\"tab in tabs\" class=\"tab-item\" :class=\"{ active: tab.selected }\" @click=\"selectTab(tab)\">\n                    <slot :name=\"tab.id\" :value=\"tab\">\n                        <span>{{ tab.label }}</span>\n                    </slot>\n                </div>\n            </div>\n            <div>\n                <slot name=\"tabs-extra\"></slot>\n            </div>\n        </div>\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        data() {\n            return {\n                tabs: [],\n                selectedTabId: null\n            };\n        },\n\n        computed: {\n\n            selectedTab() {\n                return this.tabs.find(tab => tab.id === this.selectedTabId);\n            }\n\n        },\n\n        methods: {\n\n            addTab(tab) {\n                this.tabs.push(tab);\n            },\n\n            removeTab(tab) {\n                let index = this.tabs.indexOf(tab);\n                this.tabs.splice(index, 1);\n            },\n\n            selectTab(tab) {\n                this.selectedTabId = tab.id;\n                this.$emit(\"tab-change\", tab);\n            }\n\n        },\n\n        mounted() {\n            if (this.tabs.length > 0) {\n                this.selectedTabId = this.tabs[0].id;\n            }\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .tab-control {\n        display: block;\n        border: 1px solid $colour-border;\n        border-radius: $border-radius;\n    }\n\n    .tabs-list {\n        background-color: #FAFAFA;\n        border-bottom: 1px solid $colour-border;\n    }\n\n    .tab-item {\n        position: relative;\n        padding: 0.75rem 1rem;\n        font-weight: 600;\n        border-right: 1px solid $colour-border;\n        cursor: pointer;\n\n        &:after {\n            position: absolute;\n            display: none;\n            content: \" \";\n            bottom: -1px;\n            left: 0;\n            width: 100%;\n            height: 1px;\n            background-color: $colour-background;\n        }\n\n        &.active {\n            background-color: $colour-background;\n\n            &:after {\n                display: block;\n            }\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/components/tab-control/tab-pane.vue",
    "content": "<template>\n    <div class=\"tab-pane\" v-if=\"selected\">\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        props: {\n\n            id: {\n                type: String,\n                required: true\n            },\n\n            label: {\n                type: String,\n                required: true\n            }\n\n        },\n\n        computed: {\n\n            selected() {\n                return this.$parent.selectedTab === this;\n            }\n\n        },\n\n        created() {\n            let addTab = this.$parent.addTab;\n\n            if (!addTab) {\n                console.warn(\"A tab-pane must be registered in a tab-control.\");\n                return;\n            }\n\n            addTab(this);\n        },\n\n        destroyed() {\n            this.$parent.removeTab(this);\n        }\n\n    }\n</script>\n\n<style lang=\"scss\">\n\n    .tab-pane {\n        min-height: 2rem;\n        padding: 1rem;\n    }\n\n</style>"
  },
  {
    "path": "src/components/toggles/checkbox.vue",
    "content": "<template>\n    <div class=\"checkbox\">\n        <input type=\"checkbox\" :id=\"id\" :name=\"id\" :disabled=\"disabled\" :value=\"value\" v-model=\"checked\">\n        <label :for=\"id\"></label>\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    import checkable from \"../../mixins/checkable.js\";\n\n    export default {\n\n        mixins: [ checkable ]\n\n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .checkbox {\n        display: inline-block;\n        margin-right: 1rem;\n        vertical-align: baseline;\n\n        & label {\n            position: relative;\n            display: inline-block;\n            width: 1.25rem;\n            height: 1.25rem;\n            margin-right: 0.25rem;\n            background-color: $colour-background;\n            border: 1px solid $colour-border;\n            border-radius: $border-radius;\n            vertical-align: text-bottom;\n            cursor: pointer;\n            user-select: none;\n\n            &:after {\n                position: absolute;\n                display: block;\n                content: \" \";\n                width: 0.375rem;\n                height: 0.75rem;\n                top: 0.125rem;\n                left: 0.4rem;\n                border-right: 0.2rem solid white;\n                border-bottom: 0.2rem solid white;\n                opacity: 0;\n                transform: rotate(45deg);\n                transition: opacity 150ms ease-out;\n            }\n        }\n\n        & input[type=\"checkbox\"] {\n            display: none !important;\n\n            &:checked {\n                \n                & + label {\n                    background-color: $colour-primary;\n                    border-color: $colour-primary;\n\n                    &:after {\n                        opacity: 1;\n                    }\n                }\n            }\n\n            &:disabled {\n\n                & + label {\n                    background-color: #FAFAFA;\n                    cursor: not-allowed;\n                }\n            }\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/components/toggles/radio.vue",
    "content": "<template>\n    <div class=\"radio\">\n        <input type=\"radio\" :id=\"id\" :name=\"id\" :disabled=\"disabled\" :value=\"value\" v-model=\"checked\">\n        <label :for=\"id\"></label>\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    import checkable from \"../../mixins/checkable.js\";\n\n    export default {\n\n        mixins: [ checkable ]\n        \n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .radio {\n        display: inline-block;\n        margin-right: 1rem;\n        vertical-align: baseline;\n\n        & label {\n            position: relative;\n            display: inline-block; \n            width: 1.25rem;\n            height: 1.25rem;\n            background-color: $colour-background;\n            border: 1px solid $colour-border;\n            border-radius: 50%;\n            vertical-align: text-bottom;\n            cursor: pointer;\n            user-select: none;\n\n            &:after {\n                position: absolute;\n                display: block;\n                content: \" \";\n                width: 0.5rem;\n                height: 0.5rem;\n                top: 50%;\n                left: 50%;\n                margin-top: -0.25rem;\n                margin-left: -0.25rem;\n                background-color: $colour-background;\n                border-radius: 50%;\n            }\n        }\n\n        & input[type=\"radio\"] {\n            display: none !important;\n\n            &:checked {\n                \n                & + label {\n                    background-color: $colour-primary;\n                    border-color: $colour-primary;\n                }\n            }\n\n            &:disabled {\n\n                & + label {\n                    background-color: #FAFAFA;\n                    cursor: not-allowed;\n                }\n            }\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/components/toggles/readme.md",
    "content": "# Toggles\n\nThis docucumentation will cover 3 components which all share the *toggle* behaviour"
  },
  {
    "path": "src/components/toggles/toggle.vue",
    "content": "<template>\n    <div class=\"toggle\">\n        <input type=\"checkbox\" :id=\"id\" :name=\"id\" :disabled=\"disabled\" :value=\"value\" v-model=\"checked\">\n        <label :for=\"id\"></label>\n        <slot></slot>\n    </div>\n</template>\n\n<script>\n    import checkable from \"../../mixins/checkable.js\";\n\n    export default {\n\n        mixins: [ checkable ]\n        \n    }\n</script>\n\n<style lang=\"scss\">\n    @import \"../../assets/styles/abstract/_variables.scss\";\n\n    .toggle {\n        display: inline-block;\n        margin-right: 1rem;\n        vertical-align: baseline;\n\n        & label {\n            position: relative;\n            display: inline-block; \n            width: 2.15rem;\n            height: 1.25rem;\n            background-color: $colour-background;\n            border: 1px solid $colour-border;\n            border-radius: 0.625rem;\n            vertical-align: text-bottom;\n            cursor: pointer;\n            user-select: none;\n\n            &:after {\n                position: absolute;\n                display: block;\n                content: \" \";\n                width: 0.8rem;\n                height: 0.8rem;\n                top: 50%;\n                left: 0.25rem;\n                \n                background-color: $colour-border;\n                border-radius: 50%;\n                transform: translate(0, -50%);\n                transition: transform 150ms ease-out;\n            }\n        }\n\n        & input[type=\"checkbox\"] {\n            display: none !important;\n\n            &:checked {\n                \n                & + label {\n                    background-color: $colour-primary;\n                    border-color: $colour-primary;\n\n                    &:after {\n                        background-color: $colour-background;\n                        transform: translate(0.75rem, -50%);\n                    }\n                }\n            }\n\n            &:disabled {\n\n                & + label {\n                    background-color: #FAFAFA;\n                    cursor: not-allowed;\n                }\n            }\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/directives/directives.js",
    "content": "import Drag from \"./v-drag\";\n\nexport default {\n    drag: Drag\n}"
  },
  {
    "path": "src/directives/v-drag.js",
    "content": "\nfunction genericHandler(event) {\n\n}\n\nconst eventHandlerMap = {\n    start: {\n        eventName: \"dragstart\",\n        draggable: true,\n        callback: genericHandler\n    },\n    drag: { \n        eventName: \"drag\",\n        draggable: true,\n        callback: genericHandler\n    },\n    enter: { \n        eventName: \"dragenter\",\n        callback: genericHandler\n    },\n    leave: { \n        eventName: \"dragleave\",\n        callback: genericHandler\n    },\n    over: { \n        eventName: \"dragover\",\n        callback: genericHandler\n    },\n    drop: { \n        eventName: \"drop\",\n        callback: genericHandler\n    },\n    end: { \n        eventName: \"dragend\",\n        draggable: true,\n        callback: genericHandler\n    }\n};\n\nexport default {\n\n    bind(element, binding, vNode) {\n        let eventType = binding.arg.toLowerCase();\n\n        if (!(eventType in eventHandlerMap)) {\n            console.warn(\"Event not supported\");\n            return;\n        }  \n\n        let handler = eventHandlerMap[eventType];\n\n        if (handler.draggable) {\n            element.setAttribute(\"draggable\", true);\n        }\n\n        let callback = binding.value;\n\n        if (typeof (callback) !== \"function\") {\n            callback = function (event) { };\n        }\n        \n        element.addEventListener(handler.eventName, event => {\n            handler.callback.call(element, event);\n            callback.call(element, event);\n\n            return false;\n        }, false);\n\n    }\n\n}"
  },
  {
    "path": "src/formatters/currency.js",
    "content": "import currencies from \"../maps/currencies\";\n\nexport default function currency(value, precision, currency) {\n\n    precision = precision || 2;\n\n    let parsed = parseFloat(value);\n\n    if (isNaN(parsed)) {\n        return value;\n    }\n\n    let symbol = currency ? currencies[currency.toUpperCase()] : currencies.USD;\n\n    return symbol + parsed.toFixed(precision).replace(/(\\d)(?=(\\d{3})+\\.)/g, \"$1,\");\n}"
  },
  {
    "path": "src/formatters/date-long.js",
    "content": "import datetime from \"./datetime\";\n\nexport default function dateShort(value) {\n    return datetime(value, \"D MMMM YYYY\");\n}"
  },
  {
    "path": "src/formatters/date-short.js",
    "content": "import datetime from \"./datetime\";\n\nexport default function dateShort(value) {\n    return datetime(value, \"DD/MM/YYYY\");\n}"
  },
  {
    "path": "src/formatters/datetime.js",
    "content": "import { format } from \"date-fns\";\n\nexport default function datetime(value, pattern) {\n    return format(value, pattern);\n}"
  },
  {
    "path": "src/formatters/formatters.js",
    "content": "import currency from \"./currency\";\nimport datetime from \"./datetime\";\nimport dateShort from \"./date-short\";\nimport dateLong from \"./date-long\";\n\nexport default {\n    currency,\n    datetime,\n    dateShort,\n    dateLong\n}"
  },
  {
    "path": "src/main.js",
    "content": "import \"./polyfills\";\n\nimport \"flex-layout-attribute\";\nimport \"./assets/styles/site.scss\";\n\nimport components from \"./components/components\";\nimport directives from \"./directives/directives\";\n\n// Exposed modules\nimport aggregators from \"../src/aggregators/aggregators\";\nimport formatters from \"../src/formatters/formatters\";\nimport maps from \"../src/maps/maps\";\n\nfunction registerComponents(Vue) {\n    for (let component in components) {\n        let definition = components[component];\n\n        Vue.component(component, definition);\n    }\n}\n\nfunction registerDirectives(Vue) {\n    for (let directive in directives) {\n        let definition = directives[directive];\n\n        Vue.directive(directive, definition);\n    }\n}\n\nexport default {\n\n    install(Vue) {\n        registerComponents(Vue);\n        registerDirectives(Vue);\n    },\n\n    // Expose to global scope\n    aggregators,\n    formatters,\n    maps\n\n}"
  },
  {
    "path": "src/maps/currencies.js",
    "content": "export default {\n    AED: \"د.إ\",\n    AFN: \"؋\",\n    ALL: \"L\",\n    ANG: \"ƒ\",\n    AOA: \"Kz\",\n    ARS: \"$\",\n    AUD: \"$\",\n    AWG: \"ƒ\",\n    AZN: \"₼\",\n    BAM: \"KM\",\n    BBD: \"$\",\n    BDT: \"৳\",\n    BGN: \"лв\",\n    BHD: \".د.ب\",\n    BIF: \"FBu\",\n    BMD: \"$\",\n    BND: \"$\",\n    BOB: \"Bs.\",\n    BRL: \"R$\",\n    BSD: \"$\",\n    BTN: \"Nu.\",\n    BWP: \"P\",\n    BYR: \"p.\",\n    BZD: \"BZ$\",\n    CAD: \"$\",\n    CDF: \"FC\",\n    CHF: \"Fr.\",\n    CLP: \"$\",\n    CNY: \"¥\",\n    COP: \"$\",\n    CRC: \"₡\",\n    CUC: \"$\",\n    CUP: \"₱\",\n    CVE: \"$\",\n    CZK: \"Kč\",\n    DJF: \"Fdj\",\n    DKK: \"kr\",\n    DOP: \"RD$\",\n    DZD: \"دج\",\n    EEK: \"kr\",\n    EGP: \"£\",\n    ERN: \"Nfk\",\n    ETB: \"Br\",\n    EUR: \"€\",\n    FJD: \"$\",\n    FKP: \"£\",\n    GBP: \"£\",\n    GEL: \"₾\",\n    GGP: \"£\",\n    GHC: \"₵\",\n    GHS: \"GH₵\",\n    GIP: \"£\",\n    GMD: \"D\",\n    GNF: \"FG\",\n    GTQ: \"Q\",\n    GYD: \"$\",\n    HKD: \"$\",\n    HNL: \"L\",\n    HRK: \"kn\",\n    HTG: \"G\",\n    HUF: \"Ft\",\n    IDR: \"Rp\",\n    ILS: \"₪\",\n    IMP: \"£\",\n    INR: \"₹\",\n    IQD: \"ع.د\",\n    IRR: \"﷼\",\n    ISK: \"kr\",\n    JEP: \"£\",\n    JMD: \"J$\",\n    JPY: \"¥\",\n    KES: \"KSh\",\n    KGS: \"лв\",\n    KHR: \"៛\",\n    KMF: \"CF\",\n    KPW: \"₩\",\n    KRW: \"₩\",\n    KYD: \"$\",\n    KZT: \"₸\",\n    LAK: \"₭\",\n    LBP: \"£\",\n    LKR: \"₨\",\n    LRD: \"$\",\n    LSL: \"M\",\n    LTL: \"Lt\",\n    LVL: \"Ls\",\n    MAD: \"MAD\",\n    MDL: \"lei\",\n    MGA: \"Ar\",\n    MKD: \"ден\",\n    MMK: \"K\",\n    MNT: \"₮\",\n    MOP: \"MOP$\",\n    MUR: \"₨\",\n    MVR: \"Rf\",\n    MWK: \"MK\",\n    MXN: \"$\",\n    MYR: \"RM\",\n    MZN: \"MT\",\n    NAD: \"$\",\n    NGN: \"₦\",\n    NIO: \"C$\",\n    NOK: \"kr\",\n    NPR: \"₨\",\n    NZD: \"$\",\n    OMR: \"﷼\",\n    PAB: \"B/.\",\n    PEN: \"S/.\",\n    PGK: \"K\",\n    PHP: \"₱\",\n    PKR: \"₨\",\n    PLN: \"zł\",\n    PYG: \"Gs\",\n    QAR: \"﷼\",\n    RMB: \"￥\",\n    RON: \"lei\",\n    RSD: \"Дин.\",\n    RUB: \"₽\",\n    RWF: \"R₣\",\n    SAR: \"﷼\",\n    SBD: \"$\",\n    SCR: \"₨\",\n    SDG: \"ج.س.\",\n    SEK: \"kr\",\n    SGD: \"$\",\n    SHP: \"£\",\n    SLL: \"Le\",\n    SOS: \"S\",\n    SRD: \"$\",\n    SSP: \"£\",\n    STD: \"Db\",\n    SVC: \"$\",\n    SYP: \"£\",\n    SZL: \"E\",\n    THB: \"฿\",\n    TJS: \"SM\",\n    TMT: \"T\",\n    TND: \"د.ت\",\n    TOP: \"T$\",\n    TRL: \"₤\",\n    TRY: \"₺\",\n    TTD: \"TT$\",\n    TVD: \"$\",\n    TWD: \"NT$\",\n    TZS: \"TSh\",\n    UAH: \"₴\",\n    UGX: \"USh\",\n    USD: \"$\",\n    UYU: \"$U\",\n    UZS: \"лв\",\n    VEF: \"Bs\",\n    VND: \"₫\",\n    VUV: \"VT\",\n    WST: \"WS$\",\n    XAF: \"FCFA\",\n    XBT: \"Ƀ\",\n    XCD: \"$\",\n    XOF: \"CFA\",\n    XPF: \"₣\",\n    YER: \"﷼\",\n    ZAR: \"R\",\n    ZWD: \"Z$\",\n    BTC: \"฿\"\n};"
  },
  {
    "path": "src/maps/maps.js",
    "content": "import currencies from \"./currencies\";\n\nexport default {\n    currencies\n}"
  },
  {
    "path": "src/mixins/checkable.js",
    "content": "\nexport default {\n\n    model: {\n        prop: \"source\",\n        event: \"change\"\n    },\n\n    props: {\n\n        id: {\n            type: String,\n            required: true\n        },\n\n        source: {\n            required: true\n        },\n\n        value: {\n            required: false\n        },\n\n        disabled: {\n            type: Boolean,\n            default: false\n        }\n\n    },\n\n    data() {\n        return {\n            proxy: false\n        };\n    },\n\n    computed: {\n\n        checked: {\n            get() {\n                return this.source;\n            },\n            set(value) {\n                this.proxy = value;\n                this.$emit(\"change\", this.proxy);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "src/polyfills.js",
    "content": "// Symbols\nimport \"core-js/fn/symbol\";\nimport \"core-js/fn/symbol/iterator\";\n\n// Arrays\nimport \"core-js/fn/array/find\";"
  },
  {
    "path": "src/services/calendar.js",
    "content": "import isValid from \"date-fns/is_valid\";\nimport isWithinRange from \"date-fns/is_within_range\";\nimport startOfMonth from \"date-fns/start_of_month\";\nimport endOfMonth from \"date-fns/end_of_month\";\nimport eachDay from \"date-fns/each_day\";\nimport addMonths from \"date-fns/add_months\";\nimport subMonths from \"date-fns/sub_months\";\nimport setMonth from \"date-fns/set_month\";\n\nimport pageBy from \"../utilities/page-by\";\nimport firstOf from \"../utilities/first-of.js\";\nimport lastOf from \"../utilities/last-of.js\";\n\nconst EPOCH_MIN = new Date(-8640000000000000);\nconst EPOCH_MAX = new Date(8640000000000000);\n\nconst weekdays = [\n    \"Sunday\",\n    \"Monday\",\n    \"Tuesday\",\n    \"Wednesday\",\n    \"Thursday\",\n    \"Friday\",\n    \"Saturday\"\n];\n\nfunction cleanDate(date) {\n    return isValid(date) ? date : new Date();\n}\n\n\n\nexport default class CalendarMonth {\n\n    get weekdays() {\n        return weekdays;\n    }\n\n    get minDate() {\n        return this._minDate;\n    }\n\n    set minDate(date) {\n        this._minDate = cleanDate(date);\n    }\n\n    get maxDate() {\n        return this._maxDate;\n    }\n\n    set maxDate(date) {\n        this._maxDate = cleanDate(date);\n    }\n\n    get startDate() {\n        return this._startDate;\n    }\n\n    set startDate(date) {\n        this._startDate = cleanDate(date);\n\n        if (!isWithinRange(this._startDate, this._minDate, this._maxDate)) {\n            this._startDate = this.minDate;\n        }\n    }\n\n    get paddingStart() {\n        let firstWeek = firstOf(this.weeks);\n        let firstDay = firstOf(firstWeek);\n\n        return firstDay.getDay();\n    }\n\n    get paddingEnd() {\n        let weeks = this.weeks;\n        let lastWeek = lastOf(weeks);\n        let lastDay = lastOf(lastWeek);\n\n        return 6 - lastDay.getDay();\n    }\n\n    generate() {\n        let monthStart = startOfMonth(this.startDate);\n        let monthEnd = endOfMonth(this.startDate);\n\n        let days = eachDay(monthStart, monthEnd);\n\n        this.weeks = pageBy(days, day => {\n            let weekPosition = day.getDay() + 1;\n            let monthPosition = day.getDate();\n\n            let position = (13 - weekPosition + monthPosition) / 7;\n\n            return Math.floor(position);\n        });\n\n        return this.weeks;\n    }\n\n    previousMonth() {\n        this.startDate = subMonths(this.startDate, 1);\n        return this.generate();\n    }\n\n    nextMonth() {\n        this.startDate = addMonths(this.startDate, 1);\n        return this.generate();\n    }\n\n    goToMonth(month) {\n        this.startDate = setMonth(this.startDate, month);\n        return this.generate();\n    }\n\n    constructor(startDate, minDate, maxDate) {\n        this.minDate = minDate || EPOCH_MIN;\n        this.maxDate = maxDate || EPOCH_MAX;\n        this.startDate = startDate || new Date();\n\n        this.generate();\n    }\n\n}"
  },
  {
    "path": "src/services/event-emitter.js",
    "content": "import Vue from \"vue\";\n\n// Here we can just wrap Vue's built-in pub-sub system\n// Saves me from writing my own or importing another dependency :)\n\nexport class EventEmitter {\n\n    constructor() {\n        this.emitter = new Vue();\n    }\n\n    emit(event, ...args) {\n        this.emitter.$emit.apply(this.emitter, event, args);\n    } \n\n    on(event, callback) {\n        this.emitter.$on(event, callback);\n    }\n\n    off(event, callback) {\n        this.emitter.$off(event, callback);\n    }\n\n}\n\nexport default new EventEmitter();"
  },
  {
    "path": "src/services/http-client.js",
    "content": "class HttpRequest {\n\n    constructor(url, method) {\n        this.url = url;\n        this.method = method;\n        this.type = \"text/json\";\n        this.headers = [];\n    }\n\n    execute() {\n        return new Promise((resolve, reject) => {\n            let request = new XMLHttpRequest();\n            \n            request.onload = (event) => {\n\n                resolve();\n            };\n        });\n    }\n\n}\n\nexport class HttpClient {\n    constructor() {\n\n    }\n}"
  },
  {
    "path": "src/utilities/average-of.js",
    "content": "import totalOf from \"./total-of\";\n\nexport default function averageOf(array, callback) {\n    let value = totalOf(array, callback);\n    \n    return value ? value / array.length : false;\n}"
  },
  {
    "path": "src/utilities/base/aggregator.js",
    "content": "export default function aggregate(array, callback, startValue) {\n\n    let accumulator = startValue || 0;\n\n    for (let item of array) {\n\n        let result = callback.call(this, accumulator, item, array);\n\n        if (result === false) {\n            return false;\n        }\n\n        accumulator = result;\n    }\n    \n    return accumulator;\n}\n"
  },
  {
    "path": "src/utilities/base/type-converter.js",
    "content": "import * as typeValidator from \"./type-validator\";\n\nconst floatTest = /^(\\-|\\+)?([0-9]+(\\.[0-9]+)?|Infinity)$/;\n\nconst evaluators = [\n    {\n        test: value => {\n            return typeValidator.isNumber(value) ? true : floatTest.test(value);\n        },\n        toNumber: parseFloat\n    },\n    {\n        test: value => { \n            if (typeValidator.isDate(value)) {\n                return true;\n            } \n\n            let date = new Date(value);\n            return typeValidator.isDate(date);\n        },\n        toNumber: value => (new Date(value)).getTime()\n    }\n]\n\nexport default function toNumber(value) {\n    \n    for (let evaluator of evaluators) {\n        let result = evaluator.test(value);\n\n        if (result) {\n            return evaluator.toNumber;\n        }\n    }\n\n    return (value => value);\n}"
  },
  {
    "path": "src/utilities/base/type-validator.js",
    "content": "\nconst types = {\n    array: \"[object Array]\",\n    boolean: \"[object Boolean]\",\n    date: \"[object Date]\",\n    null: \"[object Null]\",\n    number: \"[object Number]\",\n    object: \"[object Object]\",\n    string: \"[object String]\",\n    undefined: \"[object Undefined]\"\n};\n\nfunction isType(value, type) {\n    return type === Object.prototype.toString.call(value);\n}\n\nexport function isAny(value, ...validators) {\n    let any = false;\n    let index = 0;\n\n    while (!any && index < validators.length) {\n        any = validators[index].call(this, value);\n        index++\n    }    \n\n    return any;\n}\n\nexport function isArray(value) {\n    return isType(value, types.array);\n}\n\nexport function isBoolean(value) {\n    return isType(value, types.boolean);\n}\n\nexport function isDate(value) {\n    return isType(value, types.date) && !isNaN(value.getTime());\n}\n\nexport function isNull(value) {\n    return isType(value, types.null);\n}\n\nexport function isNumber(value) {\n    return isType(value, types.number);\n}\n\nexport function isObject(value) {\n    return isType(value, types.object);\n}\n\nexport function isString(value) {\n    return isType(value, types.string);\n}\n\nexport function isUndefined(value) {\n    return isType(value, types.undefined);\n}\n\nexport function isPrimitive(value) {\n    return !isAny(value, isArray, isDate, isObject);\n}\n\nexport function isCollection(value) {\n    return isAny(value, isArray, isObject);\n}"
  },
  {
    "path": "src/utilities/filter-by.js",
    "content": "// Need to add support for searching dates\nconst SEARCHABLE_TYPES = [\"string\", \"number\", \"boolean\"];\n\n/**\n * Filter an array of objects by the given phrase\n * \n * @export\n * @param {Array} array\n * @param {String} filter\n * @returns Array\n */\nexport default function filterBy(array, filter) {\n    if (!filter) {\n        return array;\n    }\n\n    let filtered = [];\n\n    for (let i = 0; i < array.length; i++) {\n        let item = array[i];\n\n        for (let prop in item) {\n            let value = item[prop];\n\n            // Ensure the value is of a searchable type \n            // This will automatically handle null values\n            if (SEARCHABLE_TYPES.indexOf(typeof (value)) < 0) {\n                continue;\n            }\n\n            // Normalise the value to get a consistent match\n            let normalised = value.toString().toLowerCase();\n\n            if (normalised.indexOf(filter.toLowerCase()) > -1) {\n                filtered.push(item);\n                break;\n            }\n        }\n    }\n\n    return filtered;\n}"
  },
  {
    "path": "src/utilities/first-of.js",
    "content": "\nexport default function firstOf(array) {\n\n    if (!array.length || array.length < 1) {\n        return;\n    }\n\n    return array[0];\n\n}"
  },
  {
    "path": "src/utilities/group-by.js",
    "content": "/**\n * Group and array of objects by a given key\n * \n * @export\n * @param {Array} array The array to group\n * @param {String} key The key to group the array by\n * @returns Object\n */\nexport default function groupBy(array, callback) {\n\n    callback = callback || (item => item);\n\n    let groups = {};\n\n    for (let item of array) {\n        let value = callback.call(array, item);\n\n        if (!groups.hasOwnProperty(value)) {\n            groups[value] = [];\n        }\n\n        groups[value].push(item);\n    }\n\n    return groups;\n}"
  },
  {
    "path": "src/utilities/last-of.js",
    "content": "\nexport default function lastOf(array) {\n\n    if (!array.length || array.length < 1) {\n        return;\n    }\n\n    return array[array.length - 1];\n}"
  },
  {
    "path": "src/utilities/map-values.js",
    "content": "export default function mapValues(object, callback) {\n    let mapped = {};\n\n    for (let prop in object) {\n        mapped[prop] = callback(object[prop]);\n    }\n\n    return mapped;\n}"
  },
  {
    "path": "src/utilities/max-of.js",
    "content": "import aggregate from \"./base/aggregator\";\nimport toNumber from \"./base/type-converter\";\n\nfunction max(accumulator, value, converter) {\n    let converted = converter(value);\n\n    return isNaN(converted) ? false : Math.max(accumulator, converted);\n}\n\nexport default function minOf(array, callback) {\n\n    callback = callback || (item => item);  \n\n    // Let's assume (in a perfect world) that the data type of the first item\n    // is the same throughout the whole array and use the same converter\n    let firstValue = callback.call(array, array[0]);\n    let converter = toNumber(firstValue);\n\n    return aggregate(array, (accumulator, item, array) => { \n        let value = callback.call(array, item);\n\n        return max(accumulator, value, converter);\n    }, -Infinity);\n}"
  },
  {
    "path": "src/utilities/median-of.js",
    "content": "import sortBy from \"./sort-by\";\n\nfunction getValue(item, callback) {\n    return callback.call(this, item);\n} \n\nexport default function medianOf(array, callback) {\n    let sorted = sortBy(array, callback);\n    let count = sorted.length;\n    let half = Math.floor(count / 2);\n\n    let primaryMedian = getValue(sorted[half], callback);\n\n    if (count % 2) {\n        return primaryMedian;\n    }    \n\n    let secondaryMedian = getValue(sorted[half - 1], callback); \n    \n    return (primaryMedian + secondaryMedian) / 2;\n}"
  },
  {
    "path": "src/utilities/min-of.js",
    "content": "import aggregate from \"./base/aggregator\";\nimport toNumber from \"./base/type-converter\";\n\nfunction min(accumulator, value, converter) {\n    let converted = converter(value);\n\n    return isNaN(converted) ? false : Math.min(accumulator, converted);\n}\n\nexport default function minOf(array, callback) {\n\n    callback = callback || (item => item);\n    \n    // Let's assume (in a perfect world) that the data type of the first item\n    // is the same throughout the whole array and use the same converter\n    let firstValue = callback.call(array, array[0]);\n    let converter = toNumber(firstValue);\n    \n    return aggregate(array, (accumulator, item, array) => { \n        let value = callback.call(array, item);\n\n        return min(accumulator, value, converter);\n    }, Infinity);\n}"
  },
  {
    "path": "src/utilities/mode-of.js",
    "content": ""
  },
  {
    "path": "src/utilities/nest.js",
    "content": "import mapValues from \"./map-values\";\n\nexport default function nest(array, keys) {\n    if (!keys.length) {\n        return array;\n    }\n\n    let key = keys.shift();\n\n    let group = groupBy(array, key);\n\n    return mapValues(group, (value, prop) => {\n        return nest(value, [...keys]);\n    });\n}"
  },
  {
    "path": "src/utilities/page-by.js",
    "content": "import groupBy from \"./group-by\";\n\nexport default function pageBy(array, callback) {\n\n    let groups = groupBy(array, callback);\n\n    let pages = [];\n\n    for (let group in groups) {\n        pages.push(groups[group]);\n    }\n\n    return pages;\n}"
  },
  {
    "path": "src/utilities/page.js",
    "content": "export default function page(array, pageSize) {\n    let pages = [];\n    let start = 0;\n    let length = array.length;\n\n    while (start < length) {\n        let end = start + pageSize;\n\n        if (length - start < pageSize) {\n            end = start + (length - start);\n        }\n\n        let page = array.slice(start, end);\n\n        pages.push(page);\n        start += pageSize;\n    }\n\n    return pages;\n}"
  },
  {
    "path": "src/utilities/sort-by.js",
    "content": "// Consider making this immutable. I'm undecided at the moment.\n/**\n * Sort an array of objects by the given key and direction\n * \n * @export\n * @param {Array} array The array to be sorted\n * @param {Function} callback The callback function to invoke to receive the key to sort on\n * @param {Number} direction The direction of the sort\n */\nexport default function sortBy(array, callback, direction) {\n\n    direction = direction || 1;\n    callback = callback || (item => item);\n\n    if (Math.abs(direction) !== 1) {\n        throw new Error(\"Sort direction must be either 1 (ascending) or -1 (descending)\");\n    }\n\n    let sortArray = [...array];\n\n    sortArray.sort((a, b) => {\n        let valueA = callback.call(array, a);\n        let valueB = callback.call(array, b);\n\n        let outcome = valueA < valueB ? -1 : valueA > valueB ? 1 : 0;\n\n        return outcome * direction;\n    });\n\n    return sortArray;\n}"
  },
  {
    "path": "src/utilities/standard-deviation-of.js",
    "content": "import varianceOf from \"./variance-of\";\n\nexport default function standardDeviationOf(array, callback) {\n    let variance = varianceOf(array, callback);\n\n    return variance ? Math.sqrt(variance) : false;\n}"
  },
  {
    "path": "src/utilities/total-of.js",
    "content": "import aggregate from \"./base/aggregator\";\n\nfunction total(accumulator, value) {\n    let num = parseFloat(value);\n\n    return isNaN(num) ? false : accumulator + num;\n}\n\nexport default function totalOf(array, callback) {\n\n    callback = callback || (item => item);\n\n    return aggregate(array, (accumulator, item, array) => {\n        let value = callback.call(array, item);\n\n        return total.call(array, accumulator, value);\n    });\n}"
  },
  {
    "path": "src/utilities/variance-of.js",
    "content": "import aggregate from \"./base/aggregator\";\nimport averageOf from \"./average-of\";\n\nexport default function varianceOf(array, callback) {\n    let count = array.length;\n    let average = averageOf(array, callback);\n    \n    let totalVariance = aggregate(array, (accumulator, item, array) => { \n        let value = callback.call(array, item);\n\n        return accumulator + Math.pow(value - average, 2);\n    });\n    \n    return totalVariance ? totalVariance / count : false;\n}"
  },
  {
    "path": "src/views/components/buttons.vue",
    "content": "<template>\n    <div id=\"buttons\">\n        <h1>Buttons</h1>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <h3>Button Elements</h3>\n                <button class=\"button\" @click=\"buttonClick()\" v-drag:drag=\"\">Primary Button</button>\n                <button class=\"button button-green\" @click=\"buttonClick()\">Green Button</button>\n                <button class=\"button button-red\" @click=\"buttonClick()\">Red Button</button>\n                <button class=\"button button-yellow\" @click=\"buttonClick()\">Yellow Button</button>\n            </div>\n        </div>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <h3>Anchor Elements</h3>\n                <a href=\"#\" class=\"button\" @click.prevent=\"buttonClick()\">Primary Button</a>\n                <a href=\"#\" class=\"button button-green\" @click.prevent=\"buttonClick()\">Green Button</a>\n                <a href=\"#\" class=\"button button-red\" @click.prevent=\"buttonClick()\">Red Button</a>\n                <a href=\"#\" class=\"button button-yellow\" @click.prevent=\"buttonClick()\">Yellow Button</a>\n                <calendar></calendar>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    import CalendarMonth from \"../../services/calendar.js\";\n\n    export default {\n\n        name: \"buttons\",\n\n        methods: {\n\n            buttonClick() {\n                alert(\"Button Clicked!\");\n            }\n\n        },\n\n        created() {\n            let calendar = new CalendarMonth(new Date(2017, 3, 18));\n            console.log(calendar.generate());\n            console.log(calendar.nextMonth());\n        }\n    }\n</script>"
  },
  {
    "path": "src/views/components/components.js",
    "content": "import Buttons from \"./buttons.vue\";\nimport Datatables from \"./datatables.vue\";\nimport Modals from \"./modals.vue\";\nimport Paginators from \"./paginators.vue\";\nimport Panels from \"./panels.vue\";\nimport TabControls from \"./tab-controls.vue\";\nimport Toggles from \"./toggles.vue\";\nimport Typography from \"./typography.vue\";\n\nexport default {\n    buttons: {\n        component: Buttons\n    },\n    datatables: {\n        component: Datatables\n    },\n    modals: {\n        component: Modals\n    },\n    paginators: {\n        component: Paginators\n    },\n    panels: {\n        component: Panels\n    },\n    tabControls: {\n        component: TabControls\n    },\n    toggles: {\n        component: Toggles\n    },\n    typography: {\n        component: Typography\n    }\n}"
  },
  {
    "path": "src/views/components/datatables.vue",
    "content": "<template>\n    <div id=\"datatables\">\n        <h1>Datatables</h1>\n        <div>\n            <h3>Configuration</h3>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <toggle id=\"striped\" v-model=\"customers.striped\">Striped</toggle>\n                    <toggle id=\"line-numbers\" v-model=\"customers.lineNumbers\">Line Numbers</toggle>\n                    <toggle id=\"editable\" v-model=\"customers.editable\">Editable</toggle>\n                </div>\n            </div>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-options\" :source=\"customers.columns\" :filterable=\"false\" editable>\n                        <datatable-column id=\"label\" label=\"Column Name\"></datatable-column>\n                        <datatable-column id=\"width\" label=\"Width\"></datatable-column>\n                        <datatable-column id=\"sortable\" label=\"Sortable\"></datatable-column>\n                        <datatable-column id=\"groupable\" label=\"Groupable\"></datatable-column>\n                        <template slot=\"sortable\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + '-sortable'\" v-model=\"cell.row.sortable\"></toggle>\n                            </div>\n                        </template>\n                        <template slot=\"groupable\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + '-groupable'\" v-model=\"cell.row.groupable\"></toggle>\n                            </div>\n                        </template>\n                    </datatable>\n                </div>\n            </div>\n        </div>\n        <div>\n            <h3>Datatable</h3>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-main\" :source=\"customers.rows\" :striped=\"customers.striped\" :editable=\"customers.editable\" :line-numbers=\"customers.lineNumbers\">\n                        <datatable-column id=\"sel\" label=\"sel\" width=\"3.25rem\" :sortable=\"false\" :groupable=\"false\" class=\"checkable-column\">\n                            <checkbox id=\"sel-all\" v-model=\"selectAll\"></checkbox>\n                        </datatable-column>\n                        <datatable-column v-for=\"column in customers.columns\" :key=\"column.id\" :id=\"column.id\" :label=\"column.label\" :width=\"column.width\" :alignment=\"column.alignment\" :formatter=\"column.formatter\"\n                            :sortable=\"column.sortable\" :groupable=\"column.groupable\" :aggregators=\"column.aggregators\">\n                            </datatable-column>\n                            <template slot=\"sel\" scope=\"cell\">\n                                <div class=\"checkable-column\">\n                                    <checkbox :id=\"cell.row.id\" :value=\"cell.row\" v-model=\"customers.selected\"></checkbox>\n                                </div>\n                            </template>\n                    </datatable>\n                </div>\n            </div>\n        </div>\n        <div>\n            <h3>Selected Rows</h3>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-selected\" :source=\"customers.selected\">\n                        <datatable-column v-for=\"column in customers.columns\" :key=\"column.id\" :id=\"column.id\" :label=\"column.label\" :width=\"column.width\" :alignment=\"column.alignment\" :formatter=\"column.formatter\"></datatable-column>\n                    </datatable>\n                </div>\n            </div>\n        </div>\n        <div>\n            <h3>Formatting</h3>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-options\" :source=\"formatters\" :filterable=\"false\" editable>\n                        <datatable-column id=\"name\" label=\"Name\" width=\"33\" :sortable=\"false\" :groupable=\"false\"></datatable-column>\n                        <datatable-column id=\"format\" label=\"Format\" :sortable=\"false\" :groupable=\"false\"></datatable-column>\n                        <template slot=\"format\" scope=\"cell\">\n                            <div v-if=\"cell.row.id === 'C'\">\n                                <select v-model.lazy=\"customers.currency\">\n                                    <option :value=\"code\" v-for=\"(symbol, code) in currencies\">{{ code }} ({{ symbol }})</option>\n                                </select>\n                            </div>\n                            <div v-else>\n                                <select v-model.lazy=\"customers.dateFormat\">\n                                    <option :value=\"format\" v-for=\"format in dateFormats\">{{ format }}</option>\n                                </select>\n                            </div>\n                        </template>\n                    </datatable>\n                </div>\n            </div>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-main\" \n                        :source=\"customers.rows\" \n                        :striped=\"customers.striped\" \n                        :editable=\"customers.editable\" \n                        :line-numbers=\"customers.lineNumbers\">\n                        <datatable-column \n                            v-for=\"column in customers.columns\" \n                            :id=\"column.id\" \n                            :label=\"column.label\" \n                            :width=\"column.width\" \n                            :alignment=\"column.alignment\" \n                            :sortable=\"column.sortable\"\n                            :groupable=\"column.groupable\"\n                            :formatter=\"column.formatter\">\n                        </datatable-column>\n                    </datatable>\n                </div>\n            </div>\n        </div>\n        <div>\n            <h3>Aggregation</h3>\n            <p>\n                This is a basic example of how to use aggregate functions with the datatable \n            </p>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-options\" :source=\"customers.columns\" :filterable=\"false\" editable>\n                        <datatable-column id=\"label\" label=\"Column Name\" width=\"25\" data-intro=\"Clicking a column will sort by that column\" data-step=\"4\"></datatable-column>\n                        <datatable-column id=\"min\" label=\"Min\"></datatable-column>\n                        <datatable-column id=\"max\" label=\"Max\"></datatable-column>\n                        <datatable-column id=\"average\" label=\"Average (mean)\"></datatable-column>\n                        <datatable-column id=\"median\" label=\"Median\"></datatable-column>\n                        <datatable-column id=\"total\" label=\"Total\"></datatable-column>\n                        <template slot=\"min\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + 'min'\" :value=\"aggregators.min\" v-model=\"cell.row.aggregators\"></toggle>\n                            </div>\n                        </template>\n                        <template slot=\"max\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + 'max'\" :value=\"aggregators.max\" v-model=\"cell.row.aggregators\"></toggle>\n                            </div>\n                        </template>\n                        <template slot=\"average\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + 'average'\" :value=\"aggregators.average\" v-model=\"cell.row.aggregators\"></toggle>\n                            </div>\n                        </template>\n                        <template slot=\"median\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + 'median'\" :value=\"aggregators.median\" v-model=\"cell.row.aggregators\"></toggle>\n                            </div>\n                        </template>\n                        <template slot=\"total\" scope=\"cell\">\n                            <div class=\"datatable-options-toggle\">\n                                <toggle :id=\"cell.row.id + 'total'\" :value=\"aggregators.total\" v-model=\"cell.row.aggregators\"></toggle>\n                            </div>\n                        </template>\n                    </datatable>\n                </div>\n            </div>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <datatable id=\"data-table-main\" \n                        :source=\"customers.rows\" \n                        :striped=\"customers.striped\" \n                        :editable=\"customers.editable\" \n                        :line-numbers=\"customers.lineNumbers\">\n                        <datatable-column \n                            v-for=\"column in customers.columns\" \n                            :id=\"column.id\" \n                            :label=\"column.label\" \n                            :width=\"column.width\"\n                            :alignment=\"column.alignment\" \n                            :sortable=\"column.sortable\"\n                            :groupable=\"column.groupable\"\n                            :aggregators=\"column.aggregators\"\n                            :formatter=\"column.formatter\">\n                        </datatable-column>\n                    </datatable>\n                </div>\n            </div>\n        </div>\n        <div>\n            <h3>Paginated</h3>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <paginator :source=\"customers.rows\" :page-size=\"3\">\n                        <template scope=\"page\">\n                            <datatable id=\"data-table-main\" :source=\"page.data\" :striped=\"customers.striped\" :editable=\"customers.editable\" :line-numbers=\"customers.lineNumbers\">\n                                <datatable-column id=\"sel\" label=\"sel\" width=\"3.25rem\" :sortable=\"false\" :groupable=\"false\" class=\"checkable-column\">\n                                    <checkbox id=\"sel-all\" v-model=\"selectAll\"></checkbox>\n                                </datatable-column>\n                                <datatable-column v-for=\"column in customers.columns\" :key=\"column.id\" :id=\"column.id\" :label=\"column.label\" :width=\"column.width\" :formatter=\"column.formatter\"\n                                    :sortable=\"column.sortable\" :groupable=\"column.groupable\">\n                                    </datatable-column>\n                                    <template slot=\"sel\" scope=\"cell\">\n                                        <div class=\"checkable-column\">\n                                            <checkbox :id=\"cell.row.id\" :value=\"cell.row\" v-model=\"customers.selected\"></checkbox>\n                                        </div>\n                                    </template>\n                            </datatable>\n                        </template>\n                    </paginator>\n                </div>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    import { format } from \"date-fns\";\n    import aggregators from \"../../aggregators/aggregators.js\";\n    import formatters from \"../../formatters/formatters.js\";\n    import currencies from \"../../maps/currencies.js\";\n\n    let customers = {\n        striped: true,\n        editable: false,\n        lineNumbers: false,\n\n        currency: \"USD\",\n        dateFormat: \"D MMMM YYYY\",\n\n        columns: [\n            {\n                id: \"purchasor_name\",\n                label: \"Client Name\",\n                width: null,\n                sortable: true,\n                groupable: true,\n                aggregators: []\n            },\n            {\n                id: \"purchasor_email\",\n                label: \"Client Email\",\n                width: 25,\n                sortable: true,\n                groupable: true,\n                aggregators: []\n            },\n            {\n                id: \"purchase_date\",\n                label: \"Purchase Date\",\n                width: null,\n                sortable: true,\n                groupable: true,\n                formatter: value => {\n                    return formatters.datetime(value, customers.dateFormat);\n                },\n                aggregators: [\n                    aggregators.min,\n                    aggregators.max\n                ]\n            },\n            {\n                id: \"purchase_amount\",\n                label: \"Purchase Amount\",\n                width: null,\n                alignment: \"right\",\n                sortable: true,\n                groupable: true,\n                formatter: value => {\n                    return formatters.currency(value, 2, customers.currency);\n                },\n                aggregators: [ \n                    aggregators.min, \n                    aggregators.max,\n                    aggregators.total\n                ]\n            }\n        ],\n\n        rows: [\n            {\n                id: \"0584e8d2-984c-4ce0-a20f-8b9e21cd2c00\",\n                purchasor_name: \"Nancy Fuller\",\n                purchasor_email: \"nfuller0@about.me\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 1166.14\n            },\n            {\n                id: \"f4769183-38af-4c22-8383-6dea302466fd\",\n                purchasor_name: \"Melissa Meyer\",\n                purchasor_email: \"mmeyer1@angelfire.com\",\n                purchase_date: \"2010-05-15T08:13:59Z\",\n                purchase_amount: 6123.50\n            },\n            {\n                id: \"e171c9fb-2438-4f23-8d0d-011b2d8e95bc\",\n                purchasor_name: \"Larry Rose\",\n                purchasor_email: \"lrose2@cdbaby.com\",\n                purchase_date: \"2014-11-23T09:18:18Z\",\n                purchase_amount: 8288.27\n            },\n            {\n                id: \"3cad078d-083b-416e-9dd4-2f1470c3458d\",\n                purchasor_name: \"Jack Simpson\",\n                purchasor_email: \"jsimpson3@mayoclinic.com\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 1215.03\n            },\n            {\n                id: \"ef7ff12c-90e5-4bfb-8fdd-9f20e4206afa\",\n                purchasor_name: \"Ernest Watson\",\n                purchasor_email: \"ewatson4@nytimes.com\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 9455.16\n            },\n            {\n                id: \"b243be08-6b9c-4ebd-bb8b-b59256ad4956\",\n                purchasor_name: \"Adam Castillo\",\n                purchasor_email: \"acastillo5@dailymotion.com\",\n                purchase_date: \"2014-08-22T08:14:28Z\",\n                purchase_amount: 9988.45\n            },\n            {\n                id: \"a491adf5-8129-4f93-9442-98522fbd1e90\",\n                purchasor_name: \"Wayne Wilson\",\n                purchasor_email: \"wwilson6@indiegogo.com\",\n                purchase_date: \"2012-03-07T22:16:08Z\",\n                purchase_amount: 4563.87\n            },\n            {\n                id: \"497a6cca-5c9c-4b93-af8e-63c93de3eacf\",\n                purchasor_name: \"Roy Coleman\",\n                purchasor_email: \"rcoleman7@independent.co.uk\",\n                purchase_date: \"2010-09-14T05:05:17Z\",\n                purchase_amount: 4563.87\n            },\n            {\n                id: \"ea34a698-fb86-44a5-b80e-57087d48737c\",\n                purchasor_name: \"Betty Diaz\",\n                purchasor_email: \"bdiaz8@dropbox.com\",\n                purchase_date: \"2012-03-07T22:16:08Z\",\n                purchase_amount: 7527.62\n            },\n            {\n                id: \"c48e5e68-cae5-4a2e-96b2-8509fca19ddb\",\n                purchasor_name: \"Sharon Gardner\",\n                purchasor_email: \"sgardner9@seesaa.net\",\n                purchase_date: \"2004-10-14T14:59:00Z\",\n                purchase_amount: 1166.14\n            }\n        ],\n\n        selected: []\n    };\n\n    export default {\n\n        name: \"datatables\",\n\n        data() {\n            return {\n                customers: customers,\n                currencies: currencies,\n                aggregators: aggregators,\n                dateFormats: [\n                    \"DD/MM/YYYY\",\n                    \"DD MMM YYYY\",\n                    \"D MMMM YYYY\",\n                    \"D/MM/YYYY h:mm a\"\n                ],\n                formatters: [\n                    { id: \"C\", name: \"Currency\" },\n                    { id: \"DT\", name: \"Date and Time\" }\n                ]\n            };\n        },\n\n        computed: {\n\n            selectAll: {\n                get() {\n                    return customers.selected.length == customers.rows.length;\n                },\n                set(value) {\n                    customers.selected = value ? customers.rows : [];\n                }\n            }\n\n        }\n    }\n</script>\n\n<style lang=\"scss\">\n\n    .datatable-options-toggle {\n        padding: 0.5rem 1rem;\n    }\n\n    .checkable-column {\n        text-align: center;\n\n        .checkbox {\n            margin: 0;\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/views/components/modals.vue",
    "content": "<template>\n    <div id=\"modals\">\n        <h1>Modals</h1>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <button class=\"button\" @click=\"openModal\">Show Modal</button>\n                <modal title=\"Test Modal\" ref=\"testModal\">\n                    <p>\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n                        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n                        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat\n                        nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n                        mollit anim id est laborum.\n                    </p>\n                    <div slot=\"modal-footer\" layout=\"row center-right\">\n                        <button class=\"button\" @click=\"closeModal\">Other button</button>\n                        <button class=\"button button-red\" @click=\"closeModal\">Close</button>\n                    </div>\n                </modal>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        name: \"modals\",\n\n        methods: {\n\n            openModal() {\n                this.$refs.testModal.open();\n            },\n\n            closeModal() {\n                this.$refs.testModal.close();\n            }\n\n        }\n    }\n</script>"
  },
  {
    "path": "src/views/components/paginators.vue",
    "content": "<template>\n    <div id=\"paginators\">\n        <h1>Paginator</h1>\n        <div>\n            <h3>Paginated Datatable</h3>\n            <div class=\"grid-row\">\n                <div class=\"grid-cell\">\n                    <input type=\"text\" placeholder=\"Filter data\" v-model=\"customers.filter\">\n                </div>\n            </div>\n            <div class=\"grid-row\" layout=\"row top-stretch\">\n                <div class=\"grid-cell\">\n                    <paginator :source=\"customers.rows\" :page-size=\"4\" :filter=\"customers.filter\">\n                        <template scope=\"page\">\n                            <datatable id=\"data-table-main\" :source=\"page.data\" :striped=\"customers.striped\" :editable=\"customers.editable\" :line-numbers=\"customers.lineNumbers\">\n                                <datatable-column id=\"sel\" label=\"sel\" width=\"3.25rem\" :sortable=\"false\" :groupable=\"false\" class=\"checkable-column\">\n                                    <checkbox id=\"sel-all\" v-model=\"selectAll\"></checkbox>\n                                </datatable-column>\n                                <datatable-column v-for=\"column in customers.columns\" :key=\"column.id\" :id=\"column.id\" :label=\"column.label\" :width=\"column.width\" :formatter=\"column.formatter\"\n                                    :sortable=\"column.sortable\" :groupable=\"column.groupable\" :total=\"column.total\">\n                                    </datatable-column>\n                                    <template slot=\"sel\" scope=\"cell\">\n                                        <div class=\"checkable-column\">\n                                            <checkbox :id=\"cell.row.id\" :value=\"cell.row\" v-model=\"customers.selected\"></checkbox>\n                                        </div>\n                                    </template>\n                            </datatable>\n                        </template>\n                    </paginator>\n                </div>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    import { format } from \"date-fns\";\n\n    let customers = {\n        striped: true,\n        editable: false,\n        lineNumbers: false,\n\n        columns: [\n            {\n                id: \"purchasor_name\",\n                label: \"Client Name\",\n                width: null,\n                sortable: true,\n                groupable: true,\n                total: false\n            },\n            {\n                id: \"purchasor_email\",\n                label: \"Client Email\",\n                width: 25,\n                sortable: true,\n                groupable: true,\n                total: false\n            },\n            {\n                id: \"purchase_date\",\n                label: \"Purchase Date\",\n                width: null,\n                sortable: true,\n                groupable: true,\n                total: false,\n                formatter: value => format(value, \"DD MMMM YYYY\")\n            },\n            {\n                id: \"purchase_amount\",\n                label: \"Purchase Amount\",\n                width: null,\n                sortable: true,\n                groupable: true,\n                total: true,\n                formatter: value => {\n                    var currency = parseFloat(value);\n\n                    if (isNaN(currency)) {\n                        return value;\n                    }\n\n                    return \"$\" + currency.toFixed(2).replace(/(\\d)(?=(\\d{3})+\\.)/g, \"$1,\");\n                }\n            }\n        ],\n\n        rows: [\n            {\n                id: \"0584e8d2-984c-4ce0-a20f-8b9e21cd2c00\",\n                purchasor_name: \"Nancy Fuller\",\n                purchasor_email: \"nfuller0@about.me\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 1166.14\n            },\n            {\n                id: \"f4769183-38af-4c22-8383-6dea302466fd\",\n                purchasor_name: \"Melissa Meyer\",\n                purchasor_email: \"mmeyer1@angelfire.com\",\n                purchase_date: \"2010-05-15T08:13:59Z\",\n                purchase_amount: 6123.50\n            },\n            {\n                id: \"e171c9fb-2438-4f23-8d0d-011b2d8e95bc\",\n                purchasor_name: \"Larry Rose\",\n                purchasor_email: \"lrose2@cdbaby.com\",\n                purchase_date: \"2014-11-23T09:18:18Z\",\n                purchase_amount: 8288.27\n            },\n            {\n                id: \"3cad078d-083b-416e-9dd4-2f1470c3458d\",\n                purchasor_name: \"Jack Simpson\",\n                purchasor_email: \"jsimpson3@mayoclinic.com\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 1215.03\n            },\n            {\n                id: \"ef7ff12c-90e5-4bfb-8fdd-9f20e4206afa\",\n                purchasor_name: \"Ernest Watson\",\n                purchasor_email: \"ewatson4@nytimes.com\",\n                purchase_date: \"2002-01-02T04:45:48Z\",\n                purchase_amount: 9455.16\n            },\n            {\n                id: \"b243be08-6b9c-4ebd-bb8b-b59256ad4956\",\n                purchasor_name: \"Adam Castillo\",\n                purchasor_email: \"acastillo5@dailymotion.com\",\n                purchase_date: \"2014-08-22T08:14:28Z\",\n                purchase_amount: 9988.45\n            },\n            {\n                id: \"a491adf5-8129-4f93-9442-98522fbd1e90\",\n                purchasor_name: \"Wayne Wilson\",\n                purchasor_email: \"wwilson6@indiegogo.com\",\n                purchase_date: \"2012-03-07T22:16:08Z\",\n                purchase_amount: 4563.87\n            },\n            {\n                id: \"497a6cca-5c9c-4b93-af8e-63c93de3eacf\",\n                purchasor_name: \"Roy Coleman\",\n                purchasor_email: \"rcoleman7@independent.co.uk\",\n                purchase_date: \"2010-09-14T05:05:17Z\",\n                purchase_amount: 4563.87\n            },\n            {\n                id: \"ea34a698-fb86-44a5-b80e-57087d48737c\",\n                purchasor_name: \"Betty Diaz\",\n                purchasor_email: \"bdiaz8@dropbox.com\",\n                purchase_date: \"2012-03-07T22:16:08Z\",\n                purchase_amount: 7527.62\n            },\n            {\n                id: \"c48e5e68-cae5-4a2e-96b2-8509fca19ddb\",\n                purchasor_name: \"Sharon Gardner\",\n                purchasor_email: \"sgardner9@seesaa.net\",\n                purchase_date: \"2004-10-14T14:59:00Z\",\n                purchase_amount: 1166.14\n            }\n        ],\n\n        filter: null,\n        selected: []\n    };\n\n    export default {\n\n        name: \"paginators\",\n\n        data() {\n            return {\n                customers: customers\n            };\n        },\n\n        computed: {\n\n            selectAll: {\n                get() {\n                    return customers.selected.length == customers.rows.length;\n                },\n                set(value) {\n                    customers.selected = value ? customers.rows : [];\n                }\n            }\n\n        }\n    }\n</script>\n\n<style lang=\"scss\">\n\n    .datatable-options-toggle {\n        padding: 0.5rem 1rem;\n    }\n\n    .checkable-column {\n        text-align: center;\n\n        .checkbox {\n            margin: 0;\n        }\n    }\n\n    .paginator {\n\n        & .datatable {\n            border: none;\n        }\n    }\n\n</style>"
  },
  {
    "path": "src/views/components/panels.vue",
    "content": "<template>\n    <div id=\"panels\">\n        <h1>Panels</h1>\n        <div class=\"grid-row\" layout=\"row top-stretch\">\n            <div class=\"grid-cell\">\n                <panel title=\"Panel 1\">\n                    <p>\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n                        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n                        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat\n                        nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n                        mollit anim id est laborum.\n                    </p>\n                </panel>\n            </div>\n            <div class=\"grid-cell\">\n                <panel title=\"Panel 2\">\n                    <p>\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n                        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n                        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat\n                        nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n                        mollit anim id est laborum.\n                    </p>\n                </panel>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        name: \"panels\",\n\n        methods: {\n\n        }\n    }\n</script>"
  },
  {
    "path": "src/views/components/tab-controls.vue",
    "content": "<template>\n    <div id=\"tab-controls\">\n        <h1>Tab Controls</h1>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <tab-control>\n                    <template slot=\"tabs-extra\">\n                        <span class=\"label\">Extra Content</span>\n                    </template>\n                    <template slot=\"tab-pane-2\" scope=\"tab\">\n                        <span>{{ tab.value.id }}</span>\n                    </template>\n                    <tab-pane id=\"tab-pane-1\" label=\"Tab Pane 1\">\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                    </tab-pane>\n                    <tab-pane id=\"tab-pane-2\" label=\"Tab Pane 2\">\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n                    </tab-pane>\n                    <tab-pane id=\"tab-pane-3\" label=\"Tab Pane 3\">\n                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                    </tab-pane>\n                </tab-control>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        name: \"tab-controls\",\n\n    }\n</script>"
  },
  {
    "path": "src/views/components/toggles.vue",
    "content": "<template>\n    <div id=\"toggles\">\n        <h1>Toggles</h1>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <h3>Checkboxes</h3>\n                <checkbox v-for=\"item in checkables\" :key=\"item.name\" :id=\"'checkbox-' + item.name\" :value=\"item\" v-model=\"checkboxes.selected\">{{ item.name }}</checkbox>\n                <div>{{ checkboxes.selected }}</div>\n                <div>\n                    here is a line of text with a <checkbox id=\"inline\" v-model=\"inline\">checkbox</checkbox> in the middle of it.\n                </div>\n            </div>\n        </div>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <h3>Radios</h3>\n                <radio v-for=\"item in checkables\" :key=\"item.name\" :id=\"'radio-' + item.name\" :value=\"item\" v-model=\"radios.selected\">{{ item.name }}</radio>\n                <div>{{ radios.selected }}</div>\n            </div>\n        </div>\n        <div class=\"grid-row\">\n            <div class=\"grid-cell\">\n                <h3>Toggles</h3>\n                <toggle v-for=\"item in checkables\" :key=\"item.name\" :id=\"'switch-' + item.name\" :value=\"item\" v-model=\"toggles.selected\">{{ item.name }}</toggle>\n                <div>{{ toggles.selected }}</div>\n            </div>\n        </div>\n    </div>\n</template>\n\n<script>\n    export default {\n        \n        name: \"toggles\",\n\n        data() {\n            return {\n\n                checkables: [\n                    {\n                        name: \"Andrew\",\n                        age: 25\n                    },\n                    {\n                        name: \"John\",\n                        age: 28\n                    },\n                    {\n                        name: \"Matthew\",\n                        age: 21\n                    }\n                ],\n\n                checkboxes: {\n                    selected: []\n                },\n\n                radios: {\n                    selected: null\n                },\n\n                toggles: {\n                    selected: []\n                },\n\n                inline: true\n                \n            }\n        }\n\n    }\n</script>"
  },
  {
    "path": "src/views/components/typography.vue",
    "content": "<template>\n    <div id=\"typography\">\n        <h1>This is the first heading</h1>\n        <h2>This is the second heading</h2>\n        <h3>This is the third heading</h3>\n        <h4>This is the fourth heading</h4>\n        <h5>This is the fifth heading</h5>\n        <h6>This is the sixth heading</h6>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis\n            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n        </p>\n        <h3>Blockquote</h3>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis\n            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n        </p>\n        <blockquote>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n        </blockquote>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis\n            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n        </p>\n        <h3>Code</h3>\n        <code>function sampleMethod(arg1, arg2) {<br />    var arg3 = arg1 * arg2;<br /><br />    return arg3;<br />}</code>\n        <p>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis\n            aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n            occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n        </p>\n        <h3>Labels</h3>\n        <p>\n            <span class=\"label\">Default Label</span> <span class=\"label label-red\">Red Label</span> <span class=\"label label-green\">Green Label</span>            <span class=\"label label-yellow\">Yellow Label</span>\n        </p>\n    </div>\n</template>\n\n<script>\n    export default {\n\n        name: \"typography\",\n\n    }\n</script>"
  },
  {
    "path": "src/views/views.js",
    "content": "import Components from \"./components/components\";\n\nexport default {\n    components: Components\n}"
  },
  {
    "path": "test/mocha.opts",
    "content": "--compilers js:babel-register \n--require babel-polyfill \n--recursive"
  },
  {
    "path": "test/test-data.js",
    "content": "export const arrays = {\n\n    simple: {\n\n        numeric: {\n            data: [5, 6, 5, 3, 9, 4, 7, 1, 4, 9, 0, 3, 5],\n            expected: {\n                first: 5,\n                last: 5,\n                min: 0,\n                max: 9,\n                average: 0,\n                total: 0\n            }\n        },\n\n        mixed: {\n            data: [5, 6, \"john\", 3, 9, 4, new Date(), 1, 4, 9, false, 3, 5]\n        }\n    },\n\n    complex: {\n        data: [{\n                id: \"0584e8d2-984c-4ce0-a20f-8b9e21cd2c00\",\n                purchasorName: \"Nancy Fuller\",\n                purchasorEmail: \"nfuller0@about.me\",\n                purchaseDate: \"2002-01-02T04:45:48Z\",\n                purchaseAmount: 1166.14,\n                quantity: 15\n            },\n            {\n                id: \"f4769183-38af-4c22-8383-6dea302466fd\",\n                purchasorName: \"Melissa Meyer\",\n                purchasorEmail: \"mmeyer1@angelfire.com\",\n                purchaseDate: \"2010-05-15T08:13:59Z\",\n                purchaseAmount: 6123.50,\n                quantity: 15\n            },\n            {\n                id: \"e171c9fb-2438-4f23-8d0d-011b2d8e95bc\",\n                purchasorName: \"Larry Rose\",\n                purchasorEmail: \"lrose2@cdbaby.com\",\n                purchaseDate: \"2014-11-23T09:18:18Z\",\n                purchaseAmount: 8288.27,\n                quantity: 15\n            },\n            {\n                id: \"3cad078d-083b-416e-9dd4-2f1470c3458d\",\n                purchasorName: \"Jack Simpson\",\n                purchasorEmail: \"jsimpson3@mayoclinic.com\",\n                purchaseDate: \"2002-01-02T04:45:48Z\",\n                purchaseAmount: 1215.03,\n                quantity: 15\n            },\n            {\n                id: \"ef7ff12c-90e5-4bfb-8fdd-9f20e4206afa\",\n                purchasorName: \"Ernest Watson\",\n                purchasorEmail: \"ewatson4@nytimes.com\",\n                purchaseDate: \"2002-01-02T04:45:48Z\",\n                purchaseAmount: 9455.16,\n                quantity: 15\n            },\n            {\n                id: \"b243be08-6b9c-4ebd-bb8b-b59256ad4956\",\n                purchasorName: \"Adam Castillo\",\n                purchasorEmail: \"acastillo5@dailymotion.com\",\n                purchaseDate: \"2014-08-22T08:14:28Z\",\n                purchaseAmount: 9988.45,\n                quantity: 15\n            },\n            {\n                id: \"a491adf5-8129-4f93-9442-98522fbd1e90\",\n                purchasorName: \"Wayne Wilson\",\n                purchasorEmail: \"wwilson6@indiegogo.com\",\n                purchaseDate: \"2012-03-07T22:16:08Z\",\n                purchaseAmount: 4563.87,\n                quantity: 15\n            },\n            {\n                id: \"497a6cca-5c9c-4b93-af8e-63c93de3eacf\",\n                purchasorName: \"Roy Coleman\",\n                purchasorEmail: \"rcoleman7@independent.co.uk\",\n                purchaseDate: \"2010-09-14T05:05:17Z\",\n                purchaseAmount: 4563.87,\n                quantity: 15\n            },\n            {\n                id: \"ea34a698-fb86-44a5-b80e-57087d48737c\",\n                purchasorName: \"Betty Diaz\",\n                purchasorEmail: \"bdiaz8@dropbox.com\",\n                purchaseDate: \"2012-03-07T22:16:08Z\",\n                purchaseAmount: 7527.62,\n                quantity: 15\n            },\n            {\n                id: \"c48e5e68-cae5-4a2e-96b2-8509fca19ddb\",\n                purchasorName: \"Sharon Gardner\",\n                purchasorEmail: \"sgardner9@seesaa.net\",\n                purchaseDate: \"2004-10-14T14:59:00Z\",\n                purchaseAmount: 1166.14,\n                quantity: 15\n            }\n        ],\n        expected: {\n            purchaseAmount: {\n                first: 1166.14,\n                last: 1166.14,\n                min: 1166.14,\n                max: 9988.45\n            }\n        }\n    }\n};\n"
  },
  {
    "path": "test/utilities/average.js",
    "content": "import {\n    assert\n} from \"chai\";\n\nimport averageOf from \"../../src/utilities/average-of\";\nimport totalOf from \"../../src/utilities/total-of\";\nimport { arrays } from \"../test-data\";\n\ndescribe(\"Average\", () => { \n\n    it(\"should find the average of an array of simple numeric structures\", () => { \n        const testData = arrays.simple.numeric;\n\n        let average = averageOf(testData.data);\n        let total = totalOf(testData.data);\n\n        assert.isNumber(average); \n        assert.equal(average, total / testData.data.length);    \n    });\n\n    it(\"should find the average of an array of complex numeric structures\", () => { \n        const testData = arrays.complex;\n\n        const callback = item => item.purchaseAmount;\n\n        let average = averageOf(testData.data, callback);\n        let total = totalOf(testData.data, callback);\n\n        assert.isNumber(average); \n        assert.equal(average, total / testData.data.length);    \n    });\n\n});"
  },
  {
    "path": "test/utilities/group-by.js",
    "content": "import {\n    assert\n} from \"chai\";\n\nimport groupBy from \"../../src/utilities/group-by\";\nimport { arrays } from \"../test-data\";\n\ndescribe(\"Group By\", () => { \n\n    it(\"should group a simple array\", () => { \n        const testData = arrays.simple.numeric;\n\n        let grouped = groupBy(testData.data);\n\n        assert.isObject(grouped);     \n        assert.lengthOf(grouped[\"3\"], 2);\n        assert.lengthOf(grouped[\"4\"], 2);\n        assert.lengthOf(grouped[\"9\"], 2);\n        assert.lengthOf(grouped[\"5\"], 3);\n    });\n\n    it(\"should group a complex array\", () => { \n        const testData = arrays.complex;\n\n        let grouped = groupBy(testData.data, item => item.purchaseAmount);\n        \n        assert.isObject(grouped);     \n        assert.lengthOf(grouped[\"1166.14\"], 2);\n        assert.lengthOf(grouped[\"4563.87\"], 2);\n    });\n\n});"
  },
  {
    "path": "test/utilities/max-of.js",
    "content": "import {\n    assert\n} from \"chai\";\n\nimport maxOf from \"../../src/utilities/max-of\";\nimport { arrays } from \"../test-data\";\n\ndescribe(\"Max Of\", () => {\n\n    it(\"should calculate the maximum value of a simple array with numeric values\", () => {    \n        const testData = arrays.simple.numeric;\n\n        let max = maxOf(testData.data);\n\n        assert.isNumber(max);\n        assert.equal(max, testData.expected.max);\n    });\n\n    it(\"should calculate the maximum value of a complex array with numeric values\", () => {    \n        const testData = arrays.complex;\n\n        let max = maxOf(testData.data, item => item.purchaseAmount);\n\n        assert.isNumber(max);\n        assert.equal(max, testData.expected.purchaseAmount.max);\n    });\n    \n    it(\"should return false if the array contains a non-numeric value\", () => {\n        const testData = arrays.simple.mixed;\n\n        let max = maxOf(testData.data);\n        \n        assert.isNotNumber(max);\n        assert.isFalse(max);\n    });\n\n});"
  },
  {
    "path": "test/utilities/median-of.js",
    "content": ""
  },
  {
    "path": "test/utilities/min-of.js",
    "content": "import {\n    assert\n} from \"chai\";\n\nimport minOf from \"../../src/utilities/min-of\";\nimport { arrays } from \"../test-data\";\n\ndescribe(\"Min Of\", () => {\n\n    it(\"should calculate the minimum value of a simple array with numeric values\", () => {    \n        const testData = arrays.simple.numeric;\n\n        let min = minOf(testData.data);\n        \n        assert.isNumber(min);\n        assert.equal(min, testData.expected.min);\n    });\n\n    it(\"should calculate the minimum value of a complex array with numeric values\", () => {  \n        const testData = arrays.complex;\n\n        let min = minOf(testData.data, item => item.purchaseAmount);\n\n        assert.isNumber(min);\n        assert.equal(min, testData.expected.purchaseAmount.min);\n    });\n    \n    it(\"should return false if the array contains a non-numeric value\", () => {\n        const testData = arrays.simple.mixed;\n\n        let min = minOf(testData.data);\n        \n        assert.isNotNumber(min);\n        assert.isFalse(min);\n    });\n\n});"
  },
  {
    "path": "test/utilities/page.js",
    "content": "import {\n    assert\n} from \"chai\";\nimport page from \"../../src/utilities/page\";\n\nconst array = [5, 6, 5, 3, 9, 4, 7, 1, 4, 9, 0, 3, 5];\n\ndescribe(\"Page\", () => { \n\n    it(\"should page an array by a chunk size\", () => { \n        let paged = page(array, 3);\n\n        assert.isArray(paged);     \n        assert.lengthOf(paged[0], 3);\n        assert.lengthOf(paged[paged.length - 1], 1);\n    });\n\n});"
  },
  {
    "path": "test/utilities/sort-by.js",
    "content": "import {\n    assert\n} from \"chai\";\nimport sortBy from \"../../src/utilities/sort-by\";\n\nconst simpleArray = [5, 6, 1, 9, 4];\n\nconst complexArray = [\n    {\n        name: \"Robert\",\n        age: 21\n    },\n    {\n        name: \"Cindy\",\n        age: 18\n    },\n    {\n        name: \"Samantha\",\n        age: 35\n    },\n    {\n        name: \"Phillip\",\n        age: 52\n    },\n    {\n        name: \"Scott\",\n        age: 23\n    }\n];\n\nconst comparitiveOperators = {\n    lt: (a, b) => a < b,\n    gt: (a, b) => a > b\n};\n\nfunction verifySortedArray(sortedArray, comparitiveOperator, key) {\n    return sortedArray.every((item, index, array) => {\n        let valueA = array[index];\n        let valueB = array[index + 1] || valueA;\n\n        if (key) {\n            valueA = valueA[key];\n            valueB = valueB[key];\n        }\n\n        return index < array.length - 1 ? comparitiveOperator(valueA, valueB) : valueA;\n    });\n}\n\ndescribe(\"Sort By\", () => {\n\n    it(\"should sort a simple array in ascending order\", () => {\n        let sortedArray = sortBy(simpleArray);\n\n        let isSorted = verifySortedArray(sortedArray, comparitiveOperators.lt);\n\n        assert.isTrue(isSorted);\n    });\n\n    it(\"should sort a simple array in descending order\", () => {\n        let sortedArray = sortBy(simpleArray, null, -1);\n\n        let isSorted = verifySortedArray(sortedArray, comparitiveOperators.gt);\n\n        assert.isTrue(isSorted);\n    });\n\n    it(\"should sort a complex array in ascending order\", () => {\n        const key = \"age\";\n\n        let sortedArray = sortBy(complexArray, item => item.age);\n        let isSorted = verifySortedArray(sortedArray, comparitiveOperators.lt, key);\n\n        assert.isTrue(isSorted);\n    });\n\n    it(\"should sort a complex array in descending order\", () => {\n        const key = \"age\";\n\n        let sortedArray = sortBy(complexArray, item => item.age, -1);\n        let isSorted = verifySortedArray(sortedArray, comparitiveOperators.gt, key);\n\n        assert.isTrue(isSorted);\n    });\n\n});"
  },
  {
    "path": "test/utilities/total-of.js",
    "content": "import {\n    assert\n} from \"chai\";\nimport totalOf from \"../../src/utilities/total-of\";\n\nconst simpleArray = [5, 6, 1, 9, 4];\n\nconst complexArray = [\n    {\n        name: \"Robert\",\n        age: 21\n    },\n    {\n        name: \"Cindy\",\n        age: 18\n    },\n    {\n        name: \"Samantha\",\n        age: 35\n    },\n    {\n        name: \"Phillip\",\n        age: 52\n    },\n    {\n        name: \"Scott\",\n        age: 23\n    }\n];\n\ndescribe(\"Total\", () => {\n\n    it(\"should calculate the total of a simple array with numeric values\", () => {\n        const array = [5, 10, 7, 4];\n        \n        let total = totalOf(array);\n\n        assert.isNumber(total);\n        assert.equal(total, 26);\n    });\n\n    it(\"should return false if the array contains a non-numeric value\", () => {\n        const array = [5, \"hello\", 7, 4];\n\n        let total = totalOf(array);\n        \n        assert.isNotNumber(total);\n        assert.isFalse(total);\n    });\n\n});"
  },
  {
    "path": "test/utilities/validators.js",
    "content": "import {\n    assert\n} from \"chai\";\n\nimport * as typeValidator from \"../../src/utilities/base/type-validator\";\n\ndescribe(\"Type Validator\", () => { \n\n    it(\"should validate the type of an array\", () => { \n        let result = typeValidator.isArray([]);\n\n        assert.isTrue(result); \n    });\n\n    it(\"should validate the type of a boolean\", () => { \n        let result = typeValidator.isBoolean(true);\n\n        assert.isTrue(result); \n    });\n\n    it(\"should validate the type of a date\", () => { \n        let result = typeValidator.isDate(new Date());\n\n        assert.isTrue(result); \n    });    \n\n    it(\"should validate the type of null\", () => { \n        let result = typeValidator.isNull(null);\n\n        assert.isTrue(result); \n    });\n\n    it(\"should validate the type of a number\", () => { \n        let result = typeValidator.isNumber(5);\n\n        assert.isTrue(result); \n    });\n\n    it(\"should validate the type of an object\", () => { \n        let result = typeValidator.isObject({});\n\n        assert.isTrue(result); \n    });\n\n    it(\"should validate primitive types\", () => { \n        let arrayResult = typeValidator.isPrimitive([]);\n        let boolResult = typeValidator.isPrimitive(true);\n        let dateResult = typeValidator.isPrimitive(new Date());\n        let numberResult = typeValidator.isPrimitive(5);\n        let objectResult = typeValidator.isPrimitive({});\n        let stringResult = typeValidator.isPrimitive(\"hello\");\n        \n        assert.isFalse(arrayResult);        \n        assert.isTrue(boolResult);\n        assert.isFalse(dateResult);\n        assert.isTrue(numberResult);\n        assert.isFalse(objectResult);\n        assert.isTrue(stringResult);\n    });\n});"
  },
  {
    "path": "webpack.config.js",
    "content": "var path = require(\"path\");\nvar webpack = require(\"webpack\");\n\nvar ExtractTextPlugin = require(\"extract-text-webpack-plugin\");\nvar BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;\n\nvar config = {\n    entry: \"./build/app.js\",\n    output: {\n        path: path.resolve(__dirname, \"./dist/app\"),\n        publicPath: \"/dist/\",\n        filename: \"app.bundle.js\",\n        library: \"vuetiful\",\n        libraryTarget: \"var\"\n    },\n    module: {\n        rules: [{\n            test: /\\.vue$/,\n            loader: \"vue-loader\",\n            options: {\n                loaders: {\n                    // Since sass-loader (weirdly) has SCSS as its default parse mode, we map\n                    // the \"scss\" and \"sass\" values for the lang attribute to the right configs here.\n                    // other preprocessors should work out of the box, no loader config like this nessessary.\n                    \"css\": ExtractTextPlugin.extract({\n                        loader: \"css-loader!postcss-loader\",\n                        fallbackLoader: \"vue-style-loader\"\n                    }),\n                    \"scss\": ExtractTextPlugin.extract({\n                        loader: \"css-loader!postcss-loader!sass-loader\",\n                        fallbackLoader: \"vue-style-loader\"\n                    }),\n                    \"sass\": ExtractTextPlugin.extract({\n                        loader: \"css-loader!postcss-loader!sass-loader?indentedSyntax\",\n                        fallbackLoader: \"vue-style-loader\"\n                    })\n                }\n                // other vue-loader options go here\n            }\n        }, {\n            test: /\\.css$/,\n            loaders: ExtractTextPlugin.extract({\n                loader: \"css-loader!postcss-loader\",\n                fallbackLoader: \"style-loader\"\n            })\n        }, {\n            test: /\\.scss$/,\n            loaders: ExtractTextPlugin.extract({\n                loader: \"css-loader!sass-loader\",\n                fallbackLoader: \"style-loader\"\n            }),\n            exclude: /node_modules/\n        }, {\n            test: /\\.js$/,\n            loader: \"babel-loader\",\n            exclude: /node_modules/\n        }, {\n            test: /\\.(png|jpg|gif|svg)$/,\n            loader: \"file-loader\",\n            options: {\n                name: \"[name].[ext]?[hash]\"\n            }\n        }]\n    },\n    resolve: {\n        alias: {\n            \"vue$\": \"vue/dist/vue.common.js\"\n        }\n    },\n    devServer: {\n        historyApiFallback: true,\n        noInfo: true,\n        compress: true\n    },\n    devtool: \"#eval-source-map\",\n    watch: true,\n    plugins: [\n        new ExtractTextPlugin(\"app.style.css\"),\n        new BundleAnalyzerPlugin({\n            analyzerMode: \"static\",\n            reportFileName: \"bundle.report.html\",\n            openAnalyzer: false\n        })\n    ]\n};\n\nif (process.env.NODE_ENV === \"production\") {\n    config.devtool = \"#source-map\";\n    \n    // http://vue-loader.vuejs.org/en/workflow/production.html\n    config.watch = false;\n\n    config.plugins = (config.plugins || []).concat([\n        new webpack.DefinePlugin({\n            \"process.env\": {\n                NODE_ENV: '\"production\"'\n            }\n        }),\n        new webpack.optimize.UglifyJsPlugin({\n            sourceMap: true,\n            compress: {\n                warnings: false\n            }\n        }),\n        new webpack.LoaderOptionsPlugin({\n            debug: false,\n            minimize: true\n        })\n    ]);\n}\n\nif (process.env.SCOPE === \"components\") {\n    config.entry = \"./build/components.js\";\n    config.output.path = path.resolve(__dirname, \"./dist/components\");\n    config.output.filename = \"components.bundle.js\";\n    config.externals = {\n        \"Vue\": \"vue\",\n        \"date-fns\": \"dateFns\"\n    };\n}\n\nmodule.exports = config;"
  }
]