diff --git a/code/url-analyzer.ipynb b/code/url-analyzer.ipynb
index 5cdc6f5..4a0719a 100644
--- a/code/url-analyzer.ipynb
+++ b/code/url-analyzer.ipynb
@@ -1,5 +1,18 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# URL domain regisrtrar variation analysis\n",
+ "\n",
+ "Author: Pekka Helenius, 2021\n",
+ "\n",
+ "- Analyzes given URLs and stores results into a new JSON data file\n",
+ "- Outputs associated domain registrars for each input URL as a plot\n",
+ " - \"Phishing campaigns register domains of websites from the same registrar (than the legitimate URL)\""
+ ]
+ },
{
"cell_type": "code",
"execution_count": 3,
@@ -9,3184 +22,80 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "Generating statistics: https://hoxhunt.com/\n"
+ "URL data: https://hoxhunt.com/\n",
+ "URL data: https://hs.fi\n",
+ "URL data: https://ts.fi\n",
+ "URL data: https://facebook.com\n",
+ "Generate statistics: https://hoxhunt.com/\n"
]
},
{
"data": {
- "application/javascript": [
- "/* Put everything inside the global mpl namespace */\n",
- "window.mpl = {};\n",
- "\n",
- "\n",
- "mpl.get_websocket_type = function() {\n",
- " if (typeof(WebSocket) !== 'undefined') {\n",
- " return WebSocket;\n",
- " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
- " return MozWebSocket;\n",
- " } else {\n",
- " alert('Your browser does not have WebSocket support. ' +\n",
- " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
- " 'Firefox 4 and 5 are also supported but you ' +\n",
- " 'have to enable WebSockets in about:config.');\n",
- " };\n",
- "}\n",
- "\n",
- "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
- " this.id = figure_id;\n",
- "\n",
- " this.ws = websocket;\n",
- "\n",
- " this.supports_binary = (this.ws.binaryType != undefined);\n",
- "\n",
- " if (!this.supports_binary) {\n",
- " var warnings = document.getElementById(\"mpl-warnings\");\n",
- " if (warnings) {\n",
- " warnings.style.display = 'block';\n",
- " warnings.textContent = (\n",
- " \"This browser does not support binary websocket messages. \" +\n",
- " \"Performance may be slow.\");\n",
- " }\n",
- " }\n",
- "\n",
- " this.imageObj = new Image();\n",
- "\n",
- " this.context = undefined;\n",
- " this.message = undefined;\n",
- " this.canvas = undefined;\n",
- " this.rubberband_canvas = undefined;\n",
- " this.rubberband_context = undefined;\n",
- " this.format_dropdown = undefined;\n",
- "\n",
- " this.image_mode = 'full';\n",
- "\n",
- " this.root = $('
');\n",
- " this._root_extra_style(this.root)\n",
- " this.root.attr('style', 'display: inline-block');\n",
- "\n",
- " $(parent_element).append(this.root);\n",
- "\n",
- " this._init_header(this);\n",
- " this._init_canvas(this);\n",
- " this._init_toolbar(this);\n",
- "\n",
- " var fig = this;\n",
- "\n",
- " this.waiting = false;\n",
- "\n",
- " this.ws.onopen = function () {\n",
- " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
- " fig.send_message(\"send_image_mode\", {});\n",
- " if (mpl.ratio != 1) {\n",
- " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
- " }\n",
- " fig.send_message(\"refresh\", {});\n",
- " }\n",
- "\n",
- " this.imageObj.onload = function() {\n",
- " if (fig.image_mode == 'full') {\n",
- " // Full images could contain transparency (where diff images\n",
- " // almost always do), so we need to clear the canvas so that\n",
- " // there is no ghosting.\n",
- " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
- " }\n",
- " fig.context.drawImage(fig.imageObj, 0, 0);\n",
- " };\n",
- "\n",
- " this.imageObj.onunload = function() {\n",
- " fig.ws.close();\n",
- " }\n",
- "\n",
- " this.ws.onmessage = this._make_on_message_function(this);\n",
- "\n",
- " this.ondownload = ondownload;\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._init_header = function() {\n",
- " var titlebar = $(\n",
- " '');\n",
- " var titletext = $(\n",
- " '');\n",
- " titlebar.append(titletext)\n",
- " this.root.append(titlebar);\n",
- " this.header = titletext[0];\n",
- "}\n",
- "\n",
- "\n",
- "\n",
- "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
- "\n",
- "}\n",
- "\n",
- "\n",
- "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
- "\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._init_canvas = function() {\n",
- " var fig = this;\n",
- "\n",
- " var canvas_div = $('');\n",
- "\n",
- " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
- "\n",
- " function canvas_keyboard_event(event) {\n",
- " return fig.key_event(event, event['data']);\n",
- " }\n",
- "\n",
- " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
- " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
- " this.canvas_div = canvas_div\n",
- " this._canvas_extra_style(canvas_div)\n",
- " this.root.append(canvas_div);\n",
- "\n",
- " var canvas = $('');\n",
- " canvas.addClass('mpl-canvas');\n",
- " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
- "\n",
- " this.canvas = canvas[0];\n",
- " this.context = canvas[0].getContext(\"2d\");\n",
- "\n",
- " var backingStore = this.context.backingStorePixelRatio ||\n",
- "\tthis.context.webkitBackingStorePixelRatio ||\n",
- "\tthis.context.mozBackingStorePixelRatio ||\n",
- "\tthis.context.msBackingStorePixelRatio ||\n",
- "\tthis.context.oBackingStorePixelRatio ||\n",
- "\tthis.context.backingStorePixelRatio || 1;\n",
- "\n",
- " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
- "\n",
- " var rubberband = $('');\n",
- " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
- "\n",
- " var pass_mouse_events = true;\n",
- "\n",
- " canvas_div.resizable({\n",
- " start: function(event, ui) {\n",
- " pass_mouse_events = false;\n",
- " },\n",
- " resize: function(event, ui) {\n",
- " fig.request_resize(ui.size.width, ui.size.height);\n",
- " },\n",
- " stop: function(event, ui) {\n",
- " pass_mouse_events = true;\n",
- " fig.request_resize(ui.size.width, ui.size.height);\n",
- " },\n",
- " });\n",
- "\n",
- " function mouse_event_fn(event) {\n",
- " if (pass_mouse_events)\n",
- " return fig.mouse_event(event, event['data']);\n",
- " }\n",
- "\n",
- " rubberband.mousedown('button_press', mouse_event_fn);\n",
- " rubberband.mouseup('button_release', mouse_event_fn);\n",
- " // Throttle sequential mouse events to 1 every 20ms.\n",
- " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
- "\n",
- " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
- " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
- "\n",
- " canvas_div.on(\"wheel\", function (event) {\n",
- " event = event.originalEvent;\n",
- " event['data'] = 'scroll'\n",
- " if (event.deltaY < 0) {\n",
- " event.step = 1;\n",
- " } else {\n",
- " event.step = -1;\n",
- " }\n",
- " mouse_event_fn(event);\n",
- " });\n",
- "\n",
- " canvas_div.append(canvas);\n",
- " canvas_div.append(rubberband);\n",
- "\n",
- " this.rubberband = rubberband;\n",
- " this.rubberband_canvas = rubberband[0];\n",
- " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
- " this.rubberband_context.strokeStyle = \"#000000\";\n",
- "\n",
- " this._resize_canvas = function(width, height) {\n",
- " // Keep the size of the canvas, canvas container, and rubber band\n",
- " // canvas in synch.\n",
- " canvas_div.css('width', width)\n",
- " canvas_div.css('height', height)\n",
- "\n",
- " canvas.attr('width', width * mpl.ratio);\n",
- " canvas.attr('height', height * mpl.ratio);\n",
- " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
- "\n",
- " rubberband.attr('width', width);\n",
- " rubberband.attr('height', height);\n",
- " }\n",
- "\n",
- " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
- " // upon first draw.\n",
- " this._resize_canvas(600, 600);\n",
- "\n",
- " // Disable right mouse context menu.\n",
- " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
- " return false;\n",
- " });\n",
- "\n",
- " function set_focus () {\n",
- " canvas.focus();\n",
- " canvas_div.focus();\n",
- " }\n",
- "\n",
- " window.setTimeout(set_focus, 100);\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._init_toolbar = function() {\n",
- " var fig = this;\n",
- "\n",
- " var nav_element = $('');\n",
- " nav_element.attr('style', 'width: 100%');\n",
- " this.root.append(nav_element);\n",
- "\n",
- " // Define a callback function for later on.\n",
- " function toolbar_event(event) {\n",
- " return fig.toolbar_button_onclick(event['data']);\n",
- " }\n",
- " function toolbar_mouse_event(event) {\n",
- " return fig.toolbar_button_onmouseover(event['data']);\n",
- " }\n",
- "\n",
- " for(var toolbar_ind in mpl.toolbar_items) {\n",
- " var name = mpl.toolbar_items[toolbar_ind][0];\n",
- " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
- " var image = mpl.toolbar_items[toolbar_ind][2];\n",
- " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
- "\n",
- " if (!name) {\n",
- " // put a spacer in here.\n",
- " continue;\n",
- " }\n",
- " var button = $('');\n",
- " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
- " 'ui-button-icon-only');\n",
- " button.attr('role', 'button');\n",
- " button.attr('aria-disabled', 'false');\n",
- " button.click(method_name, toolbar_event);\n",
- " button.mouseover(tooltip, toolbar_mouse_event);\n",
- "\n",
- " var icon_img = $('');\n",
- " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
- " icon_img.addClass(image);\n",
- " icon_img.addClass('ui-corner-all');\n",
- "\n",
- " var tooltip_span = $('');\n",
- " tooltip_span.addClass('ui-button-text');\n",
- " tooltip_span.html(tooltip);\n",
- "\n",
- " button.append(icon_img);\n",
- " button.append(tooltip_span);\n",
- "\n",
- " nav_element.append(button);\n",
- " }\n",
- "\n",
- " var fmt_picker_span = $('');\n",
- "\n",
- " var fmt_picker = $('');\n",
- " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
- " fmt_picker_span.append(fmt_picker);\n",
- " nav_element.append(fmt_picker_span);\n",
- " this.format_dropdown = fmt_picker[0];\n",
- "\n",
- " for (var ind in mpl.extensions) {\n",
- " var fmt = mpl.extensions[ind];\n",
- " var option = $(\n",
- " '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
- " fmt_picker.append(option);\n",
- " }\n",
- "\n",
- " // Add hover states to the ui-buttons\n",
- " $( \".ui-button\" ).hover(\n",
- " function() { $(this).addClass(\"ui-state-hover\");},\n",
- " function() { $(this).removeClass(\"ui-state-hover\");}\n",
- " );\n",
- "\n",
- " var status_bar = $('');\n",
- " nav_element.append(status_bar);\n",
- " this.message = status_bar[0];\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
- " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
- " // which will in turn request a refresh of the image.\n",
- " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.send_message = function(type, properties) {\n",
- " properties['type'] = type;\n",
- " properties['figure_id'] = this.id;\n",
- " this.ws.send(JSON.stringify(properties));\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.send_draw_message = function() {\n",
- " if (!this.waiting) {\n",
- " this.waiting = true;\n",
- " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
- " }\n",
- "}\n",
- "\n",
- "\n",
- "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
- " var format_dropdown = fig.format_dropdown;\n",
- " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
- " fig.ondownload(fig, format);\n",
- "}\n",
- "\n",
- "\n",
- "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
- " var size = msg['size'];\n",
- " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
- " fig._resize_canvas(size[0], size[1]);\n",
- " fig.send_message(\"refresh\", {});\n",
- " };\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
- " var x0 = msg['x0'] / mpl.ratio;\n",
- " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
- " var x1 = msg['x1'] / mpl.ratio;\n",
- " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
- " x0 = Math.floor(x0) + 0.5;\n",
- " y0 = Math.floor(y0) + 0.5;\n",
- " x1 = Math.floor(x1) + 0.5;\n",
- " y1 = Math.floor(y1) + 0.5;\n",
- " var min_x = Math.min(x0, x1);\n",
- " var min_y = Math.min(y0, y1);\n",
- " var width = Math.abs(x1 - x0);\n",
- " var height = Math.abs(y1 - y0);\n",
- "\n",
- " fig.rubberband_context.clearRect(\n",
- " 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio);\n",
- "\n",
- " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
- " // Updates the figure title.\n",
- " fig.header.textContent = msg['label'];\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
- " var cursor = msg['cursor'];\n",
- " switch(cursor)\n",
- " {\n",
- " case 0:\n",
- " cursor = 'pointer';\n",
- " break;\n",
- " case 1:\n",
- " cursor = 'default';\n",
- " break;\n",
- " case 2:\n",
- " cursor = 'crosshair';\n",
- " break;\n",
- " case 3:\n",
- " cursor = 'move';\n",
- " break;\n",
- " }\n",
- " fig.rubberband_canvas.style.cursor = cursor;\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
- " fig.message.textContent = msg['message'];\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
- " // Request the server to send over a new figure.\n",
- " fig.send_draw_message();\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
- " fig.image_mode = msg['mode'];\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.updated_canvas_event = function() {\n",
- " // Called whenever the canvas gets updated.\n",
- " this.send_message(\"ack\", {});\n",
- "}\n",
- "\n",
- "// A function to construct a web socket function for onmessage handling.\n",
- "// Called in the figure constructor.\n",
- "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
- " return function socket_on_message(evt) {\n",
- " if (evt.data instanceof Blob) {\n",
- " /* FIXME: We get \"Resource interpreted as Image but\n",
- " * transferred with MIME type text/plain:\" errors on\n",
- " * Chrome. But how to set the MIME type? It doesn't seem\n",
- " * to be part of the websocket stream */\n",
- " evt.data.type = \"image/png\";\n",
- "\n",
- " /* Free the memory for the previous frames */\n",
- " if (fig.imageObj.src) {\n",
- " (window.URL || window.webkitURL).revokeObjectURL(\n",
- " fig.imageObj.src);\n",
- " }\n",
- "\n",
- " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
- " evt.data);\n",
- " fig.updated_canvas_event();\n",
- " fig.waiting = false;\n",
- " return;\n",
- " }\n",
- " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
- " fig.imageObj.src = evt.data;\n",
- " fig.updated_canvas_event();\n",
- " fig.waiting = false;\n",
- " return;\n",
- " }\n",
- "\n",
- " var msg = JSON.parse(evt.data);\n",
- " var msg_type = msg['type'];\n",
- "\n",
- " // Call the \"handle_{type}\" callback, which takes\n",
- " // the figure and JSON message as its only arguments.\n",
- " try {\n",
- " var callback = fig[\"handle_\" + msg_type];\n",
- " } catch (e) {\n",
- " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
- " return;\n",
- " }\n",
- "\n",
- " if (callback) {\n",
- " try {\n",
- " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
- " callback(fig, msg);\n",
- " } catch (e) {\n",
- " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
- " }\n",
- " }\n",
- " };\n",
- "}\n",
- "\n",
- "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
- "mpl.findpos = function(e) {\n",
- " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
- " var targ;\n",
- " if (!e)\n",
- " e = window.event;\n",
- " if (e.target)\n",
- " targ = e.target;\n",
- " else if (e.srcElement)\n",
- " targ = e.srcElement;\n",
- " if (targ.nodeType == 3) // defeat Safari bug\n",
- " targ = targ.parentNode;\n",
- "\n",
- " // jQuery normalizes the pageX and pageY\n",
- " // pageX,Y are the mouse positions relative to the document\n",
- " // offset() returns the position of the element relative to the document\n",
- " var x = e.pageX - $(targ).offset().left;\n",
- " var y = e.pageY - $(targ).offset().top;\n",
- "\n",
- " return {\"x\": x, \"y\": y};\n",
- "};\n",
- "\n",
- "/*\n",
- " * return a copy of an object with only non-object keys\n",
- " * we need this to avoid circular references\n",
- " * http://stackoverflow.com/a/24161582/3208463\n",
- " */\n",
- "function simpleKeys (original) {\n",
- " return Object.keys(original).reduce(function (obj, key) {\n",
- " if (typeof original[key] !== 'object')\n",
- " obj[key] = original[key]\n",
- " return obj;\n",
- " }, {});\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.mouse_event = function(event, name) {\n",
- " var canvas_pos = mpl.findpos(event)\n",
- "\n",
- " if (name === 'button_press')\n",
- " {\n",
- " this.canvas.focus();\n",
- " this.canvas_div.focus();\n",
- " }\n",
- "\n",
- " var x = canvas_pos.x * mpl.ratio;\n",
- " var y = canvas_pos.y * mpl.ratio;\n",
- "\n",
- " this.send_message(name, {x: x, y: y, button: event.button,\n",
- " step: event.step,\n",
- " guiEvent: simpleKeys(event)});\n",
- "\n",
- " /* This prevents the web browser from automatically changing to\n",
- " * the text insertion cursor when the button is pressed. We want\n",
- " * to control all of the cursor setting manually through the\n",
- " * 'cursor' event from matplotlib */\n",
- " event.preventDefault();\n",
- " return false;\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
- " // Handle any extra behaviour associated with a key event\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.key_event = function(event, name) {\n",
- "\n",
- " // Prevent repeat events\n",
- " if (name == 'key_press')\n",
- " {\n",
- " if (event.which === this._key)\n",
- " return;\n",
- " else\n",
- " this._key = event.which;\n",
- " }\n",
- " if (name == 'key_release')\n",
- " this._key = null;\n",
- "\n",
- " var value = '';\n",
- " if (event.ctrlKey && event.which != 17)\n",
- " value += \"ctrl+\";\n",
- " if (event.altKey && event.which != 18)\n",
- " value += \"alt+\";\n",
- " if (event.shiftKey && event.which != 16)\n",
- " value += \"shift+\";\n",
- "\n",
- " value += 'k';\n",
- " value += event.which.toString();\n",
- "\n",
- " this._key_event_extra(event, name);\n",
- "\n",
- " this.send_message(name, {key: value,\n",
- " guiEvent: simpleKeys(event)});\n",
- " return false;\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
- " if (name == 'download') {\n",
- " this.handle_save(this, null);\n",
- " } else {\n",
- " this.send_message(\"toolbar_button\", {name: name});\n",
- " }\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
- " this.message.textContent = tooltip;\n",
- "};\n",
- "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
- "\n",
- "mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
- "\n",
- "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
- " // Create a \"websocket\"-like object which calls the given IPython comm\n",
- " // object with the appropriate methods. Currently this is a non binary\n",
- " // socket, so there is still some room for performance tuning.\n",
- " var ws = {};\n",
- "\n",
- " ws.close = function() {\n",
- " comm.close()\n",
- " };\n",
- " ws.send = function(m) {\n",
- " //console.log('sending', m);\n",
- " comm.send(m);\n",
- " };\n",
- " // Register the callback with on_msg.\n",
- " comm.on_msg(function(msg) {\n",
- " //console.log('receiving', msg['content']['data'], msg);\n",
- " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
- " ws.onmessage(msg['content']['data'])\n",
- " });\n",
- " return ws;\n",
- "}\n",
- "\n",
- "mpl.mpl_figure_comm = function(comm, msg) {\n",
- " // This is the function which gets called when the mpl process\n",
- " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
- "\n",
- " var id = msg.content.data.id;\n",
- " // Get hold of the div created by the display call when the Comm\n",
- " // socket was opened in Python.\n",
- " var element = $(\"#\" + id);\n",
- " var ws_proxy = comm_websocket_adapter(comm)\n",
- "\n",
- " function ondownload(figure, format) {\n",
- " window.open(figure.imageObj.src);\n",
- " }\n",
- "\n",
- " var fig = new mpl.figure(id, ws_proxy,\n",
- " ondownload,\n",
- " element.get(0));\n",
- "\n",
- " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
- " // web socket which is closed, not our websocket->open comm proxy.\n",
- " ws_proxy.onopen();\n",
- "\n",
- " fig.parent_element = element.get(0);\n",
- " fig.cell_info = mpl.find_output_cell(\"\");\n",
- " if (!fig.cell_info) {\n",
- " console.error(\"Failed to find cell for figure\", id, fig);\n",
- " return;\n",
- " }\n",
- "\n",
- " var output_index = fig.cell_info[2]\n",
- " var cell = fig.cell_info[0];\n",
- "\n",
- "};\n",
- "\n",
- "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
- " var width = fig.canvas.width/mpl.ratio\n",
- " fig.root.unbind('remove')\n",
- "\n",
- " // Update the output cell to use the data from the current canvas.\n",
- " fig.push_to_output();\n",
- " var dataURL = fig.canvas.toDataURL();\n",
- " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
- " // the notebook keyboard shortcuts fail.\n",
- " IPython.keyboard_manager.enable()\n",
- " $(fig.parent_element).html('');\n",
- " fig.close_ws(fig, msg);\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.close_ws = function(fig, msg){\n",
- " fig.send_message('closing', msg);\n",
- " // fig.ws.close()\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
- " // Turn the data on the canvas into data in the output cell.\n",
- " var width = this.canvas.width/mpl.ratio\n",
- " var dataURL = this.canvas.toDataURL();\n",
- " this.cell_info[1]['text/html'] = '';\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.updated_canvas_event = function() {\n",
- " // Tell IPython that the notebook contents must change.\n",
- " IPython.notebook.set_dirty(true);\n",
- " this.send_message(\"ack\", {});\n",
- " var fig = this;\n",
- " // Wait a second, then push the new image to the DOM so\n",
- " // that it is saved nicely (might be nice to debounce this).\n",
- " setTimeout(function () { fig.push_to_output() }, 1000);\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._init_toolbar = function() {\n",
- " var fig = this;\n",
- "\n",
- " var nav_element = $('');\n",
- " nav_element.attr('style', 'width: 100%');\n",
- " this.root.append(nav_element);\n",
- "\n",
- " // Define a callback function for later on.\n",
- " function toolbar_event(event) {\n",
- " return fig.toolbar_button_onclick(event['data']);\n",
- " }\n",
- " function toolbar_mouse_event(event) {\n",
- " return fig.toolbar_button_onmouseover(event['data']);\n",
- " }\n",
- "\n",
- " for(var toolbar_ind in mpl.toolbar_items){\n",
- " var name = mpl.toolbar_items[toolbar_ind][0];\n",
- " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
- " var image = mpl.toolbar_items[toolbar_ind][2];\n",
- " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
- "\n",
- " if (!name) { continue; };\n",
- "\n",
- " var button = $('');\n",
- " button.click(method_name, toolbar_event);\n",
- " button.mouseover(tooltip, toolbar_mouse_event);\n",
- " nav_element.append(button);\n",
- " }\n",
- "\n",
- " // Add the status bar.\n",
- " var status_bar = $('');\n",
- " nav_element.append(status_bar);\n",
- " this.message = status_bar[0];\n",
- "\n",
- " // Add the close button to the window.\n",
- " var buttongrp = $('');\n",
- " var button = $('');\n",
- " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
- " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
- " buttongrp.append(button);\n",
- " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
- " titlebar.prepend(buttongrp);\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._root_extra_style = function(el){\n",
- " var fig = this\n",
- " el.on(\"remove\", function(){\n",
- "\tfig.close_ws(fig, {});\n",
- " });\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._canvas_extra_style = function(el){\n",
- " // this is important to make the div 'focusable\n",
- " el.attr('tabindex', 0)\n",
- " // reach out to IPython and tell the keyboard manager to turn it's self\n",
- " // off when our div gets focus\n",
- "\n",
- " // location in version 3\n",
- " if (IPython.notebook.keyboard_manager) {\n",
- " IPython.notebook.keyboard_manager.register_events(el);\n",
- " }\n",
- " else {\n",
- " // location in version 2\n",
- " IPython.keyboard_manager.register_events(el);\n",
- " }\n",
- "\n",
- "}\n",
- "\n",
- "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
- " var manager = IPython.notebook.keyboard_manager;\n",
- " if (!manager)\n",
- " manager = IPython.keyboard_manager;\n",
- "\n",
- " // Check for shift+enter\n",
- " if (event.shiftKey && event.which == 13) {\n",
- " this.canvas_div.blur();\n",
- " // select the cell after this one\n",
- " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
- " IPython.notebook.select(index + 1);\n",
- " }\n",
- "}\n",
- "\n",
- "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
- " fig.ondownload(fig, null);\n",
- "}\n",
- "\n",
- "\n",
- "mpl.find_output_cell = function(html_output) {\n",
- " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
- " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
- " // IPython event is triggered only after the cells have been serialised, which for\n",
- " // our purposes (turning an active figure into a static one), is too late.\n",
- " var cells = IPython.notebook.get_cells();\n",
- " var ncells = cells.length;\n",
- " for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
- " data = data.data;\n",
- " }\n",
- " if (data['text/html'] == html_output) {\n",
- " return [cell, data, j];\n",
- " }\n",
- " }\n",
- " }\n",
- " }\n",
- "}\n",
- "\n",
- "// Register the function which deals with the matplotlib target/channel.\n",
- "// The kernel may be null if the page has been refreshed.\n",
- "if (IPython.notebook.kernel != null) {\n",
- " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
- "}\n"
- ],
+ "image/png": "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\n",
"text/plain": [
- ""
+ "