From 5aed85d8cdc3301c9f9a68d89d21ae7b1bf1658f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Wed, 15 Mar 2023 20:26:21 +0100 Subject: added env var TTL COOLDOWN TOOMUCH --- analiza/zvezek.ipynb | 6868 +------------------------------------------------- radio/radio.py | 95 + src/bencoding.c | 6 +- src/dht.c | 28 +- src/main.c | 21 +- travnik.py | 5 + 6 files changed, 177 insertions(+), 6846 deletions(-) create mode 100755 radio/radio.py diff --git a/analiza/zvezek.ipynb b/analiza/zvezek.ipynb index c4d32a2..bf864bd 100644 --- a/analiza/zvezek.ipynb +++ b/analiza/zvezek.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "7e32a042", "metadata": { "scrolled": false @@ -15,7 +15,7 @@ "......\n", "fixed bad single file torrent 4f269d8aefd647ee270842d53ec98aebd23a4afe\n", "fixed bad single file torrent 7b09ae0b612dafc1744562dccbbe4becf4d633c3\n", - "47843 @ 723.5033559300937 s\n" + "47843 @ 78.78622500100755 s\n" ] } ], @@ -39,18 +39,34 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "a4419e5e", - "metadata": {}, + "execution_count": 7, + "id": "978ab1cf", + "metadata": { + "scrolled": true + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "5.509342634119093 torrenti so se zbirali 16.265196759259258 dni. en torrent je bil najden v povprečju na 29.373429759839475 sekund, v 47843 so metapodatki 3084321 datotek v skupni velikosti 259.2602232018344 TiB\n" + "...\n" ] } ], + "source": [ + "from travnik import Type\n", + "for hash, torrent in torrents.items():\n", + " if torrent.type == Type.HYBRID and not torrent.dict.get(b'info').get(b'meta version'):\n", + " print(torrent.sha1.hex(), torrent.sha256.hex())\n", + "print(\"...\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4419e5e", + "metadata": {}, + "outputs": [], "source": [ "s = monotonic()\n", "prej = None\n", @@ -72,1000 +88,12 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "e170de45", "metadata": { "scrolled": false }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8.196780784986913 za 70 različnih odjemalcev\n" - ] - } - ], + "outputs": [], "source": [ "s = monotonic()\n", "def uas(normalize=True, minrepr=0):\n", @@ -1110,1047 +138,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "52de34d6", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.2505375409964472 s 41\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 [1, '', '93f549c401bebe4f86ef23626e0fed3d06183b02']\n", - "5555555 [1, '555555555555555555', '93f549c401bebe4f86ef23626e0fed3d06183b02']\n", - "name.utf8 [1, 'Connections', 'a23296ce90328791cb6974cf6f6306da4dd89735']\n", - "unique_torrent [1, 1, '2c3ea79de0771079e41fc25f4cabf23e11041829']\n", - "www.baidu.com [1, 'www.baidu.com', '43b238596c66575e7dfcd4d5b1d0fadb6c393adc']\n", - "entropy [1, 1460043970, '0635e6c7d348c2603501e9fa53e4cf07f9e31b5e']\n", - "license [1, OrderedDict([(b'creative-commons', OrderedDict([(b'attributionAuthor', b'Dave Doobie Aaron'), (b'attributionTitle', b'Doobie'), (b'attributionUrl', b'http://fb.com/doobiebrooklyn'), (b'licenseUrl', b'http://creativecommons.org/licenses/by-nc/4.0/')]))]), '1d670c41fd340c8ee280157400744402740fc1fd']\n", - "还 [1, '百度', '647e1210953d6080f714f0f8dabffe6ee9852800']\n", - "originator [1, b'0\\x82\\x03:0\\x82\\x02\"\\x02\\x01\\x010\\r\\x06\\t*\\x86H\\x86\\xf7\\r\\x01\\x01\\x05\\x05\\x000L1\\x0b0\\t\\x06\\x03U\\x04\\x06\\x13\\x02US1\\x0b0\\t\\x06\\x03U\\x04\\x08\\x13\\x02CA1\\x170\\x15\\x06\\x03U\\x04\\n\\x13\\x0eBitTorrent Inc1\\x170\\x15\\x06\\x03U\\x04\\x03\\x13\\x0ecom.bittorrent0\\x1e\\x17\\r140520235304Z\\x17\\r160509235304Z0z1\\x0b0\\t\\x06\\x03U\\x04\\x06\\x13\\x02US1\\x0b0\\t\\x06\\x03U\\x04\\x08\\x0c\\x02CA1\\x170\\x15\\x06\\x03U\\x04\\n\\x0c\\x0eBitTorrent Inc1\\x1f0\\x1d\\x06\\x03U\\x04\\x03\\x0c\\x16com.bittorrent.bundles1$0\"\\x06\\t*\\x86H\\x86\\xf7\\r\\x01\\t\\x01\\x16\\x15neteng@bittorrent.com0\\x82\\x01\"0\\r\\x06\\t*\\x86H\\x86\\xf7\\r\\x01\\x01\\x01\\x05\\x00\\x03\\x82\\x01\\x0f\\x000\\x82\\x01\\n\\x02\\x82\\x01\\x01\\x00\\xdc\\x88\\x0ePoR--\\xadlr\\xdf\\xdb*\\xf7u\\xb2\\xac\\xe2-m\\xb0y\\xc5K\\x0f\\x84\\xaf\\xedj\\xe9\\xad\\x88:\\x00\\xe8VK\\xef\\xce\\xf1\\r\\x83\\xb6\\x0c\\xb9n\\xdf\\xc2X\\xae,\\xbdOf\\xb2j*l~\\xaeO\\xc6V\\x81\\x04\\x03\\x11R\\x12\\x03t\\x02\\xda\\xc7\\x1d\\xb1\\x1b\\xe8\\xed\\x88Z\\xcc|\\xb5\\xc0IZuY\\x1b\\x9c\\x93\\xde\\xa1\\xe1\\xadFR\\xc6\\x1d\\xbd\\x80\\xf6\\xc1zV\\xa2\\x8c\\xa2\\xd90\\x06\\xe1.\\xc2\\xc3e\\x15\\xfc,5ki\\xa8\\x87i\\xbe[\\xb4`\\xc9-\\x81\\x81w\\x1d\\x811\\xb4y\\x97\\xda\\x81L\\xe6\\xces\\x9b\\xd0\\x7f\\x9e\\x93\\xffZ/\\xe2R\\x8fIP4&=ia^\\xe9\\x9c\\xbf{\\xc3\\xce\\xf3\\x9a\\x06\\x04\\xf0I\\x11\\xfb\\xc1\\xb9U8v:\\xad87\\x9a\\xeb\\xad\\x1d\\x90\\xa7\\xeb#\\xce\\x81PPXct\\x80\\'\\x8dv,Y}|\\x1b\\xb3F\\xe1\\xeb\\x85\\xd2Y\\xe7\\x9f\\x8c\\xb1y\\xa2\\xeb\\xd2\\x9aU\\x8b\\xc2\\x05\\xf3zpQ\\xf4\\xd4\\x18$\\xc1\\xc2\\xfc{1J\\x1f\\x8c\\xa7\\x0efM,\\'\\x02\\x03\\x01\\x00\\x010\\r\\x06\\t*\\x86H\\x86\\xf7\\r\\x01\\x01\\x05\\x05\\x00\\x03\\x82\\x01\\x01\\x00\\x1e}\\xb1\\x9f\\x8e\\x07L\\xaa\\xd2\\xb5\\xe0eR\\xe9\\xfb\\x18t\\xf7rJn~\\xe5%\\xc1\\x8d\\xa1\\xa5>\\xbe#Q\\xed\\x17x\\xa4B\\x83M\\x1eg\\xef\\x1dbt\\t\\xcc\\xd7\\xca\\x10\\xb2\\xad_\\x02\\x07#\\x08g7\\xae\\xf3\"\\xc9\\xd5v:#)?e\\x98\\xd4\\xe6\\xd2@u\\x7f\\xbac\\xf7\"\\xa4]\\x81k\\xca-\\xe3\\x08\\x18\\x8e$\\xf3c\\xa0\\xd4\\xd3\\xf6**\\xf4\\xe2\\xe1W|f\\xea\\xfd\\xb7\\x12E\\xa3D\\xa2+.`\\xb3V\\x04.!H\\xeb\\xcet\\x84\\x08\\xfc\\xde\\x1c\\x85\\x1e\\xdf\\x04n2?\\x03\\xdc\\xd35\\x10S9\\xd1\\x8d\\x92\\x9c)#\\xfd8\\x97\\xe5\\x87\\x0c\\xe7\\xc7\\xcf\\x8a\\x91\\xef9H\\x83\\xecaK_e9_\\xf9\\xef\\xd3q\\x03\\x05\\x13\\xb6\\'\\x8f\\xb3\\x1c\\x03[\\x99\\xa5T\\x84I\\xcc\\xdb\\xdc^\\x05S%\\x85\\x17!\\xc6\\xaa\\xa6\\xc0\\x0f\\xff%\\xcf\\xf3\\x10]\\xc0Q\\x94]\\xbfD\\xc3\\xf9\\xb5s\\xe6\\x99\\xa2\\xa3\\xf0\\xb0#\\xa9_\\xbbze\\xe1\\xc9\\xc9\\xe8I\\xdb\\xd8\\xbe\\tB\\xa6\\xecQ\\x87\\xca\\x0c\\xe2\\x8e%\\xd8\\xcc', '058b52ccb029e60a355edcfe498e8eb44812e3f1']\n", - " [2, 1, 'fa6fbc7d7796e49fbdf47731fe06a6e20ee74bb5']\n", - "abc [2, 'abc', '9c8047972d058dee41bab8ab68ad5da7c24275ed']\n", - "nnm-club_cool [4, 1, '57f6facb1bcef159b8075b578053fb4790e0c8d5']\n", - "tracker [8, '', 'e8ca2609b174df7b5c26538fb6f96d77a367da42']\n", - "x-amz-bucket [10, 'quranwave', '3af8e25c9eeca9402351820d8681fe0945c63cdb']\n", - "x-amz-key [10, 'torrent/70.zip', '3af8e25c9eeca9402351820d8681fe0945c63cdb']\n", - "attr [14, 'h', 'c9a279c4dff3b38ef806abb98515382798907654']\n", - "unique [14, 'fbvPqZTXkKQzRJzy6LXkdIp3iJoTNe', '3a84117d98683bd4a657a37932886d206486c11e']\n", - "comment [15, 'Torrent downloaded from torrent cache at http://torcache.net/', 'e92cd8e1ed1defad6d5211a42d2dbdf1e368b834']\n", - "sha256 [18, b'\\xfe\\x01\\x01\\xa4\\xf5Z\\xcd\\xa4\\xd9\\t\\x7f\\x8d\\x1c\\x9d\\x1a\\x89\\xdcV\\x9e\\x92\\xd6A\\xbf\\xf9\\x81\\x9a\\xea^\\xc8\\xcfT\\xcf', '1c565cb3249a8da64dbf7a82b3ed39e637e6e239']\n", - "creation date [55, 1400017482, '4488d559d4404875022d53c6039b0025c947ac84']\n", - "cross_seed_entry [55, '02e940fec782a353d2e767cecde08041', 'b7c0ac4a9834c8e39f543f3f721eb90fbb58e179']\n", - "md5sum [56, 'e27e7b621f0adbcf072e4f13d78c4fc8', 'ef0c6b03d16457e1134bc63c18d527221639da8e']\n", - "file tree [95, OrderedDict([(b'01 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 306045), (b'pieces root', b'\\xc6\\xaa\\xb3/\\x00\\xb3\\xe8V\\xc8\\xc2\\xa7\\xdd\\xe9\\x1b\\x8c\\xe4\\x80\\x91\\xa6\\x0e\\x9c\\xfe\\x92\\x0eck<\\xca\\x02\\x9b\\xdam')]))])), (b'02 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 11369005), (b'pieces root', b'\\xd9=I\\xd6\\x8cN\\x17tch:Si\\xb1\\x12a9h1\\xf3\\x0b\\x06\\x8f\\xe5q\\xab\\xb7\\x00\\x18O\\xe2\\xac')]))])), (b'03 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 18234404), (b'pieces root', b'3\\xb4\\xf0\\xbc\\x80\\xb5\\xa2\\x14\\xc02\\xf1\\xd4\\xc9\\x95\\xae [\\x07\\x08\\xdc\\x12j\\xcdA\\xa4{\\x9f\\xe3\\xf04g\\x83')]))])), (b'04 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8120626), (b'pieces root', b'\\xd4\\xbf$\\xadv\\xfb\\xafW\\xa01\\xcf\\xb1\\x83\\xe1\\xecW\\x90\\x01\\xcd\\xd5\\x7f\\xcc\\x02wv\\xcd\\x18\\xda\\xa3\\x00\\x1d\\xdd')]))])), (b'05 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 15192077), (b'pieces root', b'8\\xe3B\\xc5kK\\x18g9\\xaf\\x7f[\\xcf}\\x193\\x8d\\x9d\\xa3\\xdf\\x9c\\xfc\\x04\\x9a5\\x02\\xdf\\xf1\\xc3\\xbd\\xc9\\x02')]))])), (b'06 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 19926721), (b'pieces root', b'\\xb3\\xd90a!a\\x01\\x1aYr\\xf2\\x11\\xb4\\xd5\\xcc\\xe9\\xdb4G\\x8fX9ja\\xf2\\xf8\\x0c\\xb9\\xdbq\\xcdF')]))])), (b'07 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9389134), (b'pieces root', b'k|\\x0e\\xaf\\n\\xc3&,Z\"\\x95\\xe2\\xa0(\\x83\\xa8\\x91\\x8a\\xdc\\xb3\\xf5\\xebi\\xfbR\\x9b\\xfc\\xe6G.\\xbaC')]))])), (b'08 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 11024608), (b'pieces root', b\"\\xc3,\\xd6/\\xf9F;!'5\\xdbl2\\x94\\xaf\\xf6\\n\\x86\\xc0\\x1b\\x08\\xe5\\t\\x97\\xa7\\x8b\\x04\\xb8\\x82\\xb2\\x87<\")]))])), (b'09 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 18047158), (b'pieces root', b'\\xe1&\\x0f\\x08\\xe4\\xa5|E\\x1e\\x11\\x9a\\xfe\\x9d\\xe5u\\x19\\x86S\\x0b\\x055\\x83\\xfe\\xf0.\\xfd\\xb1\\xf4\\x00\\xaf:\\xd4')]))])), (b'10 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 12329479), (b'pieces root', b'V\\xbf\\x88\\x17\\xb7\\xe3\\xa73\\xfaF-@ut.;\\xf2\\xb0R\\xe7\\xd4J*\\xa6\\xbe\\xa51*\\x8b^\\xc1\\xbd')]))])), (b'11 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8220520), (b'pieces root', b'\\xd8\\x92bdA]r3&\\x83\\xa1J0\\xc2\\x01,\\x93\\xf6\\xd7\\x1d\\xf5;\\x12\\xfd\\xd5[\\xc9\\x86\\x98\\xa1\\x93\\xc9')]))])), (b'12 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 14647898), (b'pieces root', b\"\\x037\\xe1\\x17\\x02\\xb5\\xe89\\xd1RO\\x94\\t\\x98\\xb7\\x19:\\xbeF\\x13\\x9f\\x88\\xbc\\xbfC\\xdaE\\x82'iD\\xd2\")]))])), (b'13 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9183082), (b'pieces root', b'\\x1c\\x88\\x18\\x03\\x0e2\\x94\\\\Y\\xb4\\xcb\\x87\\xea\\x9a\\xe9\\xfcj\\xb3z\\xa0\\x1f\"P\\x06*\\xee\\xfa/6\\xb4\\x1eO')]))])), (b'14 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8584563), (b'pieces root', b\"\\x11\\x88\\xb1\\x80\\xb1\\x9a\\x06t'\\x80\\x15p\\xfa\\x17\\xcf\\xdej\\x93\\x82}%$\\xd49\\xf1\\x7f\\xb1\\x14\\xb1}\\xde\\xe5\")]))])), (b'15 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8667736), (b'pieces root', b'\\xfb\\x1a\\x130JY\\xc7\\x86\\x07\\x89\\xa8\\xaa\\xc2\\x97\\x0e6(\\xe0\"\\xe7)\\xa0z\\xbb\\x98\\xf2S\\x82\\xd4\\xe1e2')]))])), (b'16 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8380183), (b'pieces root', b'*\\xe4\\x92\\xc4\\xca.\\xd8\\xc7s\\xa0\\xe7\\x16\\x0f\\xec\\xb5\\xd4\\xc9\\xf8\\x8e,\\x1d\\xc9\\x97\\xad$\\x9d\\xa7\\\\\\x82\\x18\\x80O')]))])), (b'17 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 10952719), (b'pieces root', b'\\xc3s\\x18\\xd5\\xc97\\x19T\\x14[\\xe6\\x98\\x93\\x9b>\\xcb\\x82\\x92\\xa9rgl\\xc2\\xe5ny\\x92\\x0b&]\\xa2\\xcb')]))])), (b'18 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 18408693), (b'pieces root', b'\\xdf\\xe7<\\x94\\x97\\xa5\\x06\\t!\\xc9\\x00I\\\\\\xd9Q\\xffu.u\\xdd\\xae\\xdd\\xe4t\\x04V\\xe9\\xcb\\x84\\xd4\\x0e\\x02')]))])), (b'19 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 17103827), (b'pieces root', b'-\\xda/\\x9e\\xee\\xe50\\xbb\\x8cv\\xdc\\xf99\\xfco;rw\\x9e&\\x13\\xa3\\xd0\\x15\\xd6]\\xbc\\xe6P\\xbd\\xe5\\x95')]))])), (b'20 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9902808), (b'pieces root', b'J\\xb3\\x7f\\xd1lq\\x8f!\\xce\\xfa\\x9b\\x03\\xb7*\\xbaT\\xfd^\\x83\\xb5\\xd1\\xe1x\\n|I?&\\x7f3\\xf6s')]))])), (b'21 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 16769039), (b'pieces root', b'\"\\xdf\\xf8\\x99&\\xd8\\x81\\xe6HO\\xe2\\xb8L\\xfe\\\\pum\\xca<\\x17\\xd6\\x93\\x9a$\\x989v\\xf3($\\xc4')]))])), (b'22 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 15115177), (b'pieces root', b'n\\xb3+H\\xe9\\xe8b[\\xe7\\xa5\\x18\\x82\\xb1\\x9d49\\xb2 \\x80\\xcb@\\x11\\x9e\\xd0\\xe0\\x10\\x1dx\\x04ki\\xa2')]))])), (b'23 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 11751439), (b'pieces root', b'\\xb8\\x96r\\x8b\\x99\\x08Lc\\xeaa\\n\\xf9m \\xd8\\xd1i\\xc9\\xeb\\xe5=\\xcc\\xbd\\x95\\x86\\x1b~\\x00U\\xa7\\xfe\\xaf')]))])), (b'24 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 10140209), (b'pieces root', b'\\x91\\xdf\\xd9\"\\x9aE1[\\xc4\\xe3;\\xb3\\x13\\x85\\xa0\\xca \\xab\\xf9\\xd6\\xfdG\\xa9\\xeb\\xd4\\xf6Z\\xb5\\xdf\\xad\\x16:')]))])), (b'25 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9116207), (b'pieces root', b'\\x9c~\\x9c\\x08\\\\f*\\xf85\\xac\\xc8Yh\\xc6\\xdeZ\\xe4\\x85\\xf5l\\x82lc\\xa2\\t\\xdfG\\xc2Isv\\xed')]))])), (b'26 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 16717632), (b'pieces root', b'\\xb7\"1vkY\\xbe\\xcd\\xc6\\xb4Ip\\xb8\\xb1}\\x9e\\x12\\xd9\\x06\\x1d\\xa3b\\x01#\\xbf\\xe3\\xcd\\xea\\xa8\\xb2\\xfc\\xd3')]))])), (b'27 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 12950148), (b'pieces root', b'\\xe3\\x93P\\x959h\\xc1\\xfb\\xa6\\xfe\\xb3\\t\\xc9\\xf96\\xe4\\x93-s\\xd7\\x9cm\\xf6\\x15\\xc4Z\\xddZ4\\xb9\\x97\\\\')]))])), (b'28 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 15921002), (b'pieces root', b'v\\xceh\\x0e\\x9b;\\n\\xb1\\xb0\\xf4\\xf2/7\\xee\\xab\\x9c\\x1boz\\x99y\\xb4\\x1f\\xd0h\\xac\\xdf_ \\xc9\\xc7\\xd1')]))])), (b'29 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9768641), (b'pieces root', b'\\xc9s}\\xae\\x99S\\xb8\\x83<\\xc6\\xb1\\xd8\\xf7\\xffR\\xa6\\xcbT|\\xeb\\xee\\xdeG\\xfeX*\\xe2\\xc1\\x12\\x90\\xbd\\xd8')]))])), (b'30 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 6324241), (b'pieces root', b'\\x02\\tB\\xed\\x80\\xf9T(\\xd9~\\xed\\xd3(\\xd9\\x90\\xc5\\xac\\xd6\\xc0\\xb0#\\x89O\\x1d\\xcc\\xe2i\\xaa\\xf2\\xa1=|')]))])), (b'31 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 15366368), (b'pieces root', b'm\\xc2\\x90\\x94\\x90\\xf4\\x01\\xef\\xdf\\x82\\xa6\\xc8\\xfe\\xee\\xc7\\x06*1\\xa6\\xc2\\xe1\\x8e9\\xf7\\x10\\xaa\\xf6Ra\\xc6\\x1e\\x06')]))])), (b'32 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 14097446), (b'pieces root', b\"\\xbf\\xe8\\x14\\x15\\x13\\xb1xT\\xef\\x19\\xe5Dmh\\xd48<\\x93$\\xca\\xc9\\x92\\xedX\\x01\\xb4\\xda\\xf1\\xf0\\xd7\\xdc'\")]))])), (b'33 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 8691562), (b'pieces root', b'H\\x12\\x831\\x18MfTp\\xe1!\\xb6\\xaf)3\\xb5\\xfa\\xad\\xaf\\xd6\\xd1\\x94X\\x8a\\xea\\x17\\xc2\\xbb\\xa8\\xda\\xf6\\x16')]))])), (b'34 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 18585492), (b'pieces root', b'\\xd6x\\xafd\\xfc\\xdd\\x9c,\\x95\\xdd>\\xbaE\\x03\\x11\\xbf\\xdb\\x80\\x9a\\x8b?\\x91\\xdf\\xe2o\\xa1\\x7f k3\\xf9}')]))])), (b'35 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 14333175), (b'pieces root', b'\\xe1\\x04\\xa9\\x8ah\\xa6W2\\xd5\\xb7\\xf7\\x11*\\xd0\\x82\\r\\x1b\\x11\\xafq\\\\\\x86C(\\xfa\\x99\\xb3\\xdc]\\xee\\x04\\xf0')]))])), (b'36 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 16783668), (b'pieces root', b'\\x9a\\r\\x10j\\x87Z.g\\x95I+D\\xcd,w\\x83\\xd1F\\x16\\xa7\\xd0\\\\`7\\xfbZ:3\\xa1\\x19%t')]))])), (b'37 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 19032708), (b'pieces root', b'\\x07\\xf9\\xb6\\x9cW\\xbb \\\\0\\xf6B=\\xf74\\xf9\\x1cO\\x0b\\xe6\\x93_\\xe0\\xb1O\\xf2\\x82yL\\xc8\\xdc{\\x8e')]))])), (b'38 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 14793348), (b'pieces root', b'-m\\x9b\\xa0\\x02W,!\\xe2\"Bjb\\xcc\\xe0\\x104\\xb5\\xfen\\xb8\\xed\\xfe\\xda\\xe0\\x1fZr\\x89\\xf5$\\xf6')]))])), (b'39 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 9859340), (b'pieces root', b\"G\\xedO\\x8c\\x80\\xd6\\xf3\\xa1CGP\\x13\\x03\\xc7\\x9fI\\xd7Y\\n\\xf1v\\xd8'\\xb3$9:/a\\tg\\xfa\")]))])), (b'40 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 21681312), (b'pieces root', b' W\\xcd\\xcc\\xb9<\\x11\\xbc\\x0e\\x9e\\xfcm\\x04;\\x98^\\xd8\\xb0QvA\\x1c\\x81&\\xb8\\x16\\xb0+\\x1enB\\xfd')]))])), (b'41 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 13917724), (b'pieces root', b'm\\x7f}\\xbb#\\xb9\\xaf7\\x95\\x94\\x88Y\\xfe<\\x15\\x8a\\x1c\\xa1\\xdd9\\x93nK\\x8b/\\xcchX\\x1d\\xce\\x16\\x95')]))])), (b'42 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 14964290), (b'pieces root', b'Kk]\\xbe\\xef9\\x12\\xe4\\xd4u\\xafaN\\xde\\xfbD\\x80E\\x1a#|o\\xe3\\xb4\\xdd/dvB\\xbd\\xd7u')]))])), (b'43 - King of Alchemy - Simon Archer.mp3', OrderedDict([(b'', OrderedDict([(b'length', 421404), (b'pieces root', b'XE\\xb8\\x05Ih\\x80\\xd2L$j\\xe8\\x88h\\xcd\\x1d\\xafhs\\xa8\\xdd\\xfc\\x08\\xba\\x19\\xb6\\xd4\\xc4I@`\\x92')]))])), (b'Simon Archer - King of Alchemy.m3u', OrderedDict([(b'', OrderedDict([(b'length', 6855), (b'pieces root', b'\\x8e\\x90\\x18t\\x8e\\xe8\\x8f\\x11\\x01EY\\x86\\xac\\xb8\\xa5\\x9d\\xce\\xf0\\xe6\\xf0\\x01k\\xf0\\xcfu]YN\\xf5bv\\x9e')]))]))]), '44b84847f7d829225c788e161017e484526e5259']\n", - "sha1 [109, b'\\xbe^\\xdc\\xd8\\x99\\x98\\xf0\\xe8_\\x8d\\xcbZ\\xc7\\xd21\\t`\\xec\\x9c\\xee', 'b4bf549d9d48bce1c1e026ff451ee76069b98c00']\n", - "collections [119, [b'org.archive.relaxingsounds'], 'ed7d4e9657cbfcde6baf89ace313ae77a1cefe91']\n", - "meta version [298, 2, '18d35502fca02a30811e4e001809ddd4147167e6']\n", - "filehash [314, b'\\xc9m.\\x93\\xbd\\x18fj:\\xb3${\\x9ak\\x9e\\xdbUI\\xf2\\xb5', '44af4eb9d35b94218b6fe5eb25a30b8e22fa5844']\n", - "ed2k [399, b',\\xf0O\\x9e\\x829\\x8e\\x1b{\\xf58\\xea\\x94\\n\\xe8\\x92', '44af4eb9d35b94218b6fe5eb25a30b8e22fa5844']\n", - "source [908, 'BT世界网 https://www.btsj6.com/', '417ef639eb95fbf68175a6a6b03076f9ee5f5744']\n", - "file-duration [1283, [0, 0, 39097], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", - "file-media [1283, [-1, -1, 0], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", - "profiles [1283, [OrderedDict([(b'acodec', b'aac'), (b'height', 0), (b'vcodec', b''), (b'width', 0)])], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", - "publisher-url.utf-8 [1766, 'http://my155.cc', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", - "publisher.utf-8 [1830, '小隻馬', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", - "publisher-url [2602, 'http://my155.cc', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", - "publisher [2746, '小隻馬', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", - "name.utf-8 [3724, '60 Assorted Magazines Collection PDF September 4 2022 Set 3', '449a9e0e7375b6b6b7f55bdd6214f034a2edd4b8']\n", - "private [5625, 0, '449f65629260c258a999e6474f22ae00e83ee47a']\n", - "length [15890, 5209971966, '449a38ef7e042bd2d75e8921aa02f6f244165d9d']\n", - "name [47843, 'Big Buck Bunny', 'dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c']\n", - "piece length [47843, 262144, 'dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c']\n" - ] - } - ], + "outputs": [], "source": [ "s = monotonic()\n", "keys = {}\n", @@ -2180,1859 +173,12 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "fea0f2b6", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.10204320191405714 s 92.3207156741843 brez ključa source, publisher, publisher-url ali comment 854 virov\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "163 \t PMEDIA\n", - "130 \t http://tapochek.net/index.php\n", - "122 \t 高清下载吧!\n", - "122 \t https://FreeCourseWeb.com\n", - "93 \t 灣搭拉咩拉\n", - "88 \t 脫拉庫\n", - "82 \t 第一會所新片@SIS001\n", - "79 \t 大师兄福利网\n", - "77 \t 2048\n", - "75 \t 1024社區最新地址\n", - "74 \t \n", - "64 \t LostFilm.TV\n", - "47 \t [https://tanhuazu.com] 探花族社区\n", - "46 \t 2048核基地\n", - "44 \t https://hjd.tw\n", - "43 \t 1024核工厂\n", - "42 \t RV原创\n", - "41 \t 1024社區\n", - "39 \t 小贾_KTXP\n", - "37 \t 國產精品\n", - "36 \t 麻豆之神\n", - "34 \t 吃雞大神\n", - "34 \t b48t.com\n", - "33 \t https://crackshash.com/\n", - "33 \t 老含及\n", - "31 \t 欧宝\n", - "30 \t https://rh2048.com\n", - "27 \t 小隻馬\n", - "27 \t 1024\n", - "27 \t AV大平台\n", - "26 \t @蜂鳥论坛@\n", - "25 \t Weagogo\n", - "25 \t 第一會所新片\n", - "25 \t JAV Torrent 掲示板\n", - "22 \t 发发发\n", - "21 \t 刷刷刷\n", - "21 \t https://1tors.ru/\n", - "20 \t 1024工厂\n", - "20 \t hjd.tw\n", - "19 \t 不予\n", - "17 \t 小樱\n", - "17 \t (美女裸聊直播 uur68.com)\n", - "17 \t xue0117\n", - "15 \t 美女裸聊直播\n", - "15 \t xp1024\n", - "15 \t 老司机论坛\n", - "15 \t b'\\xcf\\xeb\\xb7\\xa2\\xc8\\xb4\\xb2\\xbb\\xbb\\xe1'\n", - "14 \t olo\n", - "13 \t nyaa001\n", - "13 \t b'dioguitar23(\\xb2\\xc4\\xa4\\xbb\\xa4\\xd1\\xc5]\\xa4\\xfd)\\xad\\xec\\xb3\\xd0'\n", - "13 \t https://discord.gg/vbJ7RTn\n", - "13 \t PiRaX @ TamilBlasters.Net\n", - "13 \t 愛在黑夜001\n", - "12 \t b'\\xb3\\xcc\\xb7sAV \\xa4\\xd1\\xaa\\xc5\\xbd\\xd7\\xbe\\xc2 IP'\n", - "12 \t Zamunda.NET\n", - "11 \t [animelayer.ru] Animelayer\n", - "11 \t 發片小王子@18p2p\n", - "11 \t https://infocon.org/\n", - "11 \t 约战竞技场\n", - "11 \t orion\n", - "11 \t 規懶趴會\n", - "10 \t BT世界网 https://www.btsj6.com/\n", - "10 \t threesixtyp\n", - "10 \t U6A6磁力搜索---U6A6.COM\n", - "10 \t cangkong\n", - "10 \t dioguitar23(第六天魔王)@dioguitar23.net\n", - "10 \t 0\n", - "10 \t BBVC\n", - "9 \t dio88.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "9 \t 1024核工厂/\n", - "9 \t 百撸社区\n", - "8 \t Zelka.ORG\n", - "8 \t b'\\xc1\\xf9\\xd4\\xc2\\xc1\\xaa\\xc3\\xcb'\n", - "8 \t 百撸社区|高清资源\n", - "8 \t dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "8 \t x\n", - "8 \t buxxa\n", - "7 \t [tp.m-team.cc] M-Team - TP\n", - "7 \t PMEDIA NETWORK\n", - "7 \t 6969bt.com\n", - "7 \t www.dio8899.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "7 \t BT-btt.com\n", - "6 \t Mp4Ba\n", - "6 \t 性吧RV原创\n", - "6 \t K8bet\n", - "6 \t Burnbit\n", - "6 \t 94i88影城-点击跳转\n", - "6 \t hotaru\n", - "6 \t b'\\xb7\\xf6\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1 dioguitar23 \\xad\\xec\\xb3\\xd0'\n", - "6 \t 00armand00\n", - "6 \t 么么哒\n", - "6 \t https://www.javhdbbs.com\n", - "6 \t XP1024\n", - "6 \t [https://majomparade.eu]\n", - "6 \t 鱼香肉丝\n", - "6 \t Hotaru\n", - "5 \t atrrea\n", - "5 \t rutracker.org\n", - "5 \t olo@SIS001\n", - "5 \t 广东雨神\n", - "5 \t b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1~\\xc5]\\xa7\\xd9\\xad\\xec\\xb3\\xd0'\n", - "5 \t YURASUKA\n", - "5 \t ♥im520♥\n", - "5 \t arsenal-fan\n", - "5 \t [http://x-torrents.org] X-Torrents.org\n", - "5 \t arsenal-fan@avsp2p.com\n", - "5 \t 1stDragon\n", - "5 \t dioguitar23(第六天魔王)@mw6.me\n", - "5 \t 成年人的小游戏\n", - "5 \t 99BT工厂 @ 5120911\n", - "5 \t HiHBT 精品薈萃\n", - "5 \t https://www.1024btgc.com\n", - "5 \t hhd800.com\n", - "4 \t 杏吧论坛\n", - "4 \t zgome@18p2p\n", - "4 \t 顶冠文化\n", - "4 \t XIU\n", - "4 \t b'\\x9e\\xb3\\xb4\\xee\\xc0\\xad\\xdf\\xe3\\xc0\\xad@kb978.com'\n", - "4 \t https://downloadcursos.top/\n", - "4 \t youiv\n", - "4 \t yoy123\n", - "4 \t 上善若水@www.sexinsex.net\n", - "4 \t RZK\n", - "4 \t Torrent downloaded from torrent cache at http://torcache.net/\n", - "4 \t 魔王之家\n", - "4 \t rxrj\n", - "4 \t 杏吧\n", - "4 \t dio66.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "4 \t 更多精彩!尽在99BT工厂@5120911\n", - "4 \t xueru10405\n", - "4 \t 1030社區---1030.ws\n", - "4 \t www.crackshash.com\n", - "4 \t nyaa.si\n", - "4 \t M88(明陞)\n", - "4 \t www.dio7777.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "4 \t GF@1024核工廠\n", - "4 \t Western/HD-Jiggly\n", - "4 \t 【RV原创】【sex8.cc】\n", - "4 \t kenelm\n", - "4 \t https://DesignOptimal.com\n", - "4 \t >亞捷視圖<\n", - "3 \t m6688.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "3 \t 1314\n", - "3 \t oldman原創DVD@18p2p.com\n", - "3 \t sogood@18p2p\n", - "3 \t ? nike ?\n", - "3 \t https://toonshub.xyz\n", - "3 \t 黑色点击\n", - "3 \t https://www.torrentdosfilmes.tv/\n", - "3 \t 1024社区\n", - "3 \t dioguitar23(第六天魔王)\n", - "3 \t 嗨咻阁\n", - "3 \t 枫雪动漫\n", - "3 \t 【神秘巨星CI】\n", - "3 \t dioguitar23(第六天魔王)@bbs.hotavxxx.com\n", - "3 \t GIF出处系列\n", - "3 \t https://www.terralibera.net/\n", - "3 \t dioguitar23@dio66.net\n", - "3 \t dioguitar23(第六天魔王)@hotavxxx.com\n", - "3 \t chikan\n", - "3 \t 神秘巨星CI\n", - "3 \t 萌你一脸@第一会所\n", - "3 \t 罗马教皇@草榴社区 luckjam@sexinsex.net\n", - "3 \t uid-346380\n", - "3 \t Download from Sajber.org/blog\n", - "3 \t 美女裸聊约炮\n", - "3 \t @微信订阅号专注稀有汁源\n", - "3 \t susun=eastv\n", - "3 \t bbvc\n", - "3 \t 草榴社区\n", - "3 \t rh2048.com/\n", - "3 \t www.javhdbbs.com\n", - "3 \t 2048核基地!!\n", - "3 \t 衣选集团\n", - "3 \t b'\\xc1\\xf9\\xd4\\xc2\\xcc\\xec\\xbf\\xd5'\n", - "3 \t Gfker@1024核工廠\n", - "3 \t b'99\\xa5\\xfd\\xa5\\xcd'\n", - "3 \t 18p2p by_UID 1380364\n", - "3 \t 漫之学园\n", - "3 \t https://bbs2048.org/\n", - "3 \t 9200\n", - "3 \t 安西教练\n", - "3 \t MingYSub\n", - "3 \t 尘封追忆+色十八\n", - "3 \t Downloaded from CracksHash.com\n", - "3 \t https://rutor.org\n", - "3 \t jav20s8.com/\n", - "3 \t [http://baibako.tv] BaibaKo.TV\n", - "2 \t MN Nambiar @ TamilBlasters.Net\n", - "2 \t 老司机\n", - "2 \t dioguitar23.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "2 \t https://media.defcon.org/\n", - "2 \t https://sexasia.net/feed\n", - "2 \t http://www.acgyinghua.com/\n", - "2 \t b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1 dioguitar23 \\xad\\xec\\xb3\\xd0'\n", - "2 \t Lucian2009@第一会所\n", - "2 \t www.dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "2 \t TYBBX2\n", - "2 \t roger92402094\n", - "2 \t https://downloadcursos.top\n", - "2 \t lxdng1218\n", - "2 \t 飘嫖\n", - "2 \t 红馆-红人馆-网络红人之家\n", - "2 \t CHANNEL NEO\n", - "2 \t ccc32.com\n", - "2 \t dioguitar23(第六天魔王)@dio999.com\n", - "2 \t 注册就送39元,联系:330545486\n", - "2 \t b'\\xb7\\xf6\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1@\\xb4A\\xab\\xbd\\xa8\\xe0'\n", - "2 \t ITELLYOU\n", - "2 \t Aidoru-Online\n", - "2 \t 联系TG:yyllzy,fulihuoqu\n", - "2 \t MP4BA电影网\n", - "2 \t 強片皇帝999\n", - "2 \t sogclub No.2\n", - "2 \t D2mp4\n", - "2 \t 【U6A6.COM】_全网磁力最快更新\n", - "2 \t mmklp@第一会所\n", - "2 \t ssss1111@18p2p\n", - "2 \t 感冒清@sis001\n", - "2 \t afnami@64.78.163.55\n", - "2 \t 1024核工厂最新地址\n", - "2 \t 11.55\n", - "2 \t 西門吹水\n", - "2 \t goldpuzjying\n", - "2 \t uid=1591117\n", - "2 \t [http://rudub.tv] RuDub.TV\n", - "2 \t https://to-url.com/torrent-igruha\n", - "2 \t 蜂鸟色区\n", - "2 \t b'\\xb3\\xc7\\xca\\xd0\\xefL\\xc7\\xe9~\\xc4\\xa7\\xbd\\xe4\\xd4\\xad\\x84\\x93'\n", - "2 \t 百撸社区|高清影片\n", - "2 \t [http://energy-torrent.com] Energy-Torrent\n", - "2 \t SoushkinBoudera\n", - "2 \t [http://bko.baibako.tv] BaibaKo.TV\n", - "2 \t 冷月无声\n", - "2 \t 奥利给\n", - "2 \t b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1~\\xa4p\\xb9t\\xad\\xec\\xb3\\xd0'\n", - "2 \t b'tanw\\xa9\\xceyk3325@www.sogclub.com'\n", - "2 \t 3Li\n", - "2 \t b'giogio99\\xad\\xec\\xb3\\xd0'\n", - "2 \t buxxa=bbvc\n", - "2 \t BradPitt\n", - "2 \t pin0314(1470)@www.mycould.com\n", - "2 \t b'\\xa4\\xc6\\xb0\\xa9\\xc0s@mimip2p'\n", - "2 \t 遁去的壹\n", - "2 \t 弄死你娃L@2018x.win\n", - "2 \t downloadcursos.top\n", - "2 \t KTXP_秋沫\n", - "2 \t Domaha.tv\n", - "2 \t 水母飄\n", - "2 \t 月岚星辰520@第一会所\n", - "2 \t xinnian\n", - "2 \t kaniuniu\n", - "2 \t dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "2 \t 清雨\n", - "2 \t www.loliba.info\n", - "2 \t crazylazy\n", - "2 \t 感冒清@sis001.com\n", - "2 \t 淘宝天猫优惠券秒杀\n", - "2 \t 会飞的象@第一会所\n", - "2 \t mule_by_SpeedPluss.ORG\n", - "2 \t bigwai\n", - "2 \t 深深可许@第一会所\n", - "2 \t BT伙计\n", - "2 \t 最新地址\n", - "2 \t judexkwok(SIS)\n", - "2 \t ntlv0@hotmail.com\n", - "2 \t sex8.cc\n", - "2 \t b'\\xb7\\xf6\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1~\\xaf\\xab\\xad\\xb7\\xa4p\\xa4l\\xad\\xec\\xb3\\xd0'\n", - "2 \t Betway(必威)\n", - "2 \t 天空树蜡香\n", - "2 \t 更多精彩!尽在99BT工厂\n", - "2 \t suchuanxia^@^18p2p\n", - "1 \t gnhyc11@18p2p.com\n", - "1 \t fyoulapk@18p2p\n", - "1 \t 塔卡小爹賽\n", - "1 \t HD一条街论坛\n", - "1 \t dioguitar23原創\n", - "1 \t b'\\xb3\\xce\\xbf\\xd5\\xd1\\xa7\\xd4\\xb0'\n", - "1 \t cnmzlwb\n", - "1 \t zb77@18p2p\n", - "1 \t https://www.asmr.one/work/RJ374870\n", - "1 \t [uid-1591117]\n", - "1 \t 奈特羅德\n", - "1 \t https://mega.nz/#F!DK4lCSwB!QdwaMCT3SpOxISAgnuX7nQ\n", - "1 \t 小葫芦@www.sis001.com\n", - "1 \t 柏林没有梦\n", - "1 \t ls611\n", - "1 \t qqtnt007\n", - "1 \t 3E523E31D247_by_FDZone.ORG\n", - "1 \t JPopsuki 2.0 626225292\n", - "1 \t https://elamigosedition.com/\n", - "1 \t guroemon\n", - "1 \t lyf634041775\n", - "1 \t 1234567890\n", - "1 \t https://bitnova.info/\n", - "1 \t asfile@SIS001\n", - "1 \t b'\\xbd\\xad\\xc4\\xcf\\xb7\\xe7\\xd3\\xea'\n", - "1 \t mikocon @ bbs.2djgame.net\n", - "1 \t http://mm.aayun.cc\n", - "1 \t aqcd123\n", - "1 \t 维尼\n", - "1 \t iii\n", - "1 \t pornolab\n", - "1 \t 极影字幕\n", - "1 \t b'\\xc9\\xab\\xd6\\xd0\\xc9\\xab@ypzhq\\xd4\\xad\\xb4\\xb4'\n", - "1 \t roger92402094(SIS)\n", - "1 \t erest\n", - "1 \t Baslilon=Baslilon23\n", - "1 \t sigma\n", - "1 \t 寂寞如漫天雪花\n", - "1 \t C:\\Users\\pongphon\\OneDrive\\Desktop\\New folder (2)\\FC2PPV 1218169 [Odorless video] [Leaked] JULIA High image quality BEB-016 JULIA Sweaty Backroom .ts\n", - "1 \t JPopsuki 2.0 2131292835\n", - "1 \t 不予@暗香阁\n", - "1 \t sogclub No.2 BY sogclub\n", - "1 \t uid-1591117\n", - "1 \t b'\\xba\\xda\\xc2\\xfb\\xb0\\xc5'\n", - "1 \t 微信一夜ONS协会\n", - "1 \t b'KUHO\\xd2\\xd5\\xca\\xf5\\xc1\\xaa\\xc3\\xcb'\n", - "1 \t b'\\xb6\\xc0\\xa5i\\xa8\\xe0_by_FDZone.org'\n", - "1 \t 中文字幕無水印\n", - "1 \t http://www.wozai020.com\n", - "1 \t sop168\n", - "1 \t b'SP\\xa7\\xe4\\xbc\\xd6\\xa4l@\\xaa\\xe1\\xa9M\\xa9|'\n", - "1 \t tiantianlu186@公仔箱論壇\n", - "1 \t luckyjune\n", - "1 \t SK`|yEsMan\n", - "1 \t b'@aaming2002@\\xa3\\xa2\\xb3\\xd5\\xba\\xba\\xa3\\xa2\\xc9\\xab\\xd6\\xd0\\xc9\\xab\\xa3\\xa2\\xc3\\xce\\xb9\\xab\\xd4\\xb0\\xa3\\xa2MimiP2P\\xa3\\xa2\\xa3\\xc4.\\xa3\\xc3P2P\\xa3\\xa2WaiKeungSite\\xa3\\xa2p2pZONE\\xa3\\xa2Mr.P2P\\xa3\\xa2'\n", - "1 \t hkkane@18p2p\n", - "1 \t www.4hu.com\n", - "1 \t b'\\xaeL\\xaa\\xef\\xacK@99p2p'\n", - "1 \t 夜蒅星宸@第一会所\n", - "1 \t 【更多资源用加手机QQ-17182252050】\n", - "1 \t jjjhn2003@18p2p\n", - "1 \t XIEYUXIA\n", - "1 \t b'@\\xc0\\xcb\\xb7\\xad\\xd4\\xc6@'\n", - "1 \t yjs521\n", - "1 \t hhbb_zcm\n", - "1 \t twsb.co\n", - "1 \t https://www.musicastorrent.com/\n", - "1 \t pandafood#panda1314#gg5123 獨家首發\n", - "1 \t 探花族\n", - "1 \t zhoudehua200\n", - "1 \t AV大平台 - 发布页\n", - "1 \t b'tanw\\xa9\\xceyk3325'\n", - "1 \t Rivera@18p2p.com\n", - "1 \t b'\\xd7\\xcf\\xc3\\xb5\\xb9\\xe5'\n", - "1 \t [kp.m-team.cc] M-Team - TP\n", - "1 \t www.spankhash.com\n", - "1 \t UID 235465@www.mimip2p.net\n", - "1 \t 草榴社区@MianSheng\n", - "1 \t Странник\n", - "1 \t hgr168168\n", - "1 \t BJ\n", - "1 \t mecaca\n", - "1 \t 昆仑虚之巅@草榴社區\n", - "1 \t [欧美美@草榴社区]\n", - "1 \t 没线的风筝\n", - "1 \t 尼尼撸-综合网站\n", - "1 \t 100%真人激情裸聊 www.78xo.com\n", - "1 \t jettej\n", - "1 \t Daddy\n", - "1 \t diamond\n", - "1 \t 中文片库\n", - "1 \t https://worldmkv.com\n", - "1 \t b'yatsingkoon@\\xa1\\xb9\\xb6q\\xb3c\\xa4\\xc0\\xa8\\xc9\\xbd\\xd7\\xbe\\xc2\\xa1\\xb9'\n", - "1 \t 入微\n", - "1 \t https://discord.com/invite/wweVHZd6qg\n", - "1 \t 602@第一会所\n", - "1 \t 3484988vikci@第一会所\n", - "1 \t evilzy\n", - "1 \t 化骨龍\n", - "1 \t https://www.kobo.com/ebook/an-archdemon-s-dilemma-how-to-love-your-elf-bride-volume-13\n", - "1 \t cqkd_czy\n", - "1 \t 不辣de皮特\n", - "1 \t kaito\n", - "1 \t u3c3.com\n", - "1 \t ☆影视帝国论坛☆\n", - "1 \t aaa23\n", - "1 \t hevcbay.com\n", - "1 \t gn7650104\n", - "1 \t 老舅电影\n", - "1 \t 捕鼠人\n", - "1 \t https://www.gamestorrents.nu/\n", - "1 \t 公主殿下@第一會所\n", - "1 \t b'\\xb8\\xb4\\xbb\\xee126'\n", - "1 \t 微信公众号:卡其影视分享\n", - "1 \t 百虎动画\n", - "1 \t 425307@癡漢俱樂部\n", - "1 \t avp2p\n", - "1 \t GIFchuchushipin\n", - "1 \t EndlesSea\n", - "1 \t Tanhuazu-探花族\n", - "1 \t 推特搞啥呢\n", - "1 \t @K8bet.io@\n", - "1 \t Misfits\n", - "1 \t 黑暗虫洞\n", - "1 \t magazinesbb.com\n", - "1 \t b'\\xc9\\xab\\xd6\\xd0\\xc9\\xab\\xd5\\x93\\x89\\xaf@www.SIS.xxx'\n", - "1 \t 草榴社区@z10271\n", - "1 \t 冰封爱河\n", - "1 \t b'[http://www.uniongang.net] \\xd4\\xe8\\xeb\\xfc\\xec\\xfb \\xee\\xf2 ELEKTRI4KA | \\xdd\\xcb\\xc5\\xca\\xd2\\xd0\\xc8\\xd7\\xca\\xc0 \\xed\\xe0 Uniongang'\n", - "1 \t zhangqq789@第一会所\n", - "1 \t wangye6\n", - "1 \t ann@myfun4u.org\n", - "1 \t kino9999@18p2p\n", - "1 \t b'CHD\\xc1\\xaa\\xc3\\xcb'\n", - "1 \t satu@hongfire\n", - "1 \t polee\n", - "1 \t GM3089@18P2P\n", - "1 \t BT工厂 @ 5120911\n", - "1 \t sklc-P2P101.COM\n", - "1 \t b'\\xb0\\xcb\\xd6\\xd8\\xf7\\xec'\n", - "1 \t b'\\xcc\\xda\\xb7\\xc9\\xd4\\xda\\xcf\\xdf'\n", - "1 \t b'doa_o[\\xb9\\xc5\\xce\\xef\\xce\\xdd]'\n", - "1 \t 缘聚岛\n", - "1 \t 素人辣妹正妹報報\n", - "1 \t b'sweetsmile@CHD\\xc1\\xaa\\xc3\\xcb'\n", - "1 \t javtv.me\n", - "1 \t zhaochuan99\n", - "1 \t 四魂制作组\n", - "1 \t 动漫花園\n", - "1 \t View my conspiracy torrents at\n", - "1 \t 春卅娘@18p2p\n", - "1 \t JPopsuki 2.0 904012437\n", - "1 \t wearebest@18P2P\n", - "1 \t HTCdesireHD@第一會所\n", - "1 \t shinjico\n", - "1 \t 得得撸 www.dedelu.com\n", - "1 \t Western&HD-Jiggly\n", - "1 \t ningchia\n", - "1 \t filelist.ro\n", - "1 \t dengzhi123_by_FDZone.ORG\n", - "1 \t b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1 dioguitar23(\\xb2\\xc4\\xa4\\xbb\\xa4\\xd1\\xc5]\\xa4\\xfd)\\xad\\xec\\xb3\\xd0'\n", - "1 \t HZHJS\n", - "1 \t Audible\n", - "1 \t skyuz\n", - "1 \t ever\n", - "1 \t El tio WAPILLO :v\n", - "1 \t 草莓TV\n", - "1 \t 加菲豆@第一会所\n", - "1 \t yaoshiqiao\n", - "1 \t PB\n", - "1 \t b'\\xb9\\xda\\xa4\\xbd\\xb6\\xe9\\xaeT\\xbc\\xd6\\xa4u\\xa7{@p16847'\n", - "1 \t 54CECB5A0EA7_by_FDZone.ORG\n", - "1 \t b'\\xc0\\xcb\\xd7\\xd3\\xd0\\xa1\\xb5\\xb6'\n", - "1 \t rendell_by_mimip2p.net, rendellxx_by_fdzone.org, rendell@SexInSex!\n", - "1 \t https://e-hentai.org\n", - "1 \t jinzebin86@18p2p.com\n", - "1 \t birdmanfocker@18p2p\n", - "1 \t GH37DgaBef6rQJyE2nvqb5YpS\n", - "1 \t AVdian@126.com\n", - "1 \t 亞瑟王\n", - "1 \t b'Bianca_Cooper_Touch99.com \\xa6\\xb3\\xa7\\xf3\\xa6h\\xa6n\\xb9\\xcf'\n", - "1 \t wT3j6PNrC5aOcD04yJ7xRotF8\n", - "1 \t 村花论坛\n", - "1 \t b'\\xc4\\xfa_\\x89\\xf4\\xb9\\xab\\x88@\\x8a\\xca\\x98\\xb7\\xb9\\xa4\\xb7\\xbb'\n", - "1 \t FISH321@18P2P\n", - "1 \t 第一会所 sis001\n", - "1 \t huPE@18P2P\n", - "1 \t houlai=biaoqian\n", - "1 \t b'qilibi@\\xc1\\xf9\\xd4\\xc2\\xc2\\x93\\xc3\\xcb'\n", - "1 \t 天池妖尊\n", - "1 \t sing0212000\n", - "1 \t wandy_by_FDZone.org\n", - "1 \t XO@kazamis\n", - "1 \t KOOK\n", - "1 \t HQC\n", - "1 \t mc733\n", - "1 \t 爱游戏\n", - "1 \t 1158012^@^18p2p\n", - "1 \t b'Bianca_Cooper \\xa7\\xf3\\xa6h\\xac\\xfc\\xb9\\xcf\\xa5u\\xa6bTouch99'\n", - "1 \t xiaocuitj\n", - "1 \t 星星不舔屄\n", - "1 \t https://www.crnaberza.com CrnaBerza\n", - "1 \t boby@mimip2p\n", - "1 \t magnet360@163.com\n", - "1 \t Japanadultvideos 論壇 <-----按此瀏覽更多\n", - "1 \t [http://x-torrents.nu] X-Torrents.org\n", - "1 \t euphoricer\n", - "1 \t zlb273692399@第一会所\n", - "1 \t 花和尚\n", - "1 \t b'\\xb4\\xbf\\xb0\\xae\\xc9\\xe7\\xc7\\xf8/wbzt'\n", - "1 \t 三石@第一会所\n", - "1 \t JackyCheung@草榴社區\n", - "1 \t b'\\xbf\\xe7\\xca\\xa1\\xbe\\xdc\\xb7\\xf1@9999999'\n", - "1 \t 菜牙电影网\n", - "1 \t mehappy2012\n", - "1 \t https://www.jp.square-enix.com/music/sem/page/chrono/trigger_revival/\n", - "1 \t Scientists used to invent telephones, airplanes, microwave ovens... now all they invent is statistics that say they should get more funding.\n", - "1 \t RoxMarty\n", - "1 \t rczhi@18p2p.com\n", - "1 \t kkk8568\n", - "1 \t kenan2763\n", - "1 \t arthurwarlike@第一会所\n", - "1 \t b'\\xb3\\xc7\\xca\\xd0\\xefL\\xc7\\xe9~~\\xcb\\xba\\xd2\\xb9\\xd4\\xad\\x84\\x93'\n", - "1 \t 東方明珠=ccvvm\n", - "1 \t 从小缺钙\n", - "1 \t www.lupola.com\n", - "1 \t Jackie\n", - "1 \t ashow.cc\n", - "1 \t 品色影院\n", - "1 \t 8400327@草榴社區\n", - "1 \t gamezealot@18p2p\n", - "1 \t uhla454@第一会所\n", - "1 \t 宅鱼\n", - "1 \t 1024核工厂 Bt7086\n", - "1 \t hilllxs\n", - "1 \t 豺狼也柔情\n", - "1 \t 99堂\n", - "1 \t 老肥\n", - "1 \t Chikyuji-Animes, 2006 maggle!\n", - "1 \t chaorentwo@18p2p\n", - "1 \t 若無其事@18p2p.com\n", - "1 \t hhd000.com\n", - "1 \t 掠风窃尘\n", - "1 \t b'\\xd3\\xd5\\xbb\\xf3\\xd3\\xe9\\xc0\\xd6\\xcd\\xf8\\xb5\\xe3\\xbb\\xf7\\xbd\\xf8\\xc8\\xeb \\xa8w\\xec\\xe1\\xbf\\xa1\\xc9\\xd9\\xec\\xe1\\xa8w'\n", - "1 \t Kura999 from WaikeungBBS\n", - "1 \t XFSUB\n", - "1 \t huiasd\n", - "1 \t b'Rory @ D.C.\\xb8\\xea\\xb0T\\xa5\\xe6\\xacy\\xba\\xf4'\n", - "1 \t https://t.me/deletetvwrestling\n", - "1 \t dodododo\n", - "1 \t Rambo@18p2p\n", - "1 \t b'\\xce\\xde\\xd0\\xc4\\xce\\xde\\xb4\\xe6'\n", - "1 \t filmplay\n", - "1 \t avdian@126.com\n", - "1 \t 1025\n", - "1 \t 956828@18p2p\n", - "1 \t 夜游神\n", - "1 \t b'\\xb2\\xbb\\xb5\\xc3\\xb2\\xbb\\xc9\\xab'\n", - "1 \t vbiukj\n", - "1 \t jnd16d\n", - "1 \t 烽火不熄\n", - "1 \t pietro716\n", - "1 \t Lus\n", - "1 \t b'\\x98Y\\xd4\\xad\\xa4\\xe6\\x97@'\n", - "1 \t 國產無碼\n", - "1 \t b'\\xd0\\xc2\\xc7\\xd7\\xc3\\xdc\\xb0\\xae\\xc8\\xcb\\xc2\\xdb\\xcc\\xb3@\\xd6\\xc1\\xd7\\xf0\\xcc\\xec\\xc1\\xfa'\n", - "1 \t wangzhifeng@18p2p\n", - "1 \t dabohong_by_fdzone.org\n", - "1 \t TODO\n", - "1 \t b'\\xb7\\xc9\\xd3\\xb0\\xbf\\xcd\\xcd\\xf8'\n", - "1 \t yav.me\n", - "1 \t Torrent downloaded from torrent cache at torcache.net\n", - "1 \t http://www.jizhang1.space/?3316427\n", - "1 \t handsomemouse@18p2p\n", - "1 \t 面瘫\n", - "1 \t yyyyyuuuuu@18p2p\n", - "1 \t 狼主@SexInSex.net\n", - "1 \t 1394130143@第一会所\n", - "1 \t jove\n", - "1 \t 电骡爱好者\n", - "1 \t westkyo@www.sis001.com\n", - "1 \t lzmcmbj@18p2p\n", - "1 \t dioguitar23(第六天魔王)@dioguitar23.me\n", - "1 \t VISTOR_by_FDZone.ORG\n", - "1 \t chris930\n", - "1 \t [WMAN-LorD] [UHD] [4K] [2160p] [REAL4K] [TGx]\n", - "1 \t b'A\\xab\\xac\\xa4\\xa3\\xa8}\\xc3\\xc8'\n", - "1 \t b'\\xb8\\xfc\\xb6\\xe0\\xb8\\xfc\\xd0\\xc2\\xb5\\xe7\\xd3\\xb0\\xcf\\xc2\\xd4\\xd8\\xc7\\xeb\\xb5\\xe3\\xbb\\xf7\\xd5\\xe2\\xc0\\xef'\n", - "1 \t destiny999@18p2p\n", - "1 \t HOUSEKEEPER\n", - "1 \t RV原创组\n", - "1 \t b'\\xc3\\xe2\\xb7\\xd1\\xd4\\xda\\xcf\\xdf\\xd2\\xf4\\xc0\\xd6'\n", - "1 \t www.1024pk.com\n", - "1 \t 爱城\n", - "1 \t amge50@www.sogclub.com\n", - "1 \t OneStar\n", - "1 \t b'Jocky123#\\xb8\\xfc\\xb6\\xe0\\xb5\\xc4\\xbe\\xab\\xb2\\xca\\xd3\\xb0\\xc6\\xac!'\n", - "1 \t https://getcomics.info\n", - "1 \t 点击-海量种子\n", - "1 \t btziyuan\n", - "1 \t [http://x-torrents.org] X-Torrents.org (ex X-Torrents.ru)\n", - "1 \t https://www.lspback.com\n", - "1 \t foxmoder996\n", - "1 \t https://share.dmhy.org/topics/list/user_id/712935\n", - "1 \t 玛尔亲王@第一会所\n", - "1 \t rtjhuytu\n", - "1 \t 淨空法師專集網站\n", - "1 \t b'\\xa1\\xb6\\xbd\\xcc\\xd3\\xfd\\xca\\xd6\\xc0\\xad\\xca\\xd6\\xa1\\xb7'\n", - "1 \t mc733+zgome\n", - "1 \t Goddess\n", - "1 \t NikeのB@第一会所\n", - "1 \t b'dvt\\xb0\\xc9'\n", - "1 \t 微博:止于影书,公众号:影遇见书,@小鱼\n", - "1 \t free4\n", - "1 \t 靜風@sis001\n", - "1 \t dcsk_By_FDZone.org\n", - "1 \t sigma@www.mimip2p.com\n", - "1 \t 看翍荭尘\n", - "1 \t bjiok\n", - "1 \t lins2b\n", - "1 \t 小馬克_by_FDZone.ORG\n", - "1 \t FSFS555@第一会所\n", - "1 \t flowerff\n", - "1 \t lascruces\n", - "1 \t ?nike?\n", - "1 \t SEX8.CC\n", - "1 \t b'\\xb3\\xc9\\xc8\\xcb\\xc2\\xdb\\xcc\\xb3\\xbf\\xaa\\xb7\\xc5\\xd7\\xa2\\xb2\\xe1'\n", - "1 \t APKMAZA.CO\n", - "1 \t 13121152@18p2p\n", - "1 \t UID 185363@www.mimip2p.com\n", - "1 \t b'\\xa4^\\xa4\\xa2\\xb5\\xbe@FDZone.org'\n", - "1 \t 更多资源联系qq1273288348\n", - "1 \t https://nyaa.si/user/mrshowoff\n", - "1 \t https://boards.4channel.org/h/#s=hentai+upscales\n", - "1 \t mimu@18P2P\n", - "1 \t b'\\xd7\\xd3\\xc7\\xe9 \\xd7\\xa3\\xba\\xd8\\xc9\\xab\\xd6\\xd0\\xc9\\xab \\xcb\\xc4\\xd6\\xdc\\xc4\\xea \\xcc\\xd8\\xb1\\xf0\\xcb\\xae\\xd3\\xa1\\xd1\\xb9\\xd6\\xc6'\n", - "1 \t 殇情\n", - "1 \t 风来西林\n", - "1 \t b'Nike\\xa4\\xce\\xa3\\xc2'\n", - "1 \t [www.pttime.org] PT时间\n", - "1 \t QxR\n", - "1 \t sunchiua_by_P2Pzone.org\n", - "1 \t wazx528\n", - "1 \t popgofansub\n", - "1 \t b'\\xc3\\xe2\\xb7\\xd1\\xb5\\xe7\\xd3\\xb0\\xcf\\xc2\\xd4\\xd8\\xbb\\xf9\\xb5\\xd8'\n", - "1 \t gremichaem\n", - "1 \t b'\\xd0\\xc7\\xb3\\xbd\\xd0\\xa1\\xb7\\xe7\\xa3\\xa6\\xbe\\xab\\xc9\\xf1\\xc9\\xab\\xcb\\xd8\\xa3\\xa6cookiexp\\xa3\\xc0\\xd1\\xb0\\xba\\xfc\\xc9\\xe7\\xc7\\xf8'\n", - "1 \t sukebei.nyaa.si\n", - "1 \t pademon18p2p\n", - "1 \t aaamfk+zgome+bbryans\n", - "1 \t cyxy@http://38.114.38.172/forum/\n", - "1 \t b'\\xd3\\xd7\\xc5\\xae\\xbc\\xab\\xc6\\xb7'\n", - "1 \t https://e-hentai.org/g/2375721/1b5e081312/\n", - "1 \t 18P2P_dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "1 \t b'AV\\xce\\xc4\\x99n\\xa3\\xfcADULT INTEGRATED COMMUNITY'\n", - "1 \t UID 1357210@18P2P.com\n", - "1 \t fuckkkingou\n", - "1 \t 闲云野鹤\n", - "1 \t LAPUMiA.NeT\n", - "1 \t adult_cn\n", - "1 \t psoke\n", - "1 \t 18p2p@liyang8926\n", - "1 \t littlefatbee\n", - "1 \t 秋叶TV\n", - "1 \t msy91\n", - "1 \t Niraya\n", - "1 \t https://www.kobo.com/ebook/that-time-i-got-reincarnated-as-a-slime-vol-13-light-novel\n", - "1 \t JPopsuki 2.0 941661648\n", - "1 \t yamyedye@18P2P\n", - "1 \t dansnow\n", - "1 \t H2CO3\n", - "1 \t b'\\x8e\\xf7\\x8e\\xf7@\\x88\\xc3\\x91\\xe9\\x9a\\xa0\\x8c\\xb4\\x91n'\n", - "1 \t kamigami\n", - "1 \t G@1024核工廠\n", - "1 \t The Seaside Corpse\n", - "1 \t b'\\xadw\\xbd\\xde_by_FDZone.ORG'\n", - "1 \t fangbayern\n", - "1 \t 君乐\n", - "1 \t Doctor Who\n", - "1 \t 第一流氓@18P2P\n", - "1 \t Deviloid.net\n", - "1 \t b'\\xc1\\xf9\\xd4\\xc2\\xc1\\xaa\\xc3\\xcb hgfhgf'\n", - "1 \t wcer@18p2p.com\n", - "1 \t https://www.yitarx.com\n", - "1 \t wuchengzhou9000@www.SexInSex.net\n", - "1 \t nwcd\n", - "1 \t p2p_user@mimip2p\n", - "1 \t zza@live.com\n", - "1 \t 清风浪子@草榴社区\n", - "1 \t http://www.zone54.com\n", - "1 \t ssan998\n", - "1 \t xxfhd.com\n", - "1 \t mybmw320_by_SpeedPluss.ORG\n", - "1 \t woaibt@1024核工厂\n", - "1 \t b'[http://www.uniongang.tv] \\xd4\\xe8\\xeb\\xfc\\xec\\xfb \\xee\\xf2 ELEKTRI4KA | \\xdd\\xcb\\xc5\\xca\\xd2\\xd0\\xc8\\xd7\\xca\\xc0 \\xed\\xe0 Uniongang'\n", - "1 \t hegongc163\n", - "1 \t t66y\n", - "1 \t cctc55\n", - "1 \t tto@18P2P\n", - "1 \t Antidot Team\n", - "1 \t Torrent Galaxy\n", - "1 \t 萤火虫IT服务全国连锁\n", - "1 \t 葬爱@18p2p\n", - "1 \t 贴心话\n", - "1 \t xuerui810405\n", - "1 \t SoulSeek\n", - "1 \t abbt@18p2p.com\n", - "1 \t lixuhua\n", - "1 \t b'\\xcc\\x93\\x9fo'\n", - "1 \t animekayo.com\n", - "1 \t qiupianhao\n", - "1 \t 173489627\n", - "1 \t wak11110@18P2P\n", - "1 \t [http://hdtracker.org] HD TRACKER\n", - "1 \t www.eien-acg.com\n", - "1 \t index0123\n", - "1 \t hndwje\n", - "1 \t http://www.meitubb.com/forum.php\n", - "1 \t https://anidb.net/file/3082403\n", - "1 \t 更多精彩 @ 卡卡拉\n", - "1 \t olo@第一会所\n", - "1 \t https://e-hentai.org/g/2255154/778b4d24e6/\n", - "1 \t sujinding@第一会所\n", - "1 \t MKO\n", - "1 \t chleicool=fym0624=patpat608\n", - "1 \t 撸二九论坛\n", - "1 \t flybird186\n", - "1 \t b'[http://hdclub.org] \\xd2\\xf0\\xe5\\xea\\xe5\\xf0 HDClub - \\xf1\\xea\\xe0\\xf7\\xe0\\xf2\\xfc \\xe1\\xe5\\xf1\\xef\\xeb\\xe0\\xf2\\xed\\xee \\xf4\\xe8\\xeb\\xfc\\xec\\xfb HD, \\xf1\\xea\\xe0\\xf7\\xe0\\xf2\\xfc Blu-ray \\xf4\\xe8\\xeb\\xfc\\xec\\xfb, HD DVD \\xe8 HD audio, HDTV \\xf2\\xee\\xf0\\xf0\\xe5\\xed\\xf2'\n", - "1 \t https://www.omgyes.com\n", - "1 \t DVD 2008\n", - "1 \t b'[http://uniongang.tv] \\xd4\\xe8\\xeb\\xfc\\xec\\xfb \\xee\\xf2 ELEKTRI4KA | \\xdd\\xcb\\xc5\\xca\\xd2\\xd0\\xc8\\xd7\\xca\\xc0 \\xed\\xe0 Uniongang'\n", - "1 \t b'\\xb9\\xfd\\xc5\\xab\\xd6\\xc6\\xd4\\xec\\xb2\\xa9\\xbf\\xcd'\n", - "1 \t 3267506\n", - "1 \t 中国电信\n", - "1 \t 9clonely\n", - "1 \t b'\\xd2\\xf9\\xc3\\xf1\\xcd\\xf2\\xcb\\xea'\n", - "1 \t 幸运流星@四仔论坛\n", - "1 \t Lista Espiritualista\n", - "1 \t 雪光梦想\n", - "1 \t https://exhentai.org/g/1964478/8ed0a899ca\n", - "1 \t olo@sis001\n", - "1 \t 3zi@第一會所\n", - "1 \t Andy\n", - "1 \t b'\\xb7\\xd6\\xcf\\xed'\n", - "1 \t 24262830.\n", - "1 \t 食色性者\n", - "1 \t aj11@mimip2p.net\n", - "1 \t srwH\n", - "1 \t 鴻仔\n", - "1 \t 校园迷糊大王\n", - "1 \t WCG\n", - "1 \t b'(\\xd3\\xf4\\xc3\\xc6)\\xb0\\xae\\xbf\\xb4\\xb5\\xe7\\xd3\\xb0'\n", - "1 \t kiva@18p2p\n", - "1 \t b'\\xbb\\xd8\\xbc\\xd2001@18p2p'\n", - "1 \t ffxx\n", - "1 \t chikan@T66Y\n", - "1 \t 瑞倪维儿护肤专卖\n", - "1 \t auriga@18p2p\n", - "1 \t yinchong818@(sis)\n", - "1 \t 酷安\n", - "1 \t JPopsuki 2.0 14486345\n", - "1 \t 若無其事@18p2p\n", - "1 \t b'stormly+taitan12+zhaoZero41+chinami2002+glen246+faberge@darkeagle-\\xbax\\x84\\xf0\\xaa\\xc0'\n", - "1 \t CMCT团队荣誉出品\n", - "1 \t kennyboy\n", - "1 \t 2AV.COM\n", - "1 \t DoraemonLL\n", - "1 \t duwangyang\n", - "1 \t cjy21\n", - "1 \t cnman@18P2P\n", - "1 \t zwl508\n", - "1 \t hangzhouyang\n", - "1 \t 99BT工厂\n", - "1 \t TorrentLeech.org\n", - "1 \t MPCStar\n", - "1 \t sharemovie\n", - "1 \t sexav.tv\n", - "1 \t bbking\n", - "1 \t giga17100\n", - "1 \t QQ272286821\n", - "1 \t 尤里\n", - "1 \t 吴天@第一会所\n", - "1 \t MyAV@18p2p\n", - "1 \t b'\\xa5\\xda\\xa9`\\xa5\\xdd\\xa5\\xeb\\xa5\\xed\\xa9`\\xa5\\xb9'\n", - "1 \t 牛丝社\n", - "1 \t 汐\n", - "1 \t nvsdyi\n", - "1 \t oldman@18p2p\n", - "1 \t b'dioguitar23\\xad\\xec\\xb3\\xd0'\n", - "1 \t b'\\xb6\\xe0\\xb2\\xca\\xc9\\xe7\\xc7\\xf8'\n", - "1 \t lianghua@18p2p\n", - "1 \t aiai2013\n", - "1 \t computerking123@www.SexInSex.net\n", - "1 \t b'dioguitar23(\\xb2\\xc4\\xa4\\xbb\\xa4\\xd1\\xc5]\\xa4\\xfd)@hotavxxx.com'\n", - "1 \t 梦幻天堂·龙网@航子(www.LWgod.cc)\n", - "1 \t dio99.com(第六天魔王)@最新AV海量免費播放~魔王在線\n", - "1 \t deatht\n", - "1 \t 18P2Pjheang168\n", - "1 \t 性吧发片部 ou89279546\n", - "1 \t b'\\xc4\\xfa'\n", - "1 \t jasonchan@18p2p\n", - "1 \t https://t.me/zongmange\n", - "1 \t asiamarket@18p2p\n", - "1 \t huanglaoda@xuhu\n", - "1 \t sxjjh7171\n", - "1 \t 喜歡下雨天@SIS001\n", - "1 \t Nikola\n", - "1 \t 好人\n", - "1 \t b'\\xcf\\xeb\\xb0l\\x85s\\xb2\\xbb\\x95\\xfe'\n", - "1 \t Wowshadow.net\n", - "1 \t Fp\n", - "1 \t 色花堂—FVG\n", - "1 \t b'\\xba\\xda\\xb0\\xb5\\xca\\xa5\\xb5\\xee'\n", - "1 \t xmq\n", - "1 \t kilin\n", - "1 \t http://mmgg.cctve.cn/\n", - "1 \t UID: 661086 UID: 1258553 UID: 78965\n", - "1 \t WOLF字幕组\n", - "1 \t chaijoe@18p2p\n", - "1 \t https://one2048.com\n", - "1 \t lloveppp@18p2p\n", - "1 \t (同城裸聊约炮)\n", - "1 \t b'[https://tracker.0day.kiev.ua] \\xd2\\xf0\\xe5\\xea\\xe5\\xf0 0day.kiev.ua'\n", - "1 \t Ferech\n", - "1 \t SRD\n", - "1 \t プリズム☆ま~じカル ~PRISM Generations!~\n", - "1 \t Blu-Ray\n", - "1 \t wuaibin\n", - "1 \t JPopsuki 2.0 1081189358\n", - "1 \t b'\\xb2D\\xad\\xb7\\xae\\xf6\\xa4l'\n", - "1 \t 哆学家\n", - "1 \t Forest of Good and Evil 1-2\n", - "1 \t DOBI\n", - "1 \t QQ:649020789\n", - "1 \t JPopsuki 2.0 383208255\n", - "1 \t http://ehtracker.org/2135832/announce\n", - "1 \t shuangyuboy@第一會所\n", - "1 \t №追风少年☆@第一会所\n", - "1 \t dontknowhat (TGx)\n", - "1 \t LAPUMiA.Org\n", - "1 \t fhm2888@第一会所\n", - "1 \t https://rips.club/\n", - "1 \t 魅影论坛\n", - "1 \t 最新网址\n", - "1 \t Zamunda.SE\n", - "1 \t 整理不易,请保种\n", - "1 \t https://freeplay.space/\n", - "1 \t b'\\xacn\\xacn\\xad^\\xb6\\xaf\\xa4Q\\xa4K\\xa5{ \\xad\\xba\\xad\\xb6'\n", - "1 \t wo010101\n", - "1 \t abner166@18p2p\n", - "1 \t dioguitar23(第六天魔王)原創\n", - "1 \t life小絮\n", - "1 \t tvboxnow\n", - "1 \t 撸一发吧\n", - "1 \t haobu3455\n", - "1 \t anikaiser@18p2p\n", - "1 \t b'5Q \\xcb\\xae\\xe9\\xbf\\xcd\\xa4@\\xc6\\xe6\\xd1\\xc8'\n", - "1 \t javkiss\n", - "1 \t wangxiaowu005@www.SexInSex.net\n", - "1 \t lanyidong\n", - "1 \t www.preall.com\n", - "1 \t 18p2p~海綿體 原創\n", - "1 \t b'\\xc1x\\xd3\\xc2\\xeb\\x85\\xcc\\xec\\xeaP\\xeb\\x85\\xe9L'\n", - "1 \t 吉时综合论坛\n", - "1 \t 愛在黑夜\n", - "1 \t 天使动漫\n", - "1 \t LJZ\n", - "1 \t spider.\n", - "1 \t b'\\xbb\\xb7\\xc7\\xf2\\xbc\\xab\\xcf\\xde\\xcf\\xc2\\xd4\\xd8'\n", - "1 \t HHH\n", - "1 \t 蜂鸟-日本同步-首发\n", - "1 \t b'\\xc5\\xb0\\xb0\\xae\\xd3\\xd7\\xd3\\xd7'\n", - "1 \t yakupe\n", - "1 \t UID-968398@18P2P\n", - "1 \t b'\\xc3\\xa8\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1@\\xb4A\\xab\\xbd\\xa8\\xe0'\n", - "1 \t b'lniklegend[\\xe3n\\xa4\\xeb\\xad\\xec\\xb3\\xd0\\xb2\\xd5]'\n", - "1 \t JPopsuki 2.0 600921940\n", - "1 \t https://exhentai.org/g/1701233/d6aed3161e/\n", - "1 \t b'you15648g \\xad\\xec\\xb3\\xd0\\xb5o\\xb0e'\n", - "1 \t yihyii@www.sogclub.com\n", - "0 \t ostali\n" - ] - } - ], + "outputs": [], "source": [ "s = monotonic()\n", "def removeminorities(population, minrepr=0, ostalo=\"ostalo\"):\n", @@ -4082,19 +228,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "4bd1f517", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "...\n", - "9.945079553872347 s 335643 različnih tipov v 3084321 datotekah in 259.2602232018344 TiB\n" - ] - } - ], + "outputs": [], "source": [ "s = monotonic()\n", "from mimetypes import guess_type\n", @@ -4151,2951 +288,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "82ab922a", "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\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(\n", - " '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", - "\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 = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " /* This rescales the canvas back to display pixels, so that it\n", - " * appears correct on HiDPI screens. */\n", - " canvas.style.width = width + 'px';\n", - " canvas.style.height = height + 'px';\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\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 toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\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", - "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", - "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], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\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", - " fig.canvas_div.style.cursor = msg['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.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\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", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\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", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\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(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\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(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://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", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\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", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, 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", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "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.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(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 = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\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 () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\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", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('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", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "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(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sortcount = sorted(bycount, reverse=False, key=lambda x: bycount[x])\n", "sortsize = sorted(bysize, reverse=False, key=lambda x: bysize[x])\n", diff --git a/radio/radio.py b/radio/radio.py new file mode 100755 index 0000000..2c04056 --- /dev/null +++ b/radio/radio.py @@ -0,0 +1,95 @@ +#!/usr/bin/python3 +from sys import path +path.append("..") +from travnik import Torrent +import inotify.adapters +from threading import Thread +from random import randrange +from os import stat +from time import sleep + +import libtorrent + +def random_file(torrent, save_path, endung=".flac"): + def get_index_from_endung(chosen): + for i in range(torrent.torrent_file().files().num_files()): + if (torrent.torrent_file().files().file_path(i).endswith(endung)): + if chosen == 0: + return i + break + chosen -= 1 + prios = [] + for i in torrent.get_file_priorities(): + prios.append(0) + endungs = 0 + for i in range(torrent.torrent_file().files().num_files()): + if (torrent.torrent_file().files().file_path(i).endswith(endung)): + endungs += 1 + if endungs == 0: + return False + chosen = randrange(endungs) + tries_left = endungs + while True: + if tries_left == 0: + return False + tries_left -= 1 + try: + stat(save_path + "/" + torrent.torrent_file().files().file_path(get_index_from_endung(chosen))) + except FileNotFoundError: + chosen = (chosen + 1) % endungs; + break + else: + continue + prios[get_index_from_endung(chosen)] = 4 + torrent.prioritize_files(prios) + print(f"random file {torrent.torrent_file().files().file_path(get_index_from_endung(chosen))} chosen to download") + +def watcher(session, torrents, d="/tmp/", s=".", active_torrents=10): + i = inotify.adapters.Inotify() + i.add_watch(d) + for event in i.event_gen(yield_nones=False): + (_, type_names, path, filename) = event + if "IN_CLOSE_WRITE" in type_names and filename.endswith(".torrent"): + t = Torrent() + t.file(path + filename) + for pth, size in t.paths(): + if pth[-1].endswith(b'.flac'): + info = libtorrent.torrent_info(path + filename) + torr = session.add_torrent({"ti": info, "save_path": s}) + random_file(torr, save_path=s); + torrents.append(torr) + if len(torrents) > active_torrents: + session.remove_torrent(torrents[0]) + del torrents[0] + break + +def alerts(session): + while True: + session.wait_for_alert(86400*1000*21) + for a in session.pop_alerts(): + if a.category() & libtorrent.alert.category_t.error_notification: + print(f"error notification alert from libtorrent: {a}") + if type(a) == libtorrent.file_completed_alert: + print(f"file completed alert: {a}") + if type(a) in [libtorrent.external_ip_alert, libtorrent.listen_succeeded_alert, libtorrent.dht_get_peers_alert, libtorrent.dht_outgoing_get_peers_alert, libtorrent.dht_reply_alert, libtorrent.torrent_added_alert, libtorrent.state_changed_alert, libtorrent.torrent_resumed_alert, libtorrent.stats_alert, libtorrent.torrent_checked_alert, libtorrent.peer_connect_alert, libtorrent.alert, libtorrent.peer_disconnected_alert, libtorrent.incoming_connection_alert, libtorrent.block_downloading_alert, libtorrent.dht_bootstrap_alert, libtorrent.dht_announce_alert, libtorrent.block_finished_alert, libtorrent.piece_finished_alert, libtorrent.peer_unsnubbed_alert, libtorrent.peer_snubbed_alert, libtorrent.portmap_error_alert]: + continue + print(f"{type(a)} | {a}") + +def progress(session, torrents): + while True: + for torr in torrents: + s = torr.status() + print(torr.torrent_file().name() + '\t%.2f%% complete (down: %.1f kB/s up: %.1f kB/s peers: %d) %s' % (s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, s.num_peers, s.state)) + sleep(1) +if __name__ == "__main__": + session = libtorrent.session({"alert_mask": libtorrent.alert.category_t.all_categories}); + torrents = [] + w = Thread(target=watcher, args=(session, torrents)) + a = Thread(target=alerts, args=(session,)) + p = Thread(target=progress, args=(session, torrents)) + w.start() + a.start() + p.start() + w.join() + a.join() + p.join() diff --git a/src/bencoding.c b/src/bencoding.c index 991ac9c..0fb2588 100644 --- a/src/bencoding.c +++ b/src/bencoding.c @@ -328,7 +328,7 @@ char * b2json (char * dest, struct bencoding * b) { if (b->type & num) { char buf[512]; sprintf(buf, "%ld", b->intvalue); - strncpy(dest, buf, strlen(buf)); + strcpy(dest, buf); return dest+strlen(buf); } if (b->type & (list | dict)) { @@ -708,13 +708,13 @@ char * bencode (char * dest, struct bencoding * b) { dest = bencode(dest, b->key); if (b->type & num) { sprintf(buf, "i%ld", b->intvalue); - strncpy(dest, buf, strlen(buf)); + strcpy(dest, buf); dest += strlen(buf); *dest++ = 'e'; } if (b->type & string) { sprintf(buf, "%zu:", b->valuelen); - strncpy(dest, buf, strlen(buf)); + strcpy(dest, buf); dest += strlen(buf); memcpy(dest, b->value, b->valuelen); dest += b->valuelen; diff --git a/src/dht.c b/src/dht.c index 63adcdc..513a66f 100644 --- a/src/dht.c +++ b/src/dht.c @@ -507,6 +507,8 @@ struct dht { unsigned rxrp; unsigned txrp; unsigned removed_torrents; + unsigned toomuch; + struct sockaddr_in6 insert_peer; }; /** @@ -720,6 +722,7 @@ void ping_node (struct dht * d, const struct sockaddr_in6 * a) { struct dht * dht_init (const struct bencoding * c) { struct dht * d = calloc(1, sizeof *d); + d->toomuch = 32727*1; d->time = seconds(); d->log = stderr; d->buckets = bucket_init(); @@ -755,7 +758,7 @@ struct dht * dht_init (const struct bencoding * c) { #pragma GCC diagnostic pop goto e; } -#define TOOMUCH (32727*1) +#define TOOMUCH d->toomuch unsigned pinged = 0; if (c) { const struct bencoding * id = bpath(c, "id"); @@ -1882,9 +1885,11 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) { d->possible_torrent(d, hash->value, torrent); #pragma GCC diagnostic pop unsigned i = 8; + struct bencoding * values = NULL; if (torrent) { struct peer * peer = torrent->peers; - struct bencoding * values = calloc(1, sizeof *values); + values = calloc(1, sizeof *values); + values->key = bstr(strdup("values")); values->type = list; while (i-- && peer) { // TODO implement peer preference: prefer sending peers that responded to us if (family(peer->addr.sin6_addr.s6_addr) != family(addr.sin6_addr.s6_addr)) // possible @@ -1892,14 +1897,29 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) { if (peer->flags & (unreachable || protocolerror)) goto c; struct bencoding * value = calloc(1, sizeof *value); - memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(peer->addr.sin6_addr.s6_addr))+2))), peer->addr.sin6_addr.s6_addr, ADDRLEN(family(peer->addr.sin6_addr.s6_addr))); + value->type |= string; + memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(peer->addr.sin6_addr.s6_addr))+2))), peer->addr.sin6_addr.s6_addr+(family(peer->addr.sin6_addr.s6_addr) == AF_INET ? 12 : 0), ADDRLEN(family(peer->addr.sin6_addr.s6_addr))); memcpy(value->value+ADDRLEN(family(peer->addr.sin6_addr.s6_addr)), &peer->addr.sin6_port, 2); binsert(values, value); c: peer = peer->next; } - binsert(r, values); } + if (d->insert_peer.sin6_family == AF_INET6 && family(d->insert_peer.sin6_addr.s6_addr) == family(addr.sin6_addr.s6_addr)) { + if (!values) { + values = calloc(1, sizeof *values); + values->key = bstr(strdup("values")); + values->type = list; + } + struct bencoding * value = calloc(1, sizeof *value); + value->type |= string; + memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr))+2))), d->insert_peer.sin6_addr.s6_addr+(family(d->insert_peer.sin6_addr.s6_addr) == AF_INET ? 12 : 0), ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr))); + memcpy(value->value+ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr)), &d->insert_peer.sin6_port, 2); + raise(SIGINT); + binsert(values, value); + } + if (values) + binsert(r, values); struct bencoding * tok = calloc(1, sizeof *tok); tok->type = string; tok->key = bstr(strdup("token")); diff --git a/src/main.c b/src/main.c index 199bfab..0949e4b 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include #include #define S0(x) (x ? x : "") +#define So(x, o) (x ? x : o) #define TORRENT_USERDATA struct dht * dht; #define DHT_USERDATA struct pollfd ** pollfds; size_t * pollfds_size; nfds_t * nfds; #include @@ -45,10 +46,10 @@ void found_torrent (struct dht * d __attribute__((unused)), const unsigned char L(debug, d, "%s%s", buf, t ? " stored" : " new"); if (t) { if (!t->type) - t->ttl = seconds()+256; + t->ttl = seconds()+atoi(So(getenv("TTL"), "256")); t->type |= info | peers; } else { - if (last_added + 2 > seconds()) { + if (last_added + atoi(So(getenv("COOLDOWN"), "2")) > seconds()) { L(debug, d, "not adding a torrent this fast"); return; } @@ -56,7 +57,7 @@ void found_torrent (struct dht * d __attribute__((unused)), const unsigned char t = torrent_init(); memcpy(t->hash, h, 20); t->type |= info | peers; - t->ttl = seconds()+256; + t->ttl = seconds()+atoi(So(getenv("TTL"), "256")); add_torrent(d, t); } } @@ -121,6 +122,20 @@ int main (int argc, char ** argv) { dht = dht_init(config); free_bencoding(config); config = NULL; + if (getenv("INSERT_PEER")) { + dht->insert_peer.sin6_family = AF_INET6; + dht->insert_peer.sin6_port = htons(atoi(So(getenv("INSERT_PEER_PORT"), "1337"))); + if (inet_pton(AF_INET6, getenv("INSERT_PEER"), dht->insert_peer.sin6_addr.s6_addr) != 1) { + error_at_line(0, 0, __FILE__, __LINE__, "inet_pton(AF_INET6, getenv(INSERT_PEER)) != 1"); + r = 14; + goto r; + } + error_at_line(0, 0, __FILE__, __LINE__, "feature INSERT_PEER not implemented completely -- bugs: travnik somehow starts sending packets to inserted peer ... perhaps he sends get_peers to himself?"); + r = 15; + goto r; + } + if (getenv("TOOMUCH")) + dht->toomuch = atoi(getenv("TOOMUCH")); dht->possible_torrent = found_torrent; dht->connection = connection; pollfds = malloc(sizeof *pollfds); diff --git a/travnik.py b/travnik.py index 672ed00..5b273f8 100644 --- a/travnik.py +++ b/travnik.py @@ -14,6 +14,7 @@ class Torrent(): self.files = {} self.type = Type.UNDEF self.cache = None + self.hadpieces = False def file(self, f): self.parse(open(f, "rb").read()) def parse(self, b): @@ -23,6 +24,7 @@ class Torrent(): self.dict = decode(b) if b'pieces' in self.dict.get(b'info'): self.dict.get(b'info').pop(b'pieces') + self.hadpieces = True if b'files' in self.dict.get(b'info').keys(): self.type = Type.V1 for file in self.dict.get(b'info').get(b'files'): @@ -43,6 +45,7 @@ class Torrent(): if self.type is Type.V1: self.type = Type.HYBRID else: + self.type = Type.V2 def filetree(names): r = {} for key in names.keys(): @@ -56,6 +59,8 @@ class Torrent(): self.type = Type.V1 self.files[self.dict.get(b'info').get(b'name')] = self.dict.get(b'info').get(b'length') first_filename = [i for i in self.files.keys()][0] + if self.type == Type.V2 and self.hadpieces: + self.type = Type.HYBRID; if len(self.files) == 1 and self.files[first_filename] == {}: print("fixed bad single file torrent", self.sha1.hex()) self.files[first_filename] = self.dict.get(b'info').get(b'length') -- cgit v1.2.3