2917 lines
264 KiB
Text
2917 lines
264 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Flame Speed with Sensitivity Analysis"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"In this example we simulate a freely-propagating, adiabatic, 1-D flame and\n",
|
|
"* Calculate its laminar burning velocity\n",
|
|
"* Perform a sensitivity analysis of its kinetics\n",
|
|
"\n",
|
|
"The figure below illustrates the setup, in a flame-fixed co-ordinate system. The reactants enter with density $\\rho_{u}$, temperature $T_{u}$ and speed $S_{u}$. The products exit the flame at speed $S_{b}$, density $\\rho_{b}$ and temperature $T_{b}$."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<img src=\"images/flameSpeed.png\" alt=\"Freely Propagating Flame\" style=\"width: 300px;\"/>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Import Modules"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Running Cantera Version: 2.3.0a3\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from __future__ import print_function\n",
|
|
"from __future__ import division\n",
|
|
"\n",
|
|
"import cantera as ct\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"print(\"Running Cantera Version: \" + str(ct.__version__))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Define the reactant conditions, gas mixture and kinetic mechanism associated with the gas"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#Inlet Temperature in Kelvin and Inlet Pressure in Pascals\n",
|
|
"#In this case we are setting the inlet T and P to room temperature conditions\n",
|
|
"To = 300\n",
|
|
"Po = 101325\n",
|
|
"\n",
|
|
"#Define the gas-mixutre and kinetics\n",
|
|
"#In this case, we are choosing a GRI3.0 gas\n",
|
|
"gas = ct.Solution('gri30.cti')\n",
|
|
"\n",
|
|
"# Create a stoichiometric CH4/Air premixed mixture \n",
|
|
"gas.set_equivalence_ratio(1.0, 'CH4', {'O2':1.0, 'N2':3.76})\n",
|
|
"gas.TP = To, Po"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Define flame simulation conditions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Domain width in metres\n",
|
|
"width = 0.014\n",
|
|
"\n",
|
|
"# Create the flame object\n",
|
|
"flame = ct.FreeFlame(gas, width=width)\n",
|
|
"\n",
|
|
"# Define tolerances for the solver\n",
|
|
"flame.set_refine_criteria(ratio=3, slope=0.1, curve=0.1)\n",
|
|
"\n",
|
|
"# Define logging level\n",
|
|
"loglevel = 1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Solve"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"************ Solving on 8 point grid with energy equation enabled ************\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 2.136e-05 5.446\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 0.0003649 4.417\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 4.871e-05 5.791\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 2.601e-05 5.905\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 0.0009998 4.303\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [9] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"grid refinement disabled.\n",
|
|
"\n",
|
|
"******************** Solving with grid refinement enabled ********************\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [9] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 0 1 2 3 4 5 6 \n",
|
|
" to resolve C C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 0.0001709 5.099\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 0.0003649 4.857\n",
|
|
"Attempt Newton solution of steady-state problem... failure. \n",
|
|
"Take 10 timesteps 7.306e-05 5.011\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [16] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 3 4 5 6 7 8 9 10 \n",
|
|
" to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNN HCNO HCO HNCO HO2 N N2 N2O NCO NH NH2 NH3 NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [24] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 4 5 6 7 8 9 10 11 12 13 14 15 20 \n",
|
|
" to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH NH2 NH3 NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [37] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 \n",
|
|
" to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [52] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 \n",
|
|
" to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [70] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 67 \n",
|
|
" to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO H H2 H2O H2O2 HCCO HCCOH HCN HCO HNCO HO2 N2 NO NO2 O O2 OH T u \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [99] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"##############################################################################\n",
|
|
"Refining grid in flame.\n",
|
|
" New points inserted after grid points 28 29 30 31 32 33 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 97 \n",
|
|
" to resolve C C2H2 C2H3 C2H4 C2H5 C2H6 C3H8 CH CH2 CH2(S) CH2CO CH2OH CH3 CH3CHO CH3O HCCO HCO point 97 \n",
|
|
"##############################################################################\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"Attempt Newton solution of steady-state problem... success.\n",
|
|
"\n",
|
|
"Problem solved on [129] point grid(s).\n",
|
|
"\n",
|
|
"..............................................................................\n",
|
|
"no new points needed in flame\n",
|
|
"Flame Speed is: 37.99 cm/s\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"flame.solve(loglevel=loglevel, auto=True)\n",
|
|
"Su0 = flame.u[0]\n",
|
|
"print(\"Flame Speed is: {:.2f} cm/s\".format(Su0*100))\n",
|
|
"\n",
|
|
"#Note that the variable Su0 will also be used downsteam in the sensitivity analysis"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Plot figures\n",
|
|
"\n",
|
|
"Check and see if all has gone well. Plot temperature and species fractions to see"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Import plotting modules and define plotting preference\n",
|
|
"import matplotlib.pylab as plt\n",
|
|
"%matplotlib notebook\n",
|
|
"\n",
|
|
"plt.rcParams['axes.labelsize'] = 14\n",
|
|
"plt.rcParams['xtick.labelsize'] = 12\n",
|
|
"plt.rcParams['ytick.labelsize'] = 12\n",
|
|
"plt.rcParams['legend.fontsize'] = 10\n",
|
|
"plt.rcParams['figure.figsize'] = (8,6)\n",
|
|
"\n",
|
|
"# Get the best of both ggplot and seaborn\n",
|
|
"plt.style.use('ggplot')\n",
|
|
"plt.style.use('seaborn-deep')\n",
|
|
"\n",
|
|
"plt.rcParams['figure.autolayout'] = True"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Temperature Plot"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"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": [
|
|
"plt.figure()\n",
|
|
"\n",
|
|
"plt.plot(flame.grid*100, flame.T, '-o')\n",
|
|
"plt.xlabel('Distance (cm)')\n",
|
|
"plt.ylabel('Temperature (K)');"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Major species' plot"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAAXNSR0IArs4c6QAAQABJREFUeAHsnQl8FEX695/J5CR3Qi7uSxTDrYAiILoqXohyiS8eu66rq+7+UVHAXTxYD0AEXd0Lz5Vd5AYBAV1BFFAE5JJDBAIBQg4g5L4nk/d5OunJnCGTmUlmen7Fp+nq6urqqm9NMr88VU8VEQIIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgICJgM4Ua8HIuHHjZvDrH+Ejio/dRqPxyRUrVhyyrhLnS6ipqZmj0+mG8b3WfFzg+GJOe3nZsmWVan7ON5bjr/DRgY90Pqbz/VV8RgABEAABEAABEAABvycQ0NIEWKw9x3X4NR83FxcXt2ZB931AQMCXI0eObGWnbhF8/win/4oFXRQLxZtY/N3Bxyw175gxYwZx/D+c73k+R/G9F/i88N577+2v5sEZBEAABEAABEAABECgBQmwADzBxx/UKnBcz0fO2LFjJ6ppDZ057yQ+9qp5xo8f/xFfr1Cv5czXKzn9ffO0huKcd0RD9/3xHphY9jp4WPKQKzCxZAIeljzwGQEPWwK2Kfi5sWTiSR4tagGcOHGiDPl2YkveLrXJbNmr5vg+tgL2U9Mucb6FrX0mAcgWv758vdP8GU7bxUdjyyOuDwSgOUCOg4klEPCw5CFXYGLJBDwseeAzAh62BGxT8HNjycSTPFpUAJaVlYkAJBZ7+ZZNpjxutHLPKt3ikpWxDO/25eenm92QoWGL8vh+Ht+/ZHlSBgtFXVxcXLCczcpEFARAAARAAARAAASajYCn9Uhgs7XEzovCwsIKKysrxXIQY3U7lkVbhlWaxSWLv1cYzoOceP3ixYszzW4W8rMW5XH5sWwVLDTLYxEVEyvnUax+jz32WPD8+fOf5Awzufwii4x+fCFcmEejRLQ/YAIP214GE0sm4GHJQ67AxJIJeFjywGfEhkek6BH+nBBPi1McXVnffLl06dIvbXI2IaHFrVw8P+8E13seD/3+TerP13o+ZbHYeHr58uULJc06sGD7O9+/Wa/X/4rF3xnz+3zvIxEqXJ54AitB5gCyAMxlaL9T0xyd+dm2fK9B8enoWaSDAAiAAAiAAAiAgJsJtGMNc9bNZVKLWgClMdyof7Doepa9dzezshUx+CIfFRxslm2pE4cLOH/vwMDAoYsWLcqRMsxDdXX1fC5nM6vlURcuXFiXmJg4ivOP4PcMNc/XQFyx+mVnZ8twcAPZ/OtWZGQkFRXBIKr2OnioJOrPYFLPQmLgYckDTMDDloBtCn5u6pmwbqHk5GRJ8MiXb4sLQLbKvclWuwgWbRu5kZF8/MjDsbeuXbu2dMKECe1Z0B1mCLdyvu/4fB2Lsgmcp8JgMBxjQchREitmjSwLIxe8fuAOLu8Bjs5KSEhYxPnT+bmJS5Ys2SP3GxtE/EEAWtICD/CwJGB7hc+IJRPwsOQhV2BiyQQ8LHngM2LLw1MpLT4E7KmGNbVc/mEUIVmQlZWFX1RmEKOioqiw0OE0SrOc/hEFD9t+BhNLJuBhyUOuwMSSCXhY8sBnxJKHWABTUlIkMZrjbv8CblEvYMum4goEQAAEQAAEQAAEQKA5CLT4EHBzNNJd75C5CaLI/TGwww3mNPljx6PNIAACIAACmiQAAehEt4r48+dhUBmuQAABEAABEAABEPB9AhgC9v0+RAtAAARAAARAAARAwCkCEIBO4UJmEAABEAABEAABEPB9AhCAvt+HaAEIgAAIgAAIgAAIOEUAAtApXMgMAiAAAiAAAiAAAr5PAALQ9/sQLQABEAABEAABEAABpwjAC9gpXN6ZmXdOoU8//ZTy8vIoNjaWeJcUat++vbJ1W3h4OE2fPp1GjBhB9913H/GOKzRz5kzFm/n3v/893XLLLd7ZKNQKBEAABEAABEDAYwQgAN2EtrKy0iTAgoODnSrVlWerqqroiSeeoAceeIDuv/9+03vvuOMOeuedd6hLly40depURQSq9WrVqhWNHj0a4s9ECxEQAAEQAAEQ8C8CEIAu9rdY32bPfZd27T9OFBLLuxTn0YA+3Wjq5D8q1raGinflWbXcV199lVJTU2nYsGFqknK+6aabqGvXrvTzzz/TZZddRqr4k30nv//+e3rxxRct8uMCBEAABEAABEDAfwhAALrY1yL+fsqJpoR+D5pK+inrkCIKn39ukinNXsSVZ6W83NxcWrlyJf3www82xcvwroQdO3ZQdHQ0LVu2TNnbWPY4FgtgcnKyxTMiJGWoGAEEQAAEQAAEQED7BOAE4kIfy9CtWP6iUlItSpHrHXuPUUFRGZVVVNs95N6OfcfsPrtz/zGSsi8Vdu3aRX379iWZ52cdwsLClKSdO3fSQw89ROPGjaPx48crcwQHDhxokf3YsWN08uRJizRcgAAIgAAIgAAIaJcALIAu9K04XSjDvnbKKKqOpP97ayuFhvOwsJ1QXnyRJE+SnXs6HkrOz8+nxMREO3frk8ShIyYmpj6hLrZ7925q27atYuUTkThnzhxTnr1799KgQYNM1xKRdoiVEAEEQAAEQAAEQMA/CEAAutDP4nErc/7shcjAInrn6aGmuXfWecTC99Dv11on115X5NsVdtaZBw8erDh6lJSUmKyAMsSbmZlJV111FZ0+fZoiIyNN9+T5PXv20JNPPmkqSsSiWBEXLVpkSkMEBEAABEAABEBA2wQgAF3oX3GsEIcPmfNnPgxcyNeD+l5G0ZG1w7D2XhEWEqbksfeslKk6bdh7Vk2LiIig2bNn0+uvv07du3dX5vaJJW/kyJG0b98++vjjjxVHlO3btyuOIEuXLqX09HRlXmC3bt2UYs6ePUsXLlwgOR88eJB69uypFo8zCIAACIAACICARgnoNNquJjeLvWSj+OECsaSJx6x5iIqKUtbPM09TPXll3p4M3RJb75z1Am7Ks+Z1cDUucwAnTZqkCEmxBjoK9trvKK/W08HCtofBxJIJeFjykCswsWQCHpY88Bmx5KHT6SglJUUSozleaHnX9SsIQCuGzgpA9XEZ0pV5ezInrzHWO/U5ObvyrHk5no7jl1U9YbCoZ6HGwEQlUXsGD0secgUmlkzAw5IHPiOWPDwtADEEbMm7yVci+i7ltOGocFeedVQm0kEABEAABEAABEDAEQEsA+OIDNJBAARAAARAAARAQKMEIAA12rFoFgiAAAiAAAiAAAg4IgAB6IgM0kEABEAABEAABEBAowQgADXasWgWCIAACIAACIAACDgiAAHoiAzSQQAEQAAEQAAEQECjBCAANdqxaBYIgAAIgAAIgAAIOCIAAeiIDNJBAARAAARAAARAQKMEIAA12rFoFgiAAAiAAAiAAAg4IgAB6IgM0kEABEAABEAABEBAowQgADXasWgWCIAACIAACIAACDgigK3gHJHxoXSj0Uiffvop5eXlUWxsLBkMBmrfvj0VFxfTLbfcQgsWLFC2qQsLC6NDhw7RAw880ORt63wIC6oKAiAAAiAAAiDggAAEoAMwjU2eOuN5yik4b5M9KTqBZr800ybdPMGVZ9Vyqqqq6IknnlBE3f33368m0x133EF/+ctf6OGHH6ZXX32Vunbtqtzr2bMnTZo0iRYtWmTKiwgIgAAIgIB2CNTU1NCGNWvo4J69NGXGyz7XMF+vv68AhwB0sadE/MXc09GmlJxVp2zSrBNceVYtS8RdamoqDRs2TE1SzjfddBN98MEHdPfdd5vEn9xo164dHTlyhMrKykgsggggAAIgAAKWBHxVgKj1XvffhXRNgJ4uhgRbNszLr6T+q5cvp+Xvf+CT9fdyvDbVgwC0QeKeBCMZqdxQ0WBhkseVkJubSytXrqQffvjBpphbb72VPvzwQ3rnnXcs7snwcGFhoTJMfPToUUpLS6P9+/fTH/7wB4qIiLDIiwsQAAEQ8EYCqtBxt4VLLdcVASVl1PDv2RoeneFftGSsMihnuVbTlbPcCwqiUv59bErnvKa4UkbdtYGfVe6pZVjmM1ZW0Tdpx2lr+kkamphEk5NTSKfT0d7DB+nUs9O8sQst6iTMtmScoa1nTtOwtm1pcnyiUv/DJYUW+XDhXgIQgO7laSrtdFEWTdv+hunaXkTyxFFne7calbZr1y7q27cvhYeH2+TfsWMH9enTh4L4F4x52L59O3Xr1o0iIyMVC+F9991Her2eNm7cqFgLzfMiDgIgAAJNIaAKKW8QaDXV1VRTWUnGigqqqeBzpXqupJryCuXayOevtm2jjVu20ODIKJqcUCtA9p86Qec+/DeLMvvCyyTKVOHGok1En0VgIaYLDKw9guQcZIrrQ0LIGBBQd12fXpufrzl/QKswvh/JcfW+elbLDKK3P/qQ0jNO07TefSmA36eGoJRkSp70pHrpted57/6NTmadtam/11ZYIxWDAPRQR3aITKFZ105psPRHVz3e4P1L3QzgXxwxMTE22Xbv3q04hNi79/7779PkyZOVZ55++mnlvGnTJurevbtNOUgAARAAAWcIqMKvqRa0GnZoq2GhZiwrJ2O52VFaRl9u/pq+4t9Vg8MjLQXa+x/VijtV5ClnFndSDsfNBZkirFh06XhoNCC47szX87/bRplZmTS1l6WAkvzB7dqaia86AacIuXoBppRrEmiW6fwXtmLNsscxKipKGZGxd8+ZtOfnzlXm/M3jod9BOj0NiYtX3hkQHEwh7BDo7WHa7Fn19Q8IpCGxcQ6ZeXtbfKl+EIAe6q0ACqDQwJAGS5c8roTBgwcrQ7wlJSUmK2BWVhZlZmbSyJEj6dFHH7UoXryBZb6geAarQeYClpaW0oABA9QknEEABDROQBVq7rLQGdnKtp6no6z/dBFdGxhsGsI7kJNFhVu21Yo5FnVFLPDKCwtM1yLyasyEnljo1KALDaWAuuP9PT9S5vlzbCHqZ2HhEuEV0rkj6czEnI5FT4CIPPWsiL1g5VrHYsxeeOmpP9YLEDMBFch/YMeMuNneI16VJsO9t48aRbfddZfSjrl1QrAm1DfmAJrX/5uvvqK5PAdQhKyv1N+rPgxOVAYC0AlY9rKKt689hw9Jv1Rw5VkpW+bszZ49m15//XXFgidDwfIXpYg/Cc888wy99tpriujLz89Xln558MEHlXvqf19//TU98sgjlJ6eTp06dVKTcQYBENAgAVX4ObLQicXMyNY2I/9RaeQ/DKv5kLOxpPZcrZzlXhlVK3k4b2kJvb/7R8rhPyan9e1vIdCqiwqp9MCBOiHHQ5nRURSYkGASdorACwslk9jjuCLeRMDxCIcaXq7zarW2cIlAi77pV2q2Jp/NBYh4z/qagFIbbt2OOPYC9qUg9R81diwNv/lmRcj6Wv19ibXUtX6ygK/V3EP15V+QUVx0gVjS5JeleXCXud68zJaML1y4kFasWEEh/Mv28ccft/Ektq6b1tpv3T5nrsHClhaYWDJxhYcq1Fyx0ImYqy4qJiOLMENBIX3xv//RVzzXd3BEFA2pm+P2t+O/0NNDhysiTkSd4rjAzVAEGc8907cKp4DwVjwPrRXp684St7jmdF1YK/qKh2jXL13KlhsewqsbgnyPJ/HPXPCJCYwrTKQQlYsIWLEQHWYL1yyz8k0vcjGivscV/o2pgqs8GvMOX8sDJvU9JoI4JSVFEqI57naPGFgA61n7XWzixIkkBwIIgIB3EFCFhz0LndyT4dLqwiI+ChVxJxY25ZqFnmW8SMnLE6lIHxlBH7A3aBavGmA9hKpnZ7C40aMUQWcu6hwNlTZE6Y5x4+h2tt540oLWXBYu9T0yrIoAAlolAAGo1Z5Fu0AABHyCgDg+iIVuPa9/9sVnn9HgsHCa3LrWC3Vf2jE6O2uOIvKMRSzqxMOU572JcNNH8SHnunhQUqIprqYHRIQrQ6kzHAyh6nkaSaueqW7jpAondS6ap4bw1PdAoLmt61CQHxKAAPTDTkeTQQAEXCOgWuoaM0Qoy48YLuaRgbdqNFy8SNUS57OSJnGen/vhoQOUU85z6PpYzqHT83BrzC0314s9Fn0yPCsCyJmgCiZVmHl6jpv6Pgg0Z3oJeUGgeQlAADYvb7wNBEDAhwmowk8dos0NDmLrXQEZclnQscCrFXci9i5SNlv1Ks6fVxwoZA23wLhYPuJIL+fERAq9/PK6tFj6S3Q0fbFhA1k7OYiVL7x/X7cRU4WZKgQ9ZaFzW4VREAiAgMcIQAB6DC0KBgEQ8BUCqrCzZ9ETx4jKnHPKEO2X6zewEwWvQ8e7LYiY2nvoJzozbTpb6Ni7lYWdIu5iYymU19WM4vXjKtlaJ+kB7KEv+RsKzbmMhyoEYaFrqEdwDwS0TQACUNv9i9aBAAg0QEAVfopFj71KL+hqqOiHHVSVlU1V2TlUmZ1Nhgu59OEvP1MOL3syrY/lOnRBLPI6vTNPWSjY+jVN8WZUhRksdNY0cQ0CIOBuAhCA7iaK8kAABFqcgCrs7Fr02OmiksXdusWL6X887Do4MrreosfeskXbvqdgXnohtPtlFHn9UApOTqodov38c5sh2gDZ1ouHd90dVCEIC527yaI8EAABlQAEoEoCZxAAAZ8noAo/8zl6lRlnqeLMGao8nUEVp0+TXH9w8CdeuLjUZlmUkI4dqM2ztVskWsNoziFa63fjGgRAAATcTQAC0N1EUR4IgECzExDht371alr373/zVmQhpmVUZI5e5ty3eT/UdhTMR+SwIcreqH9JTKAv1q2zsehdquKqZQ5DtJcihfsgAALeTgAC0Nt7CPUDARAw7QBhPqRbw/vPVpw+Q+XHjtPb779HZzMybJZRkTl6HefOtthWTMXpikVPFYIYolVp4gwCIOBrBCAAfa3H7NT3K948e/r06TRixAi67777KID30Jw5cyYV8m4Bv//97+mWW26xeaqM9+1csGCBsj9wWFgYHTp0iB544AHl2iYzEkCghQhYD+leqDFS3vovqPx4GlWcOEE6XhQ5tFtXeurRx2jL6VM0j+f0DQqo34pMmaNntqesdTNUIQeLnjUZXIMACGidAASgBnr4pptuoqlTpyoiMDg4WGlRK15AdvTo0XbFnwjDxx57jF599VXq2rWrkr9nz540adIkWrRokQaIoAm+SkAVfAd276Ge/frSuo8/pmuCQmly3d61e38+RFWZmRTepxfFj7mHglKSTda9u7jRIx/+TZO2IlOFICx6vvrJQb1BAAScJQAB6CyxS+RXv8DMh6ou8YjpdlOfPXLkCF122WWkij8p5/vvv6cXX3zRVLZ5RMTiPffcYxJ/cq9du3Yk5YhlUCyCCCDQnATUz/66Bf+hawL0tO1EGh1ny7b1zhjBHdpT4iMPO6yaKuRg0XOICDdAAARAQCEAAeimD4LpC+y/C5UvsIshtZa4xhTvyrNS/o4dOyiadxJYtmyZMlcqKyuLxAKYnJxMR48epbS0NNq/fz/94Q9/oEy2nmzdupXeeecdi6oZeI9RsQzKGQEEPE1A/cyLpS+1xxX0+ScLaHCrCF6OhS16vGDyfvbQHXr3KJr35Zc0SFc/pNvwUsr1tVaFICx69UwQAwEQAAFzAhCA5jSaEFe/yNb99790DX9RTY6v3cT9UFE+Gdma1lCQZ8UTcf3iJXSNPsj07OGSwoYes7m3c+dOeuihh+i6665T7sncvoEDByrxdVy+zAvU6/UkcwULeNuqPn36UJDV2mXbt2+nbt26USRvLI8AAp4iYPp54c+o/LxsTTtGx//Hlr6+lnvgBvGWaaMeeYTu+u1vmzSk66n6o1wQAAEQ0AoBCEAXe3IOz6NL2/g1TemRSgFmWz1VnjpNp56Z0mDpHx45zGuR8QbwVl9+DT5k5+auXbtozpw5pjt79+6lQYMGKddPP127ptmmTZuoO29Pde7cOYqJiTHlVSPvv/8+TZ48Wb3EGQTcQkAVfMqcPv7D4/OPPqRrQ1qxpS+l1tJXVUHDJ9xL81auYkufnobExVtsmaZa8jCk65buQCEgAAIgYCIAAWhC0bTIc+x9u6F3b15P7L91X2CtlS+wYF5QtuO8NxosdEadBXAeWwAH6WWYq/bZBh+yunmaF7YVq1047zWqhj179tCTTz6pXirz+kpLS2nAgAEUy/uULlmyxHRPImIxTE1NteswYpERFyDQSAKq8FMWZKYA2nbS/py+IJ66cCdbqO+YMKFBS58qBDGk28gOQDYQAAEQuAQBCMBLALrUbfWLSbVQzOU5gGLJoNBgCmiEM8Ud48bR7WPHNvjl56gO+/bto4/ZS1KWfZEhXHEEWbp0KaWnpyvzAmVIV8LXX39Nj/BwmqRL2jPPPEOvvfaaIvry8/OVpV8efPBBR69BOgg0moBJ+IkzB/8cTG5dOyViX1EBDWPHo3kbv7KY06cWbP1zFLdnr3oLZxAAARAAAQ8QaOycag+82juL5C+wKK5ZgThSyJeZeWjM5u7qF2BzegGb19E6vnDhQlqxYgWFhITQ448/TsOGDbPO0ujrxrS/0YX5eEawsOxA+dx/w3NM/zlvHsUUldDUXn0spkS8x/NaZy74xLSgs1gG5Q+lw/yH0ixO12LAZ8S2V8HEkgl4WPKQKzCpZyJ/GKfwvuQcojnunHNAfTEOYxCAVmhcFYBWxWnqEj+Y9d0JFrUs1D94PmdL9LUBQbT7XA4N6tePtp46SdeEhpvm9KkCUCWoPteUP5TUMrz9jM+IbQ+BiSUT8LDkIVdgUs/E0wIQQ8D1rBEDARBoJAERcLL37qK//pVujIqlZ1PaKXNfD4YE0X3v/pUm8P0Na9aQOiWihi195kEd8sWcPnMqiIMACIBA8xGAAGw+1ngTCPg8AVX4vTtzNiWxyJvR/2qLod6AuuWFVIGnzo3FnD6f73o0AARAQGMEIAA11qFoDgh4goAq/D6Z9xYFskf52JS2FMjOR7P27aFBScl0Y0obi+Vb1DqoQhCWPpUIziAAAiDgHQQgAL2jH1ALEPBKAqrwW/zOu6QvLqZoFn3Trh5ksvoNY+E341Qa7c09R4MCAqmGh4ARQAAEQAAEvJ8ABKD39xFqCALNTkAVfu/Onk3J1TX0Mg/1isfY1uwsG6tfm4REev2TfytewNnffd/sdcULQQAEQAAEnCcAAeg8MzwBApokoIq+tctX0NljRynCUE1j27SzGeodmpxSb/XjpVzEwUOGekfxepY33HKLJtmgUSAAAiCgNQIQgFrrUbQHBJwkIMJv3Wef0fw33qDAsnKKYkeOZN47ehrvHKNub2gx1MuiL4WtfjPZ6ieevnDwcBI4soMACICAFxCAAHSiE+SLUtYo8segZ0FgMBj8semabLN8lj9ftYr+9uabVFNUTKFswYsLDaUXr7nukkO9quiDg4cmPxpoFAiAgJ8QgAB0oqOLioqcyK2trCJ8/bn9WulNo9FIr73wAq1ftoKqjNV0ZWwctW+dQDns2TuEh3bFq1fOMszraKhXPHrh1auVTwTaAQIg4K8EAvy14Wg3CPgTARF+r/z5z3TdFT1oM1v+QvUB1Csujm5s01YRfwm8b/V3OVl0HS/pItbBmSwEv87KVIZ6/7Z0CbWeOIHiOnf2J2RoKwiAAAhomgAsgJruXjTO3wmo8/tenz6djJVVFBEcRJ0jo2hqn/4s+LJpG3v1isVPwvmyMjqcn0fHykrp7o6daVNxAfXs3Ftx8IDVz98/SWg/CICA1gjAAqi1HkV7QMCMwJxXXqHXpk6jbq3C6dErriRdDVFaYQG98OMOxdI3rU8/ReCtyTpLQzt0pOxWoXTNrbdSwv33Uc+Bg2jKjJfNSkMUBEAABEBAKwRgAdRKT6IdIGBFQKx/X//vK2odEkLZPMdv5amTNKHbZYoIXJR2jBYcO0JfZpymG9u2o8suv5wSxo6hnnv2mkQf5vlZAcUlCIAACGiIAASghjoTTQEBcwJzXn2VUqqNlBQXT4fyLtIV0dG0JO04BbNHtwjB5adOkSGhNX2Wm0vX9+urOHZA9JkTRBwEQAAEtEsAAlC7fYuW+TEBsf6dPJ5GF8tKKLDGSKM7daFfCvIphMWfCMEPfzlCnbp2pU/Xr/NjSmg6CIAACPgvAcwB9N++R8s1TECsfxXHjtM9HbvwXD+iozzvL7eiXBGCu/PyIP403PdoGgiAAAg0hgAsgI2hhDwg4GMExAKYV16uLO1i7eUbGxsLy5+P9SeqCwIgAALuJgALoLuJojwQ8CICIgRl6FfW+BMhuP/iBRp0441eVENUBQRAAARAoCUIQAC2BHW8EwQ8SEBEX3raCTIa67fuU4WgkYeDsbSLB+GjaBAAARDwEQIQgD7SUagmCDSWgPn8P1J29q1/Uq/HrI96GoiBAAiAgP8SwLeB//Y9Wq5RAo7m/xl4O7iI6CiNthrNAgEQAAEQcIYALIDO0EJeEPAhAuqwL+b/+VCnoaogAAIg0EwEIACbCTReAwItRUAVgtWY/9dSXYD3ggAIgIDXEYAA9LouQYVAoOkEROxZO4CopenUCM4gAAIgAAJ+TwAC0O8/AgCgJQLiAFJ9Ml1ZABoOIFrqWbQFBEAABNxLAALQvTxRGgi0KIFn//xn6jR8GK3KOEXXJiXR5dExXB8dwQGkRbsFLwcBEAABryMAAeh1XYIKgUDTCbz52muUtmkzzb36GgoM0PMC0NlYALrpOPEkCIAACGiWAASgZrsWDfNHAjIHML+ygmbv36M0f1qffqTT6QgLQPvjpwFtBgEQAAHHBCAAHbPBHRDwOQLPTZ9OV912K2WXl9HhvFyaVScEo4KDfa4tqDAIgAAIgIDnCEAAeo4tSgaBZicgQ8Cnvt1Kbw26jq6MjSc2CNKR/DwqrKxs9rrghSAAAiAAAt5LAALQe/sGNQMBpwmIE0jH64fSMzu+o+oaIz3ftz9dERNL2ALOaZR4AARAAAQ0TQACUNPdi8b5GwGxAKZ/u4XmsQVQrwvgIeC9CoL4iAh/Q4H2ggAIgAAINEAAArABOLgFAr5EQBxAUnv1ovyAAHrxx508/FtD4gQioUKPH3Vf6kvUFQRAAAQ8TSDQ0y9A+SAAAs1DQBaBTtv4Nc3skcor/xFtzc5SLIADExPpss6dm6cSeAsIgAAIgIBPEPAKAThu3LgZTOsRPqL42G00Gp9csWLFIXsEx48f/wpbNu7ge6l87Fi2bNkw83xc1vV8vZmP4rp0+S7M43wd6q5xAgFNEpD5f7OqquiZdetpVLv2NDylLQ1NTqEnvt9KN95zjybbjEaBAAiAAAg0jUCLC0AWbM9x1X/Nx83FxcVpkZGRLwUEBHw5cuTI7mvXri2106zjnPYCH7fy0cfOfUmqYcEXLWcH95EMApojoHoAz716kLIA9Mx9e5RFoMMDg2jKjJc11140CARAAARAoOkEvGFi0ONc/Tks2A5v2LChgq17Iu6CQkJC7Josli5d+gnnXcf5LjTUbBaW3tC2hqqIeyDgVgImD+BdPygewOr8vwJeGBoBBEAABEAABMwJtKhImjhxogz5duIh311qpVjcVXN8H1sBa2evqzecP59gEZjNx1c8bGwxTOx8UXgCBLyfgGoBnDfgGgsP4OjgEO+vPGoIAiAAAiDQrARaVACWlZWJACQWe/lWrc5jUajcs0q/5KXBYPiZM/VNTU3tHBoa2pUthV/w8eWYMWN6X/JhZAABHyZgsgDu3G5hASw2GHy4Vag6CIAACICAJwi06BzAsLAw3qCgkljsxVg1LpZFYYZVWqMuV61adY4znmNLouQv4WMuWwHv4PLGc/wnSUQAAS0SMFkAB16rzAGUNQCHsBNIZHCQFpuLNoEACIAACLhAoEUF4MKFCwtZnKWzOBvAbdgh7eBrPZ/6sShcINduCmwErBFvYLuBh4hH8PtGyM3HHnsseP78+cTOKHbz+mtiMO8lGxXVJKOsJpF5I49X3niD1qxYQXNem0nXxMUrawBuy8mmIvYMbo6+80YmLfnhAw9b+mBiyQQ8LHnIFZjYMmFd8vrYsWOV/TxZL33JvhBf2uZyPqVFBaBUV6fT/YPF2bM8RLuZG3aCk17ko4LDKrlvHYYPHx7YqVOnwJKSEjFr6G677TZlgpM4kEhehnRLYGDg0cWLF59iMRnKZT/GyYP1er14G9sNdTAVoJxfVM6TRUVFykK6dh/ww0QREIWFhX7YcvtN9kYe/NklnlZBxmoDHSvMp++zzrIFsA3Fh0c0S995IxP7vdc8qeBhyxlMLJmAhyUPuQKTeiasjyiCd3Fio9SfOO72L+AWF4Asvt5kC1wEi7+N3Gwxu/3I1rhbZQmYCRMmtK+urj7MDb+V830nWBISEt5n8fcQR5UlXhhOWV1cLIcSBvIz77P4i+N4GT97gM+3LlmyZI/cRAABrRJQF4Ke1rMPBfAvDhGEshj0xXJ7qylplQLaBQIgAAIg0BgCDodFG/OwFvPUWQALsrKyYAE062D8VWYGg6PeyEME34Y1a2jVrDdocEobuj4xSSzs9GeeC/jp99ssG+CBK29k4oFmNrpI8LBFBSaWTMDDkodcgUk9E/n9nZKSIgnRHNeeBbC+qYiBAAi4SqDGaCQ5jhUW0PeZGcoQsKtl4nkQAAEQAAHtEWjxIWDtIUWLQKBlCMgQ8PGvNtHz/a6yGAKu0Lfoak8tAwNvBQEQAAEQaJAAvhkaxIObIOAbBGT4N7VXL8rnn+gXdu2gbzPPKhUfxkPB3Tt39o1GoJYgAAIgAALNRgAWwGZDjReBgOcIqA4gM3v0JJnYK84fshfwQJ4HWBOD5Xs8Rx4lgwAIgIBvEoAF0Df7DbUGAQsCz02fTqOeeYrezDhF32Rl0lBeAPr5vv3pszOnKQ4WQAtWuAABEAABECCCBRCfAhDQEAHFAaSkgLbnZCkOINFhYTRlxssaaiGaAgIgAAIg4A4CEIDuoIgyQKCFCahDwFN6pMIBpIX7Aq8HARAAAV8ggCFgX+gl1BEELkFAHQKec/I4beHt3ySIA0h4kGyYgwACIAACIAAClgRgAbTkgSsQ8EkCsmDo7aNG0YBKA/1t1Spa+eMOGtW2HRnKlR0SfbJNqDQIgAAIgIDnCMAC6Dm2KBkEmo2ALAOzfvVqmv6vf1HXikqad9VA0usCCGsANlsX4EUgAAIg4FMEYAH0qe5CZUHAPgHrOYCSS4aANxXm238AqSAAAiAAAn5NABZAv+5+NF4rBNQ5gLOPHKLN2ZmmfawxBKyVHkY7QAAEQMC9BGABdC9PlAYCLUpAloE5zvsAb+e1AIckt2nRuuDlIAACIAAC3ksAAtB7+wY1A4FGE1CHgKdd2ctiGZiL5aWNLgMZQQAEQAAE/IcAhoD9p6/RUg0TMA0BH9hP3/A2cBJkDmBcaCsNtxpNAwEQAAEQaCoBWACbSg7PgYAXEjDyEPAxHgL+PusshoC9sH9QJRAAARDwFgIQgN7SE6gHCLhAQB0Cfr5PP4shYCwD4wJUPAoCIAACGiaAIWANdy6a5j8EZAj4rkn/R7P27aGtueeVhssQcPfOnf0HAloKAiAAAiDQaAIQgI1GhYwg4L0EZCeQETffTNclJdPnF87T9N07aVPmWarx3iqjZiAAAiAAAi1IAEPALQgfrwYBdxCQXUA2rFlDn//7E7qGheCs7j2UYmecSqPUzr3d8QqUAQIgAAIgoDECEIAa61A0x/8IqPP/pvRIVeb/qQTaJCTSlBkvq5c4gwAIgAAIgICJAIaATSgQAQHfJKAuATM38wxtMdsF5GxGhm82CLUGARAAARDwOAEIQI8jxgtAwLMEZP7f7aNG0RuvvUZHy8vp6R930ObMDMI2cJ7ljtJBAARAwJcJQAD6cu+h7iDABGQO4PrVq+m5adPo8tAwmnfVQNLrAghLwODjAQIgAAIg4IgA5gA6IoN0EPARAvbmAMoSMJsK832kBagmCIAACIBAcxOABbC5ieN9IOBmAuocwDnpabQ5K1OxCMorMATsZtAoDgRAAAQ0RAAWQA11Jpri3wRqZBu4gnzazo4gQ5Lb+DcMtB4EQAAEQKBBAhCADeLBTRDwfgLWQ8AyJ3BrdhbmAHp/16GGIAACINBiBDAE3GLo8WIQcA8B0xDw8V9oy7kcpVCZAxgeFOSeF6AUEAABEAABzRGABVBzXYoG+RsBdRmY/hcu0j+3bqGVvAzMqLbtMAfQ3z4IaC8IgAAIOEEAFkAnYCErCHgjAXUZmJf++x/qVlyKZWC8sZNQJxAAARDwMgKwAHpZh6A6IOAsAes5gPK8DAEfiYpwtijkBwEQAAEQ8BMCsAD6SUejmdoloM4BnH34IG09f860DIx2W4yWgQAIgAAIuEoAFkBXCeJ5EGhhAuocwF77D9Lu+Bia+803dLVRR2cv5rZwzfB6EAABEAABbyUAC6C39gzqBQJOEqipqCTSB7EFkJT1AEsMVU6WgOwgAAIgAAL+QgAWQH/pabRTswTECWTDmjX02TebaGibdvRs6yTSJSTTeyWFmm0zGgYCIAACIOAaAQhA1/jhaRBocQKqE8jUXn0pQKdr8fqgAiAAAiAAAt5PAEPA3t9HqCEINEhAnEDuenoSzdq3h7bmnocTSIO0cBMEQAAEQEAIQADicwACPk5AnEBuve02ui4pmT5nL+Dpu3fSpsyzxFMBEUAABEAABEDALgEMAdvFgkQQ8A0C6vy/dQsW0CAWgrMuv1Kp+IxTaZTaubdvNAK1BAEQAAEQaHYCEIDNjhwvBAH3EVDn/03pkWox/69NQiJNmfGy+16EkkAABEAABDRFAEPAmupONMbfCKiLQM/NPktbsjJN8//OZmT4Gwq0FwRAAARAwAkCEIBOwEJWEPA2Auoi0HPfeouOlBTR0z/uoM2ZGWQor/C2qqI+IAACIAACXkQAAtCLOgNVAQFnCcgcwPWrV9PkSZOoR0QUzbtqIOl1AVShx4+2syyRHwRAAAT8iQDmAPpTb6OtmiNgbw7gsJQ2dCQqQnNtRYNAAARAAATcRwBmAvexREkg0OwE1DmAb55Jpy3Z9XMAm70ieCEIgAAIgIBPEYAF0Ke6C5UFAUsC6hzAIYlJ9PknC2hubg5dbdTR2Yu5lhlxBQIgAAIgAAJmBGABNIOBKAj4KoGaikrSBQayFzDRsYJ8KjFU+WpTUG8QAAEQAIFmIAALYDNAxitAwFME1IWg1/zzXzS4VQQ9y5ZAXUIyvVdS6KlXolwQAAEQAAENEIAA1EAnogn+S8CeE4j/0kDLQQAEQAAEGksAQ8CNJYV8IOCFBFQnkDlpR2lLTjYWgvbCPkKVQAAEQMAbCcAC6I29gjqBQCMJqE4gV5eU0d/Xr6OVvBD0qLbtsBB0I/khGwiAAAj4KwFYAP2159FuTRBQF4J+4cMPqGtZBRaC1kSvohEgAAIg4HkCsAB6njHeAAIeI2BvDiAWgvYYbhQMAiAAApohAAugZroSDfFHAuocwDeOHKat53JMcwD9kQXaDAIgAAIg0HgCLlkA77333muMRmPmsmXLTt93332tDQbDHJ6TZAgMDJzy6aef5jW+GsgJAiDQFALqHMC+aem0vaaa5v6wHQtBNwUkngEBEAABPyPgkgWQxd/8gICAUGFWXV09k09deE5SJxaC7/oZRzQXBFqUgLGiggIC9VgIukV7AS8HARAAAd8h4JIFkJvZccmSJUeluSz8Rur1+v4sBEs4/ovvIEBNQcB3CYgTyIY1a+iz9Z/T0OQUerY1FoL23d5EzUEABECg+Qi4KgCNw4cPD0xKSrqMrYEFixcvzuSq68aNGxfefE3Am0DAfwmoTiBTU3tTgE7nvyDQchAAARAAAacIuDQEzG/6ITEx8a8s/l7juUjr5c0s/jrxCTvRCwwEEPAwAdUJZNZP+2jrhfMmJ5CzGRkefjOKBwEQAAEQ8GUCLglAHu59nIeg4hlAcVVV1asCgq8HsRhc4stQUHcQ8BUCqhPI81cNoNMd29HTvBD05swMLATtKx2IeoIACIBACxFwaQh45cqVp7jeE8zrvnz58sV8LQcCCICAhwnIHMD1q1fTZ7t20LAOHem+qwbSNt4SrkLv0t92Hq41igcBEAABEGhpAi4JQKn86NGjO4rzB38RRZo3hoXgAvNrxEEABNxPQOYAHt+4iab17W+aA4iFoN3PGSWCAAiAgNYIuCQAx48f/zsWfv9gKEU8FFViBqeG4xCAZkAQBQFPEJA5gOu6d6dZb/2VhnboQEPiWpMMCyOAAAiAAAiAQEMEXBKALP6m85fNxKUcGnoJ7oEACHiGgIi9ETfdRFd+s41+HvEreukf/6Dh4ZFUExnhmReiVBAAARAAAU0QcHWiUAzEnyY+B2iEDxOQRaC3nj9H6xd+SjfHxNG35aUU17mzD7cIVQcBEAABEPA0AZcEIFsf1o8dO3aopyuJ8kEABGwJqA4gTz/+BOkMBpocn0hD4xOobUIiTZnxsu0DSAEBEAABEACBOgIuDQHz+n9ZLAI/47mAy/jLSBaBNgXeH/gvpgtEQAAE3E5AXQR6So9UkwOI21+CAkEABEAABDRJwCUByOJvAFM5zOIvlc9yqEGcQCAAVRo4g4AHCIgDyIbevWnuBx/QoMBgGpqUAgcQD3BGkSAAAiCgRQIuCUC28mH4V4ufCrTJJwiIA8jto0bRsLbtafW/5tPc3By62qijsxexEY9PdCAqCQIgAAItSMAlAajWm7d/i+N4Bz5Osyi8qKbjDAIg4HkCxsoK0gUF8i48RMcK8qnEUOX5l+INIAACIAACPk3AJQF41113RYaEhHzEBMbUUahhMbgyODj4twsXLiz0aTKoPAh4OQFxAtmwZg2tZevftWHh9GxiEukSkum9EvzoeXnXoXogAAIg0OIEXBKALP5mcwuS2RlkIO8LfJx3BOkWEBAwt7KychanP9HirUMFQEDDBOAEouHORdNAAARAwMMEXBKAXLc7+Ri4YsWK7Lp6/shbw01gIbiTryEA66DgBAKeIKA6gcz5+z/p2ohIGioWQOwC4gnUKBMEQAAENEfAVQHYiolYzPmLiorKKykpCdMcKTQIBLyMgOoEMqi6hjbu2klzjx+DE4iX9RGqAwIgAALeSsClhaC5UT/yl9DLfFY3H9UVFxe/wNe7+UAAARBoBgI1lZUUoNfDCaQZWOMVIAACIKAVAi5ZAHm+39M8/28TO378moGk89GRjwBOu4nPCCAAAh4koDqBrH7/PbqOt4B7NgFOIB7EjaJBAARAQFMEXBKAS5Ys+XnixIlXsNPHKP4yaseC8ExQUNAaeABr6jOCxngpATiBeGnHoFogAAIg4AMEXBKA0r46sfcfH2grqggCmiKgOoG88fZf6bq41jSE9wCWeYFnMzI01U40BgRAAARAwP0EnBaAPNw7jRd7lmVeiOMvOqoS9gJ2RAbpIOAeAqoTSJ8Tp+iDnw/Rih930Ki27chQXuGeF6AUEAABEAABzRJwWgAyiRv4UAQgn292QAZ7ATsAg2QQcBcBdQ7gZ6tW8j7ASXT/VQNpW042Vehd9e1yVw1RDgiAAAiAgLcScFoAsmVvhNoYjmMvYBUGziDQzATUOYBTr+xJAXXr/w1LaUNHoiKauSZ4HQiAAAiAgK8RcMlUMH78+HfsNZiHht+2l440EAAB9xGQOYCjnnmKZh/8ibaeP8fLwIjhHQEEQAAEQAAELk3AJQHIXzi/dvCKBx2kIxkEQMBNBNQ5gH8eOoyib7mJ5ubm0DfncujsGTiBuAkxigEBEAABzRJweghYSLCFr0MdEd2ECRPa8z7A6kLQknw5H5iFXgcIJxDwNAFZCFoXGIiFoD0NGuWDAAiAgIYINEkAcvvT+VDGm1j8SVwNIgSr+ZDdQBBAAAQ8SEB1Aln1/Xc07PRperY1FoL2IG4UDQIgAAKaItAkAcgLPl/Gu32I2NvH8T4qEU4zhoaGnvvPf/5ToqbhDAIg4BkC4gRyfOPXNK1PP5MTiGfehFJBAARAAAS0RqBJApB3AEkTEC+//HIUH0atQUF7QMAXCIgTyPoeV9KsN+fS0A4daAgvBi3zAhFAAARAAARA4FIEXHICOXz48Bs8H3CI+UvGjh07lNPeME9DHARAwP0EROzdOuIWer5vf4q7dxy9dOIofZ2dWTs3w/2vQ4kgAAIgAAIaIuCSAOQ5SP+Ph3z3mvPgLyW5vt88DXEQAAHPEKiuqKSt2Vm0YfFiujkmjr4tL6W4zp098zKUCgIgAAIgoBkCLglAptCK5/uVmtNITU2Va6xEaw4FcRBwMwFxAFm/ejU99cgjJIO+k+OTaGh8ArXl/YCnzHjZzW9DcSAAAiAAAloj4KoAPMnDvcPMoRw6dEh2B0k3T0McBEDAvQTEAWT1vLdpcnJbGsq7f2Dun3v5ojQQAAEQ0DqBJjmBqFDYCvEOf/Es5nl/r7M38FF2Au7O957n9BfVPDiDAAi4n4A4gGzo3ZvmfvgRDdIH8l7AKRCB7seMEkEABEBAswRcEoDLly//mLeDC2E6k1j0dWYxmM7xVzj9A2eIsRVxBud/hI8oPnazkHxyxYoVh+yVwe97hd91B99L5WMH70dsYYGUZ7i8sXx6hY8OfKTzMZ3zreIzAghogoBY/G4fNYqu73YZrZrzprILyNW8MtPZi7maaB8aAQIgAAIg4FkCLglAqdrSpUv/xSc5mhRYrD3HD/6aj5uLi4vTIiMjX2Jr4pcjR47svnbtWov5hXUvOM5nWWj6Vj5MaxDW3aMxY8YM4vh/+AvyPhaKa/kYxfGF99577xBevmaPmg9nENACAewCooVeRBtAAARAoPkJuCwA3VDlx7mMOWyhOyxlsSAUcffbkJCQe/i8UNLMAwvOT+Sah52vFiuIddDr9Y+x6FvP+T6ru7eSy/yC0+Q9v7POj2sQ8EUC/HmmDWvW0Nr33qNrQ1rRs4nYBcQX+xF1BgEQAIGWIuCSAGRhFcci7C3+MrqFG5Bo3ggWdHrza3vxiRMnRlVWVnbiId9d6n1+rprLlR1G+nGajQBU8zk6c136cp2WmN/nNCl/jHka4iDgywTECSSNdwGZ0iMVu4D4ckei7iAAAiDQQgRc8gJmYTWPjx5c9z/yIcO19/KxlwXY03y+ZCgrK5M5f8RiL98qcx6LQuWeVXpjLqP4WYvyuPw8frCp5TXmncgDAs1KQJxARj3zFM1JT6MtvA4g/xw26/vxMhAAARAAAd8m4JIFkIXezdz8a9lqd5qtdh/weTnPtfuJBZg4gbxzKTRhYWGFbAEkzh9jlTeWRVuGVVpjLwv5WYvyuPxYrmuhowLYsWQE5xkh9x977LHg+fPnE89FdJTdL9ODg4MpKgoaWu18b+Ax4YEHaHhkNK374gt6+1Q69TcYKTM/t8X6yRuYqP3jDWfwsO0FMLFkAh6WPOQKTGyZsC55nae9Vcod1jdf8hS3L21zOZ/ikgDk10WI+Kt7beWjjz4a9N577x1lMWjjnGGvagsXLizkvOncoAF8f4fk4WsZOu7HgmyBXDsbWOjtY2uIlGcKnDaAj72mBKtIHUwFKD8rKufJoqIiWFXMOIn4Kyx0qKHNcvpH1Ft4lPPn1MhzYQ3V1XS0oICKK6tarJ+8hYm3fALBw7YnwMSSCXhY8pArMKlnwrqFIiIiiI1Sf+K427+AXRWAZ9jrtgsv2XKCq3w8Pz//LhZwFzhuz3u3vlVmMW7UP1h0PcvlbGYhKOW8yEcFh1Vm2UzR4cOHB3bq1CmwpKQkiBN1t912myxDQxs2bKiQc3V19XwuZzOr5VEXLlxYl5iYOIrLH8HvkQWqEUBAEwT4M604gaz5299pcFQ0PZsAJxBNdCwaAQIgAALNRMAlAchfQvPZ61acNU5w/C0+i/OFjuPTG1t/tr69yUOwESzaNvIzMu76I1v/bpUlYCZMmNCeBd1hFm+3cr7vpMyEhIT3Wfw9xFFl0hOr47K6uOJ0wmJ0B5f3AKfN4ryLuC7p/PxELAHDRBA0QwBOIJrpSjQEBEAABFqEgO06Ki5Ug61/HVi8RTpaxNmFopvtURaMMgRckJWFifXm0GGWN6fR8sMU/DlVLICr33mXrouJoyG8BzD/oUPvlRTSzAXKSkmWFW6GK3xGLCGDhyUPuQITSybgYckDnxFLHvI7PSUlRRKjOe49Q8As9oK5Utnh4eFt/v3vf5dLDc3mA8olAgiAgIcIyC8G2Qmkf8552nbhHM3du5ewE4iHYKNYEAABENAggSYvA8NiTzxSCnk41q1WRG9hLN7Jvhik3jk5OYT62+89Z/k4yu9suv3auJ5aU1FJusBAdlgiOlaQTyWGKtcLRQkgAAIgAAKaJ+DqHMC5TGgOe/8+zd6/mvrm+c2Tf6bUy9rS1Ml/FLdrr/8g8NA7zZ77Lu3azzvlhcSyG00eDejTDfWv6zln+TjK/9zTT9Kct/5Ouw+cIGNQtImzmm7Ov3/PzvTbh+6j+Ph4pRZ5eXkUG8t9w0GNy5IHTQnqEPBny5fSUHYAebY1nECawhHPgAAIgIC/EnDJesfDwCcZXDs+qvnI5sPIhxLYQthFjfvSWZ0DOP5P6ygnfT/1Tiqg55+b5PVNmDnnr/RTTjRFpaSa6lqYdcht9ff0XBVP19/Z8h3lrzjzDYW0H27D2Ty9psZIJ35cTSV5GRQR3ZpKLpygoLAIikvqzJ+pA0o8PrkLGctyqWf3NjR92mQKDQ019VtjIm+88ordnUAwB7Ax9Jonj6d/ZpqnFe59C5hY8gQPSx5yBSb1TLx2DmBdFV+tr6r2YiKmvt3+EV29M4MCg4KUSfbWrbSroO0msnu09cNybSdRZyfRTrba0viGoaqKvt35C3W85jcWb1Dq/8NHNHhPJgUGy6o5tsHuu+y8LCyshHjnFosCeBpao4N8kK2DmlLF9d+66xdqP+g3Flmk/lt++JiG/ZTNi4Par7/FA3xh7z0Nlb91x8d0w6EcCuL+lSB1cpQ/IrE7ndiznvoOrBfZ8oySvrc+XcRfdHI36jrgHkrbtYpSet9Frdv3MsXj26UqArGsqJK+O5BLv7rrAbrtxmvpT1OearS1WXYC2dC7N81+cy4NSUqhIa0TlLafzciQKiGAAAiAAAiAQIMEXBoCZivfhw2WroGbNTycuvfnDAqPqh3GM29STe1KNOZJDuON3anLXj6H71EWwiEqLsilmmCLzU9M9agJiqWte09RRFScKU2N1D2uXipnu+/ijHqeZ1ZtMJjy2nu2rgBTHjViL68MYaqhpDCXqgPt1786KIb+tz2N+dvWX31ePZuXqabJubiB8g383nVbjynlq1WS+ki6dagsK6KwmLbWyaSkR9emG6urqKzovCL+HMVFFEYl1RrIJW9oXDdau2kP/bBjIi1f9HGjrIGqE0jqjt30SXEhrfj+OxrVth0ZypXlMG3qiAQQAAEQAAEQMCfQJAHI6+y9wuvyvaAWNHr06I4rV648pV5r6RyuK6Kn7uuvbE/jre0Sh4TdmxfZrV54QBFNeeAql+vvSbO81H/CFllC0jZEcP3//JsBLtVfKX/bUtvCOUXKf+HhgRblK/m/s80fHBZJZQWZNuWYp4sYDI1sreSxF1dFoWQQK2GXq0cp1sDA4DAqCYymEaMfoVtvGHDJuZumOYDffk1D27SjiVcNpG052VSh9/75qjYAkQACIAACINDsBJr0bcFfPhaT4ngx6L3NXvNmeKHMoRNHiqZO1G+GKiqvkPpJPaW+5gH1r6XhLB9H+YvPHaW2rcNsOJunixgsL5LNcHhPSztxEYUh4bGKlVCGhdXh4p43Po0pCYoAAEAASURBVErdBoymToMeoL2Z4YpDT23t7f8vC0Gvnvc2Te3VVxn+FUelYSltqHvnzvYfQCoIgAAIgAAImBFokgDk52WqlHmwvja/55PxCz8tUhwoxAvYF4LUUxxWzu39hM4fXkPn9y5A/c06zlk+jvIvXfiBwvXC/v9acDal//Qp1VQW0oVT+yhAH0RhkQl04cwBU7ww9xSV5GcpVkLVGihzAmVY+PC3H9OZQ5vo1KFvafX6TVReriyvadaK+qjMAbzr6Uk0a98e2pp7HvtW16NBDARAAARAoBEEmiTc2Pu3kOf/yY4ZSuDri3x96Ula6gNefGbrprITyKlTp0yOAV5cXZuqyfAl78lMMTExbrVcenII2LwRnqq/+g5ny3eUX7x2T58+bcNZ8l+8eJE+/ORT+pGXiiGem5mTfpCCQtkLOLmTEhdnmuDIJLriuomU8fM3/NeUTpkTWJhzQrEMyhBy8cWzlBhppNXLFjh0DKnhOZkn//AUHb7+Olry8cc0PDySjkVG0CzsBKJ2d4uem+tnpkUb6eTLwcQSGHhY8pArMKln4mkv4KYKwBKu2J0sltTnP+PrUWbXsivI1/XN8J2YKgCxFZxln+GH0nke5uJRnlaFuawxOG7iI6RPuY7Opf1IOh6+FUuhzAmUYWGxDMpQccH5EzSgfRn9eeozli+vuzKUlNDCiQ/STr2OBukDaWNRAfUcOIimzHjZbn5PJ+IzYkkYPCx5yBWYWDIBD0se+IxY8vC0AGySEwhXMYyF0ibzqlpdi4un3vw+4iDgbwRkLmFiYqKp2eZxsezNnPM2fbYvk8KTrlAsf+IQIkPBimcwWwFlLuHagzk0edITFp7B/LOm7AO87pMFNIhLn5yQrCwB83NoSIuJP1MjEQEBEAABEPAJAqoFzycq2xyVhAXQPmX8pWrJxV08CgsL6dbRD1NY68uUoWCxAsa1uUKxAIoTycWMQ5Qaf4H+8tLzpgp44yLQUjl3MTE11Mcj4GHbgWBiyQQ8LHnIFZjUM/FWC2B9DREDARBoMgH5ZXf7TYOVdQD1QbW7gWQf2644iYgFUIaG91/IV/Z2FouiBHUR6Lk8728QG9qHJqfYXQC7yZXCgyAAAiAAApon0NQhYAUMO3/o2WI2hVXqw5yQyPP+onmNwBEc78DrBL6veXpoIAi4gYDsACKLQGdezKOU7oNNi0jLPEDxGs75eZMyf1AdQpa/Cm8fNYpu6NmLlr3wIs3NzaGrjTo6ezHXDbVBESAAAiAAAv5AoKnLwChsWPy9xF9G4/niJT6UrR34+jinP+4P8NBGEHAHAVnD79NP5rO3r47Ml4QRD+Fzabt4J5M8izmA6jtr2ONYx84fsoPJsYJ8KjFUqbdwBgEQAAEQAIEGCbgkAFnsPcCLQN/Flr9P+S1GeVOPHj1O8qmTxBFAAAQaR0CWholL7GhaGPrK639D7XoMJzl3GzSO3nzr76aC+A8sWr96NT373HNUU1xMz7ZOot9ddjkWgTYRQgQEQAAEQOBSBFwaAubCIxcvXpxh/pLMzEzx/q3fNNb8JuIgAAJ2CcTGxlKYvpzO5xco92UeoOwYIotGR8S04XmARaZ5gLILSNrGr2lKj1QK4OFgBBAAARAAARBwloBLFkB+2YGxHMxfmpeXN4qvNbk1nHk7EQcBdxIQB49e3dtQRUmesii0OH9IPCKuHRWzCDx14riywLS8U5xARj3zFL15+iRtyc7CLiDu7AiUBQIgAAJ+QsAlCyAvaDuN5y9tZGeQu5lXKJ8/4PNYTrvZT/ihmSDgNgJTnvkjffHtwyQ7gshyMJ3732laDubCmYP03kf/pRf/9Kzi8StOINdFx9D6FStpbnYmnEDc1gsoCARAAAT8g4BLAnDFihU7WPRdzXOSnuD5gN/wEVBdXX0Tzwn80T/woZUg4D4CMg8wpnU7Ki08pxRqvRzMrnMXTcPAkqGmsoqdQPRwAnFfF6AkEAABEPAbAi4JQKHEYu8XPk3yG2JoKAh4iIDMAwyhYsorLXCwHEyashxMQkKCshPImr//kwZHRNKziUmk491A3isp9FDNUCwIgAAIgIDWCDgtANnid2NjILAw9Mm9gBvTNuQBAU8QkHmAA/teTmu/2mlaDsZ8Wzh1ORg4gXiCPsoEARAAAf8i4LQAZDwbG4FI1gTEXsCNAIUsIGBO4NGH76dvdp8xLQdjPg8wl7eFk+VgZrw4nTb07k1z3v07XcvzAIcmJGInEHOIiIMACIAACFySgNMCkC17rnoOX7JSyAAC/kogPj6eokKreTkY+/MAZVu4qqoqZSeQqwuK6Vv2Dp576BAN0vFcwNDareL8lR3aDQIgAAIg0HgCEHONZ4WcIOBxAubLwYgncM8bH6VuA0YrZ7k+fz5XmQeoVISF4M2Dr6O/LV1CrSdOoLjOnT1eP7wABEAABEBAGwSctgBaNVvHe//+kb2Af8/pHfg4zcd8thK+w2dlazg+I4AACDhBQF0OpnX7XmSsrjItBSPXGQe+oFatWiml1VRVUkBwkGlZGFkaBgEEQAAEQAAEGkPAJQHIa0A/w+JPjjn8suN8dOOlYJ5jURi0dOnSNxtTAeQBARCwJCDLwcQmdKC0XavI3AlEFoeOiudlYkpLKSIigoyyDAw7jiCAAAiAAAiAgLMEXBKALPZ+x4s+j1yyZMke9cVjxoz5ltOW8DUEoAoFZxBwgoAsB1N84QS16X0XdR1wj8kKWJh7inIOrqeYmBiltJrKStIFBSs7gWxYs4YO7tlLU2a87MSbkBUEQEALBKbOeJ5yCs7bNCUpOoFmvzTTJt3bEszrrw/UU7WhWqmir9Tf23g2tj4uCUB+SXKPHj32mb+sV69e+w8dOpRonoY4CICAcwSCwyLsLgVTXl5BvAOPUpixooK++mE7bXxjNl0ToKeLIbAGOkcZuUFAGwRE/MXc09GmMTmrTtmkeWOCr9ffG5k2pk6uCsDjhw8fvodftEJ9GYs/mYiUpl7jDAIg4BwB3k+b4pO7mJaCESugGi6c2kevzZpH1/ZLpc82rKehKSk0Ob52GZjDWAhaxYQzCDhFwNwCZf5gS1mgqmuMZDAalKOq7mwwVlNVTW2aEje7X1xVSrXjAua1JyqsLKbNGT9YJnrhldTTXv29sKqaqpKrAvAlnv+3kheH/pypiOjryscdnDZWU5TQGBBoRgIyBGwsy+X5f5UWQ8DBYZHUumNf+mblVMrZ/D+a2rM3Beh0zVgzvAoEWoaApwWaIwvU2ZUn6HzZRTMhVl0bNwkxA1WxMFPEGqdZiDUzgWaoqXuO06pFyNXdq9YZqdJQZVZ+rcAzWvlQBugCKCggkAJ1fLC1X4nLdV28uKrEbseUV1dSelGG3XvelCj1RGh+Ai4JQPb2XXfvvfcOYcH3Wz5SeU7gGT4PW758+c7mbwreCALaICBLwfTs3oa+O5hn1xEkvvu1dOMNV9Csf/2LhrZtT0PiW2MhaG10vc+2oqUEWtaqk1RQUUQVLCAqjJVUKee6o5I96C3T6675vpLPyB72dXnPFGexBcp2CDWjOJtm7f6XSWgF1omwIBZeEq8XYhzntTiV+2bprYLCFNFWm8/qGc4fHRFFleWVdWWZ3VeEnlq+nv/Qa3jFtr2tvrP72UkMi6Pf9PB+e8y3YV/YrT8SPUugSQKQHT26qNUyGAy5HH9DvZaz3F+xYsUJ8zTEQQAEGk9g+rTJNPjGe6jzwHGKFVB98sKZA5T10xoaPeElGrRrDx0c0J/mrl2LhaBVQDi3CAFHFjR7c9BkeLPcUEHl1XwYyvlcqZzLlOu6dLN4GefJLuU5bnYE2umiLHpp59uKEAsOCKYQvRxBFKycg/kcRCGm9GCKCYlU8tTnrX3mQJj9YdKOkW1p7pA/eYxpVFQUFRZiD2+PAUbBDRJokgBkL99jZqXKGJT5mn/qNbaCM4OEKAg4Q4B/xigyNp7srQV44ejXVCOOIAYD3TbyTrrzgftJvIDj2AsYAQTsEXCnhc7IAk5EWalylFFpVRmVGOzPQcspvUDz9n1oEnyqdU7qqON/oYEhFKqvPcIkHhjK18F88DkwmKKDI5U8EUHh9ppFHSJTWKD9mfSXsJDZfdgsUYSjveArEyxkrqI9sS3pvhDM62/tBewL9ffVOjZJAHJjS/lI5yHff/GQ7/rq6upat0RfpYB6g4CXERBHkLikznaHgOOSO1H+hQtKjWUdQP45VLaGw0LQXtaJXlQdRxa6zJUnFetaaZUIOhZz6sGiTgReiVwr8dpruS/iT4KehzDDA8OoVVAoOxuUUFs77ZUh0BvbXmsSeq2j48lQXkVhLPSCA2oXMbfzmE3Sh0G1i59b3wigAJfFn3WZvnjtC0u9NMTVvP6wijZEyr33mioAU7gaD7D4e5zPz7K14r2goKCPFi1alOPe6qE0EPBPAuIIkpN+gFLq1gJUKahDwFG8G4j8FYaFoFUyvn12h4VOHBHEG7SIxVgROwWIY4AcRZWldL78ot0hVJn79ta+j6iVCDkWZaYzCzeJx4ZEs8CrvxfOcRFvcs9cwB1ZuNtuB0Sy5a5vwpWme1GRPORZ431DnuYWKFNlOeIrFjTzOiMOAo0l0CQByM4fxfyCf8rBHsBDWAD+nucCHuP4er1e/8zixYszG1sB5AMBELBPIIjXApQhYAnqlnBxba4gZQiYF4Fm0x+bYfS0fvVqLAJtH6HPpDqy0GWxhU6GUWuFXL2wE1GnpJlEXokyp06GLFsFtqLI4HAS8RXBlrMIjosTgr3QMbINzR481d4tr0rztEAzt0B5VcNRGRDwIAH7vxWceCGLwW0TJ078qaqq6iRbBP/Ei9TO58chAJ1giKwgYE1AXQuwhudbnfhxtcWWcDVVVZR37jxtOZdNO++dgEWgreF54NodFjq1Wvx7UhFr+RWFlF9ZxF6sfObD3jpop9lC9+be91nMRbCQY2GniDoWdyzqElvF8zULPE5TBV8rvrY3H25t8HL19RZnmYfnjgCB5g6KKAMEmpeASwKQl4AZIMPAlZWVo7nam3ku0u28B/Dm5m0C3gYC2iMgQ8BUkWezGLSIh/Ttn9IzTz5Jd8Qn0OTkFGUOIBaB9uxnwJGFznrivfSPzJMTQXey7Cxl5mfXCjwWeorg4/QCjoszhAyhxoREKYeB15CzFzqwhW7Odc/bu+VVabCgeVV3oDIg0CgCTRKA48eP/x3/onuMrX1JfP6AhV8qWwLPNuqNyAQCIHBJArIWYP+enWnd5n0Wy8Cc/m4Btcn5iV7ojUWgLwmxgQzusujlVRTQf3/5rE7csTWvslBZ5FfmycWFxVBkYLgi8OJ4Ll2XqPYULYKPPVtF+In3qzjwSNgZ+o1ytv4vwEcsdNb1xjUIgID3E2iSAGTRJ8O8h/iX1384rhcxOHas5WKTvBj0i97ffNQQBLyXwG8fuo+27K39u0qdA9jumvso70RXem7vChrVJomGJtVaAL23Fd5ZM0cWvWzeO1VE3YWyPMotz1N2gZBzZsk5u04URrb4JYbFU/eYzizsoljg1Yo7WVbEm7wZYaHzzs8hagUCLUmgSQKQK7yFD9Z9Ndeqf8FaNcJ8XUCrW7gEARBoDIH4+HheZqNCWQqmtCCHxCmkqqyYWkUn0eDL+5A+qJLm5p7DItAM0xmLHv/eIlmM2F44XXSW/rLzXcX7tXVYLMWHxvJac23YYhdpLzvfj6FbOgy1e8+ZRE/PoXOmLsgLAiDgHwSaJAB5uHe4f+BBK0Gg5QjIMDBVFVFpcQXpeGHoQHYCMFSUUmnheQqJr6Ff8V7AE5/6IxaB5i5yZNHLWJFGhy4eUzxpxZtWjnNlF0iWP4mnzjad2yY8SZlzJ3usmocFgR+ZX7o9Dgud25GiQBAAgUsQaJIAvESZuA0CIOAGAuxcRdkXCqgNrwVoviNIYe4pKs9gI3xQ7UK6sgC01haBdtaiZ6iptkv8bEkOrTmxkZJatVaOy2I6KeeMyCN286t7tlrfhIXOmgiuQQAEfJ0ABKCv9yDqr1kC586dI6M+jOLbpdrsCBKgN1CFbAen0eDIope9Kp3n4+VQRnG2Mi/vrHKuvW5Npi3KTVRknbvnr5b16i2Ds84VsNBZ8sMVCICA7xOAAPT9PkQLNEygVVSSaSmYzv3vpMqyIgoOi6SUU5voyMlT1JHns8k+wAd5H+ApM172ORKOLH2nM07bdbo4XZRJf93/b2oTnkhtw5Opf0Iq3dn5RjoT+bPdtjta5w4WPbu4kAgCIOBHBCAA/aiz0VTfIpCYmEjVpeeoQle7D2r2se0UGtmayosusPCJoG/T02nNuPF0rT6QLobY38zeW1rckNDr/UdbJ4qf5/1it+oyR2/mtVMooG75FDUTLHoqCZxBAARAoHEEIAAbxwm5QKDZCYgTyNCBV9KGb/ZSSvfBJBbAitJCKj57kLYeWE03JSXQ8NZJPrEQtKMh3V/eOmaXq73dLCSjzNGzFn+SDoueUEAAARAAgcYTgABsPCvkBIFmJzB18v/RF9/+hgqyj5NYAKvzztBl1QX0cr+r7AqhZq+g1QsdWfpOORjSlSVZ7AW9ztIL114e8zTM0TOngTgIgAAIXJoABOClGSEHCLQYgbKyMgqgGopO7mZhAXx532c0PCmRbkhpY9pNosUqafZiR5a+w3Mde92aPW6K6qpqKJ8XZbYOYulDAAEQAAEQcJ0ABKDrDFECCHiMQHh4OK8BGGiyAKpzAKemXkXL047Sj4FZPAcwmGpCm3cOoD1Ln16vp5Nn0qkfdbThIUO3zoQu3brSv+d94MwjyAsCIAACIOAEAed+KztRMLKCAAi4TqCkpIRqjAaTBVD1Ag5PX0NxUXH0/D/m0e4ffqA49gL2dDAXfWmnTtBVT91g88qyuYds0iQhQBdgNx2WPrtYkAgCIAACHicAAehxxHgBCDSdgCMLoL5NK6okHcl9Ty4E7Uj06RfU7lFs3bJgtkbaC46E3rVXXUOYv2ePGNJAAARAwLMEIAA9yxelg4BLBMwtgF0H3EPG6iplLcCw7P9RuaGaSktLKSIiwqV3NPSw+Zw+R6LP/Hmd+YVZHEO6ZjAQBQEQAAEvIAAB6AWdgCqAgCMCYuEL0AfZ7AYSGFlBReUlFBISQutXr3brQtA2Vj87c/oc1deRpQ/OG46IIR0EQAAEWoYABGDLcMdbQaBRBMQCGN26nc1uIGE5X5Auph09fMdIurttW7cuBO2s1c+8IbD0mdNAHARAAAS8lwAEoPf2DWoGAhQbG0th+nI6n1+g0Mg6+j0FVJXSW0Un6ZbkNnRjz94tshC0PlhP+xZ8r9Sp+mIFde3YhfSBemVBZnQbCIAACICA9xOAAPT+PkIN/ZiA7AbSq3sb2rB5j7IbSGBFISXnH6Vpfd27EHRjhn3tiT7pmqR2CYojR1RUFBUWFvpxb6HpIAACIOA7BCAAfaevUFM/JTDlmT/ybiAPU+v2vSg25XLKOxRPs/Z9RYNS2tGNvBi0zmpf3KZgcjTseynR15R34RkQAAEQAIGWJwAB2PJ9gBqAQIMEZDeQ2IQOlLZrFZUVnacUWf+vb3/6ddpFWn5mL93XpT0vBB3SYBkN3RTrn7Kunx1nj14TBpkelZ05sDizCQciIAACIODTBCAAfbr7UHl/ICDzAIsvnKA2ve9StoOLLMoiQ+5WSki9iTL3r6bYe8dR3E8HmoxCrH/6uHoB6dDqh23YmswYD4IACICAtxGAAPS2HkF9QMAOgaDQcNN2cJfHxFJZuIEKLh6noNAIunXkSLprzBg7TzWcpM77E+ufuQCE1a9hbrgLAiAAAlogYH9/Ji20DG0AAY0QyMvLI0NV7XZwV17/G2rXqS8ZQyKU7eEMBgPl5+c3qaXqvD9z8dekgvAQCIAACICAzxGABdDnugwV9jcCshi0obrGZAFsFRtDxSGllF98jCoLL9AHb/+V/vT6ay5hMR/2VQuS5V0G966fA6im4wwCIAACIOD7BCAAfb8P0QKNE7DeDq5DUTrtPvg5hZ49QvcmRdMvJ086TcDa8cN82FctTJw+sE+vSgNnEAABENAWAQhAbfUnWqNBAvXbwfWk80e+pbzDG+j2hFh6t08PZQmY40XODwGbO35YW//UhZ2xfZsGP0xoEgiAAAjUEYAAxEcBBLycgFgAo+Lb0k8rX6LLqvPp5X6Wi0AbjdUutcDa+oflXlzCiYdBAARAwCcIQAD6RDehkv5MwLQMzICxVFpeSNN5+PeW1jF0fXKKYgHU65v2Y2xt+RPGmPfnz580tB0EQMCfCDTtm8OfCKGtIOAFBILDIiihQ2+lJtfFhVP6yb301M8n6c6YYKKoiEbX0Hzpl6ueusHmOcz7s0GCBBAAARDQJAEsA6PJbkWjtERAloGJT+5ialIwVVOPTj0peeRLtLw6nFqltDHdu1QES79cihDugwAIgIB/EIAF0D/6Ga30YQIyBEwVeaYWBFVXUomxhmqMBorgRaGff/UV072GIuaev9bDv3D8aIgc7oEACICA9ghAAGqvT9EijREIDg6mAX260f7MA3Th7HEqCc6nCwFhdOCn3RRlzKW3X32NpvxlxiVbbe75C8ePS+JCBhAAARDQNAEMAWu6e9E4rRCYOvmPVJmxhaISO1NCQifKMugoseIijY8IpwPfb9dKM9EOEAABEACBZiIAAdhMoPEaEHCFgGz5VhMYQbqKYlq8/XPqUXKK3u7RmX6VkkwlpeVUWVl5yeJPZ5y+ZB5kAAEQAAEQ8A8CGAL2j35GK32cgDiC5J45QV0MP9ELvXtTgE5X36KAQGU/4MTExPo0O7GqagPJcPK+Bd9b3C3JKqAbB1xvkYYLEAABEAABbROAANR2/6J1GiEgjiDx7btQUURXenX/ChqSlEI3JCcp6wASLwQdExPTqJZaz/2Th3a/vRlbvjWKHjKBAAiAgHYIQABqpy/REg0TUB1BNmw9TM9c2ZveybhIS3b9SGPbtaHwViGKZa+h5osHcHF+kY31T57RVdU09CjugQAIgAAIaJAABKAGOxVN0i6BpC4DKbL6KF057E46G9KaVmxfRLHhpy7ZYPEAju7Smvo+ONgmryz+jAACIAACIOBfBOAE4l/9jdb6KAFx8vjxpzSK79CHgmoMVKULVIZ/Ow3+f1QR2aZRTiA+2nRUGwRAAARAwAMEYAH0AFQUCQLuJiBOIBTCC0JzCOIFoCt0erpwdBtV5Byj4Pj4Bp1A1AWgg5Nb2QwBY+9fd/cUygMBEAAB3yAAAegb/YRa+jkBdTcQHYu/77LO0rFDb9Kd8ZH0v2IDGSL0DTqBqAtA23MAwd6/fv7BQvNBAAT8lgCGgP2269FwXyIQFBREiWEGOrvqzyQLwMy7siv9ir2AywpziKqKKDDQ8d9yWP/Pl3oadQUBEACB5iHg+Fujed6Pt4AACDSCwJxXXyXj0SP0du9UizUAW0UnU0D74TR77rv0/HOT7JaE9f/sYkEiCIAACPg1AQhAv+5+NN5XCDw3fTqtvfJKenr2XBrdJoWGJacoTiCVhecpMSWVdu79RHEEkeVizIPM/yuvKKerJtxgnqzEsf6fDRIkgAAIgIDfEMAQsN90NRrqywR0vPPHoCFDqGPPYXQwv5Ce/GE7bc7MIF11ldIsHTuI5Ofn2zRR5v/pAvFjbgMGCSAAAiDg5wRgAfTzDwCa7xsEampqaMe2bZRxcAuNYgvg45d3p2052VTEazgnSBMq8u06gsj8P0NFlY33rzyCBaCFAgIIgAAI+CcBCED/7He02scIyBzAtI1f05v9+5vmAA5LaUPrimuoMOsQDejTze5uIDL/L6pdHBaA9rH+RnVBAARAwNMEIAA9TRjlg4AbCMgcwA29e9Oc+e/RoKAQup7FnwwLl+aepuAz39Bzsz6w+5aKygqKDLZd/68oM59uGjjc7jNIBAEQAAEQ0D4BCEDt9zFaqAECIvZuHzWKCnfupW+++4GWntpO4zp2oGB9EIWwF/Cct/5u1wtYho7trf/33ewNNPulmRoggyaAAAiAAAg0hQAEYFOo4RkQaGYCIuTWrlxJKzf+j25n699zl3etnwPowAtYPIArisvtzv8zlNU6jzRzM/A6EAABEAABLyEAAeglHYFqgEBDBGQO4PGvNtHMfpZzANeX1D6legEnJiaaihEP4NCYVnbn/8kSMAggAAIgAAL+S8ArBOC4ceNmcBc8wkcUH7uNRuOTK1asOGSvW+6+++4Y3hXh73zvDj6MbBlZx8Njf1i2bFmB5OeyrueTfLsVyzUH2Tghj+93UK7wHwj4IAF1HcDpb8ylm9kCODw52bQOoNIcB17A8AD2wc5GlUEABECgGQi0uABkwfYct/PXfNxcXFycFhkZ+VJAQMCXI0eO7L527dpSawYs/hZyGp+COldVVbH20y3h60/4uNssbw0Lvmi+rjFLQxQEfJaAzAG8a8wYCtm+iz6WOYAnjtP4zp2JKkvp8Dfv021Dr7TxApYlYOAB7LNdjoqDAAiAgEcJtLgA5NY9zsccFmyHpaUsCF/g029DQkLu4bOIPVPge2LFu40FYu9PP/00T26MGTNmMl/vGz16dLuVK1dmqJk5bwCXWa1e4wwCvkxA5gBuWLOGlny/jW5JSqbrk1KVOYDFAUGU1GUgN001eNe3ElvA1bNADARAAARAwJJAiwrAiRMnRlVWVnbiId9darVEtLF428eirh+nWQhAvu7LR/mSJUsOqvl5qPgnzl/J+eWeSQBy/ASnh/D5AFtPXlm6dOkW9RmcQcDXCChzADduohd797VYB1DmAMZ06EO7rLaCwxZwvtbDqC8IgAAINC+BFhWAZWVlUXq9nli8We9hlceiUOYDWgQWclFsCVHm+lncIMqXe5IWGBh4xGAw9E1NTT2UlpYWxu/4PSd/yZbCQSIWrZ7DJQj4BAGZA7i4Y0ea8Y9/0fCUtjQ8KcliDqC1E4g4gFRXV9v1AMYOID7R5agkCIAACHiUQIsKwLCwsEK2ABKLvRirVsayKDS35im3WfwVckTm9lmHmLp7tGjRohy+mcOWRMnD9hGay5bAO7i88Ry3KwDHjx8/guswQh547LHHgufPn088F1EuEeoIBAcHU1SUjSb3Wz4tweM3jz5KKVt20D/PFtAy3gtY1gFU9wIOqCqkDh14XUDuJwn6QL3D+X9FazM80pctwcSbP4DgYds7YGLJBDwsecgVmNgyYV3y+tixYyvlDmuZL3lE80vbXM6ntKgAXLhwYSGLs3Ru0ACu+g6pPl/r+dSPBdkCubYK+/g65N577+2pDgNzvA/nDeJD7jkKrA9rxBvYbqiDqQDlfKJyniwqKiKO283vj4ki/goLRX8jCIHm5iGfRZkDuOLQPp4DyF7Ag65R5gAWGo0UlLGfrurVhcrLy5VD6ncy/ST/qSQ/Srah2lDtkb5sbia2LfOuFPCw7Q8wsWQCHv+/vfOAr6pI+/+TcpOb3kMCocq6YGgWBBQUK6ILqKiArK6udf+4r65iX1bY/a+AwKpr2ZX1te2CqPQiqCAoiFJFXFCR3pJAIKTn9vc3JzmX24K5mHDbb/gMU86cOc985+TkyZRn3HmoFJmcZKI2/yUnJwsGpZ5CvNl/AQdUAVTNRKNexS+3sZiiXQlFcDey/gRvgpunrrs6jOrth4L4IZS9qTfccMNoo9EYheneqSizUN8AAi35akwD75g1a9Y+lDWi7vtw/SJMNavdxnQkEJIE9LOAn+p5rtsawDnFpVK8Y5U48i9QI+nqr0OtfdwAEpLdTKFJgARI4IwRqP9tccYe5/0gjL5NhRL4Fn5xLcfVo/D98IvsGmUCZuTIkW2hxFViivZi/U6YfrkN5Uuh5O2C8vcj8oswZPwb/TrCC7H26TPcp7TlfSg7BOE1GDHc7FKGURIIKQJqDeCwhx+SSd98LSuLDztHp2MwMtjl8gfl2yPpMnnaS25tUkfA9br9IjdvjDfyCDg3SkyQAAmQQGQSaHRaNDJxwHBg/RRweVFRkfOXbKSycG03h+VdaQRmmkJNA+/+3e/l/m+3S2x1ubYGcPGhYskZ9XdNuCPYCfzeG3/T1tCcd+WFktoxy11opCr2HJPNy9d75TdHBt8Rd4rk4c5DpcjEnQl5uPPgO+LOAwNYkp+frzLTEA+/KWD35jJFAiTgi4BS/j6cM1fmb9ksI/Ly5bJuXU+eBdxwg+tO4NgEg88j4NY+t8xX9cwjARIgARKIMAIBXwMYYbzZXBI4LQL6WcBP9PJ9FrBWqctxcEph9OUay/dVlnkkQAIkQALhS4AKYPj2LVsWRgTUGsDF7TvKpH+8Kn3zWstlOA1ETQ/YbVZ4i1Qd2SG9e3bWpn+VEWhTVZ1PG4DWWksYUWFTSIAESIAETpcAFcDTJcf7SOAMElDK3lUDL5Hji5fIktIj8sn+vXJ56wIx1ZyQrR+9KG2yE+TRSa9rEm3YtkmM6Yk+p4A3vbDyDErNR5EACZAACQQrgYDvAg5WMJSLBIKFgLb+b8ECefiB30uUxSKTzu4qz/buK/NKK8SeVyi9rh0r8W0HypTnX9FEViZg6EiABEiABEjgVAQ4AngqOrxGAkFAQLcB+FjXQqcNQCWW0W6V3AF3ahKm5hfK+obzgE1mk8BEks8pYB4DFwQdShFIgARIIAgIcAQwCDqBIpDAqQjoNgCnHtgrKw8fcponirZbpK7quLYGUN2v7wK2wSB0RqccryorDpVJv/P7euUzgwRIgARIIPIIcAQw8vqcLQ5RAg6bXX6sKZcvS4qkPzaC2K0WOfjdKqmrLJWElBxJiamQ9HQcq40dwMoItKdbPXEJjUB7QmGaBEiABCKUABXACO14Njt0CHhOAas1gauLi6Qq2iCde9+oNaR03zfiKFmj7QI215h9Tv+qfDoSIAESIAESUAQ4Bcz3gASCnIA+BTxl9075vKRYk/aS/NaSHGtwTgFnt+8pjthkMZvN0tjxPo3lB3nzKR4JkAAJkEALEOAIYAtAZZUk0JwElAmYa4cNk94mizw/e7bM+nKN3Nyho4i5xn0KODFdHn3mcTEkxvk0AfPF5KXNKRbrIgESIAESCGECVABDuPMoemQQUFO+SxculAWvvSYXp2fIXX0v1o6Bc5sCPvCtFG1dKCeqasRS63sKmEagI+N9YStJgARIoCkEqAA2hRLLkEAACXiuAVSiqCng+UVHtR3A5tpKyWzdRUp3fCoWW4XEGg0+pU1JSvaZz0wSIAESIIHII0AFMPL6nC0OMQJqDeDSHj1k8vMvSN+MTBnYKl87Bg5DfbL9szfFmJKt7QR2wEi0NbpOUgsyfU4Bn5i3L8RaTnFJgARIgARaigAVwJYiy3pJoJkJKDMwO8thBqbosGYGJioqWrpdfq/zKaX7tsjeXW9ITFyM1y7gStgAvLLPZc6yjJAACZAACUQ2ASqAkd3/bH0IENCngJ8o7K6dBKKbganEJv4sm0XUFHBcQopkt+8le3Y2YgNw0oe0ARgCfU0RSYAESOBMEaACeKZI8zkkcJoEnFPAz02R/q0LpH9WtrYGcM6Bg25TwMoYtKXa5DX6px5rRj4dCZAACZAACegEqADqJBiSQJAS0M3AdFmxSmZievcPqz6TYW0KRP3wuk0BYycwDgnx6WgD0CcWZpIACZBAxBKgAhixXc+GhwoBNeX74YIFMn/9OrmkXXsZdf6FmhkYzyngY0VfiSEp3ucGENoADJXeppwkQAIkcGYIUAE8M5z5FBI4bQJqDeDO5SvkiV7naWsAVUXKDMzckjK3KWBL9D6x0gbgaXPmjSRAAiQQSQSoAEZSb7OtIUlArQFc1LGTjIMZmMsLCuTy/DaaGZgYg9FtCnjTp4+IMS3R5wjgphdWhmTbKTQJkAAJkEDLEKAC2DJcWSsJNAsB/RSQZbM/kEEFbcWBWidu2Sy9c3IlNi7B7RkOsYrVZPO5CSTKou6kIwESIAESIIF6AlQA+SaQQBAT0E3APNa10G369961a8TY6SJJczEDo5qR0SlHbGabW4toA9ANBxMkQAIkQAIgQAWQrwEJBDEB3QTM1H+9Lr1jDDIQa//UruDU2FipMKa7rQF0OOzSfWQfr9aspg1ALybMIAESIIFIJ0AFMNLfALY/JAg47Hb5sRqngMDOS/+81prMabmd5KzeNzjlX7vwPp/Tv8o2IB0JkAAJkAAJuBKgAuhKg3ESCDICnlPA+ikg5VabdG7fU+wuU8CGpDifG0DUCCAdCZAACZAACbgSoALoSoNxEggyAvoU8JRX/yH9klJkQG4rzQTMgqNlsmvDPKmtPCrGlGypqyzFKSBmjgAGWf9RHBIgARIIVgJUAIO1ZygXCYCAfgpIH7vI8q++kmm7d0mfqGgxm2okLa+z1xQwoZEACZAACZBAUwhQAWwKJZYhgQATcJhMclXfvnLzxL/Ks+PGyfHt30v3tt01qdQ08PfrpuMUEN9TwDwFJMCdx8eTAAmQQBASoAIYhJ1CkUjAk4CtplZW7tghq2bOkD4SLXnpmaJ2/e7euECbBrZEH+YpIJ7QmCYBEiABEmiUABXARtHwAgkEnoBuCHrBv9+W/lk58kh2rjYtPP9Qkab86dPAX696nKeABL67KAEJkAAJhAwBKoAh01UUNBIJeO4C1hkkJcZLUdlBbQ2gmgJWp4DYTBafm0B4CohOjSEJkAAJkIBOgAqgToIhCQQhAX0X8OSp06R/q3zpn52jjQDm5mRLsS3buRPY5rBIakGmTzMwJ+btC8KWUSQSIAESIIFAEqACGEj6fDYJ/AQBfRdw4ZcbZMtZHWTaxx9jF3CMxMbHSnXJbsnvMVQbBdz46YMSExfjNQLIY+B+AjAvkwAJkECEEoiO0Haz2SQQUgQcNTVyza9+JdeOvlW+Mhoko0MHMSQkS3bDTmBzdZ3XGcCqgZYas0x+ZmJItZXCkgAJkAAJtDwBjgC2PGM+gQR+FgGb2Syf7d8n68eMkb6GOEmNj5M7H3hA1j/1ilavWgNoSPRtAoangPws9LyZBEiABMKWABXAsO1aNizUCeg7gJe8/Q5Mv4g8kpuvrf/bXl0hGRkZ4qg77lwDyFNAQr23KT8JkAAJnFkCVADPLG8+jQSaTKCxHcCqgri4OImyVklaq15idZSKweF7BJBGoJuMmwVJgARIIKIIUAGMqO5mY0OJgL4DeNr/viF9YmJlAHYBq00hypkxLewwpEhO+55y9MgnNAIdSh1LWUmABEggCAhQAQyCTqAIJOCLgL4D+JL2HWXB3/8u046VyAX2KDl0/JiUlZVhGDBdmwKuOnGARqB9AWQeCZAACZBAowSoADaKhhdIIDgI2LEDOApTvg6HyI/lJ6TaatHWAJbs/VYzA1NWuUqsNAIdHJ1FKUiABEggRAhQAQyRjqKYkUdA3wSy8B//lIsSk2VsbiuJysmT6dgEopxuBmbvjyIZnXK8zMDQBmDkvTNsMQmQAAk0lQAVwKaSYjkSOMMETrUJRE0BZ7bqqE0BOxx26T5S7RN2d8oEDG0AujNhigRIgARIoJ4AFUC+CSQQpAT0TSBTXnpZ+qVlyICcXOcmEGUGRp8CLile5nUCiGqSpdoUpC2jWCRAAiRAAoEmQAUw0D3A55NAIwT0TSDnHz0unxcdkmlbt2rHwDmMcdod+hTwnh2+TcDQCHQjYJlNAiRAAiQgVAD5EpBAkBNw1NbKoIEDZfjTT8mk8eNl/8ZN2i7grLxO8v366dpI35Z31nq1giOAXkiYQQIkQAIk0ECACiBfBRIIcgK26mpZsWmTLIcpmL7RMVKRna3tAhZTmdTW7JOo6HrbgJ7NiImJ8cximgRIgARIgAQ0AlQA+SKQQJAS0HcBz1+8SAbk58sjWfVrANVRcOokkPO6dZS9Kzc1agNw4wsrg7RlFIsESIAESCDQBKgABroH+HwSaISAvgv48W49JLrhBBDXonf9ZpTMWz2nURuAYrK5FmecBEiABEiABJwEqAA6UTBCAsFFQO0C/rCwm0x6booMaNdO+mdmO3cBK0mzsrJgHNomqQWZ0uv2i7yEPz53r1ceM0iABEiABEhAEaACyPeABIKUgNoFfPVlA+Xo2/+WxaVHZdme3XJ56wJxpKW4SRwTF+NlBqbiUJlc0ftSt3JMkAAJkAAJkIBOgAqgToIhCQQRAX393+I33pS+UTEy6eyumnQT9u2Swo49tLgyBm2pNnudAKIuqvxHxzyileN/JEACJEACJOBJgAqgJxGmSSAICOjr/x7rWui2/q81jEE/NmG8JqEyBm1I8m0D8POJSyQ9PT0IWkIRSIAESIAEgpEAFcBg7BXKFPEE9FNApk6fLn3jEmRAqzy39X86IGXrjzYAdRoMSYAESIAEmkqACmBTSbEcCZxBAvopIBclJcvShYtkGk4CucAeJYeOH3NKoaaADUnxPjeAqBHAEydOSG5urrM8IyRAAiRAAiSgE6ACqJNgSAJBSMBWWSXRCQnY7SvyY/kJqbZanFJOffVvpzwFhFPATlSMkAAJkAAJeBCgAugBhEkSCAYC+iaQBS+/LBenZ8jYnFYSlZMn02EEWncbv/u60VNARHyfDqLfy5AESIAESCCyCVABjOz+Z+uDlEBjm0BcxTVjNNCYluhzCnjNpGWcAnaFxTgJkAAJkIAbASqAbjiYIIHgIKBvApk87Xnpj3V8/bPrj4E7dPCgU0CLxSxWq9XnJhBzZR13ATtJMUICJEACJOBJgAqgJxGmSSAICOibQAo3bJa3K8pkztovZVibArHWmZzS2ex2yeiU42UHUBmBjo1KcpZjhARIgARIgAQ8CVAB9CTCNAkEAQF9DeC8FcvlkoK2Mvr8C2VNSbGYYqKd0qky3Uf2cab1iNoB3P6sSzgFrANhSAIkQAIk4EWACqAXEmaQQOAJqDWAO5evkCd6nus0BH1Jfmv5PjXZKdypbACW7P0vp4CdpBghARIgARLwJHByOMHzCtMkQAIBI6DWAA656y6Z9M1mWX2sFGZgYAfGxT0+4UmXlHe0DlPFdkwR05EACZAACZCALwIcAfRFhXkkEGACag3gFb17S9lHn8ji4sOybM8uubx1gTjSUjTJNmzbJHHJRp87gFdPWiodzrpRnp38vPz5mVMrigFuJh9PAiRAAiQQIAJUAAMEno8lgcYI6Ov/Fr02XfoZE2XSL7poRSfs2yWFHXto8araarHUNHYMnFmy2/eSrZvfErPZLHFxcY09ivkkQAIkQAIRSoAKYIR2PJsdvAQaswHoMJnlsQnjNcGVkhhrNPhuhCNKdm2YJymJGdwI4psQc0mABEgg4glwDWDEvwIEEGwE1Pq/YQ8/JM/t/EFWYvpXX//nagLGDgVQmYDxdMoETEarnpKW11m4EcSTDtMkQAIkQAI6AY4A6iQYkkCQEXDAyPPO8nL5suiw9M9r7SadUgobMwFjrY6S8uKdEhtPW4Bu0JggARIgARJwEqAC6ETBCAkEBwF9CvjxroWaCRil7K0uLnLaAFQ7gE9lAqb30Hul9MC3UnRsF6eAg6NLKQUJkAAJBB0BTgEHXZdQoEgnoKaAh/7hQRm3ab2sOHxQw6FsAJ7dsaMWVzuABbuEfTrk220WyW7bXWx2hyQmJvosxkwSIAESIIHIJsARwMjuf7Y+yAio0b6lCxfKh/+ZIYOU2RfIN3HLZunTKs9pAkbtAG5M/1PN2f7Zm5KQkiOpWQVSU1MjycknjUcHWXMpDgmQAAmQQIAIUAEMEHg+lgR8EdCnfx9rmP5VZdTo30Nfb5D+vQZrtygl0ZiW6NMG4BfPfSLnDLhTjh/+Xoq2LuRpIL4gM48ESIAESECoAPIlIIEgIqCmf5f26CHTXv9fuSA6VgZC+VNGoZNjDE4TMGoHsMNkkS3vrPWS3FRZ5xwB5CYQLzzMIAESIAESaCBABZCvAgkEIQG7xSI/mqrly5Iirx3AsAujmYCxmW1ukmsmYHJ7SIfCm6Ti2D4p4SYQNz5MkAAJkAAJnCRABfAkC8ZIIOAEPKeAfe0ANlebxFP5U4Jbqs1ixWjhwe9WSV1lqVRVlInRaAx4mygACZAACZBA8BHgLuDg6xNKFMEEnEagf9guq4+UaCRcdwCXlB+VqGjfO4DVVPE5l94pBV0HamHnPjfL1OdfiWCabDoJkAAJkEBjBDgC2BgZ5pNAAAgoJe7aYcOk++ZvZGNOljyzcIEMTEoRR0r9Tt79B/c3fgScxGjr/4wp2doIoNoJ/E3pCZ4HHIB+5CNJgARIINgJUAEM9h6ifBFHwI4TQD7dulXWiU2uSs+U5ZXl0q1Hd42DxWaV1IJMnzuA1z+/Qc7pe6eYayslLiGlfifwto9oDDri3iA2mARIgAR+mgAVwJ9mxBIkcEYI6DYAF7/1tvR1RMnYvDbaDuDvjPHOHcAms0lS4hK9dgCrDSBR5gyvEUCrzU5j0Gek9/gQEiABEggtAlQAQ6u/KG0YE/DcAOKrqUpJbOwM4A7dbpbM1l3cRgDLi7+nMWhfIJlHAiRAAhFOgApghL8AbH7wENBtAE559R/SD+v+BuS20kYADx08qAmpzgA2VdV5jf6pi2oHcHnxTin64QsxJCSLpbZKEtNwf3QMRwCDp4spCQmQAAkEDQEqgEHTFRQk0gnoG0DOLToi/1z3lczduE6GtSkQa51JQ6POADam+z4B5POJH0oNTL9ERUdLLKaIraYaLW3HmkEeBxfpbxbbTwIkQALeBKgAejNhDgkEhIC+BnD+f96RATgB5PbzL5Q1JcViiokWNfpXWVMlNpvN9whglUk6ntdXstt2F7vNok0DK2PQu9bN5ghgQHqTDyUBEiCB4CZABTC4+4fSRRABtQZw5/IV8ni3nhINczDKKRuA36cmyzqM/kXFRktqfprPHcCr/7pcsgoKZdeGeVJTXuKcBnagjrKyMklOrjcjo1XK/0iABEiABCKeABXAiH8FCCBYCKg1gPNS02TcjJlyeX4+fP0uYCVfeVWlxMTFaN7zDOCqonJxWJKg/M2X2qpjbs1JyWon//zX2/LXP//RLZ8JEiABEiCByCZABTCy+5+tDxIC+vTvx4sXyyCs+3PY7TJxy2bp0ypPHGkwBI1/yvnaAbzxhZUSbcuR0v1bJSmzjXuLoqJlxer18ozZLHFxce7XmCIBEiABEohYAlQAI7br2fBgIuDLBIya/p2wb5dUHqvRRLWaLD7X/0VbHHLR+b+UxR+v8dmk6po6OXr0qLRp46Ec+izNTBIgARIggUggwLOAI6GX2cagJ6Cmf391790yDjt/Vxw+KGpEUO0Kbp2TK4eiqjT5MzrleLVDGYDud35fuefOX3td0zMcdodYLBY9yZAESIAESIAEhAogXwISCDABffp3yb//I4PatpdYidKmf1ccPiT7cPavxW6FnT+T2Mw2L0lV/uRnJko0zL/oTpmCiYmNx45hszaVrOczJAESIAESIAGdAKeAdRIMSSBABOp3/34qj3ctdNv9q6Z/D9RVihib9mOqRgzzOl8oFSW7tZ3AxuRMqa04JnarSexYU0hHAiRAAiRAAjqBk8MGeg5DEiCBM0pATf8OvuUmGbdpvdv0r8VUJzXp9cqfHWf61hyt9PJqeld38UkZOA1kl2YAWm0isZprJSbGIGn5Z8v0N/6jF2NIAiRAAiRAAphtoiMBEggYAX36d+kHs+XKNm0lGmv/9N2/FTD9IgkGwYJAiU8xSmJOipecRjuuwxkMBklMyZGj+77BdLAyFxMv8VHpUlVejAllkU8/LxIzdwJrrPgfCZAACZCABIcCePPNN09AZ9wNnwq/CdNVY+bMmbPNVwddf/316fhl9wquXQdvxy/QJZj6euCDDz4o18ujvpsQ/wt8O/i98H/E9XkI6UggqAio6d8fli6Tp3qc6zb9e+9Xa6TCoKZtDdr6P0NinDb65yq8pc4sV/e7QsvKzc0Va3WRWExVktbqF1J5dLfYrDD9kpCCU0EqpLzsmBQVFUn79u1dq2CcBEiABEggQgkEfAoYytqjYH8H/FVVVVXZUObWYkH7R0OGDEn01SdQ/mYgPwdhR4SdUT4P4dt62eHDh/dB/N/IfxJhKhTEcQhnjBgx4jy9DEMSCDQBNfK3ZP582brqM8mONcikLZvk86LDzt2/8TD6bMtN0sRU07+x8fUjfa5yW6rN2gYQlads/PU9r4vEGOKkuqxIq8dqrsHaPwvOBk4QXJDrht0ipaWlrlUwTgIkQAIkEKEEAq4Agvvv4KdghG770qVLTQ0KmyE+Pv4Gzz6BsqhG9AZDQXx45syZZbjnOEYLH0He0BtvvLFAlY+JibkPwYfvv//+fFy3zZ49ey7Sy1Cveg4dCZwRAkrB+3DBAnnumfGaMuYaV4rfRT16yHvPTpQJv+gi9xd2lyd7na/JNWbt5/LJ4QNOGS01JonGWcA2i83NW81WaZ2b7yynIiOGD5W4xDSx1JVLSk4nlLdCGTwiteVHJDktVzLa9ZaB194q5/W5VL744gvZvXu34I8uOXjwoOZd42q6WPmSkhItbErcVRjX8i2R71qna7yx57qWcY23dHnXZzUl7q88TanTtQzrd6XhHW9pPt5PbN6ccJC/uLhY++Y0LxnW5otAQNcAjh49OhUvbAcocRt04ZTSBkVvC5S8c5GnRvtcXS8k6t57773/6pmYKt6K8maUV9cO4hdvL4z+vadfVyHyVP3DXfN+Kn7/kw/I4Z17JabaInOXLPup4gG//viEJ6Wk/KhTDqWAnDh0hPI3EPGXT2Plyw4US6d+PWFmBSN0Vpum3CnOer7ivmPTt5JSY5HhrdvLsr07ZfmSBVp86Z4fZfG82ZIPEy390zNlV2WFjNuwTq4uaKud+asMP79/eK9MLz8gMQ5lty9OYo0GSS3IdParHrGX1MnHc5bqSS3MycmRKKz/S4SyV1GyQ+IT0zElXC1n9xsp+79dLscPfy92m0nMhnj5nz++CAXRhI0i1ZKQlCVW7BS2omxCcpYkpreSiuIdkpKeJZl5HaVk77fa2cKZrXzHs/I6iZjK5OLe58iDY+6RKc+/Ihu+2SkSn6Hl9+7ZWR79w5hmyX/8kd+7mbzRAahdzpOnveT13ECV1+Vqauiv/E2tVy/H+nUSvsOW5uP7qc2XG07yRxuzxF53TNR3o7Gf3+YjF9k1BVQBrK2tTcWInfqgn/DohjK80Go9oJuDYqemdJ1r/VwunlDXGtKpuNetPtRfhvv06y63NR6t2LFLhkqiLKssqzehgV/sujsZ03M8QsepTW4473ep060Gl52dJ/Odd2lZKqWUDd2VnjgiWUPba3lH1u2R6s92y9DkXPkI8pvrcJKES1l1j3bnydv1ahpCHDzmUd6AseI6tSnBzTVSQUO2fnxZ/S0+yrpknYD8ra5rpz23eP0eqVyt5G+lyV9TfrxBYLeHe8l48mp9xS7VS8WJEmk9uJ5P0QbUv6a+/o/Bp/L4kZO3qhhurIQ8rQe31Z6hlV+9R5NnkSNK2gzCUW3go/Ir1jTko8ujMsxa+rcZbcSQESVflBTLqPZniQFKmYq3MyZJHN733IREOVJbK1P6Xqxt0FhdXKRt/OgNo8+w/izR6UaxJsWJGv1TCqDa/evq1IkgV/W93DVLixcUFIi58qgkZXSAfEqgKDEaMuXAf1dIfFI6FL46KHcdJf/sftgtvFPbLZz/i75u8ey23XGm8DzpeOHNosfzeww9ZVwXZOOB7XLL6Lslvu1AyTn3dj1bthZta7Z8peQ9+eiDzrr1iMrfWpLm9dxAldflamror/xNrVcvx/p1Er7Dlubj+6nNl0v5m49lJNUUUAUwISGhQg1ZQ2FL94CeAaXtoEee+qVbgbw0z3yk1f26YliBe93qQ/0ZUBDVvU12k8++AH+F1Mnu6lo5OPaJJt8XqIJ/kkxmMg3VAAARzUlEQVRZ+/qP8iWm7H7VqpX069pHO0lCyV/81PifLZaHivSz6/Os4Ckl/5s7Nfmv1eTv65S/dMIkz+J+p5+QLFn7dn3913jUX/b/p3rV97iS5+1dmjxa+XPq5dlVXSPd3qnPH6Tqacj/GBssUj4rlme695X//PiDHMG783S/i+vj1VVaPApPWXukWNZiiiMvM0Ne3PmD9MNZvwM7dtL8Axu+EFOyUZKTkrXpXklKwtI99x9RNfWblZInz433ZoJlEzIS08CLlq6QzJy2YreYRdkCrKkokbj4OCilGWJMSpA2HbtJ5cGvJSXJ6BZv2/lcjBBaJMZeJU2Nu4KLb9tVtn6/Unp16OmaDYXwHOSv+tn5Cah35WdvStGL6zEtfnJNpJL5hw27pOsld7o9N1Dl3YRoQsJf+ZtQpVsR1u+GwyvR0ny8HtjMGeEs/7atM7VTjCL1HHPoLc38trhX17K1uz/LZwrTt7tx4W+Y+n1ZFUA6BkERlL0/YP2e2xQwrrXDtT1Q8Hrq08DY3NETCt5mm83Wfu7cuQdvueWWN3BvKupTO4E1h/vmAuQxrAu8R89zDXHPINQxSOVhl2TS1KlT73W9zjgJkAAJkAAJkAAJBILA2LFjp+/bt69aPRv6z0fQZT5qDjkCrgBC+RoLhe0BKGDXoWFKGfwT/K/r6up+uWjRIsxdujsoc4uQY7BaraONRmMUwneRroLCd4MqqXYBo56VqHMUdjwugXmMYYi/g7wBUBo3qzKncigbBdj/hBKodifTNRC47777nn3ttdeeIpB6AuTh/SaQiTsT8nDnoVJk4s6EPNx58B3x5gF9ZAr0kfsxiOW6qsm74GnkuM8vnUYFP/cWaLJToQQmQ0FbjrqUpduNUAavUcrfyJEj22Jkbzsafg3KfaGehUPtb8Nw8MuxsbG7oPwpIIuQfkBdUw6bQtahvtsQnYRF8e9CoduL+0c3RflT9yvIN910UzVCv6aM1b3h7MDETCYne5g8TrLQY2Sik6gPycOdh0qRiTsT8nDnwXfEJw+ljzS78qeeFHAFUAkB5W48AuXd3KxZs5Q9DLfjD+bPn38Ceb92K+iRQH1zkKU8HQmQAAmQAAmQAAmQgAeBYLAD6CFS4JMYjWyW+fXAt6T5JCATd5bk4c5DpcjEnQl5uPPgO0Ie3gS8c/hz486EPNx5MEUCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJACrJ5EIAbYEJ6Ddd8Or4+E2wezMGJiP2eaLxfXXX59uMBhewbXr4O0wK7MEW7IfgN1B/eQRX7eFXF5TmaBcDhhMAYNL0Mhs+FLEZyFvPJiYQ67hjQjcVB6utw8dOjQFp3F8i7y2hYWFhvHjx9tdr4d63F8mKH8H2vwwPA4Llir4WXhHHkIYNs4fJrBRegEWdD+HxveCt8Kvhv8DmOxHGPIOLEagEWPg1VEwyT/1MxDu31Z/eKBspHxX/XpH9B+KcP22+vOO6Cxwzx2IN8t3NeJ2AQOeMvCsAF5VVVWVDeVlrdplM2TIkETkeTkof+o0khyEHRF2Rvk8hG97FQzhDD+ZJIPB92juFfjFpc5dvhLK33Xw3meThSgTP3k4Wwl7lC8g8Z0zI4wi/jKBfbNH0PxxeC/uhyKg/tBSPz9vwYeN85NJFL4zS8Bjy9GjR3NhxL4j4koJVIbsw8UdR0NeQbuapORHwLfVHx5h/11teMn9YeL8uQjjb6tfPJr7uxoUdgCdvXxmIr/DY6ZAedmuHoeP+DgEd2HkRp0kopQ9p8O1dkgMxoe7x8yZM8vUBfwV/wjSW2688cYCdfScs3BoR5rMBNz2oKlOZQ8jp7vB6Q0ohXeENgI36ZvMQ78LxseH4BdfN6SfhL9azw+jsMlM1F/reB/Gw4/A+7IWRzoqDLXwW8KIh2pKk5lgtEudYa7+4Hxz1apVSvGz4ufmHYTvw4eFQ19/ohqCdl36Uw2KhG+rPzwi5Lsq/jDR36Fw/rb6w6MlvqsRNQI4evToVLxUHTBqtUF/udABNsS3QKk7V89zCdVUTZ1+7rDKh8KzFYEZ5dW1kHenwcRXm6+G8rPZ14VQyzsdHjfccEMW2v8S3ok70F71PoWV85cJRrcuAoBEMOmCX/Q74Ivhl+KPpx7hAsZfJsqAPZS/V+DvAYsENf0JFnfAR6rB+rD/tjbDux4239XTZRHu31Z/uLTEdzWiFMDa2lqlACqDtSc8wJdBKdSuuebjY63yfK31Ux9zr/Ku94ZK3F8mnu3CX2dqBLUXjuZTYci70+ERExPzKpSd1/CHQlhO//rLBD9Lam1oFPww+Euw1KI9+HyDn7tl6q/YkH9J0AB/mTS0eTY4XIl4BaY/SxGqaXE1VR5xLhK+rT+nU8Ptu3q6LML92+oPl5b4rkaUApiQkKCd7wuQ6q9vV5eBX07aNddMfKxVnpq68XTpDdc880Mu7S8T1wbiI/UXcFCbaS7FsX2HXa+FatxfHliTMRK/zDp169ZtsmozeCjFR7Zt26aFKh7qzl8m+s8SWPwVI+zFS5cuNYHPU+CQ1vBXbKgjEX+ZYNSvM3h8Av9iRkaGWm+sFOEl8F+qEcGQB+JnA8Ah7L+tfiJxFg/H76qzcX5EIuHb6gcONXCl6SjN+V2NKAVwxowZCuBegOytg8fHNwbxc6EUfq3nuYRbEI8fMWKEWtulOcR7ImJAeXUt5N1pMNHajI+UWuw9An+h9ccv+Z0hD6KhAf7ygPI3CLd2gcJXgnfpKNLzkVbKXxHStzVUG9KBv0ysVqvXz1I4KcSqM/1lgp+VHritBushX5s+fboFPzO1JpNpKvI64Xvk/L6ouiPEhf239XT6MVy/q6fDIhK+rf5waYnvasRtAsFLpabrxmI90kp8eHejA/4Ej2+xaZ5nZ+AjvR+/xD+EsjcVaxFGY/QiCp2gPtoLw2gDiPjDpEFhfkf9QsO074B33323xJNbqKf94YG2PgQl+Gm9zTabTa1/ew/hecg/pueHeugPE/WzgfdkHu55Cj83W+rq6soRfwbvzHH4L0KdhS6/P0xQdiPui8Ooxt2Iv5mUlGTA1PjDyKvE92WHXmcohzB7FL1u3ToD+jgebZRNmzYZBw8ebMMIsBntcri2LRK+rf7wiITvqup/f5igeNh/W/3h0RLf1bCZpnL9uPxUHH9ljcdH6j6UU9MwG/EB1uwAjhw5si1+cW/Hx+ua999/X/tFpRZrYwv6yyj/K5RVH7FFSD/QMAKAZHi4pjJBuUvAYiVabYJXuxmVU++RAx/1sFgXqRrUVB6qrKvDh1ztgPz0p2ygud4TKnF/mIBDMtr1AvyN8GpjjNp4NRbviLb7HvGwcP4wQVllMunPaHgXePUtUTYj/wgmaxCGvEP7foP2vYmGqLYpp30X8D29DH9s74m0b6s/PFA2Ur6rfr0j9a9R/f/h+G315x1RFCLlu+ra74yTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQEgSiMiTQEKypyg0CZDAKQngmLUncerEpThZ45pTFgyxi7D+fytEHoV2DWkJ0VF/G9T7lcFg6DFz5syylngG6yQBEgg+AlQAg69PKBEJkIALASgoq5DsB18Hb4evgN8EZe91HNn4IeJ+O9S5B/f/Bfe/4ffNZ/AGnKUbn5ycrM4svwYKoDo6rkUceEwDDwN4/E+LPICVkgAJBB2B6KCTiAKRAAmQgDsBHDHrmAwFKA0+IzY29nxc/gR5s3CW5l/ci4ZXKikpSY3+HWhJ5U8Rw1m9r4PnnaNHjw6b87zD601ga0ig+QnENn+VrJEESIAEWo7Au+++W4ra/wHlzwSlZfrw4cPfnDNnzm5MAT+DUawroSwNUE/HqNYDCB6Cz4GvwbWlGOH6LfLVqGE73Psy4i8ivhf3dEf8UsSfhf8lvJod2QLF6OH33nvvG8RVfer6StRzM+5V5fLg19lstt/MnTu3CHG54447jNXV1X9E9Gb4fPgj8BNQ/78RCmS+Fvf+CdGz4Y8qGWbPnv2SuubL4Vk3Iv8j12uQIwbpB+Hvgm8LfwL+JTxjiouMI1G3Uo7V9O4K+NuRfgT13Y14LMJXwWI84ppDG7/DvcdNJtMgZHzQkM2ABEggjAlwBDCMO5dNI4FwJpCYmDhTtS8mJuYKl3Y6VBzKTGcEk6HADYFilFZXV3cWFCBtuhfpa3FtP9JjEE+B767ugTOj/CMIWxmNxnZQkn602+0LBg4c6PaHMvKuR5nzoSwVIEzE85UyqLmamprXEbmy4blqNK0/vDZ1C+XvMjxzBvwTeGYm8m/AM8YifxTijbkLUP6/HhcnIH0//O2oJ9VisfSATJ+7lkH6WrT5XIyWdkB+F/h18MWFhYUFuDYEdT4NxbkP8lzdVsjT2zWDcRIggfAl4PZhC99msmUkQALhRuCtt96qg6JXCmUmy7NtUMqsGJkT+G5Dhw49uHDhwkqUWeNaDkqa2xpoKFNfulyvvvXWW5+EcnVvVlaWGhHc1nDNASVJKXBVKo1Rx5lIj1HxUaNGZVut1luhYJ2P6ztUHsJiBMoL5HwI/lWM+K1SaVzbDuXvNeT9Fsl3VZ4PpxTFco98tU7vN7h/k8qfP3++GgFUCp7uHFD8nsJzapBRAxmXQMbBSKtnqzLrwO075F2o4ipDOaTLIYt6Hh0JkEAEEKACGAGdzCaSQDgSaJhuzYHSoqaE3dysWbP2Qrkaicz/Fx8fPx0Kzw6Uex4K0Cy3gi4JlFEjgX+FPw8+GcqfGk10QJnMRagrgIJRtCIoX8jS1s5Vo94UFTebzR2gVDowMqkpfyrPw/0CStYVeM7vGvKjcK+ahdnnUc41eRyJND2jQclMhpLZ2DO0ol26dNGUTpWATErGIr2OhrAa+Zrcej7KqOcc1tMMSYAEwpsAp4DDu3/ZOhIIWwKYblUbJOxQXD711UiscVsERW0wFLYslJkK5WsGlK/ODWXtPu75AOV2xsXFnYP70qEAdkQZpaS5jRT6uE/Lwn17VQRyqfV9vlwx6pqEujMbfAZCtbGlh6/CDXmboKgV6tcb1j9WIa+xZ+hFTyfsDkYbT+dG3kMCJBB6BDgCGHp9RolJIKIJqFEwKGfDoUw9p7zaAOIJZMSIEWdj+veshISEz8ePH1+N0cAKlFUjeraGsmqETE3turpUKFYVM2bMqISimAllaGrDPa5lGo0r5QzPeRd1vILn34GNFTtQTx5G6/Ih49eo60XUqUYj16KSz1RFuNYFeZkYmVztq2Jcm4v77sG18fp1pF9C/kTUsx/K4yZMVWegrb/E877Sy/gbQt6ukEUpym4bTvyth+VJgARChwBHAEOnrygpCUQsASg8j0HhqYA/gXV2m5G+BjBuheL0dCNQ4lDmaWyEOKjugWIzBenboDDtUeUR/zPyhuFaGfwWlYf0XfC3IK3WCyolbYnK98fhfqWsfQZlamlDPWvwrHNUHZB1Aa7fhuif4dXu4BIoi/+C91rDiGuaq6ysnIFIO2zYcI4SduvWbRzqVJtN1IhmJZThb1Cv2mzij9M2y+g3QIG8B3W+CT6e6w31IgxJgATCjECTpjbCrM1sDgmQAAmEDAGMKo6CgncrlLMhLSH0yJEjW0MB/BJ1n4tnqDWHdCRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQxgT+D22obVSjqUpWAAAAAElFTkSuQmCC\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"\"\"\"\n",
|
|
"# To plot species, we first have to identify the index of the species in the array\n",
|
|
"# For this, cut & paste the following lines and run in a new cell to get the index\n",
|
|
"for i, specie in enumerate(gas.species()):\n",
|
|
" print(str(i) + '. ' + str(specie))\n",
|
|
"\"\"\"\n",
|
|
"\n",
|
|
"# Extract concentration data\n",
|
|
"X_CH4 = flame.X[13]\n",
|
|
"X_CO2 = flame.X[15]\n",
|
|
"X_H2O = flame.X[5]\n",
|
|
"\n",
|
|
"plt.figure()\n",
|
|
"\n",
|
|
"plt.plot(flame.grid*100, X_CH4, '-o', label=r'$CH_{4}$')\n",
|
|
"plt.plot(flame.grid*100, X_CO2, '-s', label=r'$CO_{2}$')\n",
|
|
"plt.plot(flame.grid*100, X_H2O, '-<', label=r'$H_{2}O$')\n",
|
|
"\n",
|
|
"plt.legend(loc=2)\n",
|
|
"plt.xlabel('Distance (cm)')\n",
|
|
"plt.ylabel('MoleFractions');"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Sensitivity Analysis\n",
|
|
"\n",
|
|
"See which reactions effect the flame speed the most"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Import a data frame module. This simplifies the code"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import pandas as pd"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Create a dataframe to store sensitivity-analysis data\n",
|
|
"sensitivities = pd.DataFrame(data=[], index=gas.reaction_equations(range(gas.n_reactions)))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Compute sensitivities"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Set the value of the perturbation\n",
|
|
"dk = 1e-2\n",
|
|
"\n",
|
|
"# Create an empty column to store the sensitivities data\n",
|
|
"sensitivities[\"baseCase\"] = \"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"for m in range(gas.n_reactions):\n",
|
|
" gas.set_multiplier(1.0) # reset all multipliers \n",
|
|
" gas.set_multiplier(1+dk, m) # perturb reaction m \n",
|
|
" \n",
|
|
" # Always force loglevel=0 for this\n",
|
|
" # Make sure the grid is not refined, otherwise it won't strictly \n",
|
|
" # be a small perturbation analysis\n",
|
|
" flame.solve(loglevel=0, refine_grid=False)\n",
|
|
" \n",
|
|
" # The new flame speed\n",
|
|
" Su = flame.u[0]\n",
|
|
" \n",
|
|
" sensitivities[\"baseCase\"][m] = (Su-Su0)/(Su0*dk)\n",
|
|
"\n",
|
|
"# This step is essential, otherwise the mechanism will have been altered\n",
|
|
"gas.set_multiplier(1.0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>baseCase</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>2 O + M <=> O2 + M</th>\n",
|
|
" <td>0.00154932</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>H + O + M <=> OH + M</th>\n",
|
|
" <td>0.00108093</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>H2 + O <=> H + OH</th>\n",
|
|
" <td>0.0251687</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>HO2 + O <=> O2 + OH</th>\n",
|
|
" <td>0.00303606</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>H2O2 + O <=> HO2 + OH</th>\n",
|
|
" <td>0.000726028</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" baseCase\n",
|
|
"2 O + M <=> O2 + M 0.00154932\n",
|
|
"H + O + M <=> OH + M 0.00108093\n",
|
|
"H2 + O <=> H + OH 0.0251687\n",
|
|
"HO2 + O <=> O2 + OH 0.00303606\n",
|
|
"H2O2 + O <=> HO2 + OH 0.000726028"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sensitivities.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Make plots"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"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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wccZYxVMLrAO4vl6sf4UREAEREAERCBWAsGbi1gbyl8ERCBxBBCY9gh4+8aNG/UIOAHbsKG80jd1Zix/n8ZnkvZF0Mf6/76sf396lFd/dg1tKfYNJVi/9qnKnUsYX5cuXWzRuaRjvsyJRqtFNAfVi4AIiIAIiIAIiIAINC8CEoDNaz+1GhEQAREQAREQARGISqC+7wGM2rEcREAERKC5EujQLttnj2ObOuS20a/spmau8USguRLQb5PmurNalwiIQKMR6Nyxja9VZq0PeDfaeOpYBERABOJNQI+A401U/YmACIiACIiACIhAkhOQAEzyDdL0REAEREAEREAERCDeBCQA401U/YmACIiACIiACIhAkhOQAEzyDdL0REAEREAEREAERCDeBCQA401U/YmACIiACIiACIhAkhOQAEzyDdL0REAEREAEREAERCDeBCQA401U/YmACIiACIiACIhAkhOQAEzyDdL0REAEREAEREAERCDeBCQA401U/YmACIiACIiACIhAkhOQAEzyDdL0REAEREAEREAERCDeBCQA401U/YmACIiACIiACIhAkhPQ/wWc5Buk6YmACCQfgS+37PKVbdvXJBPLbZPhy22d3iRjaRAREIGvDoFmLwCHDh16alpa2rXV1dW92da22GbsJey2kpKSN4YNGzaWuhtIH0NZMNDO/Ff06NEjY/LkyVVDhgw5s0WLFndTdjxmv43X0+/dxcXF95NulNCnT5+MvLy8q+l8FNYV24OtwqbY3ImTIsBqIBP5DfYtLA3bCNNlmZmZt8+bN+9L8r7CwsITKJuCnUe2nfnAb2F2dvbU2bNn7zKfeIeCgoJJjHEerHq5+460526fhqThsY5xr+e1McPdD+UrWP+q0tLSiaSzSN+F3w/w6YJtI7+ssrLymiVLlmxzt1M6+QiUV+zz3fjoW00ysQljekoANglpDSICXy0CzfoRMAKgD9u5uqqqaiPxdxECOVlZWadx6D5NvgBzQrWTCImD5fSx9uDBgwX00RE7DL8RHNhTEBP9QtpEzJowwP+ciA6uCkRnC8TfExSNxsaXlZXlIg5OJv0+9iJrqyFqKKtXGDhwYLvRo0e3qVdjGrGm3xPNhkVJRkZGd9i0h9OPKNtJbCLah3juAb9/Yvso+w4+bRHTQ2jTe+/evc+PGzeupflFC/n5+V0ZryqaX0h9cA89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G5Wz83ceQuJvTONiduns501qya9DCJUjdt606SHwnqbcduau5edG3kf85ZH/FPHxqP0OIPlGfXIcNPC26kYqSy3aT8Cwtd4lqHGICsauoO2dJlhDmAWssjdomc9JzM8E5IN8QzqQN5K3YfxP4kNOI0Tgddh9gM1Uyux2vO2W2Usr51A3344TFILxbCjHrwPx5XLGt239Vzk2V7w7pexM9Uq2ODVnFERABERABNKXQNhdpvSdumYmAqlLAPFot4C3rl+/XreAY1zGTzfUtMofgk7V22G2zKnse6r7n8rsU9V3Njk83bt3t1OnI/moN0usYaiQGapSdSIgAiIgAiIgAiIgAulHQAIw/dZUMxIBERABERABERCBkAT0DGBIPKoUARFIVwId22d7rp50VEzTK8y3x2hjf4s4pkHVSAREQATiSEACMI4w1ZUIiEDqEOjYLstjMZZQUNA+ZX8GJpb5qo0IiED6EdAt4PRbU81IBERABERABERABEISkAAMiUeVIiACIiACIiACIpB+BCQA029NNSMREAEREAEREAERCElAAjAkHlWKgAiIgAiIgAiIQPoRkABMvzXVjERABERABERABEQgJAEJwJB4VCkCIiACIiACIiAC6UdAAjD91lQzEgEREAEREAEREIGQBCQAQ+JRpQiIgAiIgAiIgAikHwEJwPRbU81IBERABERABERABEISkAAMiUeVIiACIiACIiACIpB+BCQA029NNSMREAEREAEREAERCElA/xdwSDzRV44ePXo8rcaVl5cPib515C2GDBnSrk2bNu/S4hTG+ijylrKMlMCAAQOyu3bt+npdXd1PFyxY8PdI28Vix3lzCe36sJZnx9JebaInsHX7Hs/W6t3RN6RF19pqT9ucmJqqkQiIgAjsFQT2WgHIBfF3EDqD2JNYVV9f/xwX4l8tXLhwXShytBtK/S+J3yFmENfTdllOTs5tc+bM+YL6hynL4kI7ibQhjBo16tqMjAwTU/2scMyYMT+nnV2U9yPWEddwPG3+/PmryAcMgwYNyqPiVuJpAQ3CFPp8uBazOfgxwW2O389x3A8fzykrK3uooqJiO/Z/4PiPlNucUy6EWyvW4GKYG4dDiDuJrxB/DRsTvp4RI0b0zMrKWst5cQgC7WMrcwJ925rZej7rlNHfZfT3c457ELcQ76Te1itg6Nat2/nYfxSr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4H/zQWucX7b+fBfkYxCFjwbo/w3K8ni28kjnNjD5b2ObQ7S6Fgsx+N5ivkUyUKz+I/7sRaEfI6B+gPj7LJKx4m0Tq+9uP5hDLse2m2ZfKDa56xKZj9Z3PkfsMZJvIfi+4G/DXMshmvhbz/GlCJOZVtgSIVrfQ/m07777triAjdb/3bt3/8PuULhDc4S3BKCbpPIisBcT4Pm9UoTJSgTdmRs3blzWrVs3e2ZoIB/I/YK5zQfyhdRdh81gxN8LwewSXR6L7/zkS+bLL7+cwxzz8N/z2muvteFb+h6+9e7CX7tdnpDAWHZ76zJuy62E98cMMo3IRmzNIv8Budh9CuPHEXu38VzUBL6FZ/AhfRt2S5LwAog92xSx7zaXAQMGZB900EHZ1dXV3ou4swtiOwv+c22J42j8h7tdCR9lrY7itm+/OXPmfNESPgYbIxrfObcO5dw6knPqabttx1wOZx630PcrnFMtJv6cuUTjO22mIkIaXi7jb9ueS5tH+h3K7VnGFg3R+M7faDdeuDmGW6+r7csr69Ab7n/A4b/MmDFjZ4s67hssGv/tM4VzZRFtrmIub3AHZiv5a5nDJmLUn+8trniTAVhjikC6EGC3YyR/6Dcwn57Ef9sHAcJusTM/PhzsZYTHuIh4347k2N4srCU6F3T7m7ffvRrU0oIwWt+xn8xcHzZ/iRYc30/G979+VZSYfxm7hLGL6T2f+HcEnvd3AMeOHXsAF7p34Xeaw89+B5Cfw7gb+8HYmq8VHF9o3+7Jt3iIxnfOD+M7mdiIMedP422GFpxFpP5jdxLMV+Kandu7fS56zxH8b9HnLx08kfrOLvFhnFMP0q430TZiNhKf4MtDyaJFi74k3+IhUt/9HeMc6k/Zs8n8HcBIfcfXA/HVHoWxt63tHP8vcQFf3G6YOXNmNfmkhEj9N+eYQweSO4gjiPYCzqvEyzjn3yVVEAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERaHECSfvvflp8phpQBERABERABJpJgP+266RevXod8O67737azK7UXASSSsD+D0IFERABERABERABPwL8v6uFFP2a/3N4f/7/57P4/1Z37dy58x95eXl3Uf68n3mjQ9qOp91O2pHUD5g/f/5FjQx0IAIiIAIiIAIiIAIisPcSYNfvJwi6oY6HHD/k5AOl1J9M/KVTR/7nTl6pCOwtBLQDuLeshPwQAREQARHYqwiMGjXqOhzajx082wlc7u8c9YNtZ5BoO4KnYXcbu4Sb9uzZsyUzM/Mc6jtnZWUtmDdv3v3+bXUsAskmkJlsBzS+CIiACIhAehNg9+xx4tWhZhmJjdM+GlunTbQpu3ZjEHY53LqdgrCrIv9P/z6oW0p5bVlZ2V+x+ZDY22z69OnzZk5OTn9E4Ht1dXXzhwwZ0s6/rY5FINkEtAOY7BXQ+CIgAiKQYAJjx449aPfu3TchVvozVD6xkvhGdnb2z+bMmfNFgof3sCt2ujMG4m0lQmk14mmaU2ap28ZdHijvbxusz0BtIy1DuJ3E7t39w4cP7wa33rz40fDMH/5nOP2Q32l5bOpJMvHlkHfeeacb83uR4zKOTz322GN3tmnT5mhsvke/a0i3MYc3rJ2CCCSLgARgsshrXBEQARFoIQLcknycoZ4j9kJ4bEWUdCV/Gi80mGhRCECA3bsViLXfIAJrqf5pSUlJnZnB7sckhyOq/w+utuN3OGW9TDAi7A4lvoUoLGADsRt1hdjcb22x2YTNFsqOJd5LVBCBpBJo+BaTVC80uAiIgAiIQEIIIDzs+bWNxO8E23UaNGhQXn5+/rUIlzHYdSa+TZzq2NPHSo7fJJpwPIO4FaHzO2593kfeG7C5kMxUotlsp3459T+1SmvP8fMIoH1I7YWI3UQTVvWMUUDqtWH81Qivz0h/RfmhVm5hypQpOZs3b/6ctlPoc7H1Z7a2i8hzdn/275PjqdRfRR+HfNWDt/9c8p8Tf0b5Eqe8pVLbhUUM9mW8w5njX3gu0HgqiEDSCOgZwKSh18AiIAIikHgCiJ1NjPIWsRThdBaxD/lGX/7bt29fimD6LgKlX+/evbuSL8NmxYQJE7zijLyFycTp9NeJ+ouJd48cOfJgq6BPE1o3I2yGUN+RncVvUt/oTVnEXz2C7TzsVlN3C3b5RHf/1pWHujkk+7KDdpK3gH8QfyNIdlNX4ZQ5aaA+fX0UIg5/5NhRNpr8Dsb09kH/4/Db2LRImDt37r8Zex7xOom/FkGuQcIQ0C3gMIBULQIiIAKpToAXEk7mGcCLEEHnMpejED47yD9UWFh4FeLKngmchEA7fOHCheuJNt17sZm6a9euweRnWwFhAeLFbiN7EF0LTTyx02a3Mz/mNuluxKOHeOTQoUPXLVmyZBvlz5tttIExqhBu5bQ7h/hXX/uf4e+jjLsnkv7oYwf+PYogLcb+GWtju4fE+8l6b3uzk2hC06KCCLRKAhKArXLZNWkREIHWRGD27NmbmW+JRd/t1EGIoUcRfybUniB6EEsvI5osa8F2CHOIPezAAgLsP1/lGv6tpo2JR4/tbrGjNpbs+fxI8nT6sTdib0ewzW2wjiKDbw9g/jQ7kBciKu05uh9Sdn4UXZjpn/HhDXzpip/7IHBPIB0XZR8yF4G0JSABmLZLq4mJgAiIQFMC06dPt2fvliCMnib9DnEGsR6RdRS7f+vIxxTYUbNbqxW88JDJW7AjEWxzGePv7MZ95Neh92UKv7JGh7R5ibYf19TU/ISK/ejr+QD9uNs06RP7D+jjBdr+FCG4H8bLEKr+ItbdR6M8ba3PcC/JOLfSQ9kFs7FyewZS/yVrI/I6aCkCEoAtRVrjiIAIiEASCAwbNqwTt4CvYGi7lfsBz/jtRqCdTP5kxNENCLdPETuLuY17D+kvECSfchs3n5287/MzMf+I5GdiioqKDkNAfrNt27Z/RQBWsxtYiegyURTolu1/Gfcw6kIGbB7C4OfELuSvCmns8QTsk3a2C3gLbTsSTUxGHOAQ9hl5blX3Y1exDoYvBOsYpv3xIxOblcFsVC4CySAQ9gRPhlMaUwREQAREID4EEGa7ECD70Ju92LFhzZo1Gzm+nWhv8d5uo1RVVY0neY34FIJlK+LvPfLn8NxgsN0rqhvtjuXS39W8/LGO9lsQXbdyPBERtdYMCQ07ZAimP3BsP52yyaK39qt/GmzssLa29lGSI4jtt23bZs8EukMj22B94sdiGrUhVuKL91a30wljjydWOsfhUmwLibcg+maT5po9z0i+wRjnhGrLrWcb44RQNqoTAREQAREQAREQARGIIwHE2t+Iv45Xl+xuRvX/AjP2hcTj4zW++hGBeBHQLeB4kVQ/IiACIiACexUBxNrp7NDZjzWf3lzH2Pm7jj6i/n+BaWNvSi+j/ZnsVH6XXddrmuuL2otAPAjoFnA8KKoPERABERCBvYoAu26fIv5m4FQxt3/dt5qj9hMhGev/C2y30A/DjzN5I3qJxF/U6NUggQS0A5hAuOpaBERABEQgOQQQfQfGa2Se44vp/wXmh7KP5VnI+fjxP3YAz+BFmw/5EegP4+WX+hGB5hCQAGwOPbUVAREQARFIewLcuo3p/wWm3ee8hPMMb1PnISJPBNS/0h6WJigCIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACexeB/wf3xunklwzXVQAAAABJRU5ErkJggg==\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<matplotlib.text.Text at 0x1208b00d0>"
|
|
]
|
|
},
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Reaction mechanisms can contains thousands of elementary steps. Choose a threshold\n",
|
|
"# to see only the top few\n",
|
|
"threshold = 0.03\n",
|
|
"\n",
|
|
"firstColumn = sensitivities.columns[0]\n",
|
|
"\n",
|
|
"# For plotting, collect only those steps that are above the threshold\n",
|
|
"# Otherwise, the y-axis gets crowded and illegible\n",
|
|
"sensitivitiesSubset = sensitivities[sensitivities[firstColumn].abs() > threshold]\n",
|
|
"indicesMeetingThreshold = sensitivitiesSubset[firstColumn].abs().sort_values(ascending=False).index\n",
|
|
"sensitivitiesSubset.loc[indicesMeetingThreshold].plot.barh(title=\"Sensitivities for GRI 3.0\",\n",
|
|
" legend=None)\n",
|
|
"plt.gca().invert_yaxis()\n",
|
|
"\n",
|
|
"plt.rcParams.update({'axes.labelsize': 20})\n",
|
|
"plt.xlabel(r'Sensitivity: $\\frac{\\partial\\:\\ln{S_{u}}}{\\partial\\:\\ln{k}}$');\n",
|
|
"\n",
|
|
"# Uncomment the following to save the plot. A higher than usual resolution (dpi) helps\n",
|
|
"# plt.savefig('sensitivityPlot', dpi=300)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.5.2"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|