Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Osmium
- * Copyright (C) 2012 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gettheme = function() {
- var links = document.getElementsByTagName("link");
- for(var i = 0; i < links.length; ++i) {
- if(links[i].getAttribute('title') && links[i].getAttribute('rel').indexOf('stylesheet') !== -1) {
- if(!links[i].disabled) return links[i].getAttribute('title');
- }
- }
- };
- osmium_settheme = function(title) {
- var links = document.getElementsByTagName("link");
- var foundit = false;
- for(var i = 0; i < links.length; ++i) {
- if(links[i].getAttribute('title') && links[i].getAttribute('rel').indexOf('stylesheet') !== -1) {
- links[i].disabled = true;
- if(links[i].getAttribute('title') === title) {
- foundit = true;
- links[i].disabled = false;
- }
- }
- }
- if(foundit) {
- return;
- }
- alert('not found');
- /* If the title was not found, enable the first sheet as a fallback */
- for(var i = 0; i < links.length; ++i) {
- if(links[i].getAttribute('title') && links[i].getAttribute('rel').indexOf('stylesheet') !== -1) {
- links[i].disabled = false;
- return;
- }
- }
- };
- osmium_setcookie = function(name, value, validityms) {
- var d = new Date();
- d.setTime(d.getTime() + validityms);
- document.cookie = name + "=" + value + "; expires=" + d.toGMTString() + "; path=/";
- };
- $(function() {
- var theme, label;
- if(osmium_gettheme() === 'Light') {
- theme = 'Dark';
- label = 'Paint it black';
- } else {
- theme = 'Light';
- label = 'Paint it white';
- }
- var rlink = $(document.createElement('a'));
- rlink.prop('id', 'repaint');
- rlink.data('theme', theme);
- rlink.text(label);
- rlink.click(function() {
- var theme, label, tts;
- if((tts = $(this).data('theme')) === 'Dark') {
- theme = 'Light';
- label = 'Paint it white';
- } else {
- theme = 'Dark';
- label = 'Paint it black';
- }
- osmium_setcookie('t', tts, 86400 * 7 * 1000);
- osmium_settheme(tts);
- $(this).data('theme', theme);
- $(this).text(label);
- $(this).blur();
- });
- $("div#wrapper + footer > p").append(' — ').append(rlink);
- });
- /* Osmium
- * Copyright (C) 2012, 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_notifications = function(relative) {
- var fetch = function() {
- $.get(relative + '/internal/nc', function(cnt) {
- var a = $("a#ncount");
- var rawtitle = document.title.replace(/^\([1-9][0-9]*\) /, "");
- a.text(cnt);
- a.data('count', cnt);
- a.prop('title', cnt + ' new notification(s)');
- if(parseInt(cnt, 10) > 0) {
- a.show().css('display', 'inline-block');
- document.title = "(" + cnt + ") " + rawtitle;
- } else {
- a.hide();
- document.title = rawtitle;
- }
- });
- setTimeout(fetch, 63000);
- };
- setTimeout(fetch, 60000);
- };
- $(function() {
- var prefix = window.location.href.split("/");
- prefix[prefix.length - 1] = '';
- osmium_notifications(
- prefix.join('/') + $("div#osmium-data").data('relative')
- );
- });
- /* Osmium
- * Copyright (C) 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- $(function() {
- var fbdiv = $(document.createElement('div')).prop('id', 'glob_feedback');
- var ul = $(document.createElement('ul'));
- fbdiv.append($(document.createElement('span')).text('Feedback'));
- fbdiv.append(ul);
- ul.append(
- $(document.createElement('li')).append(
- $(document.createElement('a'))
- .prop('href', 'https://github.com/osmium-org/osmium/issues/new')
- .text('Report an issue')
- )
- );
- ul.append(
- $(document.createElement('li')).append(
- $(document.createElement('a'))
- .prop('href', 'http://irc.lc/coldfront/osmium/osmiumguest@@@')
- .text('Live chat')
- )
- );
- ul.append(
- $(document.createElement('li')).append(
- $('footer a[rel="help"]').clone().text('Help & FAQ')
- )
- );
- $('div#wrapper').append(fbdiv);
- fbdiv.children('span').first().on('click', function() {
- var fb = $(this).parent();
- var nfb = fb.clone(true); /* Hack to restart the CSS animation */
- if(nfb.hasClass('extended')) {
- nfb.removeClass('extended');
- nfb.addClass('notextended');
- } else {
- nfb.removeClass('notextended');
- nfb.addClass('extended');
- }
- fb.before(nfb);
- fb.remove();
- });
- });
- /* This snippet will be included in every page (generated with DOM\Page). */
- /* Whenever you change this script, update the information in about.php. */
- /*<<< require external //cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js before >>>*/
- /*<<< require snippet persistent_theme >>>*/
- /*<<< require snippet notifications >>>*/
- /*<<< require snippet feedback >>>*/
- /* Osmium
- * Copyright (C) 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_put_setting = function(name, value) {
- $.ajax({
- type: 'POST',
- url: osmium_relative + '/internal/ps/' + name,
- data: {
- payload: JSON.stringify(value),
- 'o___csrf': osmium_token
- }
- });
- };
- /*<<< require external /static-1/mousetrap.min.js >>>*/
- if(typeof(localStorage) === 'undefined') {
- localStorage = {
- getItem: function() { return null; },
- setItem: function() {},
- removeItem: function() {},
- };
- }
- if(typeof(sessionStorage) === 'undefined') {
- sessionStorage = {
- getItem: function() { return null; },
- setItem: function() {},
- removeItem: function() {},
- };
- }
- /* Osmium
- * Copyright (C) 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*<<< require snippet localstorage_fallback >>>*/
- osmium_keyboard_commands = {};
- /* Register a keyboard command.
- *
- * @param shortnames a Mousetrap compatible shortcut definition, or an
- * array of definitions, or null.
- *
- * @param longname a long descriptive name of the command ([a-z-]
- * only).
- *
- * @param description a description of what the command does.
- *
- * @param action called when the command is used.
- */
- osmium_register_keyboard_command = function(shortnames, longname, description, action) {
- if(longname in osmium_keyboard_commands) {
- osmium_unregister_keyboard_command(longname);
- }
- if($.isEmptyObject(osmium_keyboard_commands)) {
- /* Bind M-x */
- Mousetrap.bind([ 'meta+x', 'alt+x', 'command+x' ], function() {
- if($('div#mx-cont').length !== 0) {
- $('div#mx-cont > form > input[type="text"]').focus();
- return false;
- }
- var history = sessionStorage.getItem('mx-history');
- history = (typeof(history) === 'string') ? JSON.parse(history) : [];
- var histposition = history.length;
- var histlast = '';
- var c = $(document.createElement('div')).prop('id', 'mx-cont');
- var tabcount = 0;
- var bg = $(document.createElement('div')).prop('id', 'mx-bg');
- c.append(bg);
- var form = $(document.createElement('form'));
- form.prop('method', 'get');
- form.prop('action', '?');
- c.append(form);
- var inp = $(document.createElement('input'));
- inp.prop('type', 'text');
- inp.prop('placeholder', 'Enter command… (Press C-g or ESC twice to exit)');
- inp.addClass('mousetrap'); /* Fire events even if this input has focus */
- var lastval = inp.val();
- form.append(inp);
- var setinpval = function(val) {
- inp.val(val);
- inp.get(0).setSelectionRange(val.length, val.length);
- };
- var submit = $(document.createElement('input'));
- submit.prop('type', 'submit');
- form.append(submit); /* Form won't submit on RET without a submit button */
- var ul = $(document.createElement('ul'));
- c.append(ul);
- for(var lc in osmium_keyboard_commands) {
- var cmd = osmium_keyboard_commands[lc];
- ul.append(
- $(document.createElement('li'))
- .text(lc)
- .prop(
- 'title',
- lc + "\n"
- + (
- cmd.shortnames !== null ?
- (((typeof(cmd.shortnames) === 'string') ?
- cmd.shortnames
- : cmd.shortnames.join(', ')) + "\n")
- : ''
- )
- + cmd.description
- )
- );
- }
- ul.find('li').sort(function(a, b) {
- var at = $(a).text();
- var bt = $(b).text();
- return (at < bt) ? -1 : ((at > bt) ? 1 : 0);
- }).appendTo(ul);
- var exit = function(e, after) {
- Mousetrap.unbind([ 'esc esc', 'ctrl+g' ]);
- Mousetrap.unbind('tab');
- Mousetrap.unbind('up');
- Mousetrap.unbind('down');
- c.fadeOut(100, function() {
- c.remove();
- if(typeof after === 'function') {
- after();
- }
- });
- return false;
- };
- Mousetrap.bind([ 'esc esc', 'ctrl+g' ], exit);
- bg.click(exit);
- form.submit(function(e) {
- var command = inp.val();
- if(command in osmium_keyboard_commands) {
- inp.removeClass('error');
- inp.addClass('success');
- history.push(command);
- sessionStorage.setItem('mx-history', JSON.stringify(history));
- exit(e, function() {
- osmium_keyboard_commands[command].action();
- });
- } else {
- inp.addClass('error');
- }
- return false;
- });
- inp.on('keyup', function() {
- if(inp.val() !== lastval) {
- lastval = inp.val();
- tabcount = 0;
- inp.removeClass('error');
- }
- });
- Mousetrap.bind('tab', function() {
- var buf = inp.val();
- if(tabcount === 0) {
- /* Hide non-matching commands, fill up input with
- * largest prefix of matched commands */
- ul.find('li').each(function() {
- var li = $(this);
- if(li.text().substring(0, buf.length) === buf) {
- li.show();
- } else {
- li.hide();
- }
- });
- var matches = ul.find('li:visible');
- if(matches.length === 0) {
- inp.addClass('error');
- } else {
- inp.removeClass('error');
- var largestprefix = matches.first().text();
- matches.each(function() {
- var v = $(this).text();
- var i = 0;
- var ml = largestprefix.length;
- while(i <= ml && largestprefix.substring(0, i) === v.substring(0, i)) {
- ++i;
- }
- largestprefix = v.substring(0, i-1);
- });
- setinpval(largestprefix);
- lastval = largestprefix;
- }
- } else if(tabcount >= 2) {
- /* Cycle through matches */
- var matches = ul.find('li:visible');
- if(matches.length >= 1) {
- setinpval($(matches[(tabcount - 2) % matches.length]).text());
- lastval = inp.val();
- }
- }
- ++tabcount;
- return false;
- });
- Mousetrap.bind('up', function() {
- --histposition;
- if(histposition < 0) {
- histposition = history.length;
- setinpval(histlast);
- } else {
- if(histposition === history.length - 1) histlast = inp.val();
- setinpval(history[histposition]);
- }
- return false;
- });
- Mousetrap.bind('down', function() {
- ++histposition;
- if(histposition === history.length) {
- setinpval(histlast);
- }
- if(histposition >= history.length) histposition = history.length;
- else {
- setinpval(history[histposition]);
- }
- return false;
- });
- c.hide();
- $('body').append(c);
- c.fadeIn(100);
- inp.focus();
- return false;
- });
- }
- osmium_keyboard_commands[longname] = {
- shortnames: shortnames,
- longname: longname,
- description: description,
- action: action,
- };
- if(shortnames !== null) {
- Mousetrap.bind(shortnames, action);
- }
- };
- /* Unregister a keyboard command. Use the same longname you used in
- * osmium_register_keyboard_command. */
- osmium_unregister_keyboard_command = function(longname) {
- if(!(longname in osmium_keyboard_commands)) return;
- if(osmium_keyboard_commands[longname].shortnames !== null) {
- Mousetrap.unbind(osmium_keyboard_commands[longname].shortnames);
- }
- delete osmium_keyboard_commands[longname];
- if($.isEmptyObject(osmium_keyboard_commands)) {
- Mousetrap.unbind([ 'meta+x', 'alt+x', 'command+x' ]);
- }
- };
- if(typeof(localStorage) === 'undefined') {
- localStorage = {
- getItem: function() { return null; },
- setItem: function() {},
- removeItem: function() {},
- };
- }
- if(typeof(sessionStorage) === 'undefined') {
- sessionStorage = {
- getItem: function() { return null; },
- setItem: function() {},
- removeItem: function() {},
- };
- }
- /* Osmium
- * Copyright (C) 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- * Copyright (C) 2013 Josiah Boning <jboning@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- argsh = function(x) {
- return Math.log(x + Math.sqrt(x*x + 1.0));
- };
- osmium_targeting_time = function(targeter_scanres, targetee_sigradius) {
- /* Formula taken from the official wiki */
- return 40000.0 / (targeter_scanres * Math.pow(argsh(targetee_sigradius), 2));
- };
- osmium_gen_fattribs = function() {
- osmium_fattribs_load();
- var s = osmium_clf['X-damage-profile'][1][0] + osmium_clf['X-damage-profile'][1][1]
- + osmium_clf['X-damage-profile'][1][2] + osmium_clf['X-damage-profile'][1][3];
- $("section#defense > h4 > span.pname")
- .text(osmium_clf['X-damage-profile'][0])
- .prop('title',
- "EM: \t\t\t" + (100 * osmium_clf['X-damage-profile'][1][0] / s).toFixed(1) + "%\n" +
- "Explosive: \t" + (100 * osmium_clf['X-damage-profile'][1][1] / s).toFixed(1) + "%\n" +
- "Kinetic: \t\t" + (100 * osmium_clf['X-damage-profile'][1][2] / s).toFixed(1) + "%\n" +
- "Thermal: \t\t" + (100 * osmium_clf['X-damage-profile'][1][3] / s).toFixed(1) + "%"
- )
- ;
- var t = "Scan resolution\n\nTime to lock…";
- var sr = parseFloat($("span#scan_resolution").data('value'));
- var sig = parseFloat($("p#signature_radius").data('value'));
- for(var i = 0; i < osmium_targetclass.length; ++i) {
- if(!osmium_targetclass[i][1]) continue;
- t += "\n" + osmium_targetclass[i][0] + " (" + osmium_targetclass[i][3].toFixed(0) + " m): "
- + osmium_targeting_time(sr, osmium_targetclass[i][3]).toFixed(1) + " s"
- }
- $("span#scan_resolution").prop('title', t);
- t = "Signature radius\n\nTime to be locked by…";
- for(var i = 0; i < osmium_targetclass.length; ++i) {
- if(!osmium_targetclass[i][2]) continue;
- t += "\n" + osmium_targetclass[i][0] + " (" + osmium_targetclass[i][4].toFixed(0) + " mm) : "
- + osmium_targeting_time(osmium_targetclass[i][4], sig).toFixed(1) + " s"
- }
- $("p#signature_radius").prop('title', t);
- var capacitor = $("p#capacitor");
- capacitor.children("span.mainsprite:first-child, svg:first-child").replaceWith(
- osmium_gen_capacitor(capacitor.data('capacity'), capacitor.data('usage'))
- );
- };
- osmium_init_fattribs = function() {
- osmium_ctxmenu_bind($("div#computed_attributes > section#mastery"), function() {
- var menu = osmium_ctxmenu_create();
- for(var i = 0; i < osmium_skillsets.length; ++i) {
- osmium_ctxmenu_add_subctxmenu(menu, osmium_skillsets[i], (function(sname) {
- return function() {
- var smenu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(smenu, "Use", function() {
- osmium_clf.metadata['X-Osmium-skillset'] = sname;
- osmium_undo_push();
- osmium_commit_clf();
- }, { 'default': true });
- osmium_ctxmenu_add_option(smenu, "Set default", function() {
- osmium_put_setting('default_skillset', sname);
- }, {});
- return smenu;
- };
- })(osmium_skillsets[i]), {
- toggled: osmium_clf.metadata['X-Osmium-skillset'] === osmium_skillsets[i]
- });
- }
- return menu;
- });
- osmium_ctxmenu_bind($("div#computed_attributes > section#defense"), function() {
- var menu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_subctxmenu(menu, "Damage profiles", function() {
- var smenu = osmium_ctxmenu_create();
- for(var k in osmium_damage_profiles) {
- osmium_ctxmenu_add_subctxmenu(smenu, k, (function(profiles) {
- return function() {
- var ssmenu = osmium_ctxmenu_create();
- for(var z in profiles) {
- var s = profiles[z][0] + profiles[z][1] + profiles[z][2] + profiles[z][3];
- var opts = {
- toggled: z === osmium_clf['X-damage-profile'][0],
- title: "EM: \t\t\t" + (100 * profiles[z][0] / s).toFixed(1) + "%\n" +
- "Explosive: \t" + (100 * profiles[z][1] / s).toFixed(1) + "%\n" +
- "Kinetic: \t\t" + (100 * profiles[z][2] / s).toFixed(1) + "%\n" +
- "Thermal: \t\t" + (100 * profiles[z][3] / s).toFixed(1) + "%"
- };
- if(profiles[z].length >= 5) {
- opts.icon = profiles[z][4];
- }
- osmium_ctxmenu_add_option(ssmenu, z, (function(name, profile) {
- return function() {
- osmium_clf['X-damage-profile'] = [ name, profile.slice(0, 4) ];
- osmium_undo_push();
- osmium_commit_clf();
- };
- })(z, profiles[z]), opts);
- }
- return ssmenu;
- };
- })(osmium_damage_profiles[k]), {});
- }
- osmium_ctxmenu_add_subctxmenu(smenu, "Custom", function() {
- var ssmenu = osmium_ctxmenu_create();
- var count = 0;
- for(var k in osmium_custom_damage_profiles) {
- ++count;
- var profile = osmium_custom_damage_profiles[k];
- var s = profile[0] + profile[1] + profile[2] + profile[3];
- osmium_ctxmenu_add_subctxmenu(ssmenu, k, (function(k, profile) {
- return function() {
- var sssmenu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(sssmenu, "Use", function() {
- osmium_clf['X-damage-profile'] = [ k, profile ];
- osmium_undo_push();
- osmium_commit_clf();
- }, { 'default': true });
- osmium_ctxmenu_add_option(sssmenu, "Remove", function() {
- if(k === osmium_clf['X-damage-profile'][0]) {
- osmium_clf['X-damage-profile'] = [ "Uniform", [ .25, .25, .25, .25 ] ];
- osmium_commit_clf();
- }
- delete osmium_custom_damage_profiles[k];
- osmium_commit_custom_damage_profiles();
- }, {});
- return sssmenu;
- };
- })(k, osmium_custom_damage_profiles[k]), {
- toggled: k === osmium_clf['X-damage-profile'][0],
- title: "EM: \t\t\t" + (100 * profile[0] / s).toFixed(1) + "%\n" +
- "Explosive: \t" + (100 * profile[1] / s).toFixed(1) + "%\n" +
- "Kinetic: \t\t" + (100 * profile[2] / s).toFixed(1) + "%\n" +
- "Thermal: \t\t" + (100 * profile[3] / s).toFixed(1) + "%"
- });
- }
- if(count >= 1) {
- osmium_ctxmenu_add_separator(ssmenu);
- }
- osmium_ctxmenu_add_option(ssmenu, "Create…", function() {
- var name = prompt("Damage profile name:");
- if(!name) return;
- var prof = prompt("Damage values (EM, Explosive, Kinetic, Thermal):",
- "[ 0.25, 0.25, 0.25, 0.25 ]");
- if(!prof) return;
- try {
- var p = JSON.parse(prof);
- var s;
- if(p[0] < 0 || p[1] < 0 || p[2] < 0 || p[3] < 0 || (s = p[0] + p[1] + p[2] + p[3]) <= 0) {
- alert("Incorrect damage values: all four numbers must be positive, and at least one of them must be nonzero.");
- } else {
- osmium_custom_damage_profiles[name] = [
- p[0] / s, p[1] / s, p[2] / s, p[3] / s
- ];
- osmium_clf['X-damage-profile'] = [ name, osmium_custom_damage_profiles[name] ];
- osmium_undo_push();
- osmium_commit_clf();
- osmium_commit_custom_damage_profiles();
- }
- } catch(e) {
- alert("Incorrect syntax in damage values.");
- }
- $("ul#ctxmenu").trigger('delete_menu');
- }, {});
- return ssmenu;
- }, {});
- return smenu;
- }, {});
- return menu;
- });
- };
- osmium_commit_custom_damage_profiles = function() {
- osmium_put_setting('custom_damage_profiles', osmium_custom_damage_profiles);
- };
- /*<<< require external //cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.4.6/jquery.perfect-scrollbar-with-mousewheel.min.js >>>*/
- /*<<< require css //cdnjs.cloudflare.com/ajax/libs/jquery.perfect-scrollbar/0.4.6/perfect-scrollbar.css >>>*/
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*<<< require snippet perfectscrollbar >>>*/
- /*<<< require snippet mousetrap >>>*/
- osmium_modal_clear = function() {
- $("body > div#modalbg").fadeOut(250);
- $("body > div#modal").animate({
- 'margin-top': -$('body').width() + "px"
- }, 250);
- }
- osmium_modal = function(inside) {
- Mousetrap.unbind('esc');
- $("body > div#modalbg, body > div#modal").remove();
- var bg = $(document.createElement('div'));
- bg.prop('id', 'modalbg');
- bg.click(osmium_modal_clear);
- bg.hide();
- var modal = $(document.createElement('div'));
- modal.prop('id', 'modal');
- $('body')
- .append(bg)
- .append(modal)
- ;
- Mousetrap.bind('esc', osmium_modal_clear);
- modal
- .css('margin-left', (-modal.width() / 2) + "px")
- .css('margin-top', -$('body').width() + "px")
- .append(inside)
- .animate({
- 'margin-top': (-modal.height() / 2) + "px"
- }, 500)
- ;
- modal.perfectScrollbar({ wheelSpeed: 40 });
- bg.fadeIn(500);
- };
- osmium_modal_rotextarea = function(title, contents) {
- var m = $(document.createElement('div'));
- var h = $(document.createElement('header'));
- var textarea = $(document.createElement('textarea'));
- h.append($(document.createElement('h2')).text(title));
- m.append(h);
- textarea.text(contents);
- textarea.prop('readonly', 'readonly').prop('spellcheck', false);
- textarea.css({
- position: 'absolute',
- top: '0',
- left: '0',
- width: '100%',
- height: '100%',
- 'font-size': '0.8em'
- });
- m.append($(document.createElement('div')).css({
- position: 'absolute',
- top: '3.25em',
- left: '1em',
- right: '1em',
- bottom: '1em'
- }).append(textarea));
- osmium_modal(m.children());
- textarea.focus().select();
- };
- /* Osmium
- * Copyright (C) 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_sprite = function(alt, grid_x, grid_y, grid_width, grid_height, width, height) {
- var span = $(document.createElement('span'));
- var img = $(document.createElement('img'));
- span.addClass('mainsprite');
- span.css({
- width: width + 'px',
- height: height + 'px'
- });
- img.prop('src', osmium_relative + '/static-' + osmium_staticver + '/icons/sprite.png');
- img.prop('alt', alt);
- img.prop('title', alt);
- img.css({
- width: (width / grid_width * 1024) + 'px',
- height: (height / grid_height * 1024) + 'px',
- top: (-grid_x * width) + 'px',
- left: (-grid_y * height) + 'px'
- });
- span.append(img);
- return span;
- };
- /* Osmium
- * Copyright (C) 2012, 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_orig_anchor = null;
- osmium_selected_tabs = [];
- osmium_available_tabs = [];
- osmium_tab_ul_count = 0;
- osmium_tabify = function(ul, selected) {
- if(osmium_orig_anchor === null) {
- if(window.location.hash) {
- osmium_orig_anchor = window.location.hash.substring(1).split(",");
- } else {
- osmium_orig_anchor = [];
- }
- }
- var tabs = [];
- var i = 0;
- var selected_pref = 0;
- ul.find('li > a').each(function() {
- var t = $(this);
- var href = t.attr('href');
- if(href.substring(0, 1) != '#') return;
- t.parent().addClass('anchor');
- tabs.push(href.substring(1));
- ++i;
- });
- for(var j = 0; j < osmium_orig_anchor.length; ++j) {
- var index = $.inArray(osmium_orig_anchor[j], tabs);
- if(index !== -1) {
- /* Got one of our tabs in hash */
- if(selected_pref < 1) {
- selected = index;
- selected_pref = 1;
- }
- osmium_orig_anchor.splice(j, 1);
- /* Don't break here, as this choice may be overridden by a
- * "true" anchor in another tab */
- } else {
- if(selected_pref >= 2) continue; /* Already found */
- /* Not one of our tabs, see if it is an anchor in one of our tabs */
- var target = $('#' + osmium_orig_anchor[j]);
- if(target.length === 0) continue;
- target = target.parent();
- do {
- var id = target.prop('id');
- var index;
- if(id && ((index = $.inArray(id, tabs)) !== -1)) {
- /* Found one of our tabs as parent */
- selected = index;
- selected_pref = 2;
- break;
- }
- target = target.parent();
- } while("length" in target && target.length !== 0);
- }
- }
- i = 0;
- ul.find('li.anchor').each(function() {
- var t = $(this);
- var href = t.children('a').attr('href');
- var tget = $(href).addClass('notarget');
- if(i !== selected) {
- tget.hide().trigger('made_hidden');
- } else {
- t.addClass('active');
- tget.trigger('made_visible');
- }
- ++i;
- });
- var found = false;
- for(i = 0; i < osmium_available_tabs.length; ++i) {
- if($.inArray(tabs[selected], osmium_available_tabs[i]) !== -1) {
- ul.data('tab_ul_index', i);
- found = true;
- break;
- }
- }
- if(!found) {
- osmium_available_tabs.push(tabs);
- osmium_selected_tabs.push(tabs[selected]);
- ul.data('tab_ul_index', osmium_tab_ul_count++);
- }
- ul.find('li.anchor').on('click', osmium_tab_click);
- for(i = 0; i < osmium_orig_anchor.length; ++i) {
- var target = $("#" + osmium_orig_anchor[i]);
- if(target.length === 0) continue;
- if(!target.is(":visible")) continue;
- $(window).scrollTop(target.offset().top);
- return;
- }
- $(window).scrollTop(0);
- };
- osmium_tab_click = function(e) {
- var li = $(this);
- var ul_index = li.parent().data('tab_ul_index');
- var tabnames = osmium_available_tabs[ul_index];
- var want = li.children('a').blur().attr('href').substring(1);
- for(var i = 0; i < tabnames.length; ++i) {
- if(tabnames[i] === want) {
- $("#" + want).fadeIn(250).trigger('made_visible');
- } else {
- $("#" + tabnames[i]).hide().trigger('made_hidden');
- }
- }
- li.parent().children('li.active').removeClass('active');
- li.addClass('active');
- osmium_selected_tabs[ul_index] = want;
- if(window.history && window.history.replaceState) {
- history.replaceState(history.state, null, '#' + osmium_selected_tabs.join(','));
- }
- e.preventDefault();
- e.stopPropagation();
- return false;
- };
- osmium_tabify_nohash = function(ul, selected) {
- ul.find('li > a').on('click', function(e) {
- var t = $(this);
- var href = t.attr('href');
- if(href.substring(0, 1) !== '#') return;
- var tgt = $(t.attr('href'));
- var li = t.parent();
- if(li.hasClass('active')) return false;
- ul.find('li.active > a').each(function() {
- var a = $(this);
- var tgt = $(a.attr('href'));
- tgt.hide().trigger('made_hidden');
- a.parent().removeClass('active');
- });
- li.addClass('active');
- tgt.fadeIn(250).trigger('made_visible');
- t.blur();
- return false;
- }).each(function() {
- var t = $(this);
- var href = t.attr('href');
- if(href.substring(0, 1) !== '#') return;
- $(t.attr('href')).hide();
- });
- ul.children('li').eq(selected).children('a').click();
- };
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*<<< require snippet modal >>>*/
- /*<<< require snippet sprite >>>*/
- /*<<< require snippet tabs >>>*/
- /*<<< require snippet loadout_common >>>*/
- osmium_showinfo_sprite_position = [ 6, 58, 16, 16 ];
- osmium_showinfo = function(opts) {
- osmium_showinfo_internal(opts, function() {
- /* First error… Try committing CLF and retry once */
- osmium_commit_clf({
- success: function() {
- osmium_showinfo_internal(opts, function(xhr, error, httperror) {
- if(xhr.readyState === 0 || xhr.status === 0) {
- return;
- }
- alert('Could not show info: ' + error + ' (' + httperror
- + '). Try refreshing the page and report if the problem persists.');
- });
- }
- });
- });
- };
- osmium_showinfo_igb = function(opts) {
- osmium_showinfo_internal_igb(opts, function() {
- /* First error… Try committing CLF and retry once */
- osmium_commit_clf({
- success: function() {
- osmium_showinfo_internal_igb(opts, function(xhr, error, httperror) {
- if(xhr.readyState === 0 || xhr.status === 0) {
- return;
- }
- alert('Could not show info: ' + error + ' (' + httperror
- + '). Try refreshing the page and report if the problem persists.');
- });
- }
- });
- });
- };
- osmium_showinfo_internal_igb = function(opts, onerror) {
- osmium_clfspinner_push();
- opts.relative = osmium_relative;
- opts['o___csrf'] = osmium_token;
- opts['clftoken'] = osmium_clftoken;
- $.ajax({
- type: 'POST',
- url: osmium_relative + '/internal/showinfo',
- data: opts,
- dataType: 'json',
- error: onerror,
- complete: function() {
- osmium_clfspinner_pop();
- },
- success: function(json) {
- var vartypeids = [];
- for(var i = 0; i < 1; ++i) {
- var t = osmium_types[json.variations[i][0]];
- CCPEVE.showInfo (t[0]);
- }
- }
- });
- }
- osmium_showinfo_internal = function(opts, onerror) {
- osmium_clfspinner_push();
- opts.relative = osmium_relative;
- opts['o___csrf'] = osmium_token;
- opts['clftoken'] = osmium_clftoken;
- $.ajax({
- type: 'POST',
- url: osmium_relative + '/internal/showinfo',
- data: opts,
- dataType: 'json',
- error: onerror,
- complete: function() {
- osmium_clfspinner_pop();
- },
- success: function(json) {
- osmium_modal(json['modal']);
- osmium_tabify_nohash($('ul.showinfotabs'), 0);
- var ul = $("ul.sivariations").last();
- var vartypeids = [];
- for(var i = 0; i < json.variations.length; ++i) {
- var t = osmium_types[json.variations[i][0]];
- var li = $(document.createElement('li'));
- li.addClass('module');
- li.data('typeid', t[0]);
- li.text(t[1]);
- li.data('category', t[2]);
- li.data('subcategory', t[3]);
- vartypeids.push(t[0]);
- li.prepend(
- $(document.createElement('img'))
- .prop('src', '//image.eveonline.com/Type/' + t[0] + '_64.png')
- .prop('alt', '')
- );
- li.append(
- $(document.createElement('span'))
- .addClass('metalevel')
- .text(', meta level ' + json.variations[i][1])
- );
- if(osmium_loadout_readonly) {
- osmium_ctxmenu_bind(li, (function(typeid) {
- return function() {
- var menu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(menu, "Show info", function() {
- osmium_showinfo({
- type: 'generic',
- typeid: typeid
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': true });
- osmium_ctxmenu_add_option(menu, "Show IGB info", function() {
- osmium_showinfo_igb({
- type: 'generic',
- typeid: typeid
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': true });
- return menu;
- };
- })(t[0]));
- } else {
- osmium_add_non_shortlist_contextmenu(li);
- }
- ul.append(li);
- }
- ul.after($(document.createElement('p')).addClass('compare').append(
- $(document.createElement('a'))
- .prop('target', '_blank')
- .addClass('external')
- .prop('href', osmium_relative + '/db/comparetypes/'
- + vartypeids.join(',') + '/auto')
- .text('Compare these types')
- ));
- }
- });
- }
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_ctxmenu_bind = function(element, menu_constructor) {
- var indicator = $(document.createElement('span'));
- element.children('.contextmenuindicator').remove();
- indicator.text('≡');
- indicator.addClass('contextmenuindicator');
- element.append(indicator);
- var showmenu = function(e) {
- var menu = menu_constructor();
- menu.prop('id', 'ctxmenu');
- div = $(document.createElement('div'));
- div.prop('id', 'ctxbg');
- div.bind('click contextmenu', function(e2) {
- menu.click();
- $(document.elementFromPoint(e2.pageX, e2.pageY)).trigger(e2);
- return false;
- });
- menu.bind('click delete_menu', function() {
- $("ul#ctxmenu, div#ctxbg, ul.subctxmenu").remove();
- });
- $('ul#ctxmenu, div#ctxbg, ul.subctxmenu').remove();
- $('body').append(div).append(menu);
- var x = Math.min(e.pageX, $(document).width() - menu.width() - 5);
- var y = e.pageY;
- menu.css('left', x);
- menu.css('top', y);
- return false;
- };
- element.on('dblclick do_default_ctxmenu_action', function() {
- var menu = menu_constructor();
- menu.children('li.default').trigger('do_action');
- return false;
- });
- element.on('contextmenu', showmenu);
- indicator.on('click', showmenu);
- element.addClass('hascontextmenu');
- };
- osmium_ctxmenu_create = function() {
- return $(document.createElement('ul'));
- };
- /* opts is a Hashtable that can accept the properties:
- * - icon: URI of the icon to show
- * - title: tooltip of this option (uses title attribute)
- * - enabled: whether this option is enabled or not (default yes); disabled elements cannot be clicked on
- * - default: whether this option is the default when the element is double-clicked (default false)
- * - toggled: whether this option is "checked" or "selected"
- */
- osmium_ctxmenu_add_option = function(menu, name, action, opts) {
- var li = $(document.createElement('li'));
- li.append($(document.createElement('span')).text(name));
- osmium_ctxmenu_apply_opts(menu, li, opts);
- if(("enabled" in opts) && !opts.enabled) {
- li.addClass('disabled');
- } else {
- li.on('do_action click', function() {
- action();
- li.closest('ul#ctxmenu').click();
- });
- }
- if(("default" in opts) && opts['default'] && !li.hasClass('disabled')) {
- li.addClass('default');
- }
- menu.append(li);
- };
- osmium_ctxmenu_add_separator = function(menu) {
- var li = $(document.createElement('li'));
- li.addClass('separator');
- li.text(' ');
- menu.append(li);
- };
- osmium_ctxmenu_add_heading = function(menu, name, opts) {
- var li = $(document.createElement('li'));
- li.addClass('hd');
- li.addClass('disabled');
- li.append($(document.createElement('span')).text(name));
- osmium_ctxmenu_apply_opts(menu, li, opts);
- menu.append(li);
- };
- /* Same parameters as osmium_ctxmenu_add_option(), but the action is
- * replaced by a submenu constructor function. */
- osmium_ctxmenu_add_subctxmenu = function(menu, name, submenu_ctor, opts) {
- var li = $(document.createElement('li'));
- var timeout_in, timeout_out;
- var show_submenu;
- li.append($(document.createElement('span')).text(name));
- osmium_ctxmenu_apply_opts(menu, li, opts);
- show_submenu = function() {
- var submenu = submenu_ctor();
- submenu.addClass('subctxmenu');
- if(li.children('ul.subctxmenu').length == 1) return;
- li.parent().find('ul.subctxmenu').remove();
- li.append(submenu);
- var offset = li.offset();
- var ow = li.outerWidth();
- var sow = submenu.outerWidth();
- if(offset.left + ow + sow > $(document).width()) {
- submenu.offset({
- top: offset.top,
- left: offset.left - sow
- });
- } else {
- submenu.offset({
- top: offset.top,
- left: offset.left + ow
- });
- }
- };
- if(("enabled" in opts) && !opts.enabled) {
- li.addClass('disabled');
- } else {
- li.on('show_submenu', function(e) {
- show_submenu();
- e.stopPropagation();
- return false;
- }).on('hide_submenu', function(e) {
- li.children('ul.subctxmenu').remove();
- e.stopPropagation();
- return false;
- }).on('click', function(e) {
- var def = li.children('ul.subctxmenu').children('li.default');
- if(def.length === 1) {
- def.trigger('do_action');
- return;
- }
- li.trigger('show_submenu');
- e.stopPropagation();
- return false;
- }).on('mouseenter', function(e) {
- clearTimeout(timeout_out);
- timeout_in = setTimeout(function() {
- li.trigger('show_submenu');
- }, 100);
- }).on('mouseleave', function(e) {
- clearTimeout(timeout_in);
- timeout_out = setTimeout(function() {
- li.trigger('hide_submenu');
- }, 250);
- });
- }
- li.addClass('hassubcontextmenu');
- menu.append(li);
- };
- /* @internal */
- osmium_ctxmenu_apply_opts = function(menu, li, opts) {
- if(opts === undefined) opts = {};
- if("title" in opts) {
- li.prop('title', opts.title);
- }
- if("icon" in opts && typeof opts.icon === "string") {
- var img = $(document.createElement('img'));
- img.prop('alt', '');
- if(opts.icon.substring(0, 2) === '//') {
- /* Absolute URI of type //foo.tld/path.png */
- img.prop('src', opts.icon);
- } else {
- /* Relative URI */
- img.prop('src', osmium_relative + '/static-' + osmium_staticver + '/icons/' + opts.icon);
- }
- img.addClass('icon');
- li.prepend(img);
- li.addClass('hasicon');
- } else if("icon" in opts && typeof opts.icon === "object") {
- li.prepend(osmium_sprite(
- '',
- opts.icon[0],
- opts.icon[1],
- opts.icon[2],
- opts.icon[3],
- 16, 16
- ));
- li.addClass('hasicon');
- }
- if("toggled" in opts) {
- var c = $(document.createElement('input'));
- c.prop('type', 'checkbox');
- c.prop('checked', opts.toggled);
- li.prepend(c);
- li.addClass('hastoggle');
- if(opts.toggled) {
- li.addClass('toggled');
- }
- }
- };
- /* Osmium
- * Copyright (C) 2012, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_fattribs_load = function() {
- var hidden = $('div#osmium-data').data('fattribshidden');
- if(!hidden) return;
- var hc = hidden.length;
- var s = $("div#computed_attributes");
- for(var i = 0; i < hc; ++i) s.children("section#" + hidden[i]).addClass('hidden').children('div').hide();
- };
- osmium_fattribs_toggle = function(section) {
- if(section.hasClass('hidden')) {
- section.children('div').fadeIn(250);
- section.removeClass('hidden');
- } else {
- section.children('div').fadeOut(250);
- section.addClass('hidden');
- }
- var hidden = [];
- $("div#computed_attributes > section.hidden").each(function() {
- hidden.push($(this).prop('id'));
- });
- osmium_put_setting('fattribs_hidden', hidden);
- };
- $(function() {
- $(document).on('click', "div#computed_attributes > section > h4", function() {
- osmium_fattribs_toggle($(this).parent());
- });
- osmium_fattribs_load();
- });
- /* Osmium
- * Copyright (C) 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /**
- * Try to auto-guess "best" initial values. Returns an array of three
- * values [ tsrOptimal, tvOptimal, tdOptimal ].
- */
- osmium_probe_optimals_from_ia = function(ia) {
- var tsrc = 0, tsrs = 0, tvc = 0, tvs = 0, tdc = 0, tds = 0;
- for(var i = 0; i < ia.length; ++i) {
- var a = ia[i].raw;
- if(!("damagetype" in a)) continue;
- if("sigradius" in a) {
- ++tsrc;
- tsrs += a.sigradius;
- }
- if("expradius" in a) {
- ++tsrc;
- tsrs += a.expradius;
- }
- if(a.damagetype === "turret" && "range" in a) {
- ++tdc;
- tds += a.range / 1000.0;
- }
- }
- return [
- tsrc === 0 ? 250 : Math.round(tsrs / tsrc),
- tvc === 0 ? 0 : Math.round(tvs / tvc),
- tdc === 0 ? 1 : Math.round(tds / tdc),
- ];
- };
- /**
- * Try to auto-guess graph boundaries with some given
- * constraints. Parameters tsr, tv, td can be filled or left
- * out. Returns an array of three values [ tsrMax, tvMax, tdMax ].
- */
- osmium_probe_boundaries_from_ia = function(ia, tsr, tv, td) {
- var tsrmax = 50, tvmax = 50, tdmax = 5000;
- var a;
- if(isNaN(td)) {
- for(var j = 0; j < ia.length; ++j) {
- a = ia[j].raw;
- if(!("damagetype" in a)) continue;
- var m = Math.min(
- ("range" in a && "falloff" in a) ? (a.range + 3 * a.falloff) : Infinity,
- ("maxrange" in a) ? (a.maxrange * 1.1) : Infinity,
- ("controlrange" in a) ? (a.controlrange * 1.1) : Infinity
- );
- if(isFinite(m)) tdmax = Math.max(tdmax, m);
- }
- tdmax /= 1000;
- } else {
- tdmax = td;
- }
- if(isNaN(tsr)) {
- for(var j = 0; j < ia.length; ++j) {
- a = ia[j].raw;
- if(!("damagetype" in a)) continue;
- if("sigradius" in a) {
- tsrmax = Math.max(tsrmax, a.sigradius * 3);
- continue;
- }
- if("expradius" in a) {
- tsrmax = Math.max(tsrmax, a.expradius * 3);
- continue;
- }
- }
- } else {
- tsrmax = tsr;
- }
- if(isNaN(tv)) {
- for(var j = 0; j < ia.length; ++j) {
- a = ia[j].raw;
- if(!("damagetype" in a)) continue;
- if("trackingspeed" in a && "range" in a && "falloff" in a) {
- if(a.damagetype === "combatdrone" && a.maxvelocity > 0) {
- continue;
- }
- tvmax = Math.max(
- tvmax,
- Math.min(a.damagetype === "combatdrone" ? 2500 : 12000,
- (a.range + a.falloff) * a.trackingspeed)
- );
- continue;
- }
- if("expvelocity" in a) {
- tvmax = Math.max(tvmax, a.expvelocity * 8);
- continue;
- }
- }
- } else {
- tvmax = tv;
- }
- return [ tsrmax, tvmax, tdmax ];
- };
- /**
- * Return a color from a parameter between 0 and 1. The color is red
- * for 1, and will smoothly go through all the color spectrum to reach
- * transparent-ish purple at zero.
- */
- osmium_heat_color = function(t) {
- return "hsla("
- + Math.round((1 - t) * 360).toString()
- + ", 100%, 50%, "
- + Math.min(1, t).toFixed(2)
- + ")";
- };
- /**
- * Generate labels and append them next to a canvas element.
- *
- * @param ctx the root element to add the labels to
- * @param canvas the canvas element
- * @param xlabel text to label the X axis with
- * @param ylabel text to label the Y axis with
- */
- osmium_graph_gen_labels = function(ctx, canvas, xlabel, ylabel) {
- var xl, yl;
- ctx.append(xl = $(document.createElement('span')).addClass('xlabel').text(xlabel));
- ctx.append(yl = $(document.createElement('span')).addClass('ylabel').text(ylabel));
- var cpos = canvas.offset();
- xl.offset({
- top: cpos.top + canvas.height() + 4,
- left: cpos.left + canvas.width() / 2 - xl.width() / 2
- });
- /* Rotating first gives different results on Chromium/Firefox */
- yl.offset({
- top: cpos.top + canvas.height() / 2 - yl.height() / 2,
- left: cpos.left - yl.width() / 2 - yl.height() / 2 - 4
- }).addClass('rotated');
- };
- /**
- * Draw a labeled grid using a given canvas context.
- *
- * @param cctx the canvas context to draw with
- * @param cw canvas width
- * @param ch canvas height
- * @param xmin minimum value for X axis
- * @param xmax maximum value for X axis
- * @param xsteps minimum number of vertical guides to draw
- * @param ymin minimum value for Y axis
- * @param ymax maximum value for Y axis
- * @param ysteps minimum value of horizontal guides to draw
- * @param axisopacity opacity (between 0 and 1) of the drawn guides
- * @param labelopacity opacity (between 0 and 1) of the drawn labels
- */
- osmium_graph_draw_grid = function(cctx, cw, ch, xmin, xmax, xsteps, ymin, ymax, ysteps, axisopacity, labelopacity) {
- var steps = [ 50000, 20000, 10000,
- 5000, 2000, 1000,
- 500, 200, 100,
- 50, 20, 10,
- 5, 2, 1,
- .5, .2, .1,
- .05, .02, .01,
- .005, .002, .001,
- .0005, .0002, .0001 ];
- var xstep = 1, ystep = 1;
- for(var i = 0; i < steps.length; ++i) {
- if((xmax - xmin) / steps[i] >= xsteps) {
- xstep = steps[i];
- break;
- }
- }
- for(var i = 0; i < steps.length; ++i) {
- if((ymax - ymin) / steps[i] >= ysteps) {
- ystep = steps[i];
- break;
- }
- }
- cctx.beginPath();
- cctx.font = '0.8em "Droid Sans"';
- cctx.fillStyle = "hsla(0, 0%, 50%, " + labelopacity.toString() + ")";
- cctx.textAlign = "center";
- cctx.textBaseline = "bottom";
- for(var x = Math.ceil(xmin / xstep) * xstep; x < xmax; x += xstep) {
- if(x === xmin) continue;
- var xc = Math.floor(cw * (x - xmin) / (xmax - xmin)) + 0.5;
- cctx.moveTo(xc, 0.5);
- cctx.lineTo(xc, ch - 0.5);
- cctx.fillText(x.toString(), xc, ch - 0.5);
- }
- cctx.textAlign = "left";
- cctx.textBaseline = "middle";
- for(var y = Math.ceil(ymin / ystep) * ystep; y < ymax; y += ystep) {
- if(y === ymin) continue;
- var yc = Math.floor(ch * (y - ymin) / (ymax - ymin)) + 0.5;
- cctx.moveTo(0.5, ch - yc);
- cctx.lineTo(cw - 0.5, ch - yc);
- cctx.fillText(y.toString(), 2.5, ch - yc);
- }
- cctx.strokeStyle = "hsla(0, 0%, 50%, " + axisopacity.toString() + ")";
- cctx.stroke();
- };
- /**
- * Get the average DPS of a turret-like weapon.
- *
- * http://wiki.eveuniversity.org/Turret_Damage
- *
- * @param dps the raw DPS of the turret
- * @param trackingspeed tracking speed of the turret, in rad/s
- * @param sigresolution signature resolution of the turret, in meters
- * @param range optimal range of the turret, in meters
- * @param falloff falloff range of the turret, in meters
- * @param tsr target signature radius, in meters
- * @param tv target velocity, in m/s
- * @param td target distance, in km
- */
- osmium_turret_damage_f = function(dps, trackingspeed, sigresolution, range, falloff, tsr, tv, td) {
- if(tv == 0 && td == 0) td = .001;
- if(tsr == 0) return 0;
- var cth = Math.pow(
- 0.5,
- Math.pow(
- ((tv / (1000 * td)) / trackingspeed) * (sigresolution / tsr),
- 2
- ) + Math.pow(
- Math.max(0, (1000 * td) - range) / falloff,
- 2
- )
- );
- return (
- Math.min(cth, 0.01) * 3 + Math.max(cth - 0.01, 0) * (0.49 + (cth + 0.01) / 2)
- ) * dps;
- };
- /**
- * Get the average DPS of a missile-like weapon.
- *
- * http://wiki.eveuniversity.org/Missile_Damage
- *
- * @param dps the raw DPS of the missile launcher
- * @param maxrange the maximum range of the missile
- * @param expradius explosion radius of the missile
- * @param expvelocity explosion velocity of the missile
- * @param drf damage reduction factor
- * @param drs damage reduction sensitivity
- * @param tsr target signature radius, in meters
- * @param tv target velocity, in m/s
- * @param td target distance, in km
- */
- osmium_missile_damage_f = function(dps, maxrange, expradius, expvelocity, drf, drs, tsr, tv, td) {
- if(1000 * td > maxrange || dps == 0) return 0;
- return dps * Math.min(
- 1,
- tsr / expradius,
- (tsr != 0 && expvelocity != 0) ?
- Math.pow((tsr / expradius) * (expvelocity / tv), Math.log(drf) / Math.log(drs))
- : 0
- );
- };
- /** Get the average DPS of a fitted type. */
- osmium_get_dps_from_type_internal = function(a, tsr, tv, td) {
- if(!("damagetype" in a)) return 0;
- if(a.damagetype === "combatdrone" || a.damagetype === "fighter" || a.damagetype === "fighterbomber") {
- if(a.damagetype === "combatdrone" && "controlrange" in a && 1000 * td > a.controlrange) return 0;
- if(a.maxvelocity == 0) {
- /* Sentry drone */
- return osmium_turret_damage_f(
- a.damage / a.duration,
- a.trackingspeed, a.sigradius, a.range, a.falloff,
- tsr, tv, td
- );
- }
- /* XXX: this is a very simplistic model, totally inaccurate
- * guesswork. Critique & improvements most welcomed! */
- /* Drone tries to keep orbit at flyrange m @ cruisespeed m/s */
- /* After a full cycle, assume the drone will use MWD to
- * reenter orbit distance */
- var ddur = a.duration;
- if(tv > a.cruisespeed) {
- if(tv >= a.maxvelocity) {
- /* Drone will never catch up */
- ddur = Infinity;
- } else {
- ddur += (tv - a.cruisespeed) * a.duration / (a.maxvelocity - tv);
- }
- }
- if(a.damagetype === "fighterbomber") {
- return osmium_missile_damage_f(
- a.damage / ddur,
- a.maxrange, a.expradius, a.expvelocity, a.drf, a.drs,
- tsr, tv, a.flyrange / 1000.0
- );
- }
- return osmium_turret_damage_f(
- a.damage / ddur,
- a.trackingspeed, a.sigradius, a.range, a.falloff,
- tsr, a.cruisespeed, a.flyrange / 1000.0
- );
- }
- if(a.damagetype === "turret") {
- return osmium_turret_damage_f(
- a.damage / a.duration,
- a.trackingspeed, a.sigradius, a.range, a.falloff,
- tsr, tv, td
- );
- }
- if(a.damagetype === "missile") {
- return osmium_missile_damage_f(
- a.damage / a.duration,
- a.maxrange, a.expradius, a.expvelocity, a.drf, a.drs,
- tsr, tv, td
- );
- }
- if(a.damagetype === "smartbomb") {
- if(1000 * td > a.maxrange) return 0;
- return a.damage / a.duration;
- }
- return 0;
- };
- /** @internal */
- osmium_get_dps_internal = function(ia, args) {
- var dps = 0;
- for(var j = 0; j < ia.length; ++j) {
- dps += osmium_get_dps_from_type_internal(ia[j].raw, args[0], args[1], args[2]);
- }
- return 1000 * dps;
- };
- /**
- * Draw a line graph for every set of attributes in ia_map, using colors in color_map.
- *
- * @param ctx the root element to append the canvas and labels into
- * @param xlabel the X label
- * @param xmin the minimum X value
- * @param xmax the maximum X value
- * @param genfunc_x a function which takes the X coordinate and returns an array [ tsr, tv, td ]
- * @param dpsmin the minimum Y value
- * @param dpsmax the maximum Y value, leave null to autodetect
- */
- osmium_draw_dps_graph_1d = function(ia_map, color_map, ctx,
- xlabel, xmin, xmax, genfunc_x, dpsmin, dpsmax) {
- ctx.empty();
- var canvas = document.createElement('canvas');
- var cctx = canvas.getContext('2d');
- var cw, ch;
- canvas = $(canvas);
- ctx.append($(document.createElement('div')).addClass('cctx').append(canvas));
- canvas.attr('width', cw = canvas.width());
- canvas.attr('height', ch = canvas.height());
- osmium_graph_gen_labels(ctx, canvas, xlabel, "Damage per second");
- var x, dps, px, py;
- if(!dpsmax) {
- dpsmax = 10;
- for(var i = 0; i <= cw; ++i) {
- x = xmin + (i / cw) * (xmax - xmin);
- for(var k in ia_map) {
- if(!("ia" in ia_map[k])) continue;
- dpsmax = Math.max(dpsmax, osmium_get_dps_internal(ia_map[k].ia, genfunc_x(x)));
- }
- }
- dpsmax *= 1.05;
- }
- osmium_graph_draw_grid(cctx, cw, ch, xmin, xmax, 8, dpsmin, dpsmax, 4, 0.15, 0.5);
- for(var k in ia_map) {
- if(!("ia" in ia_map[k])) continue;
- cctx.beginPath();
- cctx.moveTo(0, 0);
- for(var i = 0; i <= cw; ++i) {
- x = xmin + (i / cw) * (xmax - xmin);
- dps = osmium_get_dps_internal(ia_map[k].ia, genfunc_x(x));
- px = i + 0.5;
- py = Math.floor(ch * (1 - (dps - dpsmin) / (dpsmax - dpsmin))) + 0.5;
- if(i === 0) {
- cctx.moveTo(px, py);
- } else {
- cctx.lineTo(px, py);
- }
- }
- cctx.strokeStyle = color_map[k];
- cctx.lineWidth = 3;
- cctx.stroke();
- }
- };
- /**
- * Draw a 2d graph. Most parameters are similar to the 1d version.
- *
- * @param genfunc_xy a function that takes two parameters (the X,Y
- * coordinates) and returns an array [ tsr, tv, td ].
- *
- * @param cololfunc a function that takes one parameter, a map of
- * array [ DPS, MaxDPS ] values and returns a color.
- *
- * @param pixelsize the size of the rectangles drawn on the
- * graph. Higher values means less rectangles to draw, but results in
- * a blockier graph.
- *
- * @returns global maximum dps
- */
- osmium_draw_dps_graph_2d = function(ia_map, colorfunc, ctx,
- xlabel, xmin, xmax, ylabel, ymin, ymax,
- genfunc_xy, pixelsize) {
- ctx.empty();
- var canvas = document.createElement('canvas');
- var cctx = canvas.getContext('2d');
- var cw, ch;
- canvas = $(canvas);
- ctx.append($(document.createElement('div')).addClass('cctx').append(canvas));
- canvas.attr('width', cw = canvas.width());
- canvas.attr('height', ch = canvas.height());
- osmium_graph_gen_labels(ctx, canvas, xlabel, ylabel);
- cctx.moveTo(0, ch);
- var x, y, px, py, localmax = {}, globalmax = 10, hps = pixelsize / 2;
- for(var k in ia_map) {
- if(!("ia" in ia_map[k])) continue;
- var ia = ia_map[k].ia;
- localmax[k] = 0;
- for(var i = 0; i <= cw; i += pixelsize) {
- x = xmin + ((i + hps) / cw) * (xmax - xmin);
- for(var j = 0; j <= ch; j += pixelsize) {
- y = ymin + ((j + hps) / ch) * (ymax - ymin);
- localmax[k] = Math.max(localmax[k], osmium_get_dps_internal(ia, genfunc_xy(x, y)));
- }
- }
- globalmax = Math.max(localmax[k], globalmax);
- }
- var dps = {};
- for(var k in ia_map) {
- dps[k] = [ 0, Math.max(1, localmax[k]) ];
- }
- for(var i = 0; i <= cw; i += pixelsize) {
- x = xmin + ((i + hps) / cw) * (xmax - xmin);
- for(var j = 0; j <= ch; j += pixelsize) {
- y = ymin + ((j + hps) / ch) * (ymax - ymin);
- for(var k in ia_map) {
- if(!("ia" in ia_map[k])) continue;
- dps[k][0] = osmium_get_dps_internal(ia_map[k].ia, genfunc_xy(x, y));
- }
- cctx.fillStyle = colorfunc(dps);
- cctx.fillRect(i, ch - j, pixelsize, pixelsize);
- }
- }
- osmium_graph_draw_grid(cctx, cw, ch, xmin, xmax, 8, ymin, ymax, 4, 0.15, 0.75);
- return globalmax;
- };
- /** Draw a legend for colored 2d graphs. */
- osmium_draw_dps_legend = function(ctx, maxdps, heatfunc) {
- ctx.find('div.cctx').addClass('twodim');
- var lcanvas = document.createElement('canvas');
- var lctx = lcanvas.getContext('2d');
- var lw, lh;
- lcanvas = $(lcanvas);
- ctx.append($(document.createElement('div')).addClass('legend').append(lcanvas));
- lcanvas.attr('width', lw = lcanvas.width());
- lcanvas.attr('height', lh = lcanvas.height());
- for(var i = 0; i <= lh; ++i) {
- lctx.fillStyle = heatfunc(i / lh);
- lctx.fillRect(0, lh - i, 100, 1);
- }
- var dlabel = $(document.createElement('span')).text('DPS');
- ctx.append(dlabel);
- var lpos = lcanvas.parent().offset();
- dlabel.offset({
- top: lpos.top + lcanvas.parent().height() + 5,
- left: lpos.left + lcanvas.parent().width() / 2 - dlabel.width() / 2
- });
- lpos = lcanvas.offset();
- var nlabels = 6;
- for(var i = 0; i <= nlabels; ++i) {
- dlabel = $(document.createElement('span')).addClass('dpslabel')
- .text(Math.round((i / nlabels) * maxdps).toString());
- ctx.append(dlabel);
- dlabel.offset({
- top: Math.min(
- Math.max(
- lpos.top + lcanvas.height() * (1 - i / nlabels) - dlabel.height() / 2,
- lpos.top
- ),
- lpos.top + lcanvas.height() - dlabel.height()
- ),
- left: lpos.left - dlabel.width() - 4
- });
- }
- };
- /* Osmium
- * Copyright (C) 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_capacitor = function(capacity, current) {
- if(capacity === null) capacity = 0;
- if(current === null) current = 0;
- var nbranches = Math.min(10, Math.max(2, Math.floor(capacity / 50.0)));
- var nbubbles = 3;
- var bubblecapacity = (capacity > 0) ? (capacity / (nbubbles * nbranches)) : 0;
- /* Avoid using the same IDs on different <svg> elements in the
- * same page */
- var idsuffix = Math.random().toFixed(20).substring(2);
- var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
- svg.setAttribute('viewBox', '-1 -1 2 2');
- svg.setAttribute('class', 'capacitorwheel');
- var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
- for(var t in { full: 1, empty: 1 }) {
- var lg = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
- lg.setAttribute('id', 'gradient-' + t + '-' + idsuffix);
- lg.setAttribute('class', t);
- var stop;
- stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
- stop.setAttribute('offset', '0%');
- lg.appendChild(stop);
- stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
- stop.setAttribute('offset', '33%');
- lg.appendChild(stop);
- stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
- stop.setAttribute('offset', '67%');
- lg.appendChild(stop);
- stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
- stop.setAttribute('offset', '100%');
- lg.appendChild(stop);
- defs.appendChild(lg);
- }
- svg.appendChild(defs);
- var progress = 0;
- for(var i = 0; i < nbranches; ++i) {
- var angle = -360 * i / nbranches;
- var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
- g.setAttribute('transform', 'rotate(' + angle + ' 0 0)');
- for(var j = 0; j < nbubbles; ++j) {
- var bubble = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
- var w = 0.2 + j * 0.12;
- bubble.setAttribute('width', w + '');
- bubble.setAttribute('height', '0.15');
- bubble.setAttribute('x', (-w / 2) + '');
- bubble.setAttribute('y', (-0.9 + 0.8 * (nbubbles - j - 1) / nbubbles) + '');
- bubble.setAttribute('rx', '0.075');
- bubble.setAttribute('ry', '0.075');
- bubble.setAttribute(
- 'fill',
- (progress < current) ?
- ('url(#gradient-full-' + idsuffix + ')')
- : ('url(#gradient-empty-' + idsuffix + ')')
- );
- g.appendChild(bubble);
- progress += bubblecapacity;
- }
- svg.appendChild(g);
- }
- var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
- svg.appendChild(g);
- var title = document.createElementNS('http://www.w3.org/2000/svg', 'title');
- title.appendChild(document.createTextNode('Capacity: ' + capacity.toFixed(0) + ' GJ'));
- g.setAttribute('class', 'overlay');
- g.appendChild(title);
- var r = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
- r.setAttribute('x', '-1');
- r.setAttribute('y', '-1');
- r.setAttribute('width', '2');
- r.setAttribute('height', '2');
- g.appendChild(r);
- svg = $(svg);
- svg.data('capacity', capacity);
- svg.data('current', current);
- svg.on('redraw', function() {
- var t = $(this);
- t.replaceWith(
- osmium_gen_capacitor(t.data('capacity'), t.data('current'))
- );
- });
- return svg;
- };
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_undo_stack = [];
- osmium_undo_stack_position = 0;
- osmium_pushed_state_count = 0;
- osmium_popstate_disablefor = 0;
- /* Push the current CLF to the undo history. */
- osmium_undo_push = function() {
- osmium_undo_stack.push($.extend(true, {}, osmium_clf));
- osmium_undo_stack_position = osmium_undo_stack.length - 1;
- osmium_set_history_undo();
- };
- /* Restore the previous CLF in the undo history. Negative values also
- * supported, in which case, use fallback_clf if going too far in the
- * future. */
- osmium_undo_pop = function(nsteps, fallback_clf) {
- if(nsteps === undefined) nsteps = 1;
- if(osmium_undo_stack_position < nsteps) {
- /* No more history to undo */
- return false;
- }
- /* Very similar to the "undo" feature of Emacs. Powerful and
- * cannot lose data by undoing stuff then doing modifications. */
- osmium_undo_stack_position -= nsteps;
- if(fallback_clf !== undefined) {
- osmium_undo_stack[osmium_undo_stack_position] = $.extend(true, {}, fallback_clf);
- }
- var clf = osmium_undo_stack[osmium_undo_stack_position];
- if(clf === undefined) {
- return false;
- }
- osmium_clf = $.extend(true, {}, clf);
- osmium_undo_stack.push($.extend(true, {}, clf));
- osmium_set_history_undo();
- return true;
- }
- /* @internal */
- osmium_set_history_undo = function() {
- if(!window.history || !window.history.pushState) return;
- /* This sucks, but popstate is async */
- osmium_popstate_disablefor += Math.max(0, osmium_pushed_state_count - osmium_undo_stack_position);
- while(osmium_pushed_state_count > osmium_undo_stack_position) {
- history.back();
- --osmium_pushed_state_count;
- }
- while(osmium_pushed_state_count < osmium_undo_stack_position) {
- ++osmium_pushed_state_count;
- history.pushState([
- osmium_pushed_state_count,
- osmium_undo_stack[osmium_pushed_state_count],
- ], null);
- }
- };
- $(function() {
- $(window).on('popstate', function(e) {
- if(osmium_popstate_disablefor > 0) {
- --osmium_popstate_disablefor;
- return;
- }
- var state = e.originalEvent.state;
- if(state === null) state = [ 0, undefined ];
- var nsteps = osmium_undo_stack_position - state[0];
- osmium_pushed_state_count -= nsteps;
- if(osmium_undo_pop(nsteps, state[1]) === false) return;
- osmium_commit_clf();
- osmium_user_initiated_push(false);
- osmium_gen();
- osmium_user_initiated_pop();
- });
- });
- osmium_register_keyboard_command('ctrl+z', 'undo', 'Undo the last change made to the loadout.', function() {
- if(osmium_undo_pop() === false) return false;
- osmium_commit_clf();
- osmium_user_initiated_push(false);
- osmium_gen();
- osmium_user_initiated_pop();
- return false;
- });
- osmium_register_keyboard_command(null, 'debug-log-clf-undo-stack', 'Print the undo history to the Javascript console.', function() {
- console.log(osmium_undo_stack_position, osmium_undo_stack);
- });
- /* Osmium
- * Copyright (C) 2012, 2013, 2014, 2015 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- * Copyright (C) 2013 Josiah Boning <jboning@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* Whenever you change this script, update the information in about.php. */
- /*<<< require external //cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js >>>*/
- /*<<< require external /static-1/jquery.jsPlumb-1.6.0-min.js >>>*/
- /*<<< require external /static-1/rawdeflate.min.js >>>*/
- /*<<< require snippet settings >>>*/
- /*<<< require snippet mousetrap >>>*/
- /*<<< require snippet keyboard >>>*/
- /*<<< require snippet localstorage_fallback >>>*/
- /*<<< require snippet new_loadout-fattribs >>>*/
- /*<<< require snippet show_info >>>*/
- /*<<< require snippet context_menu >>>*/
- /*<<< require snippet formatted_attributes >>>*/
- /*<<< require snippet graph_common >>>*/
- /*<<< require snippet capacitor >>>*/
- /*<<< require snippet loadout_undo >>>*/
- osmium_user_initiated = false;
- osmium_user_initiated_stack = [];
- osmium_clfspinner = undefined;
- osmium_clfspinner_level = 0;
- osmium_must_send_clf = false;
- osmium_sending_clf = false;
- osmium_next_clf_opts = undefined;
- osmium_load_static_client_data = function(staticver, onsuccess) {
- var idx = 'osmium_static_client_data_' + staticver;
- var onsuccess2 = function(json) {
- osmium_groups = json.groups;
- osmium_types = json.groups.types;
- osmium_charges = json.charges;
- osmium_metagroups = json.metagroups;
- osmium_module_states = json.modulestates;
- osmium_module_state_names = json.modulestatenames;
- osmium_slot_types = json.slottypes;
- osmium_ship_slots = json.shipslots;
- osmium_chargedmg = json.chargedmg;
- osmium_targetclass = json.targetclass;
- osmium_damage_profiles = json.dmgprofiles;
- osmium_booster_side_effects = json.boostersideeffects;
- osmium_modes = json.modes;
- /* Module states as they are defined in the CLF specification */
- osmium_states = ['offline', 'online', 'active', 'overloaded'];
- return onsuccess(json);
- };
- try {
- for(var i = 0; i < staticver; ++i) {
- localStorage.removeItem('osmium_static_client_data_' + i);
- }
- var cdata = localStorage.getItem(idx);
- if(cdata !== null) {
- return onsuccess2(JSON.parse(cdata));
- }
- } catch(e) { /* Incognito mode probably */ }
- $.ajax({
- type: 'GET',
- url: osmium_relative + '/static-' + staticver + '/cache/clientdata.json',
- dataType: 'json',
- error: function(xhr, error, httperror) {
- if(xhr.readyState === 0 || xhr.status === 0) {
- /* User probably clicked cancel button or is closing
- * the page */
- return;
- }
- alert('Could not fetch static client data: ' + error + ' (' + httperror
- + '). Try refreshing the page and report if the problem persists.');
- },
- success: function(json) {
- try { localStorage.setItem(idx, JSON.stringify(json)); }
- catch(e) { /* Incognito mode probably */ }
- return onsuccess2(json);
- }
- });
- };
- osmium_user_initiated_push = function(value) {
- osmium_user_initiated_stack.push(osmium_user_initiated);
- osmium_user_initiated = value;
- };
- osmium_user_initiated_pop = function() {
- osmium_user_initiated = osmium_user_initiated_stack.pop();
- };
- osmium_register_keyboard_command(
- 'ctrl+l', 'regen-from-clf',
- 'Regenerate most DOM elements from the CLF.',
- function() {
- osmium_gen();
- return false;
- }
- );
- osmium_register_keyboard_command(
- null, 'debug-log-clf',
- 'Log the current CLF to the Javascript console.',
- function() {
- console.log(osmium_clf);
- console.log(JSON.stringify(osmium_clf));
- return false;
- }
- );
- /**
- * Synchronize the CLF with the server and update the attribute list,
- * etc. It is safe to call this function repeatedly in a short amount
- * of time, it has built-in rate limiting. Requires osmium_clftype and
- * to be set. Will call osmium_on_clf_payload if defined with the
- * payload as parameter. Will also call osmium_on_clftoken_change if
- * defined when the clf token changes, with the old and new tokens as
- * parameters.
- *
- * If specified, opts is an object which can contain any of the following properties:
- *
- * - params: send these additional params to process_clf
- * - before: function(), called before actually sending the CLF
- * - after: function(), called when process_clf is done
- * - success: function(payload), called when process_clf is done and didn't throw an error
- */
- osmium_commit_clf = function(opts) {
- osmium_must_send_clf = true;
- if(osmium_sending_clf) {
- if(opts !== undefined) {
- osmium_next_clf_opts = opts;
- }
- return;
- }
- osmium_sending_clf = true;
- osmium_send_clf(opts);
- };
- /** @internal */
- osmium_send_clf = function(opts) {
- if(!osmium_must_send_clf) {
- osmium_sending_clf = false;
- return;
- }
- osmium_must_send_clf = false;
- if(opts === undefined) {
- opts = osmium_next_clf_opts;
- osmium_next_clf_opts = undefined;
- }
- if(opts === undefined) {
- opts = {};
- }
- var postopts = $.extend({
- type: osmium_clftype,
- 'o___csrf': osmium_token,
- relative: osmium_relative,
- clf: osmium_compress_json(osmium_clf),
- clftoken: osmium_clftoken
- }, (("params" in opts) ? opts.params : {}));
- osmium_clfspinner_push();
- if("before" in opts) opts.before();
- $.ajax({
- type: 'POST',
- url: osmium_relative + '/internal/syncclf',
- data: postopts,
- dataType: 'json',
- complete: function() {
- osmium_clfspinner_pop();
- if("after" in opts) {
- opts.after();
- }
- },
- error: function(xhr, error, httperror) {
- if(xhr.readyState === 0 || xhr.status === 0) {
- return;
- }
- alert('Could not sync loadout with remote: ' + error + ' (' + httperror
- + '). This shouldn\'t normally happen, try again or refresh the page. Please report if the problem persists.');
- setTimeout(osmium_send_clf, 500);
- },
- success: function(payload) {
- if(osmium_clftoken !== payload.clftoken) {
- if(typeof(osmium_on_clf_token_change) === 'function') {
- osmium_on_clf_token_change(osmium_clftoken, payload.clftoken);
- }
- osmium_clftoken = payload.clftoken;
- }
- osmium_capacitors = payload.capacitors;
- osmium_ia = payload.ia;
- if("slots" in payload) osmium_clf_slots = payload.slots;
- if("hardpoints" in payload) osmium_clf_hardpoints = payload.hardpoints;
- osmium_update_slotcounts();
- for(var key in osmium_capacitors) {
- osmium_regen_remote_capacitor(key);
- }
- $("tr.error.clferror").removeClass('error').removeClass('clferror');
- $("tr.error_message.clferror").remove();
- $("p.error_box.clferror").remove();
- $(".clferror").removeClass('clferror');
- if("form-errors" in payload) {
- for(var i = 0; i < payload['form-errors'].length; ++i) {
- var err = payload['form-errors'][i];
- var tr = $(document.createElement('tr'));
- var td = $(document.createElement('td'));
- var p = $(document.createElement('p'));
- tr.addClass('error_message').addClass('clferror');
- td.attr('colspan', '2');
- p.text(err[2]);
- td.append(p);
- tr.append(td);
- $(err[1]).closest('tr').addClass('error').addClass('clferror').before(tr);
- if(err[0]) {
- $("a[href='#" + err[0] + "']").click();
- }
- }
- }
- if("p-errors" in payload) {
- for(var i = 0; i < payload['p-errors'].length; ++i) {
- var err = payload['p-errors'][i];
- var p = $(document.createElement('p'));
- p.addClass('error_box').addClass('clferror').text(err[2]);
- $(err[1]).before(p);
- if(err[0]) {
- $("a[href='#" + err[0] + "']").click();
- }
- }
- }
- $('div#computed_attributes').empty().append($(payload.attributes).children());
- osmium_clf_rawattribs = payload.rawattribs;
- osmium_gen_fattribs();
- osmium_init_fattribs();
- $("section#modules div.slots li.hasattribs, section#drones div.drones li.hasattribs")
- .removeClass('hasattribs')
- .children('small.attribs').remove()
- ;
- var s, el;
- for(var i = 0; i < osmium_ia.length; ++i) {
- if(!("fshort" in osmium_ia[i])) continue;
- s = $(document.createElement('small'));
- s.text(osmium_ia[i].fshort);
- if("flong" in osmium_ia[i]) {
- s.prop('title', osmium_ia[i].flong);
- }
- s.addClass('attribs');
- if(osmium_ia[i].location[0] === "module") {
- el = $("section#modules div.slots." + osmium_ia[i].location[1] + " li")
- .filter(function() {
- return $(this).data('index') == osmium_ia[i].location[2];
- });
- } else if(osmium_ia[i].location[0] === "drone") {
- el = $("section#drones div.drones.space li").filter(function() {
- return $(this).data('typeid') == osmium_ia[i].location[1];
- });
- } else {
- continue;
- }
- el.addClass('hasattribs').append(s);
- }
- $("section#modules div.slots li > span.charge.hasncycles").removeClass('hasncycles')
- .children('span.ncycles').remove();
- for(var i = 0; i < payload.ncycles.length; ++i) {
- var s = $(document.createElement('span'));
- s.text(payload.ncycles[i][2]);
- s.prop('title', 'Number of module cycles before having to reload');
- s.addClass('ncycles');
- $("section#modules div.slots." + payload.ncycles[i][0] + " li").filter(function() {
- return $(this).data('index') == payload.ncycles[i][1];
- }).children('span.charge').addClass('hasncycles').append(s);
- }
- osmium_highlight_missing_prereqs(payload.missingprereqs);
- $("section#drones small.bayusage").text(
- osmium_clf_rawattribs.dronecapacityused
- + ' / ' + osmium_clf_rawattribs.dronecapacity + ' m³'
- ).toggleClass(
- 'overflow',
- osmium_clf_rawattribs.dronecapacityused > osmium_clf_rawattribs.dronecapacity
- );
- $("section#drones small.bandwidth").text(
- osmium_clf_rawattribs.dronebandwidthused
- + ' / ' + osmium_clf_rawattribs.dronebandwidth + ' Mbps'
- ).toggleClass(
- 'overflow',
- osmium_clf_rawattribs.dronebandwidthused > osmium_clf_rawattribs.dronebandwidth
- );
- var ndrones = 0;
- var dp = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']];
- if("inspace" in dp) {
- for(var i = 0; i < dp.inspace.length; ++i) {
- ndrones += dp.inspace[i].quantity;
- }
- }
- $("section#drones small.maxdrones").text(
- ndrones + ' / ' + osmium_clf_rawattribs.maxactivedrones
- ).toggleClass(
- 'overflow',
- ndrones > osmium_clf_rawattribs.maxactivedrones
- );
- osmium_clf_rawattribs.activedrones = ndrones;
- if(typeof(osmium_on_clf_payload) === 'function') {
- osmium_on_clf_payload(payload);
- }
- if("success" in opts) opts.success(payload);
- setTimeout(osmium_send_clf, 500);
- }
- });
- };
- osmium_compress_json = function(json) {
- return btoa(RawDeflate.deflate(
- JSON.stringify(json).replace(/[\u007F-\uFFFF]/g, function(m) {
- /* Thanks to Jason S. for this neat code, see
- * http://stackoverflow.com/a/4901205/615776 */
- return "\\u" + ('0000' + m.charCodeAt(0).toString(16)).slice(-4);
- })
- ));
- };
- osmium_clfspinner_push = function() {
- if(osmium_clfspinner_level === 0) {
- if(osmium_clfspinner === undefined) {
- osmium_clfspinner = $(document.createElement('span'))
- .prop('id', 'clfspinner')
- .hide()
- ;
- osmium_clfspinner
- .append($(document.createElement('span')).addClass('spinner'))
- .append(' Osmium is thinking!')
- ;
- $('body').append(osmium_clfspinner);
- }
- osmium_clfspinner.fadeIn(100);
- }
- ++osmium_clfspinner_level;
- };
- osmium_clfspinner_pop = function() {
- --osmium_clfspinner_level;
- if(osmium_clfspinner_level === 0) {
- osmium_clfspinner.fadeOut(1000);
- }
- };
- osmium_load_common_data = function() {
- var d = $("div#osmium-data");
- osmium_cdatastaticver = d.data('cdatastaticver');
- osmium_staticver = d.data('staticver');
- osmium_relative = d.data('relative');
- osmium_token = d.data('token');
- osmium_clftoken = d.data('clftoken');
- osmium_clf = d.data('clf');
- osmium_custom_damage_profiles = d.data('customdamageprofiles');
- osmium_skillsets = d.data('skillsets');
- };
- osmium_highlight_missing_prereqs = function(missingprereqs) {
- $("section#modules div.slots > ul > li, section#drones div.drones > ul > li, section#implants div.implants > ul > li").each(function() {
- var li = $(this);
- var s = li.children('span.name');
- if(li.data('typeid') in missingprereqs) {
- s.addClass('missingskill');
- } else {
- s.removeClass('missingskill');
- }
- if(!li.hasClass('hascharge')) return;
- s = li.children('span.charge').children('span.name');
- if(li.data('chargetypeid') in missingprereqs) {
- s.addClass('missingskill');
- } else {
- s.removeClass('missingskill');
- }
- });
- if("ship" in osmium_clf && "typeid" in osmium_clf.ship) {
- var s = $("section#ship h1 > strong > span.name")
- if(osmium_clf.ship.typeid in missingprereqs) {
- s.addClass('missingskill');
- } else {
- s.removeClass('missingskill');
- }
- }
- };
- /* Osmium
- * Copyright (C) 2013 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_append_loadoutid_uri = function(append) {
- var public_re = /\/loadout\/([1-9][0-9]*)([^?#\/]*)/;
- var private_re = /\/loadout\/private\/([1-9][0-9]*)([^?#\/]*)/;
- var m;
- window.location.hash = '';
- if((m = window.location.href.match(public_re)) !== null) {
- window.location.replace(window.location.href.replace(public_re, "/loadout/$1" + append));
- } else if((m = window.location.href.match(private_re)) !== null) {
- window.location.replace(window.location.href.replace(private_re, "/loadout/private/$1" + append));
- }
- };
- osmium_init_presets = function() {
- /* TODO: don't make a page reload, instead replace the URI with
- * the history API and get the new formatted preset descriptions
- * from the CLF update payload, and correctly set the preset
- * descriptions in osmium_gen_presets() */
- $('section#presets select#spreset').change(function() {
- osmium_append_loadoutid_uri('P' + $(this).val() + 'D' + osmium_clf['X-Osmium-current-dronepresetid']);
- });
- $('section#presets select#scpreset').change(function() {
- osmium_append_loadoutid_uri(
- 'P' + osmium_clf['X-Osmium-current-presetid']
- + 'C' + $(this).val()
- + 'D' + osmium_clf['X-Osmium-current-dronepresetid']
- );
- });
- $('section#presets select#sdpreset').change(function() {
- osmium_append_loadoutid_uri('P' + osmium_clf['X-Osmium-current-presetid'] + 'D' + $(this).val());
- });
- };
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_control = function() {
- var submit = $("section#control input#submit_loadout");
- if(!submit.hasClass('force')) {
- submit
- .prop('disabled', 'disabled')
- .prop('title', 'Select a ship before submitting your loadout.')
- ;
- }
- if(!("metadata" in osmium_clf)) return;
- if(!("X-Osmium-update-reason" in osmium_clf.metadata)) return;
- $("section#control input#ureason").val(osmium_clf.metadata['X-Osmium-update-reason']);
- };
- osmium_init_control = function() {
- $("section#control form").submit(function() {
- return false;
- });
- var lockcontrol = function() {
- var s = $("section#control");
- s.find('input, select').prop('disabled', true);
- s.append($(document.createElement('span')).addClass('spinner'));
- };
- var unlockcontrol = function() {
- var s = $("section#control");
- s.find('input, select').prop('disabled', false);
- s.find('span.spinner').remove();
- };
- $("section#control input#export_loadout").click(function() {
- var b = $(this);
- var exporttype = $("section#control select#export_type").val();
- osmium_commit_clf({
- params: {
- 'export': true,
- 'exportfmt': exporttype
- },
- success: function(payload) {
- osmium_modal_rotextarea('Exported loadout (' + exporttype + ')', payload['export-payload']);
- },
- before: lockcontrol,
- after: unlockcontrol,
- });
- });
- $("section#control input#submit_loadout").click(function() {
- var b = $(this);
- osmium_commit_clf({
- params: {
- submit: true,
- },
- success: function(payload) {
- if("submit-error" in payload) {
- alert(payload['submit-error']);
- } else if("submit-loadout-uri" in payload) {
- window.location.replace(payload['submit-loadout-uri']);
- }
- },
- before: lockcontrol,
- after: unlockcontrol,
- });
- });
- $("section#control input#ureason").change(function() {
- if(!("metadata" in osmium_clf)) {
- osmium_clf.metadata = {};
- }
- osmium_clf.metadata['X-Osmium-update-reason'] = $("section#control input#ureason").val();
- osmium_commit_clf();
- osmium_undo_push();
- });
- };
- osmium_loadout_can_be_submitted = function() {
- var submit = $("section#control input#submit_loadout");
- if(!submit.hasClass('force')) {
- submit
- .removeProp('disabled')
- .prop('title', '')
- ;
- }
- };
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*<<< require snippet new_loadout-control >>>*/
- osmium_gen_ship = function() {
- var section = $('section#ship');
- var p = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']];
- var img, h, small, shipname, groupname;
- if("ship" in osmium_clf && "typeid" in osmium_clf.ship) {
- groupname = osmium_types[osmium_clf.ship.typeid][5];
- shipname = osmium_types[osmium_clf.ship.typeid][1];
- img = $(document.createElement('img'));
- img.prop('src', '//image.eveonline.com/Render/' + osmium_clf.ship.typeid + '_256.png');
- osmium_loadout_can_be_submitted();
- var availslots = osmium_ship_slots[osmium_clf.ship.typeid];
- osmium_clf_slots = {
- high: availslots[0],
- medium: availslots[1],
- low: availslots[2],
- rig: availslots[3],
- subsystem: availslots[4]
- };
- osmium_clf_hardpoints = {
- turret: 0,
- launcher: 0
- };
- } else {
- groupname = '';
- shipname = '「No ship selected」';
- img = $(document.createElement('div'));
- img.addClass('notype');
- osmium_clf_slots = {
- high: 8,
- medium: 8,
- low: 8,
- rig: 3,
- subsystem: 5
- };
- osmium_clf_hardpoints = {
- turret: 0,
- launcher: 0
- };
- }
- h = $(document.createElement('h1'));
- h.append(img);
- small = $(document.createElement('small')).addClass('groupname').text(groupname);
- if(('X-mode' in p) && ('typeid' in p['X-mode'])) {
- small.append(' (' + osmium_modes[osmium_clf.ship.typeid][p['X-mode'].typeid] + ')');
- }
- h.append(small);
- h.append($(document.createElement('strong')).append(
- $(document.createElement('span')).addClass('name').text(shipname)
- ).prop('title', shipname));
- section.children('h1').remove();
- section.append(h);
- };
- osmium_init_ship = function() {
- osmium_ctxmenu_bind($("section#ship"), function() {
- var menu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(menu, "Undo (C-z)", function() {
- osmium_undo_pop();
- osmium_commit_clf();
- osmium_user_initiated_push(false);
- osmium_gen();
- osmium_user_initiated_pop();
- }, { icon: [ 1, 13, 64, 64 ] });
- osmium_ctxmenu_add_separator(menu);
- if("ship" in osmium_clf && "typeid" in osmium_clf.ship
- && osmium_clf.ship.typeid in osmium_modes) {
- var p = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']];
- var mtid = ('X-mode' in p) && ('typeid' in p['X-mode']) ? p['X-mode'].typeid : 0;
- osmium_ctxmenu_add_subctxmenu(menu, 'Ship modes', function() {
- var smenu = osmium_ctxmenu_create();
- var modes = osmium_modes[osmium_clf.ship.typeid];
- for(var t in modes) {
- osmium_ctxmenu_add_option(smenu, modes[t], (function(t) {
- return function() {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]['X-mode'] = { typeid: t };
- osmium_gen_ship();
- osmium_undo_push();
- osmium_commit_clf();
- };
- })(t), { toggled: t == mtid });
- }
- return smenu;
- }, {});
- }
- osmium_ctxmenu_add_subctxmenu(menu, "Reload times", function() {
- var smenu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(smenu, "Include in capacitor time", function() {
- osmium_clf.metadata['X-Osmium-capreloadtime'] = !osmium_clf.metadata['X-Osmium-capreloadtime'];
- osmium_undo_push();
- osmium_commit_clf();
- }, { toggled: osmium_clf.metadata['X-Osmium-capreloadtime'] });
- osmium_ctxmenu_add_option(smenu, "Include in DPS", function() {
- osmium_clf.metadata['X-Osmium-dpsreloadtime'] = !osmium_clf.metadata['X-Osmium-dpsreloadtime'];
- osmium_undo_push();
- osmium_commit_clf();
- }, { toggled: osmium_clf.metadata['X-Osmium-dpsreloadtime'] });
- osmium_ctxmenu_add_option(smenu, "Include in sustained tank", function() {
- osmium_clf.metadata['X-Osmium-tankreloadtime'] = !osmium_clf.metadata['X-Osmium-tankreloadtime'];
- osmium_undo_push();
- osmium_commit_clf();
- }, { toggled: osmium_clf.metadata['X-Osmium-tankreloadtime'] });
- return smenu;
- }, {});
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "DPS graphs…", function() {
- var hdr = $(document.createElement('header')).append(
- $(document.createElement('h2')).text('Damage per second graph ')
- .append($(document.createElement('a'))
- .text('(compare and tweak…)')
- .prop('href', osmium_relative + '/compare/dps/s,0,'
- + encodeURIComponent(window.location.href)
- + ',' + encodeURIComponent(osmium_clf.metadata.title)))
- );
- var form = $(document.createElement('form'))
- .prop('id', 'm-dpsg');
- var table = $(document.createElement('table'));
- var tbody = $(document.createElement('tbody'));
- var tr = $(document.createElement('tr'));
- tbody.append(tr);
- table.append(tbody);
- form.append(table);
- var td, label, input;
- td = $(document.createElement('td')).addClass('signatureradius');
- label = $(document.createElement('label'))
- .prop('for', 'm-dpsg-signatureradius')
- .text('Target signature radius: ')
- ;
- input = $(document.createElement('input'))
- .prop('type', 'text')
- .prop('id', 'm-dpsg-signatureradius')
- ;
- td.append([ label, input, " m" ]);
- tr.append(td);
- td = $(document.createElement('td')).addClass('velocity');
- label = $(document.createElement('label'))
- .prop('for', 'm-dpsg-velocity')
- .text('Target velocity: ')
- ;
- input = $(document.createElement('input'))
- .prop('type', 'text')
- .prop('id', 'm-dpsg-velocity')
- ;
- td.append([ label, input, " m/s" ]);
- tr.append(td);
- td = $(document.createElement('td')).addClass('distance');
- label = $(document.createElement('label'))
- .prop('for', 'm-dpsg-distance')
- .text('Target distance: ')
- ;
- input = $(document.createElement('input'))
- .prop('type', 'text')
- .prop('id', 'm-dpsg-distance')
- ;
- td.append([ label, input, " km" ]);
- tr.append(td);
- td = $(document.createElement('td'));
- input = $(document.createElement('input'))
- .prop('type', 'submit')
- .val('Generate graph')
- ;
- td.append(input);
- tr.append(td);
- var ctx = $(document.createElement('div')).prop('id', 'm-dpsg-ctx');
- form.on('submit', function(e) {
- e.preventDefault();
- var tsr, tv, td;
- tsr = parseFloat(form.find('td.signatureradius input').val());
- tv = parseFloat(form.find('td.velocity input').val());
- td = parseFloat(form.find('td.distance input').val());
- var nans = 0;
- if(isNaN(tsr)) ++nans;
- if(isNaN(tv)) ++nans;
- if(isNaN(td)) ++nans;
- if(nans !== 1 && nans !== 2) {
- alert('You must fill exactly one or two fields with number values.');
- return false;
- }
- ctx.empty();
- if(nans === 1) {
- var genfunc, xlabel, xmax;
- var limits = osmium_probe_boundaries_from_ia(osmium_ia, tsr, tv, td);
- if(isNaN(tsr)) {
- genfunc = function(x) { return [ x, tv, td ]; };
- xlabel = "Target signature radius (m)";
- xmax = limits[0];
- } else if(isNaN(tv)) {
- genfunc = function(x) { return [ tsr, x, td ]; };
- xlabel = "Target velocity (m/s)";
- xmax = limits[1];
- } else if(isNaN(td)) {
- genfunc = function(x) { return [ tsr, tv, x ]; };
- xlabel = "Target distance (km)";
- xmax = limits[2];
- }
- osmium_draw_dps_graph_1d(
- { foo: { ia: osmium_ia } },
- { foo: "hsl(0, 100%, 50%)" },
- ctx, xlabel, 0, xmax, genfunc,
- 0, null
- );
- } else if(nans === 2) {
- var genfunc, xlabel, ylabel, xmax, ymax, b;
- b = osmium_probe_boundaries_from_ia(osmium_ia, tsr, tv, td);
- if(!isNaN(tsr)) {
- genfunc = function(x, y) { return [ tsr, y, x ]; };
- ylabel = "Target velocity (m/s)";
- xlabel = "Target distance (km)";
- ymax = b[1]; xmax = b[2];
- } else if(!isNaN(tv)) {
- genfunc = function(x, y) { return [ y, tv, x ]; };
- ylabel = "Target signature radius (m)";
- xlabel = "Target distance (km)";
- ymax = b[0]; xmax = b[2];
- } else if(!isNaN(td)) {
- genfunc = function(x, y) { return [ y, x, td ]; };
- ylabel = "Target signature radius (m)";
- xlabel = "Target velocity (m/s)";
- ymax = b[0]; xmax = b[1];
- }
- var maxdps = osmium_draw_dps_graph_2d(
- { foo: { ia: osmium_ia } },
- function(fracs, cmap) {
- for(var k in fracs) {
- return osmium_heat_color(fracs[k][0] / fracs[k][1]);
- }
- return osmium_heat_color(0);
- },
- ctx,
- xlabel, 0, xmax,
- ylabel, 0, ymax,
- genfunc,
- 4
- );
- osmium_draw_dps_legend(ctx, maxdps, osmium_heat_color);
- }
- return false;
- });
- var limits = osmium_probe_boundaries_from_ia(osmium_ia, NaN, NaN, NaN);
- form.find('td.signatureradius input').val(Math.round(limits[0] / 3).toString());
- osmium_modal([ hdr, form, ctx ]);
- form.trigger('submit');
- }, {});
- if("ship" in osmium_clf && "typeid" in osmium_clf.ship) {
- osmium_ctxmenu_add_separator(menu);
- if(!osmium_loadout_readonly) {
- osmium_add_generic_browse(menu, osmium_clf.ship.typeid);
- }
- osmium_ctxmenu_add_option(menu, "Show ship info", function() {
- osmium_showinfo({ type: "ship" });
- }, { icon: osmium_showinfo_sprite_position, 'default': true });
- osmium_ctxmenu_add_option(menu, "Show IGB info", function() {
- osmium_showinfo_igb({ type: "ship" });
- }, { icon: osmium_showinfo_sprite_position, 'default': true });
- }
- return menu;
- });
- };
- /* Osmium
- * Copyright (C) 2012, 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_modules = function() {
- var p = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']];
- var cpid = osmium_clf['X-Osmium-current-chargepresetid'];
- var m, i, j, type, c, chargeid;
- var old_ias = {};
- var old_ncycles = {};
- $('section#modules > div.slots > ul > li.hasattribs > small.attribs').each(function() {
- var s = $(this);
- var li = s.parent();
- var typeid = li.data('typeid');
- var index = li.data('index');
- if(!(typeid in old_ias)) old_ias[typeid] = {};
- old_ias[typeid][index] = s.clone();
- });
- $('section#modules > div.slots > ul > li > span.charge > span.ncycles').each(function() {
- var s = $(this);
- var li = s.parent().parent();
- var typeid = li.data('typeid');
- var index = li.data('index');
- if(!(typeid in old_ncycles)) old_ncycles[typeid] = {};
- old_ncycles[typeid][index] = s.clone();
- });
- $('section#modules > div.slots > ul > li').not('.placeholder').remove();
- if(!("modules" in p)) p.modules = [];
- for(i = 0; i < p.modules.length; ++i) {
- m = p.modules[i];
- chargeid = null;
- if("charges" in m) {
- for(j = 0; j < m.charges.length; ++j) {
- if(!("cpid" in m.charges[j])) {
- m.charges[j].cpid = 0;
- }
- if(m.charges[j].cpid == cpid) {
- chargeid = m.charges[j].typeid;
- break;
- }
- }
- }
- var li = osmium_add_module(m.typeid, m.index, m.state, chargeid);
- if(m.typeid in old_ias && m.index in old_ias[m.typeid]) {
- li.addClass('hasattribs')
- .append(old_ias[m.typeid][m.index]);
- }
- if(m.typeid in old_ncycles && m.index in old_ncycles[m.typeid]) {
- li.children('span.charge')
- .addClass('hasncycles')
- .append(old_ncycles[m.typeid][m.index]);
- }
- }
- for(type in osmium_clf_slots) {
- $('section#modules > div.slots.' + type).data('type', type);
- }
- osmium_update_slotcounts();
- osmium_projected_regen_local();
- };
- osmium_init_modules = function() {
- $("section#modules > div.slots > h3 > span > small.groupcharges").on('click', function() {
- var t = $(this);
- var slotsdiv = t.parents("div.slots");
- if(slotsdiv.hasClass('grouped')) {
- slotsdiv.removeClass('grouped').addClass('ungrouped');
- t.text('Charges are not grouped');
- } else {
- slotsdiv.removeClass('ungrouped').addClass('grouped');
- t.text('Charges are grouped');
- }
- t.prop('title', t.text());
- }).each(function() {
- var t = $(this);
- t.prop('title', t.text());
- });
- if(osmium_loadout_readonly) return;
- $("section#modules > div.slots > ul").sortable({
- items: "li:not(.placeholder)",
- placeholder: "sortable-placeholder",
- start: function() {
- $("section#modules > div.slots").css('opacity', 0.5);
- $(this).addClass('sorting').parent().css('opacity', 1.0);
- },
- stop: function() {
- $("section#modules > div.slots").css('opacity', 1.0);
- $(this).removeClass('sorting');
- },
- update: function() {
- var z = 0;
- var map = {};
- $("section#modules > div.slots").find('li').each(function() {
- var t = $(this).data('typeid');
- var i = $(this).data('index');
- if(!t) return;
- if(!(t in map)) map[t] = {};
- map[t][i] = z;
- ++z;
- });
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules.sort(function(x, y) {
- return map[x.typeid][x.index] - map[y.typeid][y.index];
- });
- osmium_commit_clf();
- osmium_undo_push();
- }
- });
- };
- osmium_update_slotcounts = function() {
- $('section#modules > div.slots').each(function() {
- var t = $(this);
- osmium_update_overflow(t);
- osmium_maybe_hide_slot_type(t);
- });
- };
- osmium_maybe_hide_slot_type = function(slotsdiv) {
- if(slotsdiv.children('ul').find('li').length > 0) {
- slotsdiv.show();
- } else {
- slotsdiv.hide();
- }
- };
- osmium_update_overflow = function(slotsdiv) {
- var smallcount = slotsdiv.find('h3 > span > small.counts');
- var used = slotsdiv.children('ul').children('li').not('.placeholder').length;
- var total = osmium_clf_slots[slotsdiv.data('type')];
- smallcount.text(used + '/' + total);
- var placeholders = slotsdiv.find('li.placeholder').length;
- var ideal = total - used;
- while(placeholders < ideal) {
- osmium_add_placeholder_module(slotsdiv);
- ++placeholders;
- }
- while(placeholders > ideal) {
- slotsdiv.find('li.placeholder').last().remove();
- --placeholders;
- }
- if(used > total) {
- smallcount.addClass('overflow');
- slotsdiv.children('ul').children('li')
- .removeClass('overflow')
- .slice(total - used).addClass('overflow');
- } else {
- smallcount.removeClass('overflow');
- slotsdiv.children('ul').children('li.overflow').removeClass('overflow');
- }
- };
- osmium_add_module = function(typeid, index, state, chargeid) {
- var m = osmium_types[typeid];
- var div = $('section#modules > div.' + m[3]);
- var ul = div.children('ul');
- var placeholders = ul.children('li.placeholder');
- var li, img, a, stateimg;
- var stateful, hascharges;
- if(state === null) {
- if(osmium_module_states[typeid][2]) {
- /* Active state, if possible */
- state = osmium_states[2];
- } else if(osmium_module_states[typeid][1]) {
- /* Online state */
- state = osmium_states[1];
- } else {
- /* Offline state */
- state = osmium_states[0];
- }
- }
- li = $(document.createElement('li'));
- li.data('typeid', typeid);
- li.data('slottype', m[3]);
- li.data('index', index);
- li.data('state', state);
- li.append($(document.createElement('span')).addClass('name').text(m[1]));
- li.prop('title', m[1]);
- img = $(document.createElement('img'));
- img.prop('src', '//image.eveonline.com/Type/' + typeid + '_64.png');
- li.prepend(img);
- if(hascharges = (typeid in osmium_charges)) {
- li.on('remove_charge_nogroupcheck', function() {
- var span = li.children('span.charge');
- var charge = span.children('span.name');
- li.data('chargetypeid', null);
- span.children('img, span.mainsprite').replaceWith(
- osmium_sprite('', 0, 28, 32, 32, 32, 32)
- );
- charge.empty();
- charge.append($(document.createElement('em')).text('(No charge)'));
- var modules = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules;
- for(var i = 0; i < modules.length; ++i) {
- if(modules[i].index === index && modules[i].typeid === typeid) {
- /* Removing nonexistent charge */
- if(!("charges" in modules[i])) break;
- var charges = modules[i].charges;
- var curcpid = osmium_clf['X-Osmium-current-chargepresetid'];
- var cpid;
- for(var j = 0; j < charges.length; ++j) {
- if(!("cpid" in charges[j])) {
- cpid = 0; /* The spec says a value of 0 must be assumed */
- } else {
- cpid = charges[j].cpid;
- }
- if(curcpid == cpid) {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges.splice(j, 1);
- break;
- }
- }
- break;
- }
- }
- }).on('remove_charge', function() {
- if(li.parents('div.slots').hasClass('grouped')) {
- li.parents('div.slots').find('li.hascharge').filter(function() {
- var t = $(this);
- return t.data('typeid') === li.data('typeid')
- && t.data('chargetypeid') === li.data('chargetypeid');
- }).trigger('remove_charge_nogroupcheck');
- } else {
- li.trigger('remove_charge_nogroupcheck');
- }
- });
- var charge = $(document.createElement('span'));
- charge.addClass('charge');
- charge.text(',').append($(document.createElement('br')));
- charge.append($(document.createElement('img')).prop('alt', ''));
- charge.append($(document.createElement('span')).addClass('name'));
- li.append(charge);
- li.addClass('hascharge');
- if(chargeid === null) {
- li.trigger('remove_charge_nogroupcheck');
- } else {
- osmium_add_charge(li, chargeid);
- }
- if(!osmium_loadout_readonly) {
- charge.on('dblclick', function(e) {
- /* When dblclicking the charge, remove the charge but not the module */
- li.trigger('remove_charge');
- osmium_commit_clf();
- osmium_undo_push();
- e.stopPropagation();
- return false;
- });
- }
- }
- if(stateful = osmium_slot_types[m[3]][2]) {
- a = $(document.createElement('a'));
- stateimg = $(document.createElement('img'));
- a.addClass('toggle_state');
- stateimg.prop('alt', '');
- a.append(stateimg);
- li.append(a);
- li.on('state_changed', function() {
- var a = li.children('a.toggle_state');
- var s = osmium_module_state_names[li.data('state')];
- a.empty();
- a.append(osmium_sprite(
- s[0],
- s[1][0],
- s[1][1],
- s[1][2],
- s[1][3],
- 16, 16
- ));
- a.prop('title', s[0]);
- }).trigger('state_changed');
- a.on('click', function() {
- var a = $(this);
- var li = a.parent();
- var state = li.data('state');
- var nextstate;
- a.blur();
- if(state === 'offline') {
- nextstate = (osmium_module_states[typeid][1] ? 'online' : 'offline');
- } else if(state === 'online') {
- nextstate = (osmium_module_states[typeid][2] ? 'active' : 'offline');
- } else if(state === 'active') {
- nextstate = (osmium_module_states[typeid][3] ? 'overloaded' : 'offline');
- } else if(state === 'overloaded') {
- nextstate = 'offline';
- }
- osmium_set_module_state(li, nextstate);
- osmium_commit_clf();
- osmium_undo_push();
- return false;
- }).on('contextmenu', function() {
- var a = $(this);
- var li = a.parent();
- var state = li.data('state');
- var prevstate;
- a.blur();
- if(state === 'offline') {
- if(osmium_module_states[typeid][3]) {
- prevstate = 'overloaded';
- } else if(osmium_module_states[typeid][2]) {
- prevstate = 'active';
- } else if(osmium_module_states[typeid][1]) {
- prevstate = 'online';
- } else {
- prevstate = 'offline';
- }
- } else if(state === 'online') {
- prevstate = 'offline';
- } else if(state === 'active') {
- prevstate = 'online';
- } else if(state === 'overloaded') {
- prevstate = 'active';
- }
- osmium_set_module_state(li, prevstate);
- osmium_commit_clf();
- osmium_undo_push();
- return false;
- }).on('dblclick', function(e) {
- /* Prevent dblclick fire on the <li> itself */
- e.stopPropagation();
- return false;
- });
- }
- if(placeholders.length > 0) {
- placeholders.first().before(li);
- } else {
- ul.append(li);
- }
- if(osmium_user_initiated) {
- $('a[href="#modules"]').parent().click();
- }
- li.on('remove_module', function() {
- var modules = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules;
- var li = $(this);
- var slotsdiv = li.closest('div.slots');
- if(osmium_types[typeid][8] === 1) {
- osmium_user_initiated_push(false);
- var lis = $("section#projected div.pr-loadout.projected-local").find('li').filter(function() {
- var sli = $(this);
- return sli.data('typeid') === typeid && sli.data('index') === index;
- });
- if(lis.length !== 1) {
- alert('could not detach module – please report!');
- console.log(typeid, index, modules);
- return;
- }
- var fli = lis.first();
- jsPlumb.select({ source: fli }).detach();
- osmium_user_initiated_pop();
- }
- var found = false;
- for(var i = 0; i < modules.length; ++i) {
- if(modules[i].index === index && modules[i].typeid === typeid) {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules.splice(i, 1);
- found = true;
- break;
- }
- }
- if(!found) {
- alert('could not delete module in CLF – please report!');
- return;
- }
- li.remove();
- if(slotsdiv.find('li.overflow').length > 0) {
- slotsdiv.find('li.overflow').first().removeClass('overflow');
- } else {
- osmium_add_placeholder_module(slotsdiv);
- }
- if(osmium_types[typeid][8] === 1) {
- osmium_user_initiated_push(false);
- osmium_projected_regen_local();
- osmium_user_initiated_pop();
- }
- });
- osmium_ctxmenu_bind(li, function() {
- var menu = osmium_ctxmenu_create();
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Unfit module", function() {
- li.trigger('remove_module');
- osmium_commit_clf();
- osmium_undo_push();
- }, { 'default': true });
- osmium_ctxmenu_add_option(menu, "Unfit all of the same type", function() {
- li.parent().find('li').filter(function() {
- return $(this).data('typeid') === typeid
- }).trigger('remove_module');
- osmium_commit_clf();
- osmium_undo_push();
- osmium_update_slotcounts();
- }, {});
- osmium_ctxmenu_add_separator(menu);
- }
- if(hascharges) {
- osmium_ctxmenu_add_subctxmenu(menu, "Charges", function() {
- var chargemenu = osmium_ctxmenu_create();
- var charges_mg_pt = {}; /* metagroup -> parenttypeid -> chargetypeid */
- var charges_mg_pt_sorted = {}; /* metagroup -> [ [ parenttypeid, chargetypeids ], … ] */
- var mgcount = 0;
- var append_charges = function(menu, chargetypeids, showhelpers) {
- showhelpers = showhelpers & (
- chargetypeids.length >= 2 && (chargetypeids[0] in osmium_chargedmg)
- && osmium_chargedmg[chargetypeids[0]] > 0
- );
- if(showhelpers) {
- osmium_ctxmenu_add_option(menu, "More damage", function() {}, { enabled: false });
- osmium_ctxmenu_add_separator(menu);
- }
- for(var i = 0; i < chargetypeids.length; ++i) {
- osmium_ctxmenu_add_option(
- menu,
- osmium_types[chargetypeids[i]][1],
- (function(chargeid) {
- return function() {
- var modules = osmium_clf.presets[
- osmium_clf['X-Osmium-current-presetid']
- ].modules;
- for(var i = 0; i < modules.length; ++i) {
- if(modules[i].typeid === typeid && modules[i].index === index) {
- osmium_auto_add_charge_to_location(i, chargeid);
- osmium_commit_clf();
- osmium_undo_push();
- return;
- }
- }
- };
- })(chargetypeids[i]),
- { icon: "//image.eveonline.com/Type/" + chargetypeids[i] + "_64.png" }
- );
- }
- if(showhelpers) {
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Less damage", function() {}, { enabled: false });
- }
- };
- var pgroup = function(menu, charges_pt) {
- var showhelpers = charges_pt.length >= 2 && (charges_pt[0][1][0] in osmium_chargedmg)
- && osmium_chargedmg[charges_pt[0][1][0]] > 0;
- if(showhelpers) {
- osmium_ctxmenu_add_option(menu, "More damage", function() {}, { enabled: false });
- osmium_ctxmenu_add_separator(menu);
- }
- for(var z = 0; z < charges_pt.length; ++z) {
- if(charges_pt[z][1].length === 1) {
- append_charges(menu, charges_pt[z][1], false);
- } else {
- var c = osmium_types[charges_pt[z][0]];
- osmium_ctxmenu_add_subctxmenu(menu, c[1], (function(typeids) {
- return function() {
- var smenu = osmium_ctxmenu_create();
- append_charges(smenu, typeids, true);
- return smenu;
- };
- })(charges_pt[z][1]), {
- icon: "//image.eveonline.com/Type/" + c[0] + "_64.png"
- });
- }
- }
- if(showhelpers) {
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Less damage", function() {}, { enabled: false });
- }
- };
- compare_damage = function(a, b) {
- var x = (a in osmium_chargedmg) ? osmium_chargedmg[a] : 0;
- var y = (b in osmium_chargedmg) ? osmium_chargedmg[b] : 0;
- return y < x ? -1 : (y > x ? 1 : 0);
- };
- for(var i = 0; i < osmium_charges[typeid].length; ++i) {
- var t = osmium_types[osmium_charges[typeid][i]];
- var parent = t[7] > 0 ? t[7] : t[0];
- if(!(t[4] in charges_mg_pt)) {
- charges_mg_pt[t[4]] = {};
- charges_mg_pt_sorted[t[4]] = {};
- ++mgcount;
- }
- if(!(parent in charges_mg_pt[t[4]])) {
- charges_mg_pt[t[4]][parent] = [];
- }
- charges_mg_pt[t[4]][parent].push(t[0]);
- }
- for(var mg in charges_mg_pt) {
- var arr = [];
- for(var pt in charges_mg_pt[mg]) {
- charges_mg_pt[mg][pt].sort(compare_damage);
- arr.push([ pt, charges_mg_pt[mg][pt] ]);
- }
- arr.sort(function(a, b) {
- return compare_damage(a[1][0], b[1][0]);
- });
- charges_mg_pt_sorted[mg] = arr;
- }
- if(mgcount === 1) {
- for(var g in charges_mg_pt_sorted) {
- pgroup(chargemenu, charges_mg_pt_sorted[g]);
- }
- } else {
- for(var g in charges_mg_pt_sorted) {
- osmium_ctxmenu_add_subctxmenu(chargemenu, osmium_metagroups[g], (function(group) {
- return function() {
- var submenu = osmium_ctxmenu_create();
- pgroup(submenu, group);
- return submenu;
- };
- })(charges_mg_pt_sorted[g]), {
- icon: "//image.eveonline.com/Type/" + charges_mg_pt_sorted[g][0][0] + "_64.png"
- });
- }
- }
- return chargemenu;
- }, { icon: "//image.eveonline.com/Type/" + osmium_charges[typeid][0] + "_64.png" });
- osmium_ctxmenu_add_option(menu, "Remove charge", function() {
- li.trigger('remove_charge');
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: [ 0, 28, 32, 32 ] });
- osmium_ctxmenu_add_separator(menu);
- }
- if(stateful) {
- if(osmium_module_states[typeid][0]) {
- osmium_ctxmenu_add_option(menu, "Offline module", function() {
- osmium_set_module_state(li, "offline");
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: osmium_module_state_names['offline'][1] });
- }
- if(osmium_module_states[typeid][1]) {
- osmium_ctxmenu_add_option(menu, "Online module", function() {
- osmium_set_module_state(li, "online");
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: osmium_module_state_names['online'][1] });
- }
- if(osmium_module_states[typeid][2]) {
- osmium_ctxmenu_add_option(menu, "Activate module", function() {
- osmium_set_module_state(li, "active");
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: osmium_module_state_names['active'][1] });
- }
- if(osmium_module_states[typeid][3]) {
- osmium_ctxmenu_add_option(menu, "Toggle overload", function() {
- if(li.data('state') !== "overloaded") {
- osmium_set_module_state(li, "overloaded");
- } else {
- osmium_set_module_state(li, "active");
- }
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: osmium_module_state_names['overloaded'][1] });
- }
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Overload rack", function() {
- if(li.data('state') !== "overloaded") {
- li.closest('div.slots').find('li').each(function() {
- var t = $(this);
- var typeid = t.data('typeid');
- if(!(typeid in osmium_module_states)) return;
- if(osmium_module_states[typeid][3]) {
- osmium_set_module_state(t, "overloaded");
- }
- });
- } else {
- li.closest('div.slots').find('li').each(function() {
- var t = $(this);
- if(t.data('state') !== 'overloaded') return;
- osmium_set_module_state(t, "active");
- });
- }
- osmium_commit_clf();
- osmium_undo_push();
- }, { icon: osmium_module_state_names['overloaded'][1] });
- osmium_ctxmenu_add_separator(menu);
- }
- if(!osmium_loadout_readonly) {
- if(hascharges && li.data('chargetypeid') !== null) {
- osmium_ctxmenu_add_heading(menu, "Module");
- }
- osmium_add_generic_browse(menu, typeid);
- osmium_ctxmenu_add_option(menu, "Show module info", function() {
- osmium_showinfo({
- type: "module",
- slottype: li.data('slottype'),
- index: li.data('index')
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': osmium_loadout_readonly });
- if(hascharges && li.data('chargetypeid') !== null) {
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_heading(menu, "Charge");
- osmium_add_generic_browse(menu, li.data('chargetypeid'));
- osmium_ctxmenu_add_option(menu, "Show charge info", function() {
- osmium_showinfo({
- type: "charge",
- slottype: li.data('slottype'),
- index: li.data('index')
- });
- }, { icon: osmium_showinfo_sprite_position });
- }
- } else {
- osmium_ctxmenu_add_option(menu, "Show module info", function() {
- osmium_showinfo({
- type: "module",
- slottype: li.data('slottype'),
- index: li.data('index')
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': osmium_loadout_readonly });
- if(hascharges && li.data('chargetypeid') !== null) {
- osmium_ctxmenu_add_option(menu, "Show charge info", function() {
- osmium_showinfo({
- type: "charge",
- slottype: li.data('slottype'),
- index: li.data('index')
- });
- }, { icon: osmium_showinfo_sprite_position });
- }
- }
- return menu;
- });
- return li;
- };
- osmium_add_placeholder_module = function(slotsdiv) {
- var ul = slotsdiv.children('ul');
- var li;
- var type = slotsdiv.data('type');
- li = $(document.createElement('li'));
- li.addClass('placeholder');
- li.text('Unused ' + type + ' slot');
- li.prepend(osmium_sprite(
- '',
- osmium_slot_types[type][1][0],
- osmium_slot_types[type][1][1],
- osmium_slot_types[type][1][2],
- osmium_slot_types[type][1][3],
- 32, 32
- ));
- ul.append(li);
- };
- osmium_set_module_state = function(li, newstate) {
- var index = li.data('index');
- var typeid = li.data('typeid');
- li.data('state', newstate);
- var modules = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules;
- for(var i = 0; i < modules.length; ++i) {
- if(modules[i].index === index && modules[i].typeid === typeid) {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].state = newstate;
- break;
- }
- }
- li.trigger('state_changed');
- };
- osmium_add_charge = function(li, chargetypeid) {
- var span = li.children('span.charge');
- var img = $(document.createElement('img'));
- var charge = span.children('span.name');
- li.data('chargetypeid', chargetypeid);
- img.prop('src', '//image.eveonline.com/Type/' + chargetypeid + '_64.png');
- img.prop('alt', '');
- span.children('img, span.mainsprite').replaceWith(img);
- charge.empty();
- charge.text(osmium_types[chargetypeid][1]);
- charge.prop('title', osmium_types[chargetypeid][1]);
- };
- osmium_add_charge_by_location = function(locationtypeid, locationindex, chargetypeid) {
- var li = $('section#modules > div.slots li.hascharge').filter(function() {
- var t = $(this);
- return t.data('typeid') === locationtypeid && t.data('index') === locationindex;
- }).first();
- return osmium_add_charge(li, chargetypeid);
- };
- osmium_get_best_location_for_charge = function(typeid) {
- var location = null;
- var candidatelevel;
- for(var i = 0; i < osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules.length; ++i) {
- m = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules[i];
- var validcharge = false, currentchargeid = null;
- if(!(m.typeid in osmium_charges)) {
- /* Module can't accept charges */
- continue;
- }
- for(var j = 0; j < osmium_charges[m.typeid].length; ++j) {
- if(osmium_charges[m.typeid][j] === typeid) {
- validcharge = true;
- break;
- }
- }
- if(!validcharge) continue;
- if(location === null) {
- /* As a fallback, fit the charge to the first suitable location */
- location = i;
- candidatelevel = 0; /* This candidate is not very good */
- }
- if(!("charges" in m)) {
- /* The module has no charges and can accept the charge, perfect */
- location = i;
- break;
- }
- var charges = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges;
- var cpid;
- /* Check if charge already present */
- for(var j = 0; j < charges.length; ++j) {
- if("cpid" in charges[j]) {
- cpid = charges[j].cpid;
- } else {
- cpid = 0;
- }
- if(cpid == osmium_clf['X-Osmium-current-chargepresetid']) {
- currentchargeid = charges[j].typeid;
- break;
- }
- }
- if(currentchargeid === null) {
- /* The module has no charge in this preset and can accept the charge */
- location = i;
- break;
- } else if(currentchargeid !== typeid && candidatelevel < 1) {
- /* The module has a different charge, but it's still a
- * better candidate than the fallback */
- location = i;
- candidatelevel = 1;
- }
- }
- return location;
- };
- osmium_auto_add_charge_to_location = function(location, typeid) {
- var m = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location];
- var moduletypeid = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location].typeid;
- var moduletype = osmium_types[moduletypeid][3];
- var previouschargeid = null;
- if(!("charges" in m)) {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location].charges = [];
- }
- var charges = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location].charges;
- var cpid;
- /* Remove previous charge (if there is one) */
- for(var j = 0; j < charges.length; ++j) {
- if("cpid" in charges[j]) {
- cpid = charges[j].cpid;
- } else {
- cpid = 0;
- }
- if(cpid !== osmium_clf['X-Osmium-current-chargepresetid']) {
- continue;
- }
- previouschargeid = charges[j].typeid;
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location].charges.splice(j, 1);
- break;
- }
- /* Finally, add the new charge */
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[location].charges.push({
- typeid: typeid,
- cpid: osmium_clf['X-Osmium-current-chargepresetid']
- });
- osmium_add_charge_by_location(m.typeid, m.index, typeid);
- if($("section#modules > div.slots." + moduletype).hasClass('grouped')) {
- /* Also add this charge to identical modules with identical charges */
- var curchargeid;
- var curchargeidx;
- for(var i = 0; i < osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules.length; ++i) {
- curchargeid = null;
- curchargeidx = 0;
- m = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].modules[i];
- if(m.typeid !== moduletypeid) {
- continue;
- }
- if(!("charges" in m)) {
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges = [];
- }
- charges = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges;
- for(var j = 0; j < charges.length; ++j) {
- if("cpid" in charges[j]) {
- cpid = charges[j].cpid;
- } else {
- cpid = 0;
- }
- if(cpid !== osmium_clf['X-Osmium-current-chargepresetid']) {
- continue;
- }
- curchargeid = charges[j].typeid;
- curchargeidx = j;
- break;
- }
- if(curchargeid !== previouschargeid) {
- continue;
- }
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges.splice(curchargeidx, 1);
- osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .modules[i].charges.push({
- typeid: typeid,
- cpid: osmium_clf['X-Osmium-current-chargepresetid']
- });
- osmium_add_charge_by_location(m.typeid, m.index, typeid);
- }
- }
- };
- /* Osmium
- * Copyright (C) 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_drones = function() {
- var drones = {
- bay: {},
- space: {}
- };
- var old_ias = {};
- var dronep = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']];
- for(var p in dronep) {
- if(p !== 'inbay' && p !== 'inspace') continue;
- var map = (p === 'inbay') ? drones.bay : drones.space;
- for(var i = 0; i < dronep[p].length; ++i) {
- if(dronep[p][i].quantity == 0) continue;
- if(!(dronep[p][i].typeid in map)) {
- map[dronep[p][i].typeid] = 0;
- }
- map[dronep[p][i].typeid] += dronep[p][i].quantity;
- }
- }
- $('section#drones div.drones.space li.hasattribs > small.attribs').each(function() {
- var s = $(this);
- old_ias[s.parent().data('typeid')] = s.clone();
- });
- for(var p in drones) {
- var dronesdiv = $("section#drones div.drones." + p);
- var ul = dronesdiv.children('ul');
- ul.empty();
- for(var t in drones[p]) {
- var li = $(document.createElement('li'));
- var img = $(document.createElement('img'));
- var m = osmium_types[t];
- var qty = drones[p][t];
- var other = (p === 'bay') ? 'space' : 'bay';
- li.data('typeid', m[0]);
- li.data('location', p);
- li.data('quantity', qty);
- li.append($(document.createElement('span')).addClass('name').text(m[1]));
- li.prop('title', m[1]);
- li.prepend($(document.createElement('strong')).addClass('qty').text(qty + '×'));
- img.prop('src', '//image.eveonline.com/Type/' + t + '_64.png');
- img.prop('alt', '');
- li.prepend(img);
- if(t in old_ias) {
- li.append(old_ias[t]);
- }
- ul.append(li);
- osmium_ctxmenu_bind(li, (function(t, p, qty, other) {
- return function() {
- var menu = osmium_ctxmenu_create();
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Remove 1 drone", function() {
- osmium_remove_drone_from_clf(t, 1, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { 'default': true });
- if(qty > 5) {
- osmium_ctxmenu_add_option(menu, "Remove 5 drones", function() {
- osmium_remove_drone_from_clf(t, 5, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- }
- if(qty > 1) {
- osmium_ctxmenu_add_option(menu, "Remove " + qty + " drones", function() {
- osmium_remove_drone_from_clf(t, qty, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- }
- osmium_ctxmenu_add_separator(menu);
- }
- osmium_ctxmenu_add_option(menu, "Move 1 to " + other, function() {
- osmium_add_drone_to_clf(t, 1, other);
- osmium_remove_drone_from_clf(t, 1, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- if(qty > 5) {
- osmium_ctxmenu_add_option(menu, "Move 5 to " + other, function() {
- osmium_add_drone_to_clf(t, 5, other);
- osmium_remove_drone_from_clf(t, 5, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- }
- if(qty > 1) {
- osmium_ctxmenu_add_option(menu, "Move " + qty + " to " + other, function() {
- osmium_add_drone_to_clf(t, qty, other);
- osmium_remove_drone_from_clf(t, qty, p);
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- }
- osmium_ctxmenu_add_separator(menu);
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Clear all drones in " + p, function() {
- osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']]['in' + p] = [];
- osmium_gen_drones();
- osmium_undo_push();
- osmium_commit_clf();
- }, { });
- osmium_ctxmenu_add_separator(menu);
- }
- if(!osmium_loadout_readonly) {
- osmium_add_generic_browse(menu, t);
- }
- osmium_ctxmenu_add_option(menu, "Show drone info", function() {
- osmium_showinfo({
- type: "drone",
- typeid: t
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': osmium_loadout_readonly });
- return menu;
- };
- })(m[0], p, qty, other));
- }
- if(ul.children('li').length == 0) {
- /* Add placeholder entry */
- var li = $(document.createElement('li'));
- li.text('No drones in ' + p);
- li.addClass('placeholder');
- li.prepend(osmium_sprite('', 0, 13, 64, 64, 32, 32));
- ul.append(li);
- }
- }
- if(osmium_user_initiated) {
- $('a[href="#drones"]').parent().click();
- }
- };
- osmium_init_drones = function() {
- $("section#drones > div.drones > ul").sortable({
- items: "li:not(.placeholder)",
- placeholder: "sortable-placeholder",
- connectWith: "section#drones > div.drones > ul",
- remove: function(e, ui) {
- var d = ui.item;
- var t = d.data('typeid');
- var loc = d.data('location');
- var q = d.data('quantity');
- var drones = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']]['in' + loc];
- for(var i = 0; i < drones.length; ++i) {
- if(drones[i].typeid != t) continue;
- drones[i].quantity -= q;
- if(drones[i].quantity <= 0) {
- drones.splice(i, 1);
- }
- }
- },
- receive: function(e, ui) {
- var d = ui.item;
- var t = d.data('typeid');
- var loc = (d.data('location') === 'bay') ? 'space' : 'bay';
- var q = d.data('quantity');
- var dp = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']];
- var key = 'in' + loc;
- if(!(key in dp)) dp[key] = [];
- drones = dp[key];
- d.data('location', loc);
- for(var i = 0; i < drones.length; ++i) {
- if(drones[i].typeid != t) continue;
- drones[i].quantity += q;
- osmium_gen_drones();
- osmium_commit_clf();
- osmium_undo_push();
- return;
- }
- drones.push({
- typeid: t,
- quantity: q
- });
- osmium_gen_drones();
- osmium_commit_clf();
- osmium_undo_push();
- }
- });
- };
- osmium_remove_drone_from_clf = function(typeid, qty, location) {
- var dp = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']];
- dp = (location === 'space') ? dp.inspace : dp.inbay;
- var toremove = qty;
- for(var i = dp.length - 1; i >= 0; --i) {
- if(toremove == 0) break;
- if(dp[i].typeid != typeid) continue;
- if(dp[i].quantity > qty) {
- /* Easy case */
- dp[i].quantity -= qty;
- toremove = 0;
- break;
- } else {
- /* Annoying case */
- toremove -= dp[i].quantity;
- dp.splice(i, 1);
- }
- }
- };
- osmium_add_drone_to_clf = function(typeid, qty, location) {
- var dp = osmium_clf.drones[osmium_clf['X-Osmium-current-dronepresetid']];
- if(!("inspace" in dp)) dp.inspace = [];
- if(!("inbay" in dp)) dp.inbay = [];
- dp = (location === 'space') ? dp.inspace : dp.inbay;
- for(var i = 0; i < dp.length; ++i) {
- if(dp[i].typeid === typeid) {
- dp[i].quantity += qty;
- return;
- }
- }
- dp.push({
- typeid: typeid,
- quantity: qty
- });
- };
- /* Osmium
- * Copyright (C) 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_implants = function() {
- var p = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']];
- var i_ul = $("section#implants > div.implants > ul");
- var b_ul = $("section#implants > div.boosters > ul");
- i_ul.empty(); b_ul.empty();
- if('implants' in p && p.implants.length > 0) {
- p.implants.sort(function(x, y) {
- return parseInt(osmium_types[x.typeid][3], 10) - parseInt(osmium_types[y.typeid][3], 10);
- });
- for(var i = 0; i < p.implants.length; ++i) {
- var t = p.implants[i].typeid;
- var imp = osmium_types[t];
- var li = $(document.createElement('li'));
- var img = $(document.createElement('img'));
- var span = $(document.createElement('span'));
- img.prop('src', '//image.eveonline.com/Type/' + t + '_64.png');
- img.prop('alt', '');
- li.append($(document.createElement('span')).addClass('name').text(imp[1]));
- li.prop('title', imp[1]);
- li.prepend(img);
- span.text(', implant slot ' + imp[3]).addClass('slot');
- li.append(span);
- li.data('typeid', t);
- osmium_ctxmenu_bind(li, (function(li, t) {
- return function() {
- var menu = osmium_ctxmenu_create();
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Remove implant", function() {
- var p_imp = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].implants;
- for(var z = 0; z < p_imp.length; ++z) {
- if(t === p_imp[z].typeid) {
- var ul = li.parent();
- p_imp.splice(z, 1);
- osmium_undo_push();
- osmium_commit_clf();
- li.remove();
- if(ul.children('li').length === 0) {
- osmium_gen_implants();
- }
- break;
- }
- }
- }, { 'default': true });
- osmium_ctxmenu_add_separator(menu);
- osmium_add_generic_browse(menu, t);
- }
- osmium_ctxmenu_add_option(menu, "Show implant info", function() {
- osmium_showinfo({ type: 'implant', typeid: t });
- }, { icon: osmium_showinfo_sprite_position, "default": osmium_loadout_readonly });
- return menu;
- };
- })(li, t));
- i_ul.append(li);
- }
- } else {
- var li = $(document.createElement('li'));
- li.addClass('placeholder');
- li.text('No implants');
- i_ul.append(li);
- }
- if('boosters' in p && p.boosters.length > 0) {
- p.boosters.sort(function(x, y) {
- return parseInt(osmium_types[x.typeid][3], 10) - parseInt(osmium_types[y.typeid][3], 10);
- });
- for(var i = 0; i < p.boosters.length; ++i) {
- var t = p.boosters[i].typeid;
- var imp = osmium_types[t];
- var li = $(document.createElement('li'));
- var img = $(document.createElement('img'));
- var span = $(document.createElement('span'));
- img.prop('src', '//image.eveonline.com/Type/' + t + '_64.png');
- img.prop('alt', '');
- li.text(imp[1]);
- li.prop('title', imp[1]);
- li.prepend(img);
- span.text(', booster slot ' + imp[3]).addClass('slot');
- li.append(span);
- osmium_ctxmenu_bind(li, (function(li, t) {
- return function() {
- var menu = osmium_ctxmenu_create();
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Remove booster", function() {
- var p_bst = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']].boosters;
- for(var z = 0; z < p_bst.length; ++z) {
- if(t === p_bst[z].typeid) {
- var ul = li.parent();
- p_bst.splice(z, 1);
- osmium_undo_push();
- osmium_commit_clf();
- li.remove();
- if(ul.children('li').length === 0) {
- osmium_gen_implants();
- }
- break;
- }
- }
- }, { 'default': true });
- osmium_ctxmenu_add_separator(menu);
- }
- osmium_ctxmenu_add_subctxmenu(menu, "Side effects", function() {
- var smenu = osmium_ctxmenu_create();
- if(t in osmium_booster_side_effects) {
- for(var z = 0; z < osmium_booster_side_effects[t].length; ++z) {
- var effectid = osmium_booster_side_effects[t][z][0];
- var effectname = osmium_booster_side_effects[t][z][1];
- var clfbooster = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]
- .boosters;
- for(var k = 0; k < clfbooster.length; ++k) {
- if(clfbooster[k].typeid === t) {
- clfbooster = clfbooster[k];
- }
- }
- osmium_ctxmenu_add_option(
- smenu, osmium_format_penalty_effectname(effectname),
- (function(effectid, clfbooster) {
- return function() {
- if("X-sideeffects" in clfbooster) {
- var index = $.inArray(effectid, clfbooster['X-sideeffects']);
- if(index !== -1) {
- clfbooster['X-sideeffects'].splice(index, 1);
- } else {
- clfbooster['X-sideeffects'].push(effectid);
- }
- } else {
- clfbooster['X-sideeffects'] = [ effectid ];
- }
- osmium_undo_push();
- osmium_commit_clf();
- };
- })(effectid, clfbooster),
- {
- toggled: "X-sideeffects" in clfbooster
- && $.inArray(effectid, clfbooster['X-sideeffects']) !== -1
- }
- );
- }
- } else {
- osmium_ctxmenu_add_option(smenu, "No side effects", function() {}, { enabled: false });
- }
- return smenu;
- }, {});
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Show booster info", function() {
- osmium_showinfo({ type: 'implant', typeid: t });
- }, { icon: osmium_showinfo_sprite_position, "default": osmium_loadout_readonly });
- return menu;
- };
- })(li, t));
- b_ul.append(li);
- }
- } else {
- var li = $(document.createElement('li'));
- li.addClass('placeholder');
- li.text('No boosters');
- b_ul.append(li);
- }
- };
- osmium_init_implants = function() {
- };
- osmium_format_penalty_effectname = function(name) {
- var s = name.split(/([A-Z])/);
- var words = [];
- words.push(s.shift());
- while(s.length > 0) {
- words.push(s.shift() + s.shift());
- }
- if(words[0] === "booster") words.shift();
- var p = $.inArray("Penalty", words);
- if(p !== -1) words = words.slice(0, p);
- return words.join(" ");
- };
- /* Osmium
- * Copyright (C) 2015 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_beacons = function() {
- var ul = $("section#area > div > ul");
- var clfp = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']];
- ul.empty();
- if(!('X-beacons' in clfp) || clfp['X-beacons'].length === 0) {
- ul.append(
- $(document.createElement('li'))
- .addClass('placeholder')
- .text('No area effects')
- );
- return;
- }
- for(var i = 0; i < clfp['X-beacons'].length; ++i) {
- var btypeid = clfp['X-beacons'][i];
- var beacon = osmium_types[btypeid];
- var li;
- ul.append(
- li = $(document.createElement('li'))
- .prop('title', beacon[1])
- .append(
- $(document.createElement('img'))
- .prop('src', '//image.eveonline.com/Type/' + btypeid +'_64.png')
- .prop('alt', '')
- )
- .append(
- $(document.createElement('span'))
- .addClass('name')
- .text(beacon[1])
- )
- );
- osmium_ctxmenu_bind(li, (function(li, typeid) {
- return function() {
- var menu = osmium_ctxmenu_create();
- if(!osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Remove beacon", function() {
- var clfpb = osmium_clf.presets[osmium_clf['X-Osmium-current-presetid']]['X-beacons'];
- for(var z = 0; z < clfpb.length; ++z) {
- if(typeid === clfpb[z]) {
- var ul = li.parent();
- clfpb.splice(z, 1);
- osmium_undo_push();
- osmium_commit_clf();
- li.remove();
- if(ul.children('li').length === 0) {
- osmium_gen_beacons();
- }
- break;
- }
- }
- }, { 'default': true });
- osmium_ctxmenu_add_separator(menu);
- osmium_add_generic_browse(menu, typeid);
- }
- osmium_ctxmenu_add_option(menu, "Show beacon info", function() {
- osmium_showinfo({ type: 'beacon', typeid: typeid });
- }, { icon: osmium_showinfo_sprite_position, "default": osmium_loadout_readonly });
- return menu;
- };
- })(li, btypeid));
- }
- };
- osmium_init_beacons = function() {
- };
- /* Osmium
- * Copyright (C) 2013, 2014 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- osmium_gen_remote = function() {
- osmium_gen_fleet();
- osmium_gen_projected();
- };
- osmium_gen_fleet = function() {
- var selects = $("section#fleet select");
- selects.empty();
- for(var i = 0; i < osmium_skillsets.length; ++i) {
- selects.append(
- $(document.createElement('option'))
- .text(osmium_skillsets[i])
- .prop('value', osmium_skillsets[i])
- );
- }
- $("section#fleet").find('input, select')
- .not("[type='checkbox']").prop('disabled', true);
- if(!("X-Osmium-fleet" in osmium_clf)) {
- osmium_clf['X-Osmium-fleet'] = {};
- }
- for(var t in osmium_clf['X-Osmium-fleet']) {
- $("section#fleet select#" + t + "_skillset").val(osmium_clf['X-Osmium-fleet'][t].skillset);
- $("section#fleet input#" + t + "_fit").val(osmium_clf['X-Osmium-fleet'][t].fitting);
- $("section#fleet input#" + t + "_enabled").prop('checked', true).change();
- $("section#fleet").find("input, select").filter("." + t).prop('disabled', false);
- }
- };
- osmium_projected_clean = function() {
- jsPlumb.unbind();
- jsPlumb.doWhileSuspended(function() {
- jsPlumb.detachEveryConnection();
- jsPlumb.deleteEveryEndpoint();
- jsPlumb.unmakeEverySource();
- jsPlumb.unmakeEveryTarget();
- });
- }
- osmium_gen_projected = function() {
- jsPlumb.Defaults.Container = $("section#projected form#projected-list");
- jsPlumb.Defaults.Endpoints = [ "Blank", "Blank" ];
- osmium_projected_clean();
- jsPlumb.bind("connection", function(info) {
- var src = $(info.source), tgt = $(info.target);
- if(src.closest('div.pr-loadout').get(0) === tgt.get(0)) {
- /* Disallow self-projection. While libdogma can handle it
- * in theory, it doesn't make a lot of sense to allow it
- * since real dogma dosen't allow it. */
- jsPlumb.detach(info.connection);
- return;
- }
- /* A module can only target one entity at a time, so remove
- * other connections */
- jsPlumb.doWhileSuspended(function() {
- jsPlumb.select({ source: info.source }).each(function(conn) {
- if(conn !== info.connection) {
- jsPlumb.detach(conn);
- }
- });
- });
- /* Update the target in CLF */
- var tkey = tgt.data('key');
- var skey = src.closest('div.pr-loadout').data('key');
- var stid = src.data('typeid');
- var sidx = src.data('index');
- var clf;
- if(skey === 'local') {
- clf = osmium_clf;
- } else {
- clf = osmium_clf['X-Osmium-remote'][skey];
- }
- var m = clf.presets[clf['X-Osmium-current-presetid']].modules;
- for(var i = 0; i < m.length; ++i) {
- if(m[i].typeid === stid && m[i].index === sidx) {
- m[i]['X-Osmium-target'] = tkey;
- osmium_commit_undo_deferred();
- src.addClass('hastarget');
- src.append(
- $(document.createElement('div'))
- .addClass('bghue')
- .css('background-color', src.closest('div.pr-loadout').css('border-color'))
- );
- return;
- }
- }
- alert('Could not create connection in CLF – please report!');
- });
- jsPlumb.bind("connectionDetached", function(info) {
- var src = $(info.source);
- /* Delete the target in CLF */
- var skey = src.closest('div.pr-loadout').data('key');
- var stid = src.data('typeid');
- var sidx = src.data('index');
- var clf;
- if(skey === 'local') {
- clf = osmium_clf;
- } else {
- clf = osmium_clf['X-Osmium-remote'][skey];
- }
- var m = clf.presets[clf['X-Osmium-current-presetid']].modules;
- for(var i = 0; i < m.length; ++i) {
- if(m[i].typeid === stid && m[i].index === sidx) {
- m[i]['X-Osmium-target'] = false;
- osmium_commit_undo_deferred();
- src.children('div.bghue').remove();
- src.removeClass('hastarget');
- return;
- }
- }
- alert('Could not delete connection in CLF – please report!');
- console.log('connection not found in CLF', stid, sidx, m);
- });
- var list = $("section#projected form#projected-list");
- list.empty();
- var local = osmium_create_projected("local", osmium_clf, 0);
- list.append(local);
- if(!("X-Osmium-remote" in osmium_clf)) {
- osmium_clf['X-Osmium-remote'] = {};
- }
- var c = 0;
- var remotes = {};
- remotes.local = osmium_clf;
- for(var key in osmium_clf['X-Osmium-remote']) {
- var pfit = osmium_clf['X-Osmium-remote'][key];
- list.append(osmium_create_projected(key, pfit, ++c));
- remotes[key] = pfit;
- }
- for(var key in remotes) {
- var pclf = remotes[key];
- if(!("X-Osmium-current-presetid" in pclf)) continue;
- if(!("presets" in pclf)) continue;
- if(!(pclf['X-Osmium-current-presetid'] in pclf.presets)) continue;
- if(!("modules" in pclf.presets[pclf['X-Osmium-current-presetid']])) continue;
- var modules = pclf.presets[pclf['X-Osmium-current-presetid']].modules;
- for(var i = 0; i < modules.length; ++i) {
- var m = modules[i];
- if("X-Osmium-target" in m && m['X-Osmium-target'] !== false) {
- var source = $('section#projected div.pr-loadout.projected-' + key)
- .find('li').filter(function() {
- var li = $(this);
- return li.data('typeid') === m.typeid && li.data('index') === m.index
- }).first();
- var target = $('section#projected div.pr-loadout.projected-' + m['X-Osmium-target']);
- if(source.length !== 1) {
- alert('Could not find source from CLF connection, please report!');
- continue;
- }
- if(target.length !== 1) {
- alert('Could not find target from CLF connection, please report!');
- continue;
- }
- jsPlumb.connect({ source: source, target: target });
- }
- }
- }
- };
- osmium_init_remote = function() {
- osmium_init_fleet();
- osmium_init_projected();
- };
- osmium_init_fleet = function() {
- $("section#fleet").on('change', "input[type='checkbox']", function() {
- var c = $(this);
- var tr = c.closest('tr');
- var table = tr.closest('table');
- var type = tr.data('type');
- if(!("X-Osmium-fleet" in osmium_clf)) {
- osmium_clf['X-Osmium-fleet'] = {};
- }
- var fleet = osmium_clf['X-Osmium-fleet'];
- if(c.is(':checked')) {
- fleet[type] = {
- skillset: table.find('select#' + type + '_skillset').val(),
- fitting: table.find('input#' + type + '_fit').val()
- };
- table.find('input, select')
- .filter('.' + type).prop('disabled', false);
- } else {
- delete(fleet[type]);
- table.find('input, select')
- .filter('.' + type).not("[type='checkbox']")
- .prop('disabled', true);
- }
- if(osmium_user_initiated) {
- osmium_undo_push();
- osmium_commit_clf();
- }
- }).on('change', 'select', function() {
- var s = $(this);
- var tr = s.closest('tr');
- var table = tr.closest('table');
- var checkbox = table.find("input#" + tr.data('type') + "_enabled");
- if(!checkbox.is(':checked')) {
- return;
- }
- checkbox.trigger('change');
- }).on('click', 'input.set', function() {
- var s = $(this);
- var tr = s.closest('tr');
- var table = tr.closest('table');
- var checkbox = table.find("input#" + tr.data('type') + "_enabled");
- if(!checkbox.is(':checked')) {
- return;
- }
- checkbox.trigger('change');
- }).on('click', 'input.clear', function() {
- var s = $(this);
- var tr = s.closest('tr');
- var table = tr.closest('table');
- var checkbox = table.find("input#" + tr.data('type') + "_enabled");
- if(!checkbox.is(':checked')) {
- return;
- }
- table.find('input#' + tr.data('type') + '_fit').val('');
- checkbox.trigger('change');
- }).on('keypress', 'input.fit', function(e) {
- if(e.which != 13) return;
- e.preventDefault();
- var s = $(this);
- var tr = s.closest('tr');
- var table = tr.closest('table');
- var checkbox = table.find("input#" + tr.data('type') + "_enabled");
- if(!checkbox.is(':checked')) {
- return false;
- }
- checkbox.trigger('change');
- return false;
- });
- };
- osmium_add_projected = function(remotefit, target) {
- if(!("X-Osmium-remote" in osmium_clf)) {
- osmium_clf['X-Osmium-remote'] = {};
- }
- var key = 1;
- while((key + '') in osmium_clf['X-Osmium-remote']) ++key;
- key = key + '';
- osmium_clf['X-Osmium-remote'][key] = {
- fitting: '',
- skillset: 'All V'
- };
- var newproj = osmium_create_projected(
- key, { },
- $("section#projected > form#projected-list > div.pr-loadout").length
- );
- $("section#projected > form#projected-list").append(newproj);
- if(remotefit !== undefined) {
- osmium_clf['X-Osmium-remote'][key].fitting = remotefit;
- }
- if(remotefit !== undefined && target !== undefined) {
- var target = $("section#projected div.pr-loadout.projected-" + target);
- osmium_projected_regen_remote(key, function() {
- $("section#projected div.pr-loadout.projected-" + key).find('ul > li').each(function() {
- jsPlumb.connect({ source: $(this), target: target });
- });
- });
- } else {
- osmium_commit_undo_deferred();
- }
- return newproj;
- };
- osmium_init_projected = function() {
- if(!osmium_loadout_readonly) {
- $("section#projected input#createprojected").on('click', function() {
- osmium_add_projected('').trigger('dblclick');
- });
- }
- $("section#remote").on('made_visible', function() {
- osmium_regen_offsets();
- jsPlumb.repaintEverything();
- $("section#remote").off('made_visible');
- });
- $("section#projected input#projectedfstoggle").on('click', function() {
- var section = $("section#projected");
- var fs = section.hasClass('fs');
- $("body").scrollTop(0);
- section.animate({ opacity: 0 }, 250, function() {
- jsPlumb.doWhileSuspended(function() {
- jsPlumb.toggleDraggable(
- section.find('div.pr-loadout')
- .draggable("option", "disabled", fs)
- );
- section.toggleClass('fs');
- var exitfs = function() {
- $("section#projected input#projectedfstoggle").click();
- return false;
- };
- if(fs) {
- osmium_unregister_keyboard_command('exit-fullscreen-projected');
- $("div#fsbg").remove();
- } else {
- var bg = $(document.createElement('div'));
- bg.prop('id', 'fsbg');
- bg.click(exitfs);
- $("section#projected").prepend(bg);
- osmium_register_keyboard_command(
- 'esc', 'exit-fullscreen-projected', 'Exit fullscreen projected mode.', exitfs
- );
- }
- /* Swap fixed and draggable positions */
- $("section#projected div.pr-loadout").each(function() {
- var t = $(this);
- var otop = t.css('top');
- var oleft = t.css('left');
- t.css('top', t.data('top')).data('top', otop);
- t.css('left', t.data('left')).data('left', oleft);
- });
- osmium_regen_offsets();
- /* Auto-rearrange if necessary */
- var localtop = $("section#projected div.pr-loadout.projected-local").css('top');
- if(section.hasClass('fs') && (!localtop || localtop === 'auto' || localtop === '0px')) {
- if($("section#projected div.pr-loadout").length <= 8) {
- $("section#projected a#rearrange-circle").click();
- } else {
- $("section#projected a#rearrange-grid").click();
- }
- }
- });
- section.animate({ opacity: 1 }, 250);
- });
- });
- $("section#projected a#rearrange-circle").on('click', function() {
- var s = $("section#projected");
- var f = s.children("form#projected-list");
- var so = s.offset();
- var mx = ($(window).width() - so.left) / 2;
- var my = ($(window).height() - so.top) / 2;
- var m = Math.min(mx, my);
- var divs = f.find('div.pr-loadout');
- jsPlumb.doWhileSuspended(function() {
- divs.each(function() {
- var d = $(this);
- var angle = d.index() / divs.length * 2 * Math.PI;
- var w = d.width();
- var h = d.height();
- d.offset({
- left: (so.left + mx - (m - d.outerWidth() / 2 - 32) * Math.cos(angle) - w / 2).toFixed(0),
- top: (so.top + my - (m - d.outerHeight() / 2 - 32) * Math.sin(angle) - h / 2).toFixed(0)
- });
- });
- });
- });
- $("section#projected a#rearrange-grid").on('click', function() {
- var s = $("section#projected");
- var f = s.children("form#projected-list");
- var so = s.offset();
- var mx = ($(window).width() - so.left);
- var my = ($(window).height() - so.top - 30);
- var divs = f.find('div.pr-loadout');
- var maxw = 1, maxh = 1;
- var rows = 1, cols = 1;
- var cellw = 1, cellh = 1;
- divs.each(function() {
- var d = $(this);
- var w = d.outerWidth();
- var h = d.outerHeight();
- if(w > maxw) maxw = w;
- if(h > maxh) maxh = h;
- });
- /* Add some padding */
- maxw += 50;
- maxh += 50;
- var maxrows = Math.max(1, Math.floor(my / maxh));
- var maxcols = Math.max(1, Math.floor(mx / maxw));
- while((rows * cols) < divs.length) {
- if(cols < maxcols) {
- ++cols;
- }
- if((rows * cols) >= divs.length) break;
- ++rows;
- }
- if(rows <= maxrows) {
- /* Everything can fit */
- cellw = Math.floor(mx / cols);
- cellh = Math.floor(my / rows);
- } else {
- /* Not enough space, use vertical scrolling */
- cols = Math.max(1, Math.floor(mx / maxw));
- cellw = Math.floor(mx / cols);
- cellh = maxh;
- }
- jsPlumb.doWhileSuspended(function() {
- divs.each(function() {
- var d = $(this);
- var i = d.index();
- d.offset({
- left: (so.left + (i % cols) * cellw + 10 * Math.cos(7 * i)
- + cellw / 2 - d.width() / 2).toFixed(0),
- top: (so.top + 30 + Math.floor(i / cols) * cellh + 10 * Math.sin(7 * i)
- + cellh / 2 - d.height() / 2).toFixed(0)
- });
- });
- });
- });
- osmium_register_keyboard_command(null, 'debug-jsplumb-repaint', 'Call jsPlumb.repaintEverything().',
- function() {
- jsPlumb.repaintEverything();
- return false;
- });
- osmium_register_keyboard_command(
- null, 'debug-jsplumb-recalculate-offsets', 'Recalculate jsPlumb offsets of remotes.',
- function() {
- osmium_regen_offsets();
- }
- );
- };
- osmium_create_projected = function(key, clf, index) {
- var proj = $(document.createElement('div'));
- var ul = $(document.createElement('ul'));
- var angle;
- if(index === undefined) {
- angle = (360 * Math.random()).toFixed(0);
- } else if(index === 0) {
- angle = 0;
- } else {
- if(index < 1 || typeof index !== 'number') throw 'Invalid index parameter';
- var low = 1;
- var up = 2;
- while(!(low <= index && index < up)) {
- low = up;
- up = up + up;
- }
- angle = (360 * (2 * (index - low) + 1) / up).toFixed(0);
- }
- proj.data('hue', angle);
- proj.addClass('projected-' + key);
- proj.data('key', key);
- proj.addClass('pr-loadout');
- proj.css('border-color', 'hsl(' + angle + ', 25%, 50%)');
- proj.css('background-color', 'hsla(' + angle + ', 25%, 50%, 0.1)');
- proj.data('title', key === 'local' ? 'Local' : ('Remote #' + key));
- if("ship" in clf && "typeid" in clf.ship) {
- var img = $(document.createElement('img'));
- img.prop('alt', clf.ship.typename);
- img.prop('src', '//image.eveonline.com/Render/' + clf.ship.typeid + '_512.png');
- img.addClass('render');
- proj.append(img);
- proj.data('shiptypeid', clf.ship.typeid);
- proj.data('title', proj.data('title') + ': ' + osmium_types[clf.ship.typeid][1]);
- }
- if("presets" in clf && "X-Osmium-current-presetid" in clf
- && "modules" in clf.presets[clf['X-Osmium-current-presetid']]) {
- var p = clf.presets[clf['X-Osmium-current-presetid']].modules;
- var projectable = 0;
- var pindex = 0;
- for(var i = 0; i < p.length; ++i) {
- var t = osmium_types[p[i].typeid];
- if(t[8] !== 1) continue;
- ++projectable;
- }
- var size; /* Also diameter of the circle */
- if(projectable === 0) {
- size = 120;
- } else {
- size = 80 * Math.max(6, projectable) / Math.PI;
- }
- proj.css({
- width: size + 'px',
- height: size + 'px'
- });
- for(var i = 0; i < p.length; ++i) {
- var t = osmium_types[p[i].typeid];
- if(t[8] !== 1) continue;
- var source =
- $(document.createElement('li'))
- .data('typeid', p[i].typeid)
- .data('index', p[i].index)
- .append(
- $(document.createElement('img'))
- .prop('alt', t[1] + ' (#' + p[i].index + ')')
- .prop('title', t[1] + ' (#' + p[i].index + ')')
- .prop('src', '//image.eveonline.com/Type/' + t[0] + '_64.png')
- );
- var angle = (pindex / projectable) * 2 * Math.PI;
- var top = -size * .5 * Math.cos(angle) - 28;
- var left = size * .5 * Math.sin(angle) - 28
- source.css({ top: top + 'px', left: left + 'px' });
- osmium_ctxmenu_bind(source, (function(source, clfsource) {
- return function() {
- var menu = osmium_ctxmenu_create();
- var t = osmium_types[clfsource.typeid];
- osmium_ctxmenu_add_option(menu, t[1], function() {}, {
- enabled: false
- });
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_subctxmenu(menu, "Project on", function() {
- var smenu = osmium_ctxmenu_create();
- var ntargets = 0;
- $('section#projected div.pr-loadout').each(function() {
- var div = $(this);
- var tkey = div.data('key');
- if(tkey === key) return;
- ++ntargets;
- osmium_ctxmenu_add_option(smenu, div.data('title'), function() {
- jsPlumb.connect({
- source: source,
- target: div
- });
- }, {});
- });
- if(ntargets === 0) {
- osmium_ctxmenu_add_option(smenu, "No targets available", function() {}, {
- enabled: false
- });
- }
- return smenu;
- }, {});
- osmium_ctxmenu_add_option(menu, "Clear target", function() {
- jsPlumb.select({ source: source }).detach();
- }, { 'default': true });
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Show module info", function() {
- osmium_showinfo({
- remote: key,
- type: "module",
- slottype: osmium_types[source.data('typeid')][3],
- index: source.data('index')
- });
- }, { icon: osmium_showinfo_sprite_position });
- return menu;
- }
- })(source, p[i]));
- jsPlumb.makeSource(source, {
- anchor: [ 0.5, 0.5 ],
- paintStyle: { fillStyle: 'hsl(' + proj.data('hue') + ', 50%, 50%)' },
- connectorStyle: {
- strokeStyle: 'hsla(' + proj.data('hue') + ', 50%, 50%, 0.5)',
- lineWidth: 5
- }
- });
- ul.append(source);
- ++pindex;
- }
- }
- proj.append(ul);
- var cap = osmium_gen_capacitor(1000, 1000);
- proj.append(cap);
- osmium_regen_remote_capacitor(proj);
- jsPlumb.makeTarget(proj, {
- anchor: [ 0.5, 0.5 ],
- paintStyle: { fillStyle: 'hsl(' + proj.data('hue') + ', 50%, 50%)' }
- });
- jsPlumb.draggable(proj);
- if(!$("section#projected").hasClass('fs')) {
- jsPlumb.toggleDraggable(proj);
- }
- osmium_ctxmenu_bind(proj, function() {
- var menu = osmium_ctxmenu_create();
- osmium_ctxmenu_add_option(menu, proj.data('title'), function() {}, { enabled: false });
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_subctxmenu(menu, "Use skills", (function(key) {
- return function() {
- var smenu = osmium_ctxmenu_create();
- var clf = key === 'local' ? osmium_clf : osmium_clf['X-Osmium-remote'][key];
- for(var i = 0; i < osmium_skillsets.length; ++i) {
- osmium_ctxmenu_add_option(smenu, osmium_skillsets[i], (function(sname) {
- return function() {
- if(key === 'local') {
- clf.metadata['X-Osmium-skillset'] = sname;
- } else {
- clf.skillset = sname;
- }
- osmium_undo_push();
- osmium_commit_clf();
- };
- })(osmium_skillsets[i]), {
- toggled: (key === 'local' && clf.metadata['X-Osmium-skillset'] === osmium_skillsets[i])
- || (key !== 'local' && "skillset" in clf && clf.skillset === osmium_skillsets[i])
- });
- }
- return smenu;
- };
- })(proj.data('key')), { icon: "//image.eveonline.com/Type/3327_64.png" });
- if(proj.data('key') !== 'local') {
- osmium_ctxmenu_add_separator(menu);
- }
- if(proj.data('key') !== 'local' && !osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "Edit fitting…", (function(key) {
- return function() {
- var hdr = $(document.createElement('header'));
- hdr.append($(document.createElement('h2')).text(
- 'Edit remote loadout #' + key
- ));
- var form = $(document.createElement('form'));
- var tbody = $(document.createElement('tbody'));
- var input = $(document.createElement('input'))
- .prop('type', 'text')
- .prop('placeholder', 'Loadout URI, DNA string or gzclf:// data')
- .prop('name', 'm-remote-fitting')
- .prop('id', 'm-remote-fitting')
- ;
- if("X-Osmium-remote" in osmium_clf
- && key in osmium_clf['X-Osmium-remote']
- && 'fitting' in osmium_clf['X-Osmium-remote'][key]) {
- input.val(osmium_clf['X-Osmium-remote'][key].fitting);
- }
- tbody.append(
- $(document.createElement('tr'))
- .append(
- $(document.createElement('th'))
- .append(
- $(document.createElement('label'))
- .text('Fitting')
- .prop('for', 'm-remote-fitting')
- )
- )
- .append(
- $(document.createElement('td'))
- .append(input)
- )
- );
- var select = $(document.createElement('select'))
- .prop('name', 'm-remote-skillset')
- .prop('id', 'm-remote-skillset')
- .on('change', function() {
- osmium_clf['X-Osmium-remote'][key].skillset = $(this).val();
- osmium_undo_push();
- osmium_commit_clf();
- })
- ;
- for(var i = 0; i < osmium_skillsets.length; ++i) {
- select.append(
- $(document.createElement('option'))
- .text(osmium_skillsets[i])
- .prop('value', osmium_skillsets[i])
- );
- }
- if("X-Osmium-remote" in osmium_clf
- && key in osmium_clf['X-Osmium-remote']
- && 'skillset' in osmium_clf['X-Osmium-remote'][key]) {
- select.val(osmium_clf['X-Osmium-remote'][key].skillset);
- }
- tbody.append(
- $(document.createElement('tr'))
- .append(
- $(document.createElement('th'))
- .append(
- $(document.createElement('label'))
- .text('Skills')
- .prop('for', 'm-remote-skillset')
- )
- )
- .append(
- $(document.createElement('td'))
- .append(select)
- )
- );
- tbody.append(
- $(document.createElement('tr'))
- .append($(document.createElement('th')))
- .append(
- $(document.createElement('td'))
- .addClass('l')
- .append(
- $(document.createElement('input'))
- .prop('type', 'submit')
- .prop('value', 'Use fitting')
- )
- )
- );
- form
- .prop('id', 'm-remote')
- .append(
- $(document.createElement('table'))
- .append(tbody)
- )
- .on('submit', function(e) {
- e.preventDefault();
- var form = $(this);
- form.find('input, select').prop('disabled', true);
- form
- .find('input[type="submit"]')
- .after(
- $(document.createElement('span'))
- .addClass('spinner')
- )
- ;
- osmium_clf['X-Osmium-remote'][key].fitting =
- form.find('input#m-remote-fitting').val();
- osmium_clf['X-Osmium-remote'][key].skillset =
- form.find('select#m-remote-skillset').val();
- osmium_projected_regen_remote(key, function() {
- osmium_modal_clear();
- }, function(errors) {
- form.find('span.spinner').remove();
- form.find('input, select').prop('disabled', false);
- form.find('tr.error_message').remove();
- form.find('tr.error').removeClass('error');
- for(var i = 0; i < errors.length; ++i) {
- input.closest('tr').addClass('error').before(
- $(document.createElement('tr'))
- .addClass('error_message')
- .append(
- $(document.createElement('td'))
- .prop('colspan', '2')
- .append(
- $(document.createElement('p')).text(errors[i])
- )
- )
- );
- }
- });
- return false;
- })
- ;
- osmium_modal([ hdr, form ]);
- };
- })(key), { 'default': true });
- osmium_ctxmenu_add_option(menu, "Remove fitting", function() {
- jsPlumb.doWhileSuspended(function() {
- jsPlumb.detachAllConnections(proj);
- proj.find('ul > li').each(function() {
- jsPlumb.detachAllConnections($(this));
- });
- proj.remove();
- });
- delete osmium_clf['X-Osmium-remote'][key];
- osmium_commit_undo_deferred();
- }, {});
- }
- if(proj.data('key') !== 'local' && osmium_loadout_readonly) {
- osmium_ctxmenu_add_option(menu, "View fitting", function() {
- var loc = window.location.href.split("#")[0];
- var match = loc.match(/^(.+?)\/remote\/(.+)$/);
- if(match !== null) {
- var localkey;
- if(key.toString() === match[2]) {
- window.location.assign(match[1]);
- return;
- } else {
- localkey = key;
- }
- window.location.assign(match[1] + "/remote/" + encodeURIComponent(localkey));
- } else {
- window.location.assign(loc + '/remote/' + encodeURIComponent(key));
- }
- }, {});
- }
- if(proj.data('shiptypeid')) {
- /* No point allowing show ship info on shallow pools */
- osmium_ctxmenu_add_separator(menu);
- osmium_ctxmenu_add_option(menu, "Show ship info", function() {
- osmium_showinfo({
- remote: key,
- type: "ship"
- });
- }, { icon: osmium_showinfo_sprite_position, 'default': osmium_loadout_readonly });
- }
- return menu;
- });
- return proj;
- };
- osmium_projected_regen_local = function() {
- var oldlocal = $("section#projected div.projected-local");
- if(oldlocal.length === 0) return; /* Not yet generated, will be done later */
- var local = osmium_create_projected("local", osmium_clf, oldlocal.index());
- osmium_projected_replace_graceful(oldlocal, local);
- };
- osmium_projected_regen_remote = function(key, onsuccess, onerror) {
- var t = $("section#projected div.pr-loadout.projected-" + key);
- osmium_commit_clf({
- params: { "remoteclf": t.data('key') },
- success: function(payload) {
- if(!("remote-clf" in payload)) return;
- osmium_clf['X-Osmium-remote'][t.data("key")] = payload['remote-clf'];
- osmium_undo_push();
- osmium_projected_replace_graceful(
- t,
- osmium_create_projected(
- t.data('key'),
- osmium_clf['X-Osmium-remote'][t.data('key')],
- t.index()
- )
- );
- if('remote-errors' in payload) {
- if(typeof onerror === 'function') onerror(payload['remote-errors']);
- } else {
- if(typeof onsuccess === 'function') onsuccess(payload);
- }
- }
- });
- };
- osmium_projected_replace_graceful = function(stale, fresh) {
- var cssprops = [ "left", "top", "right", "bottom" ];
- for(var i = 0; i < cssprops.length; ++i) {
- fresh.css(cssprops[i], stale.css(cssprops[i]));
- }
- jsPlumb.doWhileSuspended(function() {
- var newconnections = [];
- osmium_user_initiated_push(false);
- /* Keep all incoming projections */
- jsPlumb.select({
- target: stale
- }).each(function(conn) {
- var source = conn.source;
- jsPlumb.detach(conn);
- newconnections.push({
- source: source,
- target: fresh
- });
- });
- osmium_user_initiated_pop();
- osmium_user_initiated_push(false);
- /* Keep outgoing projections if modules match */
- stale.find('ul > li').each(function() {
- var source = $(this);
- var newsource = fresh.find('ul > li').filter(function() {
- var t = $(this);
- return t.data('typeid') == source.data('typeid') && t.data('index') == source.data('index');
- }).first();
- var connections = jsPlumb.select({
- source: source
- });
- if(newsource.length === 1) {
- /* Found a matching module, transfer all connections to it */
- connections.each(function(conn) {
- var target = conn.target;
- jsPlumb.detach(conn);
- newconnections.push({
- source: newsource,
- target: target
- });
- });
- } else {
- /* Drop connections */
- osmium_user_initiated_pop();
- connections.detach();
- osmium_user_initiated_push(false);
- }
- jsPlumb.unmakeSource(source);
- });
- osmium_user_initiated_pop();
- jsPlumb.unmakeTarget(stale);
- stale.before(fresh);
- stale.remove();
- for(var i = 0; i < newconnections.length; ++i) {
- jsPlumb.connect(newconnections[i]);
- }
- });
- jsPlumb.recalculateOffsets(fresh);
- };
- osmium_regen_remote_capacitor = function(key_or_element) {
- if(typeof osmium_capacitors !== "object") return;
- var c, s;
- if(typeof key_or_element !== "object") {
- if(!(key_or_element in osmium_capacitors)) return;
- s = $("section#projected div.pr-loadout.projected-" + key_or_element);
- c = osmium_capacitors[key_or_element];
- } else {
- s = key_or_element;
- if(!(s.data('key') in osmium_capacitors)) return;
- c = osmium_capacitors[s.data('key')];
- }
- if(s.length !== 1) return;
- s = s.find('svg');
- if(c.capacity > 0) {
- var delta = -1000 * c.delta;
- if(delta >= 0) delta = '+' + delta.toFixed(1);
- else delta = delta.toFixed(1);
- s.data({
- capacity: c.capacity,
- current: c.stable ? (c.capacity * c.stable_fraction) : 0
- });
- s.parent().prop(
- 'title', delta + ' GJ/s, '
- + (c.stable ? ((100 * c.stable_fraction).toFixed(1) + '%') : c.depletion_time)
- );
- } else {
- s.data({ capacity: 1000, current: 1000 });
- s.parent().prop('title', ''); /* XXX: .removeProp() gives "undefined" as tooltip */
- }
- s.trigger('redraw');
- };
- osmium_regen_offsets = function() {
- var divs = $("section#projected form#projected-list").children('div.pr-loadout');
- divs.each(function() {
- jsPlumb.recalculateOffsets($(this));
- });
- }
- osmium_commit_undo_deferred_timeoutid = undefined;
- osmium_commit_undo_deferred = function(delay) {
- if(!osmium_user_initiated) return;
- if(delay === undefined) delay = 100;
- if(osmium_commit_undo_deferred_timeoutid !== undefined) {
- clearTimeout(osmium_commit_undo_deferred_timeoutid);
- } else {
- osmium_clfspinner_push();
- }
- osmium_commit_undo_deferred_timeoutid = setTimeout(function() {
- osmium_commit_undo_deferred_timeoutid = undefined;
- osmium_commit_clf();
- osmium_undo_push();
- osmium_clfspinner_pop();
- }, delay);
- };
- /* Osmium
- * Copyright (C) 2013, 2014, 2015 Romain "Artefact2" Dalmaso <artefact2@gmail.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*<<< require snippet loadout_common >>>*/
- /*<<< require snippet view_loadout-presets >>>*/
- /*<<< require snippet new_loadout-ship >>>*/
- /*<<< require snippet new_loadout-modules >>>*/
- /*<<< require snippet new_loadout-drones >>>*/
- /*<<< require snippet new_loadout-implants >>>*/
- /*<<< require snippet new_loadout-beacons >>>*/
- /*<<< require snippet new_loadout-remote >>>*/
- $(function() {
- $("section#remote").on('made_visible', function() {
- jsPlumb.setSuspendDrawing(false);
- });
- osmium_tabify($("div#vlmain > ul.tabs"), 0);
- jsPlumb.setSuspendDrawing(true);
- var odata = $("div#osmium-data");
- osmium_load_common_data();
- osmium_clf_slots = odata.data('clfslots');
- osmium_capacitors = odata.data('capacitors');
- osmium_ia = odata.data('ia');
- osmium_load_static_client_data(osmium_cdatastaticver, function(cdata) {
- osmium_gen();
- /* XXX. On T3 loadouts, gen_ship() will overwrite clf_slots
- * using the bare T3 slotcounts (0/0/0).
- *
- * Usually this is later corrected by committing the CLF and
- * reading the slot counts back from process_clf. But in the
- * initial phase, we don't commit the CLF. So undo the mess
- * gen_ship() did, then regenerate the modules again.
- */
- osmium_clf_slots = odata.data('clfslots');
- osmium_gen_modules();
- osmium_init();
- if($("a[href='#remote']").parent().hasClass('active')) {
- $("section#remote").trigger('made_visible');
- }
- osmium_highlight_missing_prereqs(odata.data('missingprereqs'));
- osmium_user_initiated_push(true);
- osmium_undo_push();
- osmium_init_votes();
- osmium_init_comment_replies();
- osmium_init_export();
- });
- $('body').on('click', '.confirm', function() {
- return confirm("You are about to do a destructive action.\n\nIt cannot be undone.\n\nContinue?");
- });
- $("h1#vltitle > ul.tags > li.retag").click(function() {
- var t = $(this);
- var ul = t.parent();
- var h1 = ul.parent();
- var form = $(document.createElement('form'));
- form.addClass('retag');
- form.prop('method', 'post');
- form.prop('action', osmium_relative + '/internal/retag/' + $("section#ship").data('loadoutid'));
- form.append(
- $(document.createElement('input'))
- .prop('type', 'hidden')
- .prop('name', 'o___csrf')
- .val(osmium_token)
- );
- var inp = $(document.createElement('input'));
- inp.prop('type', 'text');
- inp.prop('placeholder', 'Space-separated list of tags…');
- inp.prop('name', 'tags');
- var tags = [];
- ul.children('li').not('.retag').each(function() {
- tags.push($(this).text());
- });
- inp.val(tags.join(' '));
- form.append(inp);
- form.append([
- ' ',
- $(document.createElement('input'))
- .prop('type', 'submit')
- .val('Update tags')
- ]);
- form.append([
- ' ',
- $(document.createElement('a'))
- .addClass('cancel')
- .text('Cancel')
- .click(function() {
- form.remove();
- ul.show();
- })
- ]);
- form.submit(function(e) {
- e.preventDefault();
- var hidden = form.find('input[type="submit"], a.cancel');
- var spinner = $(document.createElement('span')).addClass('spinner');
- var postdata = form.serialize();
- hidden.hide();
- form.append(spinner);
- inp.prop('disabled', true);
- $.ajax({
- type: 'POST',
- url: form.prop('action'),
- data: postdata,
- dataType: 'json',
- complete: function() {
- inp.prop('disabled', false);
- spinner.remove();
- hidden.show();
- },
- success: function(payload) {
- form.find('p.error_box').remove();
- if("error" in payload) {
- form.append(
- $(document.createElement('p'))
- .addClass('error_box')
- .text(payload.error)
- );
- }
- if("dest" in payload) {
- document.location.replace(osmium_relative + '/' + payload.dest);
- }
- }
- });
- });
- form.hide();
- h1.append(form);
- ul.hide();
- form.show();
- inp.focus();
- });
- if(window.history && Array.isArray(history.state) && history.state.length === 2) {
- osmium_clf = $.extend(true, {}, history.state[1]);
- osmium_commit_clf();
- osmium_gen();
- }
- });
- osmium_loadout_readonly = true;
- osmium_clftype = 'view';
- osmium_init = function() {
- osmium_init_ship();
- osmium_init_presets();
- $("section#loadout > section#modules > div.slots > ul > li[data-typeid] span.charge").remove();
- osmium_init_modules();
- osmium_init_fattribs();
- osmium_init_drones();
- osmium_init_implants();
- osmium_init_beacons();
- osmium_init_remote();
- };
- osmium_gen = function() {
- osmium_gen_ship();
- osmium_gen_modules();
- osmium_gen_fattribs();
- osmium_gen_drones();
- osmium_gen_implants();
- osmium_gen_beacons();
- osmium_gen_remote();
- };
- osmium_init_votes = function() {
- $("section#ship > div.votes > a, section#comments > div.comment > div.votes > a").click(function() {
- var t = $(this);
- var score = t.parent().children('strong');
- var delta = 0;
- var upvoted = t.parent().children('a.upvote').hasClass('voted');
- var downvoted = t.parent().children('a.downvote').hasClass('voted');
- var action;
- if(t.hasClass('voted')) {
- t.removeClass('voted');
- delta += t.hasClass('upvote') ? -1 : 1;
- action = 'rmvote';
- } else {
- t.parent().children('a.voted').each(function() {
- delta += $(this).removeClass('voted').hasClass('upvote') ? -1 : 1;
- });
- t.addClass('voted');
- if(t.hasClass('upvote')) {
- delta += 1;
- action = 'castupvote';
- } else {
- delta += -1;
- action = 'castdownvote';
- }
- }
- score.text(parseInt(score.text(), 10) + delta);
- var targettype = t.parent().data('targettype');
- var opts = {
- 'o___csrf': osmium_token,
- loadoutid: $("section#ship").data('loadoutid')
- };
- if(targettype == 'comment') {
- opts.commentid = t.parent().parent().data('commentid');
- }
- $.ajax({
- type: 'POST',
- url: osmium_relative + '/internal/vote/' + targettype + '/' + action,
- data: opts,
- dataType: 'json',
- success: function(data) {
- if(!data['success']) {
- score.text(parseInt(score.text(), 10) - delta);
- if(upvoted) {
- t.parent().children('a.upvote').addClass('voted');
- } else {
- t.parent().children('a.upvote').removeClass('voted');
- }
- if(downvoted) {
- t.parent().children('a.downvote').addClass('voted');
- } else {
- t.parent().children('a.downvote').removeClass('voted');
- }
- var error = $(document.createElement('div'));
- error.addClass('verror');
- error.text(data['error']);
- error.append('<br /><small>(click to close)</small>');
- error.hide();
- error.click(function() {
- $(this).fadeOut(250);
- });
- t.parent().append(error);
- error.fadeIn(250);
- }
- }
- });
- });
- };
- osmium_init_comment_replies = function() {
- $("section#comments > div.comment > header > div.meta a.add_comment").click(function() {
- $(this).closest('div.comment').find('ul.replies > li.new').fadeIn(250).find('textarea').focus();
- });
- $("section#comments > div.comment > ul.replies > li.new > form > a.cancel").click(function() {
- $(this).parent().parent().hide().find('textarea').val('');
- });
- };
- osmium_init_export = function() {
- $("section#export a[type]").click(function(e) {
- e.preventDefault();
- var t = $(this);
- osmium_clfspinner_push();
- $.ajax({
- url: t.attr('href'),
- dataType: 'text',
- success: function(payload) {
- osmium_modal_rotextarea(t.text(), payload);
- },
- error: function() {
- window.location.assign(t.attr('href'));
- },
- complete: function() {
- osmium_clfspinner_pop();
- }
- });
- });
- $("section#export, h1#vltitle").on('click', 'a[data-ccpdna]', function() {
- var t = $(this);
- t.blur();
- if(typeof CCPEVE === 'object' && 'showFitting' in CCPEVE && typeof CCPEVE.showFitting === 'function') {
- CCPEVE.showFitting(t.data('ccpdna'));
- }
- });
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement