olsndot/firmware/Spectrum Measurement.ipynb
2018-05-05 19:37:48 +02:00

6672 lines
629 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import sqlite3\n",
"import time\n",
"from IPython import display\n",
"from datetime import datetime\n",
"import scipy.interpolate as inter\n",
"\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"%matplotlib notebook"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"db = sqlite3.connect('spectra.sqlite3')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def load_run(run_id):\n",
" data = db.execute('SELECT step, voltage, voltage_stdev FROM measurements WHERE run_id = ? AND led_on = 1 ORDER BY step ASC', (run_id,)).fetchall()\n",
" return zip(*data)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def load_run_zero_cal(run_id, max_stdev=1e10):\n",
" data = db.execute('SELECT a.step, a.voltage, a.voltage_stdev, b.voltage, b.voltage_stdev '\n",
" 'FROM measurements a JOIN measurements b USING (step) '\n",
" 'WHERE a.run_id = ?1 AND a.led_on = 1 AND b.run_id = ?1 AND b.led_on = 0 '\n",
" 'AND a.voltage_stdev < ?2 AND b.voltage_stdev < ?2'\n",
" 'ORDER BY step ASC', (run_id, max_stdev)).fetchall()\n",
" steps, voltages, voltage_stdevs, zero_voltages, zero_stdevs = map(np.array, zip(*data))\n",
" return steps, voltages-zero_voltages, np.sqrt(np.square(voltage_stdevs) + np.square(zero_stdevs))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def plot_rgb(id_r, id_g, id_b, loader=load_run):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" for run_id, color in [(id_g, 'green'), (id_r, 'red'), (id_b, 'blue')]:\n",
" steps, values, stdev = loader(run_id)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color)\n",
" #ax.set_ylim([2.2, 5])\n",
" #plt.close(fig)\n",
" #return fig"
]
},
{
"cell_type": "code",
"execution_count": 15,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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": [
"plot_rgb(10, 9, 12)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def live_plot_rgb(id_r, id_g, id_b, interval=1, loader=load_run):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" \n",
" while True:\n",
" ax.clear()\n",
" for run_id, color in [(id_g, 'green'), (id_r, 'red'), (id_b, 'blue')]:\n",
" steps, values, stdev = loader(run_id)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color)\n",
" fig.canvas.draw()\n",
" time.sleep(1)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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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AHOInm4blvr3NaItTmfEfkD7WbxvASwlOmr1T9ED1E8i8mQGZTID5VWnn5c9PN5da2M30SCV0WnhrU7Pk5L6ukxTRKfRuJC6XCcaXtP7WTJubTGDqPNr6Zp6/x0i8oVoS9tZ0ffmddFg50kd0VPEF0RbmPqL4+chIvJsaplPiQYyd7x5n5uKjug+JRqmtokGuIzEig4cMT/v9SJSNt39PUVPI59Pfcynoq2NmSkvIu+KvSVskthHAIt493k5e0Vct4Gr4vjFwd17lD70vyg6f6b48D/pudt/yqe+Tk+tpu62+Z9Fg3/6eRDPiQZsIiKibGGBBL8l5AbR/oxEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREROStl0XkoIicEZETIvKeiNQIaYmIiIiIKKgqiUih1N9zicjTInJMRGJCViIiIiIiyjJ5ROQpEbkqIsVCXBYiIiIiCqJWInJaRFJE5IqIjAltcYiIiIgoqxQWkSdFpH2oC0JEREREWSdGdEBINQ/3lRWRgvzhD3/4wx/+8CeifsoK+/dTBnKJyEURecDNfWVFBPzhD3/4wx/+8Ccif8oKUapBIlIy9fcSIjJDRE6JSLybxxYUESQnJ+Ps2bP8CfFP//79Q14G/vCzCMcffh7h88PPIjx+kpOTzQBYMEuSBUWE9SLyh4icF5GjIrJGRGp5eGxBEcHZs2dBoZeUlBTqIlAqfhbhhZ9H+OBnER7Onj3LAEiWMACGEVas4YOfRXjh5xE++FmEBwZAsooBMIzYbLZQF4FS8bMIL/w8wgc/i/DAAEhWMQASERFFGAZAsooBkIiIKMIwAJJVDIBEREQRhgGQrGIAJCIiijAMgGQVAyARUbSw2YCkJGDQICAxUZdJSXo7RRUGQLKKAZCIKNqcPQuI6JKiEgMgWcUASEQUbRgAox4DIFnFABiheKaHiDxiAIx6DIBkFQNghGM9T0QuWDFEPQZAsooBMMKxniciF6wYoh4DIFnFABjhWM8TkQtWDFGPAZCsYgCMcKznicgFK4aoxwBIVjEARjjW80TkghVD1GMAJKsYACMc63kicsGKIeoxAJJVDIARjvU8Eblg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O2Ab3QB8F7FOedjboFba9d9h1+imNwLAzJwo4GkkclsA9nljF4A9sGtm/wN3c7y2hWTpbNg773kRt08FMDL3i3NaqQm7CQWwD6Jvwq5ligcwGsCUiPVrwD5BnpVbBTwNZBY6Yr332mdyRrQAeDnspt28AK6FfVLrknaftkXOuQr2F9SW6W57HsDnEeudCXsbXJR2/W8ArSLW6Q1gfg6U8XSR2bYA7P58hWDvMxfBDoTpf/RB20KypG/QJ4/8sDv0XgXVAOYW1QCePKIFwEgvAliS9re2Rc64HnbfsTYRt2dVA2gG3qjWyV/RtkVm7oLd/9XQtpCYMutD8wvUhya35Yc92rElgDuhPoC5IbPQkZ33XvuM/7IbAP8H4LN017Ut/HUb7MBxVSb3XQLgCDLvA5g/7fpCZAzfK6F+Zyciq22RmTthjxg2tC0kpidhDye/AEBB2KOPtkKj6HJaBwCl0v4uB+AN2CezQrBrmrYDeAl2E0st2CMdNQrYH2fAbla8GnboiE+7HofsvffaZ/yT1ba4EEB92AMM8qSt8xvsqS0MbQv/PAI7cDSPcn8cgNUAxsLeT86BPTI1/Sjg9lYoSckAAAFkSURBVLBrnlrA3m4PwZ6eRCNPj0+sbVEN9nts9pWmADYA6JtuHW0LyRYLwE7YcwV9DM2jlRvmwK6pOAj7hDUJQNV099eCPUr4EOxO8C/kdgFD7C7YzVb/pF3M35ek3Z+d996C9hk/ZLUtrgewDnYN0++ww8b9mTyHBW0LP6TCHuW7H+655dKHkIoA5qXd9yuAgTg2Ath4GHYoPwR74E6LnCx0SMXaFo1gh/EUAPsAfAvgadhflNLTthAREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREZFc8P8L+ylJX+++RQAAAABJRU5ErkJggg==\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-18-5741f6ed4af4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mlive_plot_rgb\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m14\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m15\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m13\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mloader\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mload_run_zero_cal\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m<ipython-input-16-f9d194801c7a>\u001b[0m in \u001b[0;36mlive_plot_rgb\u001b[1;34m(id_r, id_g, id_b, interval, loader)\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[0max\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0merrorbar\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msteps\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0myerr\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mstdev\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcolor\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0mfig\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcanvas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdraw\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"#live_plot_rgb(14, 15, 13, loader=load_run_zero_cal)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def live_plot_rgb_splines(id_r, id_g, id_b, max_stdev=0.05, spline_s=1, interval=1, live=True):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}, {}, {} at {:%y-%m-%d %H:%M:%S}'.format(id_r, id_g, id_b, datetime.now()))\n",
" \n",
" while True:\n",
" ax.clear()\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for run_id, (color_dark, color_bright) in zip([id_r, id_g, id_b], colors):\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" try:\n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)\n",
" except:\n",
" pass\n",
" fig.canvas.draw()\n",
" if not live:\n",
" break\n",
" time.sleep(1)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdd3hTdd8G8C88TIGyEQURBRXFhRP3QtwijhdFfRS3DAVcgIwAhbIFyh6yQfYo1AIKCIgyBYTySBgqQ4aMMsto7/ePb08zmrRpT5pzktwfrlxpktPkR3J6zp3fFCEiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiyrNlInJORE6IyHER+V1EPrCyQCJys4gkish+EUkXkUez2baUiPwlImkiUjCXrzNSRLaIyAURGe/j8bcynveEiJzMuKzM5Ws8KiI/iMgR0f/L1V6PlxCRJSJyQERSRP8vfUWkaC5fx92Vfl7LWyDv8x0Z5TsqIodEZKaIVMvheYuIyGAROSz6f5onIlV9lO+kuN7bE6KfZXauEJGEjG0PiUi8iBRyezwvn1cLEflVRE6LyN8+Hr9cROaIyJ8ZZX4nh+fz1iDj97z3r9y+r4HsJ8HYX4mIKEosFZEubrdfET2JPGBNcUREpJaIvCsit2eUJbsAOFpEvpe8BcDmIvK46MnXXwD0FQpy424ReVNEnhIto3coKyQitcUVZCqJhvLeJl6zup/X8pbT+1xARA6KSL+M8pUQkaki8nMOzztYRDaKhr6SIjJORDa4PX5lxutdlcPzeJdls4iMySjHFSKySUS+cdsmL5/XiyLSUETa+fndyiLysYjcIxq6chMAy4vILhFZLp77V17e10D2k2Dsr0REFCW8A6CI1ty0zmGb3eI6GRo1Ov8VPfGfEJFVogHD8H+itW3HM55/UYDly64G8DkRWZ3xeF4CoGGM5F8ANBihJ6dQVlm0pmdeNtvUFq1VPCQix0RrsB5xe/xUxmsZNWtDAiifr/e5TMbz3OR23zOitWX+FM14/Fm3+8qLyHkRuS/jtrG/1AigXIaHRGuqy7rd97zo/7Fwxm0zn1cgv+u+zwdiuoh8Iln3r7y8r9587ScMgEREFDD3cPcfEWksenJ6ys82Bl8BcJFozUQR0ZPf0ozHi4uevB/KuF1ERB4OsHz+AmB50Wa56zOeN78CYKqI7M24zBXPk3Zu5BQAJ4oGt3QR+VdcYcmX2iLymOj7WFhEOooG6wper5WbGjZ/7/NA0abW4qLBZbr4fq8MN2e89qVe9/8hWuPqXr49ol8GVorICzmU7xMR2eZ132UZ5b4x47aZz8tMAPxK9IuPuzdEa/5EfO9fOb2v94k2D1f1+r3s9pNg7q9ERBThlorIGdGTzQXRmprPfWwTSAB0Pxk9LXqiEtGT3EnRprTyuSyfv2AyVUTaZvycXwGwuohck/FzORHpI9qX77I8vEagNYA3iUi3jO1z45hoLVJuXsudv/f5QRFJFt03LorIOhGpmM3z3J/x2t59GH8VbWYV0SbPu0WbM4uKhqVUEXkym+dtLyK/eN1XLKPc92bcri55/7yCWQNYRTTcGu+/r/0rt++rN1/7SXUJ3v5KREQRzj3clRCREaI1eQX9bGPwDoDegcM7lN0nIrNEay02idboBMJXMHlVRNa6PffDGa/1nwCf05u/AOjLLhF5Lw+vkZtQ9opoIPDnChGZIton7bho+LsoIk3y8FoGX+9zTdGa2w9FaxqLi0hnEdkhGr7uF9dggxOin3EgNYC+jBGt3RLRYO/+vCKB1QD6EujnFcwAmCQiLd1ue+9fOb2vgcppPxHJ+/5KREQRzjvcFRGRnaKjIw3zREccGgqJ9lfKTQAUr8fOijZj5sRXMBkjGg4OZ1yOZ2x3SHTARW7lJgDuFJH38/AauQllr4sr+PiSJCLfiavJV0RDoPF5XCGBjQJ25+t9fjHjed2Vytj2Tj/P46sPYAXRwJNds/ZoEZmUzeMPitYS+uoDWCSb3wv08wpmAEwX1755WHRfPyu6fxaWvL2vvuS0n4jkfX8lIqII56t27y3RE5cxLUdHEXGK1rgUFx15eE6yNgH7C4CXisjLIlI647FbRUPCQ+JfUXE18T2Rcduo4SstOj2HcXk547WqZpTPeP10yX5qjcIZrzFetPapqHiGiQbiaj4rLSI9RZvU3PtlLRORb7N5jQIZz3tdRnmuz7htBOM7RaReRrkLiI7I/UO0hs+fX0RkVEb5S4hID9GmROPzKJZx+ymfv+0pu/e5mujn9F7GfcVEpJPoNCSlszyTyyDRUb9XiO5D40Rkvdvj94sOECqY8X94TbQbwrPiXwHRfnbfio4sriYiv4nnKOBAPi9v/xH9P78vGgCLStbma+M9+lN0iqSi4jn9jLfLvS5TRWSGW9ny8r4Gsp/k5f9PRERRaolkDYAFRZvbYjNulxKtcTourpPgLgm8BrCy6KjVf0VrLLaLyKfZlMkIlGlel45+tvdV2/iW6Akyu2bhpV6vk57x/zIMEZ0j71TG9TzR8Opul2Rf62gEUe//y38zHr9PRNaI1giliL43PUSDnT93iDb9nRKtlWomnp+HiMgXGWU+KhrIfAnkfa4nOqL7qGiYWCYa4LJTRHSAg/F5J4j2izO8K9rceTJjm1WitWI5uUJE5our9neAuEYAiwT2eXnrJFn3gTTx/OLg6z1yD/1tRefP9MdXDXNO7+v9ou+dEd4C2U/y8v8nIiKKKBNE5KV8fo2aov0ZiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiKJAnIhsFpEUEdknIpNFpGoOvzNGRM6LyAkROZlxHZePZSQiIiKiIOomInVEpJCIxIjIJBH5LYffGSMi4/O5XEREREQUIreISJqIlM5mGwZAIiIiogjypYjsymGbMSJyVEQOi4hTRIaKSIV8LhcRERER5YN6on36Hs9huzoiUinj56tFZJGIrPKzbQERqSLavMwLL7zwwgsvvITPpYroeZwi2LMickxEns/D714pIukiUtPHY1VEBLzwwgsvvPDCS1heqghFrNdFw1+9PP5+NdF+g9f4eCxGRLBnzx6kpKTwYvGlWbNmlpeBF34Wdrzw87DPhZ+FPS579uwxAmBMHrMB2Vxz0fB3X4DbFxWRl8S1Q1QXke9FZLWf7WNEBCkpKSDrtWrVyuoiUAZ+FvbCz8M++FnYQ0pKCgNghEsXkXOic/m5z+vnHghPishrGT8XF5HlInIk4/7dIjJEXH0CvTEA2ggPrPbBz8Je+HnYBz8Le2AAJLMYAG0kKSnJ6iJQBn4W9sLPwz74WdgDAyCZxQBIREQUZhgAySwGQCIiojDDAEhmMQASERGFGQZAMosBkIiIKMwwAJJZDIBERERhhgGQzGIAJCIiCjMMgGQWAyAREVGYYQAksxgAiYiIwgwDIJnFAEhEkcPpBJKSgMREYORIvU5K0vuJIggDIJnFAEhE9maEusmTgd69gf79gdhY/Tk2Vm/37g1MmeIKe8nJgMMBTJyojw0dqtejRgHDhum1r/unTNHgOHmy5+3cBkkGUd+8P0vj/Xf/7LLb3v2z79IFiIvT2z166GMDBuT8mUXIZ8MASGYxABJReDh1SkPd8uV6ffy4Xq9fnzXs9eyp940YodczZuj1tGl6X0KC3v7tN71OTdXXMIJjQoKGg4kTXc/tHhZ++sl3MPEOo8bzJScHtr0RQnIKSt6vn1OQyi+5DXSG1FR9XzZt8vzs/IX7ceM8t09J8dwX3D+z8eP19rhx2Qe8kyc9P/swwwBIZjEAWiw9XY9D+/YBu3cDBw8C585ZXSoimzl7VoOAwwGMHq3X/fq5Tv4Oh4aFjh2Bb74B3nsPeOUV4N13gcceA555Brj1VuD664ErrwSqVQMuvRSoUAEoUwaoXBmoWFEvJUsC5csDMTF6u0wZ3f7yy4HrrtPLrbcCt90GPPwwULcu8MYbwJNPajlefVVrpjp1Avr2Bdq0cYWROXN0m40bsw9ARvAZO1YfX7TId42mEVCNx40QlFNQ9Q5Y3jWg3r9v1Jb5qxk1gq73/6dfP6BrV8/X69ULGDgQaNcO6NYN+PRTfb/ef19/7+239bpJE63Re+cd/RzffVef6+OPgeHDgdat9fnbt9f3OjFRX3vYML3u1Sv7gLdrlz5+4kQId+TgYQAksxgAQ2zHDq2AeOcd4PbbgdKlARG9FCig1wULAtWrA889p8e3bdusLjWRxVas0JDiXvuzaZOGgK5dgdq1NaQVLKh/RCVLamB7/HHgppuADz/UsBYXBzRsqMHs1VddgaNfP2DdOqBPHw0iXbtq4OjRQx9v2hT4v//T3332WaBFCw2WTzyhAbBuXaBWLf3DrVwZKFcOKFbM84+7WDFX2LzqKt3+ttv0dxs00ADZqZOWq3174KOPgJYtNUDOnKn/5y1bXEHP4dDw5XAAGzbo9d69njWOiYkalozQbARP4z00brvXeHbqBMTH6/3dugFffAF8/bUGsi+/1AD28cf6PrzxBvD881p243246SZ9b2rU0M/kssuAKlU0UJcqBRQq5HpfjEvx4kCJEvr+lCkDlC2rB8dy5fT3LrtMf9d4X72fo2BB3e7yy/XA+d57wNq1+n84eND3PrV1qz6+a1co9+SgYQAksxgAQ2DzZj2GX3stULgw8NBDenv6dD3+HjkCXLigtYFnzwJ//w0sWaJfmp96So93d92lx/Dz563+3xCFiNG8OH++9vcaPtxVu9SuHVCnjp74774beOQRDUktWgCHDrlqBf3VmBk1VcZ1ly7AoEFA586+mxqNa+O5jdpHo9bJeHz/fs/fP3BA/9h/+kkD3YwZQKNGGjSffFJrv+rW1T/0WrX0IFG5stZOFivm+lZYoABQtKgG29KlNVBVrqzbX3WVBuDrrtPnqFULuPFGfX/uvFNv33KLblurltaA1qypr2HUcJYvr69XtGjWcFa4sG5TurQr0FWvrs9xyy3AzTcD9erp/8OocX32Wdc32EaN9H1t0kRrZ5s31/D15Zcazjp1yvo+53S9aZPW9k6bpu/lJ5/o7Rdf1H2heHEtR5s2wOzZvvcr96Zi9gGkKMQAmE9SU/X4ctddwCWX6Jf6WbPy1tpw7Ji2alx3nR7rJ0zQsEgUEXLqlD9/vp6o583TkPbwwxpKnnlGa8qyGxgwdCjw3Xc599kzmguN5kOjRsyoafNuYjXCg9E30NjOX3DMS8BxOIC5c7UZdPRorXWbNEmD1KxZelAZPVprD41AGRen1x06aPhp0cJ1/9NPa+hq2FDD0muvaRPz22/rth99pO9Hy5b6PrRrByxbpuUYMkSvp07V6z/+0Ot167Ivv/f76B28/fX98742PifvAL9ggWu/MV5jyRI9SNapo8G2QwffAe/XX3X7hQtDv88HAQMgmcUAGGQHD2prScWKGtji4/WYGAwXL+p557LLtGVr9+7AfzdCBr5RJPHeKY0TeHKy53ZGc+TOndpk+tBDwJ9/BrcsK1boa8ye7dnXzXu0cKCDO/wFmZwCjnstZ3Z97PwFKyOA+RvUEuygmtN1bge/5LSv+Bps8t13evE+uC1dqvvKlVfqFwfvg97SpVozOXFicPelEGEAJLMYAIPk+HGtjChZUr9wL1wIpKXlz2sdO6ZdXMqV0+Ohrz7axnnL+3hrnF+GDzd3PCYKmjNndKccPDhrp/3z5/W+Vq2AqlW19is/RkkZo1IDHRGa2+1z4u8bmr/Rvt7T2Xj/Ifsb1LFkSWCDSbwf93fgyCnQWn1AOXVK95t77sn6WSUmaofsfv2sKZtJDIBkFgOgSadP64wTZcvql82ff87f13M/T7zxhnbZ+eor13Hd+4v+6tV6/c8/er15s14fPuzZd/zYseCez4gCNmaM7nxxcVl3wn//1Sa8yy4D3nor//o+BBrowrUqPbcB03u6mXD7/7qbMUMHjaxb53n/zJmuQTRheOBjACSzGADz6Nw5rbCoXFlH8y5cmP25Kae5bHPTUtSrl2tQn8Ohg+def137UhtBcOBA1+Pul/79PW8PGKDXPXqE7XGQwll6uo64de9n5r4T7tihAw2uvDJ/pusI10BHgTt8GLjjDuDllz3vnzhRRwr37g3s2WNN2UxgACSzGABz6X//Az7/XINf5craX3ro0KwtMYH2YfbuMrNmjV5//71e//CDqy+4e2Dr1k2vx4/X565QQQf8TZig9xszIBw54nltvM6+fZ63Z81iACQLnD3r+jZiTPNi7IROpw58KFVKm+kYzigvzpzRA3XRonoAN4wcqdPqjB2rk4mHGQZAMosBMIO/GjojuI0cqYPkqlbVgWXvvacD6Yz5XY0mV2NarZ07PZtgjQUHjEBnnOuMwGYsWGDU3BkLF3z3nWcANJ7fWATB/VwZE6PNwXnpq/3TTwyAZIF//9WRuw6HThHyzTeuoLdunfataN3a6lJSODOa9//v/3TEs6FvXx3VbDR7h9kXDAZAMiuiAmAgrTnZBb1evVwrDhnTe02YALz5pk6/UqqUTmnVvn3WplWjj7TRjcmooTPuNwYyGjWAq1bp9dKlem3MSGAEu5xmh/Ce8D85WeeqjYnRKbgCnV3B/bpLF+v7bFMUcTp1Hrfu3XVnjo/Xb0bGzvfBB9q/YvFia8tJ4cn9hBAbq4GvUCFtZgG08/b+/cAvv4Tlt18GQDIrrAOgv5kBvGdS8B4ZO3CgK6D17eu7z9yQITqn6c036/yoDRvqtFjGNFjGfLDGvK9G0+327XmrgQt0WizvwXXefbg/+0ynSHM4chfk9u/X4yFRSCUn6x8soHO6GXOybdumTXb9+rlO2ER5NXasjni74w7tQJ2e7hr95nQyAFJUCssA6G/6MGMGA2OOVqMWz6gtmzxZbxt9zt1r4owAdviwLtNWr54Gqc8+02bVnJbszKlvn78aPH9rzZupgYuP1/6J+/cH/junTmk5uNIIhdSaNa552H78USd7BrTa/b339JvYH39YVz6KDDNm6FyPPXroqivG1EOpqa4pEs6etbqUucIASGaFZQA0GF07/vpLr43J/I1mVWPEq9G/rXt3vT5wwBUAjUA2YYIuF3rNNVrx8OijQNu2OU9rldvRvTlN0xWMptf0dJ0i5pFHAp+LMD1dy3f4sPnXJwrY0qXAnDn688qVuj6i06l/hDt3ap+Kf/6xtIgUAb7/Xg+wO3boN/udO7XPS3q6aw6s/Bhlno8YAMmssA6Ap0/r321srGezrFHbZvxdG7NLGCNjhwxxrRbVpYuupHTFFTqJc4sWOmI23J04of0W+/cP/HcGDtTjIlHIzJ+vVfeA/oFOnKhV8P/9r+sb3pkz1paRwt/y5TrvH6BLxPXvr7WBSUna9cDh0FVgwqgDNAMgmRUWAdBXX79evVwDLoy577ybaf31CZw7V/sANmqkoc/oFnL6tNX/0+BavlzXIfZeWcsfo5sMUchMnar9MADg99+1U26RItoH8NAh/ZbGha/JrA0bdIQfoE1Bjzyiy8MZ4uK0aSiMMACSWWERAA1GhYAxUtZYQMDfyFjji1xqqvblGzZMB3OUKKHTuXz0kVY6RLIvvtBVkAJpCp49W9d+JwqZb7/VP2BAR1A9/7x2wAW0uS4+3rqyUeT44w9t+gH0y0XhwnpCMPTvn7vF1W2AAZDMCqsAaCxfNmeOXh886Nnk6z6IKz1dt3vzTeDaa4GCBYFatXQ1qXnzoqdS4fRpXURh1Kict/3xR60dJQqZgQM16AF6Ai5b1tVUt369q9aGyIy9e7XZCNCDf7lyusSgYfhwDYZhhAGQzAqbAHjmjGsQx8iRvmv+EhK0W0ejRsDll+uceK+8oueQQ4es/h9YZ+5cPd7lNMBj7VodDEMUMu5NbxMn6h+tMRTdfYAIkRlGs5HRFPLQQ7p+pmHcuLDr/8IASGaFTQBcudK1eoZ38Bs0CHjpJeDSS4FKlYDmzbU269w5q0ttH88/r/PqZmf7dl3fmCgkLlzQP+STJ/X2E0/oidk4Sc+dqx18iczy3tc++kgnGTdMmwb8/LM1ZcsjBkAyy9YB0Bj8MX++zt1nzO+3aRPQqZP2WXvoIR3o8MYbOtL/wgWrS21P27frhNbZDQg5cEBrWaOleZws5l4rs3+/rtLQqhWwdav+4ffrp32zwmyJLrIp99rmPn30xHHxot6eN09rDcIIAyCZZesAaDDW0TXWwe3VC6hZEyhdWpd2jPSBHMHSvLnWBPpz9mxYzodK4WrfPle/rD59dPJNY5QX4Fo/McxWaCCbio939TedMEFHA65fr7cXL9aahjDCAEhm2TIAuq/0MWKEa7qXESOABx/UmqzXX9dgSIE7eFDXM16+POtjTqfWoHbpooPlWOlC+c69z8Gtt+qwfqOWJj3d1emXAZCCwX3E+ahRwH33uSZKXbFCVwsJIwyAZJYtA6DBmPYlPl7X5a1aVWeI2LXL6pKFr86dtdncH1a6UMgYc7P9/jtQvLjOXt6vny7tY1RHc2ekYJk61dXPLz5e5wZ76SW9vW5d2I2AYwAks2wdAFevdq3dW7iwthaxf5o5x49r07m/+f7GjeM5l0LEqHX58kvgtdf0viFDtGbw4EHWAFJwua8606uXdiK/9FI9qWzdqiMKwwgDIJllqwDo3vQ7eLDWVt13n04N1qQJzwPB0rEj8Nhjvh+bPZvnXAoRYxmuqlX1GtAleRYv1kWye/QI/kLZFL1mzdIpI4yl3yZPBkR0JZqdO3VOyjDCAEhm2SoAGk6c0JDy6KNaWzVsGM8DwXTkiPYFXLky62PGsnoMgJRvjG968fG6+HapUlo743TqXIBr14ZlkxzZnDHRqTH6PCUFqFEDWLhQR6H37Gl1CXOFAZDMsmUAnD4duPtu4KqrgNatGUbyQ5s2wLPPZr1/wwYGQAqRsWP1D/3tt133zZih30yWLOGyNBQcxheOSZN0EfgpU/Qgt3Ur8OKLumD80aPa5BRGfYwYAMksWwRA96bfgQO15q9UKe0Pzpq//LFvH1CkiC6RCbg+g2nTdCQw33PKd/Hx+oeekOC6b9484IcfdAWQpUstKxpFoJ07Nfh16+b6lutw6HqhxqCjMPrmywBIZtkiABqOHNGl20qUAD7+OKz+FsPSm28CTZt63nfypB4HjdW4iPJFejrw4Yc6+tdYnQHQTvoLFuhoJGOONqJgOHLEcymp1FTtF3jLLbo/du4MHDtmdSkDxgBIZtkqAPburbVSEyeG3ZexsLRhg06Gf+SI6770dCA2NrrXTqYQOHIEuOceoE4dzz/0n37Sk7L7pL1EwWDU+KWkuE4wO3boFBPnz2sfwP37rS5lwBgAySzbBMAdO4AKFXSiZ2ONXzZD5r+HH9a5d90NGuRqGibKF5s3A2XK6BqO7gFw9WodndmtG7+FUHAlJ3suIp+YqJdLLtG5KAcMCKtJZhkAySxLA6B737977gGuvlpH/2a3Xi0F14wZOtgmLc1136RJeh4myhdOJ9CunTb/Dh3q+U1v40a9j00AFCzuJxpfNQt16+pBb8QIHRgSJhgAI1+ciGwWkRQR2Scik0Wkag6/U0REBovI4Yzfm5fN79iiBnDyZG36XbmSx/1QO3cOqFTJNT8qoF2wFi60rkwUBZ57Dnjiiaz3b9umM797V0sT5ZcPPgC++kqniAmjfqcMgJGvm4jUEZFCoh/yJBH5LYffGSwiG0VDX0kRGSciG/xsa3kAPHUKKFdOpyRh0681vvoKePll1+2ff9ZVk4jyRXq6rsAwdGjWx3bv1m+BQ4aEvFgUpQYNAp58Uucf8zU5qk0xAEafW0QkTURK+3m8qIicFpFn3e4rLyLnReQ+H9tbEgDda+Tr1weuuIJNv1ZyOrUG9sABvZ2crJNvE+WLdeuA//zHc/SRYf9+DYATJ4a+XBSdli8HLr9cayAWL7a6NAFjAIw+X4rIrmwev1k0IF7qdf8fItLcx/aW1gBu2gQUKsQuP3bw2GOuifD379dVuIjyJKc+V59/DtSu7ft3jak65s0LXXkpuh06pEvCJSR4zklpcwyA0aWeiJwUkcez2eZ+0QBY1Ov+X0WknY/tLQ2Ad98N3Hmn65jPAGid8eOBm27Sn405Uc+etbZMFOaMaTeMP2wjGNaooSsweAdDp1NPwA4H0Lcv+4JQaKSn65qjY8ZoM3CYYACMHs+KyDEReT6H7cKmBnDhQqBoUeDLL9n3zw5OnNBBmfPn62fQtSsweDA/E8oF95q/ESP0j9rh8Ozb8c8/QMGCwGef+f7Gd/Gi/g6/EVKoOJ3ANdcAzZrp4KMwOegxAEaH10XDX70AtvXVB7CCiJyTbPoANmvWDK1atUKrVq2QlJSU7ztuejpw441AgwY8ztvJq6/qGsEAm+XJBKMK2VeQGzECqF49+50rNpY7H4XWa68BzZvbfr9LSkrKPFc3a9aMATDCNRcNf77Cmz+DREf9XiEipURHAa/3s21IawCNCoIOHXS5N18VBGSdhASgWjWdE3DyZNsfC8muli7VnWfgwKw70dNP6/Qv2e1cixdz56PQ6tgRaNgwrPY71gBGvnTR2rsTGZeTGdfugfCkiLzmdruIiMSLyL8Z2yaISBU/zx/yJuD0dODaa/UccPx4WP29Rbzz54Hy5XVQ3Lx5/Gwoj+LjdeeZMMFzJzpxQoebt2iR/c7l3XeQKL9NmADcfntY7XcMgGRWyAPg/Pla+/f11+z7Z0cffqhdYRYtCqtjIdlJXJyrBrBfP9cfuMOhcz517qxNwf7+8BkAKdR+/VW//YbRfscASGaFJAC69w2vWRN4/HE2/drVwoVAlSrAihVhdSwku0hL04DncABz5wI//OB6rHFj7WfVr1/2z8EASKF25IhOBdOmTdhMf8AASGaFtAZwyRKgcGHgxx95fLerrVu1htbhALp3Z+0s5YL7NC7Dh+ts4sOG6f3nzulUG999p4/5+/3s5lN4PTkAACAASURBVA8kyg/GfleqFPD++66pEGy+3zEAklkhDYB16+pl3jwe3+2scWPgo4+0KxdRrhw6BHTrpj8vWwbMmaM/L1qkVcurV3OVD7Knu+4CXnqJNYAUNUIWAP/8U1d/+vRT1vzZ3fTp2lRvrAxCFLA//wS++UZ/XrUKmDZNf27aVDuXLl3qCoVEdvLGG8DDDwMnT1pdkoAwAJJZIQuATZsCN9zApt9wcPKkTtLdvLl26SIKWHKyq4l33TodXZmWpmutLl6szWuLFllbRiJfunQBbr4ZOHrU6pIEhAGQzApJADx/HihbVleXYAAMD888o+sDnz5tdUkorKxb52ri3bwZGD1am31Ll9YDwdSpWjNIZDdTpugo9UOHrC5JQBgAyax8DYBG39pPPgHKlAEGDAB699ZJhtn3z96GDtUFGw4ftrokFFZ++gmYNUt//t//dEdq2xZ4/XW979tvgU2brCsfkT/r1gGXXALs22d1SQLCAEhmhaQG8I47gHr1WPMXTnbt0iVbt2yxuiQUVr7/Xr/dAcDu3fqt7/rrtWMpoHMD7txpWfGI/Dp6VKeC2bzZ6pIEhAGQzMr3APjXXzr4w9/a72Rfl17KkcCUSzNn6lIygNakfP65dig1OtbHxQEHDlhXPqLsXHJJ2AxSYgAks/I9ALZrB1xzDfv+haP69XVWBKKATZigTWmA9h+oXx949lm9feGCHgjCZJQlRaFq1YD+/a0uRUAYAMmsfA2A6enap/aTTxgAw9HXXwOVK+vnSBSQ4cNdS/ykpABVq+qyb4Au/t25M4eWk33dcQfQqpXVpQgIAyCZlS8B0Bj80aWLtv706sXBH+Fo1iygSBFg2zarS0Jho18/7fcBaB/AAgVct/fu1QMBkV0980zYNHswAJJZ+VoD2LgxcNttwJkz+fL0lM+WLgXq1HHN60uUo9hY19DxIUO0Sc04vvzxh95HZFfvvacrgoQBBkAyK98C4IULQEwM8NZbbPoNV6tXa4h/7jmrS0Jh4dw57ethTB75xBPAU0+5AuGGDcC4cdaVjygnHTropOVhgAGQzMq3ALhoEVCyJNCxIwNguPr9d6B9ew3yFy5YXRqyvWPHtI9ferr29ytcGPjqK9e8asuX6yhhIrsaNkynrTh/3uqS5IgBkMzKtwDYuDFw770c/BHOdu7UAXFlygBr1lhdGrK9ffu0wy+gqyrcdJPOA7hrl97nPkcgkR3Nng0UKgTs2GF1SXLEAEhm5UsAvHhRQwOXfgtv//wD9OgBvPCCXhNla/t2YPBg/blRI21OGzpUO5MmJekk0P36AYmJHA1G9pSYCFSpEhbrVTMAkllBDYDG6N+vvwZKlNBjPUf/hq+UFA3w/ftrdy6ibG3cCIwZo9/4SpUC1q/XtYCNlRXGjOE3QrK3xYt15OLQoVaXJEcMgGRWvtQAvvGGTqd06lRQn5ZCzJi3d/VqnSD/3DmrS0S2tmoVMHWq1qJUq6Z9ASdOdE0MPWgQAyDZ29KlwJNPAl98YXVJcsQASGYFPQCmpwPlywNvvsnjfCTo3h04eBCoWBFYscLq0pCt/fADkJAAfPCBzv4OANOmaTAEdBk4BkCys5Urgf/+NyzmAmQAJLOCHgDXr9fJn9u353E+nBnN+d27a8XNAw/ocZHN+JSFsbMMHgz06aPfALt31/vnzNFaFWOKGAZAsrNffwVatwZuvdXqkuSIAZDMCnoAbNsWuOEGHucjxbBh+ll+840u60rk16RJQNOmQLFiwNmzel9iIrBwoc4FGBvLAwPZ2/r1QLduOveVzdfAZAAks4IeAG+4AXj7bR7nI8X48fpZrlmj8zpyPkDya9Qo7T9Vr57rvh9+0H6AU6dqE/DIkRwFTPa1aZPWZIu4JjC3KQZAMiuoAXDlSqBgQR39y+N8ZJg507W4Q+nSrv78RFn07Qtcc40GPYMx+fOGDcDYsdaVjSgQycnAiBFApUo6+g1wdXFITLTViY0BkMwKSgA0/j5atACuuAKYPt0Wfx8UBEuWuGpzn36a6wKTHxcuaMffwoU9Zw3/9VedFHrZMmDWLOvKRxQIYy7LunV1/jJ3qam2atpiACSzgloD+NhjwKOPurr/UPj77TfXMS8uDnjxRatLRLZ0+DDw7rs6AeiZM677f/tN1/+dN0+bg4nsbPduXb3m9de1z6q706cZACmiBC0Anj+vc8V9+KFt/j7IBKNWd/p0Xd41MVGb9suVs33faAo1p1Nr+R59FLjrLs8msq1btdls4kSuJ0j2t2ePjmTv0AFo0sTzsW3bGAApogQtAK5YoZP/d+xom78PCoKzZ/WYd+aMzuRRrJgeB4k8rF4NXHst8O23nvc7nTqP0JAhwP/+Z03ZiAJ14ICuezl2LPDQQ56PbdzIAEgRJWgBsH174OabbfX3QUHSqxewd6/+/NBD2keayMP8+UCRIlm/Hfz1l1Yd9+ihi0sT2dm//+oi9suXa4d2d2vW2OoExwBIZgUtAN5+u06ebqO/DwqSUaNcy7m2bQu884615SEb6tFD+4CkpXnef+CAnlCNoeREdnb8uO6re/YABQroyczoD2OsZb1ggS1GOTIAkllBCYDr1unfSocOtholT0Eye7YO4gSAuXN1rkciD2++Cdx5Z9b7jx7Vk2bXruw8SvbnPtCjWDHPbgsrVrj6w9gAAyCZFZQAOHOm1pZ//32Q9myyFfcZPA4e1LB/7Ji1ZSIbSU8H7r5bR4B5O3VKT5oDBoS+XES5ZSxZePo0cP31Wttn+OEHfcwmBz8GQDIrKAHwww918v+NG4O0Z5OtbN6szcCGq6/W1b2IAAAnTwJVquh0L97On9eTJieBpnCQnq77a0oK8OyzQHy867HERH3s4EHryueGAZDMCkoAvPZa4I03gEOHgrRnk63s26cDQQyNG+vUMEQAgJ07gUKFso7ydTq1WcDhAHr2ZN8QCg9du+pgkE8+AVq2dN0/Z47uy3//bV3Z3DAAklmmAqDTqeu/FywItGljm76xFEROpw7wdDiA4cP1HN60KfDgg1aXjCxndI6PjQWKFtUdxdcBIC6Oo8MofMTF6eClAQOA55933T99uu7HO3ZYVzY3DIBklukawClTtAaQx/fI1rOn6zNeuxYoWzbrgE+KUp99Blx5pf8DQN++PEBQ+OjTR0cBJyQAtWu77p80SffjrVutK5sbBkAyy3QA/OgjoEEDHt8j3YgRrs+YE0KThyeeAO65x/8BYMgQHiAofPTvr0vCJScDxYu7Rq8b08Bs2GBl6TIxAJJZpgPg9dcDH3/M43ukmzrV8zO+/349HhKhRg1dJNrfAeDff3mAoPAxeDCwfbtO9yLimsB8+HDt/Pzrr9aWLwMDIJllKgAaU4J89RWP75Fu3jzPz/jzz33P+kFRqEQJ4P33/R8AUlN5gKDwMXy41v4BOrp95Ur9OT5em4d/+sm6srlhACSzTAXA6dOB664DvvmGx/dIZ0yBZXzGM2bo0n8U5Y4e1VqSNm0YACkyfPstsGmT/vzAA8D48fpz374aDhctsq5sbhgAySxTAfCNN4BHH9W13rkCSGRyXwUpLs71Ga9cqaO/T5ywuoRkqVWrdAk4XwHP2HkSE3mAoPAxfjywfr3+/NZbQKdO+nNcHDB5so52twEGQDLLVAC89VZtBvzttyDv2WQ7W7boOdzdFVcAS5ZYUx6yAacTaN1ad4QRIxjwKDJMmQKsXq0/d+miyxymp2v/v3nzdOkrG2AAJLPyHABPnNAaoM8+s83KOJSPdu/WwXHuXnkF6NbNkuKQXXz2GXDbbVaXgih4pk939fubOBG4917XijZLlmhAtAEGQDIrTwHQ6dTa8AoVdNJ0fvGPfAcPAt27e97Xrx/w3HPWlIds4vnndcksokgxZ44ugA4Av/wCVK7sWtN67VrbLGvIAEhm5bkGsEsX4OGH2bc7Wpw8qZ/1hQuu+1at0i8BxjRZFIVq19bJQIkixfz5wOLF+vPBgzrIac8ebQLeulW7O9gAA2B0aCQiy0UkRUTSRKRgDtsvE5FzInJCRE5mXH/kZ9s8B8AnnwRef50BMFpcvOhaI92QmgoULqyD5tjPPwqlpwOlSmlzAFGkSErSNawB3cdLlgSWLtX9fMcOnQ7GBhgAo8PjoiGwiQQWAJeKSOcAnztPATAtDShdGvj0UwbAaNKjh2tOVMPddwMTJnCmj6h0+LDWjkydanVJiILnxx91sIfh5puBUaN0Gpg9e3QuQBtgAIwuD0ngAbBLgM+ZpwC4ZYvO/NChA0/60WTgwKzroH/yiV7OnuW+EHVWrdJFoTkUnCLJTz8Bs2a5bjdsCLRrpzV/hw5l7QxtEQbA6JKbAHhYRI6ISLKIxIlICT/b5ikAxsZq15/u3dnsF01GjwY2b/a8b8IEoG5dHSzHABhlxo0DatWyzdJYREGxahUwbZrr9mefAY0b6yTQx4/rgc4GHZ8ZAKNLoAGwroiUyfj5JhHZICJT/GybpwD49tt6mTgxn/ZssqUpU7Ke6//4AyhalKvBRKX27YH77gN+/93qkhAFz5o1wKRJrttDhuh+PnasrZo6GACjS6AB0NfvnReRoj4ey1MAvOEGbf5duDCf9myypblzs7b2paUBZcoALVrY5rhIofLqqzoFzK5dVpeEKHg2bNDabUNSEnDllboKSFpa1tFwFmEAjC55DYAPigbAYj4eixERNGvWDK1atUKrVq2QlJSU7U534gRQoIDW+HAFkOiyeDGQkOB5n9MJ1KkDPPOMdglgd4AoctddGgIPHrS6JETB8/vvOujDkJyszRzTp+vtbt20L6AFkpKSMs/VzZo1YwCMAgVFa+/qiwbASzJuF/CxbSUReSJjGxGR2iKyVkSm+3nuXNcALlsGVKkC9OwJ7N2bj3s62c7PP3t2jTF8/rkuC9i3b+jLRBaqUgV45x2dJJco3BlrV0+apCHP+Da7caOOdp8wQbfr3dsWJz/WAEaHt0QkXTT8pbn9/KCIXCE61999GdtWE5HVInJcdP6/7RLkQSC9e2urj8MBnDuXj3s32c7GjcCYMVnv//ZboFKlrBNFUwS7cEHXgmzZUpvFiCLFtm1Z+7OULAkMGqQ/DxwI7NxpTdncMACSWbkKgE4n8OCDQKNGXAIuGm3fDgwenPX+n3/WbgHt2wP//hv6cpEF9uzRD52TQFOkcTqzBsArr9STHqCjgbdts6Ro7hgAyaxc1wBWr84Rn9Fq716tAfa2caNOB/fJJ1nnCaQI9euvQMWKvr8REIWzAwf0BHf6tOu+224DWrfWn8eM0YOexRgAyaxcBcBDh7QrBOd8i07HjulymN5TYK1c6RoPsHatNWWjEJsxA7j+ep0agyiSnDmjJ7h9+1z3PfYY8N//6s+TJwOrV1tTNjcMgGRWrgJgYiJQsyYwbBgDYDQ6d04/9zNnPO9fuBB46y2dKstYQ50i3IABwAMP+B4VRBTOjHUt3We9f/FF4Omn9eeZM4EVK6wpmxsGQDIrVwGwc2ft/9elCwNgNEpP11VgDh/2vH/WLO0WULmya6YEimBOJ/Dyy8BDD2mfAHYGpkhgjAJOTNRpLkaNcu3Xb78N3HGHbpeQAPzwg7VlBQMgmZerAPjcc9rRv3dvBsBoYxwbu3fXwXDu5/wJE3R6oAIFOBVM1HjtNV0eiwcCikRLlwKzZ7tut2gBVK2qPy9cCCxYYEmx3DEAklm5CoCVKwNffqmtP1wDODoNHZr1nD90qA6Kq1lTvyhTFHjwQeDDDxkAKTL9/jswYoTrdtu2QJEiOuXRsmWe4dAiDIBkVsAB8PBhHQDy7be26P5AFhk7Nus5v08f4JdfgEcf1VwwfDi/HES8q68GPv2UAZAi04ED2txhjHjr2lVPgFOm6EmwRw/LD3IMgGRWwAFw8WLgqqv0ZP/nnyHYu8mWEhM9z/np6do39OhRID4euOYaZoKIl56uS2O1bMkPmyLT+fOea/526QKUL6/THKxebYv9ngGQzAooADqdwLvvAnXr6n6fkMDanWi1ZYvnse/0adeqMGvWACVKAJ06ZT02uvevZveBMGc0B3z9tS1OhET5YsAAXfHj4kXdz2+5RUe8/fabLfZ7BkAyK+AawNdeA5o1s8V+TxY6flz3AWPFj4MHddlMQPeL//xHJ4T2t48YMyxwHwpjc+dq0o+LY5qnyGN8W/3mG73Mm6cHrUcf1VCYnGyLgxgDIJkVcACsVUtrdmyw35MF3GvwunXTkb9JSdofdMAA13bXXgu89JL/fWTuXO5DYW/+fKBGDd0JiCKV0d/l4EG9btoU+Pxz7QNlg4MYAyCZFVAAPHVKp/jo188W+z1ZLClJuwEAOlhu1CjXY6+8ol0F/O0jXEYwAgwbpnOi2WAqDKJ8M3++HqymTdOOzk2a6NyXa9f6nhE/xBgAyayAAuCqVUClSjrHG0/e0c3p1IFwPXpo69+332oN4E8/aTBs1gyoVs1/q2CPHtyHwl779sAjj+jQb6JItXevHqxGjtTrsWOBe+8FTp7U20ePWlo8BkAyK6AAOHgw8Pjjus/z5E1nz+oXYodDK4N69XIFvvnzgUKFtK+gO6cT+P57/R337dltLAw1aQI89RSwfbvVJSHKP0aH5Rkz9Hr8eK0JSUzUA+DMmZwGhsJaQAGwUSOgYUOdCmnECJ68yTUh9OTJnl8K0tKAYsV0H/FmrCXMrmNhrl49oEED10ggokhkBMCUFL3eulW/3aalAf37A7t3W1o8BkAyK6AAePfdWmvjPjE6Rbfdu101wt61wjfcoDOEeDtxQrcdPDhkxaT8cMMNugzcxYtWl4Qo+LznrEpI0APXhg06/dGBA3oy3LrV0mIyAJJZOQbAtDSd8WHsWK3xJgJcX463bs0aAF95BXjyyay/c+iQbhsXF7pyUj4oXx747DOrS0GUv3xNXlqqFDBnDjBxog4GsRADIJmVYwDcsQMoXFgHQi1bFsK9m2zJ35fj5GTXNj176kAQb3v2ALGx7EcatpxOHflboADw1VfsC0LR56abdF7A2bMtPyEyAJJZOQbA2bOBm2/Wk/3vv4dw76aw4Gti55UrNSOcOuW57Y4dulxct25aG0hh6J9/tBmsfXumeIo+Tz6pHaAXLvTd0TmEGADJrBwDYOfOwOuv6/Qd//wTwr2bbM3f0m4//aSTPZcsCXzxhWcl0ZYtum18PCuNwtZvv2mfEFbjUjR691398rNihY4OthADIJmVYwB8+WVdB9tY75UoJ+npwPXXA/Xre2aE9et1JoXx4/VnCkNJSUDlygyAFJ06dNBpkDZsAMaNs7QoDIBkVrYB0OkEqlYF2rTRKWDY5YcC1aABULu2Z0ZYtQqYOlX7UC9dalnRyIyxY3UZOAZAikbDhuk32//9T5uCLcQASGZlGwDPnAEKFnSthc3jPQWqTRugTBnPfWbJEg1/xjWFoR49tCM8DwgUjRISgBtv1BFtffpYWhQGQDIr2wC4bp2exI01sXm8p0BNmqRjBfbudd33/fdag7xuHSeDDktOJ/DCCzox6PDhbBKg6LNhA1C2LHDkiPaNSk+3rCgMgGRWtgFwzBjggQe0zxYDIOXGjz/qdHFz57ruM5p+t28HBg2yrGhkxssv60ogFp74iCxz8KB+sz12TE+KZ89aVhQGQDIr2wDYujXw8cfa6sMASIEwRgePHQvcequOIDcqiaZO1X6ABw8C3btbXVLKk/vuA/7v/6wuBZE10tJ0Ytzt27Vj/JEjlhWFAZDMyjYAPvGETurLyXspt/74Q1cEeeYZ133jxmkYnD9f9ye7tSI64UQSkpCIRIzESCQiEUlIghM2KJxd1KwJNGtmdSmIrHPllToJdN++wN9/W1YMBkAyK9sAeNllQLt22tfVfa43O5ysyd727weaNgUqVnS1FhrLZ6anaw2gXb9UpCIVDjiQChsWzmplymjfJ6Jode+92sl56FAdDWwRBkAyy28APHFCuzpMnKiTnhPlxokTwNdfA4UKAbt3633x8cDOna6fGQDDzPnzelAYMcLqkhBZ55VXgF69LJ/QlAGQzPIbANesASpU0C85W7dasHdTWEtL04B3663a9w8Aevd2jQoeO9a+AfA0TjMA+rJ3rwbAhASrS0JknZYtgU8/1ZVAVqywrBgMgGSWzwDodAKffaYT+TocOnqTTb+UW717A2+8AXz+ud6OjQUOH9afZ860bwDchV1wwIFTOJXzxtFk3TogJkbX+yOKVr166Wh4o0+URRgAySy/NYBffgk0amTfkzTZ37BhQLduwIMPAhcv6r508qQ+tnixffetTdgEBxzYh31WF8VeFiwAqlTRIEgUrfr21bUuR47UUZIWdY5nACSz/AbAZ58Fmje370ma7G/iRGDKFOCSS4CUFN2Xtm1zTRMTF2fPgUU/42c44MBWsO+Dh9GjgVq19EMkilbLlulI4F9+sfQEyQBIZvkNgFdfrSOAGQApr+bM0Zq+kiW1q4z7xPlOp30ng05CEhxw4Gf8bHVR7KV7d+C224C//rK6JETWcTp1LsDffmMApLDmMwCeOQMUKMD5/8icH3/UlUAeflhbTXr2dD128KA2D4diQYlA5/cztotHPBxwYCiGch5Ady1a6BQY//5rdUmIrHPmjA6G+vlnBkAKaz4D4G+/AaVLA507MwBS3q1erdNlffEF0LgxMGCA67GzZ0O/klIykuGAAwlIyDYIjsM4DMVQTMGU0BUuHLzyii4DZ+HyV0S2ULasjoZnAKQw5jMA9u0LXHedNtmNGGHPflpkf8nJutrH9OnaZ3rYMM/Hu3cHDhzIv9f3rvmbh3lwwIH1WJ/tNC/xiMcCLMAQDMm/woWj++4DXnyR6wAT3Xij5XNZMQCSWT4D4NdfAy+9lPWETZQbf/+tq8j89Rfwn/9oGHQ3aJAuqZnfjImdf8APcMCBb/BNtgGwO7rjd/yObuiGdDDsZKpRA/jgA6tLQWQtpxO4/Xbg4481AC5YwFHAFJZ8BsAXX9R9e+bMkO7PFGGOHdNuBBcvAuXK6c/uJkzIvxlF3Gv/RmAEHHCgC7rAAQeWYRkccOAQDmX5PSMspiCFcwF6i4kB2re3uhRE1nvnHaBtW9YAUljzGQBr1wbatOF8r5R3Tqd2HXA4tCb51luBhg09vyTPmaMDRYL6ul7BbxzGwZHxLxGJHuFuGZZl+f1DOIRYxCId6eiDPtiDPcEtYLg6e1Y7vsfHW10SIut16AA0aaIHOB+zaIQCAyCZlSUAXrwIFC2qtTXJyZbs1xRBevTQY2STJtqFzN3SpRoCg8G7v98czIEDDvREz8wAOBdzMRIjkYAEOOBAP/TL0sS7EzsxEAMBAKMxGpuwKTgFDHd//QUULAhMm2Z1SYisN3Qo8MQTOpWBsbxRiDEAkllZAuDOnUChQhoAD2VtISPKlUGDNAB266bNwO7jB9avB8aNM/f83sHPCHdGP7+DOJgZAI0+f1uwBa3RGh/hI7RAC3RBF8QiFjMxE4lIxGiMBqCjgUdhVI7Tx0Q8p1OHcMfE6Pp+HBVG0W7ePOCmm7STs7HAeYgxAJJZHgHQ6dS5/6pU0ZP2/Pk8zpM5U6fqvtS7t1YgjRnj2qeczry3KPoLfrMwCw44Mkf8HsdxNEdzPINn8AJewFW4CkVQBAJBCZRAOZRDDdTAdbgOlVAJBVEQRVEU1+N6PI2n0RRNM58rGVFcJT5vnq5+wHmhiPTba7lywMCBWmtiAQZAMitLDWD//sAjj/A4T8Fx4oTuS7GxwOWX68wJgIa/WbPMTzVkDNpYgRVwwIH+6I92aId+6IfbcTsqoRIKoRCuwlVohEYYjMHYhm04h3OZg0FmYVZmDV884tEHfTAWY/EUnkJxFEd1VMdjeAwHcTD4b1C4GDFCOwfzwECk81cZfWItWhqRAZDMyhIAP/4YePVVHucpOFJTdV9yOIC779b9y9djOe1rvlbz+B7fYxRGwQEHBmAAGqERXsSLKIzCqIEaqIu66IzOHgHPvQn3LM7CAQeGYEhmE/EUTMGv+DXzNdujPRqhEaqhGsqgDLqje2ZTcqArjESErl11GTgeGIiAtDRdDq5nT2DjRkuKwAAYHRqJyHIRSRGRNBEpmMP2ZURkkogcE5GjIjJBREr72TZLAHz0UeCjj3icJ3OcTq3RS0zUyqNhw4CXXwZuuMFzu7i43O1rRo1fKlKxERvREi1xG25DDGJQFmXxHt7DR/gI8zAvx1BmPNdojIYDDpzBGQzHcGzFVgDAaZyGAw7sxV50QicMxEDUQR3UQi2swAqfZYpYH36oy8DxwECkqlXT0cBr1ljy8gyA0eFx0RDYRAILgAtEZJGIlBWRciKyWETm+Nk2SwCsUsU1vyWP8xQsqalAq1Y6IfTJk677hwzJ3b62AAvwJb5EEzRBRVREcRTHHbgD8YhHJ3TKcZk3jzJlBLd1WAcHHBiJkeiCLpiGaUhCUubScca0MSMwAhdwAX3QB5fgEsRDOzCuxMrMfocRWRPodAJ16wJPPQWMHMlBIEQAcM89QMuWwIoVOW+bDxgAo8tDknMArCYi6SJyo9t9N2fcV9XH9h4B8ORJ7dbQrh0DIAWX0dxbtarn3H8zZuj9yec8m1MnYzKGYRimYEpmqOqJnqiDOiiEQqiDOngRL2IVVgW0vq87fwNIuqJrZiB0f3wiJmaOJO6JnhiKoWiGZohBDB7DY5mPTcKkyK0JvOUWz/Z7omj38ss6v1WwJzMNEANgdAkkAD4vImd93J8qIs/6uN8jAK5fD5QsCUycyABIweHeFDxyJPDQQ8Cbb7oqj5Yv99zXvJtTz+AMXsWruBf3ogiK4Ck8hY/xcWboyk3w88d4zYVYCAccOI3TWnavoGhMLbMJm+CAAwMxEJVRGQ/gAbRBGwzCoMgNgJdfru31RKQ+/VRnt09MtOTlGQCjSyAB8A0R+cfH/QdEpLGP+2NEBDNmpCApCejYFGVIcgAAIABJREFUUbs1jBnDlh7KH0OGAI895gqG332n4wuMfS3R+QcccOAETmAsxqIGaqAkSuI1vIY2aIPZmO0x3YuZsOUd8HKa7uU3/AYHHBiLsXDAgfEYj33Yh/qoj0qohC3YAgcckbl6SLFiwPTpVpeCyD569QIefjh4s9nnEgNgdAm0BvCMj/uzrQFcs0YDYOPGwM036/QcDH6UH7ZsAS65BDh/Xm+fPq01gGfOAClIQQd0wHN4DhVREZfiUjRGY7RHe/RGb48aP6PZNphz8+U0mMMYNbwcy+GAA1uxFUlIQgIScCtuRQ3UQFu0RT/0i6y+gKdOad+Q33+3uiRE9jFxok4GPXWqJS/PABhdAu0DmCZZ+wCmSTZ9AF98sRnefbcVrryyFW6+OYlNv5Rv0tJ0/tTpv/6dWfvWtd9JTN69Cu/jfVRABZRHebRCK3RER4zBGDjgwAzM8Ahn+THyNqfnNB43BoW4TwczD/NwC25BLdRCR3T0GU7DdtqYzZuBAgV0PWAiUsuWAZUrAxMmhOwlk5KS0KpVK7Rq1QrNmjVjAIwCBUWkqIjUFw1yl2TcLuBn+wQRSRKR8iJSQUQWishsP9vGiAiGD09Bnz46Avill9j3j/JXgwbaegLosmyfTV6LJ3/phLIoi3fwDjqgQ+aAjGM45hG6kpEc9BAVaDAzRgX763d4AidQG7VRH/UDCpK27ytotNN37gyUKsU+IUTudu7UaQ1GjLDk5VkDGB3eEh3Fm5ZxMX5+UESuEJGTInKf2/ZlRGSiiBwXnQtwvPjfQWJEBIcO6SCQ8uWB995jAKT81acP8NxzwHIsx7W4Fk/82BNfz1mD9miP2ZiNkRiJOZgDBxxYhEVBG+yRV7mpuduBHYhBDF7AC5mDSbyFTQA0dOumNR08MBC5pKZq14ju3S15eQZAMiszAKak6L785Zc8zlPg8tKsOXfNfhQpexKXpJXEy8426DBpG7r0OgvH7A1ISLyApCRgifMvy4NfXiUgAYVRGDMx0+fj27E9vALghx8CNWvywEDkrUIFHQ1sAQZAMitzFPDgwdrK06kTj/OUe4HUap3CKTRDMxS5cAn+U+IMPtw0GAMwAI4jA+DochGO6Zux6Vzwm3hDLRWpuB/3oyqq4iyy9pubgilwwIF/8I8FpcuD558Hbr2VBwYib7fcArz+uiUvzQBIZsWICDZsSEH79voln9O/UF5kFwDTkY5JmIQqqIJ7cA/WYA3qPXEBTw5I1KlT0h2I7Z4GhyMdKREQMpKRjA7ogKqoiofxsEeITUUqYhELBxxIQpLVRQ3MvfcC99/PAEjk7ZlngCeesOSlGQDJrMyJoHv2BF55xZL9mCKAMUDCe5DGaIzGbbgN5VEeX+ErLMACjMRINOz5C657fhsmYAJGYiR6DjsGx+zfsOlc8KZ1CTXv5vD2aI/CKIwxGJO5zSZsypxQOhaxGIER9q7lTE8Hrr9eT3IMgESePv5Yl0m8cCHkL80ASGZlBsAPPgDatAn5PkwR4AIuoDu6wwGHxyCOx/E4iqM4PsSHOIZjAFxz6X2x7jsUjTmLUxc0VEyachEOByKiBtDwE37Ck3gSFVER3dAN/dEfndEZPdADvdAL3dAt6HMZBpXTCSQk6Pp9773HpgEibz166Bek074HfOUnBkAyKzMAPvaYNv8S5VYyktEf/eGAA2MwBu/jfVRDNVRABfwI1zqZ6UjHaIyGAw7MuZiAYmXP4LvVu5CEJAxN2gnH6L+QcMHGtWG5lIpUdERH1ERN3I27cQAH4IADB3AAALAMy+w/GGT/fqBMGV2zj4g8TZmi86cdPRryl2YAJLMyA2D16sCSJSHfhykCTMEU/IAf8DW+Rj3UQyEUwrN4Fu3R3iPcbMEW9EGfzHn9ajVMRqvPddTvmDG61GwkVTIZ/SLboz0KoRA+wScege8Ijth/MMi2bTrXWSR8IETB9vPPOnryn9D/DTMAklkxIoLDh1NQsCDw118h34cpTBn93eZiLhxwoBd6oSIq4kbciGZolrlurrFc2gIsQCxi8S2+hQMObMImPD1oAR6tlwYA2L4dGDzY4v9UkHj3BZyO6bgf9+NG3IhO6JRlNRNbDwZZtEjnhzp1yuqSENnP33/rKjkWfEFiACSzMkcBFykCXLwY8n2Ywox3uBmAAXgEj6AIiqABGmRO4Lwe6+GAA/uxHwCwDuvggCMzGCYgAV22TUORYhcx7+wirDv0J7p10zEHkSYVqWiLtqiCKmiIhpkB0Bg4Y+vBICNG6OLNRJTVhQsaAC1oPmMAJLMy5wG87rqQ778URryD30zMRHM0R1VURQVUwHRMRxKSMBmT0Ru9Mwc89ERP9EKvzKXdJmJi5vx+36cn4dLLL+DHH4Hz5wGHIzIrmoyg9yW+RGmUxiiMwjAMwxRMwQiMQBzi7DsYpEMHoFo1q0tBZF9lywLjxoX8ZRkAyawYEUHv3il4+umQ778UBryDXwIS0Amd0AANUBiF8Tbextf42udAhl/wC8ZhHBxwYDiG+xzw0KSJrj4DAL17A3v3huJ/FRre790CLMAtuAXv4l2P7ZZiqX0Hg7z7LnDnnVaXgsi+atYEYmND/rIMgGRWjIigadMUtGgR8v2XwojRX205luMG3IDyKI//4r9IQYrf8PIv/kUXdIEDDuzETp/bTZ0K3HST/jxyJLBlSyj+N9bZgi0ohmLYiq2Z9+3DPjjgwEmctLBkfjz7LNCggdWlILKve+4BmjYN+csyAJJZMSKCp55KQf/+Id9/yYaMWiujKXcohqIXeqEP+uB9vI+yKIuaqJlZa5XTWr190Tfb7Y4e1UGme/cC06cDK1ZY8b8OrVZohXqoh3Roh0djbsRt2GZxybykpwN33w00a2Z1SYjsq0ED4IUXQv6yDIBkVoyIoFatFCQkhHz/JRszavxSkIJO6IQX8SIKozA+xafoiI45Bj/DcRzPsXnz3nuBUaOAxYsRFfvhMRxDWZTFQiwE4HqvE5Foccm8nD6tk9z26mV1SYjs64MPtBYwxBgAyawYEUGxYinYujXnHY4il3d/tbEYCwcc6I/+uA7X4XJcjnfwTrZNvr5kt0awoWtX4OWXgbVrgQkTgvU/src+6IPrcT0SkYjJmIw4xCEWseiN3piCKfYYDfzPPzoAZMoUa8tBZGcOB3D11SF/WQZAMitGRCCSgjNnQr7/kg0ZzZE90AMf4kNUREVci2sxCZMyB4HkZsRqIAFw3TqgdGmdczg+Plj/E3s7i7OohmqYiIkAgNM4jc7obK/BIH/8AZQrB/z0k9UlIbKv0aOBkiVD/rIMgGRWjIjgsstSQr7zkj3Nx/zMmr/CKIz2aI+O6IhkJHvUEObU9Otdo5jd9mlpQPnyOpCuc2edei6SVgTxZxzGoTqqZwY+fyOlQ87p1Df/22+1g+aoUZH/YRDllvF3Eh+vk6VPnx7SvxMGQDIrRkRw770MgNHKPagNwAA44MA9uAelUAqN0TjXTb559c47QKtW2pricACpNqkEy08XcRE342Z8g28AAAux0B4B0DBtmp7YjhyxuiRE9rVmDVCkiPZhCSEGQDIrRkTw+usMgNHG13JlX+AL1EZtVERF9EGfzFHAoeiXNncuUKMG0KdP9ARAAEhEIsqjPI7jOP7G33DAgWM4ZnWxVN++QNGi0fNhEOXF5s1ApUrAzJkhfVkGQDIrRkTQvj0DYLTwNbGzAw60REuURmk0QAO0RduQ10KdPg0ULw4MGhRdATAd6XgEj2S+5w44sAzLrC6W+uQTbZuPlg+DKC/+/BO49lqgX7+QviwDIJkVIyIYPZoBMNoYYWMHdqARGqEYiuExPIZ5mBdQH7/88MILwOefawA8acM5kfPLaqxGCZTACqyAAw50Qzfr1wa+eBFo2BCoXp0BkCg7x44Bd90FNG8e0pdlACSzYkQES5YwAEab7diOTuiE+qiPIiiCiZhoaf8zpxNo3VpnU+jcGfjmG10absqUyB9/4IQTd+NuNERDjMAIdEd369cG/ucfoH59XaaFAZAoK2MQyIIFwBNP6KTpHARCYSRGRLB7NwNgpHNv+h2MweiIjqiDOiiP8vgAHwQ8sXN+OnxYB53OnAmMHx9dTcHrsR7FURz7sd/6tYGdTv0A7rtPQ2A0DMkmMuP994HatUP6kgyAZFaMiCAlhQEwUnn3+ZuBGfgSX+JG3IjKqIxt2GarkacPPwz06AF06RJdARAAGqIhWqAF/sJfcMCBM7Bwcs4FCzQA9u1rXRmIwkXXrkBMTEhfkgGQzGIAjBJGn78v8AXKozyextNoi7Yhm+YlUEOH6tJw0TYYBAA2YzOKoRi2YzsccOBP/GldYUaNAm64AZgxw7oyEIWLyZN1yqQTJ0L2kgyAZBYDYJTYiI14D+8hBjG4B/dgPMaHdJqXQB06BBQqBAwcGH0B0AknHsSDeBpPIw5x+BbfWvOZpKXprNzlyoV8bjOisLR8OVCsGPD77yF7SQZAMosBMEq0QzsUQRHEIc5WNX6+1KsHvPde9AVAAEhGMoqiKKZjOr7Dd6F9caNT+8yZQLt2WqMxdSr7/hHlZPNmoEoVICEhZC/JAEhmMQBGGF9LsLVGaxRBEbyMl20x2CM7Tifw6ac6GjguLjrHHzyP5/EoHkUsYq2ZDmbdOqBpU6BECSA9PTSvSRTO/v5bu0yEcDFzBkAyiwEwQvia4LkTOqElWiIGMfgUn9q+5s9w5AhQuDDQvr3VJbHGdmxHURRFa7S25jObPx9o3Bi4/vrQvi5RuEpJ0bkAW7UK4UsyAJI5DIARxhjsMQdzcBfuQgVUwGAMRixiMRiDbVvz5+3JJ4FHHgEuXLC6JNZ4G2/jXtxrTQAcOxZ4+mn9EIgoZ+npOhfgc8+F7CUZAMksBsAIsxVb0R7tcQtuQXmUx//wP6QhDQ44cBzHrS5ewKZP1zEIhw5ZXRJr7MIuFEERNEfz0AfA/v11KPYHH4T2dYnCWZMmwI03huzlGADJLAbAMOfe9DsUQ9ERHXENrkEN1MAX+AKpSM2c6uUiLlpd3IClpgKXXAJMmmR1SazzGl7DjbgRp3AqdC+alqZLsdSuDXTrFrrXJQp3nTsDJUuGrN8sAyCZxQAYIc7gDNqiLWqjNq7AFViHdZnNh/uwDz3R0+oi5lr9+iFtUbGdP/AHCqEQZmN2aF7Q6QTmzNETWfXqQJs20TcChyi3jNHzffroyPnvvgvJ3w0DIJnFABim3Gv+RmAEeqM3qqAK6qAO2qEdZmM2HHAgAQmYgin4Bt9YXeRcGzgQKF4cOH3a6pJYIxWpuBN3oi7qhu5Fd+zQN75SJeDXX0P3ukThbvFiHTm/fHlIXo4BkMxiAAxzqUjF5/gclVEZtVALszALIzESC7AAXdAF6zL+jcd4q4uaa2vX6tRaY8daXZLQMsL9ZExGW7RFYRRGS7QMzWTda9cCo0drTcaBA/n3OkSRZs0a4IorQnbAYgAksxgAw4z3dC9xiEM5lEN91EcHdPAYMDAYg7Ed27EMy0LXjBgkTqfOQfzcc8BVV0XnfIAAkI50PIAHUAu1QjMYZNEiXY+v2P+zd+ZhUVV/HD6V5pZLWZZpi/Vrs11bzLKyTCsrzSxbbFeztMXULHM5IC6ACogKKi4JgvuGC7lrpuaWWppKpqXmbuKKCry/P45nYAaGxRlEhu/L43OdO3fuHIY7537Ody0pNQAFIS9s2gT33Qddu16QtxMBKHiKCMBCSjLJfM7nVKACD/EQ//FfppIhMcSwilXEE89c5hbgaM+PpCQThla8eNH2RkYTTXGKs4xl+f9m48ZB//5wxx35/16C4Evs2AFPPw3vvHNB3k4EoOApIgALCa4xf93oRhnK0JjGdKd7lh0+rPCLI47lLC/oXyHPpKWZRNQaNeCjjwp6NAXHH/xBbWrzAi/k/5tFRpoefA0a5P97CYIvceAANGkCtS5MzK4IQMFTRABeJGSM+wommAgiCCY4U9zXbnbTmtZcwRXUpS5HOOK2WPASljCRiQxjGL/z+4X+lbzCqFHwySemJMyRwlPG0Ksc4xgd6UhpSuevkE9Lg1694PPPpQagIOQWmwU8Y4ZpYl6hgmQBC4UCEYAFTFYt3DSaecxDo9nEJifL35d8SSlK8SEfOrJ83fX23cAGhjOcEELYwY4C/C3PnyVLjEGqVi1TZaEoYru7vMu71Kd+/r3R8ePmw37jDSMEBaEIkFX/9PNOturWzSRQHTvm/YG6IAJQ8BQRgBcJ9iZ/mMNoND3ogUZzjGOO51vRilKU4jmey1b4Wf7mb/rRjx704CAHL/Sv5BV27TKaJCYGqlaFM2cKekQXjow3pv70pyc9KU1p4ojLnzfcuROCg+HBB2HixPx5D0G4SLFzsEfJVuHhULYsrFvnvYG5QQSg4CkiAC8STnACjaYf/dBo/uIvNJo1rAFgAQsoSUna0S5Xk1QiiUxjGvrcTzzxhaIHsMV6VWbOhB49jACsXLloWgETSWQiE+lBDxrSkPu4z7t/S/thjx4NAQFQogQMHVr0Uq6FIo1XBODIkXDXXTBpktfG5Q4RgIKniAAsIFyTOkIJRaOJJRaNJoYYetKTXvTicz6nJCV5nueJJjrXbopUUvHH3/NJrQBJTITBg01lkrffhltvhdmzi542SSONPvShE50oT3kWsMD7bzJ/Pnz5JRQrVrRMrYKAlwTghAlQty4E5n/nJRGAgqeIACxgTnEKjSaMMDTa0bc3mWSOcYwWtKAEJXiFV85rcgohpFALQIDNmyEsDDp3hooVjbGqKDKWsWg03ejGYzxGGl6u0zdxolHZUgJGKIJ4RQDOnAnNml2QJCoRgIKniAAsYNawBo3mH/7JJAB/5mdKUYqGNHQcl9fJaTjDC70APH0a/P1NLGCPHvDYY0WzRvGv/IpGs5e9VKISU5nqvZOnpUFIiGnA3KiR984rCIWEnez0fK5cvBjatDFWwHxGBKDgKSIALzCurt+e9ESjGcIQp/Iv3elOaUrTkY6ZhGFemMCEQi8AAaKijAA8cMBYAX/8saBHdOH5nd/RaIYznLd5mxu4gZnM9E4s4KFDRl0/+CB06uT5+QShkGG/X6c4df4nWb0aunQxPSzzGRGARQc/pdRupdQxpdQipdTd2Ry7SCl1Wil19NzxR5VSrd0cKwKwgLDuhr70zSTQFrGIspRlGMPYxKYcy71kx1rW+oQAnDPHCMDkZOjdG2rXLnpWQHvNBBJIV7pyK7cSRZR3Tr5yJYwYYVKtR470zjkFoRCxkpVoNEc5ev4n+eMPk6mmFBz14Dy5QARg0aCjUupvpVR1pVQJpVQvpdQupVRpN8cvVEYw5gYRgBcI11pT0USj0QxkoJOwiyaaK7iCEYwAPI9L8Upcy0XAH3+kC8CjR40VcMaMgh7VhcHVahxMsCNjvApVOMEJD98g0QRZDhtmKm4PGFA0Gy8LRZpFLEKj2ce+8z/Jzp3Qr5+ZoFav9t7gskAEYNHgL6VU2wyPL1NK7VdKvePm+IVKKf9cnlsE4AXGCrKZzMy02pzHPK7gCkYxymvFSQu7ALQVSuLjjQCcMsU87toVqleHs2cLeoQXHhsLeJKT1KQmfehzfifKWGvHz8+UfrnkEtiwwbsDFoRCwCxmodH8zd/nf5LDh03A8uOPm9pV+YgIQN+nnFIqTSn1qMv+H5VSfd28ZqFS6oBS6pBSapNSqrdSqkw25xcBeAHZwQ5HzF9GYfYjP1KGMkQT7dX3K+wCMCPDhqXXVz19Gm67zWiWooZt/7eXvcxjHhWowCEOnf8Jt20z6nr2bLj5Zu8NVBAKEROZiEazhS3nf5LTp8136b33TCxgPiIC0PepqowAvMNl/1il1FA3r6mllKpw7v/3KqXWKqXi3BwrAvACkkYaUUSh0U49fGczmzKUIZZYr7+nrwjAxEQYMgQGDTJCcNYsM79efXW+h9pcdNi/6c/8DEB96tOe9ud/wvnzzU0rNBReeMFLoxSEwoH1ttiSWTHEeFZovWdP0xKuaVPvDtQFEYC+z/lYAF15Sil1Rpn4wazOT5s2bWjXrh3t2rUjoagWWcsnMrpywwl3tHhbz3o0mqlMpQxlGMe4fHl/XxGAAFu2mFA1GwuYlgZPPQVff13QI7swZLyWQgihP/1JIIEZzKAUpdjM5vM78Q8/mA+1dWto74GQFIRCzFCGOnVfOm9CQ80q9Z57vDOwDCQkJDju1W3atBEBWATIKgZwn3IfA+jKk8oIwJJZPCcWwAvESU6i0UxikiOrty1tKUlJvud7r7do82qD84uEU6dMqJoVgAAbN0KpUrB+fcGO7UKSSCJTmYoffgxhCLOYxSu8wpM8mffi0GlppmuB1lCrlhGDglAECSGEvvRlKUs9O9GwYSautkQJSEnxzuCyQCyARYMOSqkdypR+KaWU6qmU2qmyzgKupJRqkOG5u5VSq5RSE9ycWwRgPuEqwAYyEI12tHLrSldKUpJBDCrooRYqRo92FoAA335rikOnphbcuAqCAQxwWHcPcYiKVCSe+Lyd5MgRo6q7dDE3rK1b82ewgnCRE0AAoxjFPOZ5dqK4OFi6FIoXN/G1+YQIwKKDVkrtUUodV851AG9Qptbf4+ce36iU+kUpdUSZ+n9blSSBFCjWBRtAgONmPYEJlKa0dzs5FBE2bjQC8ESGyifHj0O1aqZ6SVHCZi1a934kkdzKrbl39ycmQmyssQB27gxlyxbNRstCkec0px2emTwvolyZPt3E1VavbiyB+YQIQMFTRADmMyc44ZhYrAWwDGWYQREpYudlrAD84Yf0ZJCEBFNxoUwZEydYVNjFLjTakQGcQgoP8AC96Z37k8yfD1OnmuDKF1/Mp5EKwsXNf/yHH378xE9MYML5ncSWVRo6FIKCTLX6li3zbUElAlDwFBGAXsbV9RtGmEP4fczHlKQkAQQU6li8gsDOrbNmmZa1wcFGCG7alH7Ml18aV3BRqQ1ou8QMZagjzrMvfSlDGXaxK3cniYmBX36Bt94y9csEoQiyi10EE8wa1jCa0Z6dbOlSMzl17GgEYD4hAlDwFBGA+YSr63coQ7mCK5jL3IIeWqHn1Cno1StzLOCJE3DnnaZItC/jmllur7FNGDX8Nm/zOq/nfKK0NKOk//nH+NDnzMnnkQvCxckWtjCYwWxiE0MY4tnJ1q83k1NUFDzxhHcGmAUiAAVPEQGYTySRhEazkIW8zMtcwRUsZGFBD8tnGDfOzLHTpzu7gmfMMK7guUVEZ6eR5rAy29i/vezlSq5kGtOyfpE1p06daj7E0aNNB5C1ay/gyAXh4uFXfmUUo9jOdkIJ9exke/ea79XPP0P58vnWtFwEoOApRgBOnCi9P73MNKY5+rVezuWeZ5YJThw5YubYDRsyWwKjoqBSJdOWsyiwlKWZaj2OZCTXcz1HOOL+hb/9Zj68iRNNwLogFFGWspQJTGAPe86/taLl1Kn0+JTLLoO/PWgtlw0iAAVPMQJw//58uUCLEhndcgMZiB9+vMALlKIUnejkE3X4LgYyxgL2729irV1jAdPS4OOPoUYN52xhX8Vam//iL8e+NNKoRz0+4RP3L5w7Nz1W6aOPLsBIBeHi5Ed+ZCYzHR2aUjmPmlIZJ6fevWHECLjxxnzrVykCUPAUEYBe5ihH0Wg+4zNKUpKf+Kmgh+SznD6dXsM4Pt7ZFbxxowm/eeMN368PaJNBwghzKvo9n/mUoQyLWJT1CyMizIdXsyaMGnVhBy0IFxFTmMIiFjnKwZzkpGcnXLAAJk+GZs1MwHI+IAJQ8BQRgF5mMYupRz0qUIFWtPKJFmwXM4mJRsPYbUZX8L59JrehY8eCG19+ktHqHEEEfvg5JYMA9KMft3Fb5hva7t3mxtSunXFTHTx4gUcvCBcPYxjDSlaSRhr++DtKK503W7bAwIEQEABvvumdQbogAlDwFBGAHpLxJjyEIdSlLqUoRU96+kwLtouZ5GQj/EJDMwtAMI0trrkG+vYtmPFdSKKJzhQLmEIKD/MwHejg7KIKCjI3qBdfhEceKcBRC0LBM5ShbGQjAMEE576MkjuOHUuPr737bi+MMDMiAAVPkSQQL3GKU9SiFuUox2d8Jpa/C4QVgIMGZZ0VnJgIq1aZJheDfLzr3hKWoNFMYYrT4mM2sylDGeYz3xxoy1SMGwd33QWtWsn3XyjShBDCdrYDMJCBni3Y7UKrVy/TZvHSS83E5OXvlwhAwVOMADySTaagkCWulr8neZIKVMAff7H8XQAyGrOGDTPhNlpDdHTWMYHjx5uKDGFhBT3y/MPWnrRdZzIuQiKIoApVjGtr+XLzIe3da/qVbt9ecIMWhIuAnvRkP8YTFkUUv/Gb5yeNjYXu3c3q89dfPT+fCyIABU8xAnD3bq9fnEWFoxylOtWpQhW+5mvPg4eF88JaAgMCzHb//swu4V9+gQoVfNcdnFXfaUsaabzMy7zGa6SNGmk+nFGj4IEHCm7AgnARcIYzaDQnMCUDbDygxyxcaL5ntWqZWpteRgSg4ClGAG7e7PWLsyhwghM8x3NUpjLBBGe66Qr5j6slMDbWzLlZdQoBWLMGrrrKVGnwFVzbD4YSmikZBGA/+7ku7TqGT29sPpwGDYyLShCKMLYPcBqmYPNkJrOYxZ6feNMm8z1r2RI6dPD8fC6IABQ8xQjA1au9fnH6Okc4Qh3qUJ3qfMu3HOCACMCLAGsJHD3afUzgunWmUHSbNr7ZN/hf/kWj+ZvMBWgTdo/gitMl2Nr1TShVyqRKC0IRZhe7CCLI8diG73jMgQNmEgoJgeee8/x8LogAFDzFCMAFC7x+cfoyBzhADWpQhzqO0hu2GK8IwILFCsBDh8x2yBCzHTrUWQRu3w733AP168N//xX0qL2LrQvYl74MZWh6POruxRAZyde/PsP9W0px4rUXJPlDKPJsZSuDSM8QW8hCpjLV8xPbjiBTpxqflbgXAAAgAElEQVS3g5dbwokAFDzFCMBpbnqGCpn4h3+4i7toTGMCCGAOcxyB95L8UXC4uoLj483c26OH2WaVGLJ2ramCcued8OefBf0beA8bC2jDEk4nbkr/cAICONM/kDpLLuHtvc863F6CUFSxfYAtK1hBHHHnf8KMk1GvXjB8OBQrBvO82w5UBKDgKUYAjhnj1QvTF0kkkQgiqEhF6lCH3vQmkEBiiRXhdxHhKgTj4tIF4NKlmYXgzJnwwQdmgT7VC4v+gsQ1FjCCCDSa0Yw21+jJSSQs606i/3vsaduU67meEEIKetiCUKD8zM+MZ7zj8TrWMZKR3jl5fDzMmQMPPWQClL2ICEDBU4wAjIz06oXpiyxkIeUpTze60Z3uhBPOGc4U9LCEHLAu4YzWQJucFxMDwcGmI9rbb0Pp0sYiuGFDQY/aO5ziFBrNDGag0ZxZuQwaNoTKlWHPHpaznNKUZiELC3qoglBgzGEOM5jheLyFLQxmcJ7P47oAm8UsEvaMInHBUPj0U9N1x4uIABQ8xQjA4GCvXpi+RCKJfMd3lKQkH/ABMcSg0SxjWUEPTciGjJbAoUON4Js0yblUzPbtZpuUZLabN8Pjj8Mtt5gmGbGx6QIxONhYE7MKmbPvldvjLxSnEzfx48+agBQ/5i3SpH36qan7l6EkRSSRXMVVRBPtfOMSa7ZQRJjKVKdF0D/8Qz/6nff5bAhGMslmkgkJgREjTHNyLyICUPAUIwC7dfPqhelL9KMfZSnLNKah0fSkpyR7FDKsFdAKvZ07nS2CtovIqFHQpw+8/LLRSS++CN99Zzw4rhbD4GCIioLISCP0MsYd2kYbriVoLhSuloiQ1P70SO7KmOlvEbegNbPOxjsEXhpptKQl93Ef+9kv17ZQ5HCt+3eAA/Sk53mfz0kAHj9uJoM1a4yLwYtlB0QACp5iBOC33xbc3eoiJZVU2tGOSlRiFavYwx6H5U9ukoUDd4khVqDt3m22y5aZ7eDB6ULx00/hscdMEf/vvjMF/bdudX69jSW057UNNubOzZ1gzJiVnC+kpsKsWZyp9RAjln7MsP29TcLS2alOlr5NbOJ5nudJnqQLXeTaFooUwxjG7/zueHyMY2g0Zzk/sWYFoCP5KiAAwsOhZEkzyXjpCy8CUPAUIwC7dDGtE4owGa0m4YRTi1pUoYqjf+oIRki2byElJyFoLYMjR5rt/Plm26cPNGkCV14JN94ILVqY/YGBZrtihdnaeq/WohgSYrZr12YtGGNi0kvU5IvLOCkJBgyA226D664jrV49Yn7tSEhqPzSaw8l7Mi1ijnGMG7mR+7iPU5zycACCUHgIJdTRBxgghRQ0mmMcO6/zZSoJZieWJ54wq0AvIQJQ8BQjALt2NXe70FCzWgkNzZ3JwvXOmu8mjfxnLnOpRCXu4R788COCCAIJdNT7c+2uIBQechKCtm7rmDFmu25dusv4qaegXDkjBEeONBbB4OB0oag17NjhLCh79jTb1avN9siR9FhDrWHlSufjN23yIJYwNdUo1+bNjaXhjjugY0cIDCQtsA+7IzX7pgyj71HN8IPBLJp/zkJxjuMcpwMdqEAF2tI2n/8SgnDx0JOe7GNfpn22N3BeWc5yZwFoJ5qvvoJPPvF0uA5EAAqeYgTgwIHOd6KcTBauQtE+v2BB7u5gF6lw/ImfuJqreZiHHd0U7GpuClPE9esjuEvasJexq2XQbv/5B555xlgEq1SBsDDo3BkOH876+C1bnF3LQUHObeoiI802NDRrl7JrLGFWbe8iB5wirttGZrw6jNmNI0j4bhGLx/1LQgLETdtPxMjlREzZRPCEZcRs/hmNZgAD0GimM91hzR7NaPrRj7a0pQxlaEYzsXILPo/tA3yc4077+9M/y046uSGeeOd7hV3pxcaa6vNeQgSg4ClGAL75pukL2qmTaY3QoYNpXfP112Z/587w0kvmTtakCfzwA7z5pkmrfO89cydr1crcSYOCYNw46NYtPXre3tliY7OOmt9U8Fa1kYykNKXpQhc02lFDLZpoNJrJTBbXr4/jmizibh0UFQVvvQU33wyXX26SRVq0MMm12QnKjRudu5TY97H1CSdPdt5OmOASSxh6ivCAI8T1/JNpn8xg6xMfwGWXsfWFz4n9YhmxYfsIDzhCROARwv0PEeW/iwi9h2ED/iL8h7WEDt9GnwF7CIrci474l56hx9ABpwkJTaXHwEOEx+1HJyzj88QwSlKSVrSSa17waY5wBI0mlVSn/RFEsJnN53XOUYxyFoBHj5ov8qJFcMklXgu3EgEoeIoRgHXrQvXqcO+9ZvvAA3D33VCjhnl8993wv/9BzZrGB1a9Olx3Hdx+u6mgW768yXAqUQKUSv9XooTZX6WKab56111mBfT00/DII8Zd1aCBqY/Utq3xq3XvDv36Obukg4Pz5prOA2c5S3vacyVXMp/5DkvfWMai0Y7YP7H8+S6uFsHcRkLMn2/6vDdoYNrqXnUVvPCCKTtz8mRmQZnT1loKx4412x9+MNuZM6FPp8P83Gcx414fzw/vzWVoi1+Y2WM1I75PJPqHFCdXc9Ke42zU40gJHUA/ncT61aedhOzU+LPo/kfw3xqLXjuVQZvnomcvo2fcn+jB+/ALO0zXoCTa991N595HCQpOdfoa5vbruHjxRWnoFwQHu9nt1AfYMpKRrGPdeZ2zL33RaE5wwuywQcJ9+sD11xuDihe+CCIABU8xAnD//tzdocLCzHb4cLP18zPbxESzHTDAWP6GDDHWwz59jGXw669Npd0ePUwh2pdegtq1jQi8804jOK+9Fq6+2phUrICsUMHse+IJI0LffBPq1oU2beCzz8x7ffGFubtkd4dx43Le+9dy6lKXu7iLrWwljTRH+yy7MrRbEYCCJavLKT7eCLYvvoCqVU0ZmdtvN7GDn3wCXbqku3xdkz+spfDXX52/bkfX/8XEJjFEffUbPTsfZ1TblUR8spaE0Xvx1ymsmbqDnjqZgIA0x/3FX59lTegSftQ/Ex11ylgUJ6Q4nXfZyjNoDQNnbkPPWEnYzK3opXPYczgZrWFv0kn0+kl8nvolJc6W4eMzrdDLEpiaPAu9LIH1xxPzlNxi+zG7RpC4Csrcbq3wLCSRJcJFzFa2MpCBmfaPZSzLWZ7n89ni6xrNQQ6anXYl2L+/ued9+qmnwwZEAAqekzcBaKPY7WNXX5a77U8/mW1ERHpNJK1NywWt0yvz2uO6dzdWwZgYeOcd+Pxz45J+9124/35zV73uOvPv0kuNWLz8cvP41luNpbJOHXjlFSMav/zSrLpswbeQEJaO+Yzrj5bjzc0PcmxwEIkLo5iQ2IceKX5MW9+D2H+C6HdEE7cnhAnbg5n9X5y4wYRckZZm4v9GjTLrn9tuM56fMmWgWjWoVw/efx++/dYkikREmHvDlBGHiWm/ls0f9OR4pZtJK1aM/255kOROXen31d8kJYGfTiVlUCQr9Ex66tP00SdZNCeZLl1g2YJTDOvwB0Hf7OfztqkMHZhMixbQO+AszZvDl98ep+nHh2nyxhleeu8gr7U6QL239lH3nV3UqXuGp+umUbs2NHsrhUcfTaPuO7u476Ud3PnEAe569AgvNEzh3nvN1++ee+Dhx85y7+NJPPXmbu5/YRfPvLuTBxru5NX3j1CjhmmxV7OmWbM9/LD5KteqZWLhn3wSvv/efBa9ehnLaWgoNGpkLIqvv24ssu+8A9OmwUcfwZIlZu2XkGDyWyZMMKIyY2RJeHi6JXXAAPd5a3m19uZyTSlitJDhru3bVKaygAV5OlciiUxgAgEE4Icfk5JGkbA9ksSVseYiGDkS3njDTAheQASg4ClZC0B3hc5co+Nze1xO2337nH1gdjw2vXLaNLMNDzdbf3+z7dHDiMUpU4xFcOBAcwd5/31zx3nxRWNyr1zZ3IGVIq10KUICK1P6xCUMCKzK1t4fk5DQjtk/dSHy7+8J/y+AhA3BbJkfye5ITcqQyKzvFAXd5kEoVJw4YcrCxMZC164mhvDpR09w+3VJlCl+2mH0LnZpKmVKpVC+XCpXVUil4pWpXFvxDJWvSqZapWPcetVhbix/hCvLJHNFqRSKX5bqFHVh/11eLIUrrzjN1Vec4uZrT3Dj1ce56YYUqlY13U7+9z9o+LIRdK83T6bmQ6k0bHaUR55N4olnknmszhnqPHOaJxoe4ZEW67jlvZ+o82ISzzyfzMvvHKFeswM0b3WMZ56B+g3SqFsX6tdP4+mn4cMPjcCrX9+sw5o1M+9Zp44RgM8+a6JLnnoKh6C84w7zXLVqxilQpYqJsaxUCW66yWRglytnLKuuv2uJEsZZcP31JkGnenXz+ptuMgK0Rg0znqefNmvCxo2NMG/UCPr2NZEoP/wArVubaax/f9O4oXt391ZLOw24s2665sfZMOfcdo0RAXlhcO0DbPmRH5nJzDyfby1rGcnITKVlAHO/69jRa3GAIgAFTzECMCoqd8thO5vFxDgLPnfZvzmlVebV4ui6temXts6SFZBxcc4CMiYGunVjf8+veGndjVT9ryzL2tc2d6QXX4SbbybtxhsY9NtnzAt4hoQBDZn9w9vER7/J7IR2JExsSWLCQGOG+PFHcwd3TWxx9xnamd01IMo1IUZm+KLB4cMwfbqxcN99N1x2GTz6KKfqPMf+cQv4s01/1kb+wtKPhhPbZSNBrbfR5bODtH3vCJ9+dIqW757ki0+T+aLlcbp1OcuXbc8S3i6RMR1WM6HnZoZ+v4ONP6xkmU4geeoslukEjq9PdF63HU90culOSo5HL0tg9fFNTsftTzIu4SUnVvLl6Q5USa3KnQdrE5s8Mf31Pycwdsta9NQ1jE5cih6zmeBhh9GR/zJz9Z4sv662F/Ps2c6xjjayxBbStjlktu6ijY2MjDTWwx49THRJTIyJk4yPN2u/zz4zFsRXXzXetgYNjCOgQQNjabzvPiMIq1UzAvTqq00ESokS6Q4Fpcz/y5c3/6worVvX/Nnef99EsXToYM4ZEWHeY8YM4/LfsMHk1Flnh2tRcDs1unaZyWuBBYm/9Iy5zHXqA2xZwhImMSnP55vDHOKJZyhD2chG5yetK/jmm2HixPMdsgMRgIKnGAGYlJT9lZZl/Ylc1Ad09bO4C+ZxnQ09tSi61uFYuJA5o9/lurPX8NrGuzg0YzSJ0ZqEZZrZ6wKZtUwz4m8//FO68/s4bSL733oLnn/exB9Wr27+lS1rVm+XXALXXAM33GDuJA0aGJPCm2+az6Rjx/Qicq4zvzUZWBHtrsROXiPuxXRQ8GR13XfqlK4WqlY1185118Gjj5rrzM/P+Cq1huhos7UFBBcsSL9WMsbcnrumUgdFsFtHsiVkBgl6GbNjDuYpFi849DR+fZLpFXYc//DDhMTtQY/czriNGzILxM2xfJf2HTceup97Uu6j48qxZv+KmfRJDUIn9WXEmWj08lkOQekaM5jXr29OWxtBEhubXnxb6/SOLFobN7x1FmRcK9qP0tZytJWw/P2NuAwKMvGcbdsai2bLltC0qWkT+NxzZt34yCMmIuWOO0z/6GuvNRbIkiWdheTllxtL5jXXGGvk//5nzlGzprFIPvussT42aWISiD76yPwO7dqZy6l7d7NmyDglupsqrVB0rXWZkwXyfKcVKzTzer6LBXeu3lWsIoaYPJ8vllhWsIIYYljFKrMz44feu7f57teu7bEXSQSg4Cm5E4D5RU7+kIw3wOz8MNkIyFM9vqfD/vcpc7o4w04OIE13T7+DaM3JpL3oVE1QaiA6VXNmxbk4RFut19busDfn+HgTU9i2rZmxrbv58cfNHaB06fRZ/6qrjIC8/35jKmjY0NyRWrc2M3z37jBvnjnvtm3Z3+3yWpsxt5H33nJpF2XhaX/3SZOM+P/wQ7NguP56I/juuMNM+t9+azLcbUiDXST07m2248ebrW1WbPfbv/U5i3jiptPOH3X8WRL0MhYvOJPtn8AaIFy7Pua0XgsKTkUHnKZ38Gm6Bx6jU999dAzaT+/Q4+jw/fSO+wsdsYfgLVPRf41i6fHV6GUJjNq0Aj1yOyGxewgIP0JwxFECwo84hOboTSu9IhDt73PihPP+jP//+2+ztWHGNurE9VwHDzo7H6zItBnWu3Y5i8x//3X+U9qEz/HjTQvBSZOMRbJ1axPP+MYbZhp49VUzNbz0krFC2gIL111nXN2lSqULyEsuMdNKhQomfOzmm02bwvvvN8L0qaeMaHzlFXOJff21EcSff26spl275myBPN9pxfV8P/6Yu/PllODjKiBdbQ6xsSYnMSzs3GLm3LnDwnK2hmY8V+8pfzBy9p5MU9Vv/EYUee/aEUYY29jGZCazhCWZD0hJMaXTKlSAU5513BEBKHhKwQpAd+RWTOSwnF0+x5+7DlfmnmPVGLa2DbP3jyZ8vybi7CAi/tWE79cMOTsYjWb5iYUm2zcplwkx//1nttbdHBWVfsfo3NmYEZo3N7Py008bgXjrrcYUYMvlFC9uZvxq1eDBB4018cMPTcb0gAHGemSX8LZhrX3/P/90vgO5js/e8XL6PaywdCey85qS6Srac9vOIq9W5pyunby008hrRP/MmWZBEBVl/JPNm5usiEsvNVbiF14wZp2AAHNHtr5N+zex6cDW/GRVhuvfxi4KXEMhXBWcO2WXx69TptdlaI84jGGOArcTmMDzPM8diQ35JGEyI2NPooOP0i80BR14Ar++x9A9k+kfmoIOPsrQuCQiE7YzbPFmghM2EBT3N3rwHvzD/ks/PvAE/n1P4Ncnmd7BZ3J1ybnG17mW3TkfMemtsGbXrRWOVmDmFPUSHW2KHPz6q1lvDhxokmq+/NLEMH7wgXFH165tpo4aNcw0ctNNZt15xRXOVshSpcy+2283huiHHzaXbKNGZmrq1s0IU63N9DNrlhGumzYZIet6CW7f7vzYfu2tpTUhwXmb28/JCmlXAenqMHGNQspOdLpzvsTHg56wgXEL92SaMvqEnKJn3J95WsPaotLrE48TmbCdiNnbs55ORiwm4YUQZo3c45ETRwSg4CkXpwDMI643qilM4TVeo1RqSXpv+ZCzcdHGZRYawsnemrTevUjr4c9v4zUBZzQTNmhmr+nF9LX+zF4fTMIyTeL8IZ7dAWyGtDU1WNOD7Re2c6eZYSdPNiKxY0czkz/8sPEVWRNAyZJQsWJ6fcbGjY3Z4O23TfXhr782NUZs/KMNmLKJMv36mW3//mZrE2mse3ziRGeB+fPPZmv7ouX1jjl1atafl7s+ZznFmZ6vCcG+zlpus7MguxOv/fsby22bNsba+/TT5g5burQxy1SqZALCnn/eWIKtH9LeBadMcf5srWvXLhqs9dfd3c6dv6+AAr1sk3vbHacPfShLWV7lVb7lW8f+cYxDo5nEJKf+2VZAxhGHRnOIQ07ny22pJXc3SPvnGzzYGE8DAsy2Rw/3l0mWoiCDqLQWPXcWNHuZ51U4ektouq7z7CW1erVxMGzbBu3bG+H48cdmrdK0qVln1qtnRN/DD8NDDxnr4i23mMu6fHnnilyXXmqmpIoV09esd95pOuM8+qhxidevbz7rJk3Me773nnncpk36etbGfdq/1S+/pH8OGaet3budf5/1xxPR01fRP3ofetzvTD6egJ67hBmr9jgEoM0dtOsmV9FtDet2u3o16ClriZ1xJPPXLfgYPWavyjbM2/Wa6hd6Fh2xh7i4NKISdjJ40Uana8dhTQ08ReQXvxPVYRP99BHiQvYwIXg7s+P+c/r6ul57rtbY4cNFAAqeUaAC0FW4edpxIJlkmtOc//E/alErU9/eTWxy3JBspw9btf104qasLVDuvvX5Hb+YlGSsRytWmFl7wADj63n2WWNJrF7d1BU5l91M+fJGOD72mIly//xzMyP36WNm4unT4Ztv0n1ZVozYthP2TmitVXYmtn3KrIC1299+M9thw3AyXVgBat9nxYqsPxd3n5ejmrFLoJe7fmvWEuuaaeB6nLu78LffmvJAX31l/HSPPWaE3jXXGEvtJZcY39wtt5jnGzUynW6+/x7++MP5jmN7vW3dmvX72Rnd1ZyyaVP2isZV+F1gt7o7S+Ac5tCBDtzLvVSgAp/zOcEEE0MMGu0oiPs7v6PRTGUqGs0P/OAQkBrNGtY4CcW8zgPnY+HMyeDszgDtGvPmLm8uJ7Hg7vhsrVUeTCf2EnXn+rYubXtp2kt41Soj3MLCTHLLsGEmq3vwYLPueeMNk739zjtmSnruOfN1ufdeY4m89trMmduXXWaskeXLmyiJqlXNlHXnnebrVbOmEZWPP27Wu/XqwWuvmfjLrzuk8MYb0PzdNN5/36ybW7c2ETlffWUed+1qnDBduhgRbL/+Wf7reZpx8Secpp5Zs0D3OYleuACt03Kc0u1n9suJDeidw0hOhpWsJDplTJaf9aF/k1n+cgB7r72X9l+dYerE03zyibHCtmpl7ALNm5vPu2HD9LJJn35qbASvPn+SV58/yf79IgAFzyinlGJC0oQCbflkLQueFFv+i794gicoQQk605mZzCSWWIIJJoIIAgl03HDWsc5RrPN8bzq5jl/Maz/l87E0tm9viqS9/bbxFT3zjJlJqlc3s/OVV6bHJl5yiVnK33qrmXmff95YFtu2NeIyLMzM6uPHm5l19mwjHK3b0kbRW4uiTekcPdpsbQqndW/af9a3Y7fWYml9SUOHOh9vU0P79nUWpPZ97XhsNL89j7+/8Vl16JA+m772mnHLNmtm7jQPPWRMGfYzKV3aPH7wQRPZ/9pr5rPs18/cRawFz1r47Bjs72jrWFqxm1f/omsrxIs0ntKdENzIRoYwhLKU5SM+Yi970WgOcxiNpic9Ha7jjBa/3/gNjSaIIDSataz17DvpA7gTpu6KDOQUk+ep6zqvrnN3ltJffzVfyy1bzNp0yRJjhZwwwVgkBw40U1GXLqY4Q4sW5mtqoyvq1IFbb03jf0/8y/XVD1P1jmNcWeUEV11/ipJlz1CseNblkKzgLFbMRGeUKmUsnOXKwY03plHxlv+oUiWNa68106G1blaunEblG85SuXIaN91khOqtt5rt7bebjPBbbjHbypWN0L2uylkqXnuG666DKyumULZ8KmXKpDfJKl7c2S2vFFyi0ih5eSrlSp3h+oqnqHrVce65PZkqVcz73HabEX81ahjL6lNPwet1D9Cl3jIRgILHlFNK8VDSQ3zDN5ksZuc9ibmx7C1mcZb7JzM5VwLQ9byxxBJGGK/zOpdzOQ/wAB3o4Pg9rLA8yEE0miEMQaMZz3iHAPR6h4/8zpjObeGxrGb+zp3h99/N0nLIECN0Wrc2S2sbjf7YY2ZGu/HGzOmMxYqZ2fOqq4xovPlm4/u55x4T0f7QQ0ZwPf64MRvYOLiGDc0s37ixmdGbNDHC7bXXTL2O1183wq1pU2ONa9TIuLYbNjQWzPr1zfmefNJYM2vWNJnXd9xhgqCqVDEWuyuuSDc3WJ/VTTeZmf32240poW5dM4bmzY2w7dQpvVyQzca1gs9aKW0HHCtu3QVuuYundFfT4yITeLnF3fd7POOpQQ0qUpFWtGI6052EnRV+rlv7fH/6n5dLuCiS16zcnKaN3Foc3eWi2de5i07w1CW+fj3oPifQCcvQ01YzMd50uVm9/rRjzXjkiDHM79plvtqJiSaTev16s75dscJMfQsWmKSZCbOO8e6cHxg/MZW33jJT9Jtvms+uWbM0mk2Oo9kHx+nRw6yJO3c22/btzZTl52e2w4aZohEtv9/Lu++nmMzxFmdp9f0+WrY0UTaffQZzo/9l5BerWRy+lphO6/ntmbYsf3cgI4P2nVu7mo4+Npx80iTntfDYseDfJZkNNT9g4GcbRQAKHlNOKUW9pHqUoQxjGes8yZyb6DNa0oIJJoooIokkjjiHEIskkiiinI6zgmsIQ7LcH0MMAxjgEGMxxDidz/X89nEMMXShC+/xHuUox23cxsd8zFCGotFMZCKDGexwQQ1ikJNFwg8/NJqhDC08VobcJirktfROTjUc160zM9+WLWYWXbDAiLAxY4ygCwoywqpzZ7NMb9vWBBU1b24E5SuvmGXsU08Zwfj440Zc1qplyujUrGkEXI0aRqjVrm2W4M88Y1730kvGktm0qTnms8/M+3Tvbqx6gwaZWTg62gQ5rV1rZn9X13B25gtrldy7N3uBl1vLXhEuzZNGGoEEchVXcRd38R3fObmM7fc843xgXcYTmYhGk0BCkbcEeou85jflNvIlrx1TcjstuXOgxMeDHnCAwEXL0AnLCIvbgw4+yqCIVEey/ODBJsQ5t0kg42YcQ8evdCtKe6f1QUfsybUVdEDKIHT0VuNK7neEXqm9sz3+ZN+B7K98H2n+PdiiYzg1MZ55egnLo35jil6bqX5nUhJMaTSSlHvvR2tEAAoeU04pRbekbjShCVdxFY1oxDa2OX2J97AHjeZv/nZambu6bm0fRLuCt6+zj21f3T/4A43mAAfQaOYxz2lrJ357Y7DCcDrT6UpXPuADKlCBO7mTZjRjIQvRaP7jP4ew02iHBcLeWOw4rBAskhYGbwnJnKLp3SU05NYnlZM1La/vlxcBl9dEFOkOk4ljHKMtbSlBCR7jMb7hG4fgi8O5raJrcol1GS9laZaC0fX1gu+QnQOl3/h/CJ+9FZ2wDP/EMejEaGYmnCVu9n8ET9hOaNweAiIPEBq3h+AJ24mb/V+2ZWDCo07iN3if2ynOL+w/+oQku3WqOE0bUano2cvRvU+Z/X2PohOj0TrVfQLRT0mcKlGOk0NHc1r35NS5wu1/RMxnol7P7D7rmO6/ltnBvzFRr2dz5EKSbrqXsx+1YplO4MDKtSIABY8op5RictJkh8BrQQtKUYpOdOIQhwAYzWg0Gn/8sxR8ySSTRhojGYlGE0KIw6qn0UxjGk3hR5kAAB9iSURBVBpNMMFoNIEEotEMZrCTMHR9bAXcL/xCJzrxEi9RlrJUpjKNaew4bwABDuEYSaTj8XrWO21dsxG95fIu0uQ2mj6nqPicTAI5WdNsgkXGbOPevY2F0t/fpCMGBRl3rzt/lzvXrD23mzIrgnt2spOP+IgSlKApTdOL4+LewzCCEU7zzb/8m+X3OKfQEhGIhYecEgITSSSMMIYznGEMc9xDMs7heY0lX8c6RjDC7fMDEmcxJuGg27VwxilqSsJJ/BaZpJGYGAjum4aO3E1wv5RMzaDioo4RHnCE0F7HCfzuP/p+u58++gRh+hBh+iBjhhxF61QWzDpFgl5GbEyKef+gZII67CW07xnJAha8QjmlFNuTtqPR7GY3AKtZzXM8RznK0fncT8ag7WMccxJ8ySSzmc2OYO4NbHCy8FkLnM0GtCt9a+GzrXNskkYvemGDxj/hE+pS1xHj14xmDgteFFFO53VniXSNKfJG0olwkZAX9+r5xmcWAddtfvMP//AVX1Ga0tSjHlOYwhnOZHms/X5aj4Nd0A1nOBrNr/yapWUwY2hJOOFEnPsJJ/yiFYXeroTg7fNdaLKbmwcwgD/5E8BhHMh4XF7n9WUsYxzj3D4fTTRrWJPjeRITITbhIIGz1zlNEwGJcewnh56/W7eaejvt25M4Z5vp6NPjF2bpFczuv5EEvYzEmBVm/mnY0KRKn1u4Jk2cKAJQ8IhySinGJY2jN70ZwQinyWIxi3mWZylGMe7nfkYyku50ZwQjCCOMHvTAulwDCHBM0Hal7i7o250wO8lJNJrFLKY+9bmHeyhOcd7kTVrQItfnseVeXG8QrrGLhW1yFITCzkEO4o8/N3ETlahEe9pn6pnq6hL+i7/QaBaxiKySRWySlw0BseJgKEPzbO0vKAHl7UVpfi9y8+tzsmFDruO2RZaPchTAsQjIeNwJTqDRnORkrt5rLnOJJ95p3ylO8Rd/8TM/8zVf0572DGAAIYTQl770ox/DGc5UprKWtRzhCGB6B0/Eub9vCCHsYIf7AdgFZs2aJtbZeiJsTPKECWY7ZYrJZile3LR+OXdc0v79IgAFjyinlCIqKYp+9KM3vZ0E0zCG0Z/+fMVXPMETlKY0V3IldajDh3zoyN61QnAa07KM3bOPXZNB7P4NbGAJS/iGb6hMZS7lUqpRjQgi+I7vHILSXfC4fX4Tmwr16lcQigqppDKPebzN25SkJHdzN5/wCf3pn+P3/Gd+RqMdrmL7Y13GVjBmtBZGE00wwYQSSgABBBPstA0l1Cm+0C4i7ZxyPolwQQQRSigazbd8y0d8xAd8QCMa8dq5n3d5l1a0ohnNuJd7qU99alObJ3mSWtSiPvV5hVf4jM/oRz9GMIIZzGAd6zjIQdJIy/LztV4YVyHlbeF2nONeE5rHOZ4pzMiym90EEshWtpJAgqOmZDzxjvFbT9AGNuTq/cYxjjDCCCGEt3mb27kdheIyLqMKVbiN23iYh3mFV2hCE97gDZrSlHrU437u50quRKG4kRt5hEf4gi/YyEbH32QIQ3K38PjpJ1PT1bYddY1RHj3a9P17/nnzODZWBKDgFRyFoPez3+Fq2cc+x5dwMpMdzbJPcYopTKEmNSlDGa7gCm7hFl499xN97sfG6Lhm705iEiMYQTjhfMEXNKQht3IrJShBWcpSi1q8xVv0oEe2k7ON+XGdlCU4XBAKH0kkMZ7xNKc5V3Il13ANTWnK93xPOOGZYnetEPyRH7GhKxrNNrY5LUg16cWobbiKO++Ba3xhNNFOi9iMmczd6EYMMXSnOx3pSCMa8TqvU5e6PMZjVKUq13Itl3EZCsXlXE5FKlKJStSkJndwB41p7BCCL/Iiz/Ec9ahHO9oRSigd6MAzPMOrvMpTPMXjPM693Ms93MPN3Ew5yqFQlKQkVajC/dzP4zzOh3xIV7ryNV/Tla4OC5UrrhbC3JbuyjinD2GI455hPydP4jKXs9zxd3MVgL/yKyMZ6bQvjDCn89kONK7Hgbl3/cIvDGQgH/AB93APl3AJFanIy7yMH37MZCa72U0KKQDMYx7TmZ7ttXuQgyxkIa/yKrWpTSlKUZnKvMM7tKQlM5iR7esBEncvJmHKp8we9RbT1/gxe10gCasCTDcqW/+lWLFMLSNFAAqe4hCAaaQ5XCsZkyp60INYYp2+vAtYQDe6MYABvMM71KMeN3Ij13Edl3AJxShGBSpQkYpcy7Vcz/WUpjQKRTGKUYUqPMuztKc9McTwO7+TSmqOXxRBEHybs5xlCUvoSU9e5EXKU55SlOJ2budJnqQhDWlDG9rTnqEMpTvdM4Wc2ELUGs1qVpMxDjmSSDSaBSxwejyCEXShCwkk0JrWtKQljWjEG7zBwzzsJOwu5VIUihKU4BZuoRrVaEpTalOb7/iO13iN8Yzncz5nBzvQpCe2zWIW1k2dUVjapIYQQhjKUEe7vFWschKo1joaSihd6cp3fEdLWvIe71GHOjzCI1SmMsUoxqVcytVczd3cTQMa8BZv8T3fE0igQxAvYIGTUHPnrckYX5lx3DbhL5HELIWbFZqu3hlX48AsZhFEkEOwu1pegwgigAAnI0B/+hN87sfGn2tMma8BDCCIIJrTnId4iOIUpyIVaUADvud7pjKVYIKztRZOYxoDGOAYgzvrsf0MRjGK6Ux3lCm7gzu4jMu4ndt5ndfpSlf60Cdrg8XRo2x99zGGrGrJjMMxTNgeTNyeUCL/1UStaMWgxPaEngoi4LQmNKU/wUc1ww8PFQEoeIRTK7jZzEaT3prJTp6uq0jX1WPGx6c5zTa2sYENrGUtq1jFcpazkY0c4pBbl4UgCIIrqaSykY2MZSxd6UoTmnAndzoWlJdzOVWowi3cQg1qcDd304QmPMRDPMIjfMZnPMZjtKQlD/IgDWjAXdzFAzzAzdzM//gf5ShHSUqizv2UoAQ3czPVqMbjPE5tatOc5jSlKR3pyBd84RActrKB/bGJbLbWqKt7Opxwp+185qPRbGazkxC0pXDs62yJLHcWTCvcdrITjamc8CVf8h7vUZ/6vMVbXMd1XM7lFKc4N3ADNahBCCEsZrFDqK5gBRnjKe35ZzLT6fFGNqJJT9TpRz8ngWpd4FY4/sRPJJHkiPN2jdcez3j88HO0CbSuU/t+GRMOLWtY44g770Y3vuEbnuM5HuABilOcSlTiTd5kGMNIJDHTvSeMMP7ir0zXnLWG/sAP9KZ3Jsuz62f/D/+g0ZzghNPrQwnle76nBS14iIcoT3lKUII61KERjfiBH5ysoxt/n8CRqmXZ3PM9gv9tz8w1Acwe9DKzp7Rm4rrubJkcxLEgTUpof3ZHag4PFwFYVPBTSu1WSh1TSi1SSt2dzbEVlFJjlFL/KaUOK6WilVLl3RzrJADd1ePK7apOYu4EQchvEklkNrMdHX060YkW536a0pRmNOMJnqA2tWlMY57lWV7jNZ7iKb7gCxrQgP70pzGNGctYPuIjVrKSDnRwJJTkNoHNbm3YjH18iENktEZaoWSft7VLbc1SV9ezFWJWXNhSXAMZiEY7FuthhDlen1F4WgujPb89bgEL+IzP+JAPeYIneJ7nqUpVFIpylONe7uUJnqAZzWhNa3rTG41mDGPQaMf4rJvdVnCwAtAKMitEraC1gtk1xs8KV9uTfQpTHOO3HihNemUI+7o00viJn2hIQ+7kTkpSklKU4gEe4H3e51M+5Td+y/Y66k1v9rLX7fNW8NlyY/ZvZqth2P22fJnrfdJVtC9kIa1oxdu8TVWqchmXcQ3X8A7vOGIRO6V1YsyKL1j+xaPsf7UOk0a/yoS08XSlK/7405jGPM3TNKAB+5PEBVwU6KiU+lspVV0pVUIp1UsptUspVdrN8TOVUnOUUlcqpa5SSs1VSk11c6yTALSrsXjiGcIQhwC0q7HCXmJAEATfJZFExjLW4WKzbrswwhyuRteuJO7iC/MqAD3dunpT3B1n4+SsS9u1zZ4dv+v5lrAEjWYYw5xeZ48LIIAP+IBAAqlBDR7kQUpQgku5lIpU5BVe4SmeoiMdaU3rTEkmtvSW/RztT8as3hRSHBa+ZJI5ylGnY+3+MML4kz9ZwQqHgI0hhvd5nx70oBGNqEQlSlGKR3iEetSjJS3Zwx7AFCHXmIL/7jjLWTSmpJk7bDKRFb92LNblawWgFeuuAnAZy5wEoi1bZj+jTnTiTd7kO77jBV6gLGVRKEpRigpU4Bqu4WqupiIVuZRLHdbu13mdVrQSAVhE+Esp1TbD48uUUvuVUu9kceyNSqk0pdQ9Gfbdd25f1SyOz9ICaC9k184fgiAIhZGc2lra7N2csoRdY+FyGzPnWhnBVXC6ukQ9FabuBKU9zwQmoDGuXevedT1Pd7qzkY28wzv448/93M8DPEAJSqBQlKEMtajFu7xLF7rwMi8TRxwtaMEqVtGZzpnGM5e5jseb2eywaO5kJ9/xHbOYxed8zsd8zFM8xQM8wJVcySVcQlnK0oQm9KUvS1nKaU47fr+sxKgVhFlhx5Vd7Lm7erI5feaWXexCo1nJyiyPt3GTe9nLn/xJEEF0ohMrWMEHfOBIjJrLXL7kS0f9W/t6EYC+TzllxNujLvt/VEr1zeL4V5RSp7LYn6yUesnN+VmbtDZLy56djEQACoJQlHH1fmSVxJBT1mx2fdNz21/dtSSOuy5HrskdrkLyBCfww49f+ZWJTMQff4IIyrGPu81+XsQiWtCCIIJ4l3epRz2qU51qVOMKrnAkypSkJGUpy9VcTWUqcyM3ci3XUpOaVKMalahEmXM/Nv7yeq6nGtWoQQ0+4iPa0c7hInYtq5KVALT7trPd7d/zX/4lkMBs/+Y5WWPddaZx1+LQ3evDCSeQQCKIyJPYFwHo+1RVRgDe4bJ/rFJqaBbHN1dK7cli/16l1NtZ7HeyALr7AogAFARBKDhcLZjWUmktk+6K3GdXMqsPfVjCEqeWaDmVg3FXestV+E5jGh3pyHSms4pVjGMcgQTSne68xVuOBJWv+IrOdGYQg/iGb9jIRofnyQq+nMrTWNdsLLGMZSyzmOWUMZxViNKf/Ek44bn6rHMSxe7ex7UhgevfzIp5G7c5nOHZWqFdrdHDk4aLAPRxzscCeDKL/dlaANu0aUO7du1o164dCQkJEusnCILg44xhDL/wC3OYk6kjxvmSm3tHP/qxne0EEshylmc6fiYz3RaEzu17DWMYv/O729euZ322fYDz+jvl5XjX5wcwIEvrZlYkJCQ47tVt2rQRAVgEyCoGcJ9yHwOYqjLHAKaqXMQACoIgCEWDBBKYyUxiiWUFKy7Y+45lLDOYgT/+nOVslse4awmXW6KJZjWr3T6fUx/gC4lNhsnr75qUlCQCsAjQQSm1Q5nSL6WUUj2VUjuV+yzgeKVUglKqolLqamWshVPcHCsCUBAEoQiyilVEE00YYWxj2wV5z0QSGc5w/PGnJz3dWtM8DT+awASWstTt8/OY5zWrp6ec7+8qArDooJWJ7TuunOsA3qBMbcDHMxxbQSkVo5Q6okwtwNHK/QUiAlAQBKEIsp3tjkLWRzl6wd7XZr9mJ3o8FYDxxDOPeW6fn8Y05jP/vM7tLTwNtRIBKHiKCEBBEIQiRiKJTGe6IwlhJjMvWJz3CU7kuwCcy9xs+/DGEXdB3d75gQhAwVNEAAqCIBRB0kjL1GHjQmG7uLi+r7cSEH/iJyYy0e3zUUTl2CnkYkcEoOApIgAFQRCKKJFEFogAzO8SY6tYRQwxbp8fwIALFveYX4gAFDxFBKAgCEIRxbbE8zUB+Bu/EUWU2+dz6gNcGBABKHiKCEBBEIQiyoUu9n+haswmkshABmb5XAopFzzxJT8QASh4ighAQRCEIoqvdnvaxS760jfL52wrtRRSLvCovIsIQMFTRAAKgiAUUXxVAB7kIAEEZPncHvbQhz4XeETeRwSg4CkiAAVBEIoYvt7u8zjH0egsO41k1we4MCECUPAUEYCCIAiCT2Hj/I5xLNNzG9jAcIYXwKi8iwhAwVNEAAqCIAg+R096coADmfYvZzljGVsAI/IuIgAFTxEBKAiCIPgc/ejHTnZm2j+PeUxnegGMyLuIABQ8RQSgIAiC4HMMYhBb2Zpp/3SmF3gfYG8gAlDwFBGAgiAIgs8xnOFsYEOm/WMZy3KWF8CIvIsIQMFTRAAKgiAIPscYxrCSlZn2uxOGhQ0RgIKniAAUBEEQfI5JTGIJSzLt94U+wCACUPAcEYCCIAiCzzGTmcxhTqb9fejDHvYUwIi8iwhAwVNEAAqCIAg+x3zmZ8r29ZU+wCACUPAcEYCCIAiCz/EzPzOe8U77jnLUJ/oAgwhAwXNEAAqCIAg+xxrWMJrRTvt8pQ8wiAAUPEcEoCAIguBzbGITQxnqtG8b2xjAgAIakXcRASh4ighAQRAEwef4i78yiT1f6QMMIgAFzxEBKAiCIPgc//IvQQQ57VvOcuKIK6AReRcRgIKniAAUBEEQfI7DHMYPP9JIc+zLKjO4sCICUPAUEYCCIAiCz3GSk2g0pznt2Ded6cxjXgGOynuIABQ8RQSgIAiC4HOkkopGk0T6/c1X+gCDCEDBc0QACoIgCD5Jb3qzj32OxyMYwXrWF+CIvIcIQMFTRAAKgiAIPkkIIexgh+NxOOH8yZ8FOCLvIQJQ8BQRgIIgCIJPEkEEm9nseOwrfYBBBKDgOSIABUEQBJ9kJCNZxzogvQ9wxpjAwowIQMFTRAAKgiAIPkkccaxgBQDHOIZGc5azBTwq7yACUPAUEYCCIAiCTzKVqSxiEQB72UtvehfwiLyHCEDBU0QACoIgCD7JbGaTQALgW32AQQSg4DkiAAVBEASfZCELmcpUAH7jN6KIKuAReQ8RgIKniAAUBEEQfJIVrGAsYx3/95U+wCACUPAcEYCCIAiCT7KOdYxiFGD6AE9jWgGPyHuIABQ8RQSgIAiC4JNsZjORRAIQT7zP9AEGEYCC54gAFARBEHySHewglFAAxjGOZSwr4BF5DxGAgqeIABQEQRB8kr3spQ99AN/qAwwiAAXPEQEoCIIg+CRHOIJGk0Ya4YSTSGJBD8lriAAUPEUEoCAIguCTJJOMRnOKUwQSyL/8W9BD8hoiAAVPEQEoCIIg+CRppOGHH4c45FN9gEEEoOA5IgAFQRAEnyWQQBJJ9Kk+wCACUPAcEYCCIAiCzxJGGCtYQS96FfRQvIoIQMFTRAAKgiAIPssQhjCTmYQRVtBD8SoiAAVPEQEoCIIg+CyjGU000T7VBxhEAAqeIwJQEARB8FnGM54wwogltqCH4lVEAPo+TZVSfyilTiilNiqlXs3h+O5KqRSl1FGl1LFz2zHZHC8CUBAEQfBZpjENP/yYytSCHopXEQHo2zyqlDqllGqslCqmlGqilDqplKqRzWu6K6WW5OE9RAAKgiAIPsuP/IhGM5e5BT0UryIC0LcZoZSa5LJvslJqWDavEQEoCIIgFHkSSSSBBKKIQqMZznASSPCZbiAiAH2btUqpTi77vlNKrc7mNd2Vcf3uU0ptV8b9e3M2x4sAFARBEHyWZSxDo1nN6oIeilcRAVg4GamUSlNKpZ7buv5bcO64P5VSn7i8trVSams2566ulLrh3P8rK6Vizp2ntJvjRQAKgiAIPssa1qDRbGJTQQ/Fq4gALJyUVkpdlc2/sueOOx8LoCuXKxNHWM/N8+WUUrRp04Z27drRrl07EhISCvq6FgRBEASvsJGNaDQ72FHQQ/GYhIQEx726TZs2IgB9mBFKqYku+yap7GMAXblcmcSR59w8LxZAQRAEwWfZxjY0mv3sL+iheBWxAPo2jyoj3hopkwX8qjLlYLLLAn5dKVXx3P+vVUqNVkr9pZQq4+Z4EYCCIAiCz7KLXWg0xzle0EPxKiIAfZ/XlKkDeFIptUmZkjAZ+V0p9W2Gx9OUSQA5rpTaqUwSyC3ZnF8EoCAIguCznOAEGk0yyQU9FK8iAlDwFBGAgiAIgs+STLIIQEHIAhGAgiAIgs8iAlAQskYEoCAIguCziAAUhKwRASgIgiD4LCIABSFrRAAKgiAIPosIQEHIGhGAgiAIgs9hewHPYhbDGMYsZkkvYEHIgAhAQRAEQShkiAAUPEUEoCAIgiAUMkQACp4iAlAQBEEQChkiAAVPEQEoCIIgCIUMEYCCp4gAFARBEIRChghAwVNEAAqCIAhCIUMEoOApIgAFQRAEoZAhAlDwFBGAgiAIglDIEAEoeIoIQEEQBEEoZIgAFDxFBKAgCIIgFDJEAAqeIgJQEARBEAoZIgAFTxEBKAiCIAiFDBGAgqeIABQEQRCEQoYIQMFTRAAKgiAIQiFDBKDgKSIABUEQBKGQIQJQ8BQRgIIgCIJQyBABKHiKCEBBEARBKGSIABQ8RQSgIAiCIBQyRAAKniICUBAEQRAKGSIABU8RASgIgiAIhQwRgIKniAAUBEEQhEKGCEDBU0QACoIgCEIhQwSg4CkiAAVBEAShkCECUPAUEYCCIAiCUMgQASh4ighAQRAEQShkiAAUPEUEoCAIgiAUMkQACp4iAlAQBEEQChkiAAVPEQEoCIIgCIUMEYCCp4gAFARBEIRChghAwVNEAAqCIAjC/9u7uxCpyjiO41/TtNQ2qososyKCxMSwiMpMMbQoxKukC0GxFyJXDCErqHSjzKA3oqsiEiKri26iKOtCKopueqeXi6iMVfOlrDXtBXzp4n8Gz56dOTPrnJk9M/v9wMPumfOc4XD+e+b89pnz0mEMgGqWAVCSpA5jAFSzDICSJHUYA6CaZQCUJKnDGADVLAOgJEkdxgCoZhkAJUnqMAZANcsAKElShzEAqlkGQEmSOowBUM0yAEqS1GEMgGqWAVCSpA5jAFSzDICSJHUYA2B3mwm8DewEjgDXNrjcQ8AO4C/gfeDinL4GQEmSOowBsLtNA24FLgMO01gAXAv8AkwHJgCPAtuBiTX6GwBLZMuWLSO9CkpYi3KxHuVhLcrBADh6NDoC+BOwKjU9FtgDLK3R3wBYImvWrBnpVVDCWpSL9SgPa1EOBsDRo5EA2JP0uyLz+rvAEznLGABLwg/W8rAW5WI9ysNalIMBsDNtIoLa4eRntm2tskwjAfCcpN9FmddfA56vsUwPcLS/v//owMCAbYRbb2/viK+DzVqUsVmP8jRrUY7W399vAOxAE4HTc9opVZZp1QjgFOIPyGaz2Ww2W+e1KairNXMO4G5qnwM4hvjj6bHZbDabzdZRbQpxHFcXmgCcRATA65PpsTn97wa2Ebd+ORnYAPRT+ypgSZIklch5HDtXMN3Wpfp8A9yXWa4P+BU4QP37AEqSJEmSJEnqZsN5aoiKsR44BOwntvt+YHNq/kzgA2IEd3vSX8W4GfgQGCBG00/IzG9k27vPFKNeLY4AfzN4P8lua2tRjI3A10QtdgCvEHeVSJsKvEnUYQ/wLDAu06cX+JnYfz4FrmndKnetRmqxDfiHwfvGjZk+1kK5hvvUEBVjPXHgq2Yy8ei/R4DxwAziHM672rNqXW8hETxWMDR0NLLt3WeKk1cLiAA4P2d5a1GcDcAsItD1EP+QfpGaP4YIJZuASUQY/Ap4OtVnCfAHMCd5n5VEOPEK1eGpVwuIYLci5z2sheoa7lNDVIy8ALgc2MXgg+Fq4IdWr9QoM4+hoaORbe8+U7xqtYD6dz6wFq1zCVGTU5PpecB/wGmpPouJUHFiMr0VeDLzPp8D97duNUeFbC0gAuAtOctYC+XqYfj3DFQx1hMfnLuJHXkzcH4y7yngnUz/q4gPgMltWr/RoFroqLft3WdaIy8A7gT2El9h3ZaaZy1a6x4iYFesBr7P9DmLqMGMZHofMaKb9hzweitWcBTJ1gLiuLEL+I0YmV3L4K/jrYVyHc9TQ1SM6cRXKBAfoi8To0wTgReAVzP9pxEHyLPbtYKjQLXQUW/bu8+0Rq0AOJ/4ancccANxULsjmWctWmcB8Q/qwtRrDwCfZPpVbk82O5k+RNyqLO0x4L0WrONoUa0WEOfzTSL2mdlEINyYmm8tlMv/oMtjPHFC7wIcAWwXRwDLo1YAzFoPfJT8bi1aYxFx7tjizOt5I4CVC28cdSpWrVpUs5w4/7XCWqiu4T41RK0xnrjacSGwDM8BbIdqoaORbe8+U7xGA+A64OPUtLUo1lIicCyoMm8u8C/VzwEcn0xvZWj4/gzPOzseebWoZhlxxXCFtVBdPjVkZCwBzkh+PxN4iTiYTSJGmnYADxNfscwgrnT0KuBinEB8rXgdETomJtNjaGzbu88UJ68Ws4BLiQsMxiZ9fidubVFhLYqziggcV9eYPwb4EniR2E/OJa5MTV8FfBMx8jSHqNudxO1JvPJ0eOrV4kJiG1f2lSuBH4HHU32shRrSh08Nabc3iJGKA8QBazNwQWr+DOIq4YPESfAPtnsFu9hyBj9dp/L73GR+I9u+D/eZIuTVYhHwHTHCtI8IG7dXeY8+rEURjhBX+e5n8L3l0iFkKvBWMm8v8AzHrgCuWEmE8oPEhTtzWrnSXapeLS4nwvgA8CfwLXAvQx8Ray0kSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZLUBv8DqYUPrITR7dgAAAAASUVORK5CYII=\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(14, 15, 13, live=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Go further than step 250 to capture some zeros beyond the red band to allow the spline fitter to do its job more properly\n",
"* Move the entire screen further down and further increase range to properly capture blue rolloff\n",
"* Decrease amplification to avoid clipping. Maybe change amplification midway for green channel. Currenlty set to 5GOhm using 10M transimp feedback R with 1:10 T feedback and ~1:50 gain voltage amp stage. Maybe go back to plain transimp amp with 10M gain, for a total gain of 500M\n",
"* Decrease VGND bias to allow for more headroom"
]
},
{
"cell_type": "code",
"execution_count": 96,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdd3xTZfsG8Ju9pwgoAgpuQQVfZQoOhgNFHIiKihO0IPYnKLxuUJwo4sKJoii8LkARBBEUVNBSVhmy2zIqo7R00ia5fn/cLZSSNElPkic55/r66UeanHNyp02bq88UISIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIqt0UickhEDopIhoisEZH7TRZUysMi4hGRMSVuO01EpotIqohkisgGERlh4THqiEiyiLhFpGKJ2+8TkfUickBE9ovIbyJyiYXHmSD6XO4udfu5IvKriGSLyA4RedrCY4iIdC96nIp+jrtMRH4WfW4eEWnl5ZjeIrJM9LWxW0Qmi0gDP9etLyJTRb9u6SLymYjU81LfwaKPLBFJ8XNNEf9fp6dFxFXimgeL6ijLWBFJFP0Z+M3L/e+WuFbxdT0i8rqf694o+trJEZG1ItKv1P1nisiPIrJXRPaJyEciUruM61UtquWfojpSij6vX+KYW0vVelBECkVkhZ9aiYjIgRbK0eHqJtEgdLGZco5yhohsEZGVcnSNF4lInIicWPT5+aKB4KFyPs5HIjJHjg2ALUWkUdG/K4h+bXJF5LhyPEZ3EVlVVGfJAFhbRHaJyHOib/JtRIPt8HI8RrFLRJ9LJT/HdRCR20XkyqLjSwfARiKSJyLxos//ONEA9rmf684WkXmiQbGhiMwXkRkl7u9e9HgV/FynpEC+Tk+L9xBXljtF5GoReTPAc9uK1t6ujGM6iH7drhORyiJyvejrpn3R/XVEA9yYovuPF/1D7JsyrllTRJ4X/ZmoICJNRMP7t2WcU1k0tMeXcQwRETlU6QAooq0S/+fnmG1yJMi0FG0VuUM0rB0UkT9EWzmK9ReRJNGWpL2iAaEsFUVkqYhc6+PxS3tdRL7zc4w314i2cF0mxwbAkiqJyA1Fx7T3cYwvdURkY9F5Jb9uIhpA0ko97kMisqmM63UXkd9FW472i8gCETmv6L7momHDLUdag0b5qa+leA+A5xfdXqfEbXGiLVq+tBB9LbQpcdu5RbedVKL+QAJqSYF8ncoTAIM9d5KI/OnnmI/l2DD3rYh8UPTvK0W/NyVdLtp6eaIErq9oK6svA0RbIOuXcQwRETlUyXBVSbQbyS36JuXtmGLeAuA8EWks2kLzVdF5IiI1RLvYuhd9XlX8d6U+Idp16OvxS6okGjyf9HPN0o4Tke0icpYcCSWlA2Ab0TfZwqL7pwX5GCIiH4p2NYocGwBfE219LKlT0WP56hLsJCIdRZ93LdFQsl20xUck+BY2XwFQRFvuHiu6dlMRWSxlfy+uFW39Ki1fRPqUqi9ZNNTNF5FufmoM5Ov0tGiw+lf06zxVRE72c91igQTAOqKBemCp298WkVklPk8U/ZqVNFpEEor+fZVoN3bJ708v0edydYnbDoiGOF/eEZFfyrj/V9HXHhER0TEWirYYpYuGnAI5djxdoAGwS4n7i9/kRDQAZonIAxJY9+l5ooGmuOXCXwD8ULR1sVYA1y5puugbs4jvAFispojcJSKDg3yMq0RktRwJZ6UD4Ici8mWpc84sqiXQ1qAGol//c4o+9/dcSisrAPYT7WotKDpmruj305eBot2OpaWJ/nEhot2XbYvqqyUij4iGxnPLuG4gX6ezRVtARUROEO2q3iz6vfMnkAA4VLT1uqqf4zbLsa+TIaKtwCI6HnK3iLwgItVFpJloWHOLyC0B1Cqire2ZcnRLa0ltRF8TwbZWExGRQ5QMV7VE5H3RlryKPo4pVjoAlg4QpUNIF9FusH2iY+F8jderXHT/dX4eX4quPbno+ON9XM+XASLyd4n6LpHAuiXXytGtNGWpL9rKdUGJ20LRAthWtMVph2iX+oGi4y8tuj9UAbC7aMtt36Jr1RPtxvy96P7iSQfFXc0nibYA5np5jJItgN4sFB3fJ3Jk4kWW6KQkkfJ9naqKBsseZTxusUACYJKIvBjAtfy1AIpo9/o80dbKjaITrzwi0jOA698vGkQ7lnHMO6JDG4iIiLwqHa6qik68GFbitlkiMr7E55VFxxYFEwCl1H15ouOeSiu+1h7RN7m9oq1POXIkDBTX+a3oeKx6ErzJogGj+DEyRN+A94hOjPBloxw9PrIs3UVrL/lcXKItNz8WHXOHBD8GcINoIKpb9Hn9otovK/r8YglNAPw/OXYGaduix/IVuFsUXav0GEC3HBkD6M0C0UkOvpTn61RVNIwGEqr8BcBLRL93pwRwrY9F5OtSt30jR8YAetNX9PVYp4xjRDRYpknZraW1RV9jd/i5FhEROZi31rU7RcNK8ZvRU6JvtCeIdv+9ItoyVLoL2FcAbCK6LEZxUDtfNNB1l2NVEO3SK/nxh+gkjyZFx9QSDQwLxXe3b3FNvsaW1Sv1GDfKkZBS3MV5vxzpUqwjIs+KtmSVfPNdJPqG700VL88lRbTLs7grvLaI7BQdI1hdNDglS9mzgHeJyDOiX6uGomHWLUcC4GlFn59dxjWk6PxqojNLPaJjIavJkZDVQTRAXVN0bB0Rea+ovrJ8L9pVfJzoTOKf5OgJOr1Ex+ZVEP1aDxf9g6Cs7spAvk43yZGvaxMRmSIiW6XsoQGVi673nOj4xmpFH6X9T3R2cyCKv259i67fT/T1XvL5tRftmq4kGti3iv8/LF4SbfU9w89xD4r+/Hp7HkRERCKig8hLB8CKomuYFXfJ1RGd/JAhOjbvftE3rEBbAJuKLlmxT7SrcKMEt8xJ6RrvKLp2jhzpfizZXVj8+Psl8NZBby2W74mOfyueWDBfjnSzFtsqZbcYllby61asjWjrU45ouPM3meUKEVknOsZygxyZnXxZiWNeL6o5XUQe9XGd4vX43KU+SrYcDRBtBTwg2pI5W3yPOytWX3T8XXH39BQ50lopohN8kovq3yMa5r39MVCav6/TTNHnnC36fZsq3sc1ljRZjv4aFP+7pCaiwf8qH9d4V44NhzeI/gzlin6vrit1/9uiPw/Zoq/bu7xcN0uOjAksnl2dL0evSVjc9V7SahF52UetREREtvacaEtbOJ0qOv6QiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiMiZXhCR1SKSKSI7ReQLETnJzzmTRaRARA6KSFbR/18IY41EREREFELPi0g7EaksInVFZKqIrPBzzmQRmRLmuoiIiIgoQs4TEbeI1CvjGAZAIiIiIht5VES2+jlmsoiki8heEdkkIu+KSKMw10VEREREYdBDdExfTz/HtRORxkX/biUi80TkjzDWRURERERh0EdEDojIteU4t6WIeETkVC/3VRCRZqLjC/nBD37wgx/84EfsfDQTfR8nm7pNNPz1KOf5LUTHDZ7m5b5mIgJ+8IMf/OAHP/gRkx/NhGxpqGj46xLg8dVE5AbRvwxERE4WkTkisszH8XVFBKmpqcjMzHTUR1xcnPEa+Lz5vPm8+bz5vPm8y/ORmppaHADr+nh/pxjnEZFDomv5lVzXr2QgzBKRW4r+XUNEfhOR/UW3bxORd+TImMDS6ooIMjMz4TTx8fGmSzCCz9tZ+Lydhc/bOTIzMxkAyRIGQIfh83YWPm9n4fN2DgZAssqxAXDu3LmmSzCCz9tZ+Lydhc/bORgAySrHBkAiIqJYxQBIVjEAEhERxRgGQLKKAZCIiCjGMACSVQyAREREMYYBkKxiACQiIooxDIBkFQMgERFRjGEAJKsYAImIiGIMAyBZxQBIREQUYxgAySoGQCIiohjDAEhWMQASERHFGAZAsooBkIiIKMYwAJJVDIBEREQxhgGQrGIAJCIiijEMgGQVAyAREVGMYQAkqxgAiYiobBkZQEoKkJwMrF+v/09J0dvJCAZAsooBkIiIAuNyAQkJ+n8yigGQrGIAJCKiwDAARg0GQLKKAZCIiALDABg1GADJKgZAIiIKDANg1GAAJKsYAImIKDAMgFGDAZCsYgAkIqLAMABGDQZAsooBkIiIAhPOAMilZoLCAEhWMQASEVFgItECyFbGgDAAklUMgEREFBgGwKjBAEhWMQASEVFgtm7VcJaSAhw4ABQWhv4xGAADwgBIVjEAEhFRYL79FvjwQ2DZMmDNGg1qSUnAtm3A3r1AXh7g8Vh7DAbAgDAAklUMgERE5F9hIXDGGUCdOoAIUKsW0KYN0KcPMHgw8PTTwDvvALNnAxs2AGlpQHY24HYH9zgMgAFhACSrGACJiMi/gweB6tWBr77SfyclATNnAuPHAw8+CPTuDbRuDVSurB8nnwx07gz07w+MHg1MngwsXQpkZZX9OAyAAWEAJKsYAImIyL/ERA12S5eWHc4KC4EtW4CffgLefhsYPhy48kptPaxeHahQAWjSBOjQAbjtNmDMGGDaNA19Bw4wAAaIAZCsYgAkIiL/pkwBWrWyFs48HmD7du0mHj8eGDIE6NULOOccoH597Vpu0gSYMIEB0A8GQLKKAZCIiPwbPRq44orQt8653dqlvGsX8Pff2iJYowbw0UehewwbYgAkqxgAiYjIvxtvBOLjw989m50NTJoE1K4NvPii9VnFNsUASFYxABIRUdk8HuD884H334/cQtBffQU0aqShM9iZxA7AAEhWMQASEVHZ8vJ0jN4ff0QuAObnA/PmAc2bA7feChQUhO8xYxADIFnFAEhERGXbvFknaBw4ENmt4Nxu4M8/gbPO0ski2dnhe9wYwwBIVjEAEhFR2b77Dmja1MxewB4PsHo1cNFFwH/+ozuOEAMgWcYASEREZRs7FujUCUhOBtav1/+npAAZGaF/LG8h0+PRtQV79ABOO02XknE4BkCyigGQyGYyMvS9ORLv1eQQd94J3HdfZB6rrFbGnTuBm24CTjxR9yJ2MAZAsooBkMimuKEChYTHo1u6vf56ZB7P3wt33z5dQLpePWDx4sjUFIUYAMkqBkAim2IApJAoKNAWt59/jszjBfLCzcgA/vtfoGZNYNasyNQVZRgAySoGQCKbYgCkkEhL0/17d+0K7+MEO3YhOxt49VUNgYHsGmKzsREMgGQVAyCRTTEAUkgsWADUqROdO3Lk5Wn4q1MHGDcusBpt8oPBAEhWMQAS2ZRN3ufItDffBNq3N12Fb4cOAV9/DRx/PDB8uP9dQ2zyg8EASFYxABLZlE3e58i0uDhgwADTVZStsFB3DWnZUms9dMj3sTb5wWAAJKsYAIlsyibvc2Rar17AmDGmq/CveNeQs88GevYEsrK8HxfOH4wIjjNkACSrGACJbIoBkCxzuYDWrYFvvzVdSWCKdw3p0AG44AJgz55jjzGxm0kYMACSVQyARDa1fz8DIFmUmQlUqQL884/pSgLn8ejexb166a4h27YdfT8DIJGIMAAS2VJ2NjB9uo6NZwCkcvv7bw2AhYWmKwnerl3AzTfrHsarVx+5nQGQSEQYAIlsp6AAmDYNqF1bt06NxfduihKTJwOnn266ivLbuxd48EHdNeS33/Q2BkAiEWEAJLIVjweYPRto2FAbP447LmbXuaVo8NhjQJ8+pquwJiMDeOIJXTB6xgwGQKIiDIBENrJkCdC4sb7fZWcDVaseafggClq/fsDIkaarsC4rCxg/XkPgpEkMgETCAEhkG2vWAM2aAUOHakugywW0awc895zpyigmeTxA27baDWwHubnAxx/rriF3360TRcKFAZBiAAMgkQ0kJwOnnALcfvuR3bBcLn2f69MnOnfxoiiXl6dhafly05WETvGuIeeeC1SuDDRvDgwcCHz4IbBxY+h+UBgAKQYwABLFuH37gLPOAq655uj3G5cLeOst4MQTfa+JS+TTP/8AIkBOjulKQis/X8PZ8uXAu+8C99yjW91VqQI0aQJcfz3wxhtAUlL5AyEDIMUABkCiGJaVpevdXnKJvq+V5HIBv/4KVKoE/PWXmfoohn39tY4psJuS4czj0WnzmZm6XuCXX+oYigsvBKpVAxo0AK64QsdRLFly7A9ZII8RJgyAZBUDIFGMys8HunfX96qDB4+9v/g96PzzgVdfjXh5FOvGjtW/LOwmkHDm8WgonDMHGDUKuPhinUBSp47+0D32GPD998Du3Trbyu0O/jEsYgAkqxgAiWJQYaGO7WvTBvj3X+/HFL8HDRsG3HADxwFSkAYOBAYPNl1F6JU3nBUW6l7Dzz0H9O4N1K0L1KoFdO4MxMUBn30GrFsH7Nyp4zIYACnKMQASxRi3G7j1VuDUU71PZCy9H/377+sEkd27I18rxbCOHYGJE01XEXqhap1zuYAVK4AJE4DrrtNFN6tXBzp10sWnp09nAKSoxgBIFEM8HuCBB4AWLfQ9LBD79gEVKhy9GxZRmQoLdULEwoWmKwm9cHXPejzA2rXAO+8A3brpTGMGQIpiDIBEMeSxx4ATTgAWLAiuS/fMM4E33wxfXWQzu3bpDOA9e0xXEnqR2Ank++91iRkGQIpiDIBEMWLcOKBRI2DmTJ24GIz77wduuYXjAClA8+cD9eubriI8IhEAly3TCSNh3IibAZCsYgAkigFvvaXvx9Om6aTDYH35pbYCcj1ACsiECTq93I4iEQC3b9cW1DD+wDEAklUMgERR7pNPtDFhyhRg797yXWPnTqBiRWDDhtDWRjY1ZAhw222mqwiPSATAnBwNgFu2hO0hGADJKgZAoij29de60sTHH2ujghUnn6wzgon8uvxy4PnnTVcRHpEIgC6X/uD+8UfYHoIBkKxiACSKUnPn6tqzH3ygy7mUXms2WLffDtx1l/XrkM253frXwowZpisJj0gFwGbNwvo1ZAAkqxgAiaLQb78BtWsD770HrFype9hb9fHHwHnncRwg+ZGZCVSuHNbuS6MiFQDPOUf/egsTBkD7e0FEVotIpojsFJEvROQkP+dUFZG3RWRv0XmzyjiHAZAoyiQk6CYDEycCiYnet3krjy1bdL97u76vU4gsXar74Nqtqbj0CunJyfp5RkboH8vlArp21an7YcIAaH/Pi0g7Eaks+k2eKiIr/JzztoisFA19tUXkUxFJ9HEsAyBRFFm7VjcUePllYNUqIC0tdNf2eHQNwSlTQndNsqGPPgLOOst0FbHN5dK9Gv/v/8L2EAyAznOeiLhFpJ6P+6uJSI6I9Clx23EiUiAiXbwczwBIFEFlNUJs2aIB7amndLbu1q2hX7fvppt0gqfdGncohEaMAPr2NV1FbHO5dC/lO+8M20MwADrPoyKytYz7zxUNiE1K3f6PiAz1cjwDIJEBpYch7dih4+7j4zUUrl0bnpD29ttAhw4cB0hluPZaYNQo01XENpcLGDpUWwHDhAHQWXqISJaI9CzjmK6iAbBaqduXish/vRzPAEhkQMkAuGePLtJ87726zt+KFUB+fngeNylJ96u3uqQM2ZTHA5x9NvDZZ6YriW0uF/DEE0DnzmF7CAZA5+gjIgdE5Fo/x7EFkCgGFAfAffuAdu2Am2/WyR6JieEZk17M7QYaNgSmTw/fY1AMy8/XtYdWrjRdSWwqOcZj4kT9yy5ME00YAJ3hNtHw1yOAY72NAWwkIoekjDGAcXFxiI+PR3x8PObOnRvyFyoRHc3lAhYvBjp1Aq6+WjcOWL0a2LUr/I99zTXAQw9xHCB5sW6dbhmTl2e6kti3YAHQtGlILzl37tzD79VxcXEMgDY3VDT8eQtvvrwlOuu3uYjUEZ0FvNzHsWwBJDIgJ0fH4nXvrv/euBHYtCn0kz68efVVoFs3jgMkL/73P6BFC9NV2ENSki6nE6b1BtkCaH8e0da7g0UfWUX/LxkIs0TklhKfVxWRN0VkX9Gx34tIMx/XZwAkijCXC7jhBl0n9sABnQCyZk1416Ut6e+/dW/h1NTIPB7FkGeeAXr0MF2FPezbp/sBp6eH5fIMgGQVAyBRBHk8wLBhwOmnAz//rO8RiYlAbm7kaigs1G1KZ86M3GNSjLjlFiAuznQV9uB2a3f6+vVhuTwDIFnFAEgUQS++qMOCNm3SSSCJiWFrIChTjx7AyJEcB0ilXHihrhVEodGwIbBwYVguzQBIVjEAEkXIJ5/oFm8rVujevgkJOkHQhOee0xDIcYB0mMul29D89pvpSuyjdWsdVxkGDIBkFQMgUQTMmaOrayxYoOFv7VoNgIWFZupZvBho1AjYudPM41MU2rEjrGPWHCmMLaoMgGQVAyBRmP31l066+PJLIDtbl1jbtu3onUAiLT9fJyhy1Sc6bO5c/auAQueKK3RiTRgwAJJVDIBEYbRxI3D88cDrrwP79+uYv7Q0bfkzGQABoGtX3ayA4wAJADB+PNCxo+kq7OW228I2qYYBkKxiACQKk7Q04JRTgEce0QWeS+7yUXovYBMef1y3KuU4QAIA3H8/cMcdpquwl+HDgQEDwnJpBkCyigGQKAwOHgTatwduvRXYvFl3+Si51Es0BMB584BmzSKz+wjFgEsu0WnqFDpjxwK9eoXl0gyAZBUDIFGIHToE9Oyps2xXrdJlwAoKjj4mGgJgVhZQqVLYVqmgWOLxAM2bA99/b7oSe5k0CbjggrBcmgGQrGIAJAoht1uH/Zx/PvDnn8DWrd7H2EVDAAT0vWnsWI4DdLyMDF20ODnZdCX28t13QKtWYbk0AyBZxQBIFEIjRwInnwzMn69dq7729o2WAPh//6fb0h08aLYOMuz334EaNSKzGbWT/P470KBBWL6uDIBkFQMgUYiMH6/r6M6Y4X8ptWgJgDNn6lq1HAfocO+/D7RpY7oK+9m8WVtWS48BCQEGQLKKAZAoBKZO1f11p07Vtf78iZYAuH8/UKEC8McfZusgw+LjgeuvN12F/WRl6eLaYVhxnQGQrGIAJLJo3jztPZs0SSeABCJaAiCgDT8vv8xxgI529dW6LhCFXvXqugZUiDEAklUMgEQWLF0K1K4NvPJKYGEuI0P3/01O1tnBycn6efH6gCY8+KAuV8NxgA7l8QBnngl88YXpSuypadOwbLnDAEhWMQASFQk2nK1apTtnjRoV22Pnp00DzjmH4wAdq3hfwKQk05XY09lnA1OmhPyyDIBkFQMgUSmBdM+uXw+0bAnce29shz9AhydVrKjPmRxozRpdEDLQ8QsUnK5ddYZYiDEAklUMgESllBUAPR5gwwagbVugX7/oGMMXCq1bA2+8wXGAjjRtmu5ZSOHRt692E4QYAyBZxQBIVIqvAOhyAevWAd26ARdfDOTlmakvHO66Sz84DtCBnnoK6N3bdBX2dc892lUQYgyAZBUDIFEp3gJgfr72lN14o7b+HThgrr5w+OQToF27sKxWQdGuf3/goYdMV2Ffjz2m3QUhxgBIVjEAEpVSOgBmZQErVwLDhgEtWgA7dpitLxy2bAGqVNHnSQ7Tvr2uYUTh8eqr2m0QYgyAZBUDIFEpJQPgvn26hNdLLwENG2oXsB15PMCJJ2oO4DhAB3G5gPr1uRJ4OH36qXYbhBgDIFnFAEhUSnEATE0FVqwAPvtMd/n4/XfTlYXXLbcAQ4ZwHKCjJCfrThUmF6K0uzlzgGbNQn5ZBkCyigGQqJSCAg2Aq1cD8+dr+Js503RV4ffuu0CnThwH6CizZwNNmpiuwt5WrNBfIiFeL4oBkKxiACQqZccODYCJido79v77piuKjLVrdUu7NWtMV0IR8/LLQJcupquwt127tJU1Kyukl2UAJKsYAIlKyM0Fli8HfvgBOOkk4JlnTFcUOR4PcNxxOiOY4wAd4p57gLvvNl2FvRUUaADcvDmkl2UAJKsYAImKFC/yvGYN0KoVcN99sb/LR7Cuuw4YPpzjAB3j4ot1I2sKrzp1Qj6ImAGQrGIAJCqyZ4/u73vjjUDHjrr2n9O89hpw6aUcB+gIxVO/58wxXYn9tWwJfPddSC/JAEhWMQASQbdBXbFCt0Nr2hSYN88+27wFIyEBqFtXxwOSzaWnAxUqMO1HQrt2IR9MzABIVjEAEkGH5/z4o07W++kn33sB211hofZWffEFxwHa3m+/6TfbaeMcTLj8cuC550J6SQZAsooBkBzvwAFdB/ess4DHH/e9F7BTXHGF7l7FcYA2N2kScN55pqtwhv79gYcfDuklGQDJKgZAcjSXS8f9DRwIdO2qLWBOD4DPPw9ceSV7Bm3voYc0mFD4PfggcPvtIb0kAyBZxQBIjpacrBMfGjYEUlL0NqcHwMWLgUaNgPXrTVdCYXXFFcBTT5muwhmeegq46qqQXpIBkKxiACTHysrSHT7q1tX/Z2RoCExO1vCTnKyfO22XrPx8oFo14JtvOA7Q1k47DZg+3XQVzvDmm0CHDiG9JAMgWcUASI7kduus3/PO054wOlr37tpowXGANpWfD1StymbeSJk+HTj99JBekgGQrGIAJEfauRO44w6gfXtnrvfnz5NP6qLQHAdoUytXAlWq6KBXCr9Fi4Djjw/pJRkAySoGQHKcvDzg9dd1BYyNG01XE53mzQOaN9edUciGpk7VLmCKjHXrNHCHcGAxAyBZxQBIjuLx6B/jDRoAn39uuprolZUFVKqkeyJzHKANPf54yCclUBnS03U/4L17Q3ZJBkCyigGQHGXXLuCCC4BBg0xXEv0uukiXhOE4QBu68UYgPt50Fc7h8QCVKwNJSSG7JAMgWcUASI5RUADcf7+Oxc7ONl1N9BsxAhgwgOMAbem884APPzRdhbM0agT88kvILscASFYxAJJjfPYZUKOGLvxM/s2aBZx6KscB2o7LpQNgly0zXYmznHYa8OWXIbscAyBZxQBIjrBpk/4B/tZbpiuJHenpQIUKwPz5HAdoK9u26Xi0rCzTlThLx47AxIkhuxwDIFnFAEi2V1Cg27xdcw33vVDX52sAACAASURBVA9W27bA+PEcB2grs2YBJ55ougrnueoqXV8pRBgAySoGQLK9xx8HmjXTFi0KTlycTpjhOEAbeeEFoFs301U4z+23657AIcIASFYxAJKtLVwIVK8O/Pqr6Upi0/TpQJs2HAdoK4MGAffdZ7oK54mPB/r3D9nlGADJKgZAsq30dOCkk0La6+I4u3bpOMBFizgO0DY6dwZee810Fc4zbhxw+eUhuxwDIFnFAEi25PHomL8uXUK6+L4jnXaa7mXPcYA24PEATZvqVi8UWR98ALRrF7LLMQCSVQyAZEtvvaWzfrduNV1J7Lv7bmDwYI4DtIX9+3UGcFqa6UqcZ+ZMoGXLkF2OAZCsYgAk21m1CqhZM6RLbjnaJ58AF17IcYC2sHAhUL++6SqcaelSoF69kC1FwABIVjEAkq1kZ+tOH/ffz67fUNm6VXexWrKE4wBj3ttv616IFHnbtumA2vz8kFyOAZCsYgAkW7nrLh1ms2+f6Ursw+PRyTTvvw/wV0WMi4sDbrnFdBXOlJOj3e+pqSG5HAMgWcUASLbxxRfau7VkielK7OfWW4GHHuI4wJjXsyfw7LOmq3CuGjWAv/8OyaUYAMkqBkCyhU2bdHvTCRN05w8KrUmTgIsv5jjAmNeqFfD116arcK5mzYDZs0NyKQZAsooBkGJefj7Qvj1w223A3r2mq7GntWu18WLpUo4DjFl5eUClSsDGjaYrca42bXRWVQgwAJJVDIAU8x5+WH+vrlnDvX7DxePRZXWmTOE4wJiVmAhUq8bZUSZ16wa8/HJILsUASFYxAFJMmzVLu35nzNAGDgqffv2ARx8FduwwXQmVy5QpwJlnmq7C2Yp/iEKAAZCsYgCkmJGRAaSkAMnJwPr12h1Zv77ubb97t+nq7O/114EePTgOMGaNGqXb45A5992nK6uHAAMgWcUASDHH5dLw17UrMGCAjk9j12/4LV8O1K0L/PUXxwHGpH79gBEjTFfhbKNHA337huRSDIBkFQMgxRyXC7j3XuCMM4Dff9fFnyn8XC7tbp8+neMAY1KbNsDkyaarcLbXXtO/XEOAAZCsYgCkmDN/PlC9um6tmZJiuhpnueIK4KmnOA4w5rjdQK1aQEKC6Uqc7fPPgbPPDsmlGADJKgZAiikFBbqU1qhRuucvJzRG1rhxQJ8+HAcYczZvBipWBHJzTVfibPPmASecEJJLMQCSVQyAFFN+/FED4F9/AenppqtxniVLgOOP180MkpOPTMhJTtbW2IwM0xWSV999BzRvbroKWrlSuy9CMGiZAZCsYgCkmHL77cA992hPFlv/Ii8/X9+/ZszQcYAuF78XMeH554FLLzVdBaWl6X7AIfhLiQGQrGIApJiRmwvUrq3DaBg6zLnkEu0K3rGDATBmDBwIDBliugpyuYAKFUKyGwsDIFnFAEgx46uvgFNO0X1/GTrMefJJ4KabtOuXATBGdOgATJxougoCdPHSxYstX4YBkKxiAKSYcf31wODBOvaPocOc+fN1ONny5cChQ/xeRL3iffwWLDBdCQH6V+zXX1u+DAMgWcUASDEhI0O3MZ0xAygsZOgwKTsbqFwZmDMHOHCA34uot3evjjvbt890JQQAF1wAvPuu5cswAJJVDIAUEz75BDjrLI47ixYdOgDjxwOpqfxeRL0FC4DjjjNdBRXr1QsYM8byZRgAneFmEflNRDJFxC0iFf0cv0hEDonIQRHJKvr/EB/HMgBSTOjVC3joIZ2FygBo3siROq9g/Xp+L6LexInARReZroKKDRigv8wsYgB0hp6iIfAuCSwALhSRZwO8NgMgRb09e7TL8Zdf9HMGQPNmzQJOP13HAfJ7EeWGDNG0TtFh6FDg1lstX4YB0Fm6S+ABcEyA12QApKj31ltAu3ZHhjAxAJqXnq6rWfzyC78XUe/yy4HnnjNdBRV79lndU9EiBkBnCSYA7hWR/SKyTkReEJFaPo5lAKSo16kT8NhjGjpSUrj7RLQ491ztXWQAjHItW+pOIBQd3nknJF3yDIDOEmgA7Cgi9Yv+3VZEEkXkSx/HMgBSVEtO1u5f7mEffYYOBQYNYgCMajk5ugfwli2mK6FiX30FtG5t+TIMgM4SaAD0dl6BiFTzch8DIEW1l14COnbUpUcouvzvf8A55zAARrW//wZq1ADcbtOVULHffgvJrGwGQGcpbwDsJhoAq3u5r66IIC4uDvHx8YiPj8fcuXND8AonCo22bXX4Ugj2TqcQ271bG5cWLmQAjFqTJ2tKp+jxzz9ApUrl+qGZO3fu4ffquLg4BkAHqCjaetdLNADWLPq8gpdjG4tI76JjRETOEZG/ReQrH9dmCyBFrQ0bgKpVQ7JtJoXJqacCEybo4twUhUaOBK67znQVVFJmpi7MnZZm8TJsAXSCO0XEIxr+3CX+3U1Emouu9del6NgWIrJMRDJE1//bKJwEQjHq8ceBSy8FCgpMV0K+3HgjMGwYkJtruhLy6tprdQYVRQ+PB6hSBVi1ytJlGADJKgZAikoeD9CqFfevj3ajRwN9++qWcBSFzjoLmDLFdBVUWuPGuqm2BQyAZBUDIEWlhASgZk0dZ0bR6+OPdY3Gf/81XQkdw+UCqlcHEhNNV0KlnXkmMHWqpUswAJJVDIAUlYYNA66+mpM/ot3ixTqhMSXFdCV0jOLJBvn5piuh0jp3Bl5/3dIlGADJKgZAijpuN9C0KfDpp6YrIX/+/VfHs69YYboSOsbXXwOnnGK6CvKmTx8d5GwBAyBZxQBIUWfhQqBePeDgQdOVkC8ZGUd2ZalbF/jiC+7KEnXGjAF69DBdBXkzaBAweLClSzAAklUMgBR1Bg0Cbr7ZdBUUqAsvBF54gd31UeeWW4C4ONNVkDcjRugUegsYAMkqBkCKKocOAQ0aADNmmK6EAnXbbdqYwbUAo8x//gO8/bbpKsibF1/UNa4sYAAkqxgAKap8952ukMC1/2LHmDE6YYfb9UWZBg2ARYtMV0HefPwxcN55li7BAEhWMQBSVLnhBuCee0xXQcGYNg0491xg/37TldBhaWk6Oyc93XQl5M0PPwAtWli6BAMgWcUASFEjOxuoVQv49VfTlVAwli/XiSA7d5quhA6bNw84/njTVZAvf/0F1K5taeAsAyBZxQBIUWPyZP2j2O02XQkF4+BBbWxavtx0JXTYa68BnTqZroJ8SU7WH5q8vHJfggGQrGIApKjRuzcQH2+6CiqPxo11KRiKEvfdB9x5p+kqyJf8fA2A27eX+xIMgGQVAyBFhT17gGrVLO+PToZ06QKMHWu6Cjqse3ddm4eiV+3awLJl5T6dAZCsYgCkqDBhgm6PSbHp7ruBu+5i933UaNYMmDXLdBVUlpNOsvQ9YgAkqxgAyTiPR1uQnn7adCVUXi++CFx+OZCba7oSQnY2UKGCpe5FioDzzgM++qjcpzMAklUMgGTcli1A5crAtm2mK6Hy+u474IwzgAMHTFdCWLpUuxfZHBvdLr1U/3IqJwZAsooBkIwbM0Y3LaDYlZQE1KgB7N5tuhLCBx/owowU3W68EXjkkXKfzgBIVjEAklGFhUC7dsD48aYrISvy8rTX0cKYdgqV//s/XVGdotvgwZZmajMAklUMgGRUYqJ2/6alma6ErGreHJgyxXQVhKuvBv77X9NVkD9PPAH06VPu0xkAySoGQDJqxAjgkktMV0GhcOmlwJNPmq6CcPrpwNSppqsgf954A+jcudynMwCSVQyAZExOji798uGHpiuhUBg8GBg40NLuVmRVYSFQtSoX1IwFX3xhae0rBkCyigGQjFm0SN+rOHPUHiZMAC6+GDh0yHQlDrZuHVClCr8JsWDBAqBJk3KfzgBIVjEAkhFuNzBkiKUhMBRlfvwROOUU3RuYDPnf/4BTTzVdBQVizRrd/qicy/UwAJJVDIBkxP79wMknA9Omma6EQmXzZm184lIwBj39tG6qTdFv717dDzg9vVynMwCSVQyAZMSMGUCtWjoOkOyhsFBndC9ZYroSB+vfH3joIdNVUCDcbqBSJWD9+nKdzgBIVjEAUsQdOgTccQdwyy2mK6FQa90a+Phj01U4WLt2wKRJpqugQDVsqIOhy4EBkKxiAKSI27EDOOEE4IcfTFdCoXbFFcDo0aarcJiMDCAlRff+rVtXm9dTUvR2im6tW+u4zXJgACSrGAApojwe4JNPgAYNOFHRjoYNA26+2XQVDpWSomPK9u83XQkF6sILgbfeKtepDIBkFQMgRdTBgzpM6b77TFdC4fDOO0DHjjoekCJs9mygaVPA5TJdCQWqd2/gmWfKdSoDIFnFAEgRtXEjcNxxwMKFpiuhcFiwADjxRCA723QlDvTyy0CnTgyAseS224ChQ8t1KgMgWcUASBHjcgFvvqnj//geZU+pqUCFCsCuXaYrcaC77tKZVfzhih3DhwMDBpTrVAZAsooBkCJmzx7guuuA+HjTlVC4uN1AjRrlnthIVnTpAjz+OANgLBk7FujZs1ynMgCSVQyAFDErVgB16gB//WW6Egqns84C3nvPdBUO1LixbqzNABg73nsPuOCCcp3KAEhWMQBSROTmAq+8oqseeDymq6FwuuYaYORI01U4THq6zgBesIABMJZ8+y3QqlW5TmUAJKsYACkiUlKAK68EnnjCdCUUbiNGANdfb7oKh1m4EGjUCEhIYACMJUuWAPXrl+tUBkCyigGQws7t1t9z1asDa9earobC7YMPgPbty73HPQUrIwMYNw646CLdViw5mQtBx4pNm4CKFYGCgqBPZQAkqxgAKezS04HnnwfOPdd0JRQJS5ZoY1RenulKHGTwYN1fkWJLdrZ23Zdj2jwDIFnFAEhht2kTcNllwAsvmK6EImHPHn1PS001XYmDdO/OH7BYVb06kJgY9GkMgGQVAyCF1aFDwM8/A1WqANu2ma6GIsHj0S1pf/7ZdCUOcuKJwPffm66CyqNpU2Du3KBPYwAkqxgAKax27waefVY3KCDnOP/8cm9xSsE6eFCbXFNSTFdC5XH22cCUKUGfxgBIVjEAUth4PMCaNUDnzsDEiaaroUi64Qbg4YdNV+EQixcD9epx1k2s6toVGD8+6NMYAMkqBkAKm4MHtWejcmUgLc10NRRJo0freoAUAe+8U+7FhCkK9O0LjBoV9GkMgGQVAyCFzbZtujNVjx6mK6FI++QToE0bLvodEXFxugcwxaa77wbuvTfo0xgAySoGQAoLl0sntrVrB3z0kelqKNL++kt7JQ8dMl2JA1x+OTBmjOkqqLwefRTo1y/o0xgAySoGQAqLvXuBH38EqlYFDhwwXQ1FWmamzkvgzO8IaN4c+O4701VQeb3yCtCtW9CnMQCSVQyAFBIZGToJMTlZNyNYuRIYNgy46irTlZEpjRoBc+aYrsLmcnKAChWALVtMV0LlVTxeIkgMgGQVAyCFlMul25EmJABnnglMm2a6IjLlwguBCRNMV2Fzy5YBtWtzBnAs+/FHoFmzoE9jACSrGAAppIoD4KxZQK1a2kBBzjRgAPDgg6arsLkPPtBFFyl2LV+uvyyDnDHFAEhWMQBSSBUWagB86CHg1ltNV0MmPfUUcMUVpquwuYcfBvr3N10FWbFjhw6YDfKvZQZAsooBkEJq/36dAdqiBXemcrovvgDOOMN0FTbXu7cmbYpdhw5pAAxyHCcDIFnFAEghtWkT8OGHQIMGXALE6VasAGrUAAoKTFdiY61aAf/7n+kqyKq6dYE//wzqFAZAsooBkELG49G1/266qVzrmpLN5ObqBNVNm0xXYlP5+UClSsA//5iuhKxq2RKYMSOoUxgAySoGQAqZnBzt/m3YEJg/33Q1FA1OPBGYOdN0FTaVmAjUrKkzryi2nX8+8P77QZ3CAEhWMQBSyPz7r+760agRu39Jdemi69xSGHzyCXDOOaaroFC47DLg+eeDOoUBkKxiAKSQ2bJFJyTecgsbJUjdeSdw//2mq7CpESPKtYUYRaH+/YH4+KBOYQAkqxgAKSQ8Ht39o3Fj4L33GABJjR2rW9VSGFx9NTB6tOkqKBQefBAYODCoUxgAySoGQAqJ/HydjFi9OvDHHwyApL76SieqUhicdhowdarpKigUnnoq6H0zGQDJKgZAComUFGDUKKBrV90LODlZb8vIMF0ZmbR2LVClCpeCCbmCAqByZWDNGtOVUCi8+SbQsWNQpzAAklUMgBQS27cDV14Z9DhmsrmCAl2pZP1605XYzOrVQLVqTNZ2MX06cPrpQZ3CAEhWMQBSSKxerYs/B7mWKTnAyScD33xjugqb+fxz4MwzTVdBobJwoS6fEAQGQLKKAZAsKyjQoUi1a7NBgo51ySVsGQ65UaOAa64xXQWFytq12qXvdgd8CgMgWcUASJYdOAA8+qh2AROVdu+9wKBBpquwmb59gZEjTVdBoZKervsB79sX8CkMgGQVAyBZlpqqS31wwV/y5uWXgYsvNl2FzZx1FvDpp6aroFDxeLQFMCkp4FMYAMkqBkCybPVqoE4dICHBdCUUjWbOBE46yXQVNuJy6QSQxETTlVAoNWoELFgQ8OEMgGQVAyBZ4nLpjlT163PtP/Ju40agYkUgL890JTaxfr22FuXnm66EQun004Fp0wI+nAGQrGIAJEsyM4Hhw3VIEpE3hYXaYLVypelKbGL6dODUU01XQaHWsSMwcWLAhzMAklUMgGTJzp06vuuNN0xXQtHstNOCatygsjz5JGdc2dFVV+n3NkAMgGQVAyBZsmYNUKOGjgMk8qVXL+CZZ0xXYRM33gjEx5uugkLt9tuBBx4I+HAGQGe4WUR+E5FMEXGLSEU/x9cXkakickBE0kXkMxGp5+NYBkAqN48H+Phj4Pjjg1q+ihzogQeA224zXYVNtG0LfPih6Soo1OLjgf79Az6cAdAZeoqGwLsksAA4W0TmiUgDEWkoIvNFZIaPYxkAqdyys/WN/aabTFdC0e6114AOHUxXYQMejza5//WX6Uoo1MaN0/W0AsQA6CzdxX8AbCEiHhFpU+K2c4tuO8nL8QyAVG5paTpu+d13TVdC0e7HH4HGjU1XYQNbtujmyjk5piuhUPvgA6Bdu4APZwB0lkAC4LUikufl9nwR6ePldgZAKre1a3V254YNpiuhaLd1q250kJVlupIY9+23urky2c+MGUDLlgEfzgDoLIEEwIEistvL7WkicquX2xkAqVw8Hv2D9YQT9N9EZSko0L2iuVi4RWPGAD17mq6CwuHPP4F69QI+nAHQWQJtAcz1cnuZLYBxcXGIj49HfHw85s6dG8ZXONlFXh5wzz3ArbearoRixdlnA599ZrqKGDdgADB0qOkqKByKm8kPHfJ5yNy5cw+/V8fFxTEAOkigYwDdcuwYQLdwDCCF0N69QPv2nIxIgbv6auDxx01XEePateOgW7vKzdUAmJoa0OFsAXSGiiJSTUR6iQa5mkWfV/Bx/PciMldEjhORRiLyk4h85+NYBkAql6Qk3Y1q61bTlVCsGD6cM8Yt8Xh00+0lS0xXQuFSs2bA4yQYAJ3hTtFZvO6ij+J/dxOR5iKSJSJdShxfX0Q+F5EM0bUAp4jvFwgDIJXLpElA8+amq6BY8uab2mpM5ZSSAlSooPsvkj01awbMnh3QoQyAZBUDIAWtoAC44w5g0CDTlVAsmT8fqF/fdBUx7Pvv+VeX3bVpA0yeHNChDIBkFQMgBS09XX9PTZliuhKKJampOsRp/37TlcSoceOASy81XQWFU7duwCuvBHQoAyBZxQBIQVuzBqhYMeCxykQAdHJjw4bAH3+YriRGDRwIDBliugoKp379gEcfDehQBkCyigGQgvbWW0Dr1qaroFjj8QDnnw989JHpSmLUf/6jAynJvu69F7j77oAOZQAkqxgAKSgul679d++9piuhWHTddcDIkaariEEejy4SvHCh6UoonEaNAvr2DehQBkCyigGQgpKRAZxxBjBtmulKKBY98kjA729U0u7dHEDpBK+9BnTtGtChDIBkFQMgBaV4/F9amulKKBZNmqQTiChIc+Zw30Un+Owz3TInAAyAZBUDIAXljTeAM880XQXFqoULgVq1mGOC9sorwMUXm66Cwm3uXA36AWAAJKsYAClgbjfQvz/wwAOmK6FYtWuX9mTu2mW6khgzaBAH3jrBihVA9eoB/YXEAEhWMQBSwLKygFatgG++MV0JxarcXKBpU2DRItOVxJhOnXR8GNlb8VjPgwf9HsoASFYxAFLAVq3Snag4Dp3Ky+0GLrpIxwJSEBo1AubNM10FhVthof6S3bjR76EMgGQVAyAF7LXXgLZtTVdBsa5/f2D4cNNVxJC9e7VViDOvnKF+fWDJEr+HMQCSVQyAFBCPB7j+emDYMNOVUKwbNQq46irTVcSQBQuA44/nzBmnOOUU4Ntv/R7GAEhWMQBSQHJzdR/67783XQnFuo8+Ak4/3XQVMeT113UMIDnDBRcA777r9zAGQLKKAZACsmIFUKkSwJcKWbV4MVC1qu4qQwG4916dBUzO0LMnMHas38MYAMkqBkAKyKuvAu3ama6C7CAtTf+Y2LbNdCUx4uKLgZdeMl0FRcqAAQENkmUAJKsYACkg114LxMebroLsIDsbaNEC+Okn05XEiKZNgdmzTVdBkTJ0KHDbbX4PYwAkqxgAya/8fH0PmjPHdCVkB4WFQJcuwMSJpiuJARkZOgN4xw7TlVCkPPss0Lu338MYAMkqBkDy6++/gcqVgZwc05WQHXg82sDBHWUC8OuvQMOGnAHsJG+/DVx4od/DGADJKgZA8uvFF3XxXqJQeeopoEcP01XEgLfeCigMkI189RVw6ql+D2MAJKsYAMmvq64CRo40XQXZyaefAiefbLqKGDBkCDBwoOkqKJJ++01bff1gACSrGACpTAUFwHHHAfPnm66E7GTpUqBiReDQIdOVRLlLLgGef950FRRJGzboNHk/6yQxAJJVDIBUpqVLgWrVgLw805WQnaSl6etqwwbTlUS5Zs2AmTNNV0GRVDzx599/yzyMAZCsYgCkMj33HNC5s+kqyG4yM3WY06xZpiuJYllZGgS4YKKzeDy6Uvrq1WUexgBIVjEAUpl69QL++1/TVZDd5OcDl16qC4yTD3/8AdSrB7jdpiuhSGvc2O+4GwZAsooBkHwqLNT3n4ULTVdCduPxAHfeqbuckQ+TJgHt25uugkw44wxg6tQyD2EAJKsYAMmnP/4AatTgQH0KjzFjdJcz8mHYMODmm01XQSZ06gRMmFDmIQyAZBUDIPn07LNAt26mqyC7mjoVOPFE01VEsZ49gWeeMV0FmdCnD/D442UewgBIVjEAkk+XX64L9hKFQ0KCznHwucNMRgaQkgIkJwPr1+v/U1L0dido2RL4+mvTVZAJgwYBgweXeQgDIFnFAEheFRYCtWsDixebroTsavdufY2tWuXnQJdL06KfddFsJTdXF0rcuNF0JWTCI48AN9xQ5iEMgGQVAyB5tXixvjkXFpquhOzqwAHgnHN056syOTEAJiQAtWo56znTES++qNPky8AASFYxAJJXTz6pXcBE4ZKbC1xxha41WSYnBsCPPgLOPdd0FWRKAN9/BkCyigGQvOrWTWdpEoWL2w3cdx9wxx1+DiwsdF4AjI/32wVINvb990Dz5mUewgBIVjEA0jEOHdLlX/74w3QlZHfjxgEdOpRxgNutOyI4LQBeeSXwxBOmqyBTli3TMThlYAAkqxgA6Ri//KILQHP8H4XbV18Bxx1XxgEHD2r4S0hw1guydWvgyy9NV0GmJCfrFPn8fJ+HMACSVQyAdIxRo4DevU1XQU6wapW+z6Wn+zhgxw6dCZuQoLNGnCA/H6hcGVi71nQlZEp+vv5gbN/u8xAGQLKKAZCO0bkz8PzzpqsgJ9i1S1sAly3zccC6dcCePRoA163TPeTsbuVKoHp1oKDAdCVkUu3aZfxgMACSdQyAdJS8PKBaNeCvv0xXQk6wf79ud/v5517uLJ78kZur/1+50hmtgFOmAGefbboKMq15c50M4gMDIFnFAEhHmT9fW2TY+ECRkJ0NXHutjx1n0tOBpCRg0SJg6VJtLly71v6tgI8+CvTta7oKMu3cc3U5GB8YAMkqBkA6ysiRwNVXm66CnKKgAIiLA26+2cudGzcCCxboWKhHHtHxUImJOi7Qzq65RgfikrNdcokuCO0DAyBZxQBIR7nwwjJ/5xCFlMcDvPwy0K6dlzvXrAFeeglo0UJ3xUhO1vGASUn2bgU8/XTgs89MV0Gm3XADMGKEz7sZAMmquiKCpKRMR+2xTt5lZ+vkw+XLTVdCTvLttzre/ahMl5+v4/66dwcmTgQGDQL69TuyLuC+fabKDa/CQqBKFR3vSM42eLC+7n1gACSr6ooI0tPZAkjAjz8CTZuWufQUUcitWaO9vGlpJW7cs0dXIq9UCUhN1c8bNAB++EHD3+rV9mwFXLsWqFqVP4QEPP440KePz7sZAMkqBkA6LD6eY88p8lJTgRNOAH77rcSNW7YAr7xy9DYhkyYBp5yiTdVJSRoK7eaLL7QLmOj113VNLh8YAMkqBkA6rF074NVXTVdBTrNnD9CxI/Dhh0U3eDzAihVAz546BrCY2w1cdJFukbZ/v64i7XYbqTls/vtfzsIiNXUqcOaZPu9mACSr6ooI9u9nAHS6jAztbVuxwnQl5DSZmUD//sBjjxXdkJMD/PqrjoXbvPnog5cv142q16/X7tKj+o1toF8/nfFMNH8+0Lixz7sZAMmquiKC1aszbTmchgI3c6auO5qba7oScpr8fODhhzX7AAB279am6PPO837CsGFAjx66TuDKlYDLFbFaw+6cc8pc+40cZPVqHQ/qo5WbAZCsqisi6NMn0/ZLa1HZhg0Drr/enuPqKbp5PDrc6Zxzim745x/gqquAZ5/1fkJGBtCkCfDll9oSuHt3xGoNK7dbt4D7HVeHTQAAIABJREFU+2/TlVA0+PdfnR3lY3kOBkCyqq6IoHXrTPTsaZ/foxS8Nm30TZjIhFmzdAtCd6EbWLJEu3mTknyfMHWqzhxJTdVxC4WFkSs2XDZt0nEYbIYnQFu2K1UCNmzwejcDIFlVV0SwcWMmzjtPJxzZbUgN+bd/P1Chgo6pJzIhKUnf67avOQiMH68zYctqjvZ4gEsvBYYP1zfInTsjV2y4fP010KqV6SoomjRsqONhvWAAJKsOLwSdlKQT7Nq1Y0ug03zzjb7vZGebroScKjkZOPlkYP4Xe3Rz4NGj/Z+0bp22FP7+u24RF+utgE8/DfTubboKiiatWwNffeX1LgZAsuqoreBycoDLLtOZ5xwT6BxDhugsTLutqEGxIy1NN/14e3SKbguSkBDYiaNHA506aStgampQj5mBDKQgBclIxnqsRzKSkYIUZMDQlkg33aQtmkTF/vMf4J13vN7FAEhWHbMXcH6+LkPVqpXuvU72d+aZwJtvmq6CnOzAAWDgQA8e7p4ItGwZ+GyknBw9/q23tBWwoCDox3bBhQQkwAXDs4nPPRd47z2zNVB06d0beOYZr3cxAJJVxwRAQHtSbroJaNZMJ+SRfaWl6fi/NWtMV0JOlpsLPPaYB1c1SdAtaYIxa5aOlfrrL+1LDlJUBECPB6hZU7e/Iyp2663A0KFe72IAJKu8BkBAQ+CgQUCjRpwcYGfTpmkLoJeXAFHEuFzaiHdq5W3A4sXBX+Daa4E779SFooPcRzcqAuD27UDFikBWlrkaKPo89BAwYIDXuxgAySqfARAADh3SPz7q1QP+/DOcr3Iy5Z579I9MO62lSzHI48GP3+aikrhQkF+OwajbtgG1aumA+W3bAntIeJCDHGzHdiQgATnICf5xQ2XGjOC6vskZxo7VLRG9YAAkq8oMgACQlwc8+qiOy/7553C9ysmU1q19jjEmipy8PKz9dj2qVS4s/7CTceOAtm2BZcv0F5cPBSjAbuxGEpKQiERswRYkIAGrsAq5MLQG39ixwOWXm3lsil6TJgEXXOD1LgZAsspvAAS0V2LMGB2iMmNGOF7lZEJqqvY6lbXeLlFEpKVh64vTcMYph/DDD+W8xqFDOp7hySeBrVuPussNN/ZjPzZiIxKQgH/wD/ZhH1xF/yUgAalIxUqsNNMSeMstQFxc5B+Xots33wCnnOL1LgZAsiqgAAjotpuvvqoh8LPPQv0qJxOmTNEdQNLTTVdCjjd9OnYOewG9enrw2msWrrNgAVCnDjBnDjy5OTiIg9iGbUhEItZgDXZhFw7h0FGnlBwDuBu7sQIrkIUIj8Vr3x54++3IPiZFvyVLgPr1vd7FAEhWBRwAAZ0xOmmSdgfzd1Xsu+MOHTdfjpUziELH4wEGDsS+597BPffoupRA+dfpy3/4Aeyc+ipWFyRiBVYgGcnIRjY88D6+rvQkkD3Yg0QkIhMRmhnl8WhoXbQoMo9HsWPTJl2mwcsi5wyAZFVQARAAUlK0BbB+fR1ywzHLsat5cw30REZlZQEnnICsOYvx9NPHDoXbhE2YiqlIRCJWYzWSkIS1WIv1WI8N2IB/8A82YAOWYRl+xs/43jMLi35+CqsXTERyznrsxE7swi7sxm78i3+xB3uwD/uwDduwpui/VVh1VMDch31IRCIO4ED4n/+OHfomfyACj0WxJSsLEAF27TrmLgZAsiroAOjxAFu2AN99BzRurBNEGAJjz9atQOXKwNq1pishx5s7F6hVCwVZeXj/ff3DBAAykYkH8ACqoirqoi7qoz7qoi7qoA5qozZqoiZqoAaqoiqqoAoqozIqoRIqoiIkyP/qoA7mYM5RZR3AASQiEfuwL7zPf/ZsXXSVv0jJm+rVgRUrjrmZAZCsCjoAArpl2IYNwPz5QIsWwP33cxmRWPPhhzrsaO9e05WQ4w0eDPTrB48HmDdPGzz+l/MDmqEZeqDH4YkbxV20ucg9PGFjFVYhFanHzt51uYDzz4fngSFwZWWgEIUoQAHykY885CEHOchGNrKQhUxk4nN8jpqoiU/x6VGXyUQmEpGIPdgTvuf/wgu6Dx6RNyecAPz00zE3MwCSVeUKgIAOSUhK0vUBTz9d16rkWLLYceutwL33lrlaBlH4uVzAyScDX3wBAFiZVICqdfJRd3VnTMZkeOA5PEZvF3ZhLdZiOZZjK7YiE5k+x/UBAJYuBWrU0FQZQOvaAixAXdTFOIw76rpZyMIKrMBu7Lb8dL26/Xb9K5rIm7PP1hl7pTAAklXlDoCALri/cqVuI3b++bqHcK6hZbQocB4P0LQp8MEH7HUiw5YuBapVgyfrID7Gx3h98yw0O3cfPvz6ADzwIBOZh1sA12M99mJvcDt23Hcf0LUrkFH2xJFiK7ESJ+AEPIgHj3qcHORgJVZiB3aUHTrL46KLgAkTQntNso+uXYHx44+5mQGQrLIUAAHdiz0xUccFdumiPRncViy6bdgAVKvG8X8UBR55BJvv7IrLcTmaoRkWpm7CNdd68MQL2UhCElZiJVKRWv6t2vbv132C33gj4L92tmM7zsAZuB7XH9W1nItcrMIqpCAltCGwYUOusk++XXstMHr0MTczAJJVlgOgvhA1BO7aBfTqBfznPxxbFs3eeQfo2BH491/TlZCTFaIQr7x0PGoVVMODeBD7sA8b96Tj3rh8XHdXOvZiL9xwW9+r96OPgCZNdOXzAO3DPnRGZ3RFV+zH/sO35yMfq7Ea27AtNCHw33910CN/YZIvd9+t43VKYQAkq0ISAAH9/bViha5kcMMNOmxhxw7Ll6UwuOkm4MEHtfWWyIQVWIEL8s7BGesF8zO/xVZsxXIsx7rMHXh+nBtduhwJV5YDoNsNdOgA3HVXUGMecpGLvuiLs3AWkpF8+PZDOIQkJGELtsCNcuxbXNL8+RpOORaDfHn0UaBfv2NuZgB0jmdFZKeIZInIIhE5p4xjF4nIIRE5WHT8QREZ4uPYkAVAQFsAV63SYHHXXbqDzZYtIbk0hYjbDTRqBHz8Md9zKPJykYtRGIUaqIFHkq7CqpVTkIhEJCMZechDfj7wySe6xFQxywEQ0F9M1arpzgpBKEQhBmMwmqEZVmP1UbevwzpsxEZrIXD8eB07Q+TLyy8D3bodczMDoDOMFJFkETlbRKqJyDgR2SEiNX0cv1A0MAYipAHQ4wG2b9fZwQUFwMMP6wz2WbO4TEy0WL1at/Pj/r8UaYuwCKfhNLRDO3yNr7Fq9zzsXvglCnFklwOPB/jlF+0VLZ63EZIACGiz9wUX6F9BQfDAg7EYi3qoh4VYePh2F1zYUPRfuWu7+279IPJl8mSgbdtjbmYAdIatIjK0xOeVRGSPiNzm4/iFIjImwGuHNAAC+gt840adYLB9O/DMM9rDcdJJwKhRwObNIXsoKocJE4CLL/a6sDxRWBzAAdyNu1ELtTACI5CEJOzftwmealW9/kJYswY47jhg4d9Z5doKzqfMTG1aLOc+lh/hI9RETUzH9MO3ueDCRmzEOqw7KsgGrHNn4JVXylUPOcSPPwInnnjMzQyA9ldXRDwi0qHU7T+JyKs+zlkoIntFZL+IrBORF0SkVhnXD2kABLS1b9063W2isFBXevjqK+Cyy7QX5vbb9TZ2QUZe377A8OHAwYOmKyG788CDqZiKxmiMTuiEX/ErspCld44f77M17p9/dCLZ1KlhKGryZKBBA50dXA6zMRu1URsTcGTZFjfc2IzNSEISChDkYqjHHw/MmeP/OHKuhATttimFAdD+ThINgGeUun2aiLzv45yOIlK/6N9tRSRRRL70cWxYAiCgXcCrV+vewQkJR7qA160Dhg7Vvc8vuEAn6HHtwMhwuXQP5ylTgu4FIzpKBjJ8ts654cYarEFP9ER91McbeAP5yD/6Ap07A0884fXa27cDN94IPP10GAp3u3XM3aBB2seckgIkJwPr1+v/U1L8rhm4DMvQCI0wAiMOj//zwIOt2Io1WHPsc/Vl/36f+7wSHZaaqq+TUrP2GADtrzwtgKV1F5EC0fGD3q6PuLg4xMfHIz4+HnPnzg3Z6zYvT2cGJyToZJBdu4D0dL394EHg3XeBNm30D/JH/r+98w6Pqkz78AMiCkhAkCJiAwVRERUVZRVQUIouFiwfFrAviysriq5rAxv2CiKoi13RVQHBsqLYUFAmCSGVkN4baaSXub8/nkxIQvpMyiTPPddcMDNnznnfzCm/89R7zD3c0jgcKrwDA9t6JEZHoWp8XgklJJLIwzxMb3pzBVfU3j0jLQ0OOAB8fWtdZ3Iy3H23dqtpEbZv1/6qW7dWTKKs+l1qIwgnnGEM41qupZhiQEVgLLEEEEAhjWix8+OPmpFlrhCjPkpKVABGRfHtt99WXqvvuOMOE4CdgNpiAFOl7hjAmkwQFYAH1/JZi1kAXRQW6rk1IUFFYHCwnvcdDk1E2L0bPv9cs9y7d4epU2HDhsadi5t5A98pKS/XpJwpU5pUDs0w6sUlAKOIYi1rOYuzGMpQNrKx7i+98Ybe+dVRhygzE158Ud3ALYLTCXfcAaecoieaZghAgBRSGMtYJjOZHPQc6sRZ2ac4nwbqLL3yihbkNIyG8PGB33+v9pZZADsHi0QkRrT0Sw8ReVJE4qX2LOCBIjK1ymcnich2EflvHetucQFY27nV6dQ2cllZercfHa0C7n//077wAwdq0si//61dK/Ly6j83N/P83Wn46iu93g4dquVfwsNNKBvuU0IJu9nNNrZxH/fRk54sYAG5NBBgetFFejdSh+UrPx/WrIE+fVrQOJacDEceCa++6tYJZC97mcpUxjCGJPa5cpNIwh9/UkipO5Hl9tthzhxPzsroqBx9NKxbV+0tE4CdhyUikiwieVK9DuCRorX+/lLx+igR+UNEskXr/4VLGySBVKUp51anE4qLISNDYwPPOUeTRi65RGuD7dihAeJxcepFys3VJBMTgLUTFaWxVIccAk89pYLP4VDxbRjukEsuAQSwjnWMYAQnciK/83vDX8zKggMP1FovdVBWBr/+ql6vFutW43RqM2wfH3VPuHECKaGEOczhaI4mjLDK91NJxQ8/csmtvZTNhAmwdKm7MzE6A6eeqvtrFUwAGu7SrgRgbQQH70saOe009ZqEh6sQDAjQde/Ysc/NnJNjQjA3V0vu9OihJcZcMeYZGSaUDfdw4iSJJPzw4zVeoxe9uI3bqvXMrZcPPoATTmiw9dmOHVr54tdfPTDousjJgQsv1GBDNw8MJ04e4AH607+aEE4nHT/82MOe/QXg4MFaJNUwGmLyZHjyyWpvmQA03KXFBKCn4/Nyc7WH7UknVU8aKSvT87jDoa9dotBVhzAjQ+MQO0OcdVkZvPWW1l2cMGFfjL3TqQmHQUEmAI3mU0IJ4YQTQAD3cR996MPXfN20Is2XXaZxHsXF9S4WGgrnnqshCy2G0wk//wy9esHKlR45MJaznF70Yj3rK9/LJBM//Kr/nbKz1cQZG1vHmgyjCldfDQsXVnvLBKDhLi1uAfQ0rnP21Vdr0sj06bB2rXqUXOfv4mINJI+P1wuJr69mI4eHqzWssVZCb0oy+ekntZAecwx89pn+ncrKICVFy/Hs3KlhTyYAjebgcvkGEsgVXMEwhhFCSNO6dOTlqVl67doGF42KguuvV0t2i7J3r6YcH3WUxpV4gM/5nF70YhWrKt9zWQArs4O3bNGaTFaPyWgMf/+7FtCtgglAw128TgBWJTERHn1U42NFtO3clCmwYAGsWqXn2MxMPcfm5akYioxUMdQUK2F7jjGMjIRZs9RF/vTTOo/iYhW/fn4qXDMz9wnC9joPo31S1eUbQACnczoTmEAUUU3v0vHZZzBsmB50DZCYCA88oPt2ixMcDBMnamHSzEyPrPIXfqEvfXmER3DirBTKkVQ0R3/tNd2eYTSGRx6BGTOqvWUC0HAXrxaAVS1027bp9eWpp2DePBWChx9etzBMSWm8lbA9CqecHPjXv9Sgcuutat3Ly1NB6Our7vC9e6t/pz3Ow2i/lFDCLnYRSCC/8iuHczg3c3Nl3bsmM3u27qxZWQ0umpGhIR+1tED1PLm5WhNw2jStPdOI8TWGIIIYylBu4RaKKMKBAz/8tBvK/Pn69zCMxvDqqzBuXLW3TAAa7uLVArAxZGaq4Fu1Slug1SUMX38dNm3SsjM1rYTR0fr/9tCxpKxMk8EGDlSjhZ+fXq/CwvT/sbH7Z/l6kyvbaB+4XL6RRPIJn9CLXjzP8zhpZjBtUZGaqd9/v1F3IHv3atWLgw9uBS+p685o2zYtUXPWWR47OOKJ52ROZgYz+JVfSSSRYIJxTpkMjz3mkW0YnYCPP4YRI6q9ZQLQcJcOLwDrojHC8I47tCDtZ59pjKHDoV00YmP1+6XN6P3uDj/+CGPGwLHHam/l1FQdT0CAWgBbezxGx6OqyzeVVB7jMXrTmy9xM1t140atuxcS0qjFS0rUKNe1q96stCguAbhnj4rAKVO0QLMHzovZZBNIIGdzNmMZSxhh+ONP7Ool8MUXHhi80Sn44QftG10FE4CGu3RaAVgX9QnDo4/WMIy77tJyNF9+qRZCV/mZlrJURERop5TevbVsWFSUlskIDlZXmcWRG56gqst3D3u4lms5iqMIIMD9ld98sz4TExu1uNOpFu1jj4Xvv3d/8/VSNTYiO1uV5wUXaCHS3AaKWjeSAgoYxzhmM5uswmT89/xAaVS4R9ZtdAKCg6Fbt2onexOAhruYAGwEZWV6A7Zpk1oE58zRLlLdumkd2XHjtJTY4sWa4BgTo/F47paeycmB++7TOL+bbtIWpr6+GqeYk9M5StsYrUMuuexgB5FEkkAC4xjHOZxDCinur7y0FPr3h7ffbpKgCg7W8mevv+7+EOqlZnBsTo6KwEmT4C9/8ZgITCGFozmaxQm3svubZcSUR3tkvUYnICNDrRB79lS+ZQLQcBcVgEFBFhRWD3UlTxQVqZVi9Wq4806tW9a7twrD44/XDiYPPKCensTE2gVbbfF50dFqYRw4EM47T2OhfH31/fYQh2h0HJw4SSQRP/xIIw1//DmSI7mO6/aVLHGX77/X4pQOR5PM1RERmjNSo/yZ56ntAM/N1d6rEyboQVgzo6qZBBKIT3EPVj8/Gl98G+4XbBigx023bnpXVIEJQMNdVAB6qPRBR6M5yRNOpwq1L77QXsZTp8IRR1SPLbz3Xvj0U3XlukSh6xq0aZNaF489VhO//PzUxVxS0ipTNjoRVV2++eSznvX0pjdP8mTzkz1qY/58mDsXdu9u0tfi47XM08UXe24otVLXHd7evSoCzz1XhWBenkc2983rl9Kz8ADWspZQQj37tzY6LgMGaCB4BSYADXcxAdhKpKdrHPzixdoMYcQIvaHr3RvGj9eEk4kT9fXChWrxS0uz+D6jZcghhx3sIIooSinlWZ7lEA7hMz7z7IbKy/XO5+23tfZSE0hLU+t6jeRHz1NffaS8PBWB48erSzjfAxa7qVN5bcN0DuMwvuIrMshwf51Gx+f442HNmsqXJgANdzEB2EaUlmrm7ldfweOPa0mwa6/V3qdZWRbfZ7QMVV2+6aRTRBE3cRNDGIIvvp7f4G+/Qb9+ml3bxPiFnBz45hu9UWpRC3hDBTLz8zUm8OyzNTnEXRF4zDHwyScsYAHHczy/8EvjW+kZnZdx42DZssqXJgANd1EB6OdniqONyc+3Is1Gy1LT5ZtOOudxHmdwBok0Lju3ydx9N1x3ndYqauI5prAQ/vwTevbUVoctRmMqpBcUqCXwrLM0jqO5wbhFRVrbJiyMMsq4mIsZz3iiiGre+ozOw/Tp2hGkAhOAhruoAOzWTbP0pk2Dhx+GDRua7K4x3MO6dBieIpvs/dq0RRCBP/5EEUUZZQQTzLEcy1Vc1XKJCE6n1k565x0NeG3G1x0O7e4zbJjHknH30dQg38JCFYFnnKEFowubkSTj56eKtqJoZy65jGY0V3AFBViGl1EPN9ygPYErMAFouIsKwN9+g/fe05ojl10Gxx0HXbpo4dZZs7TJ7ObNHimMatSOCUDD07j6z8YTX+nydeLkG76hD314hEcopwWDTH194ZBDtMdiRvPi3Hbu1JCICy6AG2/08PiaQ1GRuoNPP11vmJsqAt9+G04+udpbscQygAHcz/2WEGLUzcKFcPXVlS9NABrusi8G0OlUP2Ramt6tb90KK1dq1eNp0zSVtUsXOOEELYS3bJnG9TTnLthTdIAeZx1gCkY7pZBCHDgIJJACCnDi5BVeoRe9+IiPWn4ADzwA11yjdzbFzesfvGuXnpISEjSU8NNPPTzG5uASgaedpm65mr0X6+Oee7Sqew1+53d60IMP+dCDAzU6FE8+qYUxKzABaLhL/UkgpaWqRBIS9Ey8aRO8/LKWdZg0CQ49FA48EMaOVdP06tXam8xVUb+1lI2ZzwyjGgUUEEAADhwUU0wJJcxjHoMYxDa2tc4gTjhBLV5BQc36ena2fjU4WE8hr78Offo0e3WepbhY3cFjxmidmsaKwBkztD5ULaxmNT3pyXa2e3CgRofhjTf0pqMCE4CGuzQtC7iqlTA6Wv0z69bBc8/BLbdollzPntCrl9bNuucebWL92Wctayk0AWgYleSSiz/+JJCAAwfppDOZyYxhDLHEts4ggoPh4IP1Xzea+SYna0Fo1+F9yy1679kuDvWSEhWBo0fDX//aOCvnccfBBx/U+pETJwtZyGAGk0CChwdreD3r1mlMbQUmAA13cb8MTE0r4Z9/wiefqLn6+uv1Dvmgg9RSOGoUXHqpxhq++Sb88ot+Lz1dRWVqqiafJCdDUpK2z0hI0IqwsbHaYy06Wl3UkZF6Zdi9W3ujORye6b9mGF5MBhmV8X5llPE5nzOCEcxkJnvxTDeLRvH44xpPHBjoltU/M1M1pEsA7t2rGuqZZzw4VncoLVURePLJMHNm/SKwpERr2uzcWecie9nLTGZyKqeSh2cKTxsdhN9/196jFZgANNzF863galoJAwPhjz+04N3y5VoW4tJL9a65Z08tiXD00RrbcPvtak1ct079PDEx+1zH8fEqBhMTVRwmJ6tYTE3V1w6HBp0HBuryubkmBo1OgxMnySTjhx85aLLWRjbigw+LWNT6deZOPRX+8x+3LfP5+Zo4W3U1f/yh/bEdDg+N1V1cIvDEE1X01lW0MDBQb4YbcBfvYhfjGMelXGr1AY19REZqS6mK/csEoOEuKgBbMru3Pves06nC7n//g5deUgF47rka7S0CRx2lvdQWLlSL4ZYtahKoaxslJZoyGBMDO3Zo9mFkpDbQrii7YBgdDSdOYoklgADyySeWWGYzm0M4hKd4ilhiiSOObFopsygyUi3+u3dDWJhbq3Id2jVPIU88ASNHeqw7m/uUlWliyKhRcMUVtYvADz7QuMgGKKGEH/mR4QxnEYtaYLCGV5Kfr9fF+HjABKDhPm0rAOvC6VTL3o8/wooV8I9/aB2Iww/XA2DQIDj/fO2ftnw5fPed9lmr6n5xOvXqkJCwz4cUFqZWw7bMXDYMD1JGGbvZTRBBFFPMt3zLUIYyhSnEENM2g3ruOa0cEBmp1nk32bVLD9+qDTjKyvRe8W9/c3v1nsMlAkeOhCuv3P+m8/77NVawEaSQwld8RT/68QZvtMBgDa+kZ89K07cJQMNd2qcArI+sLHW3vPWWupOnT1cXcteuanUYPhwuvFCtiU89pfGIf/6pQjAlReMFfX3VxRwfr0FFdbmKrUaL0Y4poYQQQggjjAwyuIVb8MGHN3ijbevJnX02rFqlFvi97scdlpbqKcTfv/qhFxOjWcHr1rm9Cc9RXq4icMQIrdlWVQTOnAn33tuo1ThxEkQQa1lLT3ryPd+30IANr2LIEPj6a8AEoOE+LScAW0M8Vd3Gzp2aVPLhh1qq5v77tQbZmWfCYYep5fCQQ+CUU/REPG8eLF4Mr76qWcrBweperk2oWpax0c4opJCd7CSSSDaykaEM5SIuar0s37pISIADDtBELX9/j8Thug6/tDSNB0xK2rfajz7Sw9sDhkbPUV6uNVKPOw7+7//2icCRI7UsTiPJIQc//HiLt+hLX0IIaZnxGt7DySdrZx1MABru0/IWwPZCbq72I123TuMN77wTLrkETjpJI8pFtB3e6NH6/l13aeGxzZs123jbtpYRgGZlNJrIXvbijz9BBHEjN+KDD2/xVvvoIrFsGUycuK9+iweoev+Vn6/3ehER+w7H667TzmzlLdjUpMmUl2u2yvDhmhiyezd0767hKk04viOIIJpoHuABhjGMdNJbeOBGu2bCBHj2WcAEoOE+nUcA1ofTqe7hrVv17ur++zWG54wztAPKAQfoc+hQGDdOP7vrLnjhBW1NsG2bWj7cEYhmZTQaQRZZ+OHHB3zAEIYwjWnE0fw6ex7n/PPVqr5rl8bxeoCah0Zpqa4+KEjDebOzNQrk5Zc9sjnP4XSqCBw2TGOYDzywyS7xYoorM7uv4ir+wl8oogmdR4yOxeWXaxk1TAAa7mMCsD5KSzWDOCwM1q/XshZPPKHWw6uv1oq0o0ap5VBEReLgwVoCY9o0uOkmrfq/bBl8/rkKxchItQAkJKjfylXKJjVVr3KWoGLUQSqp/MRPzGY2fejDala3D6ufi7Q0rXMXG6txtm7uy/UZx10FBPz8NCz41181Pj4gwENz8RQuEXjMMWoNbEY1giSSCCGEfPI5i7O4nuvb1+9utB633go33wyYADTcxwRgY6hpgnA61cVTWqqZx4WFehUKCoJvvtGSNYsX68E6fboWw3bFIXbrplbFsWPV1XzrrfDgg2o1eecdDfD181OhmJKiFoN25dsyWhsnTuKJ5xVeYTCDmcEM4olv62Htz5tvqoU8J0eVWCvU4czM1MMlMREeekhDpAoKWnyzTcPphO3btQxMMyz85ZSzk53jAqGKAAAgAElEQVSkkUYyyRzFUTzGYy0wUKPd8+9/aww7JgAN9zEB2Bg85Z4tKlJh9/PPejF4+mktZXPppSoIXfUPu3ZVS+Ipp6hL7aqr1OX84ovwxRda4zA31zNzM9o15ZTjiy9/5a/0pS/v8E77tf5Mn67xSfHxWgS+lSgo0BrLwcFw1lmwYEGrbbrxuHkOySILf/wppZSd7MQHHz7mYw8P0mj3vPCC1j/CBKDhPiYAG0NrxOe5tlFQoPUtfvtN4wtffFHF3xVX6NXtyCM1mNyV1Xz88eqKnjNHLYkrVqi72uHQQPzycks08VJKKWUFKziMw5jBjPbdHzYrS2PcIiJUie3Z06qbLy3VPIuvvtLD4ptvWnXzDePmOcSJk3DCK7O8v+ZretGL3/ndk6M02jvvvacdZzABaLiPCcD6aE3h1JQLRHm5juPHH2H1aliyBG67TUXixIl6gnBZE7t1044q55wDs2bB7NlaqPe//9WYxMREz7iYTWR6lEQSuZiL8cGnfVv9XHzwgYY6lJTs68rTyjidujsvXgwDB2pIYrvBAzeRhRTiiy/5aEXsZSxjAAOIIspTozTaO99+qw0RMAFouI8JwLbGU8KptFRjr5KS1BSyY4e2zvv2W7UkrloFTz6pAvCyyzTDedCgfSLxmGPgvPPg2mvhX/+C116DL7/UWm579jQ+nsuymd1mDWvoT3+mMKV9W/2qcvnl8Oijuq8EB7fpUDIzYcoUfbZ5+KyHb4ziiSeMsMobgju5kxM5sfXa/Blti78/HHwwYALQcB8TgB0Vp1NjDvfs0QtOaKhmZroaq/r56clk+3ZNPFm9WmMS77pLC2hPnKiFa318VCT26KFZjOedpyLynnu0nuJ//6vlcxISVIBmZ5sAbCbppHMlV+KDD8tZTjltrV4aSV6e7h9BQRr7F9/2CSqJiXp/s2RJx2oDXkYZAQSwB3Wxl1LKdKZzERdRSgeaqFE7SUl6Pt671wSg4TYmADsTrp5a+fkaa5ifr1nGubkq3DIzVTCmp2tZmpQUPeGEhcEPP2j8yVNPaRmcWbPUrXzMMXDQQXpS8vHRFlgTJ2oJnGee0aCs8PA2cQl6E5/zOQMYwCQmEUzbWtCazGef6e9eXq5VmtvJ+WTTJi0Ns25d9T7C3k4GGQQQQBl6k5VDDqMZzTzmtf9QAcM9SkuhSxfYvdsEoOE2JgA7Ey3lnnU6VTT6+WmW8t13qwCcMEEr9B54oGY2H3MMTJ6sfZqfeUath35+7UYwtAbZZBNHHLHEEkoofvhVZvguZSk5eOHfYvZsLU9RWKhW5jb3u+7j3nu1NMy2bZCR0daj8QxOnIQRVq0UUCyxDGIQS1hiIrCj07cvbNliAtBwGxOAnYnWzGZ2baOoSP1xP/wAK1dqIe0FC7SbytixejIT0TqJ48apmHjoIe2Z+ssvnktSaWeUUcbTPM0ABjCVqfzADxTQ3grYNYKiIujdW3/z1FRt0dGOKC6G007TXc7fX0PwOsLulE8+vvhSyL5i2zvYwVEcxdVcTR55bTg6o0U59lj4/HMTgIbbmADsDLSXbObiYhUJYWG6TFiYupmTkzUWcc0aTVS5+WZ1Iw8dqu6OHj00s/mvf9UYxWXLVFB6qNVYa1JGGetYx7mcSx/68BIvEUQQxRS39dCax8aNauV1OrUETHJyW49oP0JCoFcvLQ0THKy7XUeISIgllnDCq1n80khjEpMYzWgiiWzD0RktxtixsHKlCUDDbUwAGp6hqSKzpETrdOzapWIwNFTFQ1GNPqeFhfrZxo3wyitqypkxQ93JIjBggBbLvvNOtTBu2aI16VpjDk0gjzyWs5zjOI4jOIIneILNbGYXuypjubyOsjKNBV24UAWgv78mhLRDXn9dG/Ckp0NUlDYqaWJb3nZHKaX4408W1ff3Ekr4J/+kH/34ju/aaHRGi3HhhfD44yYADbcxAWi0PaWlemUOD9cYspAQTT5pqJdsbq4Gd/3nPypCLrxQa2SJqPVw2jRYtEjdydu3N16ceNBVnkAC93M/h3Iop3M67/M+ccThhx8OHN6buRkQAGeeqYXIw8NVTfn7t0r7t+bgdKoBedYsdQGnpuqutmuX1l331tKVaaSxk521Zoy/wzv0pCfP8ZzFBXYk/u//YMECE4CG25gANNoXpaUarb97t16hg4M1DrCgQC17jbHQ7dmj8YMrVsD8+ZqM0q+fupOHD9fWew8+CB99pFmrxTXcrx4QgL74cj3X053uzGQmP/Mz2WQTRBDBBJNNNg4c3mf9KyjQhI8ePeCBB/Y13k1K0jaH7Zi0NC0Ns3q1vs7N1XKZUVHeW7nIiZMQQkgiqdbP/+RPhjKU2cyuLCBteDl33AHXXWcC0HAbE4BG+6WsTMVcRISKwaAgrTeYm6tX7L17tb5HXp7+31WHMCtrX0mbjAy98qekqNXqk0+0YPHs2Zod0KuXFsI+/ni4+GKNMXztNc1mjo/XdRUVNcqyVU45X/Ilk5hET3oyn/nsYhfFFBNJJH74kUIKTpyUUeZ9AvDHH/XvdOaZ+resSlhYO2u9UTvffKOt4nbv1tfFxWpwdjjUEpiaqrtQI3/ydkEyyfjiSxRRhBJKLLHEEVdZHDqFFM7lXE7lVGKIaePRGm6zeDFMm2YC0HAbE4CGd1BWpqIuMlJLx1QtZh0QoJa8wEAVicHBelUPDVUfX3i4XvEjIvT7UVFasDg2Vq/6v/8O776rFq1Zs+Ckk7R0Td++Wvh63jy1Jm7frt9JS1PRWWEyyiefFaxgBCM4nMNZylL2sAcnTlJIwQ8/IonURI+KOMPy2BhS4hyUx8a0f79jZibccosqp5de2t9UVlamAr1m/GY7ZcECbavtSgRxda+LjdXdJDBQX7sM0BERet+RkaE/e2MLS5eXa430pUu1S+P55+u9x5Ytnv+5o4gigog6byqKKWY+8zmMw9jMZs9u3Ghdli+HM880AWi4jQlAw/to6XI2ZWV65f79d008ueYazXTt0kULHl95JSxeTNL6lTyYchv9yvoypuRE3st7neKiXHA62cteggkmkMBqtf0q6wCWxxC610FseUw1a41H8FQyi9OpbQQHDYLp01Us17W9nTvdH3crUViotQEfekhf17Y7OZ26XFaW5iZFR6uRc8cOXXbHDn0dE6Ofu4zOP/2kgm/GDDj0UPWUT5qk9xYLFuj/u3WDUaM0PPXHHz2TkVxCSWVcaX1W5bd4i5705CVesrhAb+XTT2H4cBOAhtuYADS8j9YQgLWtPzkZ1q5lx8s3MfebQRxUKFzydTc2//MUnHf+A1asoOSXzURn+OJX7iA5K5TytFQ1G9UsPtcWNRmbQny8Zk0cdhh8+GH9/tC4uLrFYTtl507tEvLrr03/M5WWasRBaCi8+aYaR085RYVd//6ai/TAA7Bhg4ZG7t2rYtK1jexsrYF+440wcCD06QNXXQXvvONeZaNUUnHgIIaYepOLtrKVwzmcOczxztqTnZ2ffoJ+/UwAGm5jAtDwHlq6nmE96y+nnK/4islMpgc9+Bt/I7Q0UN3QK1bgnDOHtIf/jv+eH4j47nWK7rhNaxquW6euY4dDfYuRkaoK9uzR9woKVFGUlXk+6Kw5ArC8XF1MvXvDnDmand0QQUFq/vIynnpKk8UDAxvenZzOfYLvxhs1FLJLF40WuP12jSCIiFChl52tIaexsRqBEBCwrwV3SIhaE11Ww/x8+OMPDes64wxtmHPWWeoqdjiaVrTaFVe6i13sYAcZZNRp5UsiiXM4h7GMJY64BtfdmqVEjQYIDYUDDiAnM9MEoOEWPiJCUE6Q591QhtEBKKCAVaziBE5gEIN4nMdJp7ooyiOPEELYyU6ys+O0ZuFDD8GUKSqkevXSwtYLF6qZ548/VDS5VEHVp6/vvrjGwEANQqsayxgRoTGMMRWxgwkJKihTUjQ2MSNDxZgrGcbV+7m0tGGBGRwM48drp4HvGqgf51IErhTa6GivUwTl5TB1Klx33f6fFRZqrN7TT6shtH9/OPhgTSj/97/1J96zp/HbKi7WP1N6uv5kERG6C/j67stviojQ+4lXX9VE9d69YfBgrYv++eea+1Qbrp8iJrYcR+heomPL2R1XiH92JGGE1WnlK6KI27mdAQzgZ35u1Dxaw3BtNEBWFoiQExlpAtBwCx8RITPH++7eDaMlSSGFR3iEwziM0Yzmbd6miOpJDqWUEkMMvviSSGKttdgoK1Mh9+abeiU/8UQ1HR17rAaKvfeeirfSUlUJhYUq2FxZza7gsqrZzElJqiJcrteoKFUP4eEamBYaqmJu5879Baa/v44nJESXj4rSfxcu1IC1f/yjut+ypKR+4ZiW5tWKIClJvdwrV8L69XDffaqBu3fXGuOXXw7PP68hoTWrBTWFuoRTbbGGoaH6M23dCm+8oW21hw/XvKSJE+G55/RnduGKK40pj8WRov/GEUcmmcQTjy++xBNfZ2zgSlbSk54sZ3m9cYGlpTrGLVu89ufuGJSXQ/fu5GzdagLQcAsfESEjxzu7pFcG1BNba/kDw2gspZSyla08wRNMYhLd6c50prOJTftdFJ04SSedHewgnPBq/VgbRVYWfP21XtlPP139fmeeCQ8/rIknnrq6ulSHy8VcVKTiMidHRWVamrqojztOfZnr1qmyCA5WC6Sv7z7h6OengjI4WK2RkZEqPoODvVoAggq/7t3hhBM0nu/tt1UTe9Ij31TLmdOp2js3V3+muDj4/nv417/g7LNVDB51lLqj16zR+4K8vH0G34ICfZ2bC6nZRQRlJuCXHkdgZB7bHU42bdJcgjffVIF710N7mX5nOJfMyeDSy5ycf752HBsxQq2QvXppfXUReOwxr/65OwYDB5Kzfr0JQMMtfESEL3O+ZDOb+Zmf2cIWtrGNP/kTX3zxx58AAtjJTgIIwA8/trOdbWzjN37jV37lJ37iB37gO77jG75hIxv5mI95kzdZyUpWsYov+IIf+KHSJeHJDDSvrKlmtClOnAQTzKu8ykxm4oMP/ejHLGbxOq/X2Uc1n3xCCSWAADLJbP5+XFURJCdrENns2Vqw+tBD4eqrVYkk1V7gt8nbqEl2tpa36dkTnn227tom5eVq+iooUDWRlaV+zJQUtULGxHi9AITGl3ZpKi0RO+fqZPLBB+q+HjxYf8ZJk+D669V9PHmyxhKOGqVxjn36OOna1YkIdOnixMfHyZFHajb0+PGa5D1rdhGn/X0rZ/57E488k8cbb6hI3LRJf+KoKHV7b9/u9T+39zNyJDlvvWUC0HALHxFBcoSajy50oRvd6E53DuZgetGL3vSmL33pT38GMpDDOZwjOZJjOIbhDGcEIxjFKE7mZMYwhtM4jbGMZRjDGMIQetKzcv3d6c5ABjKCEZzFWVzERVzN1dzO7dzHfSxlKStYwUd8xNd8ze/8TgghJJJIPvnVLrwmAI3GEE887/AO13M9h3M4B3MwF3Ihz/BMg/tPGWXEEdegO63R1CXOysq0vd2SJWrqOeAAGDNGTT8//dS0miF1bWPtWhgyRGMUIyJaZh5Gq+F0almaxx/XikUPPQQvvqj3D2vXaqkZf3/V6hnZpUSXx+KLLwkk7Be2UEghN3MzgxjEFrbsty37udsJ48eT8/TTJgANt/AREeJy4iiggGKKKaNsP6tGOeUUUkgOOaSTTiKJRBPNLnYRSCC++OLAwQ52EEIIEUQQRxwppJBBBg4cZJJJNtmkkUYEEfjhx2Y2s5a1vMM7vMqrPM7jLGIRt3EbV3M1U5nK2ZzNKEYxhCH0olelgDyQAzmMwxjOcMYylvM4j5u5mcUsZiUr2cAGHDhIIqnTC8PO6irPJJMv+IL5zGckIzmAAxjHOB7kQTazeT/XbW1/p1hiiSeeAALqDahvNE01CWVkwMcfw9y5Wo+vd2+47DINWquvLl9t2wgN1YrE/fppMoonfJymCNoNTfkp8smvTFzKIqvaZ06cLGc5PenJSlY2extGC3LJJeQsWmQC0HALjySBOHFSQgl55JFJJimkEEccEUQQTDAOHATVeAQ28NhZx8MXX37mZzawgY/4iFWs4jmeYxGLuImbuIRLOJuzOY7j6EtfBKErXRnIQE7mZCYzmeu4jkUs4kVe5GM+5ld+JZJICimsJn47mnDq6JbSAgr4nu+5n/s5kzPpSldGMYo7uZN1rNvvQlcXrr9THnmVJTVcnT3alPJyjcVbulTTUV0VhRcu1KzdwjpiEcvLYdUqLTg3e7Z7xeZcWF2QdkeT4wxxkkYa/vizm937JTn9zM8MYAC3czvp2cX2c7cn5s4l56abTAAabtHiZWBaQ3S4tlFa8SikkDzyyCGHJJLwxZeNbOQN3uAxHmM+87mCKziXcxnBCA7l0Eq3d3/6M5KRnMd5zGIW85nPEpbwPM/zJV/iiy/JJJNDDvnkU0xx2wuDRtKSv0VriOWa24giig1s4BEeYTKTOYiDOIIjmMtc3uM9Ekls0vpdlu4ssnDgwBdf4ohrv4I5O1vrg9x2mwZ69eihmcWvvrqv2W1YmLazO+ooTTwxOhzuavFSSokmGj/8SCKpmls4jjjGMpbxjCcJN+JRDc+yaBE5M2eaADTcosULQbemAHRnG0UUEU00W9jCGtbwIi+yiEVcx3VMZjIjGMFhHEaXikc/+jGCEYxnPDOZya3cyoM8yDKW8Rmf8Ru/EU00qaSyhz3kkksBBZRQ0mZWRm/5LWrixEkWWQQQwJd8yQu8wCQm0bficTmXs5zlhBFWpxivz0odQgg72FEp+gIJxIGDXOoovNYecTq1mNzzz2tsX/fuMGyYisK77tKyLoZRD3W1LyyggBu4gSEMYStb23CERiVPP03OueeaADTcwgRgE9dfQgkJJPAnf7Ke9bzGazzIg9zIjUxlKqMZzUAG0oUuCMKhHMpIRlYKxZu4ifu4jxd4gQ/5kM1sJoQQYojBgYM44ognnriKRyyxxFQ8ookmquIRSSQRFY/dFY9wwtlV8QgjjNCKRwghBBNMEEG1uuM94Zp3PQIIwIGDEELYxS4iiCCaaOKII5FEUkghnXQyySSHHPLIYy97iSCCn/iJ93mfpSxlHvOYwQxO4iR60xtB6E1vTuZkZjCDO7iDrWyt/M3LKGt2nGommeSRVynOO4SrPC9PqxX7+bX1SAwvwomTVFLxw49IIilGix9mkcViFtODHsxlLj/wg1eHw3g9//kPOSedZALQcIsWE4AdwbLlzhxKKSWRRLaznS/5kpWsZDGLuZVbmc50TuVUBjGIrnStFIrDGMYZnMEFXMDlXM6N3MgCFvAwD/Mcz/Emb/Ipn/It37KNbYQRRiKJpJJKWsUjveKRQQZ7Kh6ZZJJFFnvYUy0hp+Yjp55HbgOPvRWPbLJx4CCDDNJJJ4UUwghjE5tYzWoe5VFu53Yu5mJO53QGM5iuFY9BDOIUTmEa07iZm3mIh3id19nIRnawg1hiSah4OHAQTjjBBOOPfzXr3S52EU00iSSSTjo55FBIYe2FmmuhQwhAw3CDEkqIIgo//EghpdKyvpWtTGMaB3EQE5jAh3zY9DqYhvt8+SU5RxxhAtBwC6/uBdwRkjRcQvEP/uBlXuZ93uc1XuNJnuRe7uVWbuVKrmQKUziDMxjOcPrTnwM4oDIj2gcfjuZoxjCGiUzkUi7lRm7kLu5iCUt4mZd5l3dZy1qWsYwNbGAjG1nPetayls/5nE/5lDWs4SM+4gM+4F3e5W3e5j/8hzd4g5WsZAUrWMYyXuEVXuIlnud5nuVZnuZplrKUx3mcR3iEq7iKi7mYUziFPvRBEHrRixM5kWlM42/8jSd5kvd5n5/5mRhiKKaYUkopooh88skllyyyyCCDVFJJIol44okhhkgiceAgmWSyyCKffEopdTsWsyPsT4bhSXLJrfQO5JJbeXOUQgov8AIjGUl/+nM3dxNKaFsPt/Pwxx/k9OplAtBwC68WgB2B5ooOJ05yySWOOHayk1/4hfWs513e5RVe4VEe5S7u4kZu5DIuYxKTGMMYjuVYTuIkRjOaUzmV0zmdMziDcYzjHM7hL/yFCUxgEpO4gAu4kAuZylSmM51LuISZzOQyLmMWs7iKq7iGa7iWa7me65nDHOYylxu4gVd4hfWsxx9/9wom14JZ6Ayj9XDiJJnkSrewA0dlxQQnTn7iJ67lWrMKtiYxMeSo+DMBaDQbE4CdCG/PAnZhAtAwWp9iiisFoAMH/vgTRhgxxJBCCpFE8gzPNNsqaBb4JlBYaALQcBsTgJ2AjnZiNQFoGG2D69grppg88sgggwQS2M3uyux5X3x5l3eZyUwO4iDGM563ebvRRdTt+G6Airo/5gI23MUEoOE1dDQhaxjeRkPirJxyCihgD3sqk+Du5V6O5mj60Ie5zOU7viORRDLJpICC/ZKzTAA2DksCMdzFBKBhGIbRKJorzsop5zu+40qu5CAO4izO4lmeZStbceAgkEAiiCCBBNJIq+zEYyKwbqwMjOEuJgANwzCMRuEJ61w66dUyiP/JP/mTP0khhRhiCCW00pXswIEffgQSSBhhRBJZWb/TVWC/kMJGjaejeBBc8wh+50kTgIZbmAA0DMMw6qUlxFNdGcR55FVr7VlAATnkkEEGySRXdvAJJbSyP3xdQjGZ5P2EYimlHcLFnG2t4Aw3MQFoGIZhtClVrYJ96cupnMq1XMuDPMibvMl3fEc44RRRtN93nTibLBQdOAgjjCiiKt3O2WS7XVO0Na2MWXfdZQLQcAsTgIZhGEa7wImTrWzlcR7nMR7jVm5lClM4nuPpTncEYQhDOIdzmM1s/s2/WcUqvuVbwgirN9PYJRRdFsZUUkkkkRhiCCecIIIqxaHLmli1q5BLJBZQ0KD1sDmucidOCiggjTSiiGInO9nKVjaxibWs5X3e53Ve5zmeYzGLmZ85zwSg4RYmAA3DMIw2pyHrWTnlJJLIb/zGR3zEUpZyO7czlamMZCQHcRCCMIhBjGMc13AN93EfK1jB13xNCCHkk9+gOCujjHzySSWVaKIJJJBtbOMHfmADG/iET3if93mbt1ld8XiTN6t1THqVV7mHe1jCEu7lXv7O37mBG7icy7mQCzmHcxjDGI7jOAYzmN70rmwLKghd6YoPPgxmMMMZzmhGM45xnM/5XMzFXMmVXJN9jQnATsKjIpIoIntF5CcROameZfuKyIcikiUimSLyvoj0qWNZE4CGYRiG11NOOckks41trGENT/M085jHdKYzilH0oAeC0J/+jGQkIxjBsRzLkRzJYAbTj34cwiEcyIGVQqzqowtdOJiD8cGHAQxgCEM4hmM4nuMZxShO4RRO53TO4izGM56JTGQ605nFLG7gBuYxj7u5m4d5mKd4ild5lbd4izWsYQMb+JEf+ZM/CSGEKKKIIYY44ognngQSSCKJZJIre79HZO02AdgJuFdEYkXkRBE5SESWikiCiPSsY/mvROQ7ETlURPqJyCYRWVfHsp1WAH777bdtPYQ2webdubB5dy5s3nXjxEkqqfzJn6xnPV/xFd/zPb/wC9vYhj/+BBPMbnZXZhpX7TXeFFyJJk39XlPIzEw3AdgJiBKRf1R5fYCIpInIdbUse5SIOEXk5CrvnVLx3tBalu+0AnDhwoVtPYQ2webdubB5dy5s3u2D1ihmbQKw4+MjKt7G1Xj/fyLyfC3LzxSRwlreLxKRS+pYvwnAToTNu3Nh8+5c2LzbBy0qACtawWUFBZoA7OAMFRWAI2u8v0ZE3qhl+etFJLmW91NE5Npa3vcREeLj48nJyelUzzvuuKPNx2DztnnbvG3eNu+OM++4nDiCc4IJyglie852gnKCCM4JJi4nzuPb2Ba/zQRgB6c5FsCCWt6vywJ4hOgOZE972tOe9rSnPb3veYQYHZbaYgBTpe4YwHLZPwawXGqPAewiuvP42NOe9rSnPe1pT696HiF6HTc6KItEJEa09EsPEXlSROKl7izgDSLyrYj0F5HDRK2Fa1t8lIZhGIZhGIZHWSIa25cn1esAHilaG/AvVZbtKyIfiEi2aC3A90TvFAzDMAzDMAzDMAzDMAzD6Gw0pcOIN7JYRMpEJFd0jrmiXVJcnCIiP4taVhMqlvdGrhGRX0QkRzTes2uNzxszT2/cFxqat1M0Karq719zXt4276dEZKfonBNF5CPZP773SNFQkFzRmqHLRKRbjWXuEJFo0X3CISLntdyQPUJj5h0jWgar6u89o8Yy3jbvR0QkQtSjkyYi34jImBrLdMTjuzHz7ojHd03Wis7zgirvTRIRXxHJF5FIEZlX4zvdReQ1EUkXPV6+lNpzAIxOTFM7jHgji0UFQm0cIiJJIvKE6AFzsmhs5T9bZ2ge5UJRMXST7C+EGjNPb90X6pu3iJ44z6/n+9447ydF5DRRQecjekPjX+XzLqJC6W0R6SUqBgNE5KUqy1wlGh5ybsV65oteINtzNmFD8xZRYXdTPevwxnkfL/taeXYTkbtFy3q5Av876vHd0LxFOubxXZU5ojH85bJPAB4tKvTnif5dJoiK5EurfO81EdkhKvoOEZF3RcSvdYZseAtN6TDirdQnAOeKnlCqioYFIrK7pQfVgkyU/YVQY+bp7ftCbfMW2f/OuSbePm8RtYqUy76L5UQRKRZtBelipqjQObDi9WYReaHGevxE5MGWG6bHqTlvERWAN9fzHW+f90EicpfovPtXvNcZju/a5i3SsY/voaIWbVctYNc8HxG1/lXlRdGWryL6t8qX6mXf+otIiVTPFTA6MT7StPqC3spi0QtfqujF4UMROabisxdF3QpVOUf0JHNIK43P09QmhBqaZ0fYF+oTgEmirhCHiNxa5bOOMG8RkftEL3QuFohIaI1lDpfqLSIzRS2nVVklIp+1xABbiJrzFtFjPEVEMkStoPdKdde3t857hqjl0ika0vJclc868vFd37xFOvPcdU4AAAQ8SURBVPbx/T8RuaXi/1UF4Bci8nqNZWeL7vMi+26MBtVYZpdUF8NGJ6apHUa8lRNFXWAiehH8QPTOuKeIvCUiH9dY/gTRg2dIaw3Qw9QmhBqaZ0fYF+oSgOeL3hF3E5HpogLgbxWfdYR5TxG9wbmwynsPicjWGssdLDrX8RWvy0Rkao1lnhaR71pgjC1BbfMW0Xi+XqL7wXhRQfhUlc+9fd59RV27s6q81xmO79rmLdJxj+/5ogLQRVVX9/dSfZ8WEZkmauET0fCGctG/S1W2icgDnh2m4a14+91Rc+kuGiQ+RcwC2BEsBC7qEoA1WSwiWyr+7+3zvkTUOjKzxvv1WQBdAfDeagkTqXvetTFXNObLhTfP20UX0Ziv0RWvO8PxLbL/vGujIxzfw0StmkdWea8pFsBTxCyARiNoSoeRjkJ30ayxC0UDbDtDDGBj5unt+0JjBeAjIvJbldfeOu/rREXQlFo+myDa+rG2GMDuFa83y/4XQV9p/7Fw9c27NuaIZoC68NZ5V6WbaIzXFRWvO8PxLbL/vGujIxzfc0WP3zRR13a6qADMEpGVIvKwND0G8DDRuGCLATQqaWqHEW/kKtkXNDxItCh2lKib6BDRi8Pjoi6yk0UzxrwxC7ir6IF/kagQ6lnxuos0bp7eui/UN+/TROR00cSHAyqW2SNaBsSFN877H6IXg7pO5l1EMwBXi/72R4lmy1bNAr5S1Bp2rujf5++iJTTaczZsQ/M+TnQ+rt//bNESGVXjxrxx3gtEZGDF/weIui8zZZ+Fp6Me3w3Nu6Me3weLuu6rPp2i17K+osdznqir+0DRsIcsqZ4FvFw0uelIEektmgVcUzQaRp0dRjoK60Xv+PJED/wPRU3sLk4WzRLOFzW7P9zaA/QQc0VPEuUVT9f/J1R83ph5LhHv2xfqm/clIhIiavnKFBVBt9WyjiXiXfN2it7N50r1+mdVhdGRIrKx4rN0EXlF9mUAu5gvenHMFw2gP7clB+0BGpr3maLCN0fUVRgsIv8SFQdV8bZ5bxDdP/eKCr11osKnKh3x+G5o3h31+K6NqmVgRPT85if6e0fJvrhHF91Fa39miB4jG6R93+QYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYhmEYXsv/AxRAsHI5bUvoAAAAAElFTkSuQmCC\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(42, 43, 40, spline_s=0.01, max_stdev=1.0, live=False)"
]
},
{
"cell_type": "code",
"execution_count": 104,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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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w0THbH4c4zVFNHx2EF225knR9x8ZvNuI9qRFDo2w42SfJ1qvyfpMEBERNflOWgbAbUXXWzPHJe0oImNFe8yWi64TuFSc9wDuJiKTRU//louO27IGgkTL+GfR2cZljWWaJ3p6sI1lm+tF5LeI+2KJ1gt2f+P9ZaKnG/tZHmsvGkpOdfg3RKIvA2Nycgr4PtFgWia6LuGt0jwAdhYdg7ZJdGzniVFeZ6hoOKlv/DFvm6F5W9FlVZaI7reVokMEurR4peZ6ivZAVjaW8+GIx/8nevp6i+j4xzHS/NiJ5jLR43Kr6CQP6ynRvUWDcKmEjzEnk0CWSfj9mz/fRWxjLjmzi9grFB1SEE3kPndSryNE5MsYr9mazwQREVHWe080MKTS2eJsUgARERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERFRFnhERH4XkVIRWS8iX4vIkXGes5OIjBGRzSJSIiLviUiXFJaRiIiIiJLoAAmHt7YicpeIrBWRbWI850sR+UZEdhaRXURkkoh8msIyEhEREVGKtBeRO0WkXkS6RtlmbxFpEJGelvuOaLxvz5SWjoiIiIiS5nzR07kNImKIyHMxtr1IRKps7q8WkX7JLxoRERERpdJOInKHiFwWY5trRGSNzf1rRWSAzf3biEh3EenMH/7whz/84Q9/Muqnu8QeEkZZZBvRCSGHR3n8IhHZanN/tB7A7iIC/vCHP/zhD3/4k5E/3YUCoa2IVIrIpVEe31t0jGDkGMB6sR8D2FlEsGLFCpSVlWXdz+DBgz0vA98b31tQ3lu2vz++t8z8ydb3tmLFCjMAdk5exCA/uV1Edm28/UcRGSW6tEu3GM/5XERyRSeK/EFEJorIhCjbdhYRlJWVIRvl5OR4XYSU4XvLTNn83oDsfn98b5kpW99bWVkZA2CW+1x0TF+FiKwSXc6ll+XxvRofO8ly304i8r7oqeLNIvKuRD9AGAAzFN9bZsrm9wZk9/vje8tM2freGADJrawOgLm5uV4XIWX43jJTNr83ILvfH99bZsrW98YASG5ldQAkIiLKRgyA5BYDIBERUYZhACS3GACJiIgyDAMgucUA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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"live_plot_rgb_splines(45, 46, 44, spline_s=0.08, max_stdev=1.0, live=False)"
]
},
{
"cell_type": "code",
"execution_count": 169,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def plot_rgb_foo(data_rgb, ids_rgb, spline_s=1):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}(R), {}(G), {}(B) at {:%y-%m-%d %H:%M:%S}'.format(*ids_rgb, datetime.now()))\n",
"\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for (steps, values, stdev), (color_dark, color_bright) in zip(data_rgb, colors):\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" \n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)"
]
},
{
"cell_type": "code",
"execution_count": 171,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Poly for run 45: 2\n",
"2.282e-06 x - 0.001576 x + 0.4019\n",
"Poly for run 46: 2\n",
"6.886e-07 x - 0.0005388 x + 0.1561\n",
"Poly for run 44: 2\n",
"1.258e-06 x - 0.001514 x + 0.5252\n"
]
},
{
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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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9I8tQ7/Q+zCHt2j1+oZone4M/f9L0T8CzSZL7WV1K+Gfp4a8fyIiyhDdJf6VQHpK/Uuuh4uOlUuFvqKNWbwOEu1h3Mf0WCvRwB7P+2+ohpR7oNTeKU5ERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERk4/9EZJWIFIvIVhH5n4gcH+U17UVkjIgUiUihiHwkIu2SWEYiIiIiSqAjpDa8NRGRB0Rks4jsFeE1k0Rkioh0EJF9ROQbEZmQxDISERERUZI0F5H7RaRaRDrabHOwiNSIyLGmx34feqxLUktHRERERAlzkejl3BoRCYrI8xG2HSAi5RaP7xaRSxJfNCIiIiJKpvYicp+IXBFhm7+IyCaLxzeLyJ8tHt9LRDqLSFt+8Ytf/OIXv/jlq6/OEnlIGKWRvURvCDnO5vkBIrLL4nG7HsDOIgJ+8Ytf/OIXv/jly6/OQhmhiYiUicjlNs8fLDpGMHwMYLVYjwFsKyJYt24dduzYkXZfWVlZrpeB743vLVPeW7q/P743f36l63tbt26dEQDbJi5ikJfcKyL7h77fT0RGik7t0inCayaKSI7ojSL7isjXIjLeZtu2IoIdO3YgHWVnZ7tdhKThe/OndH5vQHq/P743f0rX97Zjxw4GwDQ3UXRMX6mIbBCdzqWn6fmuoef6mh5rLyKjRS8VF4nIh2J/gjAA+hTfmz+l83sD0vv98b35U7q+NwZAciqtA2BOTo7bRUgavjd/Suf3BqT3++N786d0fW8MgORUWgdAIiKidMQASE4xABIREfkMAyA5xQBIRETkMwyA5BQDIBERkc8wAJJTDIBEREQ+wwBITjEAEhER+QwDIDnFAEhEROQzDIDkFAMgERGRzzAAklMMgERERD7DAEhOMQASERH5DAMgOcUASERE5DMMgOQUAyAREZHPMACSUwyAREREPsMASE4xABIREfkMAyA5xQBIRETkMwyA5BQDIBERkc8wAJJTDIBEREQ+wwBITjEAEhER+QwDIDnFAEhEROQzDIDkFAMgERGRzzAAklMMgERERD7DAEhOMQASERH5DAMgOcUASERE5DMMgOQUAyAREZHP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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ids = (45, 46, 44)\n",
"bands = [(260,410), (150,330), (100,260)]\n",
"poly_degree = 2\n",
"max_stdev = 1.0\n",
"remove_thresh = 0.05\n",
"\n",
"data_rgb = []\n",
"for run_id, (l, r) in zip(ids, bands):\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" \n",
" idxs = (np.abs(stdev[1:-1] - stdev[0:-2]) < remove_thresh) |\\\n",
" (np.abs(stdev[1:-1] - stdev[2:]) < remove_thresh)\n",
" idxs = np.hstack([np.array([True]), idxs, np.array([True])])\n",
" steps, values, stdev = steps[idxs], values[idxs], stdev[idxs]\n",
" \n",
" idxs = (steps < l) | (steps > r)\n",
" poly = np.poly1d(np.polyfit(steps[idxs], values[idxs], poly_degree))\n",
" print('Poly for run {}: {}'.format(run_id, str(poly).strip()))\n",
" \n",
" values -= poly(steps)\n",
" data_rgb.append((steps, values, stdev))\n",
"\n",
"plot_rgb_foo(data_rgb, ids, spline_s=0.05)"
]
},
{
"cell_type": "code",
"execution_count": 238,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def plot_rgb_bar(data_rgb, ids_rgb, spline_s=1):\n",
" fig, ax = plt.subplots(1, 1)\n",
" fig.suptitle('Runs {}(R), {}(G), {}(B) at {:%y-%m-%d %H:%M:%S}'.format(*ids_rgb, datetime.now()))\n",
"\n",
" colors = [\n",
" ((1,0,0), (1,0.8,0.8)),\n",
" ((0,1,0), (0.8,1,0.8)),\n",
" ((0,0,1), (0.8,0.8,1))\n",
" ]\n",
" for (steps, values, stdev), (color_dark, color_bright) in zip(data_rgb, colors):\n",
" ax.errorbar(steps, values, yerr=stdev, color=color_bright)\n",
" \n",
" spline = inter.UnivariateSpline(steps, values, s=spline_s)\n",
" ax.plot(steps, spline(steps), color=color_dark)\n",
" \n",
" ax.set_xlim([380, 720])\n",
" ax.set_xlabel('$\\lambda [nm]$')\n",
" ax.set_ylabel('normalized amplitude')"
]
},
{
"cell_type": "code",
"execution_count": 226,
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nO3deZyWdb3/8XdpItuA4c6iYoaCklqJCmlamluYHj1qbqfFsjOc/I1Ji5ZKrimHLC3L49bCkZOWJ9tGM0UTFyDQ456KIJug7AMIw9zv3x/fQYbxvmfhOzPf+7qv1/PxuB8x91z3PR+vLp0X13Vf1yUBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyKjTJD0qaYWkBknvb2X5vpImSlomaamkX0nq05kDAgAAoGMdpRCBX1DbAvBPkh6QtJ2kD0r6q6T/7cwBAQAA0DkOV+sBOEhSQdK+TZ4b3vjcgM4bDQAAAJ2hLQE4WtLaIs+/I+mEzhgKAAAAnactAXiWpIVFnn9T0ueLPP8+Sf0lVfHgwYMHDx48MvXor/B7HBWurXsA1xR5vtQewP6SzIMHDx48ePDI5KO/UPEOV9s+A9ig934GsEHFPwNYJclz5871ihUruuxRXV3dpT8viw/WEeuIdcQ6KpcH66j81tHcuXM3BmBVxyQGytH7JXWTdLRCyPVo/LrUbt8/SKqV1E/S9pLul3RviWWrJHnFihXuSjU1NV3687KIddQ61lHrWEetYx21jnXUuq5eRytWrCAAc+BchbN4GxofG/98mKSBklZJGtlk+b6Sfi1pucK1AH+p0hsIAVimWEetYx21jnXUOtZR61hHrSMAkTVJArC2trZLf14WsY5axzpqHeuodayj1rGOWtfV64gARKwkAQgAALYcAYhYBCAAABlDACIWAQgAQMYQgIhFAAIAkDEEIGIRgAAAZMDbb9sTJ9rnnGO/+SYBiDgEIAAAZahQsGfMsK+80j7kEHurrewDDrAvucSePZsARBwCEACAMrFmjf3739tf+pK9yy527972ySfbt95qz5+/aTkOASMWAQgAQELLl4dDu6ecYvfsaQ8ebF94of23v9nr1hV/DQGIWAQgAABd7M037VtusY85xv7AB+zhw+3LLrOfeSYc+m0NAYhYBCAAAF1g0SL7ppvsT3wifJ7v0EPt66+3X321/e9FACIWAQgAQCdZvty+4w776KPtrbe2R40KEbhgQdz7EoCIRQACANCB1qyxf/Mb+6ST7G7dwpm7111nz5nTcT+DAEQsAhAAgEgNDfZDD4Vr9PXqZe+1l33ppfaLL3bOzyMAEYsABABgC82aFUJvt93s7be3L7jAnj69bSdyxCAAEYsABACgHerq7DvvtA8/PJzBO3q0fe+9pS/Z0hkIQMQiAAEAaEWhYD/2mP2FL4RDvPvtZ0+YEC7nkgIBiFgEIAAAJSxbZt94oz1smN23rz1mjP2Pf3T+Id7WEICIRQACANBEoWBPnWp/8Yt29+72wQeHS7msXp16sk0IQMQiAAEAsL1ypf3zn4fLtvTubX/ta/bTT6eeqjgCELEIQABArr30Uji027u3feCB4RZtq1alnqplBCBiEYAAgNxpaLD/8pdwL95u3eyzzrKfeir1VG1HACIWAQgAyI2VK8Ot2IYMsXfayb7sMnvhwtRTtR8BiFgEIACg4r32ml1TY1dV2R/9qP3LX9rvvJN6qi1HACIWAQgAqFhPPmn/y7/Y22xjn3aaPWVK+ku4dAQCELEIQABARWlosO+7z/7EJ8JFmy+80H7jjdRTdSwCELEIQABARXjnHfvWW+2997Z32cW+9tpwIedKRAAiFgEIAMi0pUvtq6+2d97ZHjrUvv32bH++ry0IQMQiAAEAmbRokf2tb4XDvIcfbv/xj+Hwbx4QgIhFAAIAMmXePPuCC+wePezjj7cffzz1RF2PAEQsAhAAkAmzZtlf/aq97bbhzN4ZM1JPlA4BiFgEIACgrL30kn3uueGOHWeeaT/3XOqJ0iMAEYsABACUpWeeCdfu69bN/vKX7VdeST1R+SAA82OcpPmSVkmaLGlYC8vuLenPkt6S9Lak2yT1KrEsAQgAKCvPPWefcordvbs9Zow9Z07qicoPAZgPYyXNkTRUUjdJV0uaJ6lHkWV7S3pD0vclbS1pB4Vg/G2J9yYAAQBl4eWX7c9/PnzGr7ranj8/9UTliwDMh1mSxjT5eitJiyWdWWTZYxT2Ejb1KUkbJO1aZHkCEACQ1Guv2f/2b5sO9c6enXqi8kcAVr4qSQVJI5o9f7+k8UWWP05SnaT3NXnuaEkNko4v8f4EIACgy82ZY593Xgi/c86xX3019UTZQQBWvgEKATik2fOTJN1SZPk+khZKukbStpL6S3pEIQDPKLI8AQgA6FLz54dDvNtua59+uv3ii6knyh4CsPK1dw+gJO0v6QFJiyT9U9JXGt/jqBLvTwACADrdkiX22LHh5I6TT7affTb1RNlFAOZDsc8ALlLxzwAWc6LC5wJ7F/lelSRXV1e7pqbGNTU1rq2tTb1dAwAqyJo19g9+YPftax91lD19euqJsqm2tvbd39XV1dUEYA5cJGm2wqVfuku6StJcFT8LWJIObPzeVpI+oRCQF5ZYlj2AAIBOUV9v33qr3b+//dGP2n/9a+qJKgd7APPjcoXP9tVp8+sADlTYuzeyybI/Ubj+X52kZyV9oYX3JQABAB2qULDvvdfeZx97zz3tSZPshobUU1UWAhCxCEAAQId59FH7kEPsHXe0b7rJXrcu9USViQBELAIQABDt+eftz37W7tXLHjfOXrUq9USVjQBELAIQALDFFi2yzz8/XNJlzJjwNTofAYhYBCAAoN3Wrg1n9lZV2aNH2y+9lHqifCEAEYsABAC0WaFg/8//2Lvvbu+/v/3QQ6knyicCELEIQABAmzz5ZDjBY5dd7DvusDdsSD1RfhGAiEUAAgBaNHu2fcYZdo8e9mWXcYJHOSAAEYsABAAUtWqVffHF4dZt555rz52beiJsRAAiFgEIANhMoWD/93+HO3iMHMmt28oRAYhYBCAA4F0zZ9qjRtm77mpPnBhiEOWHAEQsAhAA4LfeCtfz697d/s53+JxfuSMAEYsABIAcq68Pt2zbbjv7hBPsV15JPRHaggBELAIQAHLq4Yft/faz99rL/tOfUk+D9iAAEYsABICcmTfPPu00u3dv+7rr7HXrUk+E9iIAEYsABICcqK+3J0wI4ff5z9sLFqSeCFuKAEQsAhAAcuCxx+zhw+299+b2bZWAAEQsAhAAKtjixfYXvmD37Glfcw2HeysFAYhYBCAAVKCGBvvnPw9n9554YridGyoHAYhYBCAAVJgZM+wRI+zdd7fvuy/1NOgMBCBiEYAAUCGWL7f/4z/CxZwvucRevTr1ROgsBCBiEYAAkHGFgn3XXfbOO9uf+pT90kupJ0JnIwARiwAEgAx7/XX7mGPsHXe0//u/uXdvXhCAiEUAAkAG1dfb48eHs3vPO89eujT1ROhKBCBiEYAAkDHTp9sHHmgPGWI/8kjqaZACAYhYBCAAZMSqVfaFF4aTPC691F67NvVESIUARCwCEAAy4E9/snfbzR41yn7++dTTIDUCELEIQAAoY2++aZ9+ut2nT7iwc0ND6olQDghAxCIAAaAMFQr2rbfaffvap55qL1iQeiKUEwIQsQhAACgzr71mH3GEPWAAd/JAcQQgYhGAAFAmNmywb7ghXNrla1+z+U8zSiEAEYsABIAy8OKL9qGH2oMH2w8/nHoalDsCELEIQABIqL7evuYau0cPu6bGrqtLPRGygABELAIQABJ55hn7ox+199nHfvzx1NMgSwhAxCIAAaCLrVtnX3ZZuKDzxRdzQWe0HwGYH+MkzZe0StJkScNaWPZjkh6StFTSYkm/lTSoxLIEIAB0oWnT7H33tT/yEXvGjNTTIKsIwHwYK2mOpKGSukm6WtI8ST2KLPs+SYskTZC0taSekv5H0pQS700AAkAXWLPG/uY3w16/K6+0169PPRGyjADMh1mSxjT5eiuFPXtnFlm2r6QGSfs1ee54SatLvDcBCACdbMoU+8Mftg86yH7uudTToBIQgJWvSlJB0ohmz98vaXyJ1/xY0o2SuisE4d2SftnC+xOAANAJ1q61x44NZ/hef324zh/QEQjAyjdAIQCHNHt+kqRbSrzmMEkvSKqXtEHSdEk7lFiWAASATjBtmj10qP3xj9svvJB6GlQaArDytXcP4IckrZP0VUkfUNgLOE7Sq5K2LfH+rq6udk1NjWtqalxbW5t6uwaAzFq3zv7e9zZ91q++PvVEqBS1tbXv/q6urq4mAHOg2GcAF6n4ZwBPlrSs2XO9FSLy40WWZw8gAHSQZ56x998/nOH79NOpp0ElYw9gPlwkabbCpV+6S7pK0lwVPwt4kMIJH19WCMVtJV0maYWkPkWWJwABIFJ9vX3VVWGv33e/G/YCAp2JAMyPyyUtlFSnza8DOFDh2oAjmyz7aUmPK1wHcEnj8qNKvC8BCAARXnghnN27zz721Kmpp0FeEICIRQACwBbYsMEePz6c4XvRRdzNA12LAEQsAhAA2unVV+1Ro+wPfch+7LHU0yCPCEDEIgABoI0KBfunP7V79bLHjLHr6lJPhLwiABGLAASANliwwD72WHvgQPtvf0s9DfKOAEQsAhAAWvHb39r9+tlnnmkvW5Z6GoAARDwCEABKWLHCPvdce7vt7EmTUk8DbEIAIhYBCABFPPqovdtu9qc/bc+bl3oaYHMEIGIRgADQxDvv2N/6Vri8y49+ZDc0pJ4IeC8CELEIQABo9Oyz4TZuBxxgP/986mmA0ghAxCIAAeReQ4M9YULY63fxxdzKDeWPAEQsAhBArr3xhn3kkfYee3BRZ2QHAYhYBCCA3Jo40e7Tx/7iF+2VK1NPA7QdAYhYBCCA3Fm61D79dHv77e177009DdB+BCBiEYAAcuWRR8LdPI47zl64MPU0wJYhABGLAASQC+vX29/9bjjR48c/Dvf1BbKKAEQsAhBAxXvtNXvECHvYMPv//i/1NEA8AhCxCEAAFe1Xv7KrquwxY+w1a1JPA3QMAhCxCEAAFWn5cvvznw8nevzhD6mnAToWAYhYBCCAijNlir377vbRR3OiByoTAYhYBCCAilFfb19+eTjRY8IE7uOLykUAIhYBCKAivP66PXKkvffe9syZqacBOhcBiFgEIIDMu+uucEeP88+3V69OPQ3Q+QhAxCIAAWTWypX2OefY/fpxRw/kCwGIWAQggEx66il7zz3tI4+0581LPQ3QtQhAxCIAAWRKQ4N97bXhRI/rruNED+QTAYhYBCCAzHjzTfuoo8Kev2nTUk8DpEMAIhYBCCATHnjA3mkn+4wzbP6ThbwjABGLAARQ1tavt7/1LbtnT/u22+xCIfVEQHoEIGIRgADK1uuv2wcfbO+3n/3CC6mnAcoHAYhYBCCAsnT33XbfvvbXvmavWZN6GqC8EICIRQACKCtr1oQLOvfta99zT+ppgPJEACIWAQigbDz/vL3vvvYhh4TDvwCKIwARiwAEkFyhYP/Xf4UTPb7znXDiB4DSCEDEIgABJLV8uX3aaeESLw88kHoaIBsIwPwYJ2m+pFWSJksaVmK5gY3LrGzyeEdSvaQPFlmeAASQzNSp9uDB9tFHh4s8A2gbAjAfxkqaI2mopG6SrpY0T1KPNr7+t5J+X+J7BCCALtfQYF9/vd29u/2DH3A7N6C9CMB8mCVpTJOvt5K0WNKZbXhtf0nrJR1d4vsEIIAutXixfeyx9u672088kXoaIJsIwMpXJakgaUSz5++XNL4Nr/++pFdaeX8CEECXmDzZ3mUX+5RT7GXLUk8DZBcBWPkGKATgkGbPT5J0Syuv3Vrhc4MXtrAMAQig0zU02FdeaffoYf/0p9zODYhFAFa+mD2A/ypptaTtWnl/V1dXu6amxjU1Na6trU29XQOoIIsWhZM89tzT/sc/Uk8DZFdtbe27v6urq6sJwBwo9hnARWr9M4APS7q9lWXYAwig0zzyiL3rrvapp4bLvQDoGOwBzIeLJM1WuPRLd0lXSZqrls8CHqqw5/Bjrbw3AQigwzU02FddFQ75/uQnHPIFOhoBmB+XS1ooqU6bXwdw43X/RjZb/seSprbhfQlAAB1q4yHfwYM55At0FgIQsQhAAB1m4yHfU07hkC/QmQhAxCIAAURresj3pps45At0NgIQsQhAAFEWL950yHf69NTTAPlAACIWAQhgi3HIF0iDAEQsAhBAuzU02FdfzSFfIBUCELEIQADtsnix/ZnPcMgXSIkARCwCEECbPfpoOOT7L//CIV8gJQIQsQhAAK1qesj3xhs55AukRgAiFgEIoEWLF9vHHGPvsYc9bVrqaQDYBCDiEYAASpoyxe7fPxzyXbYs9TQANiIAEYsABPAehYL9wx/a3bvbN9zAIV+g3BCAiEUAAtjMypX2qaeGPX9TpqSeBkAxBCBiEYAA3vXcc/aQIfaRR9qLFqWeBkApBCBiEYAAbNsTJ9q9etmXXGJv2JB6GgAtIQARiwAEcu6dd+zqartvX/sPf0g9DYC2IAARiwAEcmzOHPugg+wDD7RnzUo9DYC2IgARiwAEcur+++1+/ezzzrPXrk09DYD2IAARiwAEcqahwR43zu7Z07799tTTANgSBCBiEYBAjrz9tn3ssfaee9ozZ6aeBsCWIgARiwAEcmLqVHvQIPvEE7mrB5B1BCBiEYBAhSsU7Jtvtnv0sH/wA+7qAVQCAhCxCECggq1ebZ99tr3TTvbDD6eeBkBHIQARiwAEKtTLL9v77muPGmUvWJB6GgAdiQBELAIQqEC//a1dVWV/4xv2+vWppwHQ0QhAxCIAgQqyfn2Ivqoq+557Uk8DoLMQgIhFAAIVYsEC+xOfCId9X3459TQAOhMBiFgEIFABJk8OJ3qcfbZdV5d6GgCdjQBELAIQyLBCIVzapUcP+2c/4xIvQF4QgIhFAAIZtWxZuKjzoEHhIs8A8oMARCwCEMigp58Ot3M75phwezcA+UIAIhYBCGTMHXfYPXva3/++3dCQehoAKRCAiEUAAhmxdq193nl2v372/fenngZASgQgYhGAQAbMmmUfeKA9YoQ9Z07qaQCkRgDmxzhJ8yWtkjRZ0rBWlv83Sf8nqU7Sm5JuKLEcAQiUuT/+0d5uO3vMGHvdutTTACgHBGA+jJU0R9JQSd0kXS1pnqQeJZb/hqTXJB0q6f2Sukvav8SyBCBQpjZssC++2O7Vy544MfU0AMoJAZgPsySNafL1VpIWSzqzyLK9FfYSHtfG9yYAgTK0aJH9qU/ZQ4bYzz2XehoA5YYArHxVkgqSRjR7/n5J44ss/xlJDZK+KumfCod//yJpeAvvTwACZeTxx+3+/e1//Vd75crU0wAoRwRg5RugEIBDmj0/SdItRZY/s3H5RyTtrHDI+FpJCxT2DjZHAAJlolCwf/SjcFePG27grh4ASiMAK1979wB+tnH5o5s8935JqxX2DhZ7fwIQSGzlyrDHb9dd7SlTUk8DoNwRgPlQ7DOAi1T8M4Ab9xge3Wz5FgOwurraNTU1rqmpcW1tbertGsiV55+3997bPvLI8Nk/ACimtrb23d/V1dXVBGAOXCRptsKlX7pLukrSXJU+C/i3CpeK2VGbzhqeK6lXkWXZAwgkdNdd4Szfiy8OZ/0CQFuwBzA/Lpe0UOG6fpO16TqAAxXO+h3ZZNlekm6VtFTSW5L+rHAJmWIIQCCBdevCdf369rXvuy/1NACyhgBELAIQ6GJvvGEffLB9wAH2a6+lngZAFhGAiEUAAl3ogQfs7be3v/zlcG9fANgSBCBiEYBAF2hosK+4wu7Z07799tTTAMg6AhCxCECgky1ZYh93nD14sD1zZuppAFQCAhCxCECgE02bZu+2mz16tL1sWeppAFQKAhCxCECgExQK9s9+Fu7qce214RAwAHQUAhCxCECgg61ebZ9zjr3TTvbDD6eeBkAlIgARiwAEOtA//2kPH26PGmXPn596GgCVigBELAIQ6CC/+51dVWV/4xv2+vWppwFQyQhAxCIAgUj19fZFF4X4u/vu1NMAyAMCELEIQCDCggX2YYfZ++5rv/xy6mkA5AUBiFgEILCFHnkknOhx1ll2XV3qaQDkCQGIWAQg0E6Fgn399eESLzffHL4GgK5EACIWAQi0w/Ll9kkn2YMG2VOnpp4GQF4RgIhFAAJt9Mwz9oc+ZB9zjP3226mnAZBnBCBiEYBAG/ziF3bPnva4cdzVA0B6BCBiEYBAC9autb/yFbtfP7u2NvU0ABAQgIhFAAIlvP66/dGP2gcdZM+Zk3oaANiEAEQsAhAo4k9/srfbzq6utt95J/U0ALA5AhCxCECgiQ0b7O9+1+7Vy544MfU0AFAcAYhYBCDQaPFi+9OftocMsZ97LvU0AFAaAYhYBCBg+4kn7AED7FNPtVeuTD0NALSMAEQsAhC5VijYP/5xuKvHD3/IXT0AZAMBiFgEIHJr1Sr79NPtXXe1H3ss9TQA0HYEIGIRgMilF16w99nHPuIIe9Gi1NMAQPsQgIhFACJ3Jk2ye/e2v/Mdu74+9TQA0H4EIGIRgMiNdevsr3/d7tvXvu++1NMAwJYjABGLAEQuzJ1rH3KIfcAB9muvpZ4GAOIQgIhFAKLi/fWv9vbb21/6kr1mTeppACAeAYhYBCAqVkODfeWVds+e9u23p54GADoOAYhYBCAq0tKl9vHH24MH2zNnpp4GADoWAYhYBCAqzvTp9u6726NH28uWpZ4GADoeAYhYBCAqRqFg33JLuKvHtdeGQ8AAUIkIQMQiAFERVq+2zz3X3nFH+6GHUk8DAJ2LAMyPcZLmS1olabKkYS0sO1nSOkkrG5dfKen8EssSgMi8V16xhw+3R460589PPQ0AdD4CMB/GSpojaaikbpKuljRPUo8Syz+sEIxtQQAi0+691+7Tx77wQnv9+tTTAEDXIADzYZakMU2+3krSYklnllj+YUnfb+N7E4DIpPp6+5vftKuq7LvvTj0NAHQtArDyVUkqSBrR7Pn7JY0v8ZqHJb0laYmkFyRdI6lnC+9PACJTFi60Dz/cHjbMfuml1NMAQNcjACvfAIUAHNLs+UmSbinxmoMl9W38836SZki6q8SyBCAy5dFH7V12sc86y66rSz0NAKRBAFa+LdkD2NzhktYrfH6w2Pu7urraNTU1rqmpcW1tbertGniPQsG+/vpwiZef/jR8DQB5Ultb++7v6urqagIwB4p9BnCRSn8GsLnDFAJw2yLfYw8gyt7y5fbnPmfvtps9dWrqaQAgPfYA5sNFkmYrXPqlu6SrJM1V8bOAd5T0mSbfGyZpmqS7S7w3AYiy9vTT9p572scea7/9duppAKA8EID5cbmkhZLqtPl1AAcqXOtvZOPXgyQ9JWm5wvX//ilOAkFG3X673bOnfcUV3NUDAJoiABGLAETZWbPG/tKX7O23t//619TTAED5IQARiwBEWXn1VXv//e1DDrHnzk09DQCUJwIQsQhAlI3//d9wV48LLrDXrUs9DQCULwIQsQhAJLfxrh69e9u/+U3qaQCg/BGAiEUAIinu6gEA7UcAIhYBiGQmT7Z33pm7egBAexGAiEUAossVCvYPfhDu6nHzzdzVAwDaiwBELAIQXWrZMvvEE8NdPaZNSz0NAGQTAYhYBCC6zMyZ4a4exx1nL1mSehoAyC4CELEIQHSJ224Ld/W48kru6gEAsQhAxCIA0anWrLG/+EV7hx3sBx9MPQ0AVAYCELEIQHSajXf1OPRQe9681NMAQOUgABGLAESnuPfecFeP//f/7PXrU08DAJWFAEQsAhAdqr7eHjuWu3oAQGciABGLAESHWbDAPuww7uoBAJ2NAEQsAhAdYvJke6ed7LPP5q4eANDZCEDEIgARpVCwr7023NXjZz/jrh4A0BUIQMQiALHFli2zR4/mrh4A0NUIQMQiALFFZsywBw+2jz+eu3oAQFcjABGLAES7FAr2z38eDvlyVw8ASIMARCwCEG22apV91lnhZI+HHko9DQDkFwGIWAQg2uT55+199rE/+Ul74cLU0wBAvhGAiEUAolW/+pXdq5d9ySXhQs8AgLQIQMQiAFHSmjX2eefZ/frZf/5z6mkAABsRgIhFAKKoV16x99/fPvhg+403Uk8DAGiKAEQsAhDvcc89dlWVfeGF9rp1qacBADRHACIWAYh3rVtnX3CB3aeP/bvfpZ4GAFAKAYhYBCBs27Nn2wcdZB9wgP3qq6mnAQC0hABELAIQ/uMf7e22s88/3167NvU0AIDWEICIRQDmWH29/e1vh0u8TJyYehoAQFsRgIhFAObU/Pn2YYfZw4bZL76YehoAQHsQgIhFAObQgw/aO+5on3OOXVeXehoAQHsRgIhFAObIhg32uHF2z572bbfZhULqiQAAW4IARCwCMCcWL7aPPtreay/76adTTwMAiEEA5sc4SfMlrZI0WdKwNrymt6Q5khokvb/EMgRgDvz973b//vapp9r8Xw0A2UcA5sNYhZAbKqmbpKslzZPUo5XX3SbpLyIAc6tQsK+/3u7Rw77xRg75AkClIADzYZakMU2+3krSYklntvCaz0p6StKRIgBzaelS+7OftXfbzZ46NfU0AICORABWvipJBUkjmj1/v6TxJV7TT9JsSftIOlwEYO5MnWrvvrt9wgn2kiWppwEAdDQCsPINUAjAIc2enyTplhKv+R9J32n8MwGYI4WCfdNN4ZDvddfZDQ2pJwIAdAYCsPK1dw/g6ZKmaVPwfVIhALdq4f1dXV3tmpoa19TUuLa2NvV2jS2wfLl9yin2rrvajz6aehoAQEerra1993d1dXU1AZgDxT4DuEjFPwN4h8KZwm81PpYrBAZXnpAAABGmSURBVORiSWcXWZ49gBVg+nR78GD7M58Jl3sBAFQ29gDmw0UKn+kbJqm7pKskzVXxs4D7SNq1yeMUhT2AAxpf2xwBmGGFQji7t0cP+5prOOQLAHlBAObH5ZIWSqrT5tcBHKiwx29kidfxGcAKtWyZffLJ4fp+f/976mkAAF2JAEQsAjCDpk2z99jDPvZY+623Uk8DAOhqBCBiEYAZUijYP/pROOR77bUc8gWAvCIAEYsAzIhly+yTTrIHDLAfeyz1NACAlAhAxCIAM+Cpp8KFnY87jkO+AAACEPEIwDJWKNg33MCFnQEAmyMAEYsALFNLl9qf+5w9cKA9ZUrqaQAA5YQARCwCsAw99ZS922728cfbb7+dehoAQLkhABGLACwjhYL9wx+GQ77XX88hXwBAcQQgYhGAZWLpUvvEE8Mh38cfTz0NAKCcEYCIRQCWgSefDId8P/tZe8mS1NMAAModAYhYBGBChYL9n/8ZDvn+53+GrwEAaA0BiFgEYCJLltijR9uDBtlPPJF6GgBAlhCAiEUAJvDEEyH8Ro/mkC8AoP0IQMQiALtQoWCPHx8O+U6YwCFfAMCWIQARiwDsIm+9ZZ9wQjjZ48knU08DAMgyAhCxCMAu8Mgjdv/+9kknhcu9AAAQgwBELAKwE23YYI8bFw753nQTh3wBAB2DAEQsArCTzJ9vH3GE/eEP2zNnpp4GAFBJCEDEIgA7wV/+Yu+wg3322faqVamnAQBUGgIQsQjADrR+vT12rN2rl33nnamnAQBUKgIQsQjADvL66/aIEfbw4faLL6aeBgBQyQhAxCIAO8A999h9+9pf+5q9Zk3qaQAAlY4ARCwCMMLatSH6+vQJEQgAQFcgABGLANxCL74YDveOGBEO/wIA0FUIQMQiALfAnXeGEz2++c1w4gcAAF2JAEQsArAdVq4Ml3bZYYdwqRcAAFIgABGLAGyjmTPtvfYKF3eePz/1NACAPCMAEYsAbEWhYN94Y7id2/e/H27vBgBASgQgYhGALVi61D7pJLt/f/uRR1JPAwBAQAAiFgFYwuOP24MG2SecYL/1VuppAADYhABELAKwmYYG+5prwiHfCRPCIWAAAMoJAYhYBGATb75pH320PXiwPW1a6mkAACiOAEQsArDRgw/aO+9sn3aavXx56mkAACiNAMyPcZLmS1olabKkYS0s+3tJ8yStaPzf2yR9sMSyuQ/A+nr7kkvsnj3tW27hkC8AoPwRgPkwVtIcSUMldZN0tULY9Six/H6Ny0lSH0l3SbqnxLK5DsDXX7cPOcQeOtR+9tnU0wAA0DYEYD7MkjSmyddbSVos6cw2vHY7SRMl/V+J7+c2ACdNsvv0sc8/3169OvU0AAC0HQFY+aokFSSNaPb8/ZLGt/C6qyWtbHxtnaSTW3j/XAVgXZ39xS/a221n/+53qacBAKD9CMDKN0Ah4oY0e36SpFva8Po9JH1f0vAS389VAM6YYQ8ZYh92mP3GG6mnAQBgyxCAlW9L9wA29XFJCxUOHRd7/4oPwELB/uEPuZ0bAKAyEID5UOwzgIvUts8AStJISQ0qfiZwlSRXV1e7pqbGNTU1rq2tTb1dd6hFi+zjjgt39XjssdTTAACwZWpra9/9XV1dXU0A5sBFkmYrXPqlu6SrJM1V8bOA95J0kqTejV8PkTRF0hMl3rui9wA+8EC4tt+pp4b7+gIAUAnYA5gflyscxq3T5tcBHKhwbcCRjV9/WNLfJS1VOAlklqSfStqxxPtWZACuW2d/85vh2n7/9V9c2w8AUFkIQMSquAB89VX74x+3hw+3X3gh9TQAAHQ8AhCxKioAf/1ru3dv++tft9euTT0NAACdgwBErIoIwJUr7bPPtvv1s++7L/U0AAB0LgIQsTIfgNOm2R/6kH3kkfb8+amnAQCg8xGAiJXZAGxosK+7zu7e3b7mGq7tBwDIDwIQsTIZgAsX2kcdZe+xh/3kk6mnAQCgaxGAiJW5APzzn+0ddrDPOMNevjz1NAAAdD0CELEyE4DvvGPX1Ni9etl33sm1/QAA+UUAIlYmAvCll+wDDrAPPNB++eXU0wAAkBYBiFhlHYCFgn377WGv3ze+Ee7wAQBA3hGAiFW2Abh8uX366faOO9q1tamnAQCgfBCAiFWWAfjEE/buu9uf+Yz95puppwEAoLwQgIhVVgG4YYN91VXh2n7jx4dr/QEAgM0RgIhVNgE4b559xBHhrh7Tp6eeBgCA8kUAIlZZBOB994X7+J57brivLwAAKI0ARKykAbh2rT1mjF1VZU+cmGQEAAAyhwBErGQB+Pzz9n772QcdZL/2Wpf/eAAAMosARKwuD8BCwf75z+2ePe1vf9tev77LfjQAABWBAESsLg3AJUvsk0+2d9nFfvDBLvmRAABUHAIQsbosAB991B440D7+eHvx4k7/cQAAVCwCELE6PQDr6+3LLrN79LB//ONwCBgAAGw5AhCxOjUA58yxR42y997bfvrpTvkRAADkDgGIWJ0WgPfcY/fta3/5y3ZdXYe/PQAAuUUAIlaHB+Dq1fZXvmL36WP/5jcd9rYAAKARAYhYHRqAzzxjDx1qH3qoPXt2h7wlAABohgBErA4JwELBvummcKLHpZeGEz8AAEDnIAARKzoA33rLHj3aHjDAnjy5A7duAABQFAGIWFEB+NBD9q672iedFC7yDAAAOh8BiFhbFIDr19sXXxwO+d58M9f2AwCgKxGAiNXuAJw1yz74YHvffe1nn+3ErRsAABRFACJWuwLwrrvC5V3+/d/tNWs6eesGAABFEYCI1aYAXLXK/sIX7A9+0L733i7augEAQFEEIGK1GoD/+If94Q/bhx9uz53bdRs3AAAojgBErJIB2NBgT5hgd+9uX3GFvWFDgi0cAAC8BwGYH+MkzZe0StJkScNKLLeDpDslzZK0svF/r5a0TYnliwbgokX2scfagwbZjz2WaOsGAABFEYD5MFbSHElDJXVTCLp5knoUWXYPSd9u/F9JGizpGUkTSrz3ewLwgQfsnXayTz3VXrYs4dYNAACKIgDzYZakMU2+3krSYklntvH1F0iaWeJ77wbgunX22LF2z572rbdybT8AAMoVAVj5qiQVJI1o9vz9ksa38T3+JOm2Ft7fM2as8Mc+Zn/kI/aLL6berAEAQEsIwMo3QCEAhzR7fpKkW9rw+u8pfHZw1xLfr5LkXr1W+IIL7LVrU2/SAACgNQRg5YvZA3iFwmcHP9TK+/v446tdU1Pjmpoa19bWpt6uAQBAM7W1te/+rq6uriYAc6DYZwAXqeXPAP5E0j8lDWzlvbfoXsAAACAd9gDmw0WSZitc+qW7pKskzVXxs4C3kjRR0rOSdm7DexOAAABkDAGYH5dLWiipTptfB3CgwrUBRzZ+fZikBklrFK4DuLLx+ytLvC8BCABAxhCAiEUAAgCQMQQgYhGAAABkDAGIWAQgAAAZQwAiFgEIAEDGEICIRQACAJAxBCBiEYAAAGQMAYhYBCAAABlDACIWAQgAQMYQgIhFAAIAkDEEIGIRgAAAZAwBiFgEIAAAGUMAIhYBCABAxhCAiEUAAgCQMQQgYhGAAABkDAGIWAQgAAAZQwAiFgEIAEDGEICIRQACAJAxBCBiEYAAAGQMAYhYBCAAABlDACIWAQgAQMYQgIhFAAIAkDEEIGIRgAAAZAwBiFgEIAAAGUMAIhYBCABAxhCAiEUAAgCQMQQgYhGAAABkDAGIWAQgAAAZQwAiFgEIAEDGEICIRQACAJAxBCBiEYAAAGQMAYhYBCAAABlDACIWAQgAQMYQgIhFAAIAkDEEIGIRgAAAZAwBmB/jJM2XtErSZEnDWlj2CkkzJK2T9Ggr70sAAgCQMQRgPoyVNEfSUEndJF0taZ6kHiWWP1fS8ZJuVJkGYG1tbZf+vCxiHbWOddQ61lHrWEetYx21rqvXEQGYD7MkjWny9VaSFks6s5XXXaYyDcCampou/XlZxDpqHeuodayj1rGOWsc6al1XryMCsPJVSSpIGtHs+fsljW/ltQRghrGOWsc6ah3rqHWso9axjlpHAKKjDVAIwCHNnp8k6ZZWXtvmAJw7d65XrFjRZY/q6uou/XlZfLCOWEesI9ZRuTxYR+W3jubOnUsAVrjO3gPYX2ED4sGDBw8ePHhk79FfqFjFPgO4SB3zGcD3KWw8VTx48ODBgwePTD36K/weR4W6SNJshUu/dJd0laS5Kn0W8NaStpV0paS/K5w53K3TpwQAAECHulzSQkl12vw6gAMVrg04ssmydygcNm5ofGz8MwAAAAAAAAB0jHsV9jwe2eS5T0r6h6TVkl6TdH6z12wj6SeS3pK0QtJ9CmdBV6rm62i3xq9XSVrZ5H97N3lNpa+jyyRt0Ob//BObfH+4pEcU9oTPa1y+ufbcNSeLWltHBUlrmn2/+Tqo9HW00SGS/qawDpZJeqzJ99iWgpbWUd63pecU/pk3PlYrrJMTG7/PNgQ0c47CWcoN2jxu6hSib2tJh0lark3/IkkhbJ5WCJpekn6hcEu7SlRqHTVI2qOF11X6OmrpxKVekhYofLZ1G0n7KnwW9oImy7T3rjlZ1NrJXQVJR7Tw/TysIymEzTJJZyn8c75f0scbv8e2FLS0jiS2peb+Q+EmDNuIbQh4jwEKJ6xsvH7hxri5VGHvX1MTJP218c/dFP52dUKT7/eTtF6bf76xEpRaRxv3AO5Z4nV5WEctxc25kt5U+CW10dclvdLk6y29a06WtCUAj2zh+3lYR1JYR9eV+B7bUtDSOpLYlpp7XiHiJLYh4D3ul/Slxj83/Y/H7yTd3GzZMyS93fjnjyjs/dqp2TIva/N/gSpBqXW0cQ/gXIVDvI9J+lyT1w1X5a+jyxQOlSyS9LrCoc3dG783QdJfmi1/iMI66aVwSYQtvWZmlrS0jqSwDhYobEPTJX25yffyso66Kxwmv1TSkwr/nZkm6eTG77Mttb6OJLalpo6UVC9pUOPXbENAE/+usHFv1PTwwYOSrmm2/DEKe68kaZTCvzjNL1fzpKSLO3bMpIqto40B2FPhPxZbK6yHsyS9o7CepHyso6EKZ7ZL0i6Sfq3wN+oekm6VdFez5fdWWCe7Ku6uOVlSbB29qk2HlY5Q2Ea2lnSspKWSvtr4vbyso/4K/5wLJR2osJfmJEnrJB0stiWp5XW0MVrYlja5W9IfmnzNNgQ0GqzwN8WBTZ5rzx7APOzdam0dFXOHwi94KR/rqLltJK2V9GnxN+5Smq6jYi7Tpg/252UdbfznvLrZ87UKfxFlW2p9HRWTx21JCn/RWq9NfxmX2IaAd52rsLdqscLhgrcUNv5lkn4m6Xtq/2cAt1f422ilfL6ttXVUzG3adIZnHtZRc9sonIV4lMKJM1vymZu23DUny5quo2IulTSlydd5WUevqHTcsC0FLa2jYvK6LV2ucOWKptiGgEbbKuz2bvooSDpVUl+Fz03UKRw++ICkTyiET9OzgG9SOKN1oMKlT36h90ZjlrW2jkYpHEJ4v8I6OkPhF3vT4Kv0dXSqwoktUtjT+UuF/4j2VPhb9XxJVyisy30VzrBretZde++ak0UtraMDFA7nfUDhl83RkpZIqm7y+jysIyn8Ml6g8Pni90karfDv08fEtrRRqXX0cbEtbbSVwpm7FzV7nm0IaEHTS5xI4dIvMxT2Ys3Sps+SbLSNpBsVDguvVPi8RaXf5LrpOvqSwme5Vimsg8e1+QeypcpfR79X+BtyncJ/KCcqHDrfaF+FMxdXK/zi+l6R97hcxe+aUylaWkcnSHpBYRtaKmmmpPOKvMflqux1tNG3JL2hcM3M6dr8L1NsS0GpdcS2FJysEMUfLPI9tiEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADk3P8H5cV2y/9BEcsAAAAASUVORK5CYII=\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(380, 720)"
]
},
"execution_count": 226,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"λ_sfh2701 = [ 300, 400, 500, 600, 700, 800, 900, 1000, 1100]\n",
"S_sfh2701 = [0.00, 0.20, 0.57, 0.76, 0.90, 1.00, 0.85, 0.37, 0.00]\n",
"Λ_sfh2701 = np.poly1d(np.polyfit(λ_sfh2701, S_sfh2701, 5))\n",
"r = np.arange(380, 720)\n",
"fig, ax = plt.subplots(1, 1)\n",
"ax.plot(r, Λ_sfh2701(r))\n",
"ax.set_xlim([380, 720])"
]
},
{
"cell_type": "code",
"execution_count": 261,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Poly for run 45:\n",
" 2\n",
"2.282e-06 x - 0.001576 x + 0.4019\n",
"Poly for run 46:\n",
" 2\n",
"6.886e-07 x - 0.0005388 x + 0.1561\n",
"Poly for run 44:\n",
" 2\n",
"1.258e-06 x - 0.001514 x + 0.5252\n",
"[297, 228, 117] [339, 270, 210]\n"
]
},
{
"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\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\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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wX5fVsE6eaTfUu8EYDzsc+p89rN1AnFcDzvWK1B7HMAjUz9rOez//BXW7RjjxflDrdq1pP8RcT/sfV4BC1de4Xc5atoEbgQbHmhhavtsWLje2vWc5rAazEzNKq5A3TX87lrb/VNld8ZBTB8LUUREYq4L6j8TyG6ofcu1K6ytXBD2RcOGstgcVsO4Udq2VrDAXp//f0M1pNx9UNNTXERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERKQOJwIYC2ApgGoAjevY93cA/gVgOoBlqa+3AGhe2CKKiIiISD71goXAAcgeADsDuDz1FQC6APgGwJ2FLKCIiIiIFEZPZA+AXi4C8FX+iyMiIiIihdbQAPgGgMfzXxwRERERKbSGBMBrAPwCYPMMjzcC0AFAWy1atGjRokVLpJYOsOu4lLj6BsAbAcwC0LWOfToAoBYtWrRo0aIlkksHSMnridwD4P0AJgPomGW/tgA4Z84cLl26NLBl4MCBgf68KC56j/Qe6T3Se1Qsi96j4nuP5syZ4wTAtr6ShRS1xgBaADgUFgBbpda9qn2bAHgGwHcANs3htdsC4NKlSxmkIUOGBPrzokjvUXZ6j7LTe5Sd3qPs9B5lF/R7tHTpUgXAGOgPIAkLf9Vp3+8Pq+FbDmDf1L77px5bBRsHcFnq8WUZXlsBsEjpPcpO71F2eo+y03uUnd6j7BQAJWpCCYBlZWWB/rwo0nuUnd6j7PQeZaf3KDu9R9kF/R4pAIpfoQRAERERaTgFQPFLAVBERCRiFADFLwVAERGRiFEAFL8UAEVERCJGAVD8UgAUERGJGAVA8UsBUEREJGIUAMUvBUAREZGIUQAUvxQARUREIkYBUPxSABQREYkYBUDxSwFQREQkYhQAxS8FQBERkYhRABS/FABFREQiRgFQ/FIAFBERiRgFQPFLAVBERCRiFADFLwVAERGRiFEAFL8UAEVERCJGAVD8UgAUERGJGAVA8UsBUEREJGIUAMUvBUAREZGIUQAUvxQApehUVJCzZ5OzZpE//mhfZ8+27SIiogAo/ikAStFKJMiJE8nycgVCEZF0CoDilwKgFC0nACYS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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ids = (45, 46, 44) # Run IDs of runs for R, G and B channel\n",
"\n",
"# Approximate bands of interest for R, G and B channelsfor offset and stray light correction.\n",
"bands = [(260,410), (150,330), (100,260)] # [step]\n",
"\n",
"# The wavelengths are from a random RGB LED datasheet and are just preliminary starting values.\n",
"# https://www.sparkfun.com/datasheets/Components/YSL-R596CR3G4B5C-C10.pdf\n",
"λ_led = [623, 518, 466] # [nm] Assumed wavelengths of R, G and B spectral peaks.\n",
"λ_be = 400 # [nm] Approximate short-λ edge of blue band\n",
"y_edge_min = 0.5\n",
"\n",
"poly_degree = 2 # degree of polynomial for stray light and offset correction. Should be 1 or 2.\n",
"\n",
"max_stdev = 1.0 # [V] Nerved value that has been used for outlier removal in earlier tries\n",
"\n",
"remove_thresh = 0.05 # [V] standard deviation delta threshold for outlier removal\n",
"\n",
"# ---\n",
"data_rgb = []\n",
"for run_id, (l, r) in zip(ids, bands):\n",
" # Load this channel from the database\n",
" steps, values, stdev = load_run_zero_cal(run_id, max_stdev)\n",
" \n",
" # Remove outlier values whose standard deviation is much larger than that of their right and left neighbors\n",
" idxs = (np.abs(stdev[1:-1] - stdev[0:-2]) < remove_thresh) |\\\n",
" (np.abs(stdev[1:-1] - stdev[2:]) < remove_thresh)\n",
" idxs = np.hstack([np.array([True]), idxs, np.array([True])])\n",
" steps, values, stdev = steps[idxs], values[idxs], stdev[idxs]\n",
" \n",
" # Remove offset and stray light by fitting a second-order polynomial over the parts of the curve\n",
" # that are clearly *not* part of the primary peak.\n",
" idxs = (steps < l) | (steps > r)\n",
" poly = np.poly1d(np.polyfit(steps[idxs], values[idxs], poly_degree))\n",
" print('Poly for run {}:'.format(run_id))\n",
" print(poly)\n",
" values -= poly(steps)\n",
" \n",
" data_rgb.append((steps, values, stdev))\n",
"\n",
"\n",
"# Produce a first estimate for wavelength scaling. Use the short-wavelength edge of the blue band and the red peak\n",
"# for this, as both can be assumed to remain stable even after photodiode response compensation. Then apply photodiode\n",
"# response compensation and do another, second round of wavelength scaling estimation but this time using all three\n",
"# peaks and a proper least-squares fit.\n",
"peaks = [ x[np.argmax(y)] for x, y, σ2 in data_rgb ]\n",
"edgesl = [ x[np.argmax(y > y_edge_min)] for x, y, σ2 in data_rgb ]\n",
"print(edgesl, peaks)\n",
"\n",
"Λ_est = np.poly1d(np.polyfit([edgesl[2], peaks[0]], [λ_be, λ_led[0]], 1))\n",
"\n",
"data_tmp = [ (x, Λ_est(x), y, σ2) for x, y, σ2 in data_rgb ]\n",
"data_tmp = [ (x, λ, y/Λ_sfh2701(λ), σ2) for x, λ, y, σ2 in data_tmp ]\n",
"# Limit wavelength range\n",
"data_tmp = [ (x[λ > 380], λ[λ > 380], y[λ > 380], σ2[λ > 380]) for x, λ, y, σ2 in data_tmp ]\n",
"\n",
"# Calibrate wavelength axis using assumed peaks for r, g and b. Use least-squares polyfit for getting coefficients.\n",
"peaks = [ x[np.argmax(y)] for x, λ, y, σ2 in data_tmp ]\n",
"Λ = np.poly1d(np.polyfit(peaks, λ_led, 1))\n",
"\n",
"data_rgb = [ (Λ(x), y, σ2) for x, y, σ2 in data_rgb ]\n",
"data_rgb = [ (λ, y/Λ_sfh2701(λ), σ2) for λ, y, σ2 in data_rgb ]\n",
"\n",
"# Limit wavelength range to slightly-larger-than visible range. We're getting improbably large values in the\n",
"# utraviolet region that are probably caused by stray light.\n",
"data_rgb = [ (λ[λ > 380], y[λ > 380], σ2[λ > 380]) for λ, y, σ2 in data_rgb ]\n",
"\n",
"# Normalize amplitude data to brightest channel for ease of reading\n",
"max_val = max(np.max(y) for λ, y, σ2 in data_rgb)\n",
"data_rgb = [ (λ, y/max_val, σ2/max_val) for λ, y, σ2 in data_rgb ]\n",
"\n",
"plot_rgb_bar(data_rgb, ids, spline_s=0.005)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}