replot/Examples.ipynb

10360 lines
908 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/phyks/.local/share/virtualenvs/physique/lib/python3.5/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.\n",
" \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n"
]
}
],
"source": [
"import replot\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" figure.plot(np.sin)\n",
" figure.plot(np.cos)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" figure.plot(np.sin, (-2, 2))"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" x = np.linspace(-np.pi, np.pi, 200)\n",
" figure.plot(np.sin, x)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" x = range(10)\n",
" figure.plot(x)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" x = range(10)\n",
" figure.plot(x, x)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nO29C3RU2Xmm7e522h5fYjsBY9MNCKmq/iQee+zcZ+I4meR3LjMrGWclTrhbCDHipsBAY5jAsliBDLAI0A2NG7eBGeS/Uf4GB0gDaaAxIqgdtS3M1UampJJKdT0gaOjEbqfbzZ7vO+dIqsa6q07t+r56n7XepapSXc7Drg0v59Q+9Y53AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQZyKRyL+Ew+HPDHGfjlAoVDWW16HX2E5x6Lleo+f62Fieayjo+X+LXus+XXw4n89Lz/lZ2v5W+nmPfm6knzPo5/V8vgYAAAAAwKBQAZnLRYcKz/8a6r5UVL5A900Mdp+BitNYCyA99tfpeX9UVlb2kdE+x0DQ8/5v2r76B16PPd56R54LIJc/eu7l+XxOAAAAAIARQYXkW1R0blKydPWnBrsv3aeS0jXYfajc/LZfnB554HXGWgBnDfXaw6BfvwIXwDcrKip+J5/POQwGHVcAAAAAlBDl5eW/zCWHys7v8d41Phw5yH0/Tb9/nfJjPuTLh2Hp8nT+He/x41JDmUSXf8jP2XMfeu7VfJ8HC2BZWdnP0f1e4OLJexXp97smTpz4nv5em363Lve16edVf5s+QM/5LD/eL7HH6bZIz+Pod3V0//N0+1/TzxT9vNbPc/9PyhuUf8vZ5sd7CiDlT+m27/MhW8qpKVOmfDTn+d/Fe07p9ja6z2362Uj55AB/fmF/2/k5f8ivQ39ev/HgXtXx48e/j67/H7q9mwsv5S/9P585/mv+xB7WB5/DL7T/P/38cs+fC98+adKkiXT5OUrS/3N/jv7Mxw005gAAAABQCBcFygX/cgOVhqbB7u8XjZ/YC9dTAPlyzp6zhx54bG8BfOyxx37WLyZ/SVff+fjjj/8MlyvKV0by2lwg6fYz9LzjqVC+2/+MYFdPkfQL4Bt02xq6+ijfZ6A/hwH2AN6n27/GpWzcuHHv5z8fvm/O4/5PTil8mB6ziD+jyMV0IA//z+o/D+RFl/dRmqdOnTqBt5d+/1W/nOYWwLftmeznOf63/5gv0NVHfO9H+bOG9LvNfJ3/jOi59vP2D7StAAAAAFAGlYAP0j/+P6BS8N/5OpcSLhZUXj4+0GNGWAAH/Awg/fwfD5ZN3hvGeyHf8UBxHOi1+bOA/uv++5y7vZPud4ue/8/916kb6jOL/vYPeAiYbn8s5zYueN/ly36J5dcPPfBcNwbbk5r7Z9WP10P8Z0Cv8/s9v+fi6e/5HGkBfDn3den6nzz4Z8FuvD28Z3CwPx8AAAAAKIEXIvAhSd675d/0kF9enhnoMfkqgHxo0t9DdacndNtdLqS5h1gHe20qqr/Cr/PgYWO6Xwvd/oS/LXVD7dX0t2dYnwHM3Qa6/Kv+HsJch1fp57/Szy8O8loDFkC6/cP8e8rPP+B0a6QFkPL/PfC6X+TPHz64vfxnzgtshvozAgAAAIAC+HNtfglLUzIcf4/gazml8G1QUZg9VAGkx//mMPYAfomuvzTC7e1vD+CDeywf4UPL9Pyf91+H9wD+01DPTffZO9ICSK87Oex9fvLxkXgMZw8g/f4Pcrbjpx/YA/iL/Lq8ZzDnOf6qnz2Ab/Phx9Pt0ZFsKwAAAAAU4S/64MUIn+G9TjkJ8V5B+v3i/h5H9/8sL2Dgz+w9cHtvqeHFDn4x+oXc++QWQF4swosm+JAqPde/67mNrv+3gbZ5oM8A8mfYeNv5eeg+W/kw54QJE97rew6rANL9/sY/ZPpwzm3D2dP2dcpRLoN8nUsZlzf+/N5ArzVEAez5DOA3ueDy3k26vDv3M4D+IpG7/l5OLoyf5D/boQogP45u66Tf/TWXSr6N/9x6DpcDAAAAQDlUAv6e8uIAv+OFFD+xWtaH97DxYpFu/zDiNP8xb+WWmnDfCZvv9BwOpcux3FXAvFqXt4P3QPqHIq/5izX6pb8CyJ9j9FcBJ/3DpCeofP0/Pb8fbgGkx0zhAthzaDR3FfA7BimA/irgL+WsEubVtYcGO1fhg39WDz5nzipgXlXMq5trKdncosZFmffm+Suxj/NK66EKIMOH18PewpW4XyJv0GN3DvXnAwAAAAAACoi/WIf31v6a7W0BAACR8KEZ+l/xt+kv0kt8iIX+1/8J29sEAAC5+OdS5K/Ve9hfacx7XPmr4vJ6QmoAACgJ+H/RfNiKTz7L1/2T2l61vV0AAJBLKBSqoL+rLoe97wrmk0Hzya3DtrcLAABEQv+r/iX6y7Q19zb/Mzv9nrUfAAAAAAAIh1e9+SeI/XX/+h/7H8b+nO1tAwAAAAAAAeGv6mv0Pwe4gw8BU/6r7e0CAAAAAACF4VH/lA/lg93p/v37BgAAAADFDf97/erpfzRt1bNM9At/YQpVJoAAcs/NFQ6HN1AODvUYflN1d79mbt3SFXaCm7zATW40+8FNZjS5ObGk6di4wS1+nK59e1EAQR+RSOSrfDoF/+Sn+3vOhj8YPDn4zXXzpq6wE9zkBW5yo9kPbjKjxS3VeN60Lap2i19bbY1JNzW7ToXoFUAxGiaH5okPNz3R7KbdD24yI93NSd4y8d3P9O716/jbzSbbke51s90fgHAkTw7NEx9u9rcFbvCDm+xIdstcvGbaVy7zyt/8OSZ57IRxnHtvc7PdH4BwpE4OzRMfbnCTGM1+cJMZiW5O9q5JPH/QRKtmuOUvtna1yXw32q+b7f4AhCNtcmie+HCDm+Ro9oObzEhzy97oNLH1dd5ev8pppqu+3jiZOwO62e4PQDiSJofmiQ83uEmPZj+4yYwkt9RLZ03bgrneQo9li0z6lQtDutnuD0A4UiaH5okPN7hpiGY/uMmMBDcncdN0Pr2jd6FH55PbjBPPDsvNdn8Awin2yaF54sMNbpqi2Q9uMlPsbumWS6Z9+RKv/NVUmuTJ0yNys90fgHCKeXJonvhwg5u2aPaDm8wUq5uTedV0PXfAROdO9xZ6rFtjsq2xEbvZ7g9AOMU4OTRPfLjBTaObdj+4yUwxunHRi9Wt8fb6UQHsamhwV/6Oxs12fwDCKbbJoXniww1uWt20+8FNZorNLfniKfdQL5e/9hW1Jt1yeUxutvsDEE4xTQ7NEx9ucNPspt0PbjJTLG68qKNz+9a+hR67drqLP8bqZrs/AOEUw+TQPPHhBrdScNPuBzeZKQa3dHOLaVu60Du9y8IqkzrTmDc32/0BCMf25NA88eEGt1Jx0+4HN5mx6cYncO7av989obO70GP9OpONxvPqZrs/AOFg4ssL3GRGs5t2P7jJjC03/uq22NpV3iHfqpkmcfDQqBZ6DOVmuz8A4WDiywvcZEazm3Y/uMlMod0c555JvnDcRKtnews9Vi4zmYvXAnOz3R+AcDDx5QVuMqPZTbsf3GSmkG7ZjrTp2LKpd6FH/Nndxkl1B+pmuz8A4WDiywvcZEazm3Y/uMlModzSTc2mrbbGW+ixuNqkzr1cEDfb/QEIBxNfXuAmM5rdtPvBTWaCdnPSt018757evX4dGzeYbHuyYG62+wMQDia+vMBNZjS7afeDm8wE6Za5ct20r17hlb95s0ziyFH3M4CFdLPdH4BwMPHlBW4yo9lNux/cZCYINy55icNH3NLnLvSgEpi52mrFzXZ/AMLBxJcXuMmMZjftfnCTmXy78eFdPszbu9Bj3173MLAtN9v9AQgHE19e4CYzmt20+8FNZvLplmo8b9oWVXsLPWpr3IUftt1s9wcgHEx8eYGbzGh20+4HN5nJh5uTvGXiu5/pW+jxt5vdU74Ug5vt/gCEg4kvL3CTGc1u2v3gJjNjdeOTOLevXOqVv/lzTPLYiYIu9BjKzXZ/AMLBxJcXuMmMZjftfnCTmdG68de2JZ4/aKJVM7zv8V272v16N9s+D7rZ7g9AOJj48gI3mdHspt0PbjIzGrfsjU4TW1/n7fWrnGa66uuNk7lj3aU/N9v9AQgHE19e4CYzmt20+8FNZkbqlnrprGlbMNdb6LFskUm/csG6w2ButvsDEA4mvrzATWY0u2n3g5vMDNfNSdw0nU/v6F3o0fnkNuPEs9a3fyg32/0BCKfUJ77EwE1mNLtp94ObzAzHLd1yybQvX+KVv5pKkzx52vp2D9fNdn8AwinliS81cJMZzW7a/eAmM4O5OZlXTddzB0x07nRvoce6NSbbGrO+zSNxs90fgHBKceJLD9xkRrObdj+4ycxAblz0YnVrvL1+VAC7Ghrclb+2t3ekbrb7AygiIpHIfwmHwxcoF+nyFcqcoR5TahNfQ+AmM5rdtPvBTWb6c0u+eMo91Ot+j++KWpNuuWx9O0frVoheAYRAhe92KBT6GF+eOnXqFCqCr0+YMOG9gz2mlCa+lsBNZjS7afeDm8zkuvGijs7tW/sWeuza6S7+sL2NY3ErTLMAIqACeKu8vPzTfJkK4CeoACbo4jsHe0wpTHzb2wI3uGl30+4HN5npccs0t5i2pQu907ssrDKpM43Wty0fbgUpFkAGVP5+l0sgpZPK392KiorfGeox2ic+3GQFbnKj2Q9uQpO9Y7oPNrgndHYXeqxfZ7LRuP3tytO4FaJXABk8QqXvLJW+3+ArVAZ/mYpg+vHHH/+ZwR7EE7+723szaQo7wU1e4CY3mv3gJi/Z70VNbO0q75Bv1UyTOHjI3HTuWt+ufI5bYaoFKHqo+P0SFb7W3Nvo+rd4r+BgjzMAAACAEu7fv2/uNp4xbfPneJ/1+5/LzY86O2xvViAE2yqAGKgAfjgcDt8rKyv7Of96iApgdygUenywx/GbSNv//Hr+dwQ3eYGb3Gj2g5uMOJ1p07llU+9Cj65nd5u3/u3fVLj1N26FaRdABFT6/oJP/+KfBuYyXx/qMTzx+c1k+/MMQXw+Am7yAje50ewHt+JPqqnZtNX+d2+hx+JqkzrXpMZtoHErRK8AitE8OeAmL3CTG81+cCveOOnbJr53T+9ev46NG0y2PanCbahxs90fgHA0Tw64yQvc5EazH9yKM5kr10376hVe+Zs3yySOHDWOc0+F23DGzXZ/AMLRPDngJi9wkxvNfnArrnDJSxw+4pY+9xs9qARmrraqcBvJuNnuD0A4micH3OQFbnKj2Q9uxRM+vMuHeXsO+cb37XUPA2twG+m42e4PQDiaJwfc5AVucqPZD27FkVTjedO2qNpb6FFbY9JNzWrcRjNutvsDEI7myQE3eYGb3Gj2g5vdOMlbJr77mb6FHls2m2xHWoXbWMbNdn8AwtE8OeAmL3CTG81+cLOXzMVrpn3lUq/8zZ9jksdOvG2hh2S3sY6b7f4AhKN5csBNXuAmN5r94Fb4ONm7JvH8QROtmuF9j+/a1Sbz3agKt3yNm+3+AISjeXLATV7gJjea/eBW2GRvdJrY+jpvr1/lNNNVX2+czB0VbvkcN9v9AQhH8+SAm7zATW40+8GtcEm9dNa0LZjrLfRYtsikX7mgxi3f42a7PwDhaJ4ccJMXuMmNZj+4BR8ncdN0Pr2jd6FH55PbjBPPqnALatxs9wcgHM2TA27yAje50ewHt2CTbrlk2pcv8cpfTaVJnjytxi3IcbPdH4BwNE8OuMkL3ORGsx/cgomTedV0PXfAROdO9xZ6rFtjsq0xFW6FGDfb/QEIR/PkgJu8wE1uNPvBLf/hoherW+Pt9aMC2NXQ4K781eBWqHGz3R+AcDRPDrjJC9zkRrMf3PKb5Iun3EO97vf4rqg16ZbLatwKOW62+wMQjubJATd5gZvcaPaDW37Cizo6t2/tW+ixa6e7+EODm41xs90fgHA0Tw64yQvc5EazH9zGnnRzi2lbutA7vcvCKpM606jGzda42e4PQDiaJwfc5AVucqPZD26jD5/AuWv/fveEzu5Cj/XrTDYaV+Fme9xs9wcgHM2TA27yAje50ewHt9GFv7ottnaVd8i3aqZJHDyU94UepTxutvsDEI7myQE3eYGb3Gj2g9vI4jj3TPKF4yZaPdtb6LFymclcvKbCrViCAgjGjObJATd5gZvcaPaD2/CT7Uibji2behd6xJ/dbZxUtwq3YgoKIBgzmicH3OQFbnKj2Q9uw0u6qdm01dZ4Cz0WV5vUuSY1bsUWFEAwZjRPDrjJC9zkRrMf3AaPk75t4nv39O7169i4wWTbkyrcijUogGDMaJ4ccJMXuMmNZj+4DZzMleumffUKr/zNm2USR466nwG07VUK42a7PwDhaJ4ccJMXuMmNZj+4/WS45CUOH3FLn7vQg0pg5mqrdZ9SGjfb/QEIR/PkgJu8wE1uNPvB7e3hw7t8mLd3oce+ve5hYNsupTZutvsDEI7myQE3eYGb3Gj2g1tfUo3nTduiam+hR22Nu/DDtkOpjpvt/gCEo3lywE1e4CY3mv3g9ppxkrdMfPczfQs9tmx2T/lie/tLedxs9wcgHM2TA27yAje50exX6m58Emc+mbNb/ubPMcljJ4pmoUcpj5vt/gCEo3lywE1e4CY3mv1K1Y2/ti3x/EETrZrhfY/v2tXu17vZ3maMGwogyAOaJwfc5AVucqPZrxTdsjc6TWx9nbfXr3Ka6aqvN07mjvXtxbj1udnuD6BIePzxx38mHA5fpHyHE4lEvk95o6ys7IODPU7z5ICbvMBNbjT7lZpb6qWzpm3BXG+hx7JFJv3KBevbiXH7SbdC9QsgDCp/K6gIHh3qfponB9zkBW5yo9mvVNycxE3T+fSO3oUenU9uM048a30bMW79uxWiSwCBUPn7bigU+qOh7qd5csBNXuAmN5r9SsEt03LJtC9f4pW/mkqTPHna+rZh3AZ3K0SXAMKoqKj4T5FIJE0XHx7qvponB9zkBW5yo9lPs9vN7Kvm9pFDJjp3urfQY90ak22N2d8ujNuQbgWoE0AaVP72UDYN5748Obq7vTeTprAT3OQFbnKj2U+rW/b7MROrW+Pt9aMCmGhoMDedu9a3C+M2PLeguwQQxoQJE95L5e+18vLyyHDubwAAAJQcr7183rQvqPQ+6/fFpeb19qjtTQIjJOg+AYQRCoXmhcPhfxru/flNpPV/R3CTF7jJjWY/TW5OV9Z0Prm173t8d+00b73+ugo3zePWn1uQXQIIJBKJNFHmDPf+PDn4zWT78wz47Afc4CY7mv20uKWbW0zb0oXe6V0WVpnUmUY1bprHbSC3ILsEKAE0Tw64yQvc5Eazn3Q3PoFz1/797gmd3YUe69eZbDSuwk3zuA3lZrs/AOFonhxwkxe4yY1mP8lu/NVtsbWrvEO+VTNN4uAh9yveNLhpHrfhuNnuD0A4micH3OQFbnKj2U+im+PcM8kXjpto9Wy3/LWvXGYyF6+pcNM8biNxs90fgHA0Tw64yQvc5EaznzS3bEfadGzZ1LfQ49ndxkl1q3DTPG4jdbPdH4BwNE8OuMkL3ORGs58kt3RTs2mrrfEWeiyuNqlzTWrcNI/baNxs9wcgHM2TA27yAje50ewnwc1J3zbxvXt69/p1bNxgsu1JFW6ax20sbrb7AxCO5skBN3mBm9xo9it2t8yV66Z99Qqv/M2bZRJHjrqfAdTgpnncxupmuz8A4WieHHCTF7jJjWa/YnXjkpc4fMQtfe5CDyqBmautKtw0j1u+3Gz3ByAczZMDbvICN7nR7FeMbnx4lw/z9i702LfXPQyswU3zuOXTzXZ/AMLRPDngJi9wkxvNfsXmlmo8b9oWVXsLPWpr3IUfWtw0j1u+3Wz3ByAczZMDbvICN7nR7Fcsbk7ylonvfqZvoceWze4pXzS4aR63oNxs9wcgHM2TA27yAje50exXDG58Emc+mbNb/ubPMcljJ4a90KPY3TSPW5ButvsDEI7myQE3eYGb3Gj2s+nGX9uWeP6giVbN8L7Hd+1q9+vdNLhpHrdCuNnuD0A4micH3OQFbnKj2c+WW/ZGp4mtr/P2+lVOM1319cbJ3FHhpnncCuVmuz8A4WieHHCTF7jJjWY/G26pl86atgVzvYUeyxaZ9CsX1LhpHrdCutnuD0A4micH3OQFbnKj2a+Qbk7ipul8ekfvQo/OJ7cZJ55V4aZ53Gy42e4PQDiaJwfc5AVucqPZr1Bu6ZZLpn35Eq/81VSa5MnTatw0j5stN9v9AQhH8+SAm7zATW40+wXt5mReNV3PHTDRudO9hR7r1phsa0yFm+Zxs+1muz8A4WieHHCTF7jJjWa/IN246MXq1nh7/agAdjU0uCt/NbjZjnY32/0BCEfz5ICbvMBNbjT7BeWWfPGUe6jX/R7fFbUm3XJZjVsxRLub7f4AhKN5csBNXuAmN5r98u3Gizo6t2/tW+ixa6e7+EODWzFFu5vt/gCEo3lywE1e4CY3mv3y6ZZubjFtSxd6p3dZWGVSZxrVuBVbtLvZ7g9AOJonB9zkBW5yo9kvH258Aueu/fvdEzq7Cz3WrzPZaFyFW7FGu5vt/gCEo3lywE1e4CY3mv3G6sZf3RZbu8o75Fs10yQOHiroQg+Mm/1tCcLNdn8AwtE8OeAmL3CTG81+o3VznHsm+cJxE62e7S30WLnMZC5es+6DcZMfFEAwZjRPDrjJC9zkRrPfaNyyHWnTsWVT70KP+LO7jZPqtu6CcdMRFEAwZjRPDrjJC9zkRrPfSN3STc2mrbbGW+ixuNqkzjVZd8C46QoKIBgzmicH3OQFbnKj2W+4bk76tonv3dO7169j4waTbU9a336Mm/1tCcLNdn8AwtE8OeAmL3CTG81+w3HLXLlu2lev8MrfvFkmceSo+xlA29uOcdPrZrs/AOFonhxwkxe4yY1mv8HcuOQlDh9xS5+70INKYOZqq/Vtxrjpd7PdH4BwNE8OuMkL3ORGs99Abnx4lw/z9i702LfXPQxse3sxbqXhZrs/gOLi0VAotDMcDt+IRCKXKfVDPUDz5ICbvMBNbjT79eeWajxv2hZVews9amvchR+2txPjVlpuhSgVQAhU/LZTnuq5XlFR8eGhHqN5csBNXuAmN5r9ct2c5C0T3/1M30KPLZvdU77Y3kaMW+m5BdsogBgmTpz4Hip/98aPH/++kTxO8+SAm7zATW40+/W4ZS5dM+0rl3rlb/4ckzx2QsRCj1IfN61uQfUJIIzy8vKPRyKRDspGyrepDJ6rqKj4naEep3lywE1e4CY3qv2cu+bOiX8w0aoZ3vf4rl3tfr2b9e3CuJW0WyG6BRBAKBT6RSp99+nnTL5Olz9JRfAWXR8/2ON4cnR3e28mTWEnuMkL3ORGq58T7TQd6+u8vX6V00zX1+rNzewd69uFcYNbYdoFKHoee+yxn6XC9yZdfKjnNrr+raH2AhoAAAD98i/fajbti6q8z/otX2x++P3rtjcJgF4CLxZADuFw+EUqfH/Il6dMmTKVrt+knx8d7DH8JtL6vyO4yQvc5EaT383kTRPftaPv9C5PbTM//sEPVLhpHrdScytMswAi4NIXiUS+QblC5e8ilcHPDfUYnhz8ZrL9eQZ89gNucJMdLX7plkumffkSr/zVVJrkydNq3DSPWym6FaJXAMVonhxwkxe4yY10Pyfzqul67oCJzp3uLfRYt8ZkW2Mq3DSPWym72e4PQDiaJwfc5AVuciPZj4terG6Nt9ePCmBXQ4NxsndVuGket1J3s90fgHA0Tw64yQvc5EaqX/LFU+6hXvd7fFfUmnTLZTVumscNbiiAYIxonhxwkxe4yY00PyeeNZ3bt/Yu9OjctdM4iZsq3DSPG9z63Gz3ByAczZMDbvICN7mR5JdubjFtSxd63+O7sMqkzjSqcdM8bnB7u5vt/gCEo3lywE1e4CY3EvyczB3TtX+/e0Jnd6HH+nUmG42rcNM8bnDr3812fwDC0Tw54CYvcJObYvfjr26LrV3lHfKtmmkSBw+9baGHZDfN4wa3gd1s9wcgHM2TA27yAje5KVY/x7lnki8cN9Hq2d5Cj5XLTObiNRVumscNbkO72e4PQDiaJwfc5AVuclOMftmOtOnYsqnvGz2e3W2cVLcKN83jBrfhudnuD0A4micH3OQFbnJTbH7ppmbTVlvjLfRYXG1S55rUuGkeN7gN3812fwDC0Tw54CYvcJObYvFz0rdNfO+e3r1+HRs3mGx7UoWb5nGD28jdbPcHIBzNkwNu8gI3uSkGv8yV66Z99Qqv/M2bZRJHjrqfAdTgpnnc4DY6N9v9AQhH8+SAm7zATW5s+nHJSxw+4pY+d6EHlcDM1VYVbprHDW5jc7PdH4BwNE8OuMkL3OTGlh8f3uXDvL0LPfbtdQ8Da3DTPG5wG7ub7f4AhKN5csBNXuAmNzb8Uo3nTduiam+hR22Nu/BDi5vmcYNbftxs9wcgHM2TA27yAje5KaSfk7xl4ruf6VvosWWze8oXDW6axw1u+XWz3R+AcDRPDrjJC9zkplB+fBJnPpmzW/7mzzHJYyfystCjGNw0jxvc8u9muz8A4WieHHCTF7jJTdB+/LVtiecPmmjVDO97fNeudr/eTYOb5nGDW3ButvsDEI7myQE3eYGb3ATpl73RaWLr67y9fpXTTFd9vXEyd1S42Q7cZAYFUDCRSCRDSQ+VoLdD8+SAm7zATW6C8ku9dNa0LZjrLfRYtsikX7mgxq0YAjeZQQEUTCgU+q3hJOjt0Dw54CYvcJObfPs5iZum8+kdvQs9Op/cZpx4VoVbMQVuMoMCCMaM5skBN3mBm9zk0y/dcsm0L1/ilb+aSpM8eVqNW7EFbjKDAqiHR8Ph8HpKO+Ue3xAKhX4/EoksCfqFNU8OuMkL3OQmH35O5lXT9dwBE+FFGSoAACAASURBVJ073VvosW6NybbGVLgVa+AmMyiASqCyt5PK3j9SfpMK4F2+raKiYhJdvhb0a2ueHHCTF7jJzVj9uOjF6tZ4e/2oAHY1NLgrf217aR87uMkMCqASeLEHlcCf9i/f6bm9pwwGiebJATd5gZvcjMUv+eIp91Cv+z2+K2pNuuWydZ9SGTu4yQwKoBKo6CUmTJjwXr7cUwDLyso+SJc7g35tzZMDbvICN7kZjR8v6ujcvrVvoceune7iD9supTR2cJMZFEAlUAHcTdnLJdAvgI/Q9S9Tngr6tTVPDrjJC9zkZqR+6eYW07Z0oXd6l4VVJnWm0bpDKY4d3GQGBVAJ48aNez+Vva9T+XuDfr5F+RFfHz9+/PuCfm3NkwNu8gI3uRmuH5/AuWv/fveEzu5Cj/XrTDYat779pTp2cJMZFEBlhEKh8eXl5b8yderUCYV6Tc2TA27yAje5GY4ff3VbbO0q75Bv1UyTOHioaBZ6lOrYwU1mUAAVQcXvA+FweAZlJf/kzwAW4nU1Tw64yQvc5GYwP8e5Z5IvHDfR6tneQo+Vy0zm4jXr24yxg5vUoAAqgQrfZyivUr4TiUQO088LfB3fBIKJDzc90ew2mF+2I206tmzqXegR/8pu4yRvWd9ejB3cJAcFUAlU9q5S8ZuTexuVv9kjPQ8grxqmXKfHXeQySc/x+aEeo3lywE1e4CY3/fmlm5pNW22Nt9BjcbVJnWuyvp0YO7hpCAqgEqi0vUY/Hn7g5kf820fyPLHy8vKPj+QxmicH3OQFbnKT6+ekb5v43j29e/06Nm4w2fak9W3E2MFNS1AAlUDF7Wv8ub8HbptGqR/h83RMnTr1EyN5jObJATd5gZvc9Phlr1437atXeOVv3iyTOHLU/Qyg7e3D2MFNU1AABUOFr4FywI97ChjKt/3L3/ZPCXNoJM/JBZAec4l+XqZ8deLEieOGeozmyQE3eYGb5Nwzr57+R7f0uQs9qARmrrYWwXZh7OBmf1uCcBt9AwFWCYVCdcPJCJ/zcf8iHz7eRGXw+FCP4cnR3e29mTSFneAmL3CTGSeWNB2bNvQe8u3at9fczNy2vl0YO7hpdhtV+QD6KSsr+wgVwHtD3c8AAMAY+NeLLSa2ZL53UuelC8wPrl2xvUkAlASF6BKgAFBhe3coFPoUlbbP0s/f68lwHz9x4sT38LkEe67TY5fTczUO9Th+E2n93xHc5AVucnIzdcvEv/JM3/f4/u1m8+N/eU2Nn+axg5v8YA+gEvzzADr8PcD088f8k/Imr+od7nNMmTJlKp/6JeczgIepEE4e6nE8OfjNZPvzDPjsB9zgJid8Emc+mbNb/ubPMcljJwx/BlCLn+axg5uOsNPYmgcoCqistVBx+0u+zCeA9n+uoTwR9Gtrnhxwkxe4FXf4a9sSzx800aoZ3iHftavdr3fT4qd57OCmKyiASsg9D2BPASQepdtTQb+25skBN3mBW/Eme6PTxNbXeXv9KqeZrvp642TuqPHTPHZws78tQbgF3Q9AAaDSF588efKH/MvfC4VCH5syZcpHh7OIY6xonhxwkxe4FWdSL501bQvmet/osWyRSTe3qPLTPHZw0+sWdD8ABSASiWylsjfdv7yC0k3J8Ln8gn5tzZMDbvICt+KKk7hpOp/e0bfQ48ltxoln1fhpHju46XcLuh8AC1Dx+82Kioo/fMdPfj1c3tE8OeAmL3ArnqRbLpn25Uu88ldTaZInT6vy0zx2cCsNt6D7AVCO5skBN3mBm/3wQo+uAwdMdO50b6HHujUm2xpT46d57OBWWm62+wMYJeFw+J8p3xwqQW+H5skBN3mBm91w0YvVrfH2+lEB7GpocAuhFj/NYwe30nMLuh+AgIhEIl8YToLeDs2TA27yAjd7Sb54yj3U636P74pak265rMpP89jBrTTdgu4HQDmaJwfc5AVuhQ8v6ujcvrVvoceune7iDy1+mscObqXtZrs/AOFonhxwkxe4FTZ8Ope2pQu907ssrDKpM42q/DSPHdzgZrs/AOFonhxwkxe4FSZ8Aueu/fvdEzq7Cz3WrzPZaFyNn+axgxvcetxs9wcgHM2TA27yArfgw1/dFlu7yjvkWzXTJA4eGvZCDwl+mscObnDLdbPdH0AeCIVC4229tubJATd5gVtwcZx7JvnCcROtnu0t9Fi5zGQuXlPjp3ns4Aa3/txs9QaQR8Lh8I8o/0D5U7r6U4V8bc2TA27yArdgku1Im44tm3oXesSf3W2cVLcaP81jBze4DeRWyK4AAqKsrOwjVP6eiEQil/2vgdtVXl7+K4V4bc2TA27yArf8J93UbNpqa7yFHourTepckyo/zWMHN7gN5laIjgAKSCgU+hQVwG2UNJXC79H1VUEeItY8OeAmL3DLX5z0bRPfu6d3r1/Hxg0m255U46d57OAGt+G4BdULgCWmTp36CSp/WykZSguVwK9T7lEJXBTE62meHHCTF7jlJ5kr10376hVe+Zs3yySOHHU/A6jFT/PYwQ1uw3ULohOAAkOlbwIVvOV8CJjKXpYLYHl5+cd7fk+3/TzlbhCvrXlywE1e4Da2cMlLHD7ilj53oQeVwMzVVjV+mscObnAbqVsQnQAUGCp3r1PpO1JRUfE5uvrO/u5Dv98TxGtrnhxwkxe4jT58eJcP8/Yu9Ni31z0MrMVP89jBDW6jcQuiE4ACw3sAbb225skBN3mB2+iSajxv2hZVews9amvchR+a/GwHbjKj3c1WbwBK0Dw54CYvcBtZnOQtE9/9TN9Cjy2b3VO+aPErlsBNZrS72e4PQDiaJwfc5AVuww+fxJlP5uyWv/lzTPLYicAXemDs7G8L3ODW42a7PwDhaJ4ccJMXuA0d/tq2xPMHTbRqhvc9vmtXu1/vpsWvGAM3mdHuZrs/AOFonhxwkxe4DZ7sjU4TW1/n7fWrnGa66uuNk7lj3Q1jJzdwkxkUQEWEQqF5kUjkDOUKXw+Hw5+h2/486NfVPDngJi9wGzipl86atgVzvYUeyxaZ9CsXrDth7OQHbjKDAqgEKnp1VPgu0M9ZPef7q6ioCPFtQb+25skBN3mB20/GSdw0nU/v6F3o0fnkNuPEs9Z9MHY6AjeZQQFUAhW9OH8fsH/5Vf/mh3IuB4bmyQE3eYHb25NuuWTaly/xyl9NpUmePG3dA2OnK3CTGRRAJfC3f9CPn+LLkUjkDv+cOHHie+hyKujX1jw54CYvcPPiZF41Xc8dMNG5072FHuvWmGxrzLoDxs7+tsANbj1uQfcDUACo6P0dlcC/9i+7BZCurw2FQvuDfm3NkwNu8gK319yiF6tb4+31owLY1dDgrvy1vf0YO7hJi3a3oPsBKAD8TSBU+F7hPX6UNykxvl5RUfHhoF9b8+SAm7yUulvyxVPuoV73e3xX1Jp0y2Xr242xg5vUaHcLuh+AwvEQFb9fDYVCn6fy92t0/eFCvKjmyQE3eSlVN17U0bl9a99Cj1073cUftrcZYwc3ydHuVoiOABSjeXLATV5K0S3d3GLali70Tu+ysMqkzjRa31aMHdw0RLub7f4A8kAoFPqFcDh8knKT8kM/r/PP0TwfPW4u5T497x8PdV/NkwNu8lJKbnwC5679+90TOrsLPdavM9lo3Pp2YuzgpiXa3UbTD0CREYlELlNhe4oK23+ky/8hNyN9rvLy8sn0uJc5KIBwk5ZSceOvboutXeUd8q2aaRIHD4lY6IGxs78tcINbj9voGgcoKqj83aMfD+Xhqfjcgaep+H2Kfp5FAYSbtGh3u3//vkkeO26i1bO9hR4rl5nMxWvWtw1jBze4yQoKoBL4dC9U2D471ueJRCIr6Lm+xJdRAHVPfLjJi9OZNukdf9u70CP+7G7jpLqtbxfGDm5wkxcUQCWUlZV9kMpbK+UEFbd9uRnuc/ifI/xnuvgIXx9JAezu9t5MmsJOcJMXrW7pl5tNW22Nt9BjcbVJn2uyvk0YO7jBTW7YaQy1AxQLVNYOUfn7Pn8OkH5uzM0InmOBfx7BGKXDX0SSpdQM9jgDAAiM+2+8YW4dqO/d65fausm8efdV25sFAFDA2NsHsA4Vtn+dPHnyh/L5nNgDqPt/fnAr/mSvXjftq1d45W/eLJM8etT9DKAGN+1jBzcd0e6Wz84ALEFl7UJZWdlH8vmcVCq/gc8Awk1aNLg5zj2TOHzELX3uQg8qgZmrrSrctI8d3HRFu1s+OwOwBBXAJ6iwfZsyh0rb7+Um6NfWPDngJi/S3bLtSdOxcUPfQo99e42Tvq3CTfvYwc3+tsBtZG5B9wNQAPgzewMkFvRra54ccJMXyW6pxvOmbVG1t9Cjtsakm5rVuGkfO7jBTVpQAMGY0Tw54CYvEt2c5C0T3/1M716/ji2bTbYjrcJN+9jBDW5SgwKojClTpkwtLy//dBlRqNfUPDngJi/S3Pgkzu0rl3rlb/4ckzx2wv0MoAY37WMHN7hJDgqgEqj4fTQSiZynvEHJ+D+bJk2aNDHo19Y8OeAmL1Lc+GvbEs8fNNGqGd73+K5d7X69mwY37WMHN7hpCAqgEsLh8N9Tvjx+/Pj38XX+SQVwF+VI0K+teXLATV4kuGVvdJrY+jpvr1/lNNNVX2+czB0VbtrHDm5w0xIUQCVQ0bsVCoXelXtbWVnZu+n27qBfW/PkgJu8FLtb6qWzpm3BXG+hx7JFJv3KBTVu2scObnDTFBRAJYTD4fby8vJw7m18HauAMfHhVhxxEjdN59M7ehd6dD65zTjxrAo37WMHN7hpdQu6H4ACQAXwi1z26GdtKBT6I/7JpZAurwr6tTVPDrjJSzG6pVsumfblS7zyV1NpkidPq3HTPnZwg5tmt6D7ASgQVPgqKacp3/N/VtLNDwX9uponB9zkpZjcnMyrpuu5AyY6d7q30GPdGpNtjalw0z52cINbKbgF3Q+AcjRPDrjJS7G4cdGL1a3x9vpRAexqaHBX/mpw0z52cINbqbjZ7g8gD4RCoT8vKyv7Ob5cXl4eCYfD5/i7fPly0K+teXLATV6KwS354in3UK/7Pb4rak265bIaN+1jBze4lZJb0P0AFAAqfG1Tp06d4F9+gfIUlcK/oRL4UtCvrXlywE1ebLrxoo7O7Vv7Fnrs2uku/tDgpn3s4Aa3UnQLuh+AAkBF7zX+yad+ofJ3j3/S1Ufo9jtBv7bmyQE3ebHllm5uMW1LF3qnd1lYZVJnGtW4aR87uMGtVN2C7gegAFDp66qoqAhR4fsTutzIt/F5AbkMBv3amicH3OSl0G58Aueu/fvdEzq7Cz3WrzPZaFyFm/axgxvcSt0t6H4ACgAVvScoP+BQ8fszvq28vPx36Xpz0K+teXLATV4K6cZf3RZbu8o75Fs10yQOHhrzQo9icdM+dnCDG9xQANXACz6I8tzrlI8H/bqaJwfc5KUQbo5zzyRfOG6i1bO9hR4rl5nMxWsq3LSPHdzgBrc+t6D7AVCO5skBN3kJ2i3bkTYdWzb1LvSIP7vbOKluFW62o9kPbjKj3c12fwDC0Tw54CYvQbqlm5pNW22Nt9BjcbVJnWtS41YM0ewHN5nR7ma7PwDhaJ4ccJOXINyc9G0T37und69fx8YNJtueVOFWTNHsBzeZ0e5muz8A4WieHHCTl3y7Za5cN+2rV3jlb94skzhy1P0MoAa3YotmP7jJjHY32/0BCEfz5ICbvOTLjUte4vARt/S5Cz2oBGautqpwK9Zo9oObzGh3s90fgHA0Tw64yUs+3PjwLh/m7V3osW+vexhYg1sxR7Mf3GRGu5vt/gCEo3lywE1exuqWajxv2hZVews9amvchR+2nUph3LT7wU1mtLvZ7g9AOJonB9zkZbRuTvKWie9+pm+hx5bN7ilfbPuUyrhp94ObzGh3s90fgHA0Tw64ycto3PgkznwyZ7f8zZ9jksdOWFvoUarjpt0PbjKj3c12fwDC0Tw54CYvI3Hjr21LPH/QRKtmeN/ju3a1+/Vuth1Kcdy0+8FNZrS72e4PQDiaJwfc5GW4btkbnSa2vs7b61c5zXTV1xsnc8f69pfquGn3g5vMaHez3R+AcDRPDrjJy3DcUi+dNW0L5noLPZYtMunmFuvbXerjpt0PbjKj3c12fwDC0Tw54CYvg7k5iZum8+kdvQs9Op/cZpx41vo2Y9z0+8FNZrS72e4PQDiaJwfc5GUgt3TLJdO+fIlX/moqTfLkaevbinErHT+4yYx2N9v9ARQR4XD4JOUS5SLlHOWTQz1G8+SAm7w86MYLPboOHDDRudO9hR7r1phsa8z6dmLcSssPbjKj3a0QvQIIIRQK/XTP5YqKis9xGRzqMZonB9zkJdeNi16sbo23148KYFdDg1sIbW8jxq30/OAmM9rdgm0UQCxU/iop3xnqfponB9zkpcctdfKUe6jX/R7fFbUm3XLZ+rZh3ErXD24yo92tEF0CCCIUCu2n4tdFidPljw11f82TA27y4nRlTeaZnIUeu3a6iz9sbxfGrbT94CYz2t0K0SmAQKj8zaYSeHyo+/Hk6O723kyawk5wk5XMKy2mfdlC7/QuC6tM6huN1rcJ4wY/uMmNdrdCdAkgFCqAP5w8efKHBruPAcAy999803QfbHBP6MzlL7l5vXnzzm3bmwUAAEVNoboEKHLKy8s/MGXKlI/2XPcXgXQN9Th+E2n93xHcij/Z70VNbO0q75Bv1UyTPHTI3H/rLRVumset1PzgJjPa3YJtFUAMVAAnU+F7JRKJXPZPBXNq6tSpnxjqcTw5+M1k+/MM+OxHabk5zj2TfOG4iVbP9hZ6rFxmMhevqXDTPG6l6gc3mdHuVohuARSjeXLArTiT7Uibji2behd6xL+y2zjJWyrcNI9bKfvBTWa0u9nuD0A4micH3Iov6aZm01Zb4y30WFxtUuea1LhpHrdS94ObzGh3s90fgHA0Tw64FU+c9G0T37und69fx8YNJtueVOGmedzgBzfJ0e5muz8A4WieHHArjmSuXDftq1d45W/eLJM4ctT9DKAGN83jBj+4SY92N9v9AQhH8+SAm91wyUscPuKWPnehB5XAzNVWFW6axw1+cNMS7W62+wMQjubJATd74cO7fJi3d6HHvr3uYWANbprHDX5w0xTtbrb7AxCO5skBNztJNZ43bYuqvYUetTXuwg8tbprHDX5ws70tcBuZm+3+AISjeXLArbDhU7nEdz/Tt9Bjy2b3lC8a3DSPG/zgBjd5QQEEY0bz5IBb4cInceaTObvlb/4ckzx2YsCFHtLcNI8b/OAGN5lBAQRjRvPkgFvwcbJ3TeL5gyZaNcMtf7G1q03mu1EVbprHDX5wg5vsoACCMaN5csAt2GRvdJrY+jpvr1/lNNNVX2+czB0VbprHDX5wg5v8oACCMaN5csAtuKReOmvaFsz1FnosW2TSzS1q3DSPG/zgBjcdQQEEY0bz5IBb/uMkbprOp3f0LvTofHKbceJZFW6axw1+cIObrqAAgjGjeXLALb9Jt1wy7cuXeOWvptIkT55W46Z53OAHN7jZ35Yg3Gz3ByAczZMDbvkJL/ToOnDAROdO9xZ6rFtjsq0xFW6axw1+cIObbjfb/QEIR/PkgNvYw0UvVrfG2+tHBbCrocEthBrcNI8b/OAGN/1utvsDEI7myQG3sSX54in3UK/7Pb4rak265bIaN83jBj+4wa003Gz3ByAczZMDbqMLL+ro3L61b6HHrp3u4g8NbprHzXY0+8FNZrS72e4PQDiaJwfcRh4+nUvb0oXe6V0WVpnUmUY1braj2U27H9xkRrub7f4AhKN5csBt+OETOHft3++e0Nld6LF+nclG4yrciiWa3bT7wU1mtLvZ7g9AOJonB9yGF/7qttjaVd4h36qZJnHwUKALPTBu9rcFfnCDm+ygAIIxo3lywG3wOM49k3zhuIlWz/YWeqxcZjIXr6lwK8ZodtPuBzeZ0e5muz8A4WieHHAbONmOtOnYsql3oUf82d3GSXWrcCvWaHbT7gc3mdHuZrs/AOFonhxw6z/ppmbTVlvjLfRYXG1S55qsO2Hc5EezH9xkRrub7f4AhKN5csDt7XHSt018757evX4dGzeYbHvSug/GTUc0+8FNZrS72e4PQDiaJwfc+pK5ct20r17hlb95s0ziyFH3M4C2XTBueqLZD24yo93Ndn8AwtE8OeDmLfRIHD7ilj53oQeVwMzVVusOGDd90ewHN5nR7ma7PwDhaJ4cpe7Gh3f5MG/vQo99e93DwLa3H+Nmf1vgBze4yQ4KIBgzmidHKbulGs+btkXV3kKP2hp34Yft7ca46XXT7gc3mdHuZrs/AOFonhyl6OYkb5n47mf6Fnps2eye8sX2NmPcdLtp94ObzGh3s90fgHA0T45Sc+OTOPPJnN3yN3+OSR47UZQLPTBu9rcFfnCDm+ygAIJeQqHQuyKRyGFKazgcvkg5SbdVDPU4zZOjVNz4a9sSzx800aoZ3vf4rl3tfr2b7e3EuJWOm3Y/uMmMdrdCdAsgAC6AFRUVf5BzfTGVwLNDPU7z5CgFt+yNThNbX+ft9aucZrrq642TuWN9GzFupeWm3Q9uMqPdLdhWAcRCZfCXIpFIbKj7aZ4c2t1SZ86atgVzvYUeyxaZ9CsXrG8bxq003bT7wU1mtLsVoksAgYRCof1UALcNdT/Nk0Or283kTZPd07fQo/PJbcaJZ+1vF8atZN20+8FNZrS7FaJLAGFQ8fsrystlZWXvHuq+PDm6u703k6awk0a3TMsl0758iVf+aipN6uRp69uEcYObdj+4yYx2t0L0CSCIcDj8BJW/b40bN+79w7m/ASK4/+Mfm9tHDpno3Olu+Uv8zZfMGzcd25sFAADAEkH3CSCIUCi0nMpfS3l5+QeG+xh+E2n935EWt+z3YyZWt8bb60cFMPF3Deb+W2+pcNM8bqXkpt0PbjKj3S3IPgEEQcXvsXA4fJ8SpXzHPxXMPw/1OJ4c/Gay/XkGfPaj/yRfPOUe6nW/x3dFrUm3XFbjpnncSs1Nux/cZEa7WyG6BVCM5skh2Y0XdXRu39q30GPXTuMkbqpw0zxupeqm3Q9uMqPdzXZ/AMLRPDmkuqWbW0zb0oXe6V0WVpnUmUY1bprHrZTdtPvBTWa0u9nuD0A4mieHNDc+gXPX/v3uCZ3db/RYv85ko3EVbprHDW76/eAmM9rdbPcHIBzNk0OSG391W2ztKu+Qb9VMkzh4yP2KNw1umscNbqXhBzeZ0e5muz8A4WieHBLcHOeeSb5w3ESrZ3sLPVYuM5mL11S4aR43uJWWH9xkRrub7f4AhKN5chS7W7YjbTq2bOpd6BF/drdxUt0q3DSPG9xKzw9uMqPdzXZ/AMLRPDmK2S3d1Gzaamu8hR6Lq03qXJMaN83jBrfS9IObzGh3s90fgHA0T45idHPSt018757evX4dGzeYbHtShZvmcYNbafvBTWa0u9nuD0A4midHsbllrlw37atXeOVv3iyTOHLU/QygBjfN4wY3+MFNZrS72e4PQDiaJ0exuHHJSxw+4pY+d6EHlcDM1VYVbprHDW7wg5vsaHez3R+AcDRPjmJw48O7fJi3d6HHvr3uYWANbprHDW7wg5v8aHez3R+AcDRPDttuqcbzpm1RtbfQo7bGXfihxU3zuMENfnDTEe1utvsDEI7myWHLzUneMvHdz/Qt9Niy2T3liwY3zeMGN/jBTVe0u9nuD0A4mieHDTc+iTOfzNktf/PnmOSxE6Na6FGMbprHDW7wg5v9bYHbyNxs9wcgHM2To5Bu/LVtiecPmmjVDO97fNeudr/eTYOb5nGDG/zgBjeJQQEEY0bz5CiUW/ZGp4mtr/P2+lVOM1319cbJ3FHhpnnc4AY/uMFNalAAwZjRPDkK4ZZ66axpWzDXW+ixbJFJN7eocdM8bnCDH9zgJjkogGDMaJ4cQbo5iZum8+kdvQs9Op/cZpx4VoWb5nGDG/zgBjcNQQEEY0bz5AjKLd1yybQvX+KVv5pKkzx5Wo2b7cBNbjT7wU1mtLvZ7g9AOJonR77deKFH14EDJjp3urfQY90ak22NqXArlsBNbjT7wU1mtLvZ7g9AOJonRz7duOjF6tZ4e/2oAHY1NLiFUINbMQVucqPZD24yo93Ndn8AwtE8OfLllnzxlHuo1/0e3xW1Jt1yWY1bsQVucqPZD24yo93Ndn8AwtE8Ocbqxos6Ordv7VvosWunu/hDg1uxBm5yo9kPbjKj3c12fwDC0Tw5xuLGp3NpW7rQO73LwiqTOtNo3SlfbsUcuMmNZj+4yYx2N9v9AQhH8+QYjRufwLlr/373hM7uQo/160w2Grfukw83CYGb3Gj2g5vMaHez3R+AcDRPjpG68Ve3xdau8g75Vs00iYOHrC30yLeblMBNbjT7wU1mtLvZ7g9AOJonx3DdHOeeSb5w3ESrZ3sLPVYuM5mL16w75MNNWuAmN5r94CYz2t1s9wcgHM2TYzhu2Y606diyqXehR/wru42TvGV9+/PhJjFwkxvNfnCTGe1utvsDEI7myTGUW7qp2bTV1ngLPRZXm9S5JuvbnS83qYGb3Gj2g5vMaHez3R+AcDRPjoHcnPRtE9+7p3evX8fGDSbbnrS+zflwkx64yY1mP7jJjHY32/0BCEfz5OjPLXPlumlfvcIrf/NmmcSRo+5nAG1vbz7cNARucqPZD24yo93Ndn8ARUI4HH4qEol00M/7U6dO/cRwH6d5cuS6cclLHD7ilj53oQeVwMzVVuvbmQ83TYGb3Gj2g5vMaHcLslMAQZSXl3960qRJE6kExlAA3z7x+fAuH+btXeixb697GNj2NubDzfa2wA1upeAHN5nR7hZkpwAC4b2AKIB9Ez997rxpW1TtLfSorXEXftjetny5aR43uMmLZj+4yYx2tyC7BBAICqCf1C1zc//evoUeWza7p3yxvl15mvhaxw1ucqPZD24yQbdJFQAAD4BJREFUo90tyC4BBDKaAtjd7b2ZtCRz6Zpp/+Iyr/zNn2OSx0/QhLlnfbvyFR4vjeMGN9nR7Ac3mdHuFmSXAAIZTQHUwv233jJ3TvyDiVbNcMtf17q/Mv+WSdveLAAAACDvBNklgEBKdQ+g0xY3HevrvL1+ldNM4mv15v6bb6pw6+9/flrGDW56otkPbjKj3S3ILgEEEQ6Hd1MSVADfoGTo8o3hPI4nB7+ZbH+eYSxJvXTWtC2Y6y30WLbIpJtbXCcNbgN99gNu8qLZTbsf3GRGu1vQvQIoR/LkcBI3TefTO3oXenQ+uc048WxJTHy4yYtmN+1+cJMZ7W62+wMQjtTJkW65ZNqXL/HKX02lSZ48XVITH27yotlNux/cZEa7m+3+AIQjbXI42bum68ABE5073S1/sXVrTLY1VnITH27yotlNux/cZEa7m+3+AIQjaXJw0YvVrfH2+lEB7GpocAthKU58uMmLZjftfnCTGe1utvsDEI6UyZF88ZR7qNf9Ht8VtSbdcrmkJz7c5EWzm3Y/uMmMdjfb/QEIp9gnBy/q6Ny+tW+hx66d7uKPUp/4cJMXzW7a/eAmM9rdbPcHIJxinhx8Ope2pQu907ssrDKpM42Y+HATG81u2v3gJjPa3Wz3ByCcYpwcTuaO6dq/3z2hs7vQY/06k43GMfHhJjqa3bT7wU1mtLvZ7g9AOMU2OTLfjZrY2lXeId+qmSZx8NCACz1KeeLDTV40u2n3g5vMaHez3R+AcIplcjjOPZM8dtxEq2d7Cz1WLjOZi9cw8eGmJprdtPvBTWa0u9nuD0A4xTA5sh1p07FlU+9Cj/hXdhsneQsTH26qotlNux/cZEa7m+3+AIRje3Kkm5pNW22Nt9BjcbVJnWvCxIcb3ARGsx/cZEa7m+3+AIRja3I46dsmvndP716/jo0bTLY9iYkPN7gJjWY/uMmMdjfb/QEIx8bkyFy5btpXr/DK37xZJnHkqPsZQEx8uMFNbjT7wU1mtLvZ7g9AOIWcHFzyEoePuKXPXehBJTBztRUTH25wUxDNfnCTGe1utvsDEE6hJgcf3uXDvL0LPfbtdQ8DY+LDDW46otkPbjKj3c12fwDCKcTk4IUdbYuqvYUetTXuwg9MfLjBTVc0+8FNZrS72e4PQDhBTg4+lUt89zN9Cz22bHZP+YKJDze46YtmP7jJjHY32/0BCCeoycEnceaTObvlb/4ckzx2Iu8LPUp54sNNXjS7afeDm8xod7PdH4Bw8j05+GvbEs8fNNGqGd73+K5d7X69GyY+3OCm1027H9xkRrub7f4AhJPPyZGNxk1sfZ23169ymumqrzdO5g4mPtzgptxNux/cZEa7m+3+AISTr8mReumsaVsw11vosWyRSb9ywfrk0Dzx4SYvmt20+8FNZrS72e4PQDhjnRxO4qbpfHpH70KPzie3GSeeLYrJoXniw01eNLtp94ObzGh3s90fgHDGMjnSLZdM+/IlXvmrqTTJk6etT4pSmfhwkxfNbtr94CYz2t1s9wcgnNFMDl7o0XXggInOne4t9Fi3xmRbY9YnRClNfLjJi2Y37X5wkxntbrb7AxDOSCcHF71Y3Rpvrx8VwK6GBrcQ2p4MpTbx4SYvmt20+8FNZrS72e4PQDgjmRzJF0+5h3rd7/FdUWvSLZetT4JSnfhwkxfNbtr94CYz2t1s9wcgnOFMDl7U0fnk1r6FHrt2uos/bE+AUp74cJMXzW7a/eAmM9rdbPcHIJyhJke6ucW0LV3ond5lYZVJnWm0/sbHxIebxGh20+4HN5nR7ma7PwDhDDQ5+ATOXfv3uyd0dhd6rF/nnujZ9pseEx9uUqPZTbsf3GRGu5vt/gCE09/k4K9ui61d5R3yrZppEgcPFeVCj1Ke+HCTF81u2v3gJjPa3Wz3B1BEVFRUhCKRyMuU74fD4VcoPz/UY3Inh+PcM8ljx020era30GPlMpO5eM36Gx0TH24aotlNux/cZEa7WyF6BRACFb8zoVBoNl+m8vendP1bQz2mZ3JkO9KmY8um3oUe8Wd3GyfVbf1NjokPNy3R7KbdD24yo90t+FYBREDFbzyVvrt08eGe26gAZijlgz2OJ0f65WbTVlvjLfRYXG1S55qsv7kx8eFme1vgBj+4yY52t8CLBZABFcBfpLJ3Pfc2PgxMt//2YI+7daC+d69fx8YNJtuetP7GxsSHG9zkRbMf3GRGu1ugpQLIob8CyIeAhyqAbvmbN8skjxylN9U9902lId3d3sTnn7a3BW5w0+6m3Q9uMqPdLdBSAeQw2kPAAAAAAABAMFT2vkH5Al+mQvhnw1kEAgAAAAAABFNeXh4Jh8Pf5NPA+Id/P2Z7mwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDpaKiIhSJRF7mFcP8jSGUn7e9TfmCXJ4irw76eX/q1KmfsL09+SQUCr2L3A5TWsnvIuUk3VZhe7vyBftQLvlu5yiftL1N+YR85vL7ksbsj21vSz6h92Mnn4jeH7fvkN/nbW9THnmUfHaS1w1yvEypt71B+eDxxx//mZ7x4vhnj3ijrKzsg7a3LR+Qy38hrwvsSJevUObY3qZ8Qf9+/wH5fNv/u/Kb2v6dAwFDb54z9JfabL5Mb6A/1XTOwPLy8k9PmjRpIjnFtE0MLoA8+XOuL6bxO2tzm/IJ+fx0z2Xy/Bz/BWdze/IJvS8n+//pellhAYyR38dtb0cQ0HtwO/+nsuc6vS8/bHN7goLGcAV5HrW9HfmCfG73nAqN/h2YQm6vT5gw4b22t2uscEEnt276+XN8nf+9I7ertrcLCKFUvjWE9wJqK4APQv8Y/RL/42t7O4KA3qOVvGfC9nbkiYfI5TTNvU9xYVdYAFXOtYkTJ76Hxuve+PHj32d7W4KGPL9L78s/sr0d+YLek7e4HPFlfm+SX4IuvtPyZo0Z/+/81tzb+D2q7WgJCIj+vjeYDwMP9b3B0tD6j1IuNGb7yXOb7e3IJ+xE78cuSlzLycx57wq5fIkvay2AvLfWP0T6VSpO42xvUz7gvZrsRtnoH3I7R/8A/47t7co35PSfyC/9jpydAtKhsftdLoH88QTe4aFl3PgoCXvRz1/3r/8x+b3FR0xsbxsQQH8F0P/mkN+2tEmBoL0Akt9f8eHEsrKyd9veliDgjyjQX2zHbW/HWCGPXyCPf6aLj/B1jQWQfB73Lz5C78lNGsaN4b8r/c9szuTrvJfF/8d3vO1tyyfktIfHzfZ25JFHeJ5RKfoNvkJl8Je54PLnHm1vWD6g999vkV+j/5+SHXwImPJfbW8XEAAOAcuHxu8JLu3jxo17v+1tCRLy/OHkyZM/ZHs7xgI5LKCxSvGhen9P2euULKXG9rYFAf2H5CN8SMr2duSDxx577GdpzN6kiw/13MbzTsveJIY/F0dOr/FXidrelnzR32FSHjfeK2hrmwLkUXK7o+3fbxAg9Gb5BuULfJkK4Z9pWgTSg9YCSOO1nNxa6C+zD9jelnzCPlOmTPloz3V/EUiXzW0KAm17APlzcrnvRX5/8t4Ji5uUV8jlRXov/iFfpvfnVLp+M/d9Kh0ar3nk9E+2tyOf8EId/k9Iz0IJ/6wX3Tl7qkXD/8nquUyeGygHbW4PEAb/b4+Xj/tL/7+l5bNWDHnt5g/88ikNeM8mn77B9jblC/J5jA9JUaL+6Rsu+ocXxcOrZPmzqPw5Mv/0Bqc0Fnj+z5emAuiXou/kfAbwMI+l7e3KF+zn/4f5Cs83bZ+1Iq8mTadI6YHG6S96xozfl3zd9jblC/6crX/apRv8mencsycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGTAJ4Uf7vkkQ6FQHd23YTSvw19hxefmHM1jAQAAAABAHvEL4DeHc1+/AB4Yzev4BTA9mscCAAAAAIA8ggIIAAAAADBCqBA9wd9bTOXmNfrZRkXnz3N+90VKO/3uFv38+9zvkeXvq/Yfe4Eu/yv9PFRWVvZB/non/i5T/goruvwLPfefOnXqBLrt7+h3WUqcy9hA20T3O0L3+UrOdmynnBzgvm8rgHR9Kz8/+/D3TtPlz/T8zi+AX6fbv+b7Xs39/bhx496f83WMabr/Trr5Uf+xKIAAAAAAkI//vdo/4C+c5+tc0nq+hJ5ur6TCE6P7hKn8vIuuf5mun+95LBdAyrf5y90nT578If+7uVvpfp+lXz9EP5/KKW18/RXKX9Pln+LHcHGk553X33Y99thjP0u/T9Lv/xs95//LpZG3rb/7PlgA6fJ03h66+DBd/kuKQ6/3bv4dF0D+nm26bQb/nr9Hli6/So4f8B/7dcreCRMmvJe/o5R+/490fb3/WBRAAAAAAMiHCk05F0D6+Sc9JakHuv00pbbn+vjx49/H5WnKlClT/cdyAZyTc/+n6PqJnutUmP4j3XbTv++vUlK5z0+/n0W3nRlo27hI8uN5bxzd948GcRj0EDD9/g49/lP+a3IB/PYDr/MdLoT0u/Hsx+Uv57G/yXtA/ceiAAIAAABAB1Rs/oxKTiMftqW8wHsF+Xa6/L0HixevgqXff9q/3EG//72c322kx+zLuf4f6PoP/df4PF1/k8sYh/e6Ue7S5SuDbNrD/l7F64Ntfz+HgFfwtvuvwfmxv1ey9xDwA48/TLetJK9foZ9v9Wyjv513+c/FfywKIAAAAAB0wXsA/cO25/j6QHsA6X5lfH0kBZB+/hofTh7J9tBzf4lP78J76Ojy/xjofrkFkPfYUbrp/h/L+f2dnu0cYA/gBd4DyIeY6eeP6KZHBtgeFEAAAAAAyIf39lF+lz/jR1cfoZ9/QyXnG/w7/gwgH/7kzwByOaTbd1Gaeh47zAL4un/1Yf8zgGsnTpz4Hrr+EH/uMHcBRi5+YbzNh5t5IQnvyaP7//v+7ptbAOk+f8h7Kf3FKo/S7Wt4z+MDBfANyjTfdzY/Ny9e8V+XPwP45Z7r9HyT6D6/7z8WBRAAAAAA8qFy93EqPM3+ql0+7PlSzyFg4iEqPat4zx3vVeOVuZMmTZrY81i+fbh7ABkqUx/mFcL8WUD/0OyF3BXHPfBn8Oh3US52Pbfxnkj/cPGjD97/gUPAfNj4q74Pv84TudvpHwI+RLfV+6uAr3Gx63ku3svpf5ax0z/8e40uL/EfiwIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYIf/Czd5pD7Z/EivAAAAAElFTkSuQmCC\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure() as figure:\n",
" x = range(10)\n",
" figure.plot(x, x, label=\"x\")\n",
" figure.xlabel = \"some x label\"\n",
" figure.ylabel = \"some y label\"\n",
" figure.title = \"A title for the figure\""
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=\"best\") as figure:\n",
" figure.plot(np.sin, label=\"sin\")"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=True) as figure:\n",
" figure.plot(np.sin, label=\"sin\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=\"best\")\n",
"fig.plot(np.sin, label=\"sin\")\n",
"fig.show()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9B5RcR3YlyO6WW400knbJaYnqboJgVUndWvXOSKPR7tlRS6OVnWmd2Tky2yRIEN577733IFDwHgThvfcehPe+stJbECCb7FG3Wk0yN17E/z8Thcyqn/nNi4j/7jn3VFZVVv73/6uIuBHx4r2XXiIQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBBcRl1d3Y9qa2u/18J7IjU1NR2cXIddYy5jjn3WZ+yzfs/JZ7UE9vl/yq71JXv5VTc/l33mXzL7H7Kvn7KvU9nXt9jXB25eg0AgEAgEAqFZMAHSHoQOEzxTWnovEyrvsvcmmntPOeHkVACyv/0/2ef+S6tWrX6z2s8oB/a5q5l965pcD+7ji5dcFoAg/thnD3DzMwkEAoFAIBAqAhMkl5nQecKYZd/+fHPvZe9pxxhv7j1M3PyZIZy+1uQ6TgXg2y1d2wZK3p/PAvBnb7zxxp+7+Zk20KxfCQQCgUAgBAitW7f+jyBymNj5K1hdg+3IZt77n9nvf8L4OWz5wjYse/0m/A5W/EDUMH6Tvf4xfKb5HvbZw+A9TQVgq1atfpe9by8IT1hVZL+vf/XVV3+51LXZ78YVX5t9vWPY9GvsM5fB3xsidj/7WZ35d+x3Y9n7z7KfT2BfU+zr3RKfPZzxXxl/WmTzN0wByPj37GePYMuW8chrr732W0Wf/4uwcsp+HmLveca+nmL892WeX61hO3zmj+E67Hn9301XVV955ZVfYd+vYT9/CoKXsY/xfNoa13xhhbXpZxiCdjP7ush8LvDzb37zm6+y1xsYk8Zz38Ce+cvlfE4gEAgEAkFDgFBgvGa83shEw7nm3m8IjRdW4UwBCK+LVs6+0uRvLQH427/92/+bIUz6sG9/7hvf+Mb/CuKKcWkl1wYByX5+nH3uK0xQ/pIRIxg3haQhAP+V/Wwk+/YX4D3lnkOZFcAv2c/Xgyh7+eWXfxWeD7y36O/WFInCr7K/6QExiiBMy92H8az+S7n7Yq9XMV58/fXXvw72st8vN8RpsQB8bmWyxGesNv7mXfbt14z7/gWINWS/mw7fwzNin7UW7C9nK4FAIBAIBM3ARMCvs8H/n5ko6ALfgygBYcHEy++X+5sKBWDZGED2tX9TsQmrYbAK+VIT4Vju2hALaFz3fy9628+x933EPv+fjOuMbSlm0bC/7BYw+/lvF/0MBN49eG2IWLh+TZPPetzcSmrxsypxX1+BZ8Cu89fm70F4GiuflQrA88XXZd//j6bPAu4N7IGVweaeD4FAIBAIBE0ABxFgSxJWt4wffcUQL4vL/Y1bAhC2Jo0Vqo9Nsp/9EARp8RZrc9dmQvWP4DpNt43Z+66ynw8ybBnb0qqmYY+tGMBiG9jr/2SsEBbfwyfs6/9kX4c0c62yApD9/N/B7xm/3eSePqpUADK+3+S6QyD+sKm98MzhgE1Lz4hAIBAIBIIGgLg2Q4SlGTNAY0XwsyJR+ByYUHinJQHI/v5PbKwAjmHfH6vQ3lIrgE1XLL8GW8vs8//RuA6sAJ5p6bPZe1ZWKgDZdb9VK+Inv1HJfdhZAWS//5siO/5tkxXAP4Drwspg0WeMKLEC+Nz9wN+znzdUYiuBQCAQCASNYBz6gMMI34NVpyLWwKog+33PUn/H3v+XcIABYvaa/NwSNXDYwRBG3yl+T7EAhMMicGgCtlTZZ/0v5s/Y9/+9nM3lYgAhhg1sh89h75kN25xf//rX/41xn7YEIHvfZGPL9KtFP7Oz0radcTeIQfgeRBmIN4jfK3etFgSgGQN4AQQurG6y10uKYwCNQyI/NFY5QTD+e3i2LQlA+Dv2syj73QQQlfAzeG7mdjmBQCAQCATNwUTADsZDZX4HByleOC1rAFbY4LDIU2Mb8QfG33xRLGpqCwmbPza3Q9nrcPEpYDitC3bACqSxFXnXOKxREqUEIMQxGqeAk8Y26QEmvn7H/L1dAcj+5jUQgObWaPEp4JeaEYDGKeAxRaeE4XTttuZyFTZ9Vk0/s+gUMJwqhtPNvRmzxUINhDKs5hknsffDSeuWBCAAttdrxcGVmCEiH7O/XdDS8yEQCAQCgUAg+AjjsA6s1v4xti0EAoEgDVinON/Y/viSzeK/W+59bJbb0Qhwb6gVqSa+Vu69BAKBgAUjlyKU1fuqcdIYVlyhVJyrCakJBAJBaUByWkhhANtL5QQgm0G3giSwkCsMvoeYHfa6u7+WEggEQstgfdMbrL+6VStqBUMyaEhuXYttF4FAIEgJWAUsJwAhWBrSTpjfsxn239qJCyIQCAQCgUAgSIwWBOB7bFY9tOj7b8NpON+MIxAIBAKBQCC4j0oEIKSnIAFIIBAIBAKBoDi82gL+8ssv84Rg4pOjB/MN7d/MN7z7/73A7JIF+S9++lNsEwma4MvPP88/eX91yf814LNd2/LUFxHcwhc//nE+NXtayf+1UOd38p9dOIttoitwS18QJEdzAvC11157HfJzQdLTl0TiVDgE0sPO58I/0dOnn+U/+oioO8HPpr8T27aJDrHdD/LxtWvyucZE/knyo3zywMF8qHsH/rvIjCn5J9lP0O0mOvc3ph1Pnnyajy18T/y/dW6bT+7clX8Sz+Zz0XQ+sXlzvqFDG/67+JrV6M9MZcrib2w+ST/Nh8eOEGKvT9d86tgJ9rNn+dzjSD62dLHV76UOHUa31am/XRUZBPkAWfIhWSoTgP9qlLJ6DD9nr5ez198332ekgQlBGhhIHPuSzTQw0GHwRvOEqDvBz4D0mfO8A4TVv9SJ0y+8L3M/lA/17so7ytiqVeh2E535G7t9J7Yak41u7fOZG3df+H36wyv5ho5v8/ckDxxCf26qUhZ/YzP63jz+v9Q4uG8+2xB/4ffJvfvF/yObeKSv3UK314m/PZIdhKCAOozgEPz8+aef5kM9O/EOMLFrd9n3Zm7eY4OyWJlJX7iEbjuxOn9jt+/MnYfi/4hNONIXLpd9X+rYSTEod2mbzz5sRH92KlIGf2MzdfyUWPljk43sg/L/R/H164VIHNArn0s9Rbe7Wn9j6weC4gh6hxEkgp9zq5eL7d3pU/K53KfNvj+xY6cxk+6Xz2U+RrefWLm/Mdt3LvvDfHjUMGMleWWL74/WLxT/mzOnoz87FYntb2zm4jm+5ctXkg8daf698L85RmwTQwgMtu3V+htbPxAUR5A7jKAxe/u+2Prt+HY++zja4vuhk2wcNlCsFjIxiG0/sTJiC4LkkeNiAjGwdz6Xetbi+7PRDF+54avOH15Bf36qEdvf2IytXiUmEJPGtzi5BWZuPxCH4Dq2sdUfykYSgATHCHKHETRGpk4UM97162z/DY/Pgi2V7h3YDPsJ+j0Q7RNTEMCKMQg/+N9JHT1h++/MVefwyCG2BnGiHP7GZjaczDd0eodPcDN3H9v+u+giseocW1yPfg/V+BtbPxAUR1A7jKARgu/5akzPTvknycqEXGTqJLEKuHUb+n0Q7RNTECT3HywIuewPbf8dF479ewnheO4i+jNUiUEWgHBYDf5novPnVvR3sPLHT6G3f6vZmEEZSQKQ4BhB7TCCxui82SLf2s6tFfs7ffGqlVIhl6ZYQFWIJQhg5a5x6AAh4k6drfjv4XCS2Mobh/4MVWJQBWAumims/t2zv/pnMrZsqVgFXLEc/V4q9Te2fiAojiB2GEFj9lFExLqwTvLzzz6t2N8woJsB05SmQx1iCQI4NW7F/lWw+mcyl/woH+rRkX9GqbQxRLn8jc3E9h1iwjB7RlV/D2mveGx013ZKhbmQACQ4hsodxpkzl/Ldu/dCt0N2xtetFTPcJYuqHiDMNB0gBLHvh2iPWIIATpg7PTgUf/998T+7SL3YrKD5G5P8oJoRa+rk4FBk2mTxP7uzfGos2UgCkOAYQeswgkboIM3UCJmbd6seICA2y8wfCLndsO+L2DIxBEG2ISZWU7q05Wk5qv4ciM3in/MuXxHEfpYqMIgCEOJE+WrzkH6ODg0VPqe/MoePSAASHEOVDiOR+CjfvXvP/F//9d/k/9t/+37+7bffzR8+fJK/ht/fvv0o/wd/8If5qVNn5v/u7/57/s///C/ye/bQdmXq9HkrGN/pAGGmWYitXIF+X8SWiSEIeGk3CMZf+J7jzzJPrcOBEuxnqQKDKACjc2a5kqaKT5T79RAT3Ot30O/Lrr+x9QNBcdjpMCKzpouTUh4QPtvOP/u2bXvy77zTzvq+sTHFBeD3v/93/HsQgL/zO7/D3wff7917OP8Xf/GX6I0Um9x3vOrHHscDBARY88MgPTpSYmgF6Lcg4Ic/BvcT23EXrzr+PCvsYNxI9GepAoMmACFejx/+gBO8kZTjz4uvWycmuMuXod+bXX9j6weC4lBFAN68+SD/ve/9aX7YsJH5jRu356PR7AsC8Lvf/W7B5kg6/53vfAe9kWIStuDM55yLZV0ZIMKjh4vTnWcuoN8fsXn6LQigriqfIPTvWdXhj6aEE+eQfxI+U8VEvbr7G5twII0f/pg22ZXPy9xrMCa4nZSY4JIAJDiGSh1GnM34du7cnx8xYgwXg7DaVywA//AP/6P13lgsl//d3/1ddJsxmTx4xCr7ZnYYTv1tnriLLpiPfn/E5um3IIitXGkkGl/v2mea5eEoB6V8/sYmVPzgIQJHjrn2mWa2Awidwb4/O/7G1g8ExaFKh3HvXogLQHidTn/MBeDixcufE4AQA2i+HwQgbAlj241J8zSmWRfTjQHCCvKHlAnplst7EfHopyCA7V9Y+ROHje679rlmcH549DD05yk7gyQAs+FU4bCRi4eErAlu/QL0e7Tjb2z9QFAcqnQYcKDjv/7X73P+zd/8bX7KlBkvbAHTCmCBsOXLt387trFOY7o1QITHjao6yS/RP/opCDI374lTlAN6uXqKMpf5JB/qLnICZh+G0Z+pzAySADQrzUSrzP1XjjxnqhXn/An6fbbkb2z9QFAcQekwgkZY9ePbvzOmPtdhuOFvs16rGyc9id7RT0Fg5e1btdL1z4ZcgHwbePsO9GcqM4MkAKFfK97dcJOQMcFpXkG//I2tHwiKIygdRtAYnTvrhRQabg0Q1iy5ZydXgv2J3tBPQWCWfktfvu76Z8NKM5WGk8vfmMylnhqnf9/MZ6MZ1z8/vmmTmMwsW4J+ry35G1s/EBRHEDqMoJFvm3VrL7bNQonnOgy3/G0N+Fdvot8vsTT9EgS8lBZMCHp18WRCADFeDR3fzjd0eEupUl26+hub5oQgPGGMJ5+fuftI/D/36yF1UmgSgATHCEKHETSmL12zkj837TDc8nd8rSgvB2XmsO+XWJp+CYLEtu1ixWTxIs+uYSaFTh0/hf5cZWVQBGB00UJPQwKeO9B09zH6/Tbnb2z9QFAcQegwgsb4mjVCnL3//gsdhlv+Tl+5IYL+hw1Ev19iafolCCJTJnp+KAhqtKpyOlN3f2OSV+zo1cU4FNTo2XViSxZLH3dKApDgGLp3GEGktT177dYLHYZb/uYdcQ/jdGYojn7PxBfphyDIpZ5Z1Ri83J6FE8B8W653F6m35XT3Nzat0+ZD+nl6ndTJMyLulE1usO+5OX9j6weC4tC9wwgaCwc0Or8Qj+X2AGHW4YSE09j3TXyRfgiCtJmnb/xoz+8HBn2VarXq6G9sQkJwP8q18TJzHd7isadw6AT7vsv5G1s/EBSH7h1G0Jjct19slb03r2SH4aa/m7sWEZ9+CILYqlUi3GDjRs/vB1LM8Gtt2oz+bGVkEARgZPIE33KQwiETfq2zcpa9JAFIcAzdO4ygMTpvtrEqd7hkh+Gmv63Vxj5daVtOQvohCCAGtFS4gRdMnTkvtuUmj0d/tjJSdwEIlYf8CDcwmdi8Raw2rliOfu/l/I2tHwiKQ+cOI2jkp9d6GwHSj6MlOwy3/d04sLdxWu4R+v0Tvfd3MSHFEJ8AdO/oSz5Ivi3HBn8QAbn0x+jPVzbqLgDTFy6LcINxI325XiHesD/6vZfzN7Z+ICgOnTuMoNHMXwWirFyH4ba/IfUHPy23Yyf6/RO993cxzWozEAvq1z2Fx4wQK44Xr6I/X9mouwC0Uk81yW7gFflBt+4dxIQ6kkK//1L+xtYPBMWhc4cRNCZ27RFbFovqy3YYbvs7deyk2JabPgX9/one+7uYVj623Xt9u6f4unW+igCVqLsADI8a5lm1mXI0S87JmH+SBCDBMXTuMILGyOwZIv7vyPGyHYbb/oZSTA3tfpBv6NqOysJJRq8FQeOgPr5v/6cvXPLt1LFq1FkA5uI50c90aZvPZfzb/oc8gKIs3FL0Z1DK39j6gaA4dO0wgsbn8vI1Jst2GF742zwIkLlxF/05EL33N9CK/+vRydcDQLwObMc2+YYObXiJOOxnLBN1FoCpMxeMA0ATfL0u9Gk8rGboAPRnUMrf2PqBoDh07TCCxszN+y0GLHs1QEDRdIoDlI9eCoLU0RNiQJ413ff7MtNzQA5C7GcsE3UWgFBykm/9f/CBr9flE2uzrnokjf4cmvobWz8QFIeuHUbQaJbKghJGzXUYXvgbtpz5YYDZM9CfA9F7fwMxRT/E/1EcoL/+xiZs+XPR/+EV368N8c0yxgGSACQ4hq4dRtAYnWvk/zt8tNkOwwt/ZxtiVKZLQnopCKxt/5v3fL8vs/pIZNI49GcsE3UVgDz/H9/2fwulKkdi23Zfqo9U429s/UBQHDp2GEFkqF8PsU3xKNJsh+GVv0P9ewpBcD+E/iyI3vrbOvjTrT3KwR+eD9A6EPAJ+nOWhboKQDj1yw/+jBmBcn0oPcjDa0YMRn8WTf2NrR8IikPHDiNoLKzANV+Rw8sBAsrB8RXIA4fQnwfRW39DGS6+AjdtMtq9NQ4fRAePfPI3NhObN4sVuNWrUK4PkwxRgeRNqQ4ekQAkOIaOHUbQmDxqLwbPywEiuXefsKF+AfrzIHrr7/jaNeg1eWNLjRjEnbvRn7Ms1FUAwkTDr/q/5YgZg9icv7H1A0Fx6NhhBI0Qm8IHw+07WuwwvPK3VYVkUB/050H01t/WKVzEwRBiXfmEY+5s9OcsC3UUgM+dwo1m0OyIrzEnPZvQn0mxv7H1A0Fx6NZhBJHhkUPEgHztVosdhlf+5nWIzbJJiB010Vt/w4AMsXcQg5dLPEG7N4h15WEP/XqgP2dZqKMAzNx9LCaWg/ui2pE6eUa6ikckAAmOoVuHETRCTArEpkCMSksZ8r0eICJTJoqtmjMX0J8L0Rt/Z24Z+SaHDUS9Nz7h6NNVTDgaYujPWgbqKACTBw+Lld735qHakQ2njMTnHaXJdEACkOAYunUYQSNsw9ktjeX1AEH52eSiF/5O7t0vBuRFC9HvLzpnpphwHD2BbosM1FEAWvkmd+1Bt6VxYG+pMh2QACQ4hm4dRtCY2LJViK41q211GF76O3XmvNgmmToJ/bkQvfF3tH6hOO297wD6/SW2bhOnQ1fhnA6VjToKwPCooUJ0Xb+Dbkt0/lzxv3/wMLotpr+x9QNBcejWYQSNcPKXr4IcO2mrw/DS31AqiW+TdJdnmyTI9MLfUBOVD8i3H6DfX/riVbH6PWEMui0yUDcByBNAd3iLJ4HOpZsPb/GDsArZUrUlv/2NrR8IikOnDiOItJMAurjD8Nrfsm2TBJlu+9tKwNy1HUoC6BfsSZgJod+Vwh5s6iYA01dvCYE/eji6LUDIOcntGTkE3RbT39j6gaA4dOowgsZCYHInWytufgwQ0Xktl6Qj+kO3/Z2+cEkMgBPlKcHWOKS/mHDceYRuCzZ1E4BQZ1qmEmxwyM4qSZd+hm4PCUCCY+jUYQSNcNq2kpg7PwYI2TrtINNtf0MONB5vum4t+r2ZjC6YL1Vclk7+xqYVcyfRZDI8apg0MYkkAAmOoVOHETTGN3xQ0albPwaI9NWbUm3bBJlu+zsyYyp6RYamTOzaLSYcy5ai24JN3QQgJJWXLZwE4v/4qeTde9FtIQFIcAydOoygEZKS8gH59DnbHYbX/n4ucLuFvIREb+m2v0O9u4h408Yk+r2ZhOTnNOHwxt+YzEUzxoGyDlIdKIPT77KkQSIBSHAMXTqMILLSAdmvAaJxxGAxc791H/0ZBZlu+jsbiosBuU839PsqZmHC8XbgJxw6CcDU2Q9FeMuUiei2FDNz00iEzvo4bFtIABIcQ5cOI2iE6gd8QO7bvaIOww9/R+sXiNidA4fQn1OQ6aa/U6fPS1cKy6RZChFOaWLboou/sRnfuFGEt6xfj25LMXOZT/hko6H9W/lcCvcgCAlAgmPo0mEEjakTp8WAPHN6RR2GH/624rLoIAgq3fR3/IPK4k39ZGzxIjHh2LMP3RZd/I1N6Nd4eMuJM+i2NCWEG9ipve6Hv7H1A0Fx6NJhBI3xtWvFgLxpc0Udhh/+Tl++IeKyxo1Ef05Bppv+tgbkk/INyFZcVj1+XJYu/sZmqH9P2/lN/aYs5elIABIcQ5cOI2iMTB4vZqHnL1XUYfjh71zyI5Ggt3NbStCLSDf9bSUcfxxFv6+mhFhTHpc1fBC6Lbr4G5O5WFbKAyAmk/sPGhOOBej+xtYPBMWhQ4cRNEKnCMmf+YAczVTUYfjl78Yh/URc1t3H6M8rqHTL31nzRKbNhON+U8RlmQl6g3sQRBcBmP7winQJx4sJZRD5hGPYQHR/Y+sHguLQocMIGq0TmRUcADE7DL/8bSVxPXIM/XkFlW75G1aZebzp5Ano91SO1kGQm/fQbVHd39hMbNsuYohXrUS3pRT5hKPTO/mG9m/mc6mnqP7G1g8ExaFDhxE0ps5UdyLTzwGi0ImvQn9eQaVb/k5s2SriTdeuQb+ncqST5/oIQBkrgDRleMwIEYJz9Saqv7H1A0Fx6NBhBI1WSa4KUyT4OUDIvo0TBLrl7+jcWeIAyNET6PdUjomdu8SEY8VydFtU9zc2G4cOkL6+s1kRBPPkOQlAgmPo0GEEjdE5M8WAfPxUxR2GX/62Arm7tZcybiwIdMvfMpbkasr0pWtiwjFhDLotqvsbk7ClClursMUq8wEyEH58wsGEIKa/sfUDQXGo3mEEkeaAnH3QWHGH4ae/Gwf2FnY+DKM/syDSDX/n4k+4Dxu6tpNayOfiucBPOHQQgKqU9rNqno/FS3VFApDgGKp3GEGjlWIFBuQKZ8h+DxDVrlQS3aEb/lZpZa1xQC9pc8ep4m9syrCyZodWP9zlXbSVShKABMdQvcMIGtNXzCTLo6rqMPz0d7WxikR36Ia/VYqti8ySN1m1Kv7GplXVZe9+dFtaYrU7MW76G1s/EBSH6h1G0JjYvUcMyMuWVtVh+Onv1Olz4rTyjKnozy2IdMPf0UULxYC8/yD6/bREq1zdhg3otqjqb2yGRw8T8abX76Db0hKjs2eg7nCQACQ4huodRtAYW1wvBuR9B6rqMPz0N1SN4AlTB/RCf25BpBv+LtQ9vY1+Py0xdeqsUR97Grotqvobk7CVWsiv9wzdnpYY37gRtT42CUCCY6jcYQSRTmbIfg8QEIzf0K09tzeXeIL+7IJGp/7mA3KXtjzWCWKesO+nJZoTDqgji22Liv7GZuZeg5gwDumHbosdWhMOpB0OEoAEx1C5wwganc6QMQYIiFXkK0hXbqA/v6DRqb8htokPyIP6oN+LHfISid07iglHLItuj2r+xiZspfIau3Nmodtih9gTDhKABMdQucMIGjN3H4kBeeiAqjsMv/0dW7oEPWFqUOnU36kTZ8QKx6zp6Pdil5B4nE84PryCbotq/sYmxG7yLdWNG9FtsUM+4TB3OOI5FH9j6weC4lC5wwgaoRIDnyHPm111h+G3v620DsuWoD+/oNGpv1U8VAGnlcHmxM7d6Lao5m9sRsxDFSfUOcUN6ZH4hOPSNRR/Y+sHguJQucMIGiGdCh+QN22uusPw299W2prxo9GfX9Do1N/YpxyrIRyO4hOOxYvQbVHN39hsHNQXNa1KNYwtX4Y24SABSHAMlTuMoDEy08hzdups1R2G3/62KkkEuEIDFp36u3FwX+lLwDVl+qpRSWIcXoUGVf2NSV4CDhIrd24rdQm4poT0SHxXZtFCFH9j6weC4lC1wwgircSjVZZWwxogGvsbFRoeR9GfYZDoxN9wyIgPyJLXZH3B7kRwJxwqC0DIaiBKwA1Dt6U6u/0vXUcCkOAYqnYYQaM1Q+5S/QwZa4CANAl85fL0efTnGCQ68bc1sI1Sa0AGwqlMPuFoiKHbooq/sZk8cEispNX7v5LmhM+V5vR5wkECkOAYqnYYQWPmxl3HM2SsAcJp7CLRf3+rOiADI9OniAnH2Qvotqjib2zGVq0UsXTbd6DbUimtGtQ+73CQACQ4hqodRtCYPHjYGJAXOOowMPydOnZS2D63utPLRP/9HVtpDMg7dqLfR6WMr10jbN+6Dd0WVfyNzcjkCeI07YVL6LZUbLs54Tjj7w4HCUCCY6jaYQSNsdWrHM+QsQaIzL3HRob//ujPMUh04u/IpPHGgHwZ/T4qZfLwUTHhWDAf3RZV/I3NUO+uYhUtnEK3pVLG164VffOWrb77G1s/EBSHqh1G0BiZOkkMyOcuOuowMPzNK5h0fDvf0OGtfC7zMfqzDAqd+DvUq4sYkCPqDciZm/dFuMTIIei2qOJvTGajGVFRo2dndFuqIaNgYBwAACAASURBVNaEgwQgwTFU7DCCyFDf7mJADiUcdRhY/m4cPkikFLnzCP1ZBoXV+htWYfiA3LsL+j1Uw1z6GS+XqNoJZix/YxOqtvCKM5PGodtSDTM376FMOEgAEhxDxQ4jaIQyQ3xA7t7R0UkzzAECqpfwOJljJ9GfZ1BYrb8hDosPyJPHo99DtWwc3E+5HIZY/sYmJFHmybtXLEe3pRrylEkIEw4SgATHULHDCBrTl92ppoE5QEB9T9XKiqnOav2d2LlLDMgrV6DfQ7WMKlhWDMvf2Iwtrhf1wvcdQLelWlpVTB76V8WEBCDBMT45vF+5DiNoTO416ukudVZPF3OASJ04LeJk5sxCf55BYbX+ji1ZbAzI+9HvoVrCRINPONjEA9sW2f2NzfCYESK++dotdFuqpdMqTdX6G1s/EBQHJLF8kn6K3oCI5WnVm9y9x3GHgTVAWCeBhw5Af55BYbX+hpVmPiBfvoF+D9US6heL1EPBmXCoKAAhpAWSKMM4BEmVse2plhi5TkkAEhyDx8ncvIvegIjlGZ44VgzIl6457jCwBohc5pN8Q8c2xkngT9CfaRBYrb9DPTvx/7dcLIt+D9UyiBMOFQUgVGvh8c39e6Lb4oTJo8fFhGP+XF/9ja0fCIqDL1sfOYregIjlaQ3I0YzjDgNzgGgcNlAE5t+lk8B+sBp/Q9oXlU8AmxSph9iEoz2bcKSDkXoIu31XQ0hrxQ8cTZ2EbosTZm4/EBOOEYN99Te2fiB4jDfeeKOmrq7uPOOj2traS4zfbvqempqaP2U//zHjdcYb8JX97BftfD5ftl6/Dr0BEUszG04aA3JXVzoMzAECtuP4hOP4KfTnGgRW4+/0xaviwNFENVNyFBMGYz7hYIMzti2y+hubUGmGxzevWoluixPCJAN2NyDfqV8ngUkABgBM+B1nYu4deM2E3d+z7y83fY8hAK9X8/l82XrWdPQGRCxNqMQgcmQ5T8mBPUDEP/jAOAn8AfpzDQKr8Xdyj3HgaJmzA0cyELbj+ITj6Al0W2T1NzZjixcpfwLYJFQ64hOOew2++dupviBIDCbsXmHC7ofs5VfNnzEBmGFs3eR9IABvVHMNvmw9uB964yGWZmLXHjEgL1/mSoeBOUAEMTAfk9X42zpwxP7vsO13yqClHsJu39VQhwNHJqNzZhqph0775m+HEoMgM5iw+wMm9h4U/wy2gdnP/6zJ+0AAfsree9X4fXe71wh1elvEyVCJLikZW7bUOAG815UOA3OAyNwNXmA+JqvxNyR/5gPyh1fQ7XfKoE04sNt3NQz1UP/AkUkr9dAH/uxwkADUHKUEIGwBNxWAr7zyyq+8/PLLv2r8/rcZb7H3/IOda8RGDREJLO894v9QRLkI5ZH4tsLFK44/6+lTMUDAV4x7eZL9RMTJdGjDX2M/W91Zjb9DfbqJATmcRLffKbN3H4kJx/CB6LbI6m9M5qKFA0fYtrjB1InChMMvf7smNgjywe4WcIm/G8b+br6da2QWzef/tD+6cilPkA+R/qIG8M8+/SG2Ka4gNlLUBP5pJoVtCqEJvvjxPwvB1LNT/ssvv8Q2xzG+/NnP+IQDdjm+/OILbHMITfDjh/dF/N/0idimuIKfpsSBvdjoob5d06HEIMgOJvZOML4Lr2FVr9QhkFatWv0m+/IVeA0rgew955gAbGfn85/t2ia2GDduRJ9BEZ/nk8QTowZwh/yTJ5+6MmMEYK4QWCeB2WwZ+/nqzkr9nbl2S5wAHjcS3Xa32Di4UKIL2xbZ/I1Nq8LRsiXotrjBJ5mPrZrAT3I/9MXfbmoNgoRo3bp1HRNzFyANjLH9+x34OXu9nP38+/Ca/awne33XSAFzh3G03c//0eUPxbL1vNnoMRTE55k2B+QxI1yLGQHwzgrpnoJYoguLlfo7uf+gGJAX1aPb7hYjM6eJCcfpc+i2yOZvbOp04MikVRP4UcQXf3ulOwgBwU+TCd8TWBLtMXnwsBDn9Qtc6zCwB4jUsZNGnAxNOLxmpf6OrV4lBuTtO9Btd4vxtWvFPW3Zim6LbP7Gpk4Hjqx7mjFVTDjOXPDF39j6gaA4eJyMsWztVwJLoj3G164Rg9fWba51GNgDROaOEZg/bCD689Wdlfo7Mm2yGLzOfohuu1tMHjwiJhwL30O3RTZ/YzPUV8Q3ZxuT6La4xfia1b5NokgAEhwDOoziOBnsBkQs0O3tKxkGiByPk/E3Y35QWam/G/v3Ev3A4yi67W4xc/2Oq2EUMlOG9m2XuXghvjmX+xTdHrdohVEs9j6MggQgwTGgw4gGKE5GJVrC/IE7wlyWAaJxUB9jwhFGf8Y6sxJ/51JP8w3tfpBv6PKuVgNyLvmREBrd2mt1X079jU0rvnnsSHRbXL2vKzfEfY0f7Yu/sfUDQXFAhxFfF5w4GVXoxUqZLANEZPoU3+JkgsxK/J25cVcMXKOGodvtNnXcanTqb2wmDxwSW/OLFqLb4iYhoTWfcPTs7Iu/sfUDQXFAh5E6HJw4GVWYuet+rJwsA0RslX6HDWRkJf5OHj4q+oD35qHb7TYjkydod9jAqb+xacXKbduObovbDPXqIpKpRzOe+xtbPxAUB3QYmZvG7H/0cPTGQxS0yljNca+MlSwDBBR+F3Eyi9Cfs86sxN/xdevEgLx5C7rdbjO2Yrl26Uac+hub1i7AWf12AcITxvhS35gEIMExoMN4kvpIxP90bad9nIwqtArZv/++qx2GDANE+vJ1MeFgHSX2c9aZlfg7MnO6GJBPnUW3220m95gJh5ei2yKLv7HZOLC3b/ny/CZMbHmFk/0HPfc3tn4gKA6zwwj16xGIOBlVGJ0/V3QiR4672mHIMEBkI2mrBij2c9aZlfi7cXA/UXP6fgjdbreZvniV3xvU1ca2RRZ/YzKXfiYWHDRNPQahLXzCsXqV5/7G1g8ExWF2GFZSTtZZYjcg4mf58MghYkC+ed/VDkOWASLUo6OIk4nn0G3RlXb9DYMw1Mxt6NBGywE5G06JCUefrui2yOBvbFq5QIcPQrfFC0IeTT7hmD7Fc39j6weC4jA7DNge4StOe/ehN6CgE7bhG7q05bPkXOqZqx2GLAMEpH/gE45rt9Bt0ZV2/Q2rfnxAHtIP3WavGOqu/4RDpvbdHFMnTrse3ywTYVubt6eBvT33N7Z+ICgOs8NI7Nwtlq1XrkRvQEEnJOLlHUj/Xq53GLIMEFDejk84Dh5Gt0VX2vV36vR5sWIxYyq6zV4xPM6YcFzVd8IhU/tujonNm0V88/r16LZ4Qb6i3ukdXmELtru99De2fiAoDrPDSJ27KAaBaZPRG1DQWfDFJNc7DFkGCMg5yQeBdWvRbdGVdv0NqTi4L9asRrfZK0brFxoTjiPotmD7G5uQboz74pC+vmgcMViE8Nx56Km/sfUDQXGYHYZfy9bElpnYsVOsxq5ydzVWpgECTptykTtrOrotutKuv/06tYhJa8Kh6apTJf7GZiH84za6LV4xOne2OFV//JSn/sbWDwTFYXYYzy9bf4zegILM2JLFYkDed8D1DkOWASJz77GYcAwdgG6LrrTr70LesuvoNnvF1MkzRtzZTHRbsP2NzSAcAItv+EBMODZu9NTf2PqBoDiKOwyoOsGXre8+Qm9AQWZ44lgxIF9yd0CWaYDgpe7g5GlHPU+eykC7/g717ipSQEVS6DZ7RauyjqYnTyvxNyaz0UwgUkCljp4QE475cz31N7Z+ICiO4g4DZsd82frEGfQGFGRatUvD7g7Isg0QZu657INGdFt0pB1/5xJPxIDcvQO6vV4SdjVgd0PX3HN2/Y1NqI7Bk8CPH41ui5fM3Lov7nPkEE/9ja0fCIqjuMOA+Bhdy0GpwlzqKfeBF1VZZBsg4NQpn3CcPo9ui4604+/M9TtioBozAt1er2lVn3gcRbcFy9/YhDhTHt+8qB7dFi8J6bt4susubT2rrkUCkOAYxR0GnMriy9YL30NvQEFl5vYDz2aOsg0Q8TVrxIRj6zZ0W3SkHX8nDx8VbX7BfHR7vSacquehFecvoduC5W9sxtcGp81DGi8vJxwkAAmOUdxhwKksLj7GjkRvPEElnBrjA/Jc95OkyjZABGU1AIt2/A21pnmw+qZN6PZ6zdiK5UJ87NqDbguWv7Fp1Zw+fQ7dFs/vdepEMeG4cNkzf2PrB4LiKO4w4FQWjwfq0RG98QSVsP3uVboK2QaI9JVgxANh0Y6//UhXIQsTu/eICcfyZei2YPkbm41D+ouDhvca0G3xmvB/xiccu/d65m9s/UBQHE07DDidxZetoxn0BhRERheZCWvdr5Ah2wCRM08E9uyMbouOtONvK2Ht7Qfo9npNWInhuSenTkS3BcvfmOSpxjq24af/c5lP0O3xmoldZnWtFZ75G1s/EBRH0w6jkBPsBnoDCiKt53/F/ecv4wAR6tlJ5ASLZdFt0Y0t+fu5mtMelqyShdmGmCclFmWhjO37uef/sFE8/8F90W3xg2mPq2uRACQ4RtMOI7a4XvuqADIz1Me7nGwyDhDhcaOMGq030W3RjS352xREof490W31g1zwdtZX8MrYvouZOnNB+5rTxbSqaw3q45m/sfUDQXE07TAKdUHXoDegoDGX/EikgOnW3pPUATIOENaW94FD6Lboxpb8bW2JTtFzS7QUCzVa9Ut2L2P7LmZi+w6jxOUqdFv8oNjyfjvf0P4tnvjeC39j6weC4mjaYUBONj4ozJyG3oCCxsxNI3noqKGefL6MA4RVo3XdWnRbdGNL/tb9UEQpRufMMpLdn0a3xW9/Y7NQ4nI/ui1+EUpdenXohQQgwTGadhiZ+yGxbD2kH3rjCRpTx06KFDDzZnvy+TIOEFB1RvcarVhsyd+6p0UpRZ2T3cvYvotZKHF5Dd0Wv1hIe+N+snsSgATHaNph8GVrqNHagWq0+s3E5s1iNez99z35fBkHiMydh9rXaMViS/4u5CnTMzFyKeqc7F7G9l3MUJ9unpS4lJlWsvvtOzzxN7Z+ICiOUh2GWaMVVgOxG1CQGK1fILZI2CDlxefLOEBAMD4vmdTZu5JJQWVL/m4c4G2lAhlpJbsfp1+yexnbt0kzvjnkUXyzrLSS3S9Z7Im/sfUDQXGU6jCoRisOISGylydiZR0gQv16CCESiqPbohOb83dQhTekGxLJ7juh2+Knv7GZuXFXCO/Rw9Bt8ZPpS9fFfU8c54m/sfUDQXGU6jDia1aLZett29EbUJDodRJuWQeIyKTxQvh+eAXdFp3YnL+trfcRg9Ht9JuQeJznntQs2b2s7RuYPHJMbL2/Nw/dFj8J2918wtG3uyf+xtYPBMVRqsNI7jvg2bI1sTRziSeio+jewbNryDpAxJYuEVvfe4NzOtAPNudvOAXrVc1p2en1SruM/sZmfMMGEd+8cSO6LX6S557s1l5MOJIfue5vbP1AUBylOoz0xasiFcwk95etiaXpxxaJrAOElR9sdTDyg/nF5vxtHTjyoOa07IzWe1duUVZ/YxMyG/CwomMn0W3xm+FRw0RM/c37rvsbWz8QFEepDgNisfhqVL8e6I0nKLRSwMyf69k1ZB0gUmfOB6pCgF9szt9wCpaLoMNH0e30m7rmnpS1fQPDI4cIEXTLXRGkAqFP90L8kgAkOEapDuO5GqEp/Uomycj4pk1iUNqwwbNryDpAFHJP9ke3RSc25+/w2JFiG/TabXQ7/WbqpJF7cvYMdFv88jcmxXjyrtgGTT1Ft8dvWtvfrI9329/Y+oGgOMp1GJCXTZRMeojegIJAP1ZkpB0gMp/wckkNHSn3pF/+DvXsJAbkeA7dTr+ZuftITDiGDUS3xS9/YzIbTnp2EEIFWgdgFsx33d/Y+oGgOMpuEbHZsSiZdAa9AQWBkJdMrMjc8uwasg4QQCiYzk9AP4qg26ILy/kbRB8fkHvqlwrFDnPpj9mE4818Q6d3tJpwyNq+C6lQxqLbgsHM9Tvi/seMcN3f2PqBoDjKdRjxtWtFKpgtW9EbUBBopaaIZT27hqwDBDAybZIQwOcuotuiC8v526sBSSU2DuytXRJsWdu3lQx5cT26LRjMxY0MDz06uu5vbP1AUBzlOgyr0S4KZqP1t4PIedJBlOowZBwggIW6tLvRbdGF5fydPHI8kDnZihmZqt+EQ9b2DYdtgr6Y4EWOVxKABMco12FYy/YTxqA3Ht1ppYDxeEVG1gECmNi1R0w4mBDEtkUXlvM35GLjQekffIBuIxZjy5cJUbJ7D7otXvsbm9E5MwMfTuRF7kkSgATHKNdhWIG7fbqhNx7dmTzqz4qMrAMEEFZieCqYqZPQbdGF5fwN/2f8wNGR4+g2YjGxc7eYcKxciW6L1/7GJlSbCfqBwugiM/eke3XeSQASHKNsrVA4ut+1nScZzInP01qR2eDtioysAwQQDn/wk5kDe6PbogvL+dtMAQOxgNg2YjF19oKYcEyfgm6L1/7GpJUCJuApxazcky4mXicBSHCM5jqMICfv9JOFFZljnl5HxgHCJJzGbOj4Nk8Hk8t8jG6PDiznbysFjIcHjmRn9kGjmHAM7odui9f+Rn3OjcFOAWMStr/5Ls8c90ovkgAkOEZzHQbUCeWxG8dPoTcgnQmxf36syMg4QBSzcegA8RzuNaDbogNL+btw4CiYKWCs52DmnuygT+5JGdt3IQVMsMuKZu4YuSdHDHbV39j6gaA4muswYLmaB0pv3ozegHQmDMZ+JOWVcYAoZmTmNDHhOH0e3RYdWMrflAKmQN1yT8rYvoOeAsZkLv2Mb4M3dG7Lt8Xd8je2fiAojuY6DCiWzpet6xegNyBdCdtwfiXllXGAKGZs9Sox4di+A90WHVjK334dOFKBVu7J85fQbfHK39i08slu3YZuCzYb+/cSE46GuGv+xtYPBMXRXIeRvnJDrBaMH43eeHSltSIzdqTn15JxgChmct9+sVqwZDG6LTqwlL8pBUyBuqWCkbF9WylgTgY3BYzJyOQJYsJx8apr/sbWDwTF0VyHkY2kxepU7y7ojUdXWnUifViRkXGAKCZ0jPxk5qTx6LbowFL+hnqkfhw4UoGFVDAr0G3xyt/YpBQwBcaWLhFtj0103fI3tn4IDOrq6jKM6ZaIbWelaKnDCHVrL+LTEk/QG5COhNQvfEVm40bPryXjAFHMbCghJhz9eqDbogNL+ZtSwBSoWyoY2dq3SAHTNvApYExCaAvv69escc3f2PohMKipqflTO8S2s1K01GGERw0TA8aNu+gNSEdG588Vs8Kj3ifllW2AaEoaMLz3tx81p1WhbqlgZGvfVgoYmtBxpk6fExOO2TNc8ze2fiAojpY6jOi8OSKG4+gJ9AakI8Ojh/smsGUbIErR2jK6/QDdFtXZ1N+UAuZ58lQwHfRJBSNb+05fukYpYIqYuftYTDiGDXTN39j6Iaj4hdra2omMjYyfwg9qamr+uq6urhe2YZWipQ4j/v77vm1RBpGhHh2NFDDeb7HLNkCUIiRKFXVDT6Pbojqb+tuvmtMqUadUMLK170IKmEXotsjAXPpjV1PBkABEAhN7C5jYO8j4J0wA/hB+9sYbb3yTvb6LbVulaKnDSB4+Kg4pLJiP3oB0YyEFTGdfrifbAFGK8XXrxMnMLVvRbVGdTf1NKWBepJUK5txFdFvc9jc2KQXMiwz17ykmHKGEK/7G1g+BBBz2YCLw3xqvPzZ/bopBldBSh5G+dsu3NCVBo/Vsx/nzbGUbIEqxkHtyIbotqrOpv/2qOa0SdUoFI1v7js6eIVbzT51Ft0UWQoYDt1LBkABEAhN6ia9//ev/Bl6bArBVq1a/zl5HUQ2rAi11GH4mKg4ardXVhe/5cj3ZBohSpNyT3vmbUsC8SJ1SwcjWvhuHDzJSwDxCt0UWQo5T3gb3H3TF39j6IZBgAnAJ40oQgYYA/Br7fhHjfGzbKoWdDqMQp+ZtqbKg0Yqv3LTJl+vJNkCUYiH3ZFd0W1RnU3/DSjNffbh2G902WZg6+6E2qWBkat/PnehP04l+k4lt20Wfv3atK/7G1g+BxMsvv/yrTOxtZ+LvX9nXLxj/Bb5/5ZVXfgXbtkphp8OAoHHKHeY+rRPWx076cj2ZBojmaOWeTH6EbovKbOpvSgHzInVKBSNT+6acnqUJ2+F818eFVDAkAJFRU1PzSuvWrf/o9ddf/zq2LdXCTocBQeNi68j7XHVBYni0kWPx5j1frifTANHscxnl73PRlcX+hlPmIgVMR3S7ZKJOqWBkat+Fqj6UAqaYsB3OJxwjBrvib2z9EFgw4fdrtbW1bzEOhq8QA4htUzWw02FA3VCqH+o+Q907+FplRaYBojlG5832dWVUVxb7m1LAlKcuqWBkat9WChiq6/0cYTucp4Lp8q7jVDAkAJHABN/3GD9hvF5XV7eTfb0G3+tYCYQ35iOUPsJtZqMZ3+ssyzRANMdCbORmdFtUZrG/IZE7b8Pz56LbJRt1SQUjU/uOr10jTldv245ui2yEbXE+4WhMOvY3tn4IJJjYu8OEX9vinzHx946OeQCBEPtHqwfuMn31pu+nXWUaIJpj8tARX09H68pif1MKmPKMrViuRSoYmdp3hFLAlCVURuETjkvXHfsbWz8EEkz8fca+fLXJj79m/Fwp2OkwKH7IfSYPGiKnfoFv15RpgGiO6atmfsRR6LaozGJ/g5jmcbyHj6LbJRt1SQUjU/u2UsDcpRQwTQmVUXhbPHDIsb+x9UMgwYTeeoj7a/KzHzCuw7KpWtjtMOgEobuMr18vVh02+7fNKdMA0Rwxtsd1ZLG/KQVMeeqSCkaW9s1TwHSmFDDlCJVR+Gr8OmepYEgA+ggm+DYyfmCQp4BhvGK8vmKkhNmGbWelsNthFAaQW+gNSAdaBx2On/LtmrIMEHbo9wEZHVns71CvLjSBK0NdUsHI0r6zoTilgGmGqRNnxO7PnFmO/Y2tHwKDmpqasXaIbWelsNth0BaSuwyPGmqkOrnv2zVlGSBsPR8zRc6Nu+i2qErT308SFMLRHHVJBSNL+y6kgBmP/kxkZObOQ1dSwZAAJDiG3Q4DqlXwZev330dvQKqTb5EgJDuWZYCwQzityldIj55At0VVmv7O3DRSwIwejm6TrGwc1Ff5VDCytO/kvgOUAqYZ5lJGKpiu7RylgiEBiIhWrVr9Uk1NzX+ora39S/b1r0xi21Up7HYYkJON0ki4w2wkJVZk+vhb7kyWAcIOrVQwGzei26IqTX+njlEKmJaoQyoYWdp3fA2lgGmJob7dxYQjnHLkb2z9EEgYeQBzUAeYff0cvjL+jDGMbVulsNthWIlkRw9DbzyqM335hniWE8b4el1ZBgg7hFADSgXjjr8T5ur9hg3oNslKKxXMrj3otjj1N3b7phQwLTM8cayYcFyuPhUMCUAkMKF3lQm/PvAaEkAbX0cyDsK1rHLY7TByZhxRd4ojcko4/s/FzaKFvl5XlgHCDuGwkUgFMxLdFlVp+jtG8bstUodUMLK078ZhA40UMI/Rn4msjC2qd5wKhgQgEorzAJoCkOEX2M9TeFZVh0o6DOskYTSD3oBUppUCZstWX68rywBhh3BalU84enZGt0VVmv6GfIp0gr956pAKRob2/XwKmI/Rn4mshL6fr8qzscCJv7H1QyDBRF/sW9/61m8Yr+/X1NT83muvvfZb7PWn2LZViko6DGsguUoDiRNG587yPQWM2WFgDxCVEE6t8glHPIdui4o0/U0Tt5aZfah+KhgZ2reVAqZ/T/TnITNTJ06LXaC51aeCIQGIhLq6utlM7L1pvB7I+JQxw7gc27ZKUUmHQalg3GF45BCxRXL7ga/XlWGAqOg5jR5OqWAc+vuLn/yEQjdsUIdUMDK0bysFzGRKAdMcoe/nIS5sLHDib2z9QHiJi8A/eeONN/72pRfLw0mPSjoMSgXjnHyLpGs7sSKTeurrtWUYICqhmQomefQ4ui0qEvz8L9EIpYCxSSsVzMMwui3V+hu7fVMKGHuE9F/wnJykgiEBSHCMSjoMSgXjnNlwUqzI9O3u+7VlGCAqYXzDB5QKxqG/f3T5Q2qzNhmZNlnpVDAytG8rBcz2HejPQ3aG+nQTE45IdalgSAD6iNra2g8ZL7REbDsrRSUdBqWCcc70peviGU4c6/u1ZRggKmHyyDEhXt6bh26LigQ/P9u7k1LA2KTqqWBkaN+RWdNFfPPpc+jPQ3ZCGjA+4bhyo2p/Y+uHwKCuru5dO8S2s1JU0mFQKhjnNFPAxBbX+35tGQaISpi+dluI5bGUCqZaf2dXLKa4XZtM7FI7FYwM7ZtSwNhntH6haJsHj1Ttb2z9QFAclXYYdKLQGePr1qKkgDE7DOwBohIWUsF0QrdFRYKfE5PHUgoYm1Q9FQx2+6YUMJUxsXmLo1QwJAAJjlFph0GpYJwxOmem2CI5ccb3a2MPENUw1KMTpYJx4O9w3240YbPJQiqYvui2VOtvzPadbRApYBr790J/FioQ0oDxEJd5s6v2N7Z+ICiOSjsMSgXjjI0jBostkjsPfb829gBRDcNjRojndf0Oui3KMUkhG5VQ9VQw2O27kAJmAvqzUIGZm/dFiMuooVX7G1s/EBRHpR0GpYKpnnyLpIuxRZJ65vv1sQeIaggHQPiE4wilgqmU2Vv36NBWhVQ5FQx2+07u2y9iKJcuQX8WKtBMBRPq1r5qf2Prh0CipqbmFb+u9cYbb9TU1dWdZ3xUW1t7ifHbZWzqyH73mLGBcSn70dfsfH6lHQalgqme2VBCNPh+PVCujz1AVMP4B0YqGPYV2xbVSG21ckamTVI2FQx2+6YUMJUz1LurmHBUEaJBAhAJTGD9C+Mexr9n3/68l9diwu84E3fvGNf9e/b95abvacUAdYhNYcret5u97m7n8yvtMCgVTPVMX7pmpIAZh3J97AGiGsLKH6WCqY6JzZvFgLyBVuvtUuVUrwcRigAAIABJREFUMNjtOzJ7BqWAqZDh8aONmPqbVfnbXbVBsAWmt36TiaxBTHTdMsrA1bdu3fqP3L4OCDp2nR++VFRhxCg517r4fWAL4yLze6hKwr4/Y+calXYYlAqmeib3HzRSwCxCuT72AFENIfaPi+YxI9BtUY2xehGvm6J4XdtM7FQ3FQx2+6YUMJUzWr9AhLgcqjwVDAlACcBE2n9ggmwOY5qJrvvs+6FubRGzz/kD9rkPin8G28Ds53/W5GfvwXWLvv82+7uonWtU02FQKpjqGF9rbJFs3YZyfewBohrC6V8+4ehBqWAqpXliP0MpYGxT5VQwmO2bUsBUx/imzVXH1JMAlACvv/76d5nYmm2szF1l4ms746dMkPVw+tmlBCBsAbckANnr71QiAJ8+Ff9Mdlk8sFTyd0Fn1NgiSZ86i3J98HM1/sYm5AGE5/YknkW3RSWGencxnlsG3RZVWEgF0w/dlkqJ2b5zjWYKmJ7oz0ElFuJ051Tlb6cag1AFmOj7OhNZA2ALmImvLAjA1q1b/775e1iBM7ZuHcGvLeBKYVYX+OzC2Wr+PLCIjRrCn9tPU0lsU5RCYpIomfSTcAjbFGXwxU9+IgbkHh2xTVEKX37+uUgF07FN/ssvvsA2Rxn8+KFIaZKcMQnbFKXwL7GoWAEcP7Kqv3eqMQhVgImrnzARtosJrf+Xfftzpd7Dfr/CjWuxzzlhlphjgvAfSh0Cee21115nNiWZPf+OffsV4xCIrRVI+CeqdMaYMFLBQHA59gxKFT55UtgieZJ5hmKDqiuAsQXzRSzbkaPotqhCMwUMDCyq+RubZiqY3KMIui2VELN9W/HNSxejPweVWJyrsxp/u6ExCBUCVgD9ulbr1q3rmKC7AGlgjO3f78DP2evl7OffN99npIEJQRoY9nrZSx6lgQGmjp6g9BIVMhuKo6aAMWNGqvE3NuMbNwoxs4FSwdilubWUWbJAOX9jU9VUMJjt24pv3rYd/Tmoxmpj6sHPHskOQlBQTYdBqWAqp5Ulf9J4NBtUFYDJo8dpwlEhzeDyZzu3KudvbFqpYHbvQbelEmK2bzO+OXXqLPpzUI1WedUKD2uRACQ4RjUdBqWCqZxWlvwli9FsUFUAFiYcw9FtUYVmycbPzp9Vzt/YVDUVDGb7tkpc3n2E/hxUY7XlVUkAEhyj2g6DUsFUxvia1ehZ8lUVgLk4TTgqpZlg9ieNDcr5G5uqpoLBat/PlbhM+1/iUnVa5VU3bKjY39j6gaA4qu0wrGXrq5RjzA4jM6ejZ8lXVQACacJR4fMyUsB8/qMfKelvTGYfFFLBYNtSCbHad7YxiR7frDKrjaknAYgIOHQBZdoYb8P3tbW132M/+ydsuypFtR1GtcvWQWXj0AFii+QeXpZ8lQVgeNzIquJkgkiryHz3Dsr6G/X5ZT4RqWA6tMnnsj9Et8cusdp3+tJ1I74Zp8Sl6qw2xIUEIBKY0BvLBN819vVtM9/fG2+8UQM/w7atUlTbYVjL1lVkMA8aYRBp6PQOepZ8lQUgTTjsM3NTpIAJjxqmrL+x2TioD3+G2UcRdFvsEqt9Y5e4VJ3VhriQAEQCE3oxqAdsvP7E+PFXil4rg2o7DEoFY5/ZhpiRJb8Xqh0qC0CacNhncXUBVf2NTSsVzPlL6LbYJVb7jq9bi1riUgdWE+JCAhAJUP2Dffl5eF1XV/cxfH311Vd/mb1OoRpWBartMCgVjH2mP7witkgmT0C1Q2UBaImaeXPQbZGdxfVFVfU3NmPLlymXCgarfUfnzBLxzSfPoD8DVVlNiAsJQCQwobeJicAJxmsuANn3o2pqatbiWlY5qu0wKBWMfSb37hNbJMuWoNqhsgCkCYd9mtvlqcNHlPU3NgupYFai22KXWO3bSgFz5yH6M1CV1YS4kABEAlQCYYLvEqz4Mf6MMQzfG6XYlIKTDoNOZtpjbNUqsZqwYyeqHSoLwMKEowO6LbLTTAGTuXZLWX9jM3X2gnKpYDDaN08B07WdiG9OUQqYallNKhgSgLj4ChN+/6mmpuYfmfj7Y/b9V7ENqgZOOgxKBWOPkRlTxYrMmfOodqgsAIFmapMsTThsPadcLKO0vzFppYIZok4qGIz2nQ0bKWD6dke/f5VZTUw9CUCCYzjpMOhkpj02DulvpIBpQLVDdQFormylr95Et0VWFqeAUd3fqM8RUsG0fyvf0FGdVDAY/k5fFilgwhPHot+/yqwmxIUEIBJqamq+U1tbe5jxCeOPDf4EvmLbVimcdBh0MrNl8hQwHd9mg8mbbFDBSwFjdhgqC4Jo/QIx4Th0BN0WWVmcAkZ1f2NTtVQwGP5OHjgkYiUX1aPfv8qsJqaeBCAS6urqbjGxN58Jwf+Lvf4/ioltW6Vw0mFQKpiWmX0cFVtJA3uj26K6ICg+3Ypti6wsPi2tur+xGZmqVioYDH/H160T8c1btqLfv+qsNKaeBCASmPj7lH35CrYdbsBJh0EnM1tm+sIlEUw+dSK6LaoLgoK4mY1ui6wsFsmq+xubhVQwe9FtsUMMf0fnGilgTpxGv3/VWWlMPQlAJEC6FyYC/xLbDjfgpMOgVDAtEwYPvkXCBhNsW1QXBJmb943tzaHotshKKy730BHl/Y3NxM5dSqWCwfB3eOQQEd98+wH6/avOSmPqSQAioVWrVr9eV1f3kPEAE4KrioltW6Vw2mFQKpjmCYMHX0Vggwm2LaoLAuuAQ7f26LbIysJBmVvK+xubViqYGVPRbbFDv/1tpYCB/j/1FP3+VWelMfUkAJHAhN42Jv4eQRwg+zq1mNi2VQqnHYa1bF1BBvMgEfKIiRQwF9Bt0UEQhHp3FYH5kTS6LTLSSgHDJmQ6+BuTmfshpVLB+O3vbCQlJmR9uqHfuw6stNoRCUAkMKH3P7/1rW/9BrYdbsBph0GpYJonDB58i4QNJti26CAIrBWuKzfQbZGNTZNl6+Bv1OepWCoYv/0NbZCHZEwYg37vOtA6wW8zpp4EIBJqa2uvtWrV6jex7XADTjsMSgVTniIFTBs+iMBggm2PDoIgWr9QTDgOHka3RTY2HUB08Dc24fS+Kqlg/PY3tEG+YrVoIfq968BKqx2RAEQCE4CD6urqrjC2ramp+atiYttWKZx2GJQKpjxh0OBbSIP6oNtidhiqC4LE5i1iwrF+PbotsrHpFpIO/samlQrmgvypYPz2N7RBHt/M2iT2vevCSqodkQBEAhN+kTIMY9tWKZx2GJQKpjzT5y6KIPJpk9BtMTsM1QVB6vgpIXLmUiqYpmy6Gq+Dv7GpUioYv/0NbZDHN7M2iX3vurD4EJcdf2PrB4LicNph5OKUCqYcE7v2iDQSK5aj22J2GKoLgswtIxXMyCHotsjGpvG4Ovgbm1YqmFXyp4Lx29+QjonHN7M2iX3vurA4jZMdf2Prh0Djtddee71169b/uRUDti3Vwo0Og1LBlCYIP5ECZje6LWaHobogMFPBQPoJSEOBbY9MbJpIVgd/Y1OlVDB++xvSMfF+n7VJ7HvXhZVUOyIBiAQm/H6rrq7uLOO/MmaMr+e++c1vvoptW6Vwo8OgVDClaaWAOfshui1mh6GDIIC0EyIVTArdFplYnAJGJ39jspAKpj+6LS3RT39DGia+89O7K/p968RKUsGQAERCbW3tDsZFr7zyyq/A9/CVCcB6xl3YtlUKNzoMSgVTmo2D+wqh8rAR3Razw9BBEEDaCT7huEypYEyWqsqji79Rn6uVCuZt6VPB+Onv9NWbIhRj/Gj0+9aJ1kn+US3H1JMARAITeh/V1NT8YvHPWrVq9Uvs50+xbKoWbnQYlArmRfIUMB3acMoycOgiCCDtBJ9wHDiEbossLHUYSxd/Y9NKBfM4im5Lc/TT3xCjxleq6heg37dOrKTaEQlAJNTW1ja2bt26tvhn8H0QTwEDKRXMi4RVP751NLgvui3FHYYOgiCxZauYcKxbh26LLLS2joraoC7+xqYqqWD89DdM9nkb3LQZ/b51o1XtqIWYehKASGACcAiIPfa1d01Nzd/BVxCF7PVQbNsqhRsdBqWCeZEQ98eDx6dPQbeluMPQQRCkTpw2UsHMQrdFFlqr8Bs2aOdvbJqpYJJ79qHb0hz99DfEqPH4ZjbxwL5v3VhIBXOzRX9j64fAggm+doxHGe8bX9uxH38F265K4UaHQalgXqSVPmKlPOkjdBEEmdsPKBVME5aKw9XF39hUJRWMn/6GyT5PAXPzHvp960bYVhfVjppPBUMCkOAYbnUYlArmecqYQFYXQZBLPaVUME1Y6iS+Lv7GZuqMGqlg/PQ3lCujFDDeMLHZXioYEoBIqKmp+adWrVr9Lrxu3bp1XW1t7em6uroT8BrbtkrhVodBqWCeZ2TKRCNu6DK6LcUdhi6CINS3u4iTCSfRbZGBpSZgOvkbk6qkgvHL3xCbJlLAdEG/Zx1ZSAXTfLUjEoBIYIIv9Prrr3/deL2XcT4ThZOZCDyGbVulcKvDoFQwz7NxQC/pTg7qJAjCE8caqWCuo9uCzVIpYHTzN+rzVSQVjF/+hkTjPASDTfqx71lHZm4a1Y5GDW3R39j6IZBgQu8z+AqpX5j4+xS+sm+/xn7+MbJpFcOtDoNSwRSYS3/MBow38w2d3pFqwNBJEMQW11MqGIOFQ1jDtfU3NlVIBeOXv2GSz1eo2KQf+551pN1UMCQAkcBEX/yNN96oYYLvf7DXp+BnkBcQxCCyaRXDrQ6DUsEUmLn7WGwZDRuIbkvTDkMXQVBIBbMW3RZslmt7Ovkbm5Gp8oV0NKVf/oaT5iIFzCb0e9aVViqYSLpZf2Prh0CCCb1BjP8MZMLvH+BnrVu3/n/Y9xexbasUbnUYlAqmwNSpsyJofNZ0dFuadhi6CILUiTNC9MyZiW4LNkulgNHN39hUIRWMX/6GiQZPAcMmHtj3rCutVDBXylc7IgGICDjwwdC6+HvG38e0qRq41WFQKpgCE1u3iQF57Rp0W5p2GLoIgsydh2KVdcRgdFuwWS7+Vid/YzOxY6eRCmYVui3l6Je/IdSAp4Bhk37se9aV0fqFLaaCIQFIcAw3OwxKBSMYW7xINN79B9Ftadph6CIIcqln+YZ2P8g3dHk38Klgyp3A18nf2FQhFYxf/rZSwCSeoN+zrrRSwaxf36y/sfUDQXG42WGEx42kVDDwHCaOE8/hklwnVHUTBFYqmMZgp4IpN/HSzd+YtFLBDB2Abks5+uFviEkTKWC6ot+vzkwdP2VUOyqfCoYEIMEx3OwwKBWMoKw56nQTBAWhfQ3dFiw2F3qhm79Rn7MCqWD88DfEpPFY7wlj0O9XZ2ZutZwKhgQgwTHc7DAoFYzcVSp0EwSybrX7yXIpYHT0NzZlTwXjh78h7RKPhVxUj36/OtNMBdPQrX3ZcYQEIMEx3OwwKBVM0cxNwjq1ugmCwmGb4KaCaa7N6eZvbMqeCsYPf0PaJV7ikrU97PvVnaE+ZiqYVFl/Y+sHguJws8OgVDD2YjewqJsgMNPtRGfPQLcFi+VSwOjob2zGli0VK8575UwF44e/oa3xFDCs7WHfr+6EbfbmUsGQACQ4hpsdBqWCgQHZXiFvDOomCDJ3HonA/OGD0G3BYnNxt7r5G5uyp4Lxw9+Q3J6ngLn7CP1+dWchFczhsv7G1g8ExeF2hxH0VDDWgHyofP4mLOomCHJpIxVM57bSxVv6xfBY8+T9be39jc3UmfMiFczMaei2lKLX/obDL1DeEtoclLvEvl/dmdi8pdlUMCQACY7hdocR9FQw5XKyyUAdBUGoXw8RJxNKoNuCcv89OokJVzwXCH9jUvZUMF77Gw6/8Psf0Av9XoPAlsKJSAASHMPtDiPoqWBCPTuLATmWRbelVIehmyCITBovBPfFq+i2+E1YZechF726BMbfqM8783G+of2bfBVMxlQwXvs7feGSWAGdOhH9XoPAlg4UkgAkOIbbHUaQU8HAKgwfkHt0QrelXIehmyCILVksJhz7DqDb4jfTV2+KAWL86MD4G5syp4Lx2t+J3XtFDOTyZej3GgRaqWDKpBQjAUhwDLc7jCCngslcvyMG5DEj0G0pRR0FQWLbdjHhWCNX3WU/aOZkiy5aGBh/YzMydZJYcT5/Cd0Wv/0dW7lCpIDZtRv9XoPCUJ9uZYsKkAAkOIbbHUaQU8EkjxwTA/J789BtKUUdBYGZCiYSwFQwLeVk09Hf2IytWC6tCPLa35Fpk4X4PXcR/V6DwuaqHZEAJDiG2x1GkFPBxDd8IFajNm5Et6UUdRQEmbuPRWD6sIHotvjNSAs52XT0NzYTu/dIuw3qtb8bB/URq1GPIuj3GhQWQlz2l/Q3tn4gKA4vOoygpoKBbW8+IB89gW5LKeooCCAdRVBTwVg52e49Doy/sQlVQPiK8xT5DkJ46W9xAEbuWsg6MrF9R9nckyQACY7hRYcR1FQwsO3NB+Sb99BtKUVdBUGof0+xMtEQR7fFL1o52dq/yQfnIPkbk/A/xnc42P8cti1++jtzr0HqFDi6MnXmgphwTJ9S0t/Y+oGgOLzoMGROhuwlQ93ai5XP5EfotpSiroIgMjl4qWBgG44PyAN7B87fmIRV5oYubUUy5NQzdHv88nfq9DkjCfZ09PsMErMPG0U7H9y3pL+x9QNBcXjRYSQ2b242g7mOzEbSYmWgT1d0W8pRV0EQW7qkbJyMroRAfD4gT5scOH9jE/Ky8ZX+2w/QbfHL3+ZWZBBP22OSr/R3bJNv6PBWPpf55AV/Y+sHguLwosNInTgjTsPOmYnegPxi+vINcfp5whh0W8pRV0FQGJxWo9vi2z3v3C1ig1auCJy/sQmVGXis7/FT6Lb45W/rMML+g+j3GTQ2DulvxPo2vOBvbP1AUBxedBhQKDxoJzPNnGyxRfXotpSjroIgiNtTcAqVD8h79gXO39iEJPd8wrFpE7otfvm7kI7kOvp9Bo3Qr5U67U8CkOAYXnQY/GSmxCWTvGB83TqRH2zLVnRbylFXQQCnYIM24YhMniAG5A+vBM7f2JQ136eX/g717W4kJE6h32fQGF+7pmS+TxKABMfwqsMIWs6oqJmT7eQZdFvKUVdB8FyN1oCkgrFOPofKn3zW1d/YLCS7H45uix/+tkqSdWsfmPYlE8vtLpEAJDiGVwMEHFvngujsBfQG5AchPUJzOdlkoM6CoHFALyMVTAzdFq8Jp0957sMuzec+1NnfqM8/YSa774Buix/+zty8LwTvqKHo9xhEpq/cKFnzmwQgwTE8CxpetVIsW+/Yid6AvKY4qfW2cVKrdE42GaizILCzJaoL4fQpHxBGDgmsv7EJp/35hCMiz5aoV/5OHTsptrznzUG/xyAyG82ICUevLi/4G1s/EBSHVwMEpOTgy9ZLFqM3IM8baDO5mmSizoIgtsxIBbNX/1QwcPqUD8hzZwfW39gMTxwr3aEIr/wNh134oZcNG9DvMagM9egocszGc8/5G1s/EBSHVwMEFK/mqxQTx6E3Hq+ZOnNenEKdMRXdluaosyCAlWY+4Vj9Yskk3RjfZOTZfP/9wPobm4UarQfQbfHa39EF88W9HjmGfo9BZXjsi9W1SAASHMOrAQJOi8meGNktqpKHTmdBoIoId4PWgHz4aGD9jU2rRqtEEw6v/B0eM0LEN1+/g36PQWWp6lokAAmO4dUAAcHpECTNl60TT9AbkJeMLa5XIkmqzoIg+8Dchu+HbovXtDsg6+xvbMo44fDC37wfN0tcat6Py8zE5i0vVNciAUhwDC8HiKDMHKH6B1+ev3ID3ZbmqLMgeL5kkrwHcdxgqLsZD9T8gKyzv7Ep44TDC39nw0mxk9O3O/r9BZmpE6dfqK5FApDgGF4OEHa3qlQnnM7iA3I0g25Lc9RdEKiQiscprZrTvbu0+F7d/Y1JPuHoULpGKxa98Hf64lWx0jlpPPr9BZmZOy9W1yIBSHAMLweIxObNLyxb68ZcLCsG5J6d0G1piboLApgd89yTJ+RNxu2UVk4wGzWndfc3NhuH9BMTjvshdFu88ndi914R67h8Gfr9BZmlqmuRACQ4hpcDRGHZehZ6A/KK6au3xIA8bhS6LS1Rd0EAEw2ee5JNPLBt8YqV1JzW3d/YjMycJiYcp8+j2+KVv2Mrlos2tWsP+v0FnY0De4vck4+jlr+x9QNBcXg5QFjL1sMHoTcer2gOyNFFC9FtaYm6CwIINeC+WDAf3RavGF+7tmRd0CD6G5vxNUaN1m3b0W3xyt+RKRNFfPOFy+j3F3RGpk0Svjh30fI3tn4gKA4vB4hSy9a6sZIBGZu6C4JCjdZh6LZ4xcjM6WLV6dTZwPsbm3Dqn6/GLm55NdYPeuHvUL8eLdacJvpDazV2527L39j6gaA4vB4grGXrRxH0BuQFrQH59Dl0W1qi7oLAKlrftZ22ResriTvT3d/YTF++bjse0w+67W/enqDmtMbtSSVa8ZjLllr+xtYPBMXh9QARmTZZCCRj2Vo3yhYI3hyDIAgKKxYJdFvcJpw2hVOnkO7Gzop6EPyNyUpOZPtBt/0dhBV1lQh1zvmJ7MnjLX9j6weC4vB6gIitWimWrXfsRG9AblMMyG04VdjiDoIgiEyeIOJkWGeJbYvbzNx9LGJqhw4gf0vCQk7GHLotbvsbSr/xmNr35qHfG/Ezvg3PJxxskmv6G1s/EBSH1wNEcu9+sWy9dAl6A3KbsOrHB+Qh/dFtscMgCAJIV6HrqcVSyWCD7m9slqrRikW3/Q21pnkar036nqpXibAND9vxsC0P2/MkAAmO4fUAUUgkOg69AblNiPvj9zZrOrotdhgEQaBz3rL4pk1iQGYDM/lbDkbrF4pk9wcOodvitr8hfZfIq3ka/d6IguFRw0TI0Y27JAAJzuH1AJENp7QtJQQnf/mAvHYtui12GARB0DRORidG588VYuPIcfK3JIQUMLwPWLMa3Ra3/Q1VJ7jYuKtvZR3VWFxdiwQgwTG8HiCeKyae/Ai9AbnaGBcZs/+Dh9FtscMgCIJso761S8Mjh4gB+eZ98rckTJ25ICYc06eg2+Kmv0Vt7bfzDe31r62tEhObt4gJx7p1JAAJzuHHABEePdxatsZuQK7e17hRIv7nKn78jx0GQRDwOBlzwpF4gm6Pq/fVpa2I/0k9I39LQkhvxeOAB/ZGt8VNf2cfNor7GtwX/b6IBUL+Tz7hmDmdBCDBOfwYIIqXrbEbkJsM9egkhEYsi26LHQZFEITHjBATjut30G1xi1D+iQ/IA3qRvyUiF+adKxPmXtFNf6fOnBdCY8ZU9GdMLNA6eDi4HwlAzfGVmpqaBbW1tSHGx+x1z3JvrKurizI+YO+7wXidvfcf7V7EjwEisWWrsWytRqycHWajGbHV2EuOHGB2GBRBEF34nphwHDqCbotbTJ39UAzI0yaTvyWjtTV/y97WvFd0099WbOPaNejPl1hg8db8k+zHJAB1BRN0bZmYOwqvv/Wtb/0GiDz2/bfLvDfcunXr36/mOn4MEFAsXSxbT0NvQG4xfemaSJI6UZ3TzUERBMVxMti2uHZP23eI082rVpG/JWOlh3O8opv+tuKbJTjdTHye5uGc7N1HJAB1BRN7+2pqav6p6PvpjBNKvZcJwMjrr7/+3Wqu48cAkX0YFsvWg/SJJ2lalkcFBkUQpE6eEROO2TPQbXGLscWLxIC8/yD5WzJWmp7HK7rpb9Xim4PE6NzZIj3P8ZMkAHUFE3W3meD7Y/N7Jga7s+/XlHlvhP3uJvt6i3H5q6+++rLd6/gxQPBl607v5Bvav5nPpXHjZNyilXCYCUFsW+wyKIIgc6+hoooZKjA8frQYkC/fIH9LxtQJMeGIIk843PS3avHNQWJ8wwdi7Nn4AQlAVcEE2wXGJ8Vk4u0j+MrE3jdKCMAe5QQgvN94+TX2d9PY+/bbtQM6jKdPRefhJc04mezt+55fyw9CYmse93PpKrotdgl+9svfmHySNWrmdmjDX2Pb4wZDPY0BOZ4lf0vG7P1CiT5MO9zydy5q1jjuiv5siS8SVv74hGPebBKAuqKSLeBitGrV6jfZ+z61e528T8guq+f/tJ9dPO/XJT1FuG83fj+f/+gzbFMIJRAbLuJkfppJY5viGJ//6Eci3rRPV2xTCCXw5eef5xs6tuGE16rjx48finCDaROwTSGUwE+TCRF+NHooCUBdUVdX965xCOSr5iEQJgh/r+n7Xn311V9u3br1r5nfs/cMYH93yu514B/KjxWCxObNRpzMevQZlFPmYuYJ4M7otlTCIK0IwXYc3zI9eQbdFqfMXL4uYhonjCF/S0pY/eM7HPcfo9nglr+Te/cZ8c1L0J8r8UU+yXzMTwHDaWB31AZBRnzVSAPTyNjABGAv8xfs53/HuAxev/baa69D6peiGMCdTBB+y+5FoMPg/1Qexy1YCSw1CMxPX7punAAei25LJQQ/++VvbFqF7DduRLfFKZN794sBecli8rekNCccEA+IZYNb/oaDbarFNweNkKAbfOSF8CAECH4NEMUJLLEbj1MWz5CxbamEQRIEqWNGnMzc2ei2OGVs5QoxIO/cRf6WlNaEY9MmNBvc8jdMbPnq+aVr6M+VWJpQCYQEIMEx/BogCieB38rn0mrXlrROAO/ag25LJQySIMjceSQmHMMGotvilJEpE8WAfP4S+VtSQg5APuGYPxfNBrf8bR04imbQnyuxNKGoAglAgmP4OUA0jhgsTs7eeYjegJwwMmm8GJAvXkW3pRIGSRBAAXs4BQzMZT5Bt8cJQ33EgaNsOEn+lpRQBYSHhYwcgmaDG/7OhlPWCWDsZ0osTyirSgKQ4Bh+DhDReXNEnMyxk+gNyAmhc+QDciSFbkslDJogMAPzM3cfodtSLSEPGx+Qe3Qif0tMyG8K9YChLjDsdmDY4Ia/0x9eEbHabJKL/UyJ5Zm5cZcEIME5/BwgICCfx8kW9o6PAAAfDElEQVRs2IDegKqlNSD3rHxAxmbQBIGVMV/hCYd14GjCGPK35Gwc2FtMDB+GUa7vhr8TO3eL+OYVy9GfJ7E8c8mP+IQDWz8QFIefA0TqxGkRJzNnJnoDqpbpy9UPyNgMmiCwJhzIJbqc0EnJwaD5G5tQ65xPOE6dRbm+G/6Gk+Y8B+C+/ejPk9g8kzt2kAAkOIOfA4QOJbqslBxL1ToBDAyaIJClRJcTwklzPiDv2Uf+lpzx9etRTwK74W+rBvAV+yUHiTgEP2PrB4Li8HOAgGB8njG/w1vKBubD1og4Abwb3ZZqOowgCQIdUg/BSrOoAXyd/C05sVMPOfV3LvdpPtS9g1FyMIf+PIkt+xtbPxAUh98DBKTlEIH5j9EbUDWMTDZOAH94Bd2WajqMIAmC51MPPUO3p2L7+YDcUQzIsSz5W3LCYSPMHQ6n/s6G4iK+uW939GdJtOdvbP1AUBx+DxCqB+YXUnKodQLY7DCCJgis1EO37qPbUimzoYSjATmI/sbk8zsc/uc6derv9LmL4gTw1Inoz5Joz9/Y+oGgOPweIOKbjJrA69ejN6BKWUjJ0RHdlmo7jKAJguh780QM3ZFj6LZUysKAPIn8rQitCcftB75f26m/E9t3iPjmVSvRnyPRnr+x9QNBcfg9QKROnxeD2oyp6A2oUkJpJBVrABd3GEETBInNW8SEY906dFsqtt0ckFevIn8rQmvCcfio79d26u9o/UJh+4FD6M+RaM/f2PqBoDj8HiCyj6MiTqZ/L/QGVCnh4IfKObKCKAhSp88pO+GI1i8QA/LBw+RvRZjYslVMONau9f3aTv0dHjNCxDdfu43+HIn2/I2tHwiKw+8BAgLbG7q1N06aPUFvRJUwtrheDMj7D6LbUm2HETRBkH0UEROOgb3RbamU4dHDxHbijbvkb0WYOnNBTDimT/H92k78zfvlru1Ev5z8CP05Eu35G1s/EBQHxgARHj/aSG2hVq4pc4acuX4H3ZZqO4ygCQI+sHVpy7Pm51JP0e2xbTecYHZodxD9jc1sQ0zECffr4fu1nfhb5Z2ZoJIEIMExMAYIJ8ltsejGgIzNoAoCayVNIeEO5cT4gDyoD/lbIWLucDjxtxWbjbBySaze39j6gaA4MAaI5N59ylXTyD5oNAbkvui2OOkwgigIYovU27qHcmJ8QJ45nfytGLGqaTjxt1U2UcHsDEElCUCCY2AMEOmrN8VpWtZRYjciu9ShrFhQBYF1eGf5MnRb7NKNdElB9Tc2rXq6e/3d4XDib6jPrnJ+1iCSBCDBMTAGiFziCd9KhaBj2DLBbkh2GN/wgRiQP/gA3RYnHUYQBUH60nUx4Rg/Gt0Wu4zOMxKmHz1B/laMid17xIRj2VJfr+vE37CzwcMk7ofQnx/Rvr+x9QNBcWANEHAqk1fUeBRBb0h2GJk9QwzIJ8+g2+KkwwiiIIBYLPAdxGapMuFoHNJPDMj3GsjfitHKFzphjK/XrdbfcOqXT8i7tOWxztjPj2jf39j6gaA4sAaIyMxpQlCdOovekOwQgvG5YH3YiG6Lkw4jqIIATjeqMuGAQ0Z8QO7sbEAOsr9R/WdWDOre0dcJR7X+Tl+9JQTrmBHoz45Ymb+x9QNBcWANEPH33xdbqhs3ojeklliYIb+r9Aw5yIJApQlH+po7A3KQ/Y1NqN/MJxwNcd+uWa2/rUN5SxajPzdiZf7G1g8ExYE1QKSOnxKHKubMQm9ILdGtARmbQRYE1oRDgRhOtwbkIPsbm5BOhU84Tp/z7ZrV+huyMYCtid170Z8bsTJ/Y+sHguLAGiAg2JinVRncD70htcTkvgNiQF68CN0Wpx1GUAVB6sRpkVZlVvVpVfyiW6dIg+xvbGJMOKr1d3jcSJS0NUTn/sbWDwTFgTVA8MTKnd7JN7R/M59LPUNvTM0RTvPxGfKuPei2OO0wgioIrMTKCpSEK9RkvUX+VpRm2igneRz98LdVAg4S3FMJOKVIApDgGJgDhCoVGsJjjRny1ZvotjjtMIIqCJ4b6BLy1qDmE6PO7lScCbK/sWnWoA717+nbNavxNxxqU2ViRHzR39j6gaA4MAeI2GKjQsPe/eiNqRytAZmvVKpZAq64wwiyILAqNEhcgzpz77EYkIc4D40Iur8xCROOUPcOoiRcLOvLNavxtxUaoXCC+6CSBCDBMTAHCKgFLPvps8zdR2JAHjoA3RY3OowgCwKzBjUk6sW2pRyTR4+Lw1HzZpO/FWd44jgx4fjwii/Xq8bfKmVjIL7ob2z9QFAcmAMEbP3y07WjhqE3pnJMHj4qBuT35qHb4kaHEWRBACvN4jBPPbot5Rhfu0aI1C1byd+KM7ZqpfDltu2+XK8af6uUHon4or+x9QNBcWAOELn0s3xDh7fyDR3b5HOZj9EbVCnGVhqd+PYd6La40WEEWRAUJhxD0W0px8jUiWJAPneR/K04rcnj/Lm+XK8af2PkKyS6529s/UBQHNgDROOIweIgyM376A2qFKGcE9/GuXgV3RY3Ogxsf2Myl/6YTTjacMJrbHtKMdS7ixiQw0nyt+LM3PE3fKRSf8P/GD+owv7nsJ8VsTp/Y+sHguLAHiCi9QvFQZD9B9EbVFNaJ0chkDsu78nRSjoMbH9jMzxyiJhw3LiLbktTZhvdHZDJ37h8PtWV9wfIKvV36sx5cQBk2mT0Z0Wszt/Y+oGgOLAHCMitx+Oyli1Bb1BNmX1gpEgY1AfdFrc6DGx/YxOSebuRZNkLQhwWH5CnTyF/a8Lw6OGu5HT0wt+QpJofAHn/ffTnRKzO39j6gaA4sAcImQuRp46dVKZcnd0OA9vf2LQOgiyS7yCIdSJzgzvVI8jf+LSquuzxfsJRqb8jM6b6Xq6O6K6/sfUDQXFgDxBQBQS2SGCrBLZMsBtVMa0TmZu3oNviVoeB7W9swtYvX9UdMRjdlqaMTJ0kBuQzF8jfmtDPCUel/g716SriTUMJ9OdErM7f2PqBoDhkGCAahw0UcVm3H6A3qmJGJk8Q2zcunMiUgSQIPuOnzeHUOZw+h1Po2PZYdkHi4B6dxIAcSZG/NWHm5j3fJhyV+BtEH483ZSIQ+xkRq/c3tn4gKA4ZBojowvfENsmBQ+iNyuTzA3Ia3R63OgwZ/I1NswRh+tptdFtMelE6jPyNz1zmk8JBEI9r7Vbib9j2dTPelOg/SQASHEOGASKxc5fYJlm+DL1Rmcw+DPtey9OPDkMGf2PTjMuSqSJIId50JvlbM1olCC9d9/Q6lfjb7XhTov8kAUhwDBkGiPSVG9IdBEkeMUpyzdXjAIjZYcjgb2xCyiHu2/qF6LaYjK1e5VoFEPK3XLSSyXtcEaQSf0PqFxFveh79+RCr9ze2fiAoDhkGCH4QxKwIIkmC3tiK5dpUACnuMGTwNzYzt+6LuKzhg9BtMWklHHexbiz5Ww5a9Z09nkxW4m83E44TcUgCkOAYsgwQUA/Yr3xZtuwZM0LYc/kGui1udhiy+BuThbist3xJ0NuiPZAwGBKOt/uBqwnHyd9y0Awnaezfy9Pr2PU3lH3j4S19u6M/G6Izf2PrB4LikGWAgPg/vuK2Yye6LeKk6NvipGhKnpOibnQYsvgbmwWB721clh1m7holw4b0I39rSC9OeDvxd+r4KXEAZOZ09GdDdOZvbP1AUByyDBDJI8eMbZLZ6LZkrt8RMYkjh6Db4naHIYu/sWnFZW3dhm5L8uBh8b//3jzyt6a0Yu5OexdzZ9ffsVXy/O8TnfkbWz8QFIcsA4RMp26t8nRL5StP57TDkMXf2LRWQWbhr4LEli0VA/LO3eRvTQmnbb0uu2bX3+GxI6VZ/SY68ze2fiAoDlkGCL5N0rOz2CZpxA1MhpUYnpfw4GH05+J2hyGLv7GZDRlxUL278P89TFsgSTBPhH79DvlbU6bOXhATjqkTPbuGHX/DITsrEbpG4S1BJAlAgmPINEBYtSlPnEG1o3FwXzEg33uM/kzc7jBk8jc2Q/16iAnHowiaDbnEE1EKsXNbfjiF/K0ns9GMmHB07+jZhMOOv9NXb4rwltHD0J8J0bm/sfUDQXHINEAkNm8W2yRr1qDZAFU/eEfdrT36ypAXHYZM/sYmxJvyld4jx9BsSJ+/JAbkiWPJ35qzcVAfMbG8683E0o6/Ia0VD29ZsRz9eRCd+xtbPxAUh0wDBORA44Ph+NFoNqROndW2RBIJgucJJ86xK9BYsWHr15O/NadV8nLvfk8+346/odIM32U5egL9eRCd+xtbPxAUh0wDBNTK5Nthnd5xfTvMLmOrjIoMm7egPw8vOgyZ/I1NqAWMfdo7MnmCGJDPXiB/a06rAo3Lp70r8Tfk/uNhD4+j6M+D6Nzf2PqBoDhkGyC8Coi3y/Do4dolgC7uMGTzNyZ5vkczITSbfPh+/eIE0LEs+VtzZu6HPE0I3ZK/QfTx8JY+3dCfBdEdf2PrB4LikG2AsBJCI5Rg4yuQvCTd29KUpHO7w5DN39i0SrBduOz7tTM3jZJ0wwaSvwNAnumgl1GCrSHuu7+Th49qV988yCQBSHAM2QYIKz/bjKm+X1uGGESvOwzZ/I1NyMvmVQxeS7TyTS5ZTP4OCCOzZ4g4wKPHffd3dNFCMbnevRf9ORDd8Te2fiAoDtkGCCiVZJ3Czf7Q12tbAfnr1qE/B686DNn8jU1M0Q8rMVwMHDpC/g4IrYNHy5b67u/CKeRH6M+B6I6/sfUDQXHIOEA0Dh0gOqqb93y9bmTyeM8C8mUgCYIXCclwRWLcNuz1U/+uyxOfd/JsO5D8LSfNMpONwwf56m8r8XnPztqltwoqSQASHEPGASK2bInYqmCzZb+uyQ8EdGkrAvLjOfRn4FWHIaO/sQmrf37HAWZuPxBCYHBf8neAyA/+dHlX9DPRjG/+tmqtz6H4P11IApDgGDIOEKljJ0Uc4Mxpvl0zfem69hnySRCUJkYcYGLnLk/j/8jf8hJyjPKdhuOnfPN3bHG9mFTv2oN+/0T3/I2tHwiKQ8YBIhtOFcom+RQHaImAdWvR79/LDkNGf2MTVv78jgOEyQ0XAWyyQ/4OFq04QJfFf3P+bhxklLe8Q/F/upAEIMExZB0gGof09zUOMDx2pNgG/PAK+r172WHI6m9MQuwfxAD6FQcIkxo45MTj/yIp8nfACCKMb/8P7O2Lvwvxf50o/k8jkgAkOIasA4SVD3DLVs+vBTF/VgWS9DP0e/eyw5DV39g08wH6cQDIOgjgUf4/8rfc5AeAencVE4BHEc/9nTxwiPL/aUgSgATHkHWASJ25ILblJo71/lpm/d8pE9Hv2+sOQ1Z/YzOxebPYllux3PtrsUmNH9cif8tLKAfHUwDtO+C5v610Q0wIYt830T2SACQ4hqwDBN+W6/g2r8yRSzzx9FrWauPWbej37XWHIau/sWlV5Rjk3alck9Zq4+nz5O+AMnnwsLEqN9tTf/Nwg+4dxGpjKIF+30T3SAKQ4BgyDxCRyRPEQHnqrKfXaRzcz4g3vI9+z153GDL7G5PPbcs9bPTuOrEsrz3Mww08jjckf8tLyP3I4/J6dHLtoFspf6ev3BATmxGD0e+Z6C5JABIcQ+YBAuoBe50qAwZ73hH36uJ75RGMDkNmf2MzuvA9o1TWHs+uYaU4mjaZ/B1wQgwoP3h29aZn/rayG6xdg36/RHdJApDgGDIPEFCyiIuz/j09O71mpmSI1i9Ev18/OgyZ/Y1NS5xNn+LZNczYLy9FJvlbDULJSTfFWSl/Q15TLjIvXkW/X6K7JAFIcAyZBwi+Ldevh1G/8rEn14hMGie2mU+eQb9fPzoMmf2NTbE9+2a+oXNbT06D83gss/ybi6c/yd9qMn3tttieHdLfE3/zuurtfpBv6NqOVzrCvl+iuyQBSHAM2QcIsyxcfNNm1z+bp3/p8BY/bJJLfoR+r350GLL7G5tmWTgvDmikr94SA/7QAeRvopgQGHGnmfsh1/0NJ4z57sbsGej3SnSfJAAJjiH7AGFVaRg11PXPTh497ls8lgwkQdAyzbjTaP0C1z/b7S0/8rf6tEq0bdvuur8j0yaJ9C9HjqPfJ9F9kgAkOIbsA0Qu8wkvCefFtlmEzYx5B7l3P/p9+tVhyO5vbGYfRwtlCNn/nlufC+EMjYP6GEH/t8jfRM7UmfOulSEs9rfY3WiTb+jYhr32No0WEYckAAmOocIAYZ3O3LHTtc+E3IKQigNScmSjGfR79KvDUMHf2ITVZi7ULlxy7TOhpKHXB5rI3+oxl3qWb+jSlsfqOc3TV+zv5OGjnh9oIuKSBCDBMVQYIFKnz4lZ8pgRrn2m1UFO1bv6R9MOQwV/Y9OqCrK43rXPjK9dK7Z/16wmfxOfY3T+XDHB3b7DNX9HZkwVuxv7D6LfH9EbkgAkOIYKAwScYAv16OhasDQQZsZBK49EgsAesw/D/H+joVt7vkLj9PP49u/A3uL/98Zd8jfxOVplL0cNc8XfuWiqcLgtlkW/P6I3JAFIcAxVBgizXFt8/XrHn5UNmx1km0B1kCQI7NMq13b0hOPPSl+6bpSZ6+Pb9i/5Wx3yOGcjPVDmXoNjfyd37jLKzM1CvzeidyQBSHAMVQaIzPU7IoaqXw/HFTug5i/vIOe5V4dTBZIgsE/YOnPrhHh0wXyxxbd5C/mbWJKxZUvFBHfdWsf+NmNYYWUR+76I3pEEIMExVBkg+DbaEFGzN3XuorPPGdzXCPK/jH5ffncYqvgbm3ByUhwS+v/bOxMYueo6jqfbWA0eSOxSnHWvmd2NiNVookSDSvCKBGIIhQjSVksRKLRRS+tRtNhKQKPUrbUiTQmUYFGKbRSl9LIGAcvSaguh1O52t3vvtkAxHhs8xu/vzf8tz3F2d859+2Y+n+SX9z9n/m/+7/jO/7wiOXj0eP6fY4tL+5ONChzkT32Xr41OErrhmuRQf36LNls9j3R3vbq1ZRFnsWNTzxCAUDBRekH0uK6NQma29e/bn+qOW7p4UrvjpoIhCHIz2x6w0FaZnm2/TF2z372N+sbGNZvkVsi6fd7yLxvdwvmbNoV+PlhpDQEIBROlF4TXKvOF+d6SCflOBvFnx/X8/MHQzyeMB0aU6jtsGzj4XKo1ZdHVeU0GsaEK/uSPvscmvzuO+o6W9W7fkZoMcsvNeeW3yR/tC69KtTYf7Q79fLDSGgIQCiZqLwh/MoiNmck178AzR1KzO21vzAqa/BF8YEStvsO2Y6tXplplHs59sfC+Xb9NtTZ/dWkorc3Ud7TM9p+2LmBveMpTB3LO37N5c0WOba5UQwBCwUTtBTF4uMMbl2UzeG3Xhlzy+gtKT+ZabFPJEAS5m78GpTf5KIexWSb4jq1YnhKP23dQ31hWZj0T3pCBW7+VUz77Q9t+3edTM4kPHAr9PLDSGwIQCiaKL4iu9etyXqh34NDhV4Vje2V2jyAIcjdPyH3ja6lhA1u3ZZ3P32faE44D+Q3qp74rz4Z6TyTbFy3MuRXQ32e6v/V71HeFGAIQCiaKLwhvv1YJORvrYsJuovTeS3z1LQUP6I+6IQjyM5stnpqhuTA5lMW2gTZe0ISf1/q3M78B/dR35ZrfCtjx9WVZzeT1nofXpLaTG+nppr4rxBCAZUxLS8uFsrbm5uYRHe8YL20ikWhSmsdlR5R+n+zsbL8nqi+I7nvvSQ2YXrF8woekzarzXuCLr/X2AA677GE+MKJa32GbrQfoja9qXTNhWvuT4V2bK1eEOtOc+o6m2VADf8mribaHs+vL39Xo+Lq11HcFGQKwjDFRF4/HZ0vMrZpIACp+d1NT01xzK/2l8j+V7fdE9YFhrSwdy7444e4gg893eFt6FbK8QrkYgiB/s7UAbfLQRLuD9D/Z5rXE2E4zk7ntG/VdXuYvV2XbuY13HflLY1m38VBXP/VdQYYArAAk7FaOJwAVXy3Rd0rOKj9M6Qdk8Ww+P8oPjP6nD6a2dBtjlqaN9bPtt7yWm7U/CL28YRuCoDDrfWTH6EvZhF56vL2o/T8bU2GZIeo72nb87o0pcbfkuozLXvXt3usNg7E/HLbMEPVdWYYArACyEIDvVfzhYJh1Ayv8/Gw+P+oPjNGXsnWB3Pnj5OCRTm8gtY29al9y7ei6WkN9J0Mva9jGC6Jwsxnk3vW24LPJ7gd+lhzs7PdmYHotMTYOy/5srFs7JRYZp76jbTa0xR960H79Am97Qnu22Y4y3nVoLc32Z+PBLdR3BRoCMMJIpD0hGw6ahNwJd6zx0+UjAK0LOBcBePJk6mKKqvU9ujM1KcQJwaB13v7t5HDPUOhlnApm9VwO9R2mDQ+/nOy5//6M15r3J2TDXcnhwZdCLyf1XR42PPBCsqv1jszX24Irk73640F9V6ZZPectQCAalLoLGAAAAACmGCYAJfDWjJdGYm+PbL5LPyeXSSAAAAAAMEVIJBIXSPj1WOue7GVZt+wii5PIu1h2l582Ho+3WJeyLQPjun/PCa/kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQOy0tLRfK2pqbm0cyrDE4ramp6YeKa5f9We4bQikklAy3tJAtPn5A9kddA/eFXSYoLraXuOr1cVsZwHYGkp0ddpmgdKieu2xDALuf7b7WPX5Z2GWC4qE6bVX9dur4n8bGxnf54dznkDN20cTj8dm6WFalC0D55yl8p7nr6urOsAcLF1V5MdHi4hB9VL+7Vc9zza3791LWBi1vVL/H7JkedjmgNKhuz6utrY1ZPQcFIPc55E0mIaCL6GGFXx7wf8eE4uSXDkpFNouLQ3Rhd6DKw1qHgsIAypNgPXOfQ0FkEoDyH9JFdW4gzfXy3zPZZYPS4QRgj+v+3ZXtvtEQDTLtD27dQ9Rz+eK6B/+k40HZhlgsNjPsMkHxSROA3Ofw/9iuIG6M16jpQjnhjjV+uiwF4CIEYLSYqP4TicSZSjbd0sr9QYUP6VgbcrGhSGR6Mbgdgs4PqUhQYlS3b3PO6arr23VP/zrUAkFJmEgAcp9D1tAFDIbqd7uug0vCLgcUB7qGKpuGhoazbPvQsMsBxYcuYCgamcaC6eKZ7yaBVPmTQNhbuLwItgLH4/Fme2jYxKAwywTFRXW6x+5lc+v+ncPg8PIlFoudpvv4dN+v+v6ynuF7QywSlIj0sZ7c55Azetlf4MaAnbJ/irJu2UUuusotA9MhO6oL6sZQCwtFx7r0XVe/jQFso/Wv/JAgaLGhALY8hOsW4k9cmVJfX9/olnTyxwBuVf3XhV0uKB6q2zvtna26fcX+sNsSbRbOfQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQXdwC8E9mk9YtIL85n+9R3o/YOmb55AUAAACAIuIE4BPZpHUC8Kf5fI8TgP355AUAAACAIoIABAAAAMgRCaKbbEtFiZu/6NguoXN5IG65ba2ouBM6/qK+vv6tfpzt7eny7pf7rzpuaWhoeLPy32vbNNrWXnK/w0/f2Ng4S2EPKG5QdtzE2FhlUrptSvOTQDnWyB4dI+3/CED5v2+fb+cje1ruD/txTgA+pPD73Pk+E4yfOXPmGwNbV/Xb1pIKnuHyIgABAAAg+rj9OP+WSCSazG8iTSLu7eZW+OckeI4pTbPEz2vlXy//Y35eE4C2H7PSn1VXV3eG29PzeaX7uKKn6dgaEG3m3ydbJfdrLI8JR33u1ZnKVVNT8xbF9yr+0/rMj5lotLJlSpsuAOW+wsojZ5XcS2RD+r7XWZwJQNuTVGFXWrzc8+R+Sed4usv7kGzjrFmzXq+0b1L8I/KvdnkRgAAAABB9JGjiJgB1vMQXST4K3ylb7Purq6vfYOKpvr6+0eU1ATgvkL5V/t/4fgmmDyhs2KV9v6wv+PmKv0phu8cqmwlJy2+tcUp78TjnMG4XsOJfVP73uO80AdiW9j0HTBAqrtrOz8RfIO+HrAXU5UUAAgAAQHkgYTNHImevddvKfmWtghYu93PpwstmwSr+POfuVPwnAnG3Kc/dAf+75f+7+47L5P+niTEza3WTnZL70DhFq3KtiofHK3+GLuClVnb3HWb/cq2So13Aafm3KmyZzut9Ov7bL6Mr5yn7XVxeBCAAAACUF9YC6Lptf2f+sVoAla7B/LkIQB3Pte7kXMqjz/6mLe9iLXRyf2msdEEBaC12spNKf04g/kW/nGO0AO63FkDrYtZxREHTxygPAhAAAACij7X2yT5qY/zkna7jrRI5eyzOxgBa96eNATRxqPAfyX7v581SAP7DeavcGMCbY7HYafJPs3GHwQkYQZxgfMG6m20iibXkKf07M6UNCkCl+ZS1UrrJKjMUvsJaHtME4Cuyz7jznWufbZNX3PfaGMD1vl+fV6s0n3R5EYAAAAAQfSTuZkvw/MHN2rVuz11+F7CYJtHzFWu5s1Y1m5lbW1sb8/NaeLYtgIbE1Jk2Q9jGArqu2f3BGcc+NgZPcUdN2Plh1hLpuotnpKdP6wK2buMN7nzse24KltN1AW9R2CY3C/hZE3b+Z1krpxvL2OW6f5+V+0aXFwEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAO/wWNRt1/gRy70gAAAABJRU5ErkJggg==\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\") as figure:\n",
" figure.plot(np.sin, label=\"sin\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9Z5RcV3Im2OyWNFpNS6PZJacltgOBqpJmZrWa2bPSrM6ONDPaI83qx57VaHa0TQcS3nvvvfcECpYAYQjCe8J7S3jvK6vSOxAgm+xRGzWbtTfufe9lopBZlS+fiWviO+dDZRWy8sV7UTci7r1xI77xDQKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAsFn1NXV/aS2tvYv2nhPtKamprOX67BrLGDMs8/6kn3Wv/byWW2Bff5/YNf6mr38pp+fyz7zr5j8D9nXL9jXGezrG+zrAz+vQSAQCAQCgdAqWADSCQIdFvBMb+u9LFB5h7032dp7ygVOXgNA9rv/O/vcn7dr1+73qv2McmCf+wGTb32L68F9/OobPgeAEPyxzx7s52cSCAQCgUAguAILSC6zQOcJY459++utvZe9513GRGvvYcHNf7QCp2+1uI7XAPCttq5dAUreX8gB4C87dOjwl35+ZgVoVa8EAoFAIBAMQvv27f83CHJYsPPXsLoG25GtvPffs///GeNXsOUL27Ds9evwf7DiB0EN4/fZ65/CZ9rvYZ89Et7TMgBs167dH7L37YPAE1YV2f/Xv/rqq79V6trs/yYWX5t9vWPJ9M/YZ66E37eC2P3sZ3X277H/m8Def5b9fDL7mmZf75b47FGM/8j4iyKZv2cHgIz/lf3sEWzZMh754Q9/+PtFn/9PYOWU/TzC3vOMfT3F+G/KPL9aS3b4zJ/Cddjz+j9arqq+8sor32bfr2U/fwoBL2N/6/l0tK75wgpry8+wAtot7OtS+7nAz7///e+/yl5vZExZz30je+Yvl9M5gUAgEAgEDQGBAuM16/UmFjSca+39VqDxwiqcHQDC66KVs5da/K4TAH73u9/9n6zApD/79te+973v/Y8QXDGucHNtCCDZz4+zz32FBZS/aeUIJuxA0goA/5H9bAz79jfgPeWeQ5kVwK/ZzzdAUPbyyy//NjwfeG/R760tCgq/yX6nN+QoQmBa7j6sZ/Wfyt0Xe72G8eJrr732HZCX/f8qKzgtDgCfW5ks8RkfWL/zDvv2W9Z9/wbkGrL/mwXfwzNin7UO5C8nK4FAIBAIBM3AgoDfZc7/H1hQ0B2+h6AEAgsWvPxRud9xGQCWzQFkXwe1DDZhNQxWIb/RInAsd23IBbSu+z8Xve3X2Ps+ZZ//99Z1JrSVs2jJX3YLmP38u0U/gwDvHry2gli4fk2Lz3rc2kpq8bMqcV8vwTNg1/nP9v9D4GmtfLoNAM8XX5d9/19aPgu4N5AHVgZbez4EAoFAIBA0ARxEgC1JWN2yfvSSFbwsK/c7fgWAsDVprVB9ZpP97McQkBZvsbZ2bRao/glcp+W2MXvfVfbzoZYsE9pa1bTkqSgHsFgG9vpPrRXC4nv4nH397+zr8FauVTYAZD//F/D/jP+yxT196jYAZPywxXWHQ/5hS3nhmcMBm7aeEYFAIBAIBA0AeW1WEJZhzAKtFcEvi4LC58AChbfbCgDZ7/95BSuA49n3x1zKW2oFsOWK5bdga5l9/n+zrgMrgGfa+mz2ntVuA0B23R/UivzJ77m5j0pWANn//19FcvxOixXA/xWuCyuDRZ8xusQK4HP3A7/Pft7gRlYCgUAgEAgawTr0AYcR/gJWnYpYA6uC7P/7lPo99v6/ggMMkLPX4udOUAOHHazA6F8Vv6c4AITDInBoArZU2Wf9D/bP2Pf/TzmZy+UAQg4byA6fw94zD7Y5v/Od7/xT6z4rCgDZ+6ZZW6bfLPpZJSttOxj3QDAI30NQBsEb5O+Vu1YbAaCdA3gBAlxY3WSvlxfnAFqHRH5srXJCwPhv4Nm2FQDC77Gfxdj/TYagEn4Gz83eLicQCAQCgaA5WBCwk/FQmf+DgxQvnJa1ACtscFjkqbWN+CPrd35VHNTUFgo2f2Zvh7LXTcWngOG0LsgBK5DWVuRd67BGSZQKACGP0ToFnLK2SQ+w4OsP7P+vNABkv/NDCADtrdHiU8DfaCUAtE4Bjy86JQyna7e3Vquw5bNq+ZlFp4DhVDGcbu7HmCsO1CBQhtU86yT2fjhp3VYACIDt9VpxcCVuBZGP2e8ubuv5EAgEAoFAIBBChHVYB1Zr/x22LAQCgUAgEAiEAGDVUoS2et+0ThrDiiu0ivO1IDWBQCBoAShlAYVqW3tPTU3NCGZM/45xitvEbQKBQAgDzDZ1YPbsVq3oFQzFoKG4dS22XAQCgSAbfgMS1pmhvFLbSjN69p4/g4Kq8NqqfbUjPBEJBAKBQCAQCL7DqntVNgCEMgksCOxa9P42i8MSCAQCgUAgECRGWwEg+7/3aq2+pdb3iXK1zggEAoFAIBAICqCCFcD64jIKUHqiXOP5Ynz99dfNBDPx+dGDzQ2dXm9ueOf/e4G55Yubf/WLX2CLSNAEX3/1VfOTDz8o+bcGfLZ7ezPZIoJf+NVPf9qcnjez5N9apNvbzV9eOIstoi/wK74gSI4Kt4A7F32fruRz4Y/o6dMvmz/9lKg7Qc+2vpPbtwuD+O6PmhPr1jbnG5PNT1KfNqcOHGyO9OrM/y86e3rzk9zn6HITvesbU44nT75oji95T/y9devYnNq1u/lJItecj2Wak1u2NDd0fpP/X2LtB+jPTGXKom9sPsk8bW6aMFoEe/17NKePnWA/e9acfxxtjq9Y5ti99KHD6LJ61bcfsQVBAbQMAOEkXfH/Q99OWAWE11angr2VfC4YDD5onhB1J+gZkDlznhtAWP1Lnzj9wvuy9yPNkX49uKGMr1mDLjfRm76xx3dymzXZ6NmpOXvj7gv/n/nkSnNDl7f4e1IHDqE/N1Upi76xGXtvIf9bahw2oDnXkHjh/1P79ou/RzbxyFy7hS6vF337G2UQpAQL9npZXQTWstf/8RuiPVLEbndU9L7p0LmAcSa0vKrks8lgmEPQ81dffNEc6dOVG8Dk7j1l35u9eY85ZbEyk7lwCV12YnX6xh7f2TsPxd8Rm3BkLlwu+770sZPCKXfv2Jx72Ij+7FSkDPrGZvr4KbHyxyYbuQfl/44SGzaIIHFw3+Z8+im63NXqO4h4g2AQTDcYJhH0nP9gldjenTW9OZ//otX3J3fusmbSA5vz2c/Q5Se61zfm+M7nftzcNHaktZK8us33x+qXiL/NObPQn52KxNY3NvOJPN/y5SvJh460/l742xwvtokhBQZb9mr1jR0/EBSHyQbDNOZu3xdbv13eas49jrX5fjCSjSOHiNVCFgxiy090R+yAIHXkuJhADOnXnE8/a/P9uViWr9zwVedPrqA/P9WIrW9sxj9YIyYQUye1ObkFZm8/EIfgurxZkT2UjRQAEjzDZINhGqMzpogZ74b1Ff8Oz8+CLZVendkM+wn6PRArJ2ZAACvGEPjB30766ImKf89edW4aM7wiJ06UQ9/YzDWlmhu6vs0nuNm7jyv+vdhSseocX1aPfg/V6Bs7fiAoDlMNhmmE5Hu+GtOna/OTlLtALjpjqlgF3LYd/T6IlRMzIEjtP1gI5HI/rvj3eOA4qK8IHM9dRH+GKtHkABAOq8HfTGzRAle/Byt//BR6pzdazRmUkRQAEjzDVINhGmML54l6a7u2udZ35uJVp6RCPkO5gKoQKyCAlbvGEYNFEHfqrOvfh8NJYitvIvozVImmBoD5WLaw+nev8tU/m/GVK8Qq4Pur0O/Frb6x4weC4jDRYJjG3KOoyHVhRvKrL79wrW9w6HbCNJXpUIdYAQGcGndy/1ys/tnMpz5tjvTuwj+jVNkYolz6xmZyx04xYZg3u6rfh7JXPDe6x7tKpblQAEjwDBMNhmlMrF8nZrjLl1btIOwyHRAIYt8PsTJiBQRwwtzrwaHEhx+Kv9ml6uVmmaZvTPKDalauqZeDQ9GZ08Tf7K7ypbFkIwWABM8wzWCYRjCQdmmE7M27VTsIyM2y6wdCbTfs+yK2TYyAINcQF6sp3TvyshxVfw7kZvHPeYevCGI/SxVoYgAIeaJ8tXn4QE+HhgqfM0iZw0cUABI8wzSDYRrTp887yfheHYRdZiG++n30+yK2TYyAgLd2g2T8Je95/iz71DocKMF+lirQxAAwNn+uL2Wq+ER5YG8xwb1+B/2+KtU3dvxAUBymGQzTGJ07y+r6sdezg4AEa34YpHcXKgytAMMOCPjhj2EDxXbcxaueP89JO5g4Bv1ZqkDTAkDI1+OHP+AEbzTt+fMS69eLCe6qlej3Vqm+seMHguIwyWCYRtiC4yUOGPPxnC8OomncKHG688wF9Psjts6wAwLoq8onCIP6VHX4oyXhxDnUn4TPVLFQr+76xiYcSOOHP2ZO8+XzsvcarAluVyUmuBQAEjzDJINhGlMHjzht32yD4VXf9om72OJF6PdHbJ1hBwTx1autQuMbfPtMuz0c1aCUT9/YhI4fPEXgyDHfPtOudgCpM9j3V4m+seMHguIwyWCYRvs0pt0X0w8H4ST5Q8mETNvtvYh4DDMggO1fWPkTh43u+/a5dnJ+07iR6M9TdpoUAOaa0oXDRj4eEnImuPWL0e+xEn1jxw8ExWGKwTCNsOXLt3+7vOmcxvTLQTRNHFt1kV9ieAwzIMjevCdOUQ7u6+spynz28+ZIL1ETMPewCf2ZykyTAkC700ysytp/5chrpjp5zp+j32db+saOHwiKwxSDYRph1Y9v/86e8ZzB8EPfdr9WP056EoNjmAGBU7dvzWrfPxtqAfJt4B070Z+pzDQpAAS7Vry74SehYoLXuoJh6Rs7fiAoDlMMhmmMLZj7QgkNvxyEM0vu09WXZH9iMAwzILBbv2UuX/f9s2GlmVrDyaVvTObTT63Tv68352JZ3z8/sXmzmMysXI5+r23pGzt+ICgOEwyGaeTbZj07iW2zSPI5g+GXvh2Hf/Um+v0SSzOsgIC30oIJQd/ugUwIIMeroctbzQ2d31CqVZeu+samPSFomjw+kM/P3n0k/p4H9pa6KDQFgATPMMFgmMbMpWtO8eeWBsMvfSfWifZy0GYO+36JpRlWQJDcvkOsmCxbGtg17KLQ6eOn0J+rrDQlAIwtXRJoSsBzB5ruPka/39b0jR0/EBSHCQbDNCbWrhXB2YcfvmAw/NJ35soNkfQ/cgj6/RJLM6yAIDp9SuCHgqBHqyqnM3XXNyZ5x46+3a1DQY2BXSe+fJn0eacUABI8Q3eDYSKd7dlrt14wGH7pmxvi3tbpzEgC/Z6JLzKMgCCffuZ0YwhyexZOAPNtuX7dpd6W013f2HROmw8fGOh10ifPiLxTNrnBvufW9I0dPxAUh+4GwzQWDmh0eyEfy28HYffhhILT2PdNfJFhBAQZu07fpHGB3w84fZV6teqob2xCQfAw2rXxNnOd3+C5p3DoBPu+y+kbO34gKA7dDYZpTH28X2yVvbewpMHwU9+tXYuIzzACgviaNSLdYNOmwO8HSszwa23egv5sZaQJAWB02uTQapDCIRN+rbNytr2kAJDgGbobDNMYWzjPWpU7XNJg+KlvZ7Wxfw/alpOQYQQEkANaKt0gCKbPnBfbctMmoT9bGal7AAidh8JIN7CZ3LJVrDa+vwr93svpGzt+ICgOnQ2GaeSn1/pZCdKPYyUNht/6bhzSzzot9wj9/onB67uYUGKITwB6dQmlHiTflmPOH4KAfOYz9OcrG3UPADMXLot0g4ljQrleId9wEPq9l9M3dvxAUBw6GwzTaNevgqCsnMHwW99Q+oOfltu5C/3+icHru5h2txnIBQ3rnprGjxYrjhevoj9f2ah7AOiUnmpR3SAo8oNuvTqLCXU0jX7/pfSNHT8QFIfOBsM0JnfvFVsWS+vLGgy/9Z0+dlJsy82ajn7/xOD1XUynHtuefaHdU2L9+lCDAJWoewDYNHZkYN1mytFuOSdj/UkKAAmeobPBMI3RebNF/t+R42UNht/6hlZMDe/+qLmhx7vUFk4yBh0QNA7tH/r2f+bCpdBOHatGnQPAfCIv7Ez3js35bHjb/1AHULSFW4H+DErpGzt+ICgOXQ2GaXyuLl9jqqzBCELf9kGA7I276M+BGLy+gU7+X++uoR4A4n1gu7zZ3ND5Td4iDvsZy0SdA8D0mQvWAaDJoV4XbBpPqxkxGP0ZlNI3dvxAUBy6GgzTmL15v82E5aAcBDRNpzxA+RhkQJA+ekI45LmzQr8vuzwH1CDEfsYyUecAEFpO8q3/jz4K9bp8Ym33VY9m0J9DS31jxw8ExaGrwTCNdqssaGHUmsEIQt+w5cwPA8ybjf4ciMHrG4gZ9EP+H+UBhqtvbMKWPw/6P7kS+rUhv1nGPEAKAAmeoavBMI2xBVb9v8NHWzUYQeg71xCnNl0SMsiAwNn2v3kv9Puyu49Ep05Ef8YyUdcAkNf/49v+b6B05Uhu3xFK95Fq9I0dPxAUh44Gw0RGBvYW2xSPoq0ajKD0HRnURwQE9yPoz4IYrL6dgz89O6Ec/OH1AJ0DAZ+jP2dZqGsACKd++cGf8aNRrg+tB3l6zehh6M+ipb6x4weC4tDRYJjGwgpc6x05gnQQ0A6Or0AeOIT+PIjB6hvacPEVuJnT0O6tcdRQOngUkr6xmdyyRazAfbAG5fowyRAdSF6X6uARBYAEz9DRYJjG1NHKcvCCdBCpfR8LGeoXoz8PYrD6Tqxbi96TN77CykHctQf9OctCXQNAmGiE1f+3HDFzEFvTN3b8QFAcOhoM0wi5KdwZ7tjZpsEISt9OF5Kh/dGfBzFYfTuncBGdIeS68gnHgnnoz1kW6hgAPncKN5ZFkyOx1p70bEZ/JsX6xo4fCIpDN4NhIpvGDBcO+dqtNg1GUPrmfYjttkmIhpoYrL7BIUPuHeTg5ZNP0O4Ncl152sPA3ujPWRbqGABm7z4WE8thA1DlSJ88I13HIwoACZ6hm8EwjZCTArkpkKPSVoX8oB1EdPoUsVVz5gL6cyEGo+/sLave5MghqPfGJxz9e4gJR0Mc/VnLQB0DwNTBw2Kl972FqHLkmtJW4fMu0lQ6oACQ4Bm6GQzTCNtwlbbGCtpBUH02uRiEvlP79guHvHQJ+v3F5s8RE46jJ9BlkYE6BoBOvcnde9FlaRzST6pKBxQAEjxDN4NhGpNbt4mga+0HFRmMIPWdPnNebJPMmIr+XIjB6DtWv0Sc9v74APr9JbdtF6dD1+CcDpWNOgaATWNHiKDr+h10WWKLFoi//YOH0WWx9Y0dPxAUh24GwzTCyV++CnLsZEUGI0h9Q6skvk3SS55tEpMZhL6hJyp3yLcfoN9f5uJVsfo9eTy6LDJQtwCQF4Du/AYvAp3PtJ7eEgZhFbKtbkth6xs7fiAoDp0MhomspAB0scEIWt+ybZOYTL/17RRg7vEuSgHoF+RJ2gWh35FCHmzqFgBmrt4SAf64UeiyAKHmJJdnzHB0WWx9Y8cPBMWhk8EwjYXE5K4VrbiF4SBiC9tuSUcMh37rO3PhknCAU+RpwdY4fJCYcNx5hC4LNnULAKHPtEwt2OCQndOSLvMMXR4KAAmeoZPBMI1w2tZNzl0YDkI2o20y/dY31EDj+abr16Hfm83Y4kVS5WXppG9sOjl3Ek0mm8aOlCYnkQJAgmfoZDBMY2LjR65O3YbhIDJXb0q1bWMy/dZ3dPYM9I4MLZncvUdMOFauQJcFm7oFgFBUXrZ0Esj/46eS9+xDl4UCQIJn6GQwTCMUJeUO+fS5ig1G0Pp+LnG7jbqExGDpt74j/bqLfNPGFPq92YTi5zThCEbfmMzHstaBss5SHSiD0++ylEGiAJDgGboYDBPp1iGH5SAaRw8TM/db99Gfkcn0U9+5SEI45P490e+rmIUJx1vGTzh0CgDTZz8R6S3Tp6DLUszsTasQOrNx2LJQAEjwDF0MhmmE7gfcIQ/o5cpghKHvWP1ikbtz4BD6czKZfuo7ffq8dK2wbNqtEOGUJrYsuugbm4lNm0R6y4YN6LIUM5/9nE82Gjq90ZxP4x4EoQCQ4Bm6GAzTmD5xWjjkObNcGYww9O3kZdFBEFT6qe/ER+7yTcNkfNlSMeHY+zG6LLroG5tg13h6y4kz6LK0JKQbVNJ7PQx9Y8cPBMWhi8EwjYl164RD3rzFlcEIQ9+ZyzdEXtbEMejPyWT6qW/HIZ+UzyE7eVn1+HlZuugbm5FBfSqubxo2ZWlPRwEgwTN0MRimMTptkpiFnr/kymCEoe986lNRoLdbRyrQi0g/9e0UHH8cQ7+vloRcU56XNWoouiy66BuT+XhOygMgNlP7D1oTjsXo+saOHwiKQweDYRrBKELxZ+6QY1lXBiMsfTcOHyjysu4+Rn9eptIvfefsE5kVFhwPmyIvyy7Qa+5BEF0CwMwnV6QrOF5MaIPIJxwjh6DrGzt+ICgOHQyGaXROZLo4AGIbjLD07RRxPXIM/XmZSr/0DavMPN902mT0eypH5yDIzXvosqiub2wmt+8QOcRrVqPLUop8wtH17eaGTq8359NPUfWNHT8QFIcOBsM0ps9UdyIzTAdRMOJr0J+XqfRL38mt20S+6bq16PdUjnTyXJ8AUMYOIC3ZNH60SMG5ehNV39jxA0Fx6GAwTKPTkstliYQwHYTs2zgm0C99xxbMFQdAjp5Av6dyTO7aLSYc769Cl0V1fWOzccRg6fs72x1BME+eUwBI8AwdDIZpjM2fIxzy8VOuDUZY+nYSuXt2kjJvzAT6pW8ZW3K1ZObSNTHhmDweXRbV9Y1J2FKFrVXYYpX5ABkEfnzCwQJBTH1jxw8ExaG6wTCRtkPOPWh0bTDC1HfjkH5CzodN6M/MRPqh73ziCddhQ493pQ7k84m88RMOHQJAVVr7OT3PJ+CVuqIAkOAZqhsM0+iUWAGH7HKGHLaDqHalkugP/dC3SitrjYP7Sls7ThV9Y1OGlbVK6Njh7u+grVRSAEjwDNUNhmnMXLGLLI+tymCEqe9qcxWJ/tAPfauUWxedK2+xalX0jU2nq8u+/eiytMVqd2L81Dd2/EBQHKobDNOY3LNXOOSVK6oyGGHqO336nDitPHsG+nMzkX7oO7Z0iXDI+w+i309bdNrVbdyILouq+sZm07iRIt/0+h10WdpibN5s1B0OCgAJnqG6wTCN8WX1wiF/fKAqgxGmvqFrBC+YOrgv+nMzkX7ou9D39Db6/bTF9KmzVn/smeiyqKpvTMJWaqG+3jN0edpiYtMm1P7YFAASPENlg2EivcyQw3YQkIzf0LMTlzeffIL+7EyjV31zh9y9I891gpwn7Ptpi/aEA/rIYsuior6xmb3XICaMwweiy1IJnQkH0g4HBYAEz1DZYJhGrzNkDAcBuYp8BenKDfTnZxq96htym7hDHtof/V4qIW+R2KuLmHDEc+jyqKZvbMJWKu+xO38uuiyVEHvCQQEgwTNUNhimMXv3kXDIIwZXbTDC1nd8xXL0gqmm0qu+0yfOiBWOubPQ76VSQuFxPuH45Aq6LKrpG5uQu8m3VDdtQpelEvIJh73Dkcij6Bs7fiAoDpUNhmmETgx8hrxwXtUGI2x9O2UdVi5Hf36m0au+VTxUAaeVQebkrj3osqimb2xG7UMVJ9Q5xQ3lkfiE49I1FH1jxw8ExaGywTCNUE6FO+TNW6o2GGHr2ylbM2kc+vMzjV71jX3KsRrC4Sg+4Vi2FF0W1fSNzcahA1DLqlTD+KqVaBMOCgAJnqGywTCN0TlWnbNTZ6s2GGHr2+kkYXCHBix61XfjsAHSt4BrycxVq5PERLwODarqG5O8BRwUVu7WUeoWcC0J5ZH4rszSJSj6xo4fCIpDVYNhIp3Co1W2VsNyEI2DrA4Nj2Poz9AketE3HDLiDlnynqwvyJ00d8KhcgAIVQ1EC7iR6LJUJ3f4resoACR4hqoGwzQ6M+Tu1c+QsRwElEngK5enz6M/R5PoRd+OYxurlkMGwqlMPuFoiKPLooq+sZk6cEispNWHv5Lmhc+15gx5wkEBIMEzVDUYpjF7467nGTKWg/Cau0gMX9+qOmRgdNZ0MeE4ewFdFlX0jc34mtUil27HTnRZ3NLpQR3yDgcFgATPUNVgmMbUwcOWQ17syWBg6Dt97KSQfUF1p5eJ4es7vtpyyDt3od+HWybWrRWyb9uOLosq+sZmdNpkcZr2wiV0WVzLbk84zoS7w0EBIMEzVDUYpjH+wRrPM2QsB5G999iq8D8I/TmaRC/6jk6dZDnky+j34Zapw0fFhGPxInRZVNE3NiP9eohVtKY0uixumVi3TtjmrdtC1zd2/EBQHKoaDNMYnTFVOORzFz0ZDAx98w4mXd5qbuj8RnM++xn6szSFXvQd6dtdOOSoeg45e/O+SJcYMxxdFlX0jclcLCs6avTphi5LNcSacFAASPAMFQ2GiYwM6CUcciTpyWBg6btx1FBRUuTOI/RnaQqr1TeswnCH3K87+j1Uw3zmGW+XqNoJZix9YxO6tvCOM1MnostSDbM376FMOCgAJHiGigbDNEKbIe6Qe3XxdNIM00FA9xKeJ3PsJPrzNIXV6hvysLhDnjYJ/R6qZeOwgcrVMMTSNzahiDIv3v3+KnRZqiEvmYQw4aAAkOAZKhoM05i57E83DUwHAf09VWsrpjqr1Xdy127hkFe/j34P1TKmYFsxLH1jM76sXvQL//gAuizV0uli8jC8LiYUABI84/PD+5UzGKYxtc/qp7vCW0v3sacAACAASURBVD9dTAeRPnFa5MnMn4v+PE1htfqOL19mOeT96PdQLWGiwSccbOKBLYvs+sZm0/jRIr/52i10Waql1y5N1eobO34gKA4oYvkk8xR9ABHL0+k3uWevZ4OB5SCck8AjBqM/T1NYrb5hpZk75Ms30O+hWkL/YlF6yJwJh4oBIKS0QBFl8ENQVBlbnmqJUeuUAkCCZ/A8mZt30QcQsTybpkwQDvnSNc8GA8tB5LOfNzd0edM6Cfw5+jM1gdXqO9KnK/97y8dz6PdQLU2ccKgYAEK3Fp7fPKgPuixemDp6XEw4Fi0IVd/Y8QNBcfBl6yNH0QcQsTwdhxzLejYYmA6iceQQkZh/l04Ch8Fq9A1lX1Q+AWxTlB5iE45ObMKRMaP0EPb4roZQ1oofOJoxFV0WL8zefiAmHKOHhapv7PiBoDj4svWG9egDiFiauaaU5ZB7+GIwMB0EbMfxCcfxU+jP1QRWo+/MxaviwNEUNUtyFBOcMZ9wMOeMLYus+sYmdJrh+c1rVqPL4oUwyYDdDah3GtZJYAoADUFNTc2I2trav2Ocwl5/r9z76urq/ph9+dYrr7zy7Q4dOtRU8tl82XruLPQBRCxN6MQgamR5L8mB7SASH31knQT+CP25msBq9J3aax04WuntwJEMhO04PuE4egJdFln1jc34sqXKnwC2CZ2O+ITjXkNo+vYtyCDICRbw/RkL7FbBa/b1uywI3FHuvez/brD3PGXc9eqrr75cyefzZethA9EHD7E0k7v3Coe8aqUvBgPTQZiYmI/JavTtHDhif3fY8nulaaWHsMd3NdThwJHN2Pw5Vumh06Hp2684gyApWDA3mgWBXe3vWZCXbOW9Hd1+fqTrWyJPhlp0Scn4yhXWCeB9vhgMTAeRvWteYj4mq9E3FH/mDvmTK+jye6VpEw7s8V0NI73VP3Bk0yk99FE4OxwUABoAFvC9x/h60fcJ2OIt9V4WAM7s0KHD37Cvo9q1a/eHlXx+fOxwUcDy3iP+B0WUi9AeiW8rXLzi+bOePhUOAr5i3MuT3OciT6bzm/w19rPVndXoO9K/p3DITSl0+b0yd/eRmHCMGoIui6z6xmQ+VjhwhC2LH0yfKEw4wtK3X3EGQVKwYK6+pqbm74u+z7z66qu/VebtL8E/L7/88m+zQPGTSj4/u3QR/6P9yZVLzQT5EB0kegD/8osfY4viC+JjRE/gX2TT2KIQWuBXP/0HETD16dr89ddfY4vjGV//8pd8wgG7HF//6lfY4hBa4KcP74v8v1lTsEXxBb9IiwN78XEjQrumDyEGQWZYW8Cdi75Pl3pfhw4d/pb93zzr22+yAPAfKvn8Z7u3iy3GTZvQZ1DE5/kk+cTqAdy5+cmTL3yZMQIwVwick8Bstoz9fHWnW31nr90SJ4AnjkGX3S82Diu06MKWRTZ9Y9PpcLRyObosfvBJ9jOnJ/CT/I9D0bcPIQZBZrCg7k9hFRBet2/fnsV1tXvhNQsKOxS/jwWAf8n+/0/g9WuvvfYH7H1HKvn8n1z+RCxbL5yHnkNBfJ4Z2yGPH+1bzgiAGyukezKxRRcW3eo7tf+gcMhL69Fl94vROTPFhOP0OXRZZNM3NnU6cGTT6Qn8KBqKvv2ONwgSggV701kQ+CMrxw/Ku7zEArwI+/nvtHhfV1gtZP83udJTwL9IJUMvYEmsjKmDh0VwXr/YN4OB7SDSx05aeTI04QiabvUd/2CNcMg7dqLL7hcT69aJe9q6DV0W2fSNTZ0OHDn3NHuGmHCcuRCKvgMJOAjmgOfJWMvWYRWwJFbGxLq1wnlt2+6bwcB2ENk7VmL+yCHoz1d3utV3dOY04bzOfoIuu19MHTwiJhxL3kOXRTZ9YzMyQOQ35xpT6LL4xcTaD0KbRFEASPAMMBjFeTLYA4hYoN/bVzI4iDzPkwm3Yr6pdKvvxkF9hR14HEOX3S9mr9/xNY1CZsowvitlPlHIb87nv0CXxy86aRTLgk+joACQ4BlgMGIG5cmoRCcwf+BPYC6Lg2gc2t+acDShP2Od6Ubf+fTT5oZ3f9Tc0P0drRxyPvWpCDR6dtLqvrzqG5tOfvOEMeiy+HpfV26I+5o0LhR9Y8cPBMUBBiOx3pw8GVUYxEqZLA4iOmt6aHkyJtONvrM37grHNXYkutx+U8etRq/6xmbqwCGxNb90CbosfhIKWvMJR59uoegbO34gKA4wGOnD5uTJqMLsXf9z5WRxEPE1+h02kJFu9J06fFTYgPcWosvtN6PTJmt32MCrvrHp5Mpt34Eui9+M9O0uiqnHsoHrGzt+ICgOMBjZm9bsf9wo9MFDFHTaWM33r42VLA4CGr+LPJml6M9ZZ7rRd2L9euGQt2xFl9tvxt9fpV25Ea/6xqazC3BWv12ApsnjQ+lvTAEgwTPAYDxJfyryf3q8q32ejCp0Gtl/+KGvBkMGB5G5fF1MOJihxH7OOtONvqNzZgmHfOosutx+M7XXLji8Al0WWfSNzcYh/UKrlxc2YWLLO5zsPxi4vrHjB4LisA1GZGBvI/JkVGFs0QJhRI4c99VgyOAgctGM0wMU+znrTDf6bhw2UPScvh9Bl9tvZi5e5fcGfbWxZZFF35jMZ56JBQdNS49BagufcHywJnB9Y8cPBMVhGwynKCczltgDiPhlc9OY4cIh37zvq8GQxUFEencReTKJPLosurJSfYMThp65DZ3f1NIh55rSYsLRvwe6LDLoG5tOLdBRQ9FlCYJQR5NPOGZND1zf2PEDQXHYBgO2R/iK076P0QeQ6YRt+IbuHfksOZ9+5qvBkMVBQPkHPuG4dgtdFl1Zqb5h1Y875OED0WUOipFe+k84ZBrfrTF94rTv+c0yEba1+Xga0i9wfWPHDwTFYRuM5K49Ytl69Wr0AWQ6oRAvNyCD+vpuMGRxENDejk84Dh5Gl0VXVqrv9OnzYsVi9gx0mYNi00RrwnFV3wmHTOO7NSa3bBH5zRs2oMsSBPmKete3eYct2O4OUt/Y8QNBcdgGI33uonACM6ehDyDTWdDFVN8NhiwOAmpOciewfh26LLqyUn1DKQ6ui7UfoMscFGP1S6wJxxF0WbD1jU0oN8Z1cUhfXTSOHiZSeO48DFTf2PEDQXHYBiOsZWti20zu3CVWY9f4uxork4OA06Y8yJ07C10WXVmpvsM6tYhJZ8Kh6aqTG31js5D+cRtdlqAYWzBPnKo/fipQfWPHDwTFYRuM55etP0MfQCYzvnyZcMgfH/DdYMjiILL3HosJx4jB6LLoykr1Xahbdh1d5qCYPnnGyjubgy4Ltr6xacIBsMTGj8SEY9OmQPWNHT8QFEexwYCuE3zZ+u4j9AFkMpumTBAO+ZK/DlkmB8Fb3cHJ0y56njyVgZXqO9KvhygBFU2jyxwUnc46mp48daNvTOZiWSNKQKWPnhATjkULAtU3dvxAUBzFBgNmx3zZ+sQZ9AFkMp3epU3+OmTZHIRdey73oBFdFh1Zib7zySfCIffqjC5vkIRdDdjd0LX2XKX6xiZ0x+BF4CeNQ5clSGZv3Rf3OWZ4oPrGjh8IiqPYYEB+jK7toFRhPv2U6yCIriyyOQg4dconHKfPo8uiIyvRd/b6HeGoxo9GlzdoOt0nHsfQZcHSNzYhz5TnNy+tR5clSEL5Ll7sunvHwLprUQBI8IxigwGnsviy9ZL30AeQqczefhDYzFE2B5FYu1ZMOLZtR5dFR1ai79Tho2LML16ELm/QhFP1PLXi/CV0WbD0jc3EOnPGPJTxCnLCQQEgwTOKDQacyuLBx4Qx6IPHVMKpMe6QF/hfJFU2B2HKagAWK9E39JrmyeqbN6PLGzTj768SwcfuveiyYOkbm07P6dPn0GUJ/F5nTBETjguXA9M3dvxAUBzFBgNOZfF8oN5d0AePqYTt96DKVcjmIDJXzMgHwmIl+g6jXIUsTO7ZKyYcq1aiy4Klb2w2Dh8kDhrea0CXJWjC3xmfcOzZF5i+seMHguJoaTDgdBZfto5l0QeQiYwttQvW+t8hQzYHkbdPBPbphi6LjqxE307B2tsP0OUNmrASw2tPzpiCLguWvjHJS411eZOf/s9nP0eXJ2gmd9vdtd4PTN/Y8QNBcbQ0GIWaYDfQB5CJdJ7/Ff+fv4wOItKnq6gJFs+hy6Ib29L3cz2nA2xZJQtzDfFAWizKQhnH93PP/2GjeP7DBqDLEgYzAXfXogCQ4BktDUZ8Wb32XQFkZqR/cDXZZHQQTRPHWj1ab6LLohvb0rcdEEUG9UGXNQzygLebvgGvjOO7mOkzF7TvOV1Mp7vW0P6B6Rs7fiAojpYGo9AXdC36ADKN+dSnogRMz06BlA6Q0UE4W94HDqHLohvb0rezJTpdzy3RUiz0aNWv2L2M47uYyR07rRaXa9BlCYNiy/ut5oZOb/DC90HoGzt+ICiOlgYDarJxpzBnJvoAMo3Zm1bx0LEjAvl8GR2E06N1/Tp0WXRjW/rW/VBEKcbmz7WK3Z9GlyVsfWOz0OJyP7osYRFaXQZ16IUCQIJntDQY2fsRsWw9fCD64DGN6WMnRQmYhfMC+XwZHQR0ndG9RysW29K37mVRSlHnYvcyju9iFlpcXkOXJSwWyt74X+yeAkCCZ7Q0GHzZGnq0dqYerWEzuWWLWA378MNAPl9GB5G981D7Hq1YbEvfhTplehZGLkWdi93LOL6LGenfM5AWlzLTKXa/Y2cg+saOHwiKo5TBsHu0wmog9gAyibH6xWKLhDmpID5fRgcByfi8ZVK34Fommcq29N04ONhOBTLSKXY/Ub9i9zKOb5t2fnMkoPxmWekUu1++LBB9Y8cPBMVRymBQj1YcQkHkIE/EyuogIgN7i0AkkkCXRSe2pm9TA28oNySK3XdFlyVMfWMze+OuCLzHjUSXJUxmLl0X9z1lYiD6xo4fCIqjlMFIrP1ALFtv34E+gExi0EW4ZXUQ0amTROD7yRV0WXRia/p2tt5HD0OXM2xC4XFee1KzYveyjm9g6sgxsfX+3kJ0WcIkbHfzCceAXoHoGzt+ICiOUgYj9fGBwJatiaWZTz4RhqJX58CuIauDiK9YLra+95lzOjAMtqZvOAUbVM9p2Rn0SruM+sZmYuNGkd+8aRO6LGGS157s2UlMOFKf+q5v7PiBoDhKGYzMxauiFMxU/5etiaUZxhaJrA7CqQ/2gRn1wcJia/p2DhwF0HNadsbqg2u3KKu+sQmVDXha0bGT6LKEzaaxI0VO/c37vusbO34gKI5SBgNysfhq1MDe6IPHFDolYBYtCOwasjqI9JnzRnUICIut6RtOwfIg6PBRdDnDpq61J2Ud38CmMcNFEHTL3yBIBYJNDyL4pQCQ4BmlDMZzPULT+rVMkpGJzZuFU9q4MbBryOogCrUnB6HLohNb03fThDFiG/TabXQ5w2b6pFV7ct5sdFnC0jcmhT95R2yDpp+iyxM2ne1vZuP91jd2/EBQHOUMBtRlEy2THqIPIBMYxoqMtA4i+zlvl9TQhWpPhqXvSJ+uwiEn8uhyhs3s3UdiwjFyCLosYekbk7mmVGAHIVSgcwBm8SLf9Y0dPxAUR9ktIjY7Fi2TzqAPIBMIdcnEisytwK4hq4MAQsN0fgL6URRdFl1YTt8Q9HGH3Ee/UiiVMJ/5jE04Xm9u6Pq2VhMOWcd3oRTKBHRZMJi9fkfc//jRvusbO34gKI5yBiOxbp0oBbN1G/oAMoFOaYp4LrBryOoggNGZU0UAfO4iuiy6sJy+g3JIKrFxSD/timDLOr6dYsjL6tFlwWA+YVV46N3Fd31jxw8ExVHOYDiDdqmZgzZcA5EPxECUMhgyOghgoS/tHnRZdGE5faeOHDeyJlsxozP0m3DIOr7hsI3piwlB1HilAJDgGeUMhrNsP3k8+uDRnU4JmIBXZGR1EMDk7r1iwsECQWxZdGE5fUMtNp6U/tFH6DJiMb5qpQhK9uxFlyVofWMzNn+O8elEQdSepACQ4BnlDIaTuNu/J/rg0Z2po+GsyMjqIICwEsNLwcyYii6LLiynb/g74weOjhxHlxGLyV17xIRj9Wp0WYLWNzah24zpBwpjS+3ak/71eacAkOAZZXuFwtH9Hu8GUsGc+DydFZmNwa7IyOoggHD4g5/MHNIPXRZdWE7fdgkYyAXElhGL6bMXxIRj1nR0WYLWNyadEjCGlxRzak/6WHidAkCCZ7RmMEwu3hkmCysyxwK9jowOwiacxmzo8hYvB5PPfoYujw4sp2+nBEyAB45kZ+5Bo5hwDBuILkvQ+kZ9zo1ml4CxCdvffJdnvn+tFykAJHhGawYD+oTy3I3jp9AHkM6E3L8wVmRkdBDFbBwxWDyHew3osujAUvouHDgyswSM8xzs2pOd9ak9KeP4LpSAMbutaPaOVXty9DBf9Y0dPxAUR2sGA5areaL0li3oA0hngjMOoyivjA6imNE5M8WE4/R5dFl0YCl9UwmYAnWrPSnj+Da9BIzNfOYZ3wZv6NaRb4v7pW/s+IGgOFozGNAsnS9b1y9GH0C6ErbhwirKK6ODKGb8gzViwrFjJ7osOrCUvsM6cKQCndqT5y+hyxKUvrHp1JPdth1dFmw2DuorJhwNCd/0jR0/EBRHawYjc+WGWC2YNA598OhKZ0VmwpjAryWjgyhm6uP9YrVg+TJ0WXRgKX1TCZgCdSsFI+P4dkrAnDS3BIzN6LTJYsJx8apv+saOHwiKozWDkYtmxOpUv+7og0dXOn0iQ1iRkdFBFBMMIz+ZOXUSuiw6sJS+oR9pGAeOVGChFMz76LIEpW9sUgmYAuMrlouxxya6fukbO34wCnV1dVnGTFvEltMN2jIYkZ6dRH5a8gn6ANKRUPqFr8hs2hT4tWR0EMXMRZJiwjGwN7osOrCUvqkETIG6lYKRbXyLEjAdjS8BYxNSW7itX7vWN31jxw9Goaam5j9UQmw53aAtg9E0dqRwGDfuog8gHRlbtEDMCo8GX5RXNgfRkuQwgtd3GD2nVaFupWBkG99OCRia0HGmT58TE455s33TN3b8QFAcbRmM2ML5Iofj6An0AaQjm8aNCi3Als1BlKKzZXT7AbosqrOlvqkEzPPkpWA661MKRrbxnbl0jUrAFDF797GYcIwc4pu+seMHk/EbtbW1UxgbGb+AH9TU1Pznurq6vtiCuUFbBiPx4YehbVGayEjvLlYJmOC32GVzEKUIhVJF39DT6LKozpb6DqvntErUqRSMbOO7UAJmKbosMjCf+czXUjAUACKCBXuLWbB3kPHPWQD4Y/hZhw4dvs9e38WWzQ3aMhipw0fFIYXFi9AHkG4slIDpFsr1ZHMQpZhYv16czNy6DV0W1dlS31QC5kU6pWDOXUSXxW99Y5NKwLzIyKA+YsIRSfqib+z4wVjAYQ8WBP6O9foz++d2MKgK2jIYmWu3QitTYhqdZzsxnGcrm4MoxULtySXosqjOlvoOq+e0StSpFIxs4zs2b7ZYzT91Fl0WWQgVDvwqBUMBICJYoJf8zne+80/htR0AtmvX7nfZ6xiqYC7RlsEIs1CxaXRWV5e8F8r1ZHMQpUi1J4PTN5WAeZE6lYKRbXw3jhpqlYB5hC6LLIQap3wM7j/oi76x4wdjwQLA5YyrIQi0AsBvse+XMi7Cls0NKjEYhTy1YFuVmUYnv3Lz5lCuJ5uDKMVC7cke6LKozpb6hpVmvvpw7Ta6bLIwffYTbUrByDS+nzvRn6ET/TaT23cIm79unS/6xo4fjMXLL7/82yzY28GCv39kX3/F+HP4/pVXXvk2tmxuUInBgKRxqh3mP50T1sdOhnI9mRxEa3RqT6Y+RZdFZbbUN5WAeZE6lYKRaXxTTc/ShO1wvuvjQykYCgAlQE1NzSvt27f/k9dee+072LJUg0oMBiSNi62j4GvVmcSmcVaNxZv3QrmeTA6i1ecyNtznoiuL9Q2nzEUJmC7ocslEnUrByDS+C119qARMMWE7nE84Rg/zRd/Y8YPRYIHfP6utrX2DcRh8hRxAbJncohKDAX1DqX+o/4z06hxqlxWZHERrjC2cF+rKqK4s1jeVgClPXUrByDS+nRIw1Nf7OcJ2OC8F0/0dz6VgKABEBAv4/oLxc8brdXV1u9jXa/C9bp1A+GA+QuUj/GYulg29z7JMDqI1FnIjt6DLojKL9Q2F3PkYXrQAXS7ZqEspGJnGd2LdWnG6evsOdFlkI2yL8wlHY8qzvrHjB2PBgr07LPDrWPwzFvy9rVsdQCDk/tHqgb/MXL0Z+mlXmRxEa0wdOhLq6WhdWaxvKgFTnvH3V2lRCkam8R2lEjBlCZ1R+ITj0nXP+saOH4wFC/6+ZF++2eLH37J+rgwqMRiUP+Q/UwetIKd+cWjXlMlBtMbMVbs+4lh0WVRmsb4hmOZ5vIePosslG3UpBSPT+HZKwNylEjAtCZ1R+Fg8cMizvrHjB2PBAr0NkPfX4mc/YlyPJVM1qNRg0AlCf5nYsEGsOmwJb5tTJgfRGjG2x3Vksb6pBEx56lIKRpbxzUvAdKMSMOUInVH4avx6b6VgKAAMGSzg28T4kUVeAobxivX6ilUSZju2nG5QqcEoOJBb6ANIBzoHHY6fCu2asjiIShj2ARkdWazvSN/uNIErQ11KwcgyvnORBJWAaYXpE2fE7s/8uZ71jR0/GIWampoJlRBbTjeo1GDQFpK/bBo7wip1cj+0a8riICp6PnaJnBt30WVRlba+nyQphaM16lIKRpbxXSgBMwn9mcjI7J2HvpSCoQCQ4BmVGgzoVsGXrT/8EH0AqU6+RYJQ7FgWB1EJ4bQqXyE9egJdFlVp6zt70yoBM24UukyysnHoAOVLwcgyvlMfH6ASMK0wn7ZKwfR411MpGAoAkdGuXbvfrKmp+be1tbV/xb7+tU1sudygUoMBNdmojIQ/zEXTYkWmf7jtzmRxEJXQKQWzaRO6LKrS1nf6GJWAaYs6lIKRZXwn1lIJmLYYGdBLTDia0p70jR0/GAurDmAe+gCzr1/BV8ZfMjZhy+YGlRoMp5DsuJHog0d1Zi7fEM9y8vhQryuLg6iEkGpApWD80XfSXr3fuBFdJlnplILZvRddFq/6xh7fVAKmbTZNmSAmHJerLwVDASAiWKB3lQV+/eE1FIC2vo5hHIormTtUajDydh5RL8oj8ko4/s+Dm6VLQr2uLA6iEsJhI1EKZgy6LKrS1nec8nfbpA6lYGQZ340jh1glYB6jPxNZGV9a77kUDAWAiCiuA2gHgAy/wX6expPKPdwYDOckYSyLPoBUplMCZuu2UK8ri4OohHBalU84+nRDl0VV2vqGeop0gr916lAKRobx/XwJmM/Qn4msBNvPV+WZL/Cib+z4wViwoC/+gx/84J9br+/X1NT86x/+8Ie/z15/gS2bG7gxGI4juUqOxAtjC+aGXgLGNhjYDsIN4dQqn3Ak8uiyqEhb3zRxa5u5h+qXgpFhfDslYAb1QX8eMjN94rTYBVpQfSkYCgARUVdXN48Fe69br4cwPmXMMq7Cls0N3BgMKgXjD5vGDBdbJLcfhHpdGRyEq+c0bhSVgvGo71/97GeUulEBdSgFI8P4dkrATKMSMK0RbD9PcWG+wIu+seMHggUW+P15hw4d/uYbL7aHkxpuDAaVgvFOvkXS412xIpN+Guq1ZXAQbmiXgkkdPY4ui4oEPf88FqUSMBXSKQXzsAldlmr1jT2+qQRMZYTyX/CcvJSCoQCQ4BluDAaVgvHOXFNKrMgM6BX6tWVwEG6Y2PgRlYLxqO+fXP6ExmyFjM6cpnQpGBnGt1MCZsdO9OchOyP9e4oJR7S6UjAUAIaM2traTxgvtEVsOd3AjcGgUjDembl0XTzDKRNCv7YMDsINU0eOieDlvYXosqhI0POzfbuoBEyFVL0UjAzjOzp3lshvPn0O/XnITigDxiccV25UrW/s+MEo1NXVvVMJseV0AzcGg0rBeKddAia+rD70a8vgINwwc+22CJYnUCmYavWde38Z5e1WyORutUvByDC+qQRM5YzVLxFj8+CRqvWNHT8QFIdbg0EnCr0xsX4dSgkY22BgOwg3LJSC6Youi4oEPSenTaASMBVS9VIw2OObSsC4Y3LLVk+lYCgAJHiGW4NBpWC8MTZ/jtgiOXEm9GtjO4hqGOndlUrBeNB304CeNGGrkIVSMAPQZalW35jjO9cgSsA0DuqL/ixUIJQB4ykuC+dVrW/s+IGgONwaDCoF442No4eJLZI7D0O/NraDqIZN40eL53X9DrosyjFFKRtuqHopGOzxXSgBMxn9WajA7M37IsVl7Iiq9Y0dPxAUh1uDQaVgqiffIulubZGkn4V+fWwHUQ3hAAifcByhUjBumbt1jw5tuaTKpWCwx3fq4/0ih3LFcvRnoQLtUjCRnp2q1jd2/GAsampqXsGWwQ+4NRhUCqZ65iJJMeAH9ka5PraDqIaJj6xSMOwrtiyqkcaqe0ZnTlW2FAz2+KYSMO4Z6ddDTDiqSNGgABARtbW1P2fcy/hf2be/HuS1WLA5gl3n7xinsNff8/q+Yrg1GFQKpnpmLl2zSsBMRLk+toOohrDyR6VgqmNyyxbhkDfSan2lVLkUDPb4js6bTSVgXLJp0jgrp/5mVfr2L8oguEK7du1+jwVaQ+vq6m5ZbeDq27dv/yd+X4cFcn9mt5djX7/LrrnDy/tawq3BoFIw1TO1/6BVAmYpyvWxHUQ1hNw/HjSPH40ui2qM14t83TTl61bM5C51S8Fgj28qAeOesfrFIsXlkPtSMBQASgIWfP1bFnTNZ8ywwOs+rMT5tUXMPnM0+6yu9vfs85Ne3tcS1RgMKgVTHRPrrC2SbdtRro/tIKohnP7lE47eVArGLe0T+1kqAVMxVS4Fgzm+qQRMdUxs3lJ1Tj0FgJLgtdde+19YADaPMct4FVbfGL9gAVlvr5/NPuc9xteLvk+88sor3672fS0BBuPpU/HHVCmLHYubr5bMwwAAIABJREFU3zOdMWuLJHPqLMr1Qc/V6BubUAcQntuTRA5dFpUY6dfdem5ZdFlUYaEUzEB0WdwSc3znG+0SMH3Qn4NKLOTpzq9K317jC0KVYEHfd1iANxi2gFmwlYMAsH379n9k/z/72b9k/LHX68DWMrvO3xd9n3n11Vd/q9r3tURzFbC7C3x54Ww1v24s4mOH8+f2i3QKWxSlkJwqWib9rCmCLYoy+NXPfiYccu8u2KIoha+/+kqUgunyZvPXv/oVtjjK4KcPRUmT1Oyp2KIohZ/HY2IFcNKYqn7fa3xBqBIsuPsZC7J2d+jQ4W/Zt79W6j3s/9/3eh1ra7dz0fdpL+9rCfgjcjtjTFqlYCC5HHsGpQqfPClskTzJPkORQdUVwPjiRSKX7chRdFlUoV0CBhyLavrGpl0KJv8oii6LG2KObye/ecUy9OegEotrdVajb6/xBaFKwApgGNdhgdyfwuoevG7fvn0tnDyG1yzY61DJ+9oCGAz+h+gi9yB99ASVl3DJXCSBWgLGzhmpRt/YTGzaJIKZjVQKplLaW0vZ5YuV0zc2VS0Fgzm+nfzm7TvQn4NqrDanHvTsd7xBkBAs2JvOgrsfMc7s0KFDDfvRSyzAi7Cf/04b72sT1RgMKgXjnk6V/KmT0GRQNQBMHT1OEw6XtJPLn+3appy+semUgtmzF10WN8Qc33Z+c/rUWfTnoBqd9qouD2tRAEjwjGoMBpWCcU+nSv7yZWgyqBoAFiYco9BlUYV2y8Yvz59VTt/YVLUUDOb4dlpc3n2E/hxUY7XtVSkAJHhGtQaDSsG4Y2LtB+hV8lUNAPMJmnC4pV1g9meNDcrpG5uqloLBGt/PtbjMhN/iUnU67VU3bnStb+z4gaA4qjUYzrL1VaoxVgmjc2ahV8lXNQAE0oTD5fOySsB89ZOfKKlvTOYeFErBYMvihljjO9eYQs9vVpnV5tRTAIiMmpqaLnV1dccZb8P3tbW1f1FcikUFVGswql22NpWNIwaLLZJ7eFXyVQ4AmyaOqSpPxkQ6TeZ7dVZW36jPL/u5KAXT+c3mfO7H6PJUSqzxnbl03cpvxmlxqTqrTXGhABARLNCbwAK+a+zrW3a9Pzh4AT/Dls0NqjUYzrJ1FRXMTSM4kYaub6NXyVc5AKQJR+XM3hQlYJrGjlRW39hsHNqfP8Pcoyi6LJUSa3xjt7hUndWmuFAAiAgW6MWhH7D1+nPrxy8VvVYC1RoMKgVTOXMNcatKfl9UOVQOAGnCUTmLuwuoqm9sOqVgzl9Cl6VSYo3vxPp1qC0udWA1KS4UACICun+wL78Or+vq6j6Dr9B5o9ICzLKgWoNBpWAqZ+aTK2KLZNpkVDlUDgCdoGbhfHRZZGdxf1FV9Y3N+KqVypWCwRrfsflzRX7zyTPoz0BVVpPiQgEgIligt5kFgZOt1zwAZN+PrampWYcrmTtUazCoFEzlTO37WGyRrFyOKofKASBNOCqnvV2ePnxEWX1js1AKZjW6LJUSa3w7JWDuPER/BqqymhQXCgARAZ1AWMB3CVb8GH/J2ATfd+jQ4V9gy+YGXgwGncysjPE1a8Rqws5dqHKoHAAWJhyd0WWRnXYJmOy1W8rqG5vpsxeUKwWDMb55CZge74r85jSVgKmW1ZSCoQAQHy9BC7aampr/xoK/f8e+/ya2QG7hxWBQKZjKGJ09Q6zInDmPKofKASDQLm2SowlHRc8pH88qrW9MOqVghqtTCgZjfOearBIwA3qh37/KrCanngJAgmd4MRh0MrMyNg4fZJWAaUCVQ/UA0F7Zyly9iS6LrCwuAaO6vlGfI5SC6fRGc0MXdUrBYOg7c1mUgGmaMgH9/lVmNSkuFAAioqam5l/V1tYeZnzC+FOLP4Ov2LK5gReDQScz2yYvAdPlLeZMXmdOBa8EjG0wVA4IYvWLxYTj0BF0WWRlcQkY1fWNTdVKwWDoO3XgkMiVXFqPfv8qs5qcegoAEVFXV3eLBXuLWCD4Z+z1HxcTWzY38GIwqBRM28w9jomtpCH90GVRPSAoPt2KLYusLD4trbq+sRmdoVYpGAx9J9avF/nNW7eh37/qdJtTTwEgIljw9wX78hK2HF7hxWDQycy2mblwSSSTz5iCLovqAUEhuJmHLousLA6SVdc3NgulYPahy1IJMfQdW2CVgDlxGv3+VafbnHoKABEB5V5YEPhX2HJ4hReDQaVg2iY4D75FwpwJtiyqBwTZm/et7c0R6LLISicv99AR5fWNzeSu3UqVgsHQd9OY4SK/+fYD9PtXnW5z6ikARES7du1+t66u7iHjARYIrikmtmxu4NVgUCmY1gnOg68iMGeCLYvqAYFzwKFnJ3RZZGXhoMwt5fWNTacUzOwZ6LJUwrD17ZSAAfuffop+/6rTbU49BYCIYIHedhb8PYI8QPZ1RjGxZXMDrwbDWbZ2UcHcJEIdMVEC5gK6LDoEBJF+PURifjSDLouMdErAsAmZDvrGZPZ+RKlSMGHrOxdNiwlZ/57o964D3XY7ogAQESzQ++8/+MEP/jm2HF7h1WBQKZjWCc6Db5EwZ4Itiw4BgbPCdeUGuiyysWWxbB30jfo8FSsFE7a+YQzylIzJ49HvXQc6J/grzKmnABARtbW119q1a/d72HJ4hVeDQaVgylOUgHmTOxFwJtjy6BAQxOqXiAnHwcPossjGlg5EB31jE07vq1IKJmx9wxjkK1ZLl6Dfuw502+2IAkBEsABwaF1d3RXGjjU1NX9dTGzZ3MCrwaBSMOUJToNvIQ3tjy6LbTBUDwiSW7aKCceGDeiyyMaWW0g66BubTimYC/KXgglb3zAGeX4zG5PY964L3XQ7ogAQESzwi5ZhE7ZsbuDVYFApmPLMnLsokshnTkWXxTYYqgcE6eOnRJCzgErBtGTL1Xgd9I1NlUrBhK1vGIM8v5mNSex714XFh7gq0Td2/EBQHF4NRj5BpWDKMbl7rygj8f4qdFlsg6F6QJC9ZZWCGTMcXRbZ2DIfVwd9Y9MpBbNG/lIwYesbyjHx/GY2JrHvXRcWl3GqRN/Y8YPx+OEPf/ha+/bt/307BmxZqoEfBoNKwZQmBH6iBMwedFlsg6F6QGCXgoHyE1CGAlsemdiykKwO+samSqVgwtY3lGPidp+NSex714Vuuh1RAIgIFvj9fl1d3VnGf2TMWl/Pff/7338VWzY38MNgUCmY0nRKwJz9BF0W22DoEBBA2QlRCiaNLotMLC4Bo5O+MVkoBTMIXZa2GKa+oQwT3/np1wP9vnWim1IwFAAiora2difj0ldeeeXb8D18ZQFgPeNubNncwA+DQaVgSrNx2AARqDxsRJfFNhg6BARQdoJPOC5TKRibpbry6KJv1OfqlIJ5S/pSMGHqO3P1pkjFmDQO/b51onOSf2zbOfUUACKCBXqf1tTU/JPin7Vr1+432c+fYslUDfwwGFQK5kXyEjCd3+SUxXHoEhBA2Qk+4ThwCF0WWVjqMJYu+samUwrmcQxdltYYpr4hR42vVNUvRr9vneim2xEFgIiora1tbN++fW3xz+B7004BA6kUzIuEVT++dTRsALosxQZDh4AguXWbmHCsX48uiyx0to6KxqAu+samKqVgwtQ3TPb5GNy8Bf2+daPT7aiNnHoKABHBAsDhEOyxr/1qamr+b/gKQSF7PQJbNjfww2BQKZgXCXl/PHl81nR0WYoNhg4BQfrEaasUzFx0WWShswq/caN2+samXQomtfdjdFlaY5j6hhw1nt/MJh7Y960bC6Vgbrapb+z4wWiwgO9dxqOM962v77Ifv4Qtlxv4YTCoFMyLdMpHrJanfIQuAUH29gMqBdOCpfJwddE3NlUpBROmvmGyz0vA3LyHft+6EbbVRbej1kvBUABI8Ay/DAaVgnmeMhaQ1SUgyKefUimYFix1El8XfWMzfUaNUjBh6hvalVEJmGCY3FJZKRgKABFRU1Pz9+3atftDeN2+ffu62tra03V1dSfgNbZsbuCXwaBSMM8zOn2KlTd0GV2WYoOhS0AQGdBL5Mk0pdBlkYGlJmA66RuTqpSCCUvfkJsmSsB0R79nHVkoBdN6tyMKABHBAr7Ia6+99h3r9T7GRSwonMaCwGPYsrmBXwaDSsE8z8bBfaU7OahTQNA0ZYJVCuY6uizYLFUCRjd9oz5fRUrBhKVvKDTOUzDYpB/7nnVk9qbV7WjsiDb1jR0/GAsW6H0JX6H0Cwv+voCv7NtvsZ9/hiyaK/hlMKgUTIH5zGfMYbze3ND1bakchk4BQXxZPZWCsVg4hDVKW31jU4VSMGHpGyb5fIWKTfqx71lHVloKhgJARLCgL9GhQ4caFvD9F/b6FPwM6gJCMIgsmiv4ZTCoFEyB2buPxZbRyCHosrQ0GLoEBIVSMOvQZcFmubGnk76xGZ0hX0pHS4albzhpLkrAbEa/Z13plIKJZlrVN3b8YCxYoDeU8R+ALPD7f+Fn7du3/z/Z9xexZXMDvwwGlYIpMH3qrEganzsLXZaWBkOXgCB94owIeubPQZcFm6VKwOimb2yqUAomLH3DRIOXgGETD+x71pVOKZgr5bsdUQCIDDjwwdC++HvGP8KUyS38MhhUCqbA5LbtwiGvW4suS0uDoUtAkL3zUKyyjh6GLgs2y+Xf6qRvbCZ37rJKwaxBl6Ucw9I3pBrwEjBs0o99z7oyVr+kzVIwFAASPMNPg0GlYATjy5aKwbv/ILosLQ2GLgFBPv2sueHdHzU3dH/H+FIw5U7g66RvbKpQCiYsfTslYJJP0O9ZVzqlYDZsaFXf2PEDQXH4aTCaJo6hUjDwHKZMFM/hklwnVHULCJxSMI1ml4IpN/HSTd+YdErBjBiMLks5hqFvyEkTJWB6oN+vzkwfP2V1OypfCoYCQIJn+GkwqBSMoKw16nQLCAqB9jV0WbDYWuqFbvpGfc4KlIIJQ9+Qk8ZzvSePR79fnZm91XYpGAoACZ7hp8GgUjByd6nQLSCQdas9TJYrAaOjvrEpeymYMPQNZZd4LuTSevT71Zl2KZiGnp3K+hEKAAme4afBoFIwRTM3CfvU6hYQFA7bmFsKprUxp5u+sSl7KZgw9A1ll3iLSzb2sO9Xd0b626Vg0mX1jR0/EBSHnwaDSsFUlruBRd0CArvcTmzebHRZsFiuBIyO+sZmfOUKseK8T85SMGHoG8YaLwHDxh72/epO2GZvrRQMBYAEz/DTYFApGHDIlTXyxqBuAUH2ziORmD9qKLosWGwt71Y3fWNT9lIwYegbitvzEjB3H6Hfr+4slII5XFbf2PEDQXH4bTBMLwXjOORD5es3YVG3gCCfsUrBdOsoXb5lWGyaYJ+8v629vrGZPnNelIKZMxNdllIMWt9w+AXaW8KYg3aX2PerO5NbtrZaCoYCQIJn+G0wTC8FU64mmwzUMSCIDOwt8mQiSXRZUO6/d1cx4UrkjdA3JmUvBRO0vuHwC7//wX3R79UEtpVORAEgwTP8Nhiml4KJ9OkmHHI8hy5LKYOhW0AQnTpJBNwXr6LLEjZhlZ2nXPTtboy+UZ939rPmhk6v81UwGUvBBK3vzIVLYgV0xhT0ezWBbR0opACQ4Bl+GwyTS8HAKgx3yL27ostSzmDoFhDEly8TE46PD6DLEjYzV28KBzFpnDH6xqbMpWCC1ndyzz6RA7lqJfq9mkCnFEyZkmIUABI8w2+DYXIpmOz1O8Ihjx+NLksp6hgQJLfvEBOOtXL1XQ6Ddk222NIlxugbm9EZU8WK8/lL6LKEre/46vdFCZjde9Dv1RRG+vcs21SAAkCCZ/htMEwuBZM6ckw45PcWostSijoGBHYpmKiBpWDaqsmmo76xGX9/lbRBUND6js6cJoLfcxfR79UUttbtiAJAgmf4bTBMLgWT2PiRWI3atAldllLUMSDI3n0sEtNHDkGXJWxG26jJpqO+sZncs1fabdCg9d04tL9YjXoURb9XU1hIcdlfUt/Y8QNBcQRhMEwtBQPb3twhHz2BLksp6hgQQDkKU0vBODXZ7j02Rt/YhC4gfMV5unwHIYLUtzgAI3cvZB2Z3LGzbO1JCgAJnhGEwTC1FAxse3OHfPMeuiylqGtAEBnUR6xMNCTQZQmLTk22Tq9z52ySvjEJf2N8h4P9zWHLEqa+s/capC6BoyvTZy6ICces6SX1jR0/EBRHEAZD5mLIQTLSs5NY+Ux9ii5LKeoaEESnmVcKBrbhuEMe0s84fWMSVpkbuncUxZDTz9DlCUvf6dPnrCLYs9Dv0yTmHjaKcT5sQEl9Y8cPBMURhMFIbtnSagVzHZmLZsTKQP8e6LKUo64BQXzF8rJ5MroSEvG5Q545zTh9YxPqsvGV/tsP0GUJS9/2VqSJp+0xyVf6u7zZ3ND5jeZ89vMX9I0dPxAURxAGI33ijDgNO38O+gAKi5nLN8Tp58nj0WUpR10DgoJz+gBdltDuedcekRu0+n3j9I1N6MzAc32Pn0KXJSx9O4cR9h9Ev0/T2Dh8kJXr2/CCvrHjB4LiCMJgQKNw005m2jXZ4kvr0WUpR10DAhO3p+AUKnfIez82Tt/YhCL3fMKxeTO6LGHpu1CO5Dr6fZpGsGulTvtTAEjwjCAMBj+ZKXHLpCCYWL9e1Afbug1dlnLUNSCAU7CmTTii0yYLh/zJFeP0jU1Z630Gqe/IgF5WQeI0+n2axsS6tSXrfVIASPCMoAyGaTWjYnZNtpNn0GUpR10Dgud6tBpSCsY5+Rwpf/JZV31js1DsfhS6LGHo22lJ1rOTMeNLJpbbXaIAkOAZQTkIOLbOA6KzF9AHUBiE8git1WSTgToHBI2D+1qlYOLosgRNOH3Kax92b732oc76Rn3+SbvYfWd0WcLQd/bmfRHwjh2Bfo8mMnPlRsme3xQAEjwjsKThNavFsvXOXegDKGiKk1pvWSe1Stdkk4E6BwSVbInqQjh9yh3CmOHG6hubcNqfTzii8myJBqXv9LGTYst74Xz0ezSRuVhWTDj6dn9B39jxA0FxBOUgoCQHX7Zevgx9AAU+QFup1SQTdQ4I4iutUjD79C8FA6dPuUNeMM9YfWOzacoE6Q5FBKVvOOzCD71s3Ih+j6Yy0ruLqDGbyD+nb+z4gaA4gnIQ0Lyar1JMmYg+eIJm+sx5cQp19gx0WVqjzgEBrDTzCccHL7ZM0o2JzVadzQ8/NFbf2Cz0aD2ALkvQ+o4tXiTu9cgx9Hs0lU0TXuyuRQEgwTOCchBwWkz2wsh+UZU6dDoHBKoE4X7QcciHjxqrb2w6PVolmnAEpe+m8aNFfvP1O+j3aCpLddeiAJDgGUE5CEhOhyRpvmydfII+gIJkfFm9EkVSdQ4Icg/sbfiB6LIEzUodss76xqaME44g9M3tuN3iUnM7LjOTW7a+0F2LAkCCZwTpIEyZOUL3D748f+UGuiytUeeA4PmWSfIexPGDkV52PlDrDllnfWNTxglHEPrONaXETs6AXuj3ZzLTJ06/0F2LAkCCZwTpICrdqlKdcDqLO+RYFl2W1qh7QKBCKR6vdHpO9+ve5nt11zcm+YSjc+kerVgMQt+Zi1fFSufUSej3ZzKzd17srkUBIMEzgnQQyS1bXli21o35eE445D5d0WVpi7oHBDA75rUnT8hbjNsrnZpgFfSc1l3f2GwcPlBMOO5H0GUJSt/JPftEruOqlej3ZzJLddeiAJDgGUE6iMKy9Vz0ARQUM1dvCYc8cSy6LG1R94AAJhq89iSbeGDLEhTd9JzWXd/YjM6ZKSYcp8+jyxKUvuPvrxJjavde9PsznY1D+onak49jjr6x4weC4gjSQTjL1qOGog+eoGg75NjSJeiytEXdAwJINeC6WLwIXZagmFi3rmRfUBP1jc3EWqtH6/Yd6LIEpe/o9Ckiv/nCZfT7M53RmVOFLs5ddPSNHT8QFEeQDqLUsrVudOOQsal7QFDo0ToSXZagGJ0zS6w6nTprvL6xCaf++WrssrZXY8NgEPqODOzdZs9pYjh0VmN37XH0jR0/EBRH0A7CWbZ+FEUfQEHQccinz6HL0hZ1DwicpvU93tW2ab2bvDPd9Y3NzOXrFedjhkG/9c3HE/Sc1ng8qUQnH3PlCkff2PEDQXEE7SCiM6eJAMlattaNsiWCt0YTAoLCikUSXRa/CadN4dQplLupZEXdBH1j0s2J7DDot75NWFFXidDnnJ/InjbJ0Td2/EBQHEE7iPia1WLZeucu9AHkN4VDfpNThS1uEwKC6LTJIk+GGUtsWfxm9u5jkVM7YjDpWxIWajLm0WXxW9/Q+o3n1L63EP3eiF/ybXg+4WCTXFvf2PEDQXEE7SBS+/aLZesVy9EHkN+EVT/ukIcPQpelEpoQEEC5Cl1PLZYqBmu6vrFZqkcrFv3WN/Sa5mW8Nut7ql4lwjY8bMfDtjxsz1MASPCMoB1EoZDoRPQB5Dch74/f29xZ6LJUQhMCAp3rliU2bxYOmTlm0rccjNUvEcXuDxxCl8VvfUP5LlFX8zT6vREFm8aOFClHN+5SAEjwjqAdRK4prW0rITj5yx3yunXoslRCEwKClnkyOjG2aIEINo4cJ31LQigBw23A2g/QZfFb39B1ggcbd/XtrKMai7trUQBI8IygHcRzzcRTn6IPIF8H41Jr9n/wMLosldCEgCDXqG/v0qYxw4VDvnmf9C0J02cuiAnHrOnosvipb9Fb+63mhk7699ZWicktW8WEY/16CgAJ3hGGg2gaN8pZtsYeQL7e18SxIv/nKn7+TyU0ISDgeTL2hCP5BF0eX++re0eR/5N+RvqWhFDeiucBD+mHLouf+s49bBT3NWwA+n0RC4T6n3zCMWcWBYAE7wjDQRQvW2MPID8Z6d1VBBrxHLosldCUgKBp/Ggx4bh+B10Wvwjtn7hDHtyX9C0ReWDezV1gHhT91Hf6zHkRaMyegf6MiQU6Bw+HDaQAkOAdYTiI5NZt1rK1GrlylTAXy4qtxr5y1ACrhKYEBLEl74kJx6Ej6LL4xfTZT4RDnjmN9C0Zna35W5VtzQdFP/Xt5DauW4v+fIkFFm/NP8l9RgGg7qipqRlRW1v7d4xT2Ovvtfbeurq6P2ZfvvXKK698u0OHDjWVfH4YDgKapYtl65noA8gvZi5dE0VSp6hzutmUgKA4TwZbFt/uacdOcbp5zRrSt2R0ezgnKPqpbye/WYLTzcTnaR/Oyd19RAGgzmAB35+xoG4VvGZfv8uCwB2tvZ/9/w32vqeMu1599dWXK7lGGA4i97BJLFsP1SefpGVbHhVoSkCQPnlGTDjmzUaXxS/Gly0VDnn/QdK3ZHRbnico+qlv1fKbTWJswTxRnuf4SQoAdQYL5EazILCr/T0L8JJtvL+j22uE4SD4snXXt5sbOr3enM/g5sn4RafgMAsEsWWplKYEBNl7Da46ZqjApknjhEO+fIP0LRnTJ8SEI4Y84fBT36rlN5vExMaPhO/Z9BEFgDqDBXzvMb5e9H0CtnfLvZ8FgDM7dOjwN+zrqHbt2v1hJdcAg/H0qTAeQdLOk8ndvh/4tcIgFLbmeT+XrqLLUilBz2HpG5NPclbP3M5v8tfY8vjBSB/LISdypG/JmLtfaNGHKYdf+s7H7B7HPdCfLfFFwsofn3AsnEcBoM5ggVx9TU3N3xd9n3n11Vd/q5VfeQn+efnll3+bBYufVHKN5pCQW1nP/2i/vHg+rEsGiqYBPfn9fPWTL7FFIZRAfJTIk/lFNoMtimd89ZOfiHzT/j2wRSGUwNdffdXc0OVNTnitOn76+KFIN5g5GVsUQgn8IpUU6UfjRlAAqDpYUPfnEKwxXmjBHbCSxwLAzkXvTZf7nA4dOvwt+/951rffZL//D5VcH/6gwlghSG7ZYuXJbECfQXllPm6fAO6GLosbmrQiBNtxfMv05Bl0Wbwye/m6yGmcPJ70LSlh9Y/vcNx/jCaDX/pO7fvYym9ejv5ciS/ySfYzfgoYTgN7DD8IMoMFdH8Kq4Dwun379iymq91r/x8LDDsUv5cFgH/J3vMn8Pq11177A/beI5VcAwwG/6MKOG/BKWCpQWJ+5tJ16wTwBHRZ3BD0HJa+sek0st+0CV0Wr0zt2y8c8vJlpG9JaU84IB8QSwa/9A0H21TLbzaNUKAbdORnvEGQECzQm86CwB9Z+X12aZeXWIAXYf/3Oy3e2xVWDNn/TZbpFDCwuIAl9uDxyuIZMrYsbmhSQJA+ZuXJLJiHLotXxle/Lxzyrt2kb0npTDg2b0aTwS99w8SWr55fuob+XImlCZ1AKAAkeEZYDqJwEviN5nxG7d6Szgng3XvRZXFDkwKC7J1HYsIxcgi6LF4ZnT5FOOTzl0jfkhJqAPIJx6IFaDL4pW/nwFEsi/5ciaUJTRUoACR4RpgOonH0MHFy9s5D9AHkhdGpk4RDvngVXRY3NCkggAb2cAoYmM9+ji6PF0b6iwNHuaYU6VtSQhcQnhYyZjiaDH7oO9eUdk4AYz9TYnlCW1UKAAmeEaaDiC2cL/Jkjp1EH0BeCMaRO+RoGl0WNzQtILAT87N3H6HLUi2hDht3yL27kr4lJtQ3hX7A0BcYdjswZPBD35lProhcbTbJxX6mxPLM3rhLASDBO8J0EJCQz/NkNm5EH0DV0nHIfdw7ZGyaFhA4FfMVnnA4B44mjyd9S87GIf3ExPBhE8r1/dB3ctcekd/8/ir050ksz3zqUz7hwI4fCIojTAeRPnFa5MnMn4M+gKpl5nL1DhmbpgUEzoQDuUWXF3ppOWiavrEJvc75hOPUWZTr+6FvOGnOawB+vB/9eRJbZ2rnTgoACd4QpoPQoUWXU5JjhVongIGmBQSytOjyQjhpzh3y3o9J35IzsWED6klgP/Tt9AC+UnnLQSIOQc/Y8QNBcYTpICAZn1fM7/yGson5sDUiTgDvQZelGoNhUkCgQ+khWGkWPYCvk74lJ3bpIa/6zue/aI706my1HMyjP09i2/rGjh/7kjc4AAAdWElEQVQIiiNsBwFlOURi/mP0AVQNo9OsE8CfXEGXpRqDYVJA8HzpoWfo8riWnzvkLsIhx3Okb8kJh40wdzi86jsXSYj85gG90J8lsTJ9Y8cPBMURtoNQPTG/UJJDrRPAtsEwLSBwSg/duo8ui1vmIklPDtlEfWPy+R2O8GudetV35txFcQJ4xhT0Z0msTN/Y8QNBcYTtIBKbrZ7AGzagDyC3LJTk6IIuS7UGw7SAIPbeQpFDd+QYuixuWXDIU0nfitCZcNx+EPq1veo7uWOnyG9esxr9ORIr0zd2/EBQHGE7iPTp88KpzZ6BPoDcElojqdgDuNhgmBYQJLdsFROO9evRZXEtu+2QP1hD+laEzoTj8NHQr+1V37H6JUL2A4fQnyOxMn1jxw8ExRG2g8g9jok8mUF90QeQW8LBD5VrZJkYEKRPn1N2whGrXywc8sHDpG9FmNy6TUw41q0L/dpe9d00frTIb752G/05EivTN3b8QFAcYTsISGxv6NnJOmn2BH0QuWF8Wb1wyPsPostSrcEwLSDIPYqKCceQfuiyuGXTuJFiO/HGXdK3IkyfuSAmHLOmh35tL/rmdrnHu8Iupz5Ff47EyvSNHT8QFAeGg2iaNM4qbaFWrSl7hpy9fgddlmoNhmkBAXds3Tvyqvn59FN0eSqWG04we5TbRH1jM9cQF3nCA3uHfm0v+lZ5Z8ZUUgBI8AwMB+GluC0W/XDI2DQ1IHBW0hQK3KGdGHfIQ/uTvhUi5g6HF307udkIK5fE6vWNHT8QFAeGg0jt+1i5bhq5B42WQx6ALosXg2FiQBBfqt7WPbQT4w55zizSt2LE6qbhRd9O20QFqzOYSgoACZ6B4SAyV2+K07TMUGIPokqpQ1sxUwMC5/DOqpXoslRKP8olmapvbDr9dPeFu8PhRd/Qn13l+qwmkgJAgmdgOIh88gnfSoWkY9gywR5IlTCx8SPhkD/6CF0WLwbDxIAgc+m6mHBMGocuS6WMLbQKph89QfpWjMk9e8WEY+WKUK/rRd+ws8HTJO5H0J8fsXJ9Y8cPBMWB5SDgVCbvqPEoij6QKmF03mzhkE+eQZfFi8EwMSCAXCzQHeRmqTLhaBw+UDjkew2kb8Xo1AudPD7U61arbzj1yyfk3TvyXGfs50esXN/Y8QNBcWA5iOicmSKgOnUWfSBVQkjG5wHrw0Z0WbwYDFMDAjjdqMqEAw4ZcYfczZtDNlnfqPqzOwb16hLqhKNafWeu3hIB6/jR6M+O6E7f2PEDQXFgOYjEhx+KLdVNm9AHUlsszJDfUXqGbHJAoNKEI3PNH4dssr6xCf2b+YSjIRHaNavVt3Mob/ky9OdGdKdv7PiBoDiwHET6+ClxqGL+XPSB1Bb9csjYNDkgcCYcCuRw+uWQTdY3NqGcCp9wnD4X2jWr1TdUYwBZk3v2oT83ojt9Y8cPBMWB5SAg2ZiXVRk2EH0gtcXUxweEQ162FF0WrwbD1IAgfeK0KKsyt/qyKmHRr1OkJusbmxgTjmr13TRxDErZGqJ3fWPHDwTFgeUgeGHlrm83N3R6vTmffoY+mFojnObjM+Tde9Fl8WowTA0InMLKCrSEK/RkvUX6VpR22SgvdRzD0LfTAg4K3FMLOKVIASDBMzAdhCodGpomWDPkqzfRZfFqMEwNCJ5zdEl5e1DziVE3fzrOmKxvbNo9qCOD+oR2zWr0DYfaVJkYEV/UN3b8QFAcmA4ivszq0LBvP/pgKkfHIfOVSjVbwBUbDJMDAqdDg8Q9qLP3HguHPNx7aoTp+sYkTDgivTqLlnDxXCjXrEbfTmqEwgXuTSUFgATPwHQQ0AtY9tNn2buPhEMeMRhdFj8MhskBgd2DGgr1YstSjqmjx8XhqIXzSN+Ks2nKRDHh+ORKKNerRt8qVWMgvqhv7PiBoDgwHQRs/fLTtWNHog+mckwdPioc8nsL0WXxw2CYHBDASrM4zFOPLks5JtatFUHq1m2kb8UZX7Na6HL7jlCuV42+VSqPRHxR39jxA0FxYDqIfOZZc0PnN5oburzZnM9+hj6gSjG+2jLiO3aiy+KHwTA5IChMOEagy1KO0RlThEM+d5H0rTidyeOiBaFcrxp9Y9QrJPqnb+z4gaA4sB1E4+hh4iDIzfvoA6oUoZ0T38a5eBVdFj8MBra+MZnPfMYmHG9ywmtseUox0q+7cMhNKdK34szeCTd9xK2+4W+MH1Rhf3PYz4pYnb6x4weC4sB2ELH6JeIgyP6D6AOqJZ2To5DInZD35Kgbg4Gtb2w2jRkuJhw37qLL0pK5Rn8dMukbl8+Xugr+AJlbfafPnBcHQGZOQ39WxOr0jR0/EBQHtoOA2no8L2vlcvQB1ZK5B1aJhKH90WXxy2Bg6xubUMzbjyLLQRDysLhDnjWd9K0Jm8aN8qWmYxD6hiLV/ADIhx+iPydidfrGjh8IigPbQcjciDx97KQy7eoqNRjY+samcxBkqXwHQZwTmRv96R5B+san09Vlb/ATDrf6js6eEXq7OqK/+saOHwiKA9tBQBcQ2CKBrRLYMsEeVMV0TmRu2Youi18GA1vf2IStX76qO3oYuiwtGZ0xVTjkMxdI35owzAmHW31H+vcQ+aaRJPpzIlanb+z4gaA4ZHAQjSOHiLys2w/QB1Uxo9Mmi+0bH05kykAKCL7kp83h1DmcPodT6NjyOHJB4eDeXYVDjqZJ35owe/NeaBMON/qGoI/nm7IgEPsZEavXN3b8QFAcMjiI2JL3xDbJgUPog8rm8w45gy6PXwZDBn1j025BmLl2G10Wm0G0DiN94zOf/bxwECTgXrtu9A3bvn7mmxLDJwWABM+QwUEkd+0W2ySrVqIPKpu5h02h9/IMw2DIoG9s2nlZMnUEKeSbziF9a0anBeGl64Fex42+/c43JYZPCgAJniGDg8hcuSHdQZDUEasl1wI9DoDYBkMGfWMTSg5x3dYvQZfFZvyDNb51ACF9y0WnmHzAHUHc6BtKv4h80/Poz4dYvb6x4weC4pDBQfCDIHZHEEkK9MbfX6VNB5BigyGDvrGZvXVf5GWNGooui02n4LiPfWNJ33LQ6e8c8GTSjb79LDhOxCEFgATPkMVBQD/gsOplVSTP+NFCnss30GXx02DIom9MFvKy3gilQG+b8kDBYCg4/u6PfC04TvqWg3Y6SeOgvoFep1J9Q9s3nt4yoBf6syF60zd2/EBQHLI4CMj/4ytuO3ehyyJOir4lToqm5Tkp6ofBkEXf2CwE+MHmZVXC7F2rZdjwgaRvDRnECW8v+k4fPyUOgMyZhf5siN70jR0/EBSHLA4ideSYtU0yD12W7PU7IidxzHB0Wfw2GLLoG5tOXta27eiypA4eFn/77y0kfWtKJ+fudHA5d5XqO75Gnr99ojd9Y8cPBMUhi4OQ6dSt055uhXzt6bwaDFn0jU1nFWQu/ipIfOUK4ZB37SF9a0o4bRt027VK9d00YYw0q99Eb/rGjh8IikMWB8G3Sfp0E9skjbiJybASw+sSHjyM/lz8Nhiy6BubuYiVB9WvO//bw5QFigTzQujX75C+NWX67AUx4ZgxJbBrVKJvOGTnFELXKL3FRFIASPAMmRyE05vyxBlUORqHDRAO+d5j9Gfit8GQSd/YjAzsLSYcj6JoMuSTT0QrxG4d+eEU0reezMWyYsLRq0tgE45K9J25elOkt4wbif5MiN71jR0/EBSHTA4iuWWL2CZZuxZNBuj6wQ11z07oK0NBGAyZ9I1NyDflK71HjqHJkDl/STjkKRNI35qzcWh/MbG8G8zEshJ9Q1krnt7y/ir050H0rm/s+IGgOGRyEFADjTvDSePQZEifOqttiyQKCJ4nnDjH7kDj5IZt2ED61pxOy8t9+wP5/Er0DZ1m+C7L0RPoz4PoXd/Y8QNBccjkIKBXJt8O6/q279thlTK+xurIsGUr+vMIwmDIpG9sQi9g7NPe0WmThUM+e4H0rTmdDjQ+n/Z2o2+o/cfTHh7H0J8H0bu+seMHguKQzUEElRBfKZvGjdKuAHSxwZBN35jk9R7tgtBs8hH69YsLQMdzpG/Nmb0fCbQgdFv6hqCPp7f074n+LIj+6Bs7fiAoDtkchFMQGqEFG1+B5C3p3pKmJZ3fBkM2fWPTacF24XLo187etFrSjRxC+jaAvNJBX6sFW0MidH2nDh/Vrr+5yaQAkOAZsjkIpz7b7BmhX1uGHMSgDYZs+sYm1GULKgevLTr1JpcvI30bwui82SIP8Ojx0PUdW7pETK737EN/DkR/9I0dPxAUh2wOAlolOadwcz8O9dpOQv769ejPISiDIZu+sYkZ9MNKDA8GDh0hfRtC5+DRyhWh67twCvkR+nMg+qNv7PiBoDhkdBCNIwYLQ3XzXqjXjU6bFFhCvgykgOBFQjFcURj3Tfb6aXjX5YXPuwa2HUj6lpN2m8nGUUND1bdT+LxPN+3KW5lKCgAJniGjg4ivXC62KthsOaxr8gMB3TuKhPxEHv0ZBGUwZNQ3NmH1L+w8wOztByIQGDaA9G0Q+cGf7u8IOxPLhqZvp9f6fMr/04UUABI8Q0YHkT52UuQBzpkZ2jUzl65rXyGfAoLSxMgDTO7aHWj+H+lbXkKNUb7TcPxUaPqOL6sXk+rde9Hvn+ifvrHjB4LikNFB5JrShbZJIeUBOkHA+nXo9x+kwZBR39iElb+w8wBhcsODADbZIX2bRScP0OfgvzV9Nw612lveofw/XUgBIMEzZHUQjcMHhZoH2DRhjNgG/OQK+r0HaTBk1TcmIfcPcgDDygOESQ0ccuL5f9E06dswQhDGt/+H9AtF34X8v66U/6cRKQAkeIasDsKpB7h1W+DXgpw/pwNJ5hn6vQdpMGTVNzbteoBhHAByDgIEVP+P9C03+QGgfj3EBOBRNHB9pw4covp/GpICQIJnyOog0mcuiG25KROCv5bd/3f6FPT7DtpgyKpvbCa3bBHbcu+vCv5abFITxrVI3/IS2sHxEkAfHwhc3065IRYIYt830T9SAEjwDFkdBN+W6/IW78yRTz4J9FrOauO27ej3HbTBkFXf2HS6cgwN7lSuTWe18fR50rehTB08bK3KzQtU3zzdoFdnsdoYSaLfN9E/UgBI8AyZHUR02mThKE+dDfQ6jcMGWvmG99HvOWiDIbO+MfncttzDxuCuE8/x3sM83SDgfEPSt7yE2o88L693V98OupXSd+bKDTGxGT0M/Z6J/pICQIJnyOwgoB9w0KUywNlzQ9y3e+idRzAMhsz6xmZsyXtWq6y9gV3DKXE0cxrp23BCDig/eHb1ZmD6dqobrFuLfr9Ef0kBIMEzZHYQ0LKIB2eD+gR2es0uyRCrX4J+v2EYDJn1jU0nOJs1PbBr2LlfQQaZpG81CC0n/QzOSukb6pryIPPiVfT7JfpLCgAJniGzg+DbcgN7W/0rHwdyjejUiWKb+eQZ9PsNw2DIrG9siu3Z15sbunUM5DQ4z8ey27/5ePqT9K0mM9dui+3Z4YMC0Tfvq/7uj5oberzLOx1h3y/RX1IASPAM2R2E3RYusXmL75/Ny790foMfNsmnPkW/1zAMhuz6xqbdFi6IAxqZq7eEwx8xmPRNFBMCK+80ez/iu77hhDHf3Zg3G/1eif6TAkCCZ8juIJwuDWNH+P7ZqaPHQ8vHkoEUELRNO+80Vr/Y98/2e8uP9K0+nRZt23f4ru/ozKmi/MuR4+j3SfSfFAASPEN2B5HPfs5bwgWxbRZlM2NuIPftR7/PsAyG7PrGZu5xrNCGkP3t+fW5kM7QOLS/lfR/i/RN5EyfOe9bG8JifYvdjTebG7q8yV4HW0aLiEMKAAmeoYKDcE5n7tzl22dCbUEoxQElOXKxLPo9hmUwVNA3NmG1mQdqFy759pnQ0jDoA02kb/WYTz9rbujekefqea3TV6zv1OGjgR9oIuKSAkCCZ6jgINKnz4lZ8vjRvn2mYyBn6N39o6XBUEHf2HS6giyr9+0zE+vWie3ftR+QvonPMbZogZjg7tjpm76js2eI3Y39B9HvjxgMKQAkeIYKDgJOsEV6d/EtWRoIM2PT2iNRQFAZcw+b+N9GQ89OfIXG6+fx7d8h/cTf7427pG/ic3TaXo4d6Yu+87F04XBbPId+f8RgSAEgwTNUcRB2u7bEhg2ePyvXZBvIN40ykBQQVE6nXdvRE54/K3PputVmrn9o27+kb3XI85yt8kDZew2e9Z3atdtqMzcX/d6IwZECQIJnqOIgstfviByqgb09d+yAnr/cQC70rw+nCqSAoHLC1plfJ8RjixeJLb4tW0nfxJKMr1whJrjr13nWt53DCiuL2PdFDI4UABI8QxUHwbfRhouevelzF719zrABVpL/ZfT7CttgqKJvbMLJSXFI6PXmXEO8+s+B4tL2YSOPSf6kb33pHBLq0605n6muaDPo+eeJWKG1pY+n2InykQJAgmeo5CCS1taGl5NtmUvXxHbckH6hbsfJQAoI3BHaA3pdlUnu3iv+ZmfPIH0TWyUccvNSt4+Xf1ltFc5fvx79fojBkgJAgmeo5CD4qkz3d3jJhGoPg9in45Jbt6HfD4bBUEnf2Mzeui9WU3p3qeowCKQq2Ic/0mfD344jfavF1KEj4jDIxLFV/T4c/oh0fUusNjck0O+HGCwpACR4hmoOwj4MAjkzbn83e+eRON0JvTENOvxRbDBU0zc2m6ZMEKsyH7svFp4+dlKsNo8cgrLaTPpWi9B/GraAeXrK5euufz+5aZORuc2mkgJAgmeo5iByDxp5Xhac4IWuDW5+1y4oHWYtNplIAYF72jUo+eGj/7+9+4+Ro6zjOJ5r42kqoMY7q3u0d7e3txB/hPgHNU1aIf4MfxiVaNOiVD0rUJFGI20DVVAryB8C3tlWtAGLBsXYWoKJSCsGo+lpjmKojUC8cu1d73p3HL+MKEHN+vnOPlMf193b352bnfcr+XbnxzO7z3Vmdr77zDMzVfTNsoTvqW1b8snjLw+wvomKws5MBF0GbvpqVcvZD9rRqz6Vv5L40SOR/x1E84MEEHWL4wHi+K4dVd+o99SRx/+bOI4m8/QICUH1ESRyX74u321g/30VLxc+ZzpIHE/V1qmf9Z28mDn5dG70sxuqbgUMnzM9NfhN1ndCggQQdYvjASJ4XqsSOevrYoldufLBQXz7V+ru0B/3ICGoLexq8fwVmhtyMxU8NtD6C1riF7T+HaytQz/rO7kRtgIeu35zRVfyBt+Hn8k/Tu6liXHWd0KCBBB1i+sBYvzuPfkO09u2lP2StKvqggP4NVcGzwCOuu5RfmHEdX1HHXY/wKB/1eDtZcvaj4xg27xxW6RXmrO+4xnW1SC85VW5x8PZ9hU+1ejEjiHWd4KCBDAhstnsFel0elW5cplMZmt/f/+liu0aPreS947rF4a1shzb/PmyTweZfuJY8Eivem6v0CpBQlB72L0A7eKhck8HmRoeCVpi7EkzZ/Kxb6zv1orwdlX2OLf5tqPw1lh22njm+BTrO0FBAtj62pXIXa0EcERJ3TvnK6hyK1Vutw3rtUvl91XyAXH+wph65LH8I91KXKVpff3s8VtBy83QtyKvb9RBQlBfnHzgwOmDsiV6hfPtQB3+2FgItxlifcc7Ttx1Zz6523RV0dteTT70cNANxn5w2G2GWN/JChLAhFAy9/1yCaCSvuuVBG7wlpmo5L3j/oVx+qBsp0Du+E5u+smxoCO19b0a3XTl6ftqzUzORV7XqIMDRP1hV5AH29vAx3Lj9/4kNz02FVyBGbTEWD8s+7GxY2hB3GSc9R3vsK4tYdeD0Y0DweMJ7bvNnigTbIfW0mw/Nn66l/WdwCABTIhKEkDNH1Ks88bHOzs7zyr33vaFMTeX35jiGpMPHsxfFOISQT/Gbvl6bnZiJvI6LoSw9dwK6zvKmJ19ITdxzz1Ft7XgR8ju7+Vmp5+LvJ6s79aI2VPP5I4P3lZ8exu4LHdSPzxY38kMW8+NyC+wwFXYArgzk8ms8canUqnUkubXDgAAAFVRorZayd2w4pAXw34fvipOAQ9445PNrDcAAACaqFgCqGSvzx9XwrfCWgFtOJ1Oq3j//WeyjgAAAGgQJXoblcwdVezR8MVucpvGRzV+TkHZm5UErlXc0tfXlznztQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVCmbzV6RTqdX+dMymczW/v7+SxXbNXxuVHVD82i9X6CXxfa4QG4Z1HrYh5OF/Tk5Co/Z7OuoRbs2lqu1MY34N5nWtJWattuG9drlP5EErUPr9Y9av3OK/alUqiPq+qBx2IeTh/05Ef7vmM2+jroUPmXEPVJugzd/IpqaoZm0ntdHXQc0B/tw8rA/J4d/zGZfR10KE0ANDynWeePjdlohmtqhWdzTYi7R63U9PT3nR10fNA77cPKwPyeHf8xmX0ddirQA7tQvijXe+FQqlVoSTe3QRG32T0dHx9la/8NRVwaNwz6cSOzPCVHQAsi+juK0May2LwPFIS+G/X4CJU4BD3jjk2e63qhfiXVvsa+vr+9Dmn+bK7pI016MtLJoKPbhZHH7861ulP25xRU5Bcy+jtoUSQBX2K8KG06n05rVf390tUMz6IDxLq3bC224t7f3PK3jA1HXCY3DPpws7M/JUpAAsq+jNvrlsFEbzFHFHg1f7E2/WRvVWtevhFsKtCDrOGy/HLXuv8ZVg62HfThZ2J+Todgxm30dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiKdsNvuJSh8hlslkblTZH9fyOVr2In3WqVqWBQAAQAO5BPBQJWVdAvijWj7HJYBTtSwLAACABiIBBAAAqJISomsV40pu/qrXUSU6a7x5WxTHNO9pvf6su7v7TeE8TRtzyx7W8N/0urenp+e1Wv5uDb+gaY9p+M1h+d7e3qWadq/mTStOWDJWqk4qd5/KfNerx+2KB0uU/Z8EUOO32vvb36N4xH9euEsA92n6D93f+yd/fkdHx9kav0MxYcmeyn9bk9vdsiSAAAAg/tLpdFbJzovhczgtSVMSd74Na/onlfA8ZQ9qV/LzSo3v0vhvw2UtAVSMqPwbly9f/joNP6l4QuXeq9lteh30kjYb/4M971XDr7BlLHHU+366WL26urper/knNf+Des/3WNJodStWtjAB1PA6q48GF2l4k2JGn/cqm2cJoMq/rGmX2XwNr9fwc/obX+OW3ae4c+nSpa9W2XM0/wGNb3fLkgACAID4U0KTtgRQrx8Ok6SQph9UXBOOd3Z2nmXJU3d3d69b1hLA9V75QY3/IhxXwrRS02Zd2RWKSf/9Nf/jmvZQqbpZImnLW2ucyn5gnr9h3lPAmv+sln+7+0xLAEcKPudRSwg1r9P+Pkv+vGVXWwuoW5YEEAAAtAYlNh9RkvOwnbZV/NxaBW26hv9cmHjZVbCav8oNj2n++7x539Ayd3njF2j87+4zPqrxf1oyZmGtbornNXxknqotcq2Kj89X/yKngL9odXefYfEv1yp5+hRwwfL7NW2z/q4L9frvsI6uns/b/4tblgQQAAC0FmsBdKdtf2PjpVoAVa7HxqtJAPX6DjudXE199N432O1drIVOw18oVc5PAK3FTjGn8m/x5j8b1rNEC+BhawG0U8x6fUmTFpeoDwkgAACIP2vtU7zb+vhpdLFeb1KS82ubZ30A7fSn9QG05FDTdyp+Fy5bYQL4Dze6yPUB/FIqlVqi8Tbrd+hfgOFzCeMzdrrZLiSxljyVf2uxsn4CqDKXWCulu1ilXdO3WctjQQL4smKt+3svt/e2i1fc51ofwF3huN5vmcq83y1LAggAAOJPyd3blPD83l21a6c9fxWeApY2JT1breXOWtXsytxly5alwmVteqUtgEbJ1BvsCmHrC+hOzR72rzgOWR88zfuLJXbhNGuJdKeL2wvLF5wCttPGu93fY59zrV9Pdwp4r6b9wF0FfNQSu/C9rJXT9WU87k7/HtXw59yyJIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsJD9B9nu5nKiCNk2AAAAAElFTkSuQmCC\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=False) as figure:\n",
" figure.plot(np.sin, label=\"sin\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with replot.Figure(xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=True) as figure:\n",
" figure.plot(np.sin)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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 = $('<div/>');\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",
" 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",
" this.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",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\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 = $('<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 = $('<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 rubberband = $('<canvas/>');\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);\n",
" canvas.attr('height', height);\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 = $('<div/>')\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 = $('<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 = $('<span/>');\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 = $('<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 = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\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",
" '<option/>', {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 = $('<span class=\"mpl-message\"/>');\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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, fig.canvas.height);\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;\n",
" var y = canvas_pos.y;\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 overriden (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(\"<div id='\" + id + \"'></div>\");\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",
" 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('<img src=\"' + dataURL + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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 = $('<div/>')\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 = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></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 = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 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"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"replot.plot([np.sin],\n",
" xlabel=\"some x label\",\n",
" ylabel=\"some y label\",\n",
" title=\"A title for the figure\",\n",
" legend=\"best\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "physique",
"language": "python",
"name": "physique"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}