diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe412d6..c8cd894 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,7 @@ jobs: path: | build/assets/* build/index.html - serve.js + serve.cjs - name: 'If build on master branch, bump version on develop' if: ${{ github.ref_name == 'master' }} diff --git a/.gitignore b/.gitignore index 9195d15..d462f51 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,8 @@ typings/ dist -build \ No newline at end of file +build + +config.json + +server.* \ No newline at end of file diff --git a/README.md b/README.md index b323e48..ea26ae1 100644 --- a/README.md +++ b/README.md @@ -20,31 +20,31 @@ The backend provider can be selected on startup. Supported backend providers are ## Usage * download latest release zip file: `wget https://github.com/zzeekk/generic-referencedata-editor/releases/latest/download/editor.zip` * unzip -* open "dist/index.html" in browser +* open `build/index.html` in browser * choose provider and enter informations to access data file in repository, or upload schema and data * edit data records * commit data to repository or download data using buttons in the upper right of the table view -### without cross-site scripting (Bitbucket Server & Cloud) +### without cross-site scripting (Bitbucket Server) Start a local https server to forward api request to repository server: * complete basic stpeps above * make sure nodejs is installed -* create config.json with following properties: - - "port": port to use - - "bitbucketServerUrl" Bitbucket server Url - - "sslKeyFile" + "sslCertFile": if you have no certificate for the server, you can create self-signed certificate for testing with the following steps: +* create `config.json` with following properties: + - `port`: port to use + - `bitbucketServerUrl` Bitbucket server Url + - `sslKeyFile` + `sslCertFile`: if you have no certificate for the server, you can create self-signed certificate for testing with the following steps: - openssl genrsa -out server.key 2048 - - openssl req -new -key server.key -out server.crt.-req + - openssl req -new -key server.key -out server.crt.req - openssl x509 -req -in server.crt.req -signkey server.key -out server.crt -* run server: `node serve.js` -* open "dist/index.html" in browser, choose provider and use localhost as hostname +* run server: `node serve.cjs` +* open "https://localhost:" in browser, choose Provider BitbucketServer ## Build * make sure nodejs & npm are installed * clone git repository * install yarn package manager: `npm install --global yarn` * `yarn build` -* check build folder for artifacts +* check `build` folder for artifacts ## Built With * react diff --git a/dist/448c34a56d699c29117adc64c43affeb.woff2 b/dist/448c34a56d699c29117adc64c43affeb.woff2 deleted file mode 100644 index 64539b5..0000000 Binary files a/dist/448c34a56d699c29117adc64c43affeb.woff2 and /dev/null differ diff --git a/dist/89889688147bd7575d6327160d64e760.svg b/dist/89889688147bd7575d6327160d64e760.svg deleted file mode 100644 index 94fb549..0000000 --- a/dist/89889688147bd7575d6327160d64e760.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dist/e18bbf611f2a2e43afc071aa2f4e1512.ttf b/dist/e18bbf611f2a2e43afc071aa2f4e1512.ttf deleted file mode 100644 index 1413fc6..0000000 Binary files a/dist/e18bbf611f2a2e43afc071aa2f4e1512.ttf and /dev/null differ diff --git a/dist/f4769f9bdb7466be65088239c12046d1.eot b/dist/f4769f9bdb7466be65088239c12046d1.eot deleted file mode 100644 index b93a495..0000000 Binary files a/dist/f4769f9bdb7466be65088239c12046d1.eot and /dev/null differ diff --git a/dist/fa2772327f55d8198301fdb8bcfc8158.woff b/dist/fa2772327f55d8198301fdb8bcfc8158.woff deleted file mode 100644 index 9e61285..0000000 Binary files a/dist/fa2772327f55d8198301fdb8bcfc8158.woff and /dev/null differ diff --git a/dist/index.html b/dist/index.html deleted file mode 100644 index 36dc87d..0000000 --- a/dist/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Referenzdateneditor - - - -
-
- -
- - - diff --git a/dist/refedit.bundle.js b/dist/refedit.bundle.js deleted file mode 100644 index 7264807..0000000 --- a/dist/refedit.bundle.js +++ /dev/null @@ -1,4333 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "./node_modules/angular-base64/angular-base64.js": -/*!*******************************************************!*\ - !*** ./node_modules/angular-base64/angular-base64.js ***! - \*******************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -eval("/*** IMPORTS FROM imports-loader ***/\nvar define = false;\n\n'use strict';\n\n(function () {\n 'use strict';\n\n /*\n * Encapsulation of Nick Galbreath's base64.js library for AngularJS\n * Original notice included below\n */\n\n /*\n * Copyright (c) 2010 Nick Galbreath\n * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n /* base64 encode/decode compatible with window.btoa/atob\n *\n * window.atob/btoa is a Firefox extension to convert binary data (the \"b\")\n * to base64 (ascii, the \"a\").\n *\n * It is also found in Safari and Chrome. It is not available in IE.\n *\n * if (!window.btoa) window.btoa = base64.encode\n * if (!window.atob) window.atob = base64.decode\n *\n * The original spec's for atob/btoa are a bit lacking\n * https://developer.mozilla.org/en/DOM/window.atob\n * https://developer.mozilla.org/en/DOM/window.btoa\n *\n * window.btoa and base64.encode takes a string where charCodeAt is [0,255]\n * If any character is not [0,255], then an exception is thrown.\n *\n * window.atob and base64.decode take a base64-encoded string\n * If the input length is not a multiple of 4, or contains invalid characters\n * then an exception is thrown.\n */\n\n angular.module('base64', []).constant('$base64', function () {\n\n var PADCHAR = '=';\n\n var ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n function getbyte64(s, i) {\n var idx = ALPHA.indexOf(s.charAt(i));\n if (idx == -1) {\n throw \"Cannot decode base64\";\n }\n return idx;\n }\n\n function decode(s) {\n // convert to string\n s = \"\" + s;\n var pads, i, b10;\n var imax = s.length;\n if (imax == 0) {\n return s;\n }\n\n if (imax % 4 != 0) {\n throw \"Cannot decode base64\";\n }\n\n pads = 0;\n if (s.charAt(imax - 1) == PADCHAR) {\n pads = 1;\n if (s.charAt(imax - 2) == PADCHAR) {\n pads = 2;\n }\n // either way, we want to ignore this last block\n imax -= 4;\n }\n\n var x = [];\n for (i = 0; i < imax; i += 4) {\n b10 = getbyte64(s, i) << 18 | getbyte64(s, i + 1) << 12 | getbyte64(s, i + 2) << 6 | getbyte64(s, i + 3);\n x.push(String.fromCharCode(b10 >> 16, b10 >> 8 & 0xff, b10 & 0xff));\n }\n\n switch (pads) {\n case 1:\n b10 = getbyte64(s, i) << 18 | getbyte64(s, i + 1) << 12 | getbyte64(s, i + 2) << 6;\n x.push(String.fromCharCode(b10 >> 16, b10 >> 8 & 0xff));\n break;\n case 2:\n b10 = getbyte64(s, i) << 18 | getbyte64(s, i + 1) << 12;\n x.push(String.fromCharCode(b10 >> 16));\n break;\n }\n return x.join('');\n }\n\n function getbyte(s, i) {\n var x = s.charCodeAt(i);\n if (x > 255) {\n throw \"INVALID_CHARACTER_ERR: DOM Exception 5\";\n }\n return x;\n }\n\n function encode(s) {\n if (arguments.length != 1) {\n throw \"SyntaxError: Not enough arguments\";\n }\n\n var i, b10;\n var x = [];\n\n // convert to string\n s = \"\" + s;\n\n var imax = s.length - s.length % 3;\n\n if (s.length == 0) {\n return s;\n }\n for (i = 0; i < imax; i += 3) {\n b10 = getbyte(s, i) << 16 | getbyte(s, i + 1) << 8 | getbyte(s, i + 2);\n x.push(ALPHA.charAt(b10 >> 18));\n x.push(ALPHA.charAt(b10 >> 12 & 0x3F));\n x.push(ALPHA.charAt(b10 >> 6 & 0x3f));\n x.push(ALPHA.charAt(b10 & 0x3f));\n }\n switch (s.length - imax) {\n case 1:\n b10 = getbyte(s, i) << 16;\n x.push(ALPHA.charAt(b10 >> 18) + ALPHA.charAt(b10 >> 12 & 0x3F) + PADCHAR + PADCHAR);\n break;\n case 2:\n b10 = getbyte(s, i) << 16 | getbyte(s, i + 1) << 8;\n x.push(ALPHA.charAt(b10 >> 18) + ALPHA.charAt(b10 >> 12 & 0x3F) + ALPHA.charAt(b10 >> 6 & 0x3f) + PADCHAR);\n break;\n }\n return x.join('');\n }\n\n return {\n encode: encode,\n decode: decode\n };\n }());\n})();\n\n\n//# sourceURL=webpack:///./node_modules/angular-base64/angular-base64.js?"); - -/***/ }), - -/***/ "./node_modules/angular-datatables/dist/angular-datatables.js": -/*!********************************************************************!*\ - !*** ./node_modules/angular-datatables/dist/angular-datatables.js ***! - \********************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -eval("/* WEBPACK VAR INJECTION */(function(jQuery) {/*** IMPORTS FROM imports-loader ***/\nvar define = false;\n\n\"use strict\";\n\n/*!\n * angular-datatables - v0.6.2\n * https://github.com/l-lin/angular-datatables\n * License: MIT\n */\nif (typeof module !== \"undefined\" && typeof exports !== \"undefined\" && module.exports === exports) {\n module.exports = 'datatables';\n}\n(function (window, document, $, angular) {\n\n 'use strict';\n\n angular.module('datatables.directive', ['datatables.instances', 'datatables.renderer', 'datatables.options', 'datatables.util']).directive('datatable', dataTable);\n\n /* @ngInject */\n function dataTable($q, $http, $log, DTRendererFactory, DTRendererService, DTPropertyUtil) {\n compileDirective.$inject = ['tElm'];\n ControllerDirective.$inject = ['$scope'];\n return {\n restrict: 'A',\n scope: {\n dtOptions: '=',\n dtColumns: '=',\n dtColumnDefs: '=',\n datatable: '@',\n dtInstance: '='\n },\n compile: compileDirective,\n controller: ControllerDirective\n };\n\n /* @ngInject */\n function compileDirective(tElm) {\n var _staticHTML = tElm[0].innerHTML;\n\n return function postLink($scope, $elem, iAttrs, ctrl) {\n function handleChanges(newVal, oldVal) {\n if (newVal !== oldVal) {\n ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML);\n }\n }\n\n // Options can hold heavy data, and other deep/large objects.\n // watchcollection can improve this by only watching shallowly\n var watchFunction = iAttrs.dtDisableDeepWatchers ? '$watchCollection' : '$watch';\n angular.forEach(['dtColumns', 'dtColumnDefs', 'dtOptions'], function (tableDefField) {\n $scope[watchFunction].call($scope, tableDefField, handleChanges, true);\n });\n DTRendererService.showLoading($elem, $scope);\n ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML);\n };\n }\n\n /* @ngInject */\n function ControllerDirective($scope) {\n var _dtInstance;\n var vm = this;\n vm.buildOptionsPromise = buildOptionsPromise;\n vm.render = render;\n\n function buildOptionsPromise() {\n var defer = $q.defer();\n // Build options\n $q.all([$q.when($scope.dtOptions), $q.when($scope.dtColumns), $q.when($scope.dtColumnDefs)]).then(function (results) {\n var dtOptions = results[0],\n dtColumns = results[1],\n dtColumnDefs = results[2];\n // Since Angular 1.3, the promise throws a \"Maximum call stack size exceeded\" when cloning\n // See https://github.com/l-lin/angular-datatables/issues/110\n DTPropertyUtil.deleteProperty(dtOptions, '$promise');\n DTPropertyUtil.deleteProperty(dtColumns, '$promise');\n DTPropertyUtil.deleteProperty(dtColumnDefs, '$promise');\n var options;\n if (angular.isDefined(dtOptions)) {\n options = {};\n angular.extend(options, dtOptions);\n // Set the columns\n if (angular.isArray(dtColumns)) {\n options.aoColumns = dtColumns;\n }\n\n // Set the column defs\n if (angular.isArray(dtColumnDefs)) {\n options.aoColumnDefs = dtColumnDefs;\n }\n\n // HACK to resolve the language source manually instead of DT\n // See https://github.com/l-lin/angular-datatables/issues/181\n if (options.language && options.language.url) {\n var languageDefer = $q.defer();\n var languageUrl = options.language.url;\n $http.get(options.language.url).then(function (language) {\n languageDefer.resolve(language.data);\n }, function () {\n $log.error('Could not fetch the content of the language from ' + languageUrl);\n });\n options.language = languageDefer.promise;\n }\n }\n return DTPropertyUtil.resolveObjectPromises(options, ['data', 'aaData', 'fnPromise']);\n }).then(function (options) {\n defer.resolve(options);\n });\n return defer.promise;\n }\n\n function render($elem, optionsPromise, staticHTML) {\n optionsPromise.then(function (options) {\n DTRendererService.preRender(options);\n\n var isNgDisplay = $scope.datatable && $scope.datatable === 'ng';\n // Render dataTable\n if (_dtInstance && _dtInstance._renderer) {\n _dtInstance._renderer.withOptions(options).render($elem, $scope, staticHTML).then(function (dtInstance) {\n _dtInstance = dtInstance;\n _setDTInstance(dtInstance);\n });\n } else {\n DTRendererFactory.fromOptions(options, isNgDisplay).render($elem, $scope, staticHTML).then(function (dtInstance) {\n _dtInstance = dtInstance;\n _setDTInstance(dtInstance);\n });\n }\n });\n }\n\n function _setDTInstance(dtInstance) {\n if (angular.isFunction($scope.dtInstance)) {\n $scope.dtInstance(dtInstance);\n } else if (angular.isDefined($scope.dtInstance)) {\n $scope.dtInstance = dtInstance;\n }\n }\n }\n }\n dataTable.$inject = ['$q', '$http', '$log', 'DTRendererFactory', 'DTRendererService', 'DTPropertyUtil'];\n\n 'use strict';\n angular.module('datatables.factory', []).factory('DTOptionsBuilder', dtOptionsBuilder).factory('DTColumnBuilder', dtColumnBuilder).factory('DTColumnDefBuilder', dtColumnDefBuilder).factory('DTLoadingTemplate', dtLoadingTemplate);\n\n /* @ngInject */\n function dtOptionsBuilder() {\n /**\n * The wrapped datatables options class\n * @param sAjaxSource the ajax source to fetch the data\n * @param fnPromise the function that returns a promise to fetch the data\n */\n var DTOptions = {\n /**\n * Add the option to the datatables options\n * @param key the key of the option\n * @param value an object or a function of the option\n * @returns {DTOptions} the options\n */\n withOption: function withOption(key, value) {\n if (angular.isString(key)) {\n this[key] = value;\n }\n return this;\n },\n\n /**\n * Add the Ajax source to the options.\n * This corresponds to the \"ajax\" option\n * @param ajax the ajax source\n * @returns {DTOptions} the options\n */\n withSource: function withSource(ajax) {\n this.ajax = ajax;\n return this;\n },\n\n /**\n * Add the ajax data properties.\n * @param sAjaxDataProp the ajax data property\n * @returns {DTOptions} the options\n */\n withDataProp: function withDataProp(sAjaxDataProp) {\n this.sAjaxDataProp = sAjaxDataProp;\n return this;\n },\n\n /**\n * Set the server data function.\n * @param fn the function of the server retrieval\n * @returns {DTOptions} the options\n */\n withFnServerData: function withFnServerData(fn) {\n if (!angular.isFunction(fn)) {\n throw new Error('The parameter must be a function');\n }\n this.fnServerData = fn;\n return this;\n },\n\n /**\n * Set the pagination type.\n * @param sPaginationType the pagination type\n * @returns {DTOptions} the options\n */\n withPaginationType: function withPaginationType(sPaginationType) {\n if (angular.isString(sPaginationType)) {\n this.sPaginationType = sPaginationType;\n } else {\n throw new Error('The pagination type must be provided');\n }\n return this;\n },\n\n /**\n * Set the language of the datatables\n * @param language the language\n * @returns {DTOptions} the options\n */\n withLanguage: function withLanguage(language) {\n this.language = language;\n return this;\n },\n\n /**\n * Set the language source\n * @param languageSource the language source\n * @returns {DTOptions} the options\n */\n withLanguageSource: function withLanguageSource(languageSource) {\n return this.withLanguage({\n url: languageSource\n });\n },\n\n /**\n * Set default number of items per page to display\n * @param iDisplayLength the number of items per page\n * @returns {DTOptions} the options\n */\n withDisplayLength: function withDisplayLength(iDisplayLength) {\n this.iDisplayLength = iDisplayLength;\n return this;\n },\n\n /**\n * Set the promise to fetch the data\n * @param fnPromise the function that returns a promise\n * @returns {DTOptions} the options\n */\n withFnPromise: function withFnPromise(fnPromise) {\n this.fnPromise = fnPromise;\n return this;\n },\n\n /**\n * Set the Dom of the DataTables.\n * @param dom the dom\n * @returns {DTOptions} the options\n */\n withDOM: function withDOM(dom) {\n this.dom = dom;\n return this;\n }\n };\n\n return {\n /**\n * Create a wrapped datatables options\n * @returns {DTOptions} a wrapped datatables option\n */\n newOptions: function newOptions() {\n return Object.create(DTOptions);\n },\n /**\n * Create a wrapped datatables options with the ajax source setted\n * @param ajax the ajax source\n * @returns {DTOptions} a wrapped datatables option\n */\n fromSource: function fromSource(ajax) {\n var options = Object.create(DTOptions);\n options.ajax = ajax;\n return options;\n },\n /**\n * Create a wrapped datatables options with the data promise.\n * @param fnPromise the function that returns a promise to fetch the data\n * @returns {DTOptions} a wrapped datatables option\n */\n fromFnPromise: function fromFnPromise(fnPromise) {\n var options = Object.create(DTOptions);\n options.fnPromise = fnPromise;\n return options;\n }\n };\n }\n\n function dtColumnBuilder() {\n /**\n * The wrapped datatables column\n * @param mData the data to display of the column\n * @param sTitle the sTitle of the column title to display in the DOM\n */\n var DTColumn = {\n /**\n * Add the option of the column\n * @param key the key of the option\n * @param value an object or a function of the option\n * @returns {DTColumn} the wrapped datatables column\n */\n withOption: function withOption(key, value) {\n if (angular.isString(key)) {\n this[key] = value;\n }\n return this;\n },\n\n /**\n * Set the title of the colum\n * @param sTitle the sTitle of the column\n * @returns {DTColumn} the wrapped datatables column\n */\n withTitle: function withTitle(sTitle) {\n this.sTitle = sTitle;\n return this;\n },\n\n /**\n * Set the CSS class of the column\n * @param sClass the CSS class\n * @returns {DTColumn} the wrapped datatables column\n */\n withClass: function withClass(sClass) {\n this.sClass = sClass;\n return this;\n },\n\n /**\n * Hide the column\n * @returns {DTColumn} the wrapped datatables column\n */\n notVisible: function notVisible() {\n this.bVisible = false;\n return this;\n },\n\n /**\n * Set the column as not sortable\n * @returns {DTColumn} the wrapped datatables column\n */\n notSortable: function notSortable() {\n this.bSortable = false;\n return this;\n },\n\n /**\n * Render each cell with the given parameter\n * @mRender mRender the function/string to render the data\n * @returns {DTColumn} the wrapped datatables column\n */\n renderWith: function renderWith(mRender) {\n this.mRender = mRender;\n return this;\n }\n };\n\n return {\n /**\n * Create a new wrapped datatables column\n * @param mData the data of the column to display\n * @param sTitle the sTitle of the column title to display in the DOM\n * @returns {DTColumn} the wrapped datatables column\n */\n newColumn: function newColumn(mData, sTitle) {\n if (angular.isUndefined(mData)) {\n throw new Error('The parameter \"mData\" is not defined!');\n }\n var column = Object.create(DTColumn);\n column.mData = mData;\n if (angular.isDefined(sTitle)) {\n column.sTitle = sTitle;\n }\n return column;\n },\n DTColumn: DTColumn\n };\n }\n\n /* @ngInject */\n function dtColumnDefBuilder(DTColumnBuilder) {\n return {\n newColumnDef: function newColumnDef(targets) {\n if (angular.isUndefined(targets)) {\n throw new Error('The parameter \"targets\" must be defined! See https://datatables.net/reference/option/columnDefs.targets');\n }\n var column = Object.create(DTColumnBuilder.DTColumn);\n if (angular.isArray(targets)) {\n column.aTargets = targets;\n } else {\n column.aTargets = [targets];\n }\n return column;\n }\n };\n }\n dtColumnDefBuilder.$inject = ['DTColumnBuilder'];\n\n function dtLoadingTemplate($compile, DTDefaultOptions, DT_LOADING_CLASS) {\n return {\n compileHtml: function compileHtml($scope) {\n return $compile(angular.element('
' + DTDefaultOptions.loadingTemplate + '
'))($scope);\n },\n isLoading: function isLoading(elem) {\n return elem.hasClass(DT_LOADING_CLASS);\n }\n };\n }\n dtLoadingTemplate.$inject = ['$compile', 'DTDefaultOptions', 'DT_LOADING_CLASS'];\n\n 'use strict';\n\n angular.module('datatables.instances', ['datatables.util']).factory('DTInstanceFactory', dtInstanceFactory);\n\n function dtInstanceFactory() {\n var DTInstance = {\n reloadData: reloadData,\n changeData: changeData,\n rerender: rerender\n };\n return {\n newDTInstance: newDTInstance,\n copyDTProperties: copyDTProperties\n };\n\n function newDTInstance(renderer) {\n var dtInstance = Object.create(DTInstance);\n dtInstance._renderer = renderer;\n return dtInstance;\n }\n\n function copyDTProperties(result, dtInstance) {\n dtInstance.id = result.id;\n dtInstance.DataTable = result.DataTable;\n dtInstance.dataTable = result.dataTable;\n }\n\n function reloadData(callback, resetPaging) {\n /*jshint validthis:true */\n this._renderer.reloadData(callback, resetPaging);\n }\n\n function changeData(data) {\n /*jshint validthis:true */\n this._renderer.changeData(data);\n }\n\n function rerender() {\n /*jshint validthis:true */\n this._renderer.rerender();\n }\n }\n\n 'use strict';\n\n angular.module('datatables', ['datatables.directive', 'datatables.factory']).run(initAngularDataTables);\n\n /* @ngInject */\n function initAngularDataTables() {\n if ($.fn.DataTable.Api) {\n /**\n * Register an API to destroy a DataTable without detaching the tbody so that we can add new data\n * when rendering with the \"Angular way\".\n */\n $.fn.DataTable.Api.register('ngDestroy()', function (remove) {\n remove = remove || false;\n\n return this.iterator('table', function (settings) {\n var orig = settings.nTableWrapper.parentNode;\n var classes = settings.oClasses;\n var table = settings.nTable;\n var tbody = settings.nTBody;\n var thead = settings.nTHead;\n var tfoot = settings.nTFoot;\n var jqTable = $(table);\n var jqTbody = $(tbody);\n var jqWrapper = $(settings.nTableWrapper);\n var rows = $.map(settings.aoData, function (r) {\n return r.nTr;\n });\n var ien;\n\n // Flag to note that the table is currently being destroyed - no action\n // should be taken\n settings.bDestroying = true;\n\n // Fire off the destroy callbacks for plug-ins etc\n $.fn.DataTable.ext.internal._fnCallbackFire(settings, 'aoDestroyCallback', 'destroy', [settings]);\n\n // If not being removed from the document, make all columns visible\n if (!remove) {\n new $.fn.DataTable.Api(settings).columns().visible(true);\n }\n\n // Blitz all `DT` namespaced events (these are internal events, the\n // lowercase, `dt` events are user subscribed and they are responsible\n // for removing them\n jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');\n $(window).unbind('.DT-' + settings.sInstance);\n\n // When scrolling we had to break the table up - restore it\n if (table !== thead.parentNode) {\n jqTable.children('thead').detach();\n jqTable.append(thead);\n }\n\n if (tfoot && table !== tfoot.parentNode) {\n jqTable.children('tfoot').detach();\n jqTable.append(tfoot);\n }\n\n // Remove the DataTables generated nodes, events and classes\n jqTable.detach();\n jqWrapper.detach();\n\n settings.aaSorting = [];\n settings.aaSortingFixed = [];\n $.fn.DataTable.ext.internal._fnSortingClasses(settings);\n\n $(rows).removeClass(settings.asStripeClasses.join(' '));\n\n $('th, td', thead).removeClass(classes.sSortable + ' ' + classes.sSortableAsc + ' ' + classes.sSortableDesc + ' ' + classes.sSortableNone);\n\n if (settings.bJUI) {\n $('th span.' + classes.sSortIcon + ', td span.' + classes.sSortIcon, thead).detach();\n $('th, td', thead).each(function () {\n var wrapper = $('div.' + classes.sSortJUIWrapper, this);\n $(this).append(wrapper.contents());\n wrapper.detach();\n });\n }\n\n // -------------------------------------------------------------------------\n // This is the only change with the \"destroy()\" API (with DT v1.10.1)\n // -------------------------------------------------------------------------\n if (!remove && orig) {\n // insertBefore acts like appendChild if !arg[1]\n if (orig.contains(settings.nTableReinsertBefore)) {\n orig.insertBefore(table, settings.nTableReinsertBefore);\n } else {\n orig.appendChild(table);\n }\n }\n // Add the TR elements back into the table in their original order\n // jqTbody.children().detach();\n // jqTbody.append( rows );\n // -------------------------------------------------------------------------\n\n // Restore the width of the original table - was read from the style property,\n // so we can restore directly to that\n jqTable.css('width', settings.sDestroyWidth).removeClass(classes.sTable);\n\n // If the were originally stripe classes - then we add them back here.\n // Note this is not fool proof (for example if not all rows had stripe\n // classes - but it's a good effort without getting carried away\n ien = settings.asDestroyStripes.length;\n\n if (ien) {\n jqTbody.children().each(function (i) {\n $(this).addClass(settings.asDestroyStripes[i % ien]);\n });\n }\n\n /* Remove the settings object from the settings array */\n var idx = $.inArray(settings, $.fn.DataTable.settings);\n if (idx !== -1) {\n $.fn.DataTable.settings.splice(idx, 1);\n }\n });\n });\n }\n }\n\n 'use strict';\n angular.module('datatables.options', []).constant('DT_DEFAULT_OPTIONS', {\n // Default ajax properties. See http://legacy.datatables.net/usage/options#sAjaxDataProp\n sAjaxDataProp: '',\n // Set default columns (used when none are provided)\n aoColumns: []\n }).constant('DT_LOADING_CLASS', 'dt-loading').service('DTDefaultOptions', dtDefaultOptions);\n\n function dtDefaultOptions() {\n var options = {\n loadingTemplate: '

Loading...

',\n bootstrapOptions: {},\n setLoadingTemplate: setLoadingTemplate,\n setLanguageSource: setLanguageSource,\n setLanguage: setLanguage,\n setDisplayLength: setDisplayLength,\n setBootstrapOptions: setBootstrapOptions,\n setDOM: setDOM,\n setOption: setOption\n };\n\n return options;\n\n /**\n * Set the default loading template\n * @param loadingTemplate the HTML to display when loading the table\n * @returns {DTDefaultOptions} the default option config\n */\n function setLoadingTemplate(loadingTemplate) {\n options.loadingTemplate = loadingTemplate;\n return options;\n }\n\n /**\n * Set the default language source for all datatables\n * @param sLanguageSource the language source\n * @returns {DTDefaultOptions} the default option config\n */\n function setLanguageSource(sLanguageSource) {\n // HACK to resolve the language source manually instead of DT\n // See https://github.com/l-lin/angular-datatables/issues/356\n $.ajax({\n dataType: 'json',\n url: sLanguageSource,\n success: function success(json) {\n $.extend(true, $.fn.DataTable.defaults, {\n language: json\n });\n }\n });\n return options;\n }\n\n /**\n * Set the language for all datatables\n * @param language the language\n * @returns {DTDefaultOptions} the default option config\n */\n function setLanguage(language) {\n $.extend(true, $.fn.DataTable.defaults, {\n language: language\n });\n return options;\n }\n\n /**\n * Set the default number of items to display for all datatables\n * @param displayLength the number of items to display\n * @returns {DTDefaultOptions} the default option config\n */\n function setDisplayLength(displayLength) {\n $.extend($.fn.DataTable.defaults, {\n displayLength: displayLength\n });\n return options;\n }\n\n /**\n * Set the default options to be use for Bootstrap integration.\n * See https://github.com/l-lin/angular-datatables/blob/dev/src/angular-datatables.bootstrap.options.js to check\n * what default options Angular DataTables is using.\n * @param oBootstrapOptions an object containing the default options for Bootstrap integration\n * @returns {DTDefaultOptions} the default option config\n */\n function setBootstrapOptions(oBootstrapOptions) {\n options.bootstrapOptions = oBootstrapOptions;\n return options;\n }\n\n /**\n * Set the DOM for all DataTables.\n * See https://datatables.net/reference/option/dom\n * @param dom the dom\n * @returns {DTDefaultoptions} the default option config\n */\n function setDOM(dom) {\n $.extend($.fn.DataTable.defaults, {\n dom: dom\n });\n return options;\n }\n\n /**\n * Set global default option to all DataTables.\n * @param key the key of the default option\n * @param value the value of the default option\n */\n function setOption(key, value) {\n if (angular.isString(key)) {\n var obj = {};\n obj[key] = value;\n $.extend($.fn.DataTable.defaults, obj);\n }\n }\n }\n\n 'use strict';\n angular.module('datatables.renderer', ['datatables.instances', 'datatables.factory', 'datatables.options', 'datatables.instances']).factory('DTRendererService', dtRendererService).factory('DTRenderer', dtRenderer).factory('DTDefaultRenderer', dtDefaultRenderer).factory('DTNGRenderer', dtNGRenderer).factory('DTPromiseRenderer', dtPromiseRenderer).factory('DTAjaxRenderer', dtAjaxRenderer).factory('DTRendererFactory', dtRendererFactory);\n\n /* @ngInject */\n function dtRendererService(DTLoadingTemplate) {\n var plugins = [];\n var rendererService = {\n showLoading: showLoading,\n hideLoading: hideLoading,\n renderDataTable: renderDataTable,\n hideLoadingAndRenderDataTable: hideLoadingAndRenderDataTable,\n registerPlugin: registerPlugin,\n postRender: postRender,\n preRender: preRender\n };\n return rendererService;\n\n function showLoading($elem, $scope) {\n var $loading = angular.element(DTLoadingTemplate.compileHtml($scope));\n $elem.after($loading);\n $elem.hide();\n $loading.show();\n }\n\n function hideLoading($elem) {\n $elem.show();\n var next = $elem.next();\n if (DTLoadingTemplate.isLoading(next)) {\n next.remove();\n }\n }\n\n function renderDataTable($elem, options) {\n var dtId = '#' + $elem.attr('id');\n if ($.fn.dataTable.isDataTable(dtId) && angular.isObject(options)) {\n options.destroy = true;\n }\n // See http://datatables.net/manual/api#Accessing-the-API to understand the difference between DataTable and dataTable\n var DT = $elem.DataTable(options);\n var dt = $elem.dataTable();\n\n var result = {\n id: $elem.attr('id'),\n DataTable: DT,\n dataTable: dt\n };\n\n postRender(options, result);\n\n return result;\n }\n\n function hideLoadingAndRenderDataTable($elem, options) {\n rendererService.hideLoading($elem);\n return rendererService.renderDataTable($elem, options);\n }\n\n function registerPlugin(plugin) {\n plugins.push(plugin);\n }\n\n function postRender(options, result) {\n angular.forEach(plugins, function (plugin) {\n if (angular.isFunction(plugin.postRender)) {\n plugin.postRender(options, result);\n }\n });\n }\n\n function preRender(options) {\n angular.forEach(plugins, function (plugin) {\n if (angular.isFunction(plugin.preRender)) {\n plugin.preRender(options);\n }\n });\n }\n }\n dtRendererService.$inject = ['DTLoadingTemplate'];\n\n function dtRenderer() {\n return {\n withOptions: function withOptions(options) {\n this.options = options;\n return this;\n }\n };\n }\n\n /* @ngInject */\n function dtDefaultRenderer($q, DTRenderer, DTRendererService, DTInstanceFactory) {\n return {\n create: create\n };\n\n function create(options) {\n var _oTable;\n var _$elem;\n var _$scope;\n var renderer = Object.create(DTRenderer);\n renderer.name = 'DTDefaultRenderer';\n renderer.options = options;\n renderer.render = render;\n renderer.reloadData = reloadData;\n renderer.changeData = changeData;\n renderer.rerender = rerender;\n\n function render($elem, $scope) {\n _$elem = $elem;\n _$scope = $scope;\n var dtInstance = DTInstanceFactory.newDTInstance(renderer);\n var result = DTRendererService.hideLoadingAndRenderDataTable($elem, renderer.options);\n _oTable = result.DataTable;\n DTInstanceFactory.copyDTProperties(result, dtInstance);\n return $q.when(dtInstance);\n }\n\n function reloadData() {\n // Do nothing\n }\n\n function changeData() {\n // Do nothing\n }\n\n function rerender() {\n _oTable.destroy();\n DTRendererService.showLoading(_$elem, _$scope);\n render(_$elem, _$scope);\n }\n return renderer;\n }\n }\n dtDefaultRenderer.$inject = ['$q', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];\n\n /* @ngInject */\n function dtNGRenderer($log, $q, $compile, $timeout, DTRenderer, DTRendererService, DTInstanceFactory) {\n /**\n * Renderer for displaying the Angular way\n * @param options\n * @returns {{options: *}} the renderer\n * @constructor\n */\n return {\n create: create\n };\n\n function create(options) {\n var _staticHTML;\n var _oTable;\n var _$elem;\n var _parentScope;\n var _newParentScope;\n var dtInstance;\n var renderer = Object.create(DTRenderer);\n renderer.name = 'DTNGRenderer';\n renderer.options = options;\n renderer.render = render;\n renderer.reloadData = reloadData;\n renderer.changeData = changeData;\n renderer.rerender = rerender;\n return renderer;\n\n function render($elem, $scope, staticHTML) {\n _staticHTML = staticHTML;\n _$elem = $elem;\n _parentScope = $scope.$parent;\n dtInstance = DTInstanceFactory.newDTInstance(renderer);\n\n var defer = $q.defer();\n var _$tableElem = _staticHTML.match(//i);\n var _expression = _$tableElem[1];\n // Find the resources from the comment displayed by angular in the DOM\n // This regexp is inspired by the one used in the \"ngRepeat\" directive\n var _match = _expression.match(/^\\s*.+?\\s+in\\s+([a-zA-Z0-9\\.-_$]*)\\s*/m);\n\n if (!_match) {\n throw new Error('Expected expression in form of \"_item_ in _collection_[ track by _id_]\" but got \"{0}\".', _expression);\n }\n var _ngRepeatAttr = _match[1];\n\n var _alreadyRendered = false;\n\n _parentScope.$watchCollection(_ngRepeatAttr, function () {\n if (_oTable && _alreadyRendered) {\n _destroyAndCompile();\n }\n $timeout(function () {\n _alreadyRendered = true;\n // Ensure that prerender is called when the collection is updated\n // See https://github.com/l-lin/angular-datatables/issues/502\n DTRendererService.preRender(renderer.options);\n var result = DTRendererService.hideLoadingAndRenderDataTable(_$elem, renderer.options);\n _oTable = result.DataTable;\n DTInstanceFactory.copyDTProperties(result, dtInstance);\n defer.resolve(dtInstance);\n }, 0, false);\n }, true);\n return defer.promise;\n }\n\n function reloadData() {\n $log.warn('The Angular Renderer does not support reloading data. You need to do it directly on your model');\n }\n\n function changeData() {\n $log.warn('The Angular Renderer does not support changing the data. You need to change your model directly.');\n }\n\n function rerender() {\n _destroyAndCompile();\n DTRendererService.showLoading(_$elem, _parentScope);\n // Ensure that prerender is called after loadData from promise\n // See https://github.com/l-lin/angular-datatables/issues/563\n DTRendererService.preRender(options);\n $timeout(function () {\n var result = DTRendererService.hideLoadingAndRenderDataTable(_$elem, renderer.options);\n _oTable = result.DataTable;\n DTInstanceFactory.copyDTProperties(result, dtInstance);\n }, 0, false);\n }\n\n function _destroyAndCompile() {\n if (_newParentScope) {\n _newParentScope.$destroy();\n }\n _oTable.ngDestroy();\n // Re-compile because we lost the angular binding to the existing data\n _$elem.html(_staticHTML);\n _newParentScope = _parentScope.$new();\n $compile(_$elem.contents())(_newParentScope);\n }\n }\n }\n dtNGRenderer.$inject = ['$log', '$q', '$compile', '$timeout', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];\n\n /* @ngInject */\n function dtPromiseRenderer($q, $timeout, $log, DTRenderer, DTRendererService, DTInstanceFactory) {\n /**\n * Renderer for displaying with a promise\n * @param options the options\n * @returns {{options: *}} the renderer\n * @constructor\n */\n return {\n create: create\n };\n\n function create(options) {\n var _oTable;\n var _loadedPromise = null;\n var _$elem;\n var _$scope;\n\n var dtInstance;\n var renderer = Object.create(DTRenderer);\n renderer.name = 'DTPromiseRenderer';\n renderer.options = options;\n renderer.render = render;\n renderer.reloadData = reloadData;\n renderer.changeData = changeData;\n renderer.rerender = rerender;\n return renderer;\n\n function render($elem, $scope) {\n var defer = $q.defer();\n dtInstance = DTInstanceFactory.newDTInstance(renderer);\n _$elem = $elem;\n _$scope = $scope;\n _resolve(renderer.options.fnPromise, DTRendererService.renderDataTable).then(function (result) {\n _oTable = result.DataTable;\n DTInstanceFactory.copyDTProperties(result, dtInstance);\n defer.resolve(dtInstance);\n });\n return defer.promise;\n }\n\n function reloadData(callback, resetPaging) {\n var previousPage = _oTable && _oTable.page() ? _oTable.page() : 0;\n if (angular.isFunction(renderer.options.fnPromise)) {\n _resolve(renderer.options.fnPromise, _redrawRows).then(function (result) {\n if (angular.isFunction(callback)) {\n callback(result.DataTable.data());\n }\n if (resetPaging === false) {\n result.DataTable.page(previousPage).draw(false);\n }\n });\n } else {\n $log.warn('In order to use the reloadData functionality with a Promise renderer, you need to provide a function that returns a promise.');\n }\n }\n\n function changeData(fnPromise) {\n renderer.options.fnPromise = fnPromise;\n // We also need to set the $scope.dtOptions, otherwise, when we change the columns, it will revert to the old data\n // See https://github.com/l-lin/angular-datatables/issues/359\n _$scope.dtOptions.fnPromise = fnPromise;\n _resolve(renderer.options.fnPromise, _redrawRows);\n }\n\n function rerender() {\n _oTable.destroy();\n DTRendererService.showLoading(_$elem, _$scope);\n // Ensure that prerender is called after loadData from promise\n // See https://github.com/l-lin/angular-datatables/issues/563\n DTRendererService.preRender(options);\n render(_$elem, _$scope);\n }\n\n function _resolve(fnPromise, callback) {\n var defer = $q.defer();\n if (angular.isUndefined(fnPromise)) {\n throw new Error('You must provide a promise or a function that returns a promise!');\n }\n if (_loadedPromise) {\n _loadedPromise.then(function () {\n defer.resolve(_startLoading(fnPromise, callback));\n });\n } else {\n defer.resolve(_startLoading(fnPromise, callback));\n }\n return defer.promise;\n }\n\n function _startLoading(fnPromise, callback) {\n var defer = $q.defer();\n if (angular.isFunction(fnPromise)) {\n _loadedPromise = fnPromise();\n } else {\n _loadedPromise = fnPromise;\n }\n _loadedPromise.then(function (result) {\n var data = result;\n // In case the data is nested in an object\n if (renderer.options.sAjaxDataProp) {\n var properties = renderer.options.sAjaxDataProp.split('.');\n while (properties.length) {\n var property = properties.shift();\n if (property in data) {\n data = data[property];\n }\n }\n }\n _loadedPromise = null;\n defer.resolve(_doRender(renderer.options, _$elem, data, callback));\n });\n return defer.promise;\n }\n\n function _doRender(options, $elem, data, callback) {\n var defer = $q.defer();\n // Since Angular 1.3, the promise renderer is throwing \"Maximum call stack size exceeded\"\n // By removing the $promise attribute, we avoid an infinite loop when jquery is cloning the data\n // See https://github.com/l-lin/angular-datatables/issues/110\n delete data.$promise;\n options.aaData = data;\n // Add $timeout to be sure that angular has finished rendering before calling datatables\n $timeout(function () {\n DTRendererService.hideLoading($elem);\n // Set it to true in order to be able to redraw the dataTable\n options.bDestroy = true;\n defer.resolve(callback($elem, options));\n }, 0, false);\n return defer.promise;\n }\n\n function _redrawRows($elem, options) {\n _oTable.clear();\n _oTable.rows.add(options.aaData).draw(options.redraw);\n return {\n id: dtInstance.id,\n DataTable: dtInstance.DataTable,\n dataTable: dtInstance.dataTable\n };\n }\n }\n }\n dtPromiseRenderer.$inject = ['$q', '$timeout', '$log', 'DTRenderer', 'DTRendererService', 'DTInstanceFactory'];\n\n /* @ngInject */\n function dtAjaxRenderer($q, $timeout, DTRenderer, DTRendererService, DT_DEFAULT_OPTIONS, DTInstanceFactory) {\n /**\n * Renderer for displaying with Ajax\n * @param options the options\n * @returns {{options: *}} the renderer\n * @constructor\n */\n return {\n create: create\n };\n\n function create(options) {\n var _oTable;\n var _$elem;\n var _$scope;\n var renderer = Object.create(DTRenderer);\n renderer.name = 'DTAjaxRenderer';\n renderer.options = options;\n renderer.render = render;\n renderer.reloadData = reloadData;\n renderer.changeData = changeData;\n renderer.rerender = rerender;\n return renderer;\n\n function render($elem, $scope) {\n _$elem = $elem;\n _$scope = $scope;\n var defer = $q.defer();\n var dtInstance = DTInstanceFactory.newDTInstance(renderer);\n // Define default values in case it is an ajax datatables\n if (angular.isUndefined(renderer.options.sAjaxDataProp)) {\n renderer.options.sAjaxDataProp = DT_DEFAULT_OPTIONS.sAjaxDataProp;\n }\n if (angular.isUndefined(renderer.options.aoColumns)) {\n renderer.options.aoColumns = DT_DEFAULT_OPTIONS.aoColumns;\n }\n _doRender(renderer.options, $elem).then(function (result) {\n _oTable = result.DataTable;\n DTInstanceFactory.copyDTProperties(result, dtInstance);\n defer.resolve(dtInstance);\n });\n return defer.promise;\n }\n\n function reloadData(callback, resetPaging) {\n if (_oTable) {\n _oTable.ajax.reload(callback, resetPaging);\n }\n }\n\n function changeData(ajax) {\n renderer.options.ajax = ajax;\n // We also need to set the $scope.dtOptions, otherwise, when we change the columns, it will revert to the old data\n // See https://github.com/l-lin/angular-datatables/issues/359\n _$scope.dtOptions.ajax = ajax;\n }\n\n function rerender() {\n // Ensure that prerender is called after loadData from promise\n // See https://github.com/l-lin/angular-datatables/issues/563\n DTRendererService.preRender(options);\n render(_$elem, _$scope);\n }\n\n function _doRender(options, $elem) {\n var defer = $q.defer();\n // Destroy the table if it exists in order to be able to redraw the dataTable\n options.bDestroy = true;\n if (_oTable) {\n _oTable.destroy();\n DTRendererService.showLoading(_$elem, _$scope);\n // Empty in case of columns change\n $elem.empty();\n }\n DTRendererService.hideLoading($elem);\n // Condition to refresh the dataTable\n if (_shouldDeferRender(options)) {\n $timeout(function () {\n defer.resolve(DTRendererService.renderDataTable($elem, options));\n }, 0, false);\n } else {\n defer.resolve(DTRendererService.renderDataTable($elem, options));\n }\n return defer.promise;\n }\n // See https://github.com/l-lin/angular-datatables/issues/147\n function _shouldDeferRender(options) {\n if (angular.isDefined(options) && angular.isDefined(options.dom)) {\n // S for scroller plugin\n return options.dom.indexOf('S') >= 0;\n }\n return false;\n }\n }\n }\n dtAjaxRenderer.$inject = ['$q', '$timeout', 'DTRenderer', 'DTRendererService', 'DT_DEFAULT_OPTIONS', 'DTInstanceFactory'];\n\n /* @ngInject */\n function dtRendererFactory(DTDefaultRenderer, DTNGRenderer, DTPromiseRenderer, DTAjaxRenderer) {\n return {\n fromOptions: fromOptions\n };\n\n function fromOptions(options, isNgDisplay) {\n if (isNgDisplay) {\n if (options && options.serverSide) {\n throw new Error('You cannot use server side processing along with the Angular renderer!');\n }\n return DTNGRenderer.create(options);\n }\n if (angular.isDefined(options)) {\n if (angular.isDefined(options.fnPromise) && options.fnPromise !== null) {\n if (options.serverSide) {\n throw new Error('You cannot use server side processing along with the Promise renderer!');\n }\n return DTPromiseRenderer.create(options);\n }\n if (angular.isDefined(options.ajax) && options.ajax !== null || angular.isDefined(options.ajax) && options.ajax !== null) {\n return DTAjaxRenderer.create(options);\n }\n return DTDefaultRenderer.create(options);\n }\n return DTDefaultRenderer.create();\n }\n }\n dtRendererFactory.$inject = ['DTDefaultRenderer', 'DTNGRenderer', 'DTPromiseRenderer', 'DTAjaxRenderer'];\n\n 'use strict';\n\n angular.module('datatables.util', []).factory('DTPropertyUtil', dtPropertyUtil);\n\n /* @ngInject */\n function dtPropertyUtil($q) {\n return {\n overrideProperties: overrideProperties,\n deleteProperty: deleteProperty,\n resolveObjectPromises: resolveObjectPromises,\n resolveArrayPromises: resolveArrayPromises\n };\n\n /**\n * Overrides the source property with the given target properties.\n * Source is not written. It's making a fresh copy of it in order to ensure that we do not change the parameters.\n * @param source the source properties to override\n * @param target the target properties\n * @returns {*} the object overrided\n */\n function overrideProperties(source, target) {\n var result = angular.copy(source);\n\n if (angular.isUndefined(result) || result === null) {\n result = {};\n }\n if (angular.isUndefined(target) || target === null) {\n return result;\n }\n if (angular.isObject(target)) {\n for (var prop in target) {\n if (target.hasOwnProperty(prop)) {\n result[prop] = overrideProperties(result[prop], target[prop]);\n }\n }\n } else {\n result = angular.copy(target);\n }\n return result;\n }\n\n /**\n * Delete the property from the given object\n * @param obj the object\n * @param propertyName the property name\n */\n function deleteProperty(obj, propertyName) {\n if (angular.isObject(obj)) {\n delete obj[propertyName];\n }\n }\n\n /**\n * Resolve any promises from a given object if there are any.\n * @param obj the object\n * @param excludedPropertiesName the list of properties to ignore\n * @returns {promise} the promise that the object attributes promises are all resolved\n */\n function resolveObjectPromises(obj, excludedPropertiesName) {\n var defer = $q.defer(),\n promises = [],\n resolvedObj = {},\n excludedProp = excludedPropertiesName || [];\n if (!angular.isObject(obj) || angular.isArray(obj)) {\n defer.resolve(obj);\n } else {\n resolvedObj = angular.extend(resolvedObj, obj);\n for (var prop in resolvedObj) {\n if (resolvedObj.hasOwnProperty(prop) && $.inArray(prop, excludedProp) === -1) {\n if (angular.isArray(resolvedObj[prop])) {\n promises.push(resolveArrayPromises(resolvedObj[prop]));\n } else {\n promises.push($q.when(resolvedObj[prop]));\n }\n }\n }\n $q.all(promises).then(function (result) {\n var index = 0;\n for (var prop in resolvedObj) {\n if (resolvedObj.hasOwnProperty(prop) && $.inArray(prop, excludedProp) === -1) {\n resolvedObj[prop] = result[index++];\n }\n }\n defer.resolve(resolvedObj);\n });\n }\n return defer.promise;\n }\n\n /**\n * Resolve the given array promises\n * @param array the array containing promise or not\n * @returns {promise} the promise that the array contains a list of objects/values promises that are resolved\n */\n function resolveArrayPromises(array) {\n var defer = $q.defer(),\n promises = [],\n resolveArray = [];\n if (!angular.isArray(array)) {\n defer.resolve(array);\n } else {\n angular.forEach(array, function (item) {\n if (angular.isObject(item)) {\n promises.push(resolveObjectPromises(item));\n } else {\n promises.push($q.when(item));\n }\n });\n $q.all(promises).then(function (result) {\n angular.forEach(result, function (item) {\n resolveArray.push(item);\n });\n defer.resolve(resolveArray);\n });\n }\n return defer.promise;\n }\n }\n dtPropertyUtil.$inject = ['$q'];\n})(window, document, jQuery, angular);\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack:///./node_modules/angular-datatables/dist/angular-datatables.js?"); - -/***/ }), - -/***/ "./node_modules/angular-datatables/dist/css/angular-datatables.min.css": -/*!*****************************************************************************!*\ - !*** ./node_modules/angular-datatables/dist/css/angular-datatables.min.css ***! - \*****************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -eval("\nvar content = __webpack_require__(/*! !../../../css-loader!./angular-datatables.min.css */ \"./node_modules/css-loader/index.js!./node_modules/angular-datatables/dist/css/angular-datatables.min.css\");\n\nif(typeof content === 'string') content = [[module.i, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = __webpack_require__(/*! ../../../style-loader/lib/addStyles.js */ \"./node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(false) {}\n\n//# sourceURL=webpack:///./node_modules/angular-datatables/dist/css/angular-datatables.min.css?"); - -/***/ }), - -/***/ "./node_modules/angular-datatables/dist/plugins/bootstrap/angular-datatables.bootstrap.js": -/*!************************************************************************************************!*\ - !*** ./node_modules/angular-datatables/dist/plugins/bootstrap/angular-datatables.bootstrap.js ***! - \************************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -eval("/* WEBPACK VAR INJECTION */(function(jQuery) {/*** IMPORTS FROM imports-loader ***/\nvar define = false;\n\n\"use strict\";\n\n/*!\n * angular-datatables - v0.6.2\n * https://github.com/l-lin/angular-datatables\n * License: MIT\n */\nif (typeof module !== \"undefined\" && typeof exports !== \"undefined\" && module.exports === exports) {\n module.exports = 'datatables.bootstrap';\n}\n(function (window, document, $, angular) {\n\n 'use strict';\n\n angular.module('datatables.bootstrap.colvis', ['datatables.bootstrap.options', 'datatables.util']).service('DTBootstrapColVis', dtBootstrapColVis);\n\n /* @ngInject */\n function dtBootstrapColVis(DTPropertyUtil, DTBootstrapDefaultOptions) {\n var _initializedColVis = false;\n return {\n integrate: integrate,\n deIntegrate: deIntegrate\n };\n\n function integrate(addDrawCallbackFunction, bootstrapOptions) {\n if (!_initializedColVis) {\n var colVisProperties = DTPropertyUtil.overrideProperties(DTBootstrapDefaultOptions.getOptions().ColVis, bootstrapOptions ? bootstrapOptions.ColVis : null);\n /* ColVis Bootstrap compatibility */\n if ($.fn.DataTable.ColVis) {\n addDrawCallbackFunction(function () {\n $('.ColVis_MasterButton').attr('class', 'ColVis_MasterButton ' + colVisProperties.classes.masterButton);\n $('.ColVis_Button').removeClass('ColVis_Button');\n });\n }\n\n _initializedColVis = true;\n }\n }\n\n function deIntegrate() {\n if (_initializedColVis && $.fn.DataTable.ColVis) {\n _initializedColVis = false;\n }\n }\n }\n dtBootstrapColVis.$inject = ['DTPropertyUtil', 'DTBootstrapDefaultOptions'];\n\n 'use strict';\n\n // See http://getbootstrap.com\n angular.module('datatables.bootstrap', ['datatables.bootstrap.options', 'datatables.bootstrap.tabletools', 'datatables.bootstrap.colvis']).config(dtBootstrapConfig).run(initBootstrapPlugin).service('DTBootstrap', dtBootstrap);\n\n /* @ngInject */\n function dtBootstrapConfig($provide) {\n $provide.decorator('DTOptionsBuilder', dtOptionsBuilderDecorator);\n\n function dtOptionsBuilderDecorator($delegate) {\n var newOptions = $delegate.newOptions;\n var fromSource = $delegate.fromSource;\n var fromFnPromise = $delegate.fromFnPromise;\n\n $delegate.newOptions = function () {\n return _decorateOptions(newOptions);\n };\n $delegate.fromSource = function (ajax) {\n return _decorateOptions(fromSource, ajax);\n };\n $delegate.fromFnPromise = function (fnPromise) {\n return _decorateOptions(fromFnPromise, fnPromise);\n };\n\n return $delegate;\n\n function _decorateOptions(fn, params) {\n var options = fn(params);\n options.withBootstrap = withBootstrap;\n options.withBootstrapOptions = withBootstrapOptions;\n return options;\n\n /**\n * Add bootstrap compatibility\n * @returns {DTOptions} the options\n */\n function withBootstrap() {\n options.hasBootstrap = true;\n // Override page button active CSS class\n if (angular.isObject(options.oClasses)) {\n options.oClasses.sPageButtonActive = 'active';\n } else {\n options.oClasses = {\n sPageButtonActive: 'active'\n };\n }\n return options;\n }\n\n /**\n * Add bootstrap options\n * @param bootstrapOptions the bootstrap options\n * @returns {DTOptions} the options\n */\n function withBootstrapOptions(bootstrapOptions) {\n options.bootstrap = bootstrapOptions;\n return options;\n }\n }\n }\n dtOptionsBuilderDecorator.$inject = ['$delegate'];\n }\n dtBootstrapConfig.$inject = ['$provide'];\n\n /* @ngInject */\n function initBootstrapPlugin(DTRendererService, DTBootstrap) {\n var columnFilterPlugin = {\n preRender: preRender\n };\n DTRendererService.registerPlugin(columnFilterPlugin);\n\n function preRender(options) {\n // Integrate bootstrap (or not)\n if (options && options.hasBootstrap) {\n DTBootstrap.integrate(options);\n } else {\n DTBootstrap.deIntegrate();\n }\n }\n }\n initBootstrapPlugin.$inject = ['DTRendererService', 'DTBootstrap'];\n\n /**\n * Source: https://editor.datatables.net/release/DataTables/extras/Editor/examples/bootstrap.html\n */\n /* @ngInject */\n function dtBootstrap(DTBootstrapTableTools, DTBootstrapColVis, DTBootstrapDefaultOptions, DTPropertyUtil) {\n var _initialized = false,\n _drawCallbackFunctionList = [],\n _savedFn = {};\n\n return {\n integrate: integrate,\n deIntegrate: deIntegrate\n };\n\n function _saveFnToBeOverrided() {\n _savedFn.oStdClasses = angular.copy($.fn.dataTableExt.oStdClasses);\n _savedFn.fnPagingInfo = $.fn.dataTableExt.oApi.fnPagingInfo;\n _savedFn.renderer = angular.copy($.fn.DataTable.ext.renderer);\n if ($.fn.DataTable.TableTools) {\n _savedFn.TableTools = {\n classes: angular.copy($.fn.DataTable.TableTools.classes),\n oTags: angular.copy($.fn.DataTable.TableTools.DEFAULTS.oTags)\n };\n }\n }\n\n function _revertToDTFn() {\n $.extend($.fn.dataTableExt.oStdClasses, _savedFn.oStdClasses);\n $.fn.dataTableExt.oApi.fnPagingInfo = _savedFn.fnPagingInfo;\n $.extend(true, $.fn.DataTable.ext.renderer, _savedFn.renderer);\n }\n\n function _overrideClasses() {\n /* Default class modification */\n $.extend($.fn.dataTableExt.oStdClasses, {\n 'sWrapper': 'dataTables_wrapper form-inline',\n 'sFilterInput': 'form-control input-sm',\n 'sLengthSelect': 'form-control input-sm',\n 'sFilter': 'dataTables_filter',\n 'sLength': 'dataTables_length'\n });\n }\n\n function _overridePagingInfo() {\n /* API method to get paging information */\n $.fn.dataTableExt.oApi.fnPagingInfo = function (oSettings) {\n return {\n 'iStart': oSettings._iDisplayStart,\n 'iEnd': oSettings.fnDisplayEnd(),\n 'iLength': oSettings._iDisplayLength,\n 'iTotal': oSettings.fnRecordsTotal(),\n 'iFilteredTotal': oSettings.fnRecordsDisplay(),\n 'iPage': oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength),\n 'iTotalPages': oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength)\n };\n };\n }\n\n function _overridePagination(bootstrapOptions) {\n // Note: Copy paste with some changes from DataTables v1.10.1 source code\n $.extend(true, $.fn.DataTable.ext.renderer, {\n pageButton: {\n _: function _(settings, host, idx, buttons, page, pages) {\n var classes = settings.oClasses;\n var lang = settings.language ? settings.language.oPaginate : settings.oLanguage.oPaginate;\n var btnDisplay,\n btnClass,\n counter = 0;\n var paginationClasses = DTPropertyUtil.overrideProperties(DTBootstrapDefaultOptions.getOptions().pagination, bootstrapOptions ? bootstrapOptions.pagination : null);\n var $paginationContainer = $('', {\n 'class': paginationClasses.classes.ul\n });\n\n var attach = function attach(container, buttons) {\n var i, ien, node, button;\n var clickHandler = function clickHandler(e) {\n e.preventDefault();\n // IMPORTANT: Reference to internal functions of DT. It might change between versions\n $.fn.DataTable.ext.internal._fnPageChange(settings, e.data.action, true);\n };\n\n for (i = 0, ien = buttons.length; i < ien; i++) {\n button = buttons[i];\n\n if ($.isArray(button)) {\n // Override DT element\n button.DT_el = 'li';\n var inner = $('<' + (button.DT_el || 'div') + '/>').appendTo($paginationContainer);\n attach(inner, button);\n } else {\n btnDisplay = '';\n btnClass = '';\n var $paginationBtn = $('
  • '),\n isDisabled;\n\n switch (button) {\n case 'ellipsis':\n $paginationContainer.append('
  • ');\n break;\n\n case 'first':\n btnDisplay = lang.sFirst;\n btnClass = button;\n if (page <= 0) {\n $paginationBtn.addClass(classes.sPageButtonDisabled);\n isDisabled = true;\n }\n break;\n\n case 'previous':\n btnDisplay = lang.sPrevious;\n btnClass = button;\n if (page <= 0) {\n $paginationBtn.addClass(classes.sPageButtonDisabled);\n isDisabled = true;\n }\n break;\n\n case 'next':\n btnDisplay = lang.sNext;\n btnClass = button;\n if (page >= pages - 1) {\n $paginationBtn.addClass(classes.sPageButtonDisabled);\n isDisabled = true;\n }\n break;\n\n case 'last':\n btnDisplay = lang.sLast;\n btnClass = button;\n if (page >= pages - 1) {\n $paginationBtn.addClass(classes.sPageButtonDisabled);\n isDisabled = true;\n }\n break;\n\n default:\n btnDisplay = button + 1;\n btnClass = '';\n if (page === button) {\n $paginationBtn.addClass(classes.sPageButtonActive);\n }\n break;\n }\n\n if (btnDisplay) {\n $paginationBtn.appendTo($paginationContainer);\n node = $('', {\n 'href': '#',\n 'class': btnClass,\n 'aria-controls': settings.sTableId,\n 'data-dt-idx': counter,\n 'tabindex': settings.iTabIndex,\n 'id': idx === 0 && typeof button === 'string' ? settings.sTableId + '_' + button : null\n }).html(btnDisplay).appendTo($paginationBtn);\n\n // IMPORTANT: Reference to internal functions of DT. It might change between versions\n $.fn.DataTable.ext.internal._fnBindAction(node, {\n action: button\n }, clickHandler);\n\n counter++;\n }\n }\n }\n };\n\n // IE9 throws an 'unknown error' if document.activeElement is used\n // inside an iframe or frame. Try / catch the error. Not good for\n // accessibility, but neither are frames.\n try {\n // Because this approach is destroying and recreating the paging\n // elements, focus is lost on the select button which is bad for\n // accessibility. So we want to restore focus once the draw has\n // completed\n var activeEl = $(document.activeElement).data('dt-idx');\n\n // Add