UNPKG

clustergrammer

Version:

This is a clustergram implemented in D3.js. I started from the example http://bost.ocks.org/mike/miserables/ and added the following features

1,656 lines (1,382 loc) 960 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var make_config = __webpack_require__(1); var make_params = __webpack_require__(9); var make_viz = __webpack_require__(89); var resize_viz = __webpack_require__(152); var play_demo = __webpack_require__(229); var ini_demo = __webpack_require__(247); var filter_viz_using_nodes = __webpack_require__(250); var filter_viz_using_names = __webpack_require__(251); var update_cats = __webpack_require__(252); var reset_cats = __webpack_require__(253); var two_translate_zoom = __webpack_require__(144); var update_view = __webpack_require__(202); var save_matrix = __webpack_require__(255); var brush_crop_matrix = __webpack_require__(259); var run_zoom = __webpack_require__(153); var d3_tip_custom = __webpack_require__(100); var all_reorder = __webpack_require__(143); var make_matrix_string = __webpack_require__(257); // moved d3.slider to src d3.slider = __webpack_require__(261); /* eslint-disable */ var awesomplete = __webpack_require__(263); // getting css from src __webpack_require__(265); __webpack_require__(269); /* clustergrammer v1.19.5 * Nicolas Fernandez, Ma'ayan Lab, Icahn School of Medicine at Mount Sinai * (c) 2017 */ function Clustergrammer(args) { /* Main program * ----------------------------------------------------------------------- */ // consume and validate user input // build giant config object // visualize based on config object // handle user events // consume and validate user arguments, produce configuration object var config = make_config(args); var cgm = {}; // make visualization parameters using configuration object cgm.params = make_params(config); cgm.config = config; // set up zoom cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () { run_zoom(cgm); }); cgm.params.zoom_behavior.translate([cgm.params.viz.clust.margin.left, cgm.params.viz.clust.margin.top]); if (cgm.params.use_sidebar) { var make_sidebar = __webpack_require__(271); make_sidebar(cgm); } // make visualization using parameters make_viz(cgm); function external_resize() { d3.select(cgm.params.viz.viz_svg).style('opacity', 0.5); var wait_time = 500; if (this.params.viz.run_trans === true) { wait_time = 2500; } setTimeout(resize_fun, wait_time, this); } function resize_fun(cgm) { resize_viz(cgm); } function run_update_cats(cat_data) { update_cats(this, cat_data); } function zoom_api(pan_dx, pan_dy, fin_zoom) { two_translate_zoom(this, pan_dx, pan_dy, fin_zoom); } function expose_d3_tip_custom() { // this allows external modules to have access to d3_tip return d3_tip_custom; } function api_reorder(inst_rc, inst_order) { if (inst_order === 'sum') { inst_order = 'rank'; } if (inst_order === 'var') { inst_order = 'rankvar'; } all_reorder(this, inst_order, inst_rc); } function export_matrix_string() { return make_matrix_string(this.params); } function external_update_view(filter_type, inst_state) { update_view(this, filter_type, inst_state); } // add more API endpoints cgm.update_view = update_view; cgm.resize_viz = external_resize; cgm.play_demo = play_demo; cgm.ini_demo = ini_demo; cgm.filter_viz_using_nodes = filter_viz_using_nodes; cgm.filter_viz_using_names = filter_viz_using_names; cgm.update_cats = run_update_cats; cgm.reset_cats = reset_cats; cgm.zoom = zoom_api; cgm.save_matrix = save_matrix; cgm.brush_crop_matrix = brush_crop_matrix; cgm.d3_tip_custom = expose_d3_tip_custom; cgm.reorder = api_reorder; cgm.export_matrix_string = export_matrix_string; cgm.update_view = external_update_view; return cgm; } module.exports = Clustergrammer; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var utils = __webpack_require__(2); var transpose_network = __webpack_require__(3); var get_available_filters = __webpack_require__(4); var get_filter_default_state = __webpack_require__(5); var set_defaults = __webpack_require__(6); var check_sim_mat = __webpack_require__(7); var check_nodes_for_categories = __webpack_require__(8); module.exports = function make_config(args) { var defaults = set_defaults(); // Mixin defaults with user-defined arguments. var config = utils.extend(defaults, args); config.network_data = args.network_data; var super_string = ': '; // replace undersores with space in row/col names _.each(['row', 'col'], function (inst_rc) { var inst_nodes = config.network_data[inst_rc + '_nodes']; var has_cats = check_nodes_for_categories(inst_nodes); inst_nodes.forEach(function (d, i) { // add index to row_nodes and col_nodes d[inst_rc + '_index'] = i; if (has_cats) { config.super_labels = true; config.super[inst_rc] = d.name.split(super_string)[0]; d.name = d.name.split(super_string)[1]; } d.name = String(d.name); d.name = d.name.replace(/_/g, ' '); }); }); config.network_data.row_nodes_names = utils.pluck(config.network_data.row_nodes, 'name'); config.network_data.col_nodes_names = utils.pluck(config.network_data.col_nodes, 'name'); config.sim_mat = check_sim_mat(config); var filters = get_available_filters(config.network_data.views); var default_states = {}; _.each(_.keys(filters.possible_filters), function (inst_filter) { var tmp_state = get_filter_default_state(filters.filter_data, inst_filter); default_states[inst_filter] = tmp_state; }); // process view if (_.has(config.network_data, 'views')) { config.network_data.views.forEach(function (inst_view) { _.each(_.keys(filters.possible_filters), function (inst_filter) { if (!_.has(inst_view, inst_filter)) { inst_view[inst_filter] = default_states[inst_filter]; } }); var inst_nodes = inst_view.nodes; // proc row/col nodes names in views _.each(['row', 'col'], function (inst_rc) { var has_cats = check_nodes_for_categories(inst_nodes[inst_rc + '_nodes']); inst_nodes[inst_rc + '_nodes'].forEach(function (d, i) { // add index to row_nodes and col_nodes d[inst_rc + '_index'] = i; if (has_cats) { d.name = d.name.split(super_string)[1]; } d.name = String(d.name); d.name = d.name.replace(/_/g, ' '); }); }); }); } var col_nodes = config.network_data.col_nodes; var row_nodes = config.network_data.row_nodes; // console.log( config.network_data.links[0] ) // console.log( config.network_data.links[1] ) // console.log( config.network_data.links[2] ) // console.log(_.has(config.network_data,'mat')); /////////////////////////// // convert 'mat' to links /////////////////////////// if (_.has(config.network_data, 'mat')) { var links = []; var mat = config.network_data.mat; var inst_link = {}; // console.log('found mat') for (var i = 0; i < mat.length; i++) { for (var j = 0; j < mat[0].length; j++) { // console.log(mat[i][j]) inst_link = {}; inst_link.source = i; inst_link.target = j; inst_link.value = mat[i][j]; links.push(inst_link); } } // save to network_data config.network_data.links = links; } // add names and instantaneous positions to links config.network_data.links.forEach(function (d) { d.name = row_nodes[d.source].name + '_' + col_nodes[d.target].name; d.row_name = row_nodes[d.source].name; d.col_name = col_nodes[d.target].name; }); // transpose network if necessary if (config.transpose) { config.network_data = transpose_network(config.network_data); var tmp_col_label = args.col_label; var tmp_row_label = args.row_label; args.row_label = tmp_col_label; args.col_label = tmp_row_label; } // super-row/col labels if (!utils.is_undefined(args.row_label) && !utils.is_undefined(args.col_label)) { config.super_labels = true; config.super = {}; config.super.row = args.row_label; config.super.col = args.col_label; } // initialize cluster ordering - both rows and columns config.inst_order = {}; if (!utils.is_undefined(args.order) && utils.is_supported_order(args.order)) { config.inst_order.row = args.order; config.inst_order.col = args.order; } else { config.inst_order.row = 'clust'; config.inst_order.col = 'clust'; } // set row or column order directly -- note that row/col are swapped // !! need to swap row/col orderings if (!utils.is_undefined(args.row_order) && utils.is_supported_order(args.row_order)) { // !! row and col orderings are swapped, need to fix config.inst_order.col = args.row_order; } if (!utils.is_undefined(args.col_order) && utils.is_supported_order(args.col_order)) { // !! row and col orderings are swapped, need to fix config.inst_order.row = args.col_order; } var row_has_group = utils.has(config.network_data.row_nodes[0], 'group'); var col_has_group = utils.has(config.network_data.col_nodes[0], 'group'); config.show_dendrogram = row_has_group || col_has_group; if (utils.has(config.network_data.links[0], 'value_orig')) { config.keep_orig = true; } else { config.keep_orig = false; } return config; }; /***/ }), /* 2 */ /***/ (function(module, exports) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* Utility functions * ----------------------------------------------------------------------- */ module.exports = { normal_name: function normal_name(d) { var inst_name = d.name.replace(/_/g, ' ').split('#')[0]; return inst_name; }, is_supported_order: function is_supported_order(order) { return order === 'ini' || order === 'clust' || order === 'rank_var' || order === 'rank' || order === 'class' || order == 'alpha'; }, /* Returns whether or not an object has a certain property. */ has: function has(obj, key) { return obj != null && hasOwnProperty.call(obj, key); }, property: function property(key) { return function (obj) { return obj == null ? void 0 : obj[key]; }; }, // Convenience version of a common use case of `map`: fetching a property. pluck: function pluck(arr, key) { var self = this; // Double check that we have lodash or underscore available if (window._) { // Underscore provides a _.pluck function. Use that. if (typeof _.pluck === 'function') { return _.pluck(arr, key); } else if (typeof _.map === 'function') { // Lodash does not have a pluck function. // Use _.map with the property function defined above. return _.map(arr, self.property(key)); } } else if (arr.map && typeof arr.map === 'function') { // If lodash or underscore not available, check to see if the native arr.map is available. // If so, use it with the property function defined above. return arr.map(self.property(key)); } }, /* Returns true if the object is undefined. */ is_undefined: function is_undefined(obj) { return obj === void 0; }, /* Mixes two objects in together, overwriting a target with a source. */ extend: function extend(target, source) { target = target || {}; for (var prop in source) { if (_typeof(source[prop]) === 'object') { target[prop] = this.extend(target[prop], source[prop]); } else { target[prop] = source[prop]; } } return target; } }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var utils = __webpack_require__(2); /* Transpose network. */ module.exports = function (net) { var tnet = {}, inst_link, i; tnet.row_nodes = net.col_nodes; tnet.col_nodes = net.row_nodes; tnet.links = []; for (i = 0; i < net.links.length; i++) { inst_link = {}; inst_link.source = net.links[i].target; inst_link.target = net.links[i].source; inst_link.value = net.links[i].value; // Optional highlight. if (utils.has(net.links[i], 'highlight')) { inst_link.highlight = net.links[i].highlight; } if (utils.has(net.links[i], 'value_up')) { inst_link.value_up = net.links[i].value_up; } if (utils.has(net.links[i], 'value_dn')) { inst_link.value_dn = net.links[i].value_dn; } if (utils.has(net.links[i], 'info')) { inst_link.info = net.links[i].info; } tnet.links.push(inst_link); } return tnet; }; /***/ }), /* 4 */ /***/ (function(module, exports) { 'use strict'; module.exports = function get_available_filters(views) { var possible_filters = {}; var filter_data = {}; _.each(views, function (inst_view) { var inst_keys = _.keys(inst_view); _.each(inst_keys, function (inst_key) { if (inst_key != 'nodes') { if (!_.has(filter_data, inst_key)) { filter_data[inst_key] = []; } filter_data[inst_key].push(inst_view[inst_key]); filter_data[inst_key] = _.uniq(filter_data[inst_key]); } }); }); var tmp_filters = _.keys(filter_data); _.each(tmp_filters, function (inst_filter) { var options = filter_data[inst_filter]; var num_options = options.length; var filter_type = 'categorical'; _.each(options, function (inst_option) { if (typeof inst_option === 'number') { filter_type = 'numerical'; } }); if (num_options > 1) { possible_filters[inst_filter] = filter_type; } }); var filters = {}; filters.possible_filters = possible_filters; filters.filter_data = filter_data; return filters; }; /***/ }), /* 5 */ /***/ (function(module, exports) { "use strict"; module.exports = function get_filter_default_state(filter_data, filter_type) { var default_state = filter_data[filter_type].sort(function (a, b) { return b - a; })[0]; default_state = String(default_state); return default_state; }; /***/ }), /* 6 */ /***/ (function(module, exports) { 'use strict'; module.exports = function set_defaults() { var defaults = { // Label options row_label_scale: 1, col_label_scale: 1, super_labels: false, super: {}, show_label_tooltips: true, show_tile_tooltips: true, // matrix options transpose: false, tile_colors: ['#FF0000', '#1C86EE'], bar_colors: ['#FF0000', '#1C86EE'], // value-cat colors // cat_value_colors: ['#2F4F4F', '#8A2BE2'], cat_value_colors: ['#2F4F4F', '#9370DB'], outline_colors: ['orange', 'black'], highlight_color: '#FFFF00', tile_title: false, // Default domain is set to 0: the domain will be set automatically input_domain: 0, opacity_scale: 'linear', do_zoom: true, is_zoom: 0, is_slider_drag: false, is_cropping: false, background_color: '#FFFFFF', super_border_color: '#F5F5F5', outer_margins: { top: 0, bottom: 0, left: 0, right: 0 }, ini_expand: false, grey_border_width: 2, tile_click_hlight: false, super_label_scale: 1, make_tile_tooltip: function make_tile_tooltip(d) { return d.info; }, // initialize view, e.g. initialize with row filtering ini_view: null, // record of requested views requested_view: null, use_sidebar: true, title: null, about: null, sidebar_width: 160, sidebar_icons: true, row_search_placeholder: 'Row', buffer_width: 10, show_sim_mat: false, cat_colors: null, resize: true, clamp_opacity: 0.85, expand_button: true, max_allow_fs: 20, dendro_filter: { 'row': false, 'col': false }, cat_filter: { 'row': false, 'col': false }, crop_filter_nodes: { 'row': false, 'col': false }, row_tip_callback: null, col_tip_callback: null, tile_tip_callback: null, matrix_update_callback: null, cat_update_callback: null, dendro_callback: null, dendro_click_callback: null, new_row_cats: null, make_modals: true, show_viz_border: false }; return defaults; }; /***/ }), /* 7 */ /***/ (function(module, exports) { "use strict"; module.exports = function check_sim_mat(config) { var sim_mat = false; var num_rows = config.network_data.row_nodes_names.length; var num_cols = config.network_data.col_nodes_names.length; if (num_rows == num_cols) { // the sort here was causing errors var rows = config.network_data.row_nodes_names; var cols = config.network_data.col_nodes_names; sim_mat = true; _.each(rows, function (inst_row) { var inst_index = rows.indexOf(inst_row); if (inst_row !== cols[inst_index]) { sim_mat = false; } }); } if (sim_mat) { config.expand_button = false; } return sim_mat; }; /***/ }), /* 8 */ /***/ (function(module, exports) { 'use strict'; module.exports = function check_nodes_for_categories(nodes) { var super_string = ': '; var has_cat = true; _.each(nodes, function (inst_node) { var inst_name = String(inst_node.name); if (inst_name.indexOf(super_string) < 0) { has_cat = false; } }); return has_cat; }; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var make_network_using_view = __webpack_require__(10); var ini_sidebar_params = __webpack_require__(64); var make_requested_view = __webpack_require__(65); var get_available_filters = __webpack_require__(4); var calc_viz_params = __webpack_require__(66); var ini_zoom_info = __webpack_require__(88); /* Params: calculates the size of all the visualization elements in the clustergram. */ module.exports = function make_params(input_config) { var config = $.extend(true, {}, input_config); var params = config; // keep a copy of inst_view params.inst_nodes = {}; params.inst_nodes.row_nodes = params.network_data.row_nodes; params.inst_nodes.col_nodes = params.network_data.col_nodes; // when pre-loading the visualization using a view if (params.ini_view !== null) { var requested_view = params.ini_view; var filters = get_available_filters(params.network_data.views); params.viz = {}; params.viz.possible_filters = filters.possible_filters; params.viz.filter_data = filters.filter_data; requested_view = make_requested_view(params, requested_view); params.network_data = make_network_using_view(config, params, requested_view); // save ini_view as requested_view params.requested_view = requested_view; } params = calc_viz_params(params); if (params.use_sidebar) { params.sidebar = ini_sidebar_params(params); } params.zoom_info = ini_zoom_info(); return params; }; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var filter_network_using_new_nodes = __webpack_require__(11); var get_subset_views = __webpack_require__(63); module.exports = function make_network_using_view(config, params, requested_view) { var orig_views = config.network_data.views; var is_enr = false; if (_.has(orig_views[0], 'enr_score_type')) { is_enr = true; } var sub_views = get_subset_views(params, orig_views, requested_view); ////////////////////////////// // Enrichr specific rules ////////////////////////////// if (is_enr && sub_views.length == 0) { requested_view = { 'N_row_sum': 'all', 'N_col_sum': '10' }; sub_views = get_subset_views(params, orig_views, requested_view); } var inst_view = sub_views[0]; var new_network_data; // get new_network_data or default back to old_network_data if (typeof inst_view !== 'undefined') { var new_nodes = inst_view.nodes; new_network_data = filter_network_using_new_nodes(config, new_nodes); } else { new_network_data = config.network_data; } return new_network_data; }; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var utils = __webpack_require__(2); var core = __webpack_require__(12); var math = core.create(); math.import(__webpack_require__(25)); math.import(__webpack_require__(62)); module.exports = function filter_network_using_new_nodes(config, new_nodes) { var links = config.network_data.links; // // make new mat from links // var new_mat = config.network_data.mat; // get new names of rows and cols var row_names = utils.pluck(new_nodes.row_nodes, 'name'); var col_names = utils.pluck(new_nodes.col_nodes, 'name'); var new_mat = math.matrix(math.zeros([new_nodes.row_nodes.length, new_nodes.col_nodes.length])); new_mat = new_mat.toArray(); var new_links = _.filter(links, function (inst_link) { var inst_row = inst_link.name.split('_')[0]; var inst_col = inst_link.name.split('_')[1]; var row_index = _.indexOf(row_names, inst_row); var col_index = _.indexOf(col_names, inst_col); // only keep links that have not been filtered out if (row_index > -1 & col_index > -1) { // redefine source and target inst_link.source = row_index; inst_link.target = col_index; new_mat[row_index][col_index] = inst_link.value; return inst_link; } }); // set up new_network_data var new_network_data = {}; // rows new_network_data.row_nodes = new_nodes.row_nodes; new_network_data.row_nodes_names = row_names; // cols new_network_data.col_nodes = new_nodes.col_nodes; new_network_data.col_nodes_names = col_names; // save all links new_network_data.links = new_links; new_network_data.all_links = links; // mat new_network_data.mat = new_mat; // add back all views new_network_data.views = config.network_data.views; // add cat_colors if necessary if (_.has(config.network_data, 'cat_colors')) { new_network_data.cat_colors = config.network_data.cat_colors; } return new_network_data; }; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; module.exports = __webpack_require__(13); /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var isFactory = __webpack_require__(14).isFactory; var typedFactory = __webpack_require__(16); var emitter = __webpack_require__(20); var importFactory = __webpack_require__(22); var configFactory = __webpack_require__(24); /** * Math.js core. Creates a new, empty math.js instance * @param {Object} [options] Available options: * {number} epsilon * Minimum relative difference between two * compared values, used by all comparison functions. * {string} matrix * A string 'Matrix' (default) or 'Array'. * {string} number * A string 'number' (default), 'BigNumber', or 'Fraction' * {number} precision * The number of significant digits for BigNumbers. * Not applicable for Numbers. * {boolean} predictable * Predictable output type of functions. When true, * output type depends only on the input types. When * false (default), output type can vary depending * on input values. For example `math.sqrt(-4)` * returns `complex('2i')` when predictable is false, and * returns `NaN` when true. * {string} randomSeed * Random seed for seeded pseudo random number generator. * Set to null to randomly seed. * @returns {Object} Returns a bare-bone math.js instance containing * functions: * - `import` to add new functions * - `config` to change configuration * - `on`, `off`, `once`, `emit` for events */ exports.create = function create(options) { // simple test for ES5 support if (typeof Object.create !== 'function') { throw new Error('ES5 not supported by this JavaScript engine. ' + 'Please load the es5-shim and es5-sham library for compatibility.'); } // cached factories and instances var factories = []; var instances = []; // create a namespace for the mathjs instance, and attach emitter functions var math = emitter.mixin({}); math.type = {}; math.expression = { transform: {}, mathWithTransform: {} }; // create a new typed instance math.typed = typedFactory.create(math.type); // create configuration options. These are private var _config = { // minimum relative difference between two compared values, // used by all comparison functions epsilon: 1e-12, // type of default matrix output. Choose 'matrix' (default) or 'array' matrix: 'Matrix', // type of default number output. Choose 'number' (default) 'BigNumber', or 'Fraction number: 'number', // number of significant digits in BigNumbers precision: 64, // predictable output type of functions. When true, output type depends only // on the input types. When false (default), output type can vary depending // on input values. For example `math.sqrt(-4)` returns `complex('2i')` when // predictable is false, and returns `NaN` when true. predictable: false, // random seed for seeded pseudo random number generation // null = randomly seed randomSeed: null }; /** * Load a function or data type from a factory. * If the function or data type already exists, the existing instance is * returned. * @param {{type: string, name: string, factory: Function}} factory * @returns {*} */ function load(factory) { if (!isFactory(factory)) { throw new Error('Factory object with properties `type`, `name`, and `factory` expected'); } var index = factories.indexOf(factory); var instance; if (index === -1) { // doesn't yet exist if (factory.math === true) { // pass with math namespace instance = factory.factory(math.type, _config, load, math.typed, math); } else { instance = factory.factory(math.type, _config, load, math.typed); } // append to the cache factories.push(factory); instances.push(instance); } else { // already existing function, return the cached instance instance = instances[index]; } return instance; } // load the import and config functions math['import'] = load(importFactory); math['config'] = load(configFactory); math.expression.mathWithTransform['config'] = math['config']; // apply options if (options) { math.config(options); } return math; }; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var isBigNumber = __webpack_require__(15); /** * Clone an object * * clone(x) * * Can clone any primitive type, array, and object. * If x has a function clone, this function will be invoked to clone the object. * * @param {*} x * @return {*} clone */ exports.clone = function clone(x) { var type = typeof x === 'undefined' ? 'undefined' : _typeof(x); // immutable primitive types if (type === 'number' || type === 'string' || type === 'boolean' || x === null || x === undefined) { return x; } // use clone function of the object when available if (typeof x.clone === 'function') { return x.clone(); } // array if (Array.isArray(x)) { return x.map(function (value) { return clone(value); }); } if (x instanceof Number) return new Number(x.valueOf()); if (x instanceof String) return new String(x.valueOf()); if (x instanceof Boolean) return new Boolean(x.valueOf()); if (x instanceof Date) return new Date(x.valueOf()); if (isBigNumber(x)) return x; // bignumbers are immutable if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp // object return exports.map(x, clone); }; /** * Apply map to all properties of an object * @param {Object} object * @param {function} callback * @return {Object} Returns a copy of the object with mapped properties */ exports.map = function (object, callback) { var clone = {}; for (var key in object) { if (exports.hasOwnProperty(object, key)) { clone[key] = callback(object[key]); } } return clone; }; /** * Extend object a with the properties of object b * @param {Object} a * @param {Object} b * @return {Object} a */ exports.extend = function (a, b) { for (var prop in b) { if (exports.hasOwnProperty(b, prop)) { a[prop] = b[prop]; } } return a; }; /** * Deep extend an object a with the properties of object b * @param {Object} a * @param {Object} b * @returns {Object} */ exports.deepExtend = function deepExtend(a, b) { // TODO: add support for Arrays to deepExtend if (Array.isArray(b)) { throw new TypeError('Arrays are not supported by deepExtend'); } for (var prop in b) { if (exports.hasOwnProperty(b, prop)) { if (b[prop] && b[prop].constructor === Object) { if (a[prop] === undefined) { a[prop] = {}; } if (a[prop].constructor === Object) { deepExtend(a[prop], b[prop]); } else { a[prop] = b[prop]; } } else if (Array.isArray(b[prop])) { throw new TypeError('Arrays are not supported by deepExtend'); } else { a[prop] = b[prop]; } } } return a; }; /** * Deep test equality of all fields in two pairs of arrays or objects. * @param {Array | Object} a * @param {Array | Object} b * @returns {boolean} */ exports.deepEqual = function deepEqual(a, b) { var prop, i, len; if (Array.isArray(a)) { if (!Array.isArray(b)) { return false; } if (a.length != b.length) { return false; } for (i = 0, len = a.length; i < len; i++) { if (!exports.deepEqual(a[i], b[i])) { return false; } } return true; } else if (a instanceof Object) { if (Array.isArray(b) || !(b instanceof Object)) { return false; } for (prop in a) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } for (prop in b) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } return true; } else { return (typeof a === 'undefined' ? 'undefined' : _typeof(a)) === (typeof b === 'undefined' ? 'undefined' : _typeof(b)) && a == b; } }; /** * Test whether the current JavaScript engine supports Object.defineProperty * @returns {boolean} returns true if supported */ exports.canDefineProperty = function () { // test needed for broken IE8 implementation try { if (Object.defineProperty) { Object.defineProperty({}, 'x', { get: function get() {} }); return true; } } catch (e) {} return false; }; /** * Attach a lazy loading property to a constant. * The given function `fn` is called once when the property is first requested. * On older browsers (<IE8), the function will fall back to direct evaluation * of the properties value. * @param {Object} object Object where to add the property * @param {string} prop Property name * @param {Function} fn Function returning the property value. Called * without arguments. */ exports.lazy = function (object, prop, fn) { if (exports.canDefineProperty()) { var _uninitialized = true; var _value; Object.defineProperty(object, prop, { get: function get() { if (_uninitialized) { _value = fn(); _uninitialized = false; } return _value; }, set: function set(value) { _value = value; _uninitialized = false; }, configurable: true, enumerable: true }); } else { // fall back to immediate evaluation object[prop] = fn(); } }; /** * Traverse a path into an object. * When a namespace is missing, it will be created * @param {Object} object * @param {string} path A dot separated string like 'name.space' * @return {Object} Returns the object at the end of the path */ exports.traverse = function (object, path) { var obj = object; if (path) { var names = path.split('.'); for (var i = 0; i < names.length; i++) { var name = names[i]; if (!(name in obj)) { obj[name] = {}; } obj = obj[name]; } } return obj; }; /** * A safe hasOwnProperty * @param {Object} object * @param {string} property */ exports.hasOwnProperty = function (object, property) { return object && Object.hasOwnProperty.call(object, property); }; /** * Test whether an object is a factory. a factory has fields: * * - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object]) (required) * - name: string (optional) * - path: string A dot separated path (optional) * - math: boolean If true (false by default), the math namespace is passed * as fifth argument of the factory function * * @param {*} object * @returns {boolean} */ exports.isFactory = function (object) { return object && typeof object.factory === 'function'; }; /***/ }), /* 15 */ /***/ (function(module, exports) { "use strict"; /** * Test whether a value is a BigNumber * @param {*} x * @return {boolean} */ module.exports = function isBigNumber(x) { return x && x.constructor.prototype.isBigNumber || false; }; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var typedFunction = __webpack_require__(17); var digits = __webpack_require__(18).digits; var isBigNumber = __webpack_require__(15); var isMatrix = __webpack_require__(19); // returns a new instance of typed-function var _createTyped = function createTyped() { // initially, return the original instance of typed-function // consecutively, return a new instance from typed.create. _createTyped = typedFunction.create; return typedFunction; }; /** * Factory function for creating a new typed instance * @param {Object} type Object with data types like Complex and BigNumber * @returns {Function} */ exports.create = function create(type) { // TODO: typed-function must be able to silently ignore signatures with unknown data types // type checks for all known types // // note that: // // - check by duck-typing on a property like `isUnit`, instead of checking instanceof. // instanceof cannot be used because that would not allow to pass data from // one instance of math.js to another since each has it's own instance of Unit. // - check the `isUnit` property via the constructor, so there will be no // matches for "fake" instances like plain objects with a property `isUnit`. // That is important for security reasons. // - It must not be possible to override the type checks used internally, // for security reasons, so these functions are not exposed in the expression // parser. type.isNumber = function (x) { return typeof x === 'number'; }; type.isComplex = function (x) { return type.Complex && x instanceof type.Complex || false; }; type.isBigNumber = isBigNumber; type.isFraction = function (x) { return type.Fraction && x instanceof type.Fraction || false; }; type.isUnit = function (x) { return x && x.constructor.prototype.isUnit || false; }; type.isString = function (x) { return typeof x === 'string'; }; type.isArray = Array.isArray; type.isMatrix = isMatrix; type.isDenseMatrix = function (x) { return x && x.isDenseMatrix && x.constructor.prototype.isMatrix || false; }; type.isSparseMatrix = function (x) { return x && x.isSparseMatrix && x.constructor.prototype.isMatrix || false; }; type.isRange = function (x) { return x && x.constructor.prototype.isRange || false; }; type.isIndex = function (x) { return x && x.constructor.prototype.isIndex || false; }; type.isBoolean = function (x) { return typeof x === 'boolean'; }; type.isResultSet = function (x) { return x && x.constructor.prototype.isResultSet || false; }; type.isHelp = function (x) { return x && x.constructor.prototype.isHelp || false; }; type.isFunction = function (x) { return typeof x === 'function'; }; type.isDate = function (x) { return x instanceof Date; }; type.isRegExp = function (x) { return x instanceof RegExp; }; type.isObject = function (x) { return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object'; }; type.isNull = function (x) { return x === null; }; type.isUndefined = function (x) { return x === undefined; }; type.isAccessorNode = function (x) { return x && x.isAccessorNode && x.constructor.prototype.isNode || false; }; type.isArrayNode = function (x) { return x && x.isArrayNode && x.constructor.prototype.isNode || false; }; type.isAssignmentNode = function (x) { return x && x.isAssignmentNode && x.constructor.prototype.isNode || false; }; type.isBlockNode = function (x) { return x && x.isBlockNode && x.constructor.prototype.isNode || false; }; type.isConditionalNode = function (x) { return x && x.isConditionalNode && x.constructor.prototype.isNode || false; }; type.isConstantNode = function (x) { return x && x.isConstantNode && x.constructor.prototype.isNode || false; }; type.isFunctionAssignmentNode = function (x) { return x && x.isFunctionAssignmentNode && x.constructor.prototype.isNode || false; }; type.isFunctionNode = function (x) { return x && x.isFunctionNode && x.constructor.prototype.isNode || false; }; type.isIndexNode = function (x) { return x && x.isIndexNode && x.constructor.prototype.isNode || false; }; type.isNode = function (x) { return x && x.isNode && x.constructor.prototype.isNode || false; }; type.isObjectNode = function (x) { return x && x.isObjectNode && x.constructor.prototype.isNode || false; }; type.isOperatorNode = function (x) { return x && x.isOperatorNode && x.constructor.prototype.isNode || false; }; type.isParenthesisNode = function (x) { return x && x.isParenthesisNode && x.constructor.prototype.isNode || false; }; type.isRangeNode = function (x) { return x && x.isRangeNode && x.constructor.prototype.isNode || false; }; type.isSymbolNode = function (x) { return x && x.isSymbolNode && x.constructor.prototype.isNode || false; }; type.isChain = function (x) { return x && x.constructor.prototype.isChain || false; }; // get a new instance of typed-function var typed = _createTyped(); // define all types. The order of the types determines in which order function // arguments are type-checked (so for performance it's important to put the // most used types first). typed.types = [{ name: 'number', test: type.isNumber }, { name: 'Complex', test: type.isComplex }, { name: 'BigNumber', test: type.isBigNumber }, { name: 'Fraction', test: type.isFraction }, { name: 'Unit', test: type.isUnit }, { name: 'string', test: type.isString }, { name: 'Array', test: type.isArray }, { name: 'Matrix', test: type.isMatrix }, { name: 'DenseMatrix', test: type.isDenseMatrix }, { name: 'SparseMatrix', test: type.isSparseMatrix }, { name: 'Range', test: type.isRange }, { name: 'Index', test: type.isIndex }, { name: 'boolean', test: type.isBoolean }, { name: 'ResultSet', test: type.isResultSet }, { name: 'Help', test: type.isHelp }, { name: 'function', test: type.isFunction }, { name: 'Date', test: type.isDate }, { name: 'RegExp', test: type.isRegExp }, { name: 'Object', test: type.isObject }, { name: 'null', test: type.isNull }, { name: 'undefined', test: type.isUndefined }, { name: 'OperatorNode', test: type.isOperatorNode }, { name: 'ConstantNode', test: type.isConstantNode }, { name: 'SymbolNode', test: type.isSymbolNode }, { name: 'ParenthesisNode', test: type.isParenthesisNode }, { name: 'FunctionNode', test: type.isFunctionNode }, { name: 'FunctionAssignmentNode', test: type.isFunctionAssignmentNode }, { name: 'ArrayNode', test: type.isArrayNode }, { name: 'AssignmentNode', test: type.isAssignmentNode }, { name: 'BlockNode', test: type.isBlockNode }, { name: 'ConditionalNode', test: type.isConditionalNode }, { name: 'IndexNode', test: type.isIndexNode }, { name: 'RangeNode', test: type.isRangeNode }, { name: 'Node', test: type.isNode }]; // TODO: add conversion from BigNumber to number? typed.conversions = [{ from: 'number', to: 'BigNumber', convert: function convert(x) { // note: conversion from number to BigNumber can fail if x has >15 digits if (digits(x) > 15) { throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' + '(value: ' + x + '). ' + 'Use function bignumber(x) to convert to BigNumber.'); } return new type.BigNumber(x); } }, { from: 'number', to: 'Complex', convert: function convert(x) { return new type.Complex(x, 0); } }, { from: 'number', to: 'string', convert: function convert(x) { return x + ''; } }, { from: 'BigNumber', to: 'Complex', convert: function convert(x) { return new type.Complex(x.toNumber(), 0); } }, { from: 'Fraction', to: 'BigNumber', convert: function convert(x) { throw new TypeError('Cannot implicitly convert a Fraction to BigNumber or vice versa. ' + 'Use function bignumber(x) to convert to BigNumber or fraction(x) to convert to Fraction.'); } }, { from: 'Fraction', to: 'Complex', convert: function convert(x) { return new type.Complex(x.valueOf(), 0); } }, { from: 'number', to: 'Fraction', convert: function convert(x) { var f = new type.Fraction(x); if (f.valueOf() !== x) { throw new TypeError('Cannot implicitly convert a number to a Fraction when there will be a loss of precision ' + '(value: ' + x + '). ' + 'Use function fraction(x) to convert to Fraction.'); } return new type.Fraction(x); } }, { // FIXME: add conversion from Fraction to number, for example for `sqrt(fraction(1,3))` // from: 'Fraction', // to: 'number', // convert: function (x) { // return x.valueOf(); // } //}, { from: 'string', to: 'number', convert: function convert(x) { var n = Number(x); if (isNaN(n)) { throw new Error('Cannot convert "' + x + '" to a number'); } return n; } }, { from: 'string', to: 'BigNumber', convert: function convert(x) { try { return new type.BigNumber(x); } catch (err) { throw new Error('Cannot convert "' + x + '" to BigNumber'); } } }, { from: 'string', to: 'Fraction', convert: function convert(x) { try { return new type.Fraction(x); } catch (err) { throw new Error('Cannot convert "' + x + '" to Fraction'); } } }, { from: 'string', to: 'Complex', convert: function convert(x) { try { return new type.Complex(x); } catch (err) { throw new Error('Cannot convert "' + x + '" to Complex'); } } }, { from: 'boolean', to: 'number', convert: function convert(x) { return +x; } }, { from: 'boolean', to: 'BigNumber', convert: function convert(x) { return new type.BigNumber(+x); } }, { from: 'boolean', to: 'Fraction', convert: function convert(x) { return new type.Fraction(+x); } }, { from: 'boolean', to: 'string', convert: function convert(x) { return +x; } }, { from: 'null', to: 'number', convert: function convert() { return 0; } }, { from: 'null', to: 'string', convert: function convert() { return 'null'; } }, { from: 'null', to: 'BigNumber', convert: function convert() { return new type.BigNumber(0); } }, { from: 'null', to: 'Fraction', convert: function convert() { return new type.Fraction(0); } }, { from: 'Array', to: 'Matrix', convert: function convert(array) { // TODO: how to decide on the right type of matrix to create? return new type.DenseMatrix(array); } }, { from: 'Matrix', to: 'Array', convert: function convert(matrix) { return matrix.valueOf(); } }]; return typed; }; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** * typed-function * * Type checking for JavaScript functions * * https://github.com/josdejong/typed-function */ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; (function (root, factory) { if (true) { // AMD. Register as an anonymous module. !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object') { // OldNode. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like OldNode. module.exports = factory(); } else { // Browser globals (root is window) root.typed = factory(); } })(undefined, function () { // factory function to create a new instance of typed-function // TODO: allow passing configuration, type