diff --git a/CHANGELOG.md b/CHANGELOG.md
index f81ce743..161d75e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
* Now uses WebP cache images when the browser supports it
* Replaces JS minifier with pre-minified scripts (Removes the need for one caching folder, too)
* Updated console command to sync Kitsu and Anilist data
+* Added page to update settings without having to edit config files
## Version 4
* Updated to use Kitsu API after discontinuation of Hummingbird
diff --git a/public/js/scripts-authed.min.js b/public/js/scripts-authed.min.js
index 828399d3..45a64f7a 100644
--- a/public/js/scripts-authed.min.js
+++ b/public/js/scripts-authed.min.js
@@ -1,630 +1,24 @@
-(function () {
- 'use strict';
-
- // -------------------------------------------------------------------------
- // ! Base
- // -------------------------------------------------------------------------
-
- const matches = (elm, selector) => {
- let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),
- i = matches.length;
- while (--i >= 0 && matches.item(i) !== elm) {} return i > -1;
- };
-
- const AnimeClient = {
- /**
- * Placeholder function
- */
- noop: () => {},
- /**
- * DOM selector
- *
- * @param {string} selector - The dom selector string
- * @param {object} [context]
- * @return {[HTMLElement]} - array of dom elements
- */
- $(selector, context = null) {
- if (typeof selector !== 'string') {
- return selector;
- }
-
- context = (context !== null && context.nodeType === 1)
- ? context
- : document;
-
- let elements = [];
- if (selector.match(/^#([\w]+$)/)) {
- elements.push(document.getElementById(selector.split('#')[1]));
- } else {
- elements = [].slice.apply(context.querySelectorAll(selector));
- }
-
- return elements;
- },
- /**
- * Does the selector exist on the current page?
- *
- * @param {string} selector
- * @returns {boolean}
- */
- hasElement (selector) {
- return AnimeClient.$(selector).length > 0;
- },
- /**
- * Scroll to the top of the Page
- *
- * @return {void}
- */
- scrollToTop () {
- window.scroll(0,0);
- },
- /**
- * Hide the selected element
- *
- * @param {string|Element} sel - the selector of the element to hide
- * @return {void}
- */
- hide (sel) {
- sel.setAttribute('hidden', 'hidden');
- },
- /**
- * UnHide the selected element
- *
- * @param {string|Element} sel - the selector of the element to hide
- * @return {void}
- */
- show (sel) {
- sel.removeAttribute('hidden');
- },
- /**
- * Display a message box
- *
- * @param {string} type - message type: info, error, success
- * @param {string} message - the message itself
- * @return {void}
- */
- showMessage (type, message) {
- let template =
- `
-
- ${message}
-
-
`;
-
- let sel = AnimeClient.$('.message');
- if (sel[0] !== undefined) {
- sel[0].remove();
- }
-
- AnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);
- },
- /**
- * Finds the closest parent element matching the passed selector
- *
- * @param {HTMLElement} current - the current HTMLElement
- * @param {string} parentSelector - selector for the parent element
- * @return {HTMLElement|null} - the parent element
- */
- closestParent (current, parentSelector) {
- if (Element.prototype.closest !== undefined) {
- return current.closest(parentSelector);
- }
-
- while (current !== document.documentElement) {
- if (matches(current, parentSelector)) {
- return current;
- }
-
- current = current.parentElement;
- }
-
- return null;
- },
- /**
- * Generate a full url from a relative path
- *
- * @param {string} path - url path
- * @return {string} - full url
- */
- url (path) {
- let uri = `//${document.location.host}`;
- uri += (path.charAt(0) === '/') ? path : `/${path}`;
-
- return uri;
- },
- /**
- * Throttle execution of a function
- *
- * @see https://remysharp.com/2010/07/21/throttling-function-calls
- * @see https://jsfiddle.net/jonathansampson/m7G64/
- * @param {Number} interval - the minimum throttle time in ms
- * @param {Function} fn - the function to throttle
- * @param {Object} [scope] - the 'this' object for the function
- * @return {Function}
- */
- throttle (interval, fn, scope) {
- let wait = false;
- return function (...args) {
- const context = scope || this;
-
- if ( ! wait) {
- fn.apply(context, args);
- wait = true;
- setTimeout(function() {
- wait = false;
- }, interval);
- }
- };
- },
- };
-
- // -------------------------------------------------------------------------
- // ! Events
- // -------------------------------------------------------------------------
-
- function addEvent(sel, event, listener) {
- // Recurse!
- if (! event.match(/^([\w\-]+)$/)) {
- event.split(' ').forEach((evt) => {
- addEvent(sel, evt, listener);
- });
- }
-
- sel.addEventListener(event, listener, false);
- }
-
- function delegateEvent(sel, target, event, listener) {
- // Attach the listener to the parent
- addEvent(sel, event, (e) => {
- // Get live version of the target selector
- AnimeClient.$(target, sel).forEach((element) => {
- if(e.target == element) {
- listener.call(element, e);
- e.stopPropagation();
- }
- });
- });
- }
-
- /**
- * Add an event listener
- *
- * @param {string|HTMLElement} sel - the parent selector to bind to
- * @param {string} event - event name(s) to bind
- * @param {string|HTMLElement|function} target - the element to directly bind the event to
- * @param {function} [listener] - event listener callback
- * @return {void}
- */
- AnimeClient.on = (sel, event, target, listener) => {
- if (listener === undefined) {
- listener = target;
- AnimeClient.$(sel).forEach((el) => {
- addEvent(el, event, listener);
- });
- } else {
- AnimeClient.$(sel).forEach((el) => {
- delegateEvent(el, target, event, listener);
- });
- }
- };
-
- // -------------------------------------------------------------------------
- // ! Ajax
- // -------------------------------------------------------------------------
-
- /**
- * Url encoding for non-get requests
- *
- * @param data
- * @returns {string}
- * @private
- */
- function ajaxSerialize(data) {
- let pairs = [];
-
- Object.keys(data).forEach((name) => {
- let value = data[name].toString();
-
- name = encodeURIComponent(name);
- value = encodeURIComponent(value);
-
- pairs.push(`${name}=${value}`);
- });
-
- return pairs.join('&');
- }
-
- /**
- * Make an ajax request
- *
- * Config:{
- * data: // data to send with the request
- * type: // http verb of the request, defaults to GET
- * success: // success callback
- * error: // error callback
- * }
- *
- * @param {string} url - the url to request
- * @param {Object} config - the configuration object
- * @return {void}
- */
- AnimeClient.ajax = (url, config) => {
- // Set some sane defaults
- const defaultConfig = {
- data: {},
- type: 'GET',
- dataType: '',
- success: AnimeClient.noop,
- mimeType: 'application/x-www-form-urlencoded',
- error: AnimeClient.noop
- };
-
- config = {
- ...defaultConfig,
- ...config,
- };
-
- let request = new XMLHttpRequest();
- let method = String(config.type).toUpperCase();
-
- if (method === 'GET') {
- url += (url.match(/\?/))
- ? ajaxSerialize(config.data)
- : `?${ajaxSerialize(config.data)}`;
- }
-
- request.open(method, url);
-
- request.onreadystatechange = () => {
- if (request.readyState === 4) {
- let responseText = '';
-
- if (request.responseType === 'json') {
- responseText = JSON.parse(request.responseText);
- } else {
- responseText = request.responseText;
- }
-
- if (request.status > 299) {
- config.error.call(null, request.status, responseText, request.response);
- } else {
- config.success.call(null, responseText, request.status);
- }
- }
- };
-
- if (config.dataType === 'json') {
- config.data = JSON.stringify(config.data);
- config.mimeType = 'application/json';
- } else {
- config.data = ajaxSerialize(config.data);
- }
-
- request.setRequestHeader('Content-Type', config.mimeType);
-
- switch (method) {
- case 'GET':
- request.send(null);
- break;
-
- default:
- request.send(config.data);
- break;
- }
- };
-
- /**
- * Do a get request
- *
- * @param {string} url
- * @param {object|function} data
- * @param {function} [callback]
- */
- AnimeClient.get = (url, data, callback = null) => {
- if (callback === null) {
- callback = data;
- data = {};
- }
-
- return AnimeClient.ajax(url, {
- data,
- success: callback
- });
- };
-
- /**
- * Event handlers
- */
- // Close event for messages
- AnimeClient.on('header', 'click', '.message', (e) => {
- AnimeClient.hide(e.target);
- });
-
- // Confirm deleting of list or library items
- AnimeClient.on('form.js-delete', 'submit', (event) => {
- const proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');
-
- if (proceed === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- });
-
- // Clear the api cache
- AnimeClient.on('.js-clear-cache', 'click', () => {
- AnimeClient.get('/cache_purge', () => {
- AnimeClient.showMessage('success', 'Successfully purged api cache');
- });
- });
-
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.register('/sw.js').then(reg => {
- console.log('Service worker registered', reg.scope);
- }).catch(error => {
- console.error('Failed to register service worker', error);
- });
- }
-
- // Click on hidden MAL checkbox so
- // that MAL id is passed
- AnimeClient.on('main', 'change', '.big-check', (e) => {
- const id = e.target.id;
- document.getElementById(`mal_${id}`).checked = true;
- });
-
- function renderAnimeSearchResults (data) {
- const results = [];
-
- data.forEach(x => {
- const item = x.attributes;
- const titles = item.titles.reduce((prev, current) => {
- return prev + `${current}
`;
- }, []);
-
- results.push(`
-
-
-
-
- `);
- });
-
- return results.join('');
- }
-
- function renderMangaSearchResults (data) {
- const results = [];
-
- data.forEach(x => {
- const item = x.attributes;
- const titles = item.titles.reduce((prev, current) => {
- return prev + `${current}
`;
- }, []);
-
- results.push(`
-
-
-
-
- `);
- });
-
- return results.join('');
- }
-
- const search = (query) => {
- // Show the loader
- AnimeClient.$('.cssload-loader')[ 0 ].removeAttribute('hidden');
-
- // Do the api search
- AnimeClient.get(AnimeClient.url('/anime-collection/search'), { query }, (searchResults, status) => {
- searchResults = JSON.parse(searchResults);
-
- // Hide the loader
- AnimeClient.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');
-
- // Show the results
- AnimeClient.$('#series_list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data);
- });
- };
-
- if (AnimeClient.hasElement('.anime #search')) {
- AnimeClient.on('#search', 'keyup', AnimeClient.throttle(250, (e) => {
- const query = encodeURIComponent(e.target.value);
- if (query === '') {
- return;
- }
-
- search(query);
- }));
- }
-
- // Action to increment episode count
- AnimeClient.on('body.anime.list', 'click', '.plus_one', (e) => {
- let parentSel = AnimeClient.closestParent(e.target, 'article');
- let watchedCount = parseInt(AnimeClient.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;
- let totalCount = parseInt(AnimeClient.$('.total_number', parentSel)[ 0 ].textContent, 10);
- let title = AnimeClient.$('.name a', parentSel)[ 0 ].textContent;
-
- // Setup the update data
- let data = {
- id: parentSel.dataset.kitsuId,
- mal_id: parentSel.dataset.malId,
- data: {
- progress: watchedCount + 1
- }
- };
-
- // If the episode count is 0, and incremented,
- // change status to currently watching
- if (isNaN(watchedCount) || watchedCount === 0) {
- data.data.status = 'current';
- }
-
- // If you increment at the last episode, mark as completed
- if ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {
- data.data.status = 'completed';
- }
-
- AnimeClient.show(AnimeClient.$('#loading-shadow')[ 0 ]);
-
- // okay, lets actually make some changes!
- AnimeClient.ajax(AnimeClient.url('/anime/increment'), {
- data,
- dataType: 'json',
- type: 'POST',
- success: (res) => {
- const resData = JSON.parse(res);
-
- if (resData.errors) {
- AnimeClient.hide(AnimeClient.$('#loading-shadow')[ 0 ]);
- AnimeClient.showMessage('error', `Failed to update ${title}. `);
- AnimeClient.scrollToTop();
- return;
- }
-
- if (resData.data.attributes.status === 'completed') {
- AnimeClient.hide(parentSel);
- }
-
- AnimeClient.hide(AnimeClient.$('#loading-shadow')[ 0 ]);
-
- AnimeClient.showMessage('success', `Successfully updated ${title}`);
- AnimeClient.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;
- AnimeClient.scrollToTop();
- },
- error: () => {
- AnimeClient.hide(AnimeClient.$('#loading-shadow')[ 0 ]);
- AnimeClient.showMessage('error', `Failed to update ${title}. `);
- AnimeClient.scrollToTop();
- }
- });
- });
-
- const search$1 = (query) => {
- AnimeClient.$('.cssload-loader')[ 0 ].removeAttribute('hidden');
- AnimeClient.get(AnimeClient.url('/manga/search'), { query }, (searchResults, status) => {
- searchResults = JSON.parse(searchResults);
- AnimeClient.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');
- AnimeClient.$('#series_list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data);
- });
- };
-
- if (AnimeClient.hasElement('.manga #search')) {
- AnimeClient.on('#search', 'keyup', AnimeClient.throttle(250, (e) => {
- let query = encodeURIComponent(e.target.value);
- if (query === '') {
- return;
- }
-
- search$1(query);
- }));
- }
-
- /**
- * Javascript for editing manga, if logged in
- */
- AnimeClient.on('.manga.list', 'click', '.edit_buttons button', (e) => {
- let thisSel = e.target;
- let parentSel = AnimeClient.closestParent(e.target, 'article');
- let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';
- let completed = parseInt(AnimeClient.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;
- let total = parseInt(AnimeClient.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);
- let mangaName = AnimeClient.$('.name', parentSel)[ 0 ].textContent;
-
- if (isNaN(completed)) {
- completed = 0;
- }
-
- // Setup the update data
- let data = {
- id: parentSel.dataset.kitsuId,
- mal_id: parentSel.dataset.malId,
- data: {
- progress: completed
- }
- };
-
- // If the episode count is 0, and incremented,
- // change status to currently reading
- if (isNaN(completed) || completed === 0) {
- data.data.status = 'current';
- }
-
- // If you increment at the last chapter, mark as completed
- if ((!isNaN(completed)) && (completed + 1) === total) {
- data.data.status = 'completed';
- }
-
- // Update the total count
- data.data.progress = ++completed;
-
- AnimeClient.show(AnimeClient.$('#loading-shadow')[ 0 ]);
-
- AnimeClient.ajax(AnimeClient.url('/manga/increment'), {
- data,
- dataType: 'json',
- type: 'POST',
- mimeType: 'application/json',
- success: () => {
- if (data.data.status === 'completed') {
- AnimeClient.hide(parentSel);
- }
-
- AnimeClient.hide(AnimeClient.$('#loading-shadow')[ 0 ]);
-
- AnimeClient.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed;
- AnimeClient.showMessage('success', `Successfully updated ${mangaName}`);
- AnimeClient.scrollToTop();
- },
- error: () => {
- AnimeClient.hide(AnimeClient.$('#loading-shadow')[ 0 ]);
- AnimeClient.showMessage('error', `Failed to update ${mangaName}`);
- AnimeClient.scrollToTop();
- }
- });
- });
-
-}());
+(function(){var matches=function(elm,selector){var matches=(elm.document||elm.ownerDocument).querySelectorAll(selector);var i=matches.length;while(--i>=0&&matches.item(i)!==elm);return i>-1};var AnimeClient={noop:function(){},$:function(selector,context){context=context===undefined?null:context;if(typeof selector!=="string")return selector;context=context!==null&&context.nodeType===1?context:document;var elements=[];if(selector.match(/^#([\w]+$)/))elements.push(document.getElementById(selector.split("#")[1]));
+else elements=[].slice.apply(context.querySelectorAll(selector));return elements},hasElement:function(selector){return AnimeClient.$(selector).length>0},scrollToTop:function(){window.scroll(0,0)},hide:function(sel){sel.setAttribute("hidden","hidden")},show:function(sel){sel.removeAttribute("hidden")},showMessage:function(type,message){var template="\x3cdiv class\x3d'message "+type+"'\x3e\n\t\t\t\t\x3cspan class\x3d'icon'\x3e\x3c/span\x3e\n\t\t\t\t"+message+"\n\t\t\t\t\x3cspan class\x3d'close'\x3e\x3c/span\x3e\n\t\t\t\x3c/div\x3e";
+var sel=AnimeClient.$(".message");if(sel[0]!==undefined)sel[0].remove();AnimeClient.$("header")[0].insertAdjacentHTML("beforeend",template)},closestParent:function(current,parentSelector){if(Element.prototype.closest!==undefined)return current.closest(parentSelector);while(current!==document.documentElement){if(matches(current,parentSelector))return current;current=current.parentElement}return null},url:function(path){var uri="//"+document.location.host;uri+=path.charAt(0)==="/"?path:"/"+path;return uri},
+throttle:function(interval,fn,scope){var wait=false;return function(args){var $jscomp$restParams=[];for(var $jscomp$restIndex=0;$jscomp$restIndex299)config.error.call(null,request.status,responseText,request.response);else config.success.call(null,responseText,
+request.status)}};if(config.dataType==="json"){config.data=JSON.stringify(config.data);config.mimeType="application/json"}else config.data=ajaxSerialize(config.data);request.setRequestHeader("Content-Type",config.mimeType);switch(method){case "GET":request.send(null);break;default:request.send(config.data);break}};AnimeClient.get=function(url,data,callback){callback=callback===undefined?null:callback;if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data:data,success:callback})};
+AnimeClient.on("header","click",".message",function(e){AnimeClient.hide(e.target)});AnimeClient.on("form.js-delete","submit",function(event){var proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}});AnimeClient.on(".js-clear-cache","click",function(){AnimeClient.get("/cache_purge",function(){AnimeClient.showMessage("success","Successfully purged api cache")})});if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered",
+reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)});AnimeClient.on("main","change",".big-check",function(e){var id=e.target.id;document.getElementById("mal_"+id).checked=true});function renderAnimeSearchResults(data){var results=[];data.forEach(function(x){var item=x.attributes;var titles=item.titles.reduce(function(prev,current){return prev+(current+"\x3cbr /\x3e")},[]);results.push('\n\t\t\t\x3carticle class\x3d"media search"\x3e\n\t\t\t\t\x3cdiv class\x3d"name"\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" class\x3d"mal-check" id\x3d"mal_'+
+item.slug+'" name\x3d"mal_id" value\x3d"'+x.mal_id+'" /\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" class\x3d"big-check" id\x3d"'+item.slug+'" name\x3d"id" value\x3d"'+x.id+'" /\x3e\n\t\t\t\t\t\x3clabel for\x3d"'+item.slug+'"\x3e\n\t\t\t\t\t\t\x3cpicture width\x3d"220"\x3e\n\t\t\t\t\t\t\t\x3csource srcset\x3d"/public/images/anime/'+x.id+'.webp" type\x3d"image/webp" /\x3e\n\t\t\t\t\t\t\t\x3csource srcset\x3d"/public/images/anime/'+x.id+'.jpg" type\x3d"image/jpeg" /\x3e\n\t\t\t\t\t\t\t\x3cimg src\x3d"/public/images/anime/'+
+x.id+'.jpg" alt\x3d"" width\x3d"220" /\x3e\n\t\t\t\t\t\t\x3c/picture\x3e\n\t\t\t\t\t\t\n\t\t\t\t\t\t\x3cspan class\x3d"name"\x3e\n\t\t\t\t\t\t\t'+item.canonicalTitle+"\x3cbr /\x3e\n\t\t\t\t\t\t\t\x3csmall\x3e"+titles+'\x3c/small\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/label\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\t\x3cdiv class\x3d"table"\x3e\n\t\t\t\t\t\x3cdiv class\x3d"row"\x3e\n\t\t\t\t\t\t\x3cspan class\x3d"edit"\x3e\n\t\t\t\t\t\t\t\x3ca class\x3d"bracketed" href\x3d"/anime/details/'+item.slug+
+'"\x3eInfo Page\x3c/a\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/div\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\x3c/article\x3e\n\t\t')});return results.join("")}function renderMangaSearchResults(data){var results=[];data.forEach(function(x){var item=x.attributes;var titles=item.titles.reduce(function(prev,current){return prev+(current+"\x3cbr /\x3e")},[]);results.push('\n\t\t\t\x3carticle class\x3d"media search"\x3e\n\t\t\t\t\x3cdiv class\x3d"name"\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" id\x3d"mal_'+
+item.slug+'" name\x3d"mal_id" value\x3d"'+x.mal_id+'" /\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" class\x3d"big-check" id\x3d"'+item.slug+'" name\x3d"id" value\x3d"'+x.id+'" /\x3e\n\t\t\t\t\t\x3clabel for\x3d"'+item.slug+'"\x3e\n\t\t\t\t\t\t\x3cpicture width\x3d"220"\x3e\n\t\t\t\t\t\t\t\x3csource srcset\x3d"/public/images/manga/'+x.id+'.webp" type\x3d"image/webp" /\x3e\n\t\t\t\t\t\t\t\x3csource srcset\x3d"/public/images/manga/'+x.id+'.jpg" type\x3d"image/jpeg" /\x3e\n\t\t\t\t\t\t\t\x3cimg src\x3d"/public/images/manga/'+
+x.id+'.jpg" alt\x3d"" width\x3d"220" /\x3e\n\t\t\t\t\t\t\x3c/picture\x3e\n\t\t\t\t\t\t\x3cspan class\x3d"name"\x3e\n\t\t\t\t\t\t\t'+item.canonicalTitle+"\x3cbr /\x3e\n\t\t\t\t\t\t\t\x3csmall\x3e"+titles+'\x3c/small\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/label\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\t\x3cdiv class\x3d"table"\x3e\n\t\t\t\t\t\x3cdiv class\x3d"row"\x3e\n\t\t\t\t\t\t\x3cspan class\x3d"edit"\x3e\n\t\t\t\t\t\t\t\x3ca class\x3d"bracketed" href\x3d"/manga/details/'+item.slug+'"\x3eInfo Page\x3c/a\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/div\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\x3c/article\x3e\n\t\t')});
+return results.join("")}var search=function(query){AnimeClient.$(".cssload-loader")[0].removeAttribute("hidden");AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.$(".cssload-loader")[0].setAttribute("hidden","hidden");AnimeClient.$("#series_list")[0].innerHTML=renderAnimeSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".anime #search"))AnimeClient.on("#search","keyup",AnimeClient.throttle(250,
+function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;search(query)}));AnimeClient.on("body.anime.list","click",".plus_one",function(e){var parentSel=AnimeClient.closestParent(e.target,"article");var watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;var totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);var title=AnimeClient.$(".name a",parentSel)[0].textContent;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,
+data:{progress:watchedCount+1}};if(isNaN(watchedCount)||watchedCount===0)data.data.status="current";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="completed";AnimeClient.show(AnimeClient.$("#loading-shadow")[0]);AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data:data,dataType:"json",type:"POST",success:function(res){var resData=JSON.parse(res);if(resData.errors){AnimeClient.hide(AnimeClient.$("#loading-shadow")[0]);AnimeClient.showMessage("error","Failed to update "+
+title+". ");AnimeClient.scrollToTop();return}if(resData.data.attributes.status==="completed")AnimeClient.hide(parentSel);AnimeClient.hide(AnimeClient.$("#loading-shadow")[0]);AnimeClient.showMessage("success","Successfully updated "+title);AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;AnimeClient.scrollToTop()},error:function(){AnimeClient.hide(AnimeClient.$("#loading-shadow")[0]);AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop()}})});
+var search$1=function(query){AnimeClient.$(".cssload-loader")[0].removeAttribute("hidden");AnimeClient.get(AnimeClient.url("/manga/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.$(".cssload-loader")[0].setAttribute("hidden","hidden");AnimeClient.$("#series_list")[0].innerHTML=renderMangaSearchResults(searchResults.data)})};if(AnimeClient.hasElement(".manga #search"))AnimeClient.on("#search","keyup",AnimeClient.throttle(250,function(e){var query=
+encodeURIComponent(e.target.value);if(query==="")return;search$1(query)}));AnimeClient.on(".manga.list","click",".edit_buttons button",function(e){var thisSel=e.target;var parentSel=AnimeClient.closestParent(e.target,"article");var type=thisSel.classList.contains("plus_one_chapter")?"chapter":"volume";var completed=parseInt(AnimeClient.$("."+type+"s_read",parentSel)[0].textContent,10)||0;var total=parseInt(AnimeClient.$("."+type+"_count",parentSel)[0].textContent,10);var mangaName=AnimeClient.$(".name",
+parentSel)[0].textContent;if(isNaN(completed))completed=0;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:completed}};if(isNaN(completed)||completed===0)data.data.status="current";if(!isNaN(completed)&&completed+1===total)data.data.status="completed";data.data.progress=++completed;AnimeClient.show(AnimeClient.$("#loading-shadow")[0]);AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data:data,dataType:"json",type:"POST",mimeType:"application/json",success:function(){if(data.data.status===
+"completed")AnimeClient.hide(parentSel);AnimeClient.hide(AnimeClient.$("#loading-shadow")[0]);AnimeClient.$("."+type+"s_read",parentSel)[0].textContent=completed;AnimeClient.showMessage("success","Successfully updated "+mangaName);AnimeClient.scrollToTop()},error:function(){AnimeClient.hide(AnimeClient.$("#loading-shadow")[0]);AnimeClient.showMessage("error","Failed to update "+mangaName);AnimeClient.scrollToTop()}})})})();
//# sourceMappingURL=scripts-authed.min.js.map
diff --git a/public/js/scripts-authed.min.js.map b/public/js/scripts-authed.min.js.map
index feaa56d9..6908ca80 100644
--- a/public/js/scripts-authed.min.js.map
+++ b/public/js/scripts-authed.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"scripts-authed.min.js.map","sources":["src/base/AnimeClient.js","src/base/events.js","src/index.js","src/template-helpers.js","src/anime.js","src/manga.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './AnimeClient.js';\n/**\n * Event handlers\n */\n// Close event for messages\n_.on('header', 'click', '.message', (e) => {\n\t_.hide(e.target);\n});\n\n// Confirm deleting of list or library items\n_.on('form.js-delete', 'submit', (event) => {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n});\n\n// Clear the api cache\n_.on('.js-clear-cache', 'click', () => {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n});\n","import './base/events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n","import _ from './base/AnimeClient.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n});\n\nexport function renderAnimeSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.reduce((prev, current) => {\n\t\t\treturn prev + `${current}
`;\n\t\t}, []);\n\n\t\tresults.push(`\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\n\t\t`);\n\t});\n\n\treturn results.join('');\n}\n\nexport function renderMangaSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.reduce((prev, current) => {\n\t\t\treturn prev + `${current}
`;\n\t\t}, []);\n\n\t\tresults.push(`\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\n\t\t`);\n\t});\n\n\treturn results.join('');\n}","import _ from './base/AnimeClient.js'\nimport { renderAnimeSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t// Show the loader\n\t_.$('.cssload-loader')[ 0 ].removeAttribute('hidden');\n\n\t// Do the api search\n\t_.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');\n\n\t\t// Show the results\n\t\t_.$('#series_list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.anime #search')) {\n\t_.on('#search', 'keyup', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tsearch(query);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus_one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t_.show(_.$('#loading-shadow')[ 0 ]);\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res);\n\n\t\t\tif (resData.errors) {\n\t\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t\t_.scrollToTop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (resData.data.attributes.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\n\t\t\t_.showMessage('success', `Successfully updated ${title}`);\n\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});","import _ from './base/AnimeClient.js'\nimport { renderMangaSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t_.$('.cssload-loader')[ 0 ].removeAttribute('hidden');\n\t_.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');\n\t\t_.$('#series_list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\t_.on('#search', 'keyup', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tsearch(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit_buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet mangaName = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show(_.$('#loading-shadow')[ 0 ]);\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: () => {\n\t\t\tif (data.data.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\n\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed;\n\t\t\t_.showMessage('success', `Successfully updated ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t_.showMessage('error', `Failed to update ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});"],"names":["_","search"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"scripts-authed.min.js.map","sources":["src/base/AnimeClient.js","src/base/events.js","src/index.js","src/template-helpers.js","src/anime.js","src/manga.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './AnimeClient.js';\n/**\n * Event handlers\n */\n// Close event for messages\n_.on('header', 'click', '.message', (e) => {\n\t_.hide(e.target);\n});\n\n// Confirm deleting of list or library items\n_.on('form.js-delete', 'submit', (event) => {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n});\n\n// Clear the api cache\n_.on('.js-clear-cache', 'click', () => {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n});\n","import './base/events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n","import _ from './base/AnimeClient.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n});\n\nexport function renderAnimeSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.reduce((prev, current) => {\n\t\t\treturn prev + `${current}
`;\n\t\t}, []);\n\n\t\tresults.push(`\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\n\t\t`);\n\t});\n\n\treturn results.join('');\n}\n\nexport function renderMangaSearchResults (data) {\n\tconst results = [];\n\n\tdata.forEach(x => {\n\t\tconst item = x.attributes;\n\t\tconst titles = item.titles.reduce((prev, current) => {\n\t\t\treturn prev + `${current}
`;\n\t\t}, []);\n\n\t\tresults.push(`\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\n\t\t`);\n\t});\n\n\treturn results.join('');\n}","import _ from './base/AnimeClient.js'\nimport { renderAnimeSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t// Show the loader\n\t_.$('.cssload-loader')[ 0 ].removeAttribute('hidden');\n\n\t// Do the api search\n\t_.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');\n\n\t\t// Show the results\n\t\t_.$('#series_list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.anime #search')) {\n\t_.on('#search', 'keyup', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tsearch(query);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus_one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t_.show(_.$('#loading-shadow')[ 0 ]);\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res);\n\n\t\t\tif (resData.errors) {\n\t\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t\t_.scrollToTop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (resData.data.attributes.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\n\t\t\t_.showMessage('success', `Successfully updated ${title}`);\n\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});","import _ from './base/AnimeClient.js'\nimport { renderMangaSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t_.$('.cssload-loader')[ 0 ].removeAttribute('hidden');\n\t_.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');\n\t\t_.$('#series_list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\t_.on('#search', 'keyup', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tsearch(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit_buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet mangaName = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'current';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'completed';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show(_.$('#loading-shadow')[ 0 ]);\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: () => {\n\t\t\tif (data.data.status === 'completed') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t}\n\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\n\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed;\n\t\t\t_.showMessage('success', `Successfully updated ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide(_.$('#loading-shadow')[ 0 ]);\n\t\t\t_.showMessage('error', `Failed to update ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});"],"names":["matches","elm","selector","querySelectorAll","document","ownerDocument","i","length","item","AnimeClient","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","scrollToTop","window","scroll","hide","sel","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","forEach","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","el","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","defaultConfig","dataType","success","mimeType","error","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","_","proceed","confirm","preventDefault","navigator","serviceWorker","register","then","reg","console","log","catch","id","checked","renderAnimeSearchResults","results","x","attributes","titles","reduce","prev","slug","mal_id","canonicalTitle","renderMangaSearchResults","search","query","searchResults","parentSel","watchedCount","parseInt","totalCount","title","dataset","kitsuId","malId","progress","isNaN","res","resData","errors","search$1","thisSel","classList","contains","completed","total","mangaName"],"mappings":"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"}
\ No newline at end of file
diff --git a/public/js/scripts.min.js b/public/js/scripts.min.js
index 2203e0cf..78aa6a49 100644
--- a/public/js/scripts.min.js
+++ b/public/js/scripts.min.js
@@ -1,369 +1,11 @@
-(function () {
- 'use strict';
-
- // -------------------------------------------------------------------------
- // ! Base
- // -------------------------------------------------------------------------
-
- const matches = (elm, selector) => {
- let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),
- i = matches.length;
- while (--i >= 0 && matches.item(i) !== elm) {} return i > -1;
- };
-
- const AnimeClient = {
- /**
- * Placeholder function
- */
- noop: () => {},
- /**
- * DOM selector
- *
- * @param {string} selector - The dom selector string
- * @param {object} [context]
- * @return {[HTMLElement]} - array of dom elements
- */
- $(selector, context = null) {
- if (typeof selector !== 'string') {
- return selector;
- }
-
- context = (context !== null && context.nodeType === 1)
- ? context
- : document;
-
- let elements = [];
- if (selector.match(/^#([\w]+$)/)) {
- elements.push(document.getElementById(selector.split('#')[1]));
- } else {
- elements = [].slice.apply(context.querySelectorAll(selector));
- }
-
- return elements;
- },
- /**
- * Does the selector exist on the current page?
- *
- * @param {string} selector
- * @returns {boolean}
- */
- hasElement (selector) {
- return AnimeClient.$(selector).length > 0;
- },
- /**
- * Scroll to the top of the Page
- *
- * @return {void}
- */
- scrollToTop () {
- window.scroll(0,0);
- },
- /**
- * Hide the selected element
- *
- * @param {string|Element} sel - the selector of the element to hide
- * @return {void}
- */
- hide (sel) {
- sel.setAttribute('hidden', 'hidden');
- },
- /**
- * UnHide the selected element
- *
- * @param {string|Element} sel - the selector of the element to hide
- * @return {void}
- */
- show (sel) {
- sel.removeAttribute('hidden');
- },
- /**
- * Display a message box
- *
- * @param {string} type - message type: info, error, success
- * @param {string} message - the message itself
- * @return {void}
- */
- showMessage (type, message) {
- let template =
- `
-
- ${message}
-
-
`;
-
- let sel = AnimeClient.$('.message');
- if (sel[0] !== undefined) {
- sel[0].remove();
- }
-
- AnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);
- },
- /**
- * Finds the closest parent element matching the passed selector
- *
- * @param {HTMLElement} current - the current HTMLElement
- * @param {string} parentSelector - selector for the parent element
- * @return {HTMLElement|null} - the parent element
- */
- closestParent (current, parentSelector) {
- if (Element.prototype.closest !== undefined) {
- return current.closest(parentSelector);
- }
-
- while (current !== document.documentElement) {
- if (matches(current, parentSelector)) {
- return current;
- }
-
- current = current.parentElement;
- }
-
- return null;
- },
- /**
- * Generate a full url from a relative path
- *
- * @param {string} path - url path
- * @return {string} - full url
- */
- url (path) {
- let uri = `//${document.location.host}`;
- uri += (path.charAt(0) === '/') ? path : `/${path}`;
-
- return uri;
- },
- /**
- * Throttle execution of a function
- *
- * @see https://remysharp.com/2010/07/21/throttling-function-calls
- * @see https://jsfiddle.net/jonathansampson/m7G64/
- * @param {Number} interval - the minimum throttle time in ms
- * @param {Function} fn - the function to throttle
- * @param {Object} [scope] - the 'this' object for the function
- * @return {Function}
- */
- throttle (interval, fn, scope) {
- let wait = false;
- return function (...args) {
- const context = scope || this;
-
- if ( ! wait) {
- fn.apply(context, args);
- wait = true;
- setTimeout(function() {
- wait = false;
- }, interval);
- }
- };
- },
- };
-
- // -------------------------------------------------------------------------
- // ! Events
- // -------------------------------------------------------------------------
-
- function addEvent(sel, event, listener) {
- // Recurse!
- if (! event.match(/^([\w\-]+)$/)) {
- event.split(' ').forEach((evt) => {
- addEvent(sel, evt, listener);
- });
- }
-
- sel.addEventListener(event, listener, false);
- }
-
- function delegateEvent(sel, target, event, listener) {
- // Attach the listener to the parent
- addEvent(sel, event, (e) => {
- // Get live version of the target selector
- AnimeClient.$(target, sel).forEach((element) => {
- if(e.target == element) {
- listener.call(element, e);
- e.stopPropagation();
- }
- });
- });
- }
-
- /**
- * Add an event listener
- *
- * @param {string|HTMLElement} sel - the parent selector to bind to
- * @param {string} event - event name(s) to bind
- * @param {string|HTMLElement|function} target - the element to directly bind the event to
- * @param {function} [listener] - event listener callback
- * @return {void}
- */
- AnimeClient.on = (sel, event, target, listener) => {
- if (listener === undefined) {
- listener = target;
- AnimeClient.$(sel).forEach((el) => {
- addEvent(el, event, listener);
- });
- } else {
- AnimeClient.$(sel).forEach((el) => {
- delegateEvent(el, target, event, listener);
- });
- }
- };
-
- // -------------------------------------------------------------------------
- // ! Ajax
- // -------------------------------------------------------------------------
-
- /**
- * Url encoding for non-get requests
- *
- * @param data
- * @returns {string}
- * @private
- */
- function ajaxSerialize(data) {
- let pairs = [];
-
- Object.keys(data).forEach((name) => {
- let value = data[name].toString();
-
- name = encodeURIComponent(name);
- value = encodeURIComponent(value);
-
- pairs.push(`${name}=${value}`);
- });
-
- return pairs.join('&');
- }
-
- /**
- * Make an ajax request
- *
- * Config:{
- * data: // data to send with the request
- * type: // http verb of the request, defaults to GET
- * success: // success callback
- * error: // error callback
- * }
- *
- * @param {string} url - the url to request
- * @param {Object} config - the configuration object
- * @return {void}
- */
- AnimeClient.ajax = (url, config) => {
- // Set some sane defaults
- const defaultConfig = {
- data: {},
- type: 'GET',
- dataType: '',
- success: AnimeClient.noop,
- mimeType: 'application/x-www-form-urlencoded',
- error: AnimeClient.noop
- };
-
- config = {
- ...defaultConfig,
- ...config,
- };
-
- let request = new XMLHttpRequest();
- let method = String(config.type).toUpperCase();
-
- if (method === 'GET') {
- url += (url.match(/\?/))
- ? ajaxSerialize(config.data)
- : `?${ajaxSerialize(config.data)}`;
- }
-
- request.open(method, url);
-
- request.onreadystatechange = () => {
- if (request.readyState === 4) {
- let responseText = '';
-
- if (request.responseType === 'json') {
- responseText = JSON.parse(request.responseText);
- } else {
- responseText = request.responseText;
- }
-
- if (request.status > 299) {
- config.error.call(null, request.status, responseText, request.response);
- } else {
- config.success.call(null, responseText, request.status);
- }
- }
- };
-
- if (config.dataType === 'json') {
- config.data = JSON.stringify(config.data);
- config.mimeType = 'application/json';
- } else {
- config.data = ajaxSerialize(config.data);
- }
-
- request.setRequestHeader('Content-Type', config.mimeType);
-
- switch (method) {
- case 'GET':
- request.send(null);
- break;
-
- default:
- request.send(config.data);
- break;
- }
- };
-
- /**
- * Do a get request
- *
- * @param {string} url
- * @param {object|function} data
- * @param {function} [callback]
- */
- AnimeClient.get = (url, data, callback = null) => {
- if (callback === null) {
- callback = data;
- data = {};
- }
-
- return AnimeClient.ajax(url, {
- data,
- success: callback
- });
- };
-
- /**
- * Event handlers
- */
- // Close event for messages
- AnimeClient.on('header', 'click', '.message', (e) => {
- AnimeClient.hide(e.target);
- });
-
- // Confirm deleting of list or library items
- AnimeClient.on('form.js-delete', 'submit', (event) => {
- const proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');
-
- if (proceed === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- });
-
- // Clear the api cache
- AnimeClient.on('.js-clear-cache', 'click', () => {
- AnimeClient.get('/cache_purge', () => {
- AnimeClient.showMessage('success', 'Successfully purged api cache');
- });
- });
-
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.register('/sw.js').then(reg => {
- console.log('Service worker registered', reg.scope);
- }).catch(error => {
- console.error('Failed to register service worker', error);
- });
- }
-
-}());
+(function(){var matches=function(elm,selector){var matches=(elm.document||elm.ownerDocument).querySelectorAll(selector);var i=matches.length;while(--i>=0&&matches.item(i)!==elm);return i>-1};var AnimeClient={noop:function(){},$:function(selector,context){context=context===undefined?null:context;if(typeof selector!=="string")return selector;context=context!==null&&context.nodeType===1?context:document;var elements=[];if(selector.match(/^#([\w]+$)/))elements.push(document.getElementById(selector.split("#")[1]));
+else elements=[].slice.apply(context.querySelectorAll(selector));return elements},hasElement:function(selector){return AnimeClient.$(selector).length>0},scrollToTop:function(){window.scroll(0,0)},hide:function(sel){sel.setAttribute("hidden","hidden")},show:function(sel){sel.removeAttribute("hidden")},showMessage:function(type,message){var template="\x3cdiv class\x3d'message "+type+"'\x3e\n\t\t\t\t\x3cspan class\x3d'icon'\x3e\x3c/span\x3e\n\t\t\t\t"+message+"\n\t\t\t\t\x3cspan class\x3d'close'\x3e\x3c/span\x3e\n\t\t\t\x3c/div\x3e";
+var sel=AnimeClient.$(".message");if(sel[0]!==undefined)sel[0].remove();AnimeClient.$("header")[0].insertAdjacentHTML("beforeend",template)},closestParent:function(current,parentSelector){if(Element.prototype.closest!==undefined)return current.closest(parentSelector);while(current!==document.documentElement){if(matches(current,parentSelector))return current;current=current.parentElement}return null},url:function(path){var uri="//"+document.location.host;uri+=path.charAt(0)==="/"?path:"/"+path;return uri},
+throttle:function(interval,fn,scope){var wait=false;return function(args){var $jscomp$restParams=[];for(var $jscomp$restIndex=0;$jscomp$restIndex299)config.error.call(null,request.status,responseText,request.response);else config.success.call(null,responseText,
+request.status)}};if(config.dataType==="json"){config.data=JSON.stringify(config.data);config.mimeType="application/json"}else config.data=ajaxSerialize(config.data);request.setRequestHeader("Content-Type",config.mimeType);switch(method){case "GET":request.send(null);break;default:request.send(config.data);break}};AnimeClient.get=function(url,data,callback){callback=callback===undefined?null:callback;if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data:data,success:callback})};
+AnimeClient.on("header","click",".message",function(e){AnimeClient.hide(e.target)});AnimeClient.on("form.js-delete","submit",function(event){var proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}});AnimeClient.on(".js-clear-cache","click",function(){AnimeClient.get("/cache_purge",function(){AnimeClient.showMessage("success","Successfully purged api cache")})});if("serviceWorker"in navigator)navigator.serviceWorker.register("/sw.js").then(function(reg){console.log("Service worker registered",
+reg.scope)})["catch"](function(error){console.error("Failed to register service worker",error)})})();
//# sourceMappingURL=scripts.min.js.map
diff --git a/public/js/scripts.min.js.map b/public/js/scripts.min.js.map
index 5a96391e..ce7f14fc 100644
--- a/public/js/scripts.min.js.map
+++ b/public/js/scripts.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"scripts.min.js.map","sources":["src/base/AnimeClient.js","src/base/events.js","src/index.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './AnimeClient.js';\n/**\n * Event handlers\n */\n// Close event for messages\n_.on('header', 'click', '.message', (e) => {\n\t_.hide(e.target);\n});\n\n// Confirm deleting of list or library items\n_.on('form.js-delete', 'submit', (event) => {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n});\n\n// Clear the api cache\n_.on('.js-clear-cache', 'click', () => {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n});\n","import './base/events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n"],"names":["_"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"scripts.min.js.map","sources":["src/base/AnimeClient.js","src/base/events.js","src/index.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './AnimeClient.js';\n/**\n * Event handlers\n */\n// Close event for messages\n_.on('header', 'click', '.message', (e) => {\n\t_.hide(e.target);\n});\n\n// Confirm deleting of list or library items\n_.on('form.js-delete', 'submit', (event) => {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n});\n\n// Clear the api cache\n_.on('.js-clear-cache', 'click', () => {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n});\n","import './base/events.js';\n\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}\n\n"],"names":["matches","elm","selector","querySelectorAll","document","ownerDocument","i","length","item","AnimeClient","noop","$","context","nodeType","elements","match","push","getElementById","split","slice","apply","hasElement","scrollToTop","window","scroll","hide","sel","setAttribute","show","removeAttribute","showMessage","type","message","template","undefined","remove","insertAdjacentHTML","closestParent","current","parentSelector","Element","prototype","closest","documentElement","parentElement","url","path","uri","location","host","charAt","throttle","interval","fn","scope","wait","args","setTimeout","addEvent","event","listener","forEach","evt","addEventListener","delegateEvent","target","e","element","call","stopPropagation","on","AnimeClient.on","el","ajaxSerialize","data","pairs","Object","keys","name","value","toString","encodeURIComponent","join","ajax","AnimeClient.ajax","config","defaultConfig","dataType","success","mimeType","error","request","XMLHttpRequest","method","String","toUpperCase","open","onreadystatechange","request.onreadystatechange","readyState","responseText","responseType","JSON","parse","status","response","stringify","setRequestHeader","send","get","AnimeClient.get","callback","_","proceed","confirm","preventDefault","navigator","serviceWorker","register","then","reg","console","log","catch"],"mappings":"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"}
\ No newline at end of file
diff --git a/public/js/tables.min.js b/public/js/tables.min.js
index 1cd9e19a..55a661ce 100644
--- a/public/js/tables.min.js
+++ b/public/js/tables.min.js
@@ -1,75 +1,4 @@
-(function () {
- 'use strict';
-
- const LightTableSorter = (() => {
- let th = null;
- let cellIndex = null;
- let order = '';
- const text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();
- const sort = (a, b) => {
- let textA = text(a);
- let textB = text(b);
- const n = parseInt(textA, 10);
- if (n) {
- textA = n;
- textB = parseInt(textB, 10);
- }
- if (textA > textB) {
- return 1;
- }
- if (textA < textB) {
- return -1;
- }
- return 0;
- };
- const toggle = () => {
- const c = order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';
- th.className = (th.className.replace(order, '') + ' ' + c).trim();
- return order = c;
- };
- const reset = () => {
- th.classList.remove('sorting_asc', 'sorting_desc');
- th.classList.add('sorting');
- return order = '';
- };
- const onClickEvent = (e) => {
- if (th && (cellIndex !== e.target.cellIndex)) {
- reset();
- }
- th = e.target;
- if (th.nodeName.toLowerCase() === 'th') {
- cellIndex = th.cellIndex;
- const tbody = th.offsetParent.getElementsByTagName('tbody')[0];
- let rows = Array.from(tbody.rows);
- if (rows) {
- rows.sort(sort);
- if (order === 'sorting_asc') {
- rows.reverse();
- }
- toggle();
- tbody.innerHtml = '';
-
- rows.forEach(row => {
- tbody.appendChild(row);
- });
- }
- }
- };
- return {
- init: () => {
- let ths = document.getElementsByTagName('th');
- let results = [];
- for (let i = 0, len = ths.length; i < len; i++) {
- let th = ths[i];
- th.classList.add('sorting');
- results.push(th.onclick = onClickEvent);
- }
- return results;
- }
- };
- })();
-
- LightTableSorter.init();
-
-}());
+(function(){var LightTableSorter=function(){var th=null;var cellIndex=null;var order="";var text=function(row){return row.cells.item(cellIndex).textContent.toLowerCase()};var sort=function(a,b){var textA=text(a);var textB=text(b);var n=parseInt(textA,10);if(n){textA=n;textB=parseInt(textB,10)}if(textA>textB)return 1;if(textA {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconst n = parseInt(textA, 10);\n\t\tif (n) {\n\t\t\ttextA = n;\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting_asc', 'sorting_desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting_asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"tables.min.js.map","sources":["src/base/sort_tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconst n = parseInt(textA, 10);\n\t\tif (n) {\n\t\t\ttextA = n;\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting_asc', 'sorting_desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting_asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":["LightTableSorter","th","cellIndex","order","text","row","cells","item","textContent","toLowerCase","sort","a","b","textA","textB","n","parseInt","toggle","c","className","trim","replace","reset","classList","remove","add","onClickEvent","e","target","nodeName","tbody","offsetParent","getElementsByTagName","rows","Array","from","reverse","innerHtml","forEach","appendChild","init","ths","document","results","i","len","length","push","onclick"],"mappings":"YAAA,IAAMA,iBAAoB,QAAA,EAAM,CAC/B,IAAIC,GAAK,IACT,KAAIC,UAAY,IAChB,KAAIC,MAAQ,EACZ,KAAMC,KAAOA,QAAA,CAACC,GAAD,CAAS,CAAA,MAAAA,IAAAC,MAAAC,KAAA,CAAeL,SAAf,CAAAM,YAAAC,YAAA,EAAA,CACtB,KAAMC,KAAOA,QAAA,CAACC,CAAD,CAAIC,CAAJ,CAAU,CACtB,IAAIC,MAAQT,IAAA,CAAKO,CAAL,CACZ,KAAIG,MAAQV,IAAA,CAAKQ,CAAL,CACZ,KAAMG,EAAIC,QAAA,CAASH,KAAT,CAAgB,EAAhB,CACV,IAAIE,CAAJ,CAAO,CACNF,KAAA,CAAQE,CACRD,MAAA,CAAQE,QAAA,CAASF,KAAT,CAAgB,EAAhB,CAFF,CAIP,GAAID,KAAJ,CAAYC,KAAZ,CACC,MAAO,EAER,IAAID,KAAJ,CAAYC,KAAZ,CACC,MAAQ,EAET,OAAO,EAde,CAgBvB,KAAMG,OAASA,QAAA,EAAM,CACpB,IAAMC,EAAIf,KAAA,GAAU,aAAV,CAA0B,aAA1B,CAA0C,cACpDF,GAAAkB,UAAA,CAAeC,CAACnB,EAAAkB,UAAAE,QAAA,CAAqBlB,KAArB,CAA4B,EAA5B,CAADiB,CAAmC,GAAnCA,CAAyCF,CAAzCE,MAAA,EACf,OAAOjB,MAAP;AAAee,CAHK,CAKrB,KAAMI,MAAQA,QAAA,EAAM,CACnBrB,EAAAsB,UAAAC,OAAA,CAAoB,aAApB,CAAmC,cAAnC,CACAvB,GAAAsB,UAAAE,IAAA,CAAiB,SAAjB,CACA,OAAOtB,MAAP,CAAe,EAHI,CAKpB,KAAMuB,aAAeA,QAAA,CAACC,CAAD,CAAO,CAC3B,GAAI1B,EAAJ,EAAWC,SAAX,GAAyByB,CAAAC,OAAA1B,UAAzB,CACCoB,KAAA,EAEDrB,GAAA,CAAK0B,CAAAC,OACL,IAAI3B,EAAA4B,SAAApB,YAAA,EAAJ,GAAkC,IAAlC,CAAwC,CACvCP,SAAA,CAAYD,EAAAC,UACZ,KAAM4B,MAAQ7B,EAAA8B,aAAAC,qBAAA,CAAqC,OAArC,CAAA,CAA8C,CAA9C,CACd,KAAIC,KAAOC,KAAAC,KAAA,CAAWL,KAAAG,KAAX,CACX,IAAIA,IAAJ,CAAU,CACTA,IAAAvB,KAAA,CAAUA,IAAV,CACA,IAAIP,KAAJ,GAAc,aAAd,CACC8B,IAAAG,QAAA,EAEDnB,OAAA,EACAa,MAAAO,UAAA,CAAkB,EAElBJ,KAAAK,QAAA,CAAa,QAAA,CAAAjC,GAAA,CAAO,CACnByB,KAAAS,YAAA,CAAkBlC,GAAlB,CADmB,CAApB,CARS,CAJ6B,CALb,CAuB5B;MAAO,CACNmC,KAAMA,QAAA,EAAM,CACX,IAAIC,IAAMC,QAAAV,qBAAA,CAA8B,IAA9B,CACV,KAAIW,QAAU,EACd,KAAK,IAAIC,EAAI,CAAR,CAAWC,IAAMJ,GAAAK,OAAtB,CAAkCF,CAAlC,CAAsCC,GAAtC,CAA2CD,CAAA,EAA3C,CAAgD,CAC/C,IAAI3C,KAAKwC,GAAA,CAAIG,CAAJ,CACT3C,KAAAsB,UAAAE,IAAA,CAAiB,SAAjB,CACAkB,QAAAI,KAAA,CAAa9C,IAAA+C,QAAb,CAA0BtB,YAA1B,CAH+C,CAKhD,MAAOiB,QARI,CADN,CAtDwB,CAAP,EAoEzB3C,iBAAAwC,KAAA;"}
\ No newline at end of file
diff --git a/public/package.json b/public/package.json
index 53363503..a092b621 100644
--- a/public/package.json
+++ b/public/package.json
@@ -8,7 +8,6 @@
"watch": "concurrently \"npm:watch:css\" \"npm:watch:js\" --kill-others"
},
"devDependencies": {
- "@ampproject/rollup-plugin-closure-compiler": "^0.7.2",
"concurrently": "^3.6.1",
"cssnano": "^4.0.5",
"postcss-cachify": "^1.3.1",
@@ -16,5 +15,8 @@
"postcss-import": "^12.0.0",
"rollup": "^0.64.1",
"watch": "^1.0.2"
+ },
+ "dependencies": {
+ "rollup-plugin-closure-compiler-js": "^1.0.6"
}
}
diff --git a/public/tools/build-js.js b/public/tools/build-js.js
index 124a30e7..03499b4c 100644
--- a/public/tools/build-js.js
+++ b/public/tools/build-js.js
@@ -1,13 +1,13 @@
-import closure from '@ampproject/rollup-plugin-closure-compiler';
+import closure from 'rollup-plugin-closure-compiler-js';
const plugins = [
closure({
assumeFunctionWrapper: true,
- compilationLevel: 'SIMPLE', //'WHITESPACE_ONLY', //'ADVANCED',
+ compilationLevel: 'WHITESPACE_ONLY', //'ADVANCED',
createSourceMap: true,
env: 'BROWSER',
languageIn: 'ECMASCRIPT_2018',
- languageOut: 'ES5'
+ languageOut: 'ES3'
})
];
diff --git a/public/yarn.lock b/public/yarn.lock
index 2cf3511a..34c3b5e9 100644
--- a/public/yarn.lock
+++ b/public/yarn.lock
@@ -2,15 +2,6 @@
# yarn lockfile v1
-"@ampproject/rollup-plugin-closure-compiler@^0.7.2":
- version "0.7.2"
- resolved "https://registry.yarnpkg.com/@ampproject/rollup-plugin-closure-compiler/-/rollup-plugin-closure-compiler-0.7.2.tgz#897bd27d4536a9d57b65ca1b111df6b18c696fe4"
- dependencies:
- acorn "5.7.3"
- google-closure-compiler "20180910.0.0"
- magic-string "0.25.1"
- temp-write "3.4.0"
-
"@types/estree@0.0.39":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
@@ -19,14 +10,14 @@
version "10.10.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.10.1.tgz#d5c96ca246a418404914d180b7fdd625ad18eca6"
-acorn@5.7.3:
- version "5.7.3"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
-
alphanum-sort@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
+amdefine@>=0.0.4:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@@ -129,7 +120,7 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, can
version "1.0.30000885"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000885.tgz#e889e9f8e7e50e769f2a49634c932b8aee622984"
-chalk@^1.0.0, chalk@^1.1.3:
+chalk@^1.1.3:
version "1.1.3"
resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@@ -518,25 +509,13 @@ function-bind@^1.1.0, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
-google-closure-compiler-linux@^20180910.0.1:
- version "20180910.0.1"
- resolved "https://registry.yarnpkg.com/google-closure-compiler-linux/-/google-closure-compiler-linux-20180910.0.1.tgz#22567f7f5b605946d23c99c86a3e29a2210386da"
-
-google-closure-compiler-osx@^20180910.0.1:
- version "20180910.0.1"
- resolved "https://registry.yarnpkg.com/google-closure-compiler-osx/-/google-closure-compiler-osx-20180910.0.1.tgz#83e88bf892038655efd281fad61e3f6377a60afb"
-
-google-closure-compiler@20180910.0.0:
- version "20180910.0.0"
- resolved "https://registry.yarnpkg.com/google-closure-compiler/-/google-closure-compiler-20180910.0.0.tgz#74f7fdb16931cce2ba6af17a447d264f46e10c47"
+google-closure-compiler-js@>20170000:
+ version "20180610.0.0"
+ resolved "https://registry.yarnpkg.com/google-closure-compiler-js/-/google-closure-compiler-js-20180610.0.0.tgz#df0dbf39ba3977027db2c1beb244368521c9220b"
dependencies:
- chalk "^1.0.0"
minimist "^1.2.0"
vinyl "^2.0.1"
- vinyl-sourcemaps-apply "^0.2.0"
- optionalDependencies:
- google-closure-compiler-linux "^20180910.0.1"
- google-closure-compiler-osx "^20180910.0.1"
+ webpack-core "^0.6.8"
graceful-fs@^4.1.2:
version "4.1.11"
@@ -645,10 +624,6 @@ is-resolvable@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
-is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-
is-svg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
@@ -720,18 +695,6 @@ lodash@^4.5.1:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
-magic-string@0.25.1:
- version "0.25.1"
- resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e"
- dependencies:
- sourcemap-codec "^1.4.1"
-
-make-dir@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
- dependencies:
- pify "^3.0.0"
-
math-expression-evaluator@^1.2.14:
version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
@@ -1470,6 +1433,12 @@ rgba-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
+rollup-plugin-closure-compiler-js@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/rollup-plugin-closure-compiler-js/-/rollup-plugin-closure-compiler-js-1.0.6.tgz#58e3e31297ad1a532d9114108bc06f2756d72c3d"
+ dependencies:
+ google-closure-compiler-js ">20170000"
+
rollup@^0.64.1:
version "0.64.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.64.1.tgz#9188ee368e5fcd43ffbc00ec414e72eeb5de87ba"
@@ -1499,7 +1468,11 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"
-source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6:
+source-list-map@~0.1.7:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
+
+source-map@^0.5.3, source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@@ -1507,9 +1480,11 @@ source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
-sourcemap-codec@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz#c8fd92d91889e902a07aee392bdd2c5863958ba2"
+source-map@~0.4.1:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
+ dependencies:
+ amdefine ">=0.0.4"
spawn-command@^0.0.2-1:
version "0.0.2-1"
@@ -1604,21 +1579,6 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
-temp-dir@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"
-
-temp-write@3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492"
- dependencies:
- graceful-fs "^4.1.2"
- is-stream "^1.1.0"
- make-dir "^1.0.0"
- pify "^3.0.0"
- temp-dir "^1.0.0"
- uuid "^3.0.1"
-
timsort@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
@@ -1661,10 +1621,6 @@ util.promisify@~1.0.0:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"
-uuid@^3.0.1:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
-
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -1680,12 +1636,6 @@ viewport-dimensions@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz#de740747db5387fd1725f5175e91bac76afdf36c"
-vinyl-sourcemaps-apply@^0.2.0:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705"
- dependencies:
- source-map "^0.5.1"
-
vinyl@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86"
@@ -1703,3 +1653,10 @@ watch@^1.0.2:
dependencies:
exec-sh "^0.2.0"
minimist "^1.2.0"
+
+webpack-core@^0.6.8:
+ version "0.6.9"
+ resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2"
+ dependencies:
+ source-list-map "~0.1.7"
+ source-map "~0.4.1"