{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "7e32a042", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "......\n", "fixed bad single file torrent 4f269d8aefd647ee270842d53ec98aebd23a4afe\n", "fixed bad single file torrent 7b09ae0b612dafc1744562dccbbe4becf4d633c3\n", "37769 @ 434.7589800900314 s\n" ] } ], "source": [ "from bencodepy import decode\n", "from enum import Enum\n", "from hashlib import sha1, sha256\n", "from os import scandir\n", "from time import monotonic\n", "class Type(Enum):\n", " UNDEF = 0,\n", " V1 = 1,\n", " V2 = 2,\n", " HYBRID = 3\n", "class Torrent():\n", " def __init__(self):\n", " self.sha1 = b''\n", " self.files = {}\n", " self.type = Type.UNDEF\n", " def file(self, f):\n", " self.parse(open(f, \"rb\").read())\n", " def parse(self, b):\n", " infodict = b[b.find(b'4:info')+6:b.rfind(b'6:sourced2:ip')]\n", " self.sha1 = sha1(infodict).digest()\n", " self.sha256 = sha256(infodict).digest()\n", " self.dict = decode(b)\n", " if b'pieces' in self.dict.get(b'info'):\n", " self.dict.get(b'info').pop(b'pieces')\n", " if b'files' in self.dict.get(b'info').keys():\n", " self.type = Type.V1\n", " for file in self.dict.get(b'info').get(b'files'):\n", " if file.get(b'attr') is not None and b'p' in file.get(b'attr') or b'padding.file' in b'/'.join(file.get(b'path')) or b'.pad' in file.get(b'path'):\n", " continue\n", " def insert_file(d, path, length, self):\n", " name = path.pop()\n", " if not len(path):\n", " d[name] = length\n", " return\n", " if name not in d.keys():\n", " d[name] = {}\n", " insert_file(d[name], path, length, self)\n", " file.get(b'path').reverse()\n", " insert_file(self.files, file.get(b'path'), file.get(b'length'), self)\n", " self.dict.get(b'info').pop(b'files')\n", " if b'file tree' in self.dict.get(b'info').keys(): # some torrents have broken file trees so we use files first\n", " if self.type is Type.V1:\n", " self.type = Type.HYBRID\n", " else:\n", " def filetree(names):\n", " r = {}\n", " for key in names.keys():\n", " if key == b'':\n", " return names.get(key).get(b'length')\n", " r[key] = filetree(names.get(key))\n", " return r\n", " self.files = filetree(self.dict.get(b'info').get(b'file tree'))\n", " self.dict.get(b'info').pop(b'file tree')\n", " if not len(self.files):\n", " self.type = Type.V1\n", " self.files[self.dict.get(b'info').get(b'name')] = self.dict.get(b'info').get(b'length')\n", " first_filename = [i for i in self.files.keys()][0]\n", " if len(self.files) == 1 and self.files[first_filename] == {}:\n", " print(\"fixed bad single file torrent\", self.sha1.hex())\n", " self.files[first_filename] = self.dict.get(b'info').get(b'length')\n", " def paths(self):\n", " def paths_r(d, path=None):\n", " if path is None:\n", " path = []\n", " for f in d.keys():\n", " if type(d[f]) is int:\n", " z = path.copy()\n", " z.append(f)\n", " yield z, d[f]\n", " else:\n", " z = path.copy()\n", " z.append(f)\n", " for z, v in paths_r(d[f], z):\n", " yield z, v\n", " for z, v in paths_r(self.files):\n", " yield z, v\n", " def __repr__(self):\n", " return str(self.__dict__)\n", " def __hash__(self):\n", " if len(self.sha1):\n", " return int.from_bytes(self.sha1, byteorder=\"big\")\n", " return id(self)\n", "def glob(d):\n", " r = {}\n", " for f in scandir(d):\n", " if f.name.endswith(\".torrent\") and f.is_file():\n", " t = Torrent()\n", " t.file(f.path)\n", " r[t.sha1] = t\n", " return r\n", "print(\"......\")\n", "start = monotonic()\n", "torrents = glob(\"/root/projects/travnik\")\n", "print(len(torrents), \"@\", monotonic()-start, \"s\")\n", "# t = Torrent()\n", "# t.file(\"/root/projects/travnik/449a38ef7e042bd2d75e8921aa02f6f244165d9d.torrent\")\n", "# print(t.sha1.hex())\n", "# for path, length in t.paths():\n", "# print(path, length)\n", "# print(t)" ] }, { "cell_type": "code", "execution_count": 30, "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": [ "0.22313746600411832 za 67 različnih odjemalcev\n" ] } ], "source": [ "s = monotonic()\n", "def uas(normalize=True, minrepr=0):\n", " odjemalci = {}\n", " for sha1, torrent in torrents.items():\n", " odjemalec = torrent.dict.get(b'source').get(b'v')\n", " if normalize and odjemalec is not None:\n", " if b'/' in odjemalec:\n", " odjemalec = odjemalec.split(b'/')[0]\n", " elif b' (' in odjemalec:\n", " odjemalec = odjemalec.split(b' (')[0]\n", " else:\n", " odjemalec = odjemalec.split(b' ')[0]\n", " odjemalec = odjemalec.replace(b'\\xc2\\xb5', b'\\xce\\xbc').decode()\n", " if odjemalec not in odjemalci.keys():\n", " odjemalci[odjemalec] = 1\n", " else:\n", " odjemalci[odjemalec] += 1\n", " trueodj = {\"ostali\": 0}\n", " count = 0\n", " for key, value in odjemalci.items():\n", " count += 1\n", " if value < minrepr:\n", " trueodj[\"ostali\"] += value\n", " else:\n", " trueodj[key] = value\n", " trueodj = [(v, k) for k, v in trueodj.items()]\n", " return trueodj, count\n", "odjemalci, count = uas(True, minrepr=0*len(torrents))\n", "odjemalci = sorted(odjemalci, reverse=False)\n", "from matplotlib import pyplot\n", "%matplotlib notebook\n", "fig, axes = pyplot.subplots()\n", "from math import log\n", "# axes.pie([log(sights) if sights else 0 for sights, name in odjemalci], labels=[name for sights, name in odjemalci])\n", "axes.barh([name if name is not None else \"neznan\" for sights, name in odjemalci], [sights for sights, name in odjemalci])\n", "axes.set_title(\"log skala odjemalcev\")\n", "pyplot.xscale(\"log\")\n", "fig.show()\n", "print(monotonic()-s, \"za\", count, \"različnih odjemalcev\")" ] }, { "cell_type": "code", "execution_count": 31, "id": "52de34d6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.15033814194612205 s 40\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", " [2, 1, 'fa6fbc7d7796e49fbdf47731fe06a6e20ee74bb5']\n", "abc [2, 'abc', '9c8047972d058dee41bab8ab68ad5da7c24275ed']\n", "nnm-club_cool [3, 1, '57f6facb1bcef159b8075b578053fb4790e0c8d5']\n", "x-amz-bucket [5, 'quranwave', '3af8e25c9eeca9402351820d8681fe0945c63cdb']\n", "x-amz-key [5, 'torrent/70.zip', '3af8e25c9eeca9402351820d8681fe0945c63cdb']\n", "tracker [6, '', 'e8ca2609b174df7b5c26538fb6f96d77a367da42']\n", "attr [11, 'h', 'c9a279c4dff3b38ef806abb98515382798907654']\n", "comment [11, 'Torrent downloaded from torrent cache at http://torcache.net/', 'e92cd8e1ed1defad6d5211a42d2dbdf1e368b834']\n", "unique [11, 'fbvPqZTXkKQzRJzy6LXkdIp3iJoTNe', '3a84117d98683bd4a657a37932886d206486c11e']\n", "sha256 [12, 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 [39, 1400017482, '4488d559d4404875022d53c6039b0025c947ac84']\n", "md5sum [39, 'e27e7b621f0adbcf072e4f13d78c4fc8', 'ef0c6b03d16457e1134bc63c18d527221639da8e']\n", "cross_seed_entry [44, '02e940fec782a353d2e767cecde08041', 'b7c0ac4a9834c8e39f543f3f721eb90fbb58e179']\n", "sha1 [72, b'\\xbe^\\xdc\\xd8\\x99\\x98\\xf0\\xe8_\\x8d\\xcbZ\\xc7\\xd21\\t`\\xec\\x9c\\xee', 'b4bf549d9d48bce1c1e026ff451ee76069b98c00']\n", "file tree [81, 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", "collections [100, [b'org.archive.relaxingsounds'], 'ed7d4e9657cbfcde6baf89ace313ae77a1cefe91']\n", "meta version [251, 2, '18d35502fca02a30811e4e001809ddd4147167e6']\n", "filehash [252, b'\\xc9m.\\x93\\xbd\\x18fj:\\xb3${\\x9ak\\x9e\\xdbUI\\xf2\\xb5', '44af4eb9d35b94218b6fe5eb25a30b8e22fa5844']\n", "ed2k [307, b',\\xf0O\\x9e\\x829\\x8e\\x1b{\\xf58\\xea\\x94\\n\\xe8\\x92', '44af4eb9d35b94218b6fe5eb25a30b8e22fa5844']\n", "source [737, 'BT世界网 https://www.btsj6.com/', '417ef639eb95fbf68175a6a6b03076f9ee5f5744']\n", "file-duration [959, [0, 0, 39097], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", "file-media [959, [-1, -1, 0], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", "profiles [959, [OrderedDict([(b'acodec', b'aac'), (b'height', 0), (b'vcodec', b''), (b'width', 0)])], '449a9054916600bc0a395a47c4a2421aa06ad04a']\n", "publisher-url.utf-8 [1408, 'http://my155.cc', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", "publisher.utf-8 [1454, '小隻馬', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", "publisher-url [2051, 'http://my155.cc', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", "publisher [2158, '小隻馬', '4488cffb9ad5afc1174bc96754e9887158ce03eb']\n", "name.utf-8 [2958, '60 Assorted Magazines Collection PDF September 4 2022 Set 3', '449a9e0e7375b6b6b7f55bdd6214f034a2edd4b8']\n", "private [4420, 0, '449f65629260c258a999e6474f22ae00e83ee47a']\n", "length [12420, 5209971966, '449a38ef7e042bd2d75e8921aa02f6f244165d9d']\n", "name [37600, 'Big Buck Bunny', 'dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c']\n", "piece length [37600, 262144, 'dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c']\n" ] } ], "source": [ "s = monotonic()\n", "keys = {}\n", "for sha1, torrent in torrents.items():\n", " for key in torrent.dict.get(b'info').keys():\n", " if key.decode() not in keys.keys():\n", " value = torrent.dict.get(b'info').get(key)\n", " if type(value) is bytes:\n", " try:\n", " value = value.decode()\n", " except UnicodeDecodeError:\n", " pass\n", " keys[key.decode()] = [1, value, sha1.hex()]\n", " else:\n", " keys[key.decode()][0] += 1\n", "sort = sorted(keys, key=lambda x: keys[x][0])\n", "print(monotonic()-s, \"s\", len(keys))\n", "%matplotlib notebook\n", "fig, ax = pyplot.subplots();\n", "ax.barh(sort, [keys[x][0] for x in sort])\n", "pyplot.xscale(\"log\")\n", "pyplot.xlabel(\"število pojavitev ključa v slovarju info\")\n", "fig.show() ## TODO komentiraj\n", "for i in sort:\n", " print(i, keys[i])" ] }, { "cell_type": "code", "execution_count": 32, "id": "fea0f2b6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.07545290817506611 s 92.2872340425532 brez ključa source, publisher ali publisher-url 729 virov\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
PMEDIA 134
http://tapochek.net/index.php 114
高清下载吧! 98
https://FreeCourseWeb.com 91
灣搭拉咩拉 79
脫拉庫 69
1024社區最新地址 68
第一會所新片@SIS001 64
大师兄福利网 59
2048 56
53
LostFilm.TV 50
[https://tanhuazu.com] 探花族社区 37
RV原创 37
2048核基地 37
https://hjd.tw 35
小贾_KTXP 33
1024核工厂 33
https://crackshash.com/ 29
國產精品 28
https://rh2048.com 27
吃雞大神 26
1024社區 26
b48t.com 25
麻豆之神 24
欧宝 24
老含及 24
小隻馬 20
@蜂鳥论坛@ 20
JAV Torrent 掲示板 20
AV大平台 19
刷刷刷 18
第一會所新片 18
发发发 18
1024 17
1024工厂 17
Weagogo 16
hjd.tw 16
https://1tors.ru/ 15
b'\\xcf\\xeb\\xb7\\xa2\\xc8\\xb4\\xb2\\xbb\\xbb\\xe1' 14
olo 13
不予 13
老司机论坛 13
小樱 12
xp1024 12
(美女裸聊直播 uur68.com) 12
美女裸聊直播 11
發片小王子@18p2p 11
b'\\xb3\\xcc\\xb7sAV \\xa4\\xd1\\xaa\\xc5\\xbd\\xd7\\xbe\\xc2 IP' 11
BT世界网 https://www.btsj6.com/ 10
[animelayer.ru] Animelayer 10
nyaa001 10
https://discord.gg/vbJ7RTn 10
PiRaX @ TamilBlasters.Net 10
orion 10
愛在黑夜001 10
b'dioguitar23(\\xb2\\xc4\\xa4\\xbb\\xa4\\xd1\\xc5]\\xa4\\xfd)\\xad\\xec\\xb3\\xd0' 9
U6A6磁力搜索---U6A6.COM 9
https://infocon.org/ 9
约战竞技场 9
xue0117 9
BBVC 9
Zelka.ORG 8
threesixtyp 8
dio88.net(第六天魔王)@最新AV海量免費播放~魔王在線 8
dioguitar23(第六天魔王)@dioguitar23.net 8
規懶趴會 8
b'\\xc1\\xf9\\xd4\\xc2\\xc1\\xaa\\xc3\\xcb' 7
百撸社区|高清资源 7
Zamunda.NET 7
百撸社区 7
www.dio8899.net(第六天魔王)@最新AV海量免費播放~魔王在線 7
K8bet 6
cangkong 6
[tp.m-team.cc] M-Team - TP 6
dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線 6
b'\\xb7\\xf6\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1 dioguitar23 \\xad\\xec\\xb3\\xd0' 6
00armand00 6
6969bt.com 6
[https://majomparade.eu] 6
鱼香肉丝 6
性吧RV原创 5
Burnbit 5
94i88影城-点击跳转 5
♥im520♥ 5
arsenal-fan 5
[http://x-torrents.org] X-Torrents.org 5
1024核工厂/ 5
PMEDIA NETWORK 5
arsenal-fan@avsp2p.com 5
https://www.javhdbbs.com 5
dioguitar23(第六天魔王)@mw6.me 5
成年人的小游戏 5
Hotaru 5
Mp4Ba 4
b'\\x9e\\xb3\\xb4\\xee\\xc0\\xad\\xdf\\xe3\\xc0\\xad@kb978.com' 4
https://downloadcursos.top/ 4
youiv 4
rutracker.org 4
yoy123 4
olo@SIS001 4
上善若水@www.sexinsex.net 4
b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1~\\xc5]\\xa7\\xd9\\xad\\xec\\xb3\\xd0' 4
魔王之家 4
杏吧 4
dio66.net(第六天魔王)@最新AV海量免費播放~魔王在線 4
更多精彩!尽在99BT工厂@5120911 4
hotaru 4
xueru10405 4
1030社區---1030.ws 4
x 4
www.crackshash.com 4
1stDragon 4
buxxa 4
www.dio7777.net(第六天魔王)@最新AV海量免費播放~魔王在線 4
BT-btt.com 4
kenelm 4
HiHBT 精品薈萃 4
m6688.net(第六天魔王)@最新AV海量免費播放~魔王在線 3
杏吧论坛 3
XIU 3
atrrea 3
1314 3
oldman原創DVD@18p2p.com 3
sogood@18p2p 3
? nike ? 3
https://toonshub.xyz 3
https://www.torrentdosfilmes.tv/ 3
1024社区 3
dioguitar23(第六天魔王) 3
广东雨神 3
RZK 3
rxrj 3
枫雪动漫 3
YURASUKA 3
【神秘巨星CI】 3
GIF出处系列 3
https://www.terralibera.net/ 3
dioguitar23@dio66.net 3
dioguitar23(第六天魔王)@hotavxxx.com 3
萌你一脸@第一会所 3
罗马教皇@草榴社区 luckjam@sexinsex.net 3
么么哒 3
XP1024 3
nyaa.si 3
uid-346380 3
Download from Sajber.org/blog 3
美女裸聊约炮 3
@微信订阅号专注稀有汁源 3
susun=eastv 3
M88(明陞) 3
rh2048.com/ 3
99BT工厂 @ 5120911 3
衣选集团 3
b'\\xc1\\xf9\\xd4\\xc2\\xcc\\xec\\xbf\\xd5' 3
【RV原创】【sex8.cc】 3
Gfker@1024核工廠 3
b'99\\xa5\\xfd\\xa5\\xcd' 3
漫之学园 3
https://DesignOptimal.com 3
9200 3
安西教练 3
尘封追忆+色十八 3
zgome@18p2p 2
顶冠文化 2
MN Nambiar @ TamilBlasters.Net 2
老司机 2
dioguitar23.net(第六天魔王)@最新AV海量免費播放~魔王在線 2
https://media.defcon.org/ 2
https://sexasia.net/feed 2
黑色点击 2
http://www.acgyinghua.com/ 2
嗨咻阁 2
Lucian2009@第一会所 2
dioguitar23(第六天魔王)@bbs.hotavxxx.com 2
roger92402094 2
lxdng1218 2
飘嫖 2
红馆-红人馆-网络红人之家 2
CHANNEL NEO 2
ccc32.com 2
chikan 2
神秘巨星CI 2
dioguitar23(第六天魔王)@dio999.com 2
注册就送39元,联系:330545486 2
b'\\xb7\\xf6\\xba~\\xad\\xd1\\xbc\\xd6\\xb3\\xa1@\\xb4A\\xab\\xbd\\xa8\\xe0' 2
ITELLYOU 2
联系TG:yyllzy,fulihuoqu 2
強片皇帝999 2
sogclub No.2 2
D2mp4 2
mmklp@第一会所 2
ssss1111@18p2p 2
bbvc 2
感冒清@sis001 2
afnami@64.78.163.55 2
西門吹水 2
goldpuzjying 2
uid=1591117 2
[http://rudub.tv] RuDub.TV 2
GF@1024核工廠 2
www.javhdbbs.com 2
蜂鸟色区 2
b'\\xb3\\xc7\\xca\\xd0\\xefL\\xc7\\xe9~\\xc4\\xa7\\xbd\\xe4\\xd4\\xad\\x84\\x93' 2
[http://energy-torrent.com] Energy-Torrent 2
SoushkinBoudera 2
[http://bko.baibako.tv] BaibaKo.TV 2
Western/HD-Jiggly 2
冷月无声 2
奥利给 2
b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1~\\xa4p\\xb9t\\xad\\xec\\xb3\\xd0' 2
b'tanw\\xa9\\xceyk3325@www.sogclub.com' 2
3Li 2
b'giogio99\\xad\\xec\\xb3\\xd0' 2
BradPitt 2
遁去的壹 2
downloadcursos.top 2
KTXP_秋沫 2
xinnian 2
18p2p by_UID 1380364 2
https://bbs2048.org/ 2
https://www.1024btgc.com 2
清雨 2
crazylazy 2
感冒清@sis001.com 2
MingYSub 2
淘宝天猫优惠券秒杀 2
Downloaded from CracksHash.com 2
会飞的象@第一会所 2
mule_by_SpeedPluss.ORG 2
https://rutor.org 2
BT伙计 2
hhd800.com 2
gnhyc11@18p2p.com 1
fyoulapk@18p2p 1
塔卡小爹賽 1
HD一条街论坛 1
dioguitar23原創 1
b'\\xb3\\xce\\xbf\\xd5\\xd1\\xa7\\xd4\\xb0' 1
cnmzlwb 1
zb77@18p2p 1
https://www.asmr.one/work/RJ374870 1
[uid-1591117] 1
奈特羅德 1
https://mega.nz/#F!DK4lCSwB!QdwaMCT3SpOxISAgnuX7nQ 1
小葫芦@www.sis001.com 1
柏林没有梦 1
ls611 1
qqtnt007 1
3E523E31D247_by_FDZone.ORG 1
JPopsuki 2.0 626225292 1
https://elamigosedition.com/ 1
guroemon 1
lyf634041775 1
1234567890 1
https://bitnova.info/ 1
asfile@SIS001 1
b'\\xbd\\xad\\xc4\\xcf\\xb7\\xe7\\xd3\\xea' 1
mikocon @ bbs.2djgame.net 1
http://mm.aayun.cc 1
aqcd123 1
维尼 1
iii 1
pornolab 1
极影字幕 1
b'\\xc9\\xab\\xd6\\xd0\\xc9\\xab@ypzhq\\xd4\\xad\\xb4\\xb4' 1
roger92402094(SIS) 1
erest 1
Baslilon=Baslilon23 1
b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1 dioguitar23 \\xad\\xec\\xb3\\xd0' 1
sigma 1
寂寞如漫天雪花 1
C:\\Users\\pongphon\\OneDrive\\Desktop\\New folder (2)\\FC2PPV 1218169 [Odorless video] [Leaked] JULIA High image quality BEB-016 JULIA Sweaty Backroom .ts 1
JPopsuki 2.0 2131292835 1
不予@暗香阁 1
sogclub No.2 BY sogclub 1
uid-1591117 1
b'\\xba\\xda\\xc2\\xfb\\xb0\\xc5' 1
微信一夜ONS协会 1
b'KUHO\\xd2\\xd5\\xca\\xf5\\xc1\\xaa\\xc3\\xcb' 1
b'\\xb6\\xc0\\xa5i\\xa8\\xe0_by_FDZone.org' 1
中文字幕無水印 1
http://www.wozai020.com 1
sop168 1
b'SP\\xa7\\xe4\\xbc\\xd6\\xa4l@\\xaa\\xe1\\xa9M\\xa9|' 1
tiantianlu186@公仔箱論壇 1
luckyjune 1
SK`|yEsMan<sk·> 1
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' 1
hkkane@18p2p 1
www.4hu.com 1
b'\\xaeL\\xaa\\xef\\xacK@99p2p' 1
夜蒅星宸@第一会所 1
【更多资源用加手机QQ-17182252050】 1
jjjhn2003@18p2p 1
XIEYUXIA 1
b'@\\xc0\\xcb\\xb7\\xad\\xd4\\xc6@' 1
www.dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線 1
TYBBX2 1
yjs521 1
hhbb_zcm 1
twsb.co 1
https://downloadcursos.top 1
https://www.musicastorrent.com/ 1
pandafood#panda1314#gg5123 獨家首發 1
探花族 1
zhoudehua200 1
AV大平台 - 发布页 1
b'tanw\\xa9\\xceyk3325' 1
Rivera@18p2p.com 1
b'\\xd7\\xcf\\xc3\\xb5\\xb9\\xe5' 1
[kp.m-team.cc] M-Team - TP 1
www.spankhash.com 1
UID 235465@www.mimip2p.net 1
草榴社区@MianSheng 1
Странник 1
hgr168168 1
BJ 1
mecaca 1
昆仑虚之巅@草榴社區 1
[欧美美@草榴社区] 1
没线的风筝 1
尼尼撸-综合网站 1
100%真人激情裸聊 www.78xo.com 1
jettej 1
Daddy 1
diamond 1
中文片库 1
https://worldmkv.com 1
b'yatsingkoon@\\xa1\\xb9\\xb6q\\xb3c\\xa4\\xc0\\xa8\\xc9\\xbd\\xd7\\xbe\\xc2\\xa1\\xb9' 1
入微 1
https://discord.com/invite/wweVHZd6qg 1
602@第一会所 1
3484988vikci@第一会所 1
evilzy 1
化骨龍 1
https://www.kobo.com/ebook/an-archdemon-s-dilemma-how-to-love-your-elf-bride-volume-13 1
cqkd_czy 1
不辣de皮特 1
kaito 1
u3c3.com 1
☆影视帝国论坛☆ 1
aaa23 1
hevcbay.com 1
gn7650104 1
老舅电影 1
捕鼠人 1
https://www.gamestorrents.nu/ 1
Aidoru-Online 1
公主殿下@第一會所 1
MP4BA电影网 1
b'\\xb8\\xb4\\xbb\\xee126' 1
微信公众号:卡其影视分享 1
百虎动画 1
425307@癡漢俱樂部 1
avp2p 1
GIFchuchushipin 1
EndlesSea 1
Tanhuazu-探花族 1
推特搞啥呢 1
@K8bet.io@ 1
Misfits 1
黑暗虫洞 1
magazinesbb.com 1
b'\\xc9\\xab\\xd6\\xd0\\xc9\\xab\\xd5\\x93\\x89\\xaf@www.SIS.xxx' 1
草榴社区@z10271 1
冰封爱河 1
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' 1
zhangqq789@第一会所 1
wangye6 1
ann@myfun4u.org 1
kino9999@18p2p 1
b'CHD\\xc1\\xaa\\xc3\\xcb' 1
satu@hongfire 1
polee 1
GM3089@18P2P 1
BT工厂 @ 5120911 1
【U6A6.COM】_全网磁力最快更新 1
sklc-P2P101.COM 1
b'\\xb0\\xcb\\xd6\\xd8\\xf7\\xec' 1
b'\\xcc\\xda\\xb7\\xc9\\xd4\\xda\\xcf\\xdf' 1
b'doa_o[\\xb9\\xc5\\xce\\xef\\xce\\xdd]' 1
缘聚岛 1
素人辣妹正妹報報 1
b'sweetsmile@CHD\\xc1\\xaa\\xc3\\xcb' 1
javtv.me 1
zhaochuan99 1
草榴社区 1
四魂制作组 1
动漫花園 1
View my conspiracy torrents at 1
春卅娘@18p2p 1
1024核工厂最新地址 1
JPopsuki 2.0 904012437 1
wearebest@18P2P 1
HTCdesireHD@第一會所 1
11.55 1
shinjico 1
得得撸 www.dedelu.com 1
Western&HD-Jiggly 1
ningchia 1
filelist.ro 1
dengzhi123_by_FDZone.ORG 1
b'\\xab\\xb0\\xa5\\xab\\xad\\xb7\\xb1\\xa1 dioguitar23(\\xb2\\xc4\\xa4\\xbb\\xa4\\xd1\\xc5]\\xa4\\xfd)\\xad\\xec\\xb3\\xd0' 1
HZHJS 1
Audible 1
skyuz 1
ever 1
El tio WAPILLO :v 1
草莓TV 1
加菲豆@第一会所 1
yaoshiqiao 1
PB 1
b'\\xb9\\xda\\xa4\\xbd\\xb6\\xe9\\xaeT\\xbc\\xd6\\xa4u\\xa7{@p16847' 1
54CECB5A0EA7_by_FDZone.ORG 1
b'\\xc0\\xcb\\xd7\\xd3\\xd0\\xa1\\xb5\\xb6' 1
rendell_by_mimip2p.net, rendellxx_by_fdzone.org, rendell@SexInSex! 1
https://e-hentai.org 1
https://to-url.com/torrent-igruha 1
jinzebin86@18p2p.com 1
birdmanfocker@18p2p 1
GH37DgaBef6rQJyE2nvqb5YpS 1
AVdian@126.com 1
亞瑟王 1
b'Bianca_Cooper_Touch99.com \\xa6\\xb3\\xa7\\xf3\\xa6h\\xa6n\\xb9\\xcf' 1
wT3j6PNrC5aOcD04yJ7xRotF8 1
村花论坛 1
b'\\xc4\\xfa_\\x89\\xf4\\xb9\\xab\\x88@\\x8a\\xca\\x98\\xb7\\xb9\\xa4\\xb7\\xbb' 1
FISH321@18P2P 1
第一会所 sis001 1
huPE@18P2P 1
houlai=biaoqian 1
b'qilibi@\\xc1\\xf9\\xd4\\xc2\\xc2\\x93\\xc3\\xcb' 1
天池妖尊 1
sing0212000 1
wandy_by_FDZone.org 1
XO@kazamis 1
百撸社区|高清影片 1
KOOK 1
HQC 1
mc733 1
爱游戏 1
1158012^@^18p2p 1
b'Bianca_Cooper \\xa7\\xf3\\xa6h\\xac\\xfc\\xb9\\xcf\\xa5u\\xa6bTouch99' 1
xiaocuitj 1
星星不舔屄 1
https://www.crnaberza.com CrnaBerza 1
boby@mimip2p 1
magnet360@163.com 1
Japanadultvideos 論壇 <-----按此瀏覽更多 1
[http://x-torrents.nu] X-Torrents.org 1
euphoricer 1
2048核基地!! 1
zlb273692399@第一会所 1
花和尚 1
b'\\xb4\\xbf\\xb0\\xae\\xc9\\xe7\\xc7\\xf8/wbzt' 1
三石@第一会所 1
JackyCheung@草榴社區 1
b'\\xbf\\xe7\\xca\\xa1\\xbe\\xdc\\xb7\\xf1@9999999' 1
菜牙电影网 1
mehappy2012 1
https://www.jp.square-enix.com/music/sem/page/chrono/trigger_revival/ 1
Scientists used to invent telephones, airplanes, microwave ovens... now all they invent is statistics that say they should get more funding. 1
RoxMarty 1
rczhi@18p2p.com 1
kkk8568 1
kenan2763 1
arthurwarlike@第一会所 1
b'\\xb3\\xc7\\xca\\xd0\\xefL\\xc7\\xe9~~\\xcb\\xba\\xd2\\xb9\\xd4\\xad\\x84\\x93' 1
東方明珠=ccvvm 1
从小缺钙 1
Jackie 1
www.lupola.com 1
ashow.cc 1
品色影院 1
8400327@草榴社區 1
gamezealot@18p2p 1
uhla454@第一会所 1
宅鱼 1
1024核工厂 Bt7086 1
hilllxs 1
豺狼也柔情 1
99堂 1
老肥 1
Chikyuji-Animes, 2006 maggle! 1
chaorentwo@18p2p 1
若無其事@18p2p.com 1
hhd000.com 1
掠风窃尘 1
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' 1
Kura999 from WaikeungBBS 1
XFSUB 1
huiasd 1
b'Rory @ D.C.\\xb8\\xea\\xb0T\\xa5\\xe6\\xacy\\xba\\xf4' 1
https://t.me/deletetvwrestling 1
dodododo 1
Rambo@18p2p 1
b'\\xce\\xde\\xd0\\xc4\\xce\\xde\\xb4\\xe6' 1
filmplay 1
avdian@126.com 1
1025 1
956828@18p2p 1
夜游神 1
b'\\xb2\\xbb\\xb5\\xc3\\xb2\\xbb\\xc9\\xab' 1
vbiukj 1
buxxa=bbvc 1
jnd16d 1
烽火不熄 1
pietro716 1
Lus 1
b'\\x98Y\\xd4\\xad\\xa4\\xe6\\x97@' 1
國產無碼 1
b'\\xd0\\xc2\\xc7\\xd7\\xc3\\xdc\\xb0\\xae\\xc8\\xcb\\xc2\\xdb\\xcc\\xb3@\\xd6\\xc1\\xd7\\xf0\\xcc\\xec\\xc1\\xfa' 1
wangzhifeng@18p2p 1
dabohong_by_fdzone.org 1
TODO 1
b'\\xb7\\xc9\\xd3\\xb0\\xbf\\xcd\\xcd\\xf8' 1
yav.me 1
http://www.jizhang1.space/?3316427 1
pin0314(1470)@www.mycould.com 1
handsomemouse@18p2p 1
b'\\xa4\\xc6\\xb0\\xa9\\xc0s@mimip2p' 1
面瘫 1
弄死你娃L@2018x.win 1
yyyyyuuuuu@18p2p 1
狼主@SexInSex.net 1
1394130143@第一会所 1
jove 1
电骡爱好者 1
westkyo@www.sis001.com 1
lzmcmbj@18p2p 1
dioguitar23(第六天魔王)@dioguitar23.me 1
VISTOR_by_FDZone.ORG 1
chris930 1
[WMAN-LorD] [UHD] [4K] [2160p] [REAL4K] [TGx] 1
b'A\\xab\\xac\\xa4\\xa3\\xa8}\\xc3\\xc8' 1
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' 1
Domaha.tv 1
destiny999@18p2p 1
水母飄 1
HOUSEKEEPER 1
RV原创组 1
月岚星辰520@第一会所 1
b'\\xc3\\xe2\\xb7\\xd1\\xd4\\xda\\xcf\\xdf\\xd2\\xf4\\xc0\\xd6' 1
www.1024pk.com 1
爱城 1
amge50@www.sogclub.com 1
OneStar 1
b'Jocky123#\\xb8\\xfc\\xb6\\xe0\\xb5\\xc4\\xbe\\xab\\xb2\\xca\\xd3\\xb0\\xc6\\xac!' 1
https://getcomics.info 1
点击-海量种子 1
btziyuan 1
[http://x-torrents.org] X-Torrents.org (ex X-Torrents.ru) 1
https://www.lspback.com 1
foxmoder996 1
https://share.dmhy.org/topics/list/user_id/712935 1
玛尔亲王@第一会所 1
rtjhuytu 1
淨空法師專集網站 1
b'\\xa1\\xb6\\xbd\\xcc\\xd3\\xfd\\xca\\xd6\\xc0\\xad\\xca\\xd6\\xa1\\xb7' 1
mc733+zgome 1
Goddess 1
NikeのB@第一会所 1
b'dvt\\xb0\\xc9' 1
微博:止于影书,公众号:影遇见书,@小鱼 1
free4 1
靜風@sis001 1
kaniuniu 1
dcsk_By_FDZone.org 1
sigma@www.mimip2p.com 1
看翍荭尘 1
bjiok 1
lins2b 1
小馬克_by_FDZone.ORG 1
FSFS555@第一会所 1
flowerff 1
lascruces 1
?nike? 1
SEX8.CC 1
b'\\xb3\\xc9\\xc8\\xcb\\xc2\\xdb\\xcc\\xb3\\xbf\\xaa\\xb7\\xc5\\xd7\\xa2\\xb2\\xe1' 1
dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線 1
APKMAZA.CO 1
13121152@18p2p 1
UID 185363@www.mimip2p.com 1
b'\\xa4^\\xa4\\xa2\\xb5\\xbe@FDZone.org' 1
更多资源联系qq1273288348 1
https://nyaa.si/user/mrshowoff 1
https://boards.4channel.org/h/#s=hentai+upscales 1
mimu@18P2P 1
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' 1
殇情 1
风来西林 1
www.loliba.info 1
b'Nike\\xa4\\xce\\xa3\\xc2' 1
[www.pttime.org] PT时间 1
QxR 1
sunchiua_by_P2Pzone.org 1
wazx528 1
popgofansub 1
b'\\xc3\\xe2\\xb7\\xd1\\xb5\\xe7\\xd3\\xb0\\xcf\\xc2\\xd4\\xd8\\xbb\\xf9\\xb5\\xd8' 1
gremichaem 1
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' 1
sukebei.nyaa.si 1
pademon18p2p 1
aaamfk+zgome+bbryans 1
cyxy@http://38.114.38.172/forum/ 1
b'\\xd3\\xd7\\xc5\\xae\\xbc\\xab\\xc6\\xb7' 1
https://e-hentai.org/g/2375721/1b5e081312/ 1
18P2P_dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線 1
b'AV\\xce\\xc4\\x99n\\xa3\\xfcADULT INTEGRATED COMMUNITY' 1
UID 1357210@18P2P.com 1
fuckkkingou 1
闲云野鹤 1
LAPUMiA.NeT 1
adult_cn 1
psoke 1
18p2p@liyang8926 1
littlefatbee 1
秋叶TV 1
msy91 1
Niraya 1
https://www.kobo.com/ebook/that-time-i-got-reincarnated-as-a-slime-vol-13-light-novel 1
JPopsuki 2.0 941661648 1
yamyedye@18P2P 1
dansnow 1
H2CO3 1
b'\\x8e\\xf7\\x8e\\xf7@\\x88\\xc3\\x91\\xe9\\x9a\\xa0\\x8c\\xb4\\x91n' 1
kamigami 1
G@1024核工廠 1
The Seaside Corpse 1
b'\\xadw\\xbd\\xde_by_FDZone.ORG' 1
fangbayern 1
君乐 1
Doctor Who 1
第一流氓@18P2P 1
Deviloid.net 1
b'\\xc1\\xf9\\xd4\\xc2\\xc1\\xaa\\xc3\\xcb hgfhgf' 1
wcer@18p2p.com 1
https://www.yitarx.com 1
wuchengzhou9000@www.SexInSex.net 1
nwcd 1
p2p_user@mimip2p 1
zza@live.com 1
清风浪子@草榴社区 1
http://www.zone54.com 1
ssan998 1
xxfhd.com 1
mybmw320_by_SpeedPluss.ORG 1
woaibt@1024核工厂 1
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' 1
hegongc163 1
bigwai 1
t66y 1
cctc55 1
tto@18P2P 1
Antidot Team 1
Torrent Galaxy 1
萤火虫IT服务全国连锁 1
葬爱@18p2p 1
贴心话 1
xuerui810405 1
SoulSeek 1
abbt@18p2p.com 1
深深可许@第一会所 1
lixuhua 1
b'\\xcc\\x93\\x9fo' 1
animekayo.com 1
qiupianhao 1
173489627 1
wak11110@18P2P 1
[http://hdtracker.org] HD TRACKER 1
www.eien-acg.com 1
index0123 1
hndwje 1
http://www.meitubb.com/forum.php 1
最新地址 1
https://anidb.net/file/3082403 1
更多精彩 @ 卡卡拉 1
olo@第一会所 1
https://e-hentai.org/g/2255154/778b4d24e6/ 1
sujinding@第一会所 1
MKO 1
chleicool=fym0624=patpat608 1
撸二九论坛 1
flybird186 1
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' 1
https://www.omgyes.com 1
DVD 2008 1
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' 1
>亞捷視圖< 1
b'\\xb9\\xfd\\xc5\\xab\\xd6\\xc6\\xd4\\xec\\xb2\\xa9\\xbf\\xcd' 1
3267506 1
中国电信 1
9clonely 1
b'\\xd2\\xf9\\xc3\\xf1\\xcd\\xf2\\xcb\\xea' 1
幸运流星@四仔论坛 1
Lista Espiritualista 1
雪光梦想 1
https://exhentai.org/g/1964478/8ed0a899ca 1
olo@sis001 1
3zi@第一會所 1
Andy 1
b'\\xb7\\xd6\\xcf\\xed' 1
24262830. 1
食色性者 1
aj11@mimip2p.net 1
srwH 1
鴻仔 1
校园迷糊大王 1
WCG 1
b'(\\xd3\\xf4\\xc3\\xc6)\\xb0\\xae\\xbf\\xb4\\xb5\\xe7\\xd3\\xb0' 1
kiva@18p2p 1
b'\\xbb\\xd8\\xbc\\xd2001@18p2p' 1
ffxx 1
judexkwok(SIS) 1
chikan@T66Y 1
瑞倪维儿护肤专卖 1
auriga@18p2p 1
yinchong818@(sis) 1
ntlv0@hotmail.com 1
酷安 1
jav20s8.com/ 1
JPopsuki 2.0 14486345 1
若無其事@18p2p 1
b'stormly+taitan12+zhaoZero41+chinami2002+glen246+faberge@darkeagle-\\xbax\\x84\\xf0\\xaa\\xc0' 1
CMCT团队荣誉出品 1
kennyboy 1
2AV.COM 1
" ], "text/plain": [ "'\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
PMEDIA 134
http://tapochek.net/index.php 114
高清下载吧! 98
https://FreeCourseWeb.com 91
灣搭拉咩拉 79
脫拉庫 69
1024社區最新地址 68
第一會所新片@SIS001 64
大师兄福利网 59
2048 56
53
LostFilm.TV 50
[https://tanhuazu.com] 探花族社区 37
RV原创 37
2048核基地 37
https://hjd.tw 35
小贾_KTXP 33
1024核工厂 33
https://crackshash.com/ 29
國產精品 28
https://rh2048.com 27
吃雞大神 26
1024社區 26
b48t.com 25
麻豆之神 24
欧宝 24
老含及 24
小隻馬 20
@蜂鳥论坛@ 20
JAV Torrent 掲示板 20
AV大平台 19
刷刷刷 18
第一會所新片 18
发发发 18
1024 17
1024工厂 17
Weagogo 16
hjd.tw 16
https://1tors.ru/ 15
b'\\\\xcf\\\\xeb\\\\xb7\\\\xa2\\\\xc8\\\\xb4\\\\xb2\\\\xbb\\\\xbb\\\\xe1' 14
olo 13
不予 13
老司机论坛 13
小樱 12
xp1024 12
(美女裸聊直播 uur68.com) 12
美女裸聊直播 11
發片小王子@18p2p 11
b'\\\\xb3\\\\xcc\\\\xb7sAV \\\\xa4\\\\xd1\\\\xaa\\\\xc5\\\\xbd\\\\xd7\\\\xbe\\\\xc2 IP' 11
BT世界网 https://www.btsj6.com/ 10
[animelayer.ru] Animelayer 10
nyaa001 10
https://discord.gg/vbJ7RTn 10
PiRaX @ TamilBlasters.Net 10
orion 10
愛在黑夜001 10
b'dioguitar23(\\\\xb2\\\\xc4\\\\xa4\\\\xbb\\\\xa4\\\\xd1\\\\xc5]\\\\xa4\\\\xfd)\\\\xad\\\\xec\\\\xb3\\\\xd0' 9
U6A6磁力搜索---U6A6.COM 9
https://infocon.org/ 9
约战竞技场 9
xue0117 9
BBVC 9
Zelka.ORG 8
threesixtyp 8
dio88.net(第六天魔王)@最新AV海量免費播放~魔王在線 8
dioguitar23(第六天魔王)@dioguitar23.net 8
規懶趴會 8
b'\\\\xc1\\\\xf9\\\\xd4\\\\xc2\\\\xc1\\\\xaa\\\\xc3\\\\xcb' 7
百撸社区|高清资源 7
Zamunda.NET 7
百撸社区 7
www.dio8899.net(第六天魔王)@最新AV海量免費播放~魔王在線 7
K8bet 6
cangkong 6
[tp.m-team.cc] M-Team - TP 6
dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線 6
b'\\\\xb7\\\\xf6\\\\xba~\\\\xad\\\\xd1\\\\xbc\\\\xd6\\\\xb3\\\\xa1 dioguitar23 \\\\xad\\\\xec\\\\xb3\\\\xd0' 6
00armand00 6
6969bt.com 6
[https://majomparade.eu] 6
鱼香肉丝 6
性吧RV原创 5
Burnbit 5
94i88影城-点击跳转 5
♥im520♥ 5
arsenal-fan 5
[http://x-torrents.org] X-Torrents.org 5
1024核工厂/ 5
PMEDIA NETWORK 5
arsenal-fan@avsp2p.com 5
https://www.javhdbbs.com 5
dioguitar23(第六天魔王)@mw6.me 5
成年人的小游戏 5
Hotaru 5
Mp4Ba 4
b'\\\\x9e\\\\xb3\\\\xb4\\\\xee\\\\xc0\\\\xad\\\\xdf\\\\xe3\\\\xc0\\\\xad@kb978.com' 4
https://downloadcursos.top/ 4
youiv 4
rutracker.org 4
yoy123 4
olo@SIS001 4
上善若水@www.sexinsex.net 4
b'\\\\xab\\\\xb0\\\\xa5\\\\xab\\\\xad\\\\xb7\\\\xb1\\\\xa1~\\\\xc5]\\\\xa7\\\\xd9\\\\xad\\\\xec\\\\xb3\\\\xd0' 4
魔王之家 4
杏吧 4
dio66.net(第六天魔王)@最新AV海量免費播放~魔王在線 4
更多精彩!尽在99BT工厂@5120911 4
hotaru 4
xueru10405 4
1030社區---1030.ws 4
x 4
www.crackshash.com 4
1stDragon 4
buxxa 4
www.dio7777.net(第六天魔王)@最新AV海量免費播放~魔王在線 4
BT-btt.com 4
kenelm 4
HiHBT 精品薈萃 4
m6688.net(第六天魔王)@最新AV海量免費播放~魔王在線 3
杏吧论坛 3
XIU 3
atrrea 3
1314 3
oldman原創DVD@18p2p.com 3
sogood@18p2p 3
? nike ? 3
https://toonshub.xyz 3
https://www.torrentdosfilmes.tv/ 3
1024社区 3
dioguitar23(第六天魔王) 3
广东雨神 3
RZK 3
rxrj 3
枫雪动漫 3
YURASUKA 3
【神秘巨星CI】 3
GIF出处系列 3
https://www.terralibera.net/ 3
dioguitar23@dio66.net 3
dioguitar23(第六天魔王)@hotavxxx.com 3
萌你一脸@第一会所 3
罗马教皇@草榴社区 luckjam@sexinsex.net 3
么么哒 3
XP1024 3
nyaa.si 3
uid-346380 3
Download from Sajber.org/blog 3
美女裸聊约炮 3
@微信订阅号专注稀有汁源 3
susun=eastv 3
M88(明陞) 3
rh2048.com/ 3
99BT工厂 @ 5120911 3
衣选集团 3
b'\\\\xc1\\\\xf9\\\\xd4\\\\xc2\\\\xcc\\\\xec\\\\xbf\\\\xd5' 3
【RV原创】【sex8.cc】 3
Gfker@1024核工廠 3
b'99\\\\xa5\\\\xfd\\\\xa5\\\\xcd' 3
漫之学园 3
https://DesignOptimal.com 3
9200 3
安西教练 3
尘封追忆+色十八 3
zgome@18p2p 2
顶冠文化 2
MN Nambiar @ TamilBlasters.Net 2
老司机 2
dioguitar23.net(第六天魔王)@最新AV海量免費播放~魔王在線 2
https://media.defcon.org/ 2
https://sexasia.net/feed 2
黑色点击 2
http://www.acgyinghua.com/ 2
嗨咻阁 2
Lucian2009@第一会所 2
dioguitar23(第六天魔王)@bbs.hotavxxx.com 2
roger92402094 2
lxdng1218 2
飘嫖 2
红馆-红人馆-网络红人之家 2
CHANNEL NEO 2
ccc32.com 2
chikan 2
神秘巨星CI 2
dioguitar23(第六天魔王)@dio999.com 2
注册就送39元,联系:330545486 2
b'\\\\xb7\\\\xf6\\\\xba~\\\\xad\\\\xd1\\\\xbc\\\\xd6\\\\xb3\\\\xa1@\\\\xb4A\\\\xab\\\\xbd\\\\xa8\\\\xe0' 2
ITELLYOU 2
联系TG:yyllzy,fulihuoqu 2
強片皇帝999 2
sogclub No.2 2
D2mp4 2
mmklp@第一会所 2
ssss1111@18p2p 2
bbvc 2
感冒清@sis001 2
afnami@64.78.163.55 2
西門吹水 2
goldpuzjying 2
uid=1591117 2
[http://rudub.tv] RuDub.TV 2
GF@1024核工廠 2
www.javhdbbs.com 2
蜂鸟色区 2
b'\\\\xb3\\\\xc7\\\\xca\\\\xd0\\\\xefL\\\\xc7\\\\xe9~\\\\xc4\\\\xa7\\\\xbd\\\\xe4\\\\xd4\\\\xad\\\\x84\\\\x93' 2
[http://energy-torrent.com] Energy-Torrent 2
SoushkinBoudera 2
[http://bko.baibako.tv] BaibaKo.TV 2
Western/HD-Jiggly 2
冷月无声 2
奥利给 2
b'\\\\xab\\\\xb0\\\\xa5\\\\xab\\\\xad\\\\xb7\\\\xb1\\\\xa1~\\\\xa4p\\\\xb9t\\\\xad\\\\xec\\\\xb3\\\\xd0' 2
b'tanw\\\\xa9\\\\xceyk3325@www.sogclub.com' 2
3Li 2
b'giogio99\\\\xad\\\\xec\\\\xb3\\\\xd0' 2
BradPitt 2
遁去的壹 2
downloadcursos.top 2
KTXP_秋沫 2
xinnian 2
18p2p by_UID 1380364 2
https://bbs2048.org/ 2
https://www.1024btgc.com 2
清雨 2
crazylazy 2
感冒清@sis001.com 2
MingYSub 2
淘宝天猫优惠券秒杀 2
Downloaded from CracksHash.com 2
会飞的象@第一会所 2
mule_by_SpeedPluss.ORG 2
https://rutor.org 2
BT伙计 2
hhd800.com 2
gnhyc11@18p2p.com 1
fyoulapk@18p2p 1
塔卡小爹賽 1
HD一条街论坛 1
dioguitar23原創 1
b'\\\\xb3\\\\xce\\\\xbf\\\\xd5\\\\xd1\\\\xa7\\\\xd4\\\\xb0' 1
cnmzlwb 1
zb77@18p2p 1
https://www.asmr.one/work/RJ374870 1
[uid-1591117] 1
奈特羅德 1
https://mega.nz/#F!DK4lCSwB!QdwaMCT3SpOxISAgnuX7nQ 1
小葫芦@www.sis001.com 1
柏林没有梦 1
ls611 1
qqtnt007 1
3E523E31D247_by_FDZone.ORG 1
JPopsuki 2.0 626225292 1
https://elamigosedition.com/ 1
guroemon 1
lyf634041775 1
1234567890 1
https://bitnova.info/ 1
asfile@SIS001 1
b'\\\\xbd\\\\xad\\\\xc4\\\\xcf\\\\xb7\\\\xe7\\\\xd3\\\\xea' 1
mikocon @ bbs.2djgame.net 1
http://mm.aayun.cc 1
aqcd123 1
维尼 1
iii 1
pornolab 1
极影字幕 1
b'\\\\xc9\\\\xab\\\\xd6\\\\xd0\\\\xc9\\\\xab@ypzhq\\\\xd4\\\\xad\\\\xb4\\\\xb4' 1
roger92402094(SIS) 1
erest 1
Baslilon=Baslilon23 1
b'\\\\xab\\\\xb0\\\\xa5\\\\xab\\\\xad\\\\xb7\\\\xb1\\\\xa1 dioguitar23 \\\\xad\\\\xec\\\\xb3\\\\xd0' 1
sigma 1
寂寞如漫天雪花 1
C:\\\\Users\\\\pongphon\\\\OneDrive\\\\Desktop\\\\New folder (2)\\\\FC2PPV 1218169 [Odorless video] [Leaked] JULIA High image quality BEB-016 JULIA Sweaty Backroom .ts 1
JPopsuki 2.0 2131292835 1
不予@暗香阁 1
sogclub No.2 BY sogclub 1
uid-1591117 1
b'\\\\xba\\\\xda\\\\xc2\\\\xfb\\\\xb0\\\\xc5' 1
微信一夜ONS协会 1
b'KUHO\\\\xd2\\\\xd5\\\\xca\\\\xf5\\\\xc1\\\\xaa\\\\xc3\\\\xcb' 1
b'\\\\xb6\\\\xc0\\\\xa5i\\\\xa8\\\\xe0_by_FDZone.org' 1
中文字幕無水印 1
http://www.wozai020.com 1
sop168 1
b'SP\\\\xa7\\\\xe4\\\\xbc\\\\xd6\\\\xa4l@\\\\xaa\\\\xe1\\\\xa9M\\\\xa9|' 1
tiantianlu186@公仔箱論壇 1
luckyjune 1
SK`|yEsMan<sk·> 1
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' 1
hkkane@18p2p 1
www.4hu.com 1
b'\\\\xaeL\\\\xaa\\\\xef\\\\xacK@99p2p' 1
夜蒅星宸@第一会所 1
【更多资源用加手机QQ-17182252050】 1
jjjhn2003@18p2p 1
XIEYUXIA 1
b'@\\\\xc0\\\\xcb\\\\xb7\\\\xad\\\\xd4\\\\xc6@' 1
www.dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線 1
TYBBX2 1
yjs521 1
hhbb_zcm 1
twsb.co 1
https://downloadcursos.top 1
https://www.musicastorrent.com/ 1
pandafood#panda1314#gg5123 獨家首發 1
探花族 1
zhoudehua200 1
AV大平台 - 发布页 1
b'tanw\\\\xa9\\\\xceyk3325' 1
Rivera@18p2p.com 1
b'\\\\xd7\\\\xcf\\\\xc3\\\\xb5\\\\xb9\\\\xe5' 1
[kp.m-team.cc] M-Team - TP 1
www.spankhash.com 1
UID 235465@www.mimip2p.net 1
草榴社区@MianSheng 1
Странник 1
hgr168168 1
BJ 1
mecaca 1
昆仑虚之巅@草榴社區 1
[欧美美@草榴社区] 1
没线的风筝 1
尼尼撸-综合网站 1
100%真人激情裸聊 www.78xo.com 1
jettej 1
Daddy 1
diamond 1
中文片库 1
https://worldmkv.com 1
b'yatsingkoon@\\\\xa1\\\\xb9\\\\xb6q\\\\xb3c\\\\xa4\\\\xc0\\\\xa8\\\\xc9\\\\xbd\\\\xd7\\\\xbe\\\\xc2\\\\xa1\\\\xb9' 1
入微 1
https://discord.com/invite/wweVHZd6qg 1
602@第一会所 1
3484988vikci@第一会所 1
evilzy 1
化骨龍 1
https://www.kobo.com/ebook/an-archdemon-s-dilemma-how-to-love-your-elf-bride-volume-13 1
cqkd_czy 1
不辣de皮特 1
kaito 1
u3c3.com 1
☆影视帝国论坛☆ 1
aaa23 1
hevcbay.com 1
gn7650104 1
老舅电影 1
捕鼠人 1
https://www.gamestorrents.nu/ 1
Aidoru-Online 1
公主殿下@第一會所 1
MP4BA电影网 1
b'\\\\xb8\\\\xb4\\\\xbb\\\\xee126' 1
微信公众号:卡其影视分享 1
百虎动画 1
425307@癡漢俱樂部 1
avp2p 1
GIFchuchushipin 1
EndlesSea 1
Tanhuazu-探花族 1
推特搞啥呢 1
@K8bet.io@ 1
Misfits 1
黑暗虫洞 1
magazinesbb.com 1
b'\\\\xc9\\\\xab\\\\xd6\\\\xd0\\\\xc9\\\\xab\\\\xd5\\\\x93\\\\x89\\\\xaf@www.SIS.xxx' 1
草榴社区@z10271 1
冰封爱河 1
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' 1
zhangqq789@第一会所 1
wangye6 1
ann@myfun4u.org 1
kino9999@18p2p 1
b'CHD\\\\xc1\\\\xaa\\\\xc3\\\\xcb' 1
satu@hongfire 1
polee 1
GM3089@18P2P 1
BT工厂 @ 5120911 1
【U6A6.COM】_全网磁力最快更新 1
sklc-P2P101.COM 1
b'\\\\xb0\\\\xcb\\\\xd6\\\\xd8\\\\xf7\\\\xec' 1
b'\\\\xcc\\\\xda\\\\xb7\\\\xc9\\\\xd4\\\\xda\\\\xcf\\\\xdf' 1
b'doa_o[\\\\xb9\\\\xc5\\\\xce\\\\xef\\\\xce\\\\xdd]' 1
缘聚岛 1
素人辣妹正妹報報 1
b'sweetsmile@CHD\\\\xc1\\\\xaa\\\\xc3\\\\xcb' 1
javtv.me 1
zhaochuan99 1
草榴社区 1
四魂制作组 1
动漫花園 1
View my conspiracy torrents at 1
春卅娘@18p2p 1
1024核工厂最新地址 1
JPopsuki 2.0 904012437 1
wearebest@18P2P 1
HTCdesireHD@第一會所 1
11.55 1
shinjico 1
得得撸 www.dedelu.com 1
Western&HD-Jiggly 1
ningchia 1
filelist.ro 1
dengzhi123_by_FDZone.ORG 1
b'\\\\xab\\\\xb0\\\\xa5\\\\xab\\\\xad\\\\xb7\\\\xb1\\\\xa1 dioguitar23(\\\\xb2\\\\xc4\\\\xa4\\\\xbb\\\\xa4\\\\xd1\\\\xc5]\\\\xa4\\\\xfd)\\\\xad\\\\xec\\\\xb3\\\\xd0' 1
HZHJS 1
Audible 1
skyuz 1
ever 1
El tio WAPILLO :v 1
草莓TV 1
加菲豆@第一会所 1
yaoshiqiao 1
PB 1
b'\\\\xb9\\\\xda\\\\xa4\\\\xbd\\\\xb6\\\\xe9\\\\xaeT\\\\xbc\\\\xd6\\\\xa4u\\\\xa7{@p16847' 1
54CECB5A0EA7_by_FDZone.ORG 1
b'\\\\xc0\\\\xcb\\\\xd7\\\\xd3\\\\xd0\\\\xa1\\\\xb5\\\\xb6' 1
rendell_by_mimip2p.net, rendellxx_by_fdzone.org, rendell@SexInSex! 1
https://e-hentai.org 1
https://to-url.com/torrent-igruha 1
jinzebin86@18p2p.com 1
birdmanfocker@18p2p 1
GH37DgaBef6rQJyE2nvqb5YpS 1
AVdian@126.com 1
亞瑟王 1
b'Bianca_Cooper_Touch99.com \\\\xa6\\\\xb3\\\\xa7\\\\xf3\\\\xa6h\\\\xa6n\\\\xb9\\\\xcf' 1
wT3j6PNrC5aOcD04yJ7xRotF8 1
村花论坛 1
b'\\\\xc4\\\\xfa_\\\\x89\\\\xf4\\\\xb9\\\\xab\\\\x88@\\\\x8a\\\\xca\\\\x98\\\\xb7\\\\xb9\\\\xa4\\\\xb7\\\\xbb' 1
FISH321@18P2P 1
第一会所 sis001 1
huPE@18P2P 1
houlai=biaoqian 1
b'qilibi@\\\\xc1\\\\xf9\\\\xd4\\\\xc2\\\\xc2\\\\x93\\\\xc3\\\\xcb' 1
天池妖尊 1
sing0212000 1
wandy_by_FDZone.org 1
XO@kazamis 1
百撸社区|高清影片 1
KOOK 1
HQC 1
mc733 1
爱游戏 1
1158012^@^18p2p 1
b'Bianca_Cooper \\\\xa7\\\\xf3\\\\xa6h\\\\xac\\\\xfc\\\\xb9\\\\xcf\\\\xa5u\\\\xa6bTouch99' 1
xiaocuitj 1
星星不舔屄 1
https://www.crnaberza.com CrnaBerza 1
boby@mimip2p 1
magnet360@163.com 1
Japanadultvideos 論壇 <-----按此瀏覽更多 1
[http://x-torrents.nu] X-Torrents.org 1
euphoricer 1
2048核基地!! 1
zlb273692399@第一会所 1
花和尚 1
b'\\\\xb4\\\\xbf\\\\xb0\\\\xae\\\\xc9\\\\xe7\\\\xc7\\\\xf8/wbzt' 1
三石@第一会所 1
JackyCheung@草榴社區 1
b'\\\\xbf\\\\xe7\\\\xca\\\\xa1\\\\xbe\\\\xdc\\\\xb7\\\\xf1@9999999' 1
菜牙电影网 1
mehappy2012 1
https://www.jp.square-enix.com/music/sem/page/chrono/trigger_revival/ 1
Scientists used to invent telephones, airplanes, microwave ovens... now all they invent is statistics that say they should get more funding. 1
RoxMarty 1
rczhi@18p2p.com 1
kkk8568 1
kenan2763 1
arthurwarlike@第一会所 1
b'\\\\xb3\\\\xc7\\\\xca\\\\xd0\\\\xefL\\\\xc7\\\\xe9~~\\\\xcb\\\\xba\\\\xd2\\\\xb9\\\\xd4\\\\xad\\\\x84\\\\x93' 1
東方明珠=ccvvm 1
从小缺钙 1
Jackie 1
www.lupola.com 1
ashow.cc 1
品色影院 1
8400327@草榴社區 1
gamezealot@18p2p 1
uhla454@第一会所 1
宅鱼 1
1024核工厂 Bt7086 1
hilllxs 1
豺狼也柔情 1
99堂 1
老肥 1
Chikyuji-Animes, 2006 maggle! 1
chaorentwo@18p2p 1
若無其事@18p2p.com 1
hhd000.com 1
掠风窃尘 1
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' 1
Kura999 from WaikeungBBS 1
XFSUB 1
huiasd 1
b'Rory @ D.C.\\\\xb8\\\\xea\\\\xb0T\\\\xa5\\\\xe6\\\\xacy\\\\xba\\\\xf4' 1
https://t.me/deletetvwrestling 1
dodododo 1
Rambo@18p2p 1
b'\\\\xce\\\\xde\\\\xd0\\\\xc4\\\\xce\\\\xde\\\\xb4\\\\xe6' 1
filmplay 1
avdian@126.com 1
1025 1
956828@18p2p 1
夜游神 1
b'\\\\xb2\\\\xbb\\\\xb5\\\\xc3\\\\xb2\\\\xbb\\\\xc9\\\\xab' 1
vbiukj 1
buxxa=bbvc 1
jnd16d 1
烽火不熄 1
pietro716 1
Lus 1
b'\\\\x98Y\\\\xd4\\\\xad\\\\xa4\\\\xe6\\\\x97@' 1
國產無碼 1
b'\\\\xd0\\\\xc2\\\\xc7\\\\xd7\\\\xc3\\\\xdc\\\\xb0\\\\xae\\\\xc8\\\\xcb\\\\xc2\\\\xdb\\\\xcc\\\\xb3@\\\\xd6\\\\xc1\\\\xd7\\\\xf0\\\\xcc\\\\xec\\\\xc1\\\\xfa' 1
wangzhifeng@18p2p 1
dabohong_by_fdzone.org 1
TODO 1
b'\\\\xb7\\\\xc9\\\\xd3\\\\xb0\\\\xbf\\\\xcd\\\\xcd\\\\xf8' 1
yav.me 1
http://www.jizhang1.space/?3316427 1
pin0314(1470)@www.mycould.com 1
handsomemouse@18p2p 1
b'\\\\xa4\\\\xc6\\\\xb0\\\\xa9\\\\xc0s@mimip2p' 1
面瘫 1
弄死你娃L@2018x.win 1
yyyyyuuuuu@18p2p 1
狼主@SexInSex.net 1
1394130143@第一会所 1
jove 1
电骡爱好者 1
westkyo@www.sis001.com 1
lzmcmbj@18p2p 1
dioguitar23(第六天魔王)@dioguitar23.me 1
VISTOR_by_FDZone.ORG 1
chris930 1
[WMAN-LorD] [UHD] [4K] [2160p] [REAL4K] [TGx] 1
b'A\\\\xab\\\\xac\\\\xa4\\\\xa3\\\\xa8}\\\\xc3\\\\xc8' 1
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' 1
Domaha.tv 1
destiny999@18p2p 1
水母飄 1
HOUSEKEEPER 1
RV原创组 1
月岚星辰520@第一会所 1
b'\\\\xc3\\\\xe2\\\\xb7\\\\xd1\\\\xd4\\\\xda\\\\xcf\\\\xdf\\\\xd2\\\\xf4\\\\xc0\\\\xd6' 1
www.1024pk.com 1
爱城 1
amge50@www.sogclub.com 1
OneStar 1
b'Jocky123#\\\\xb8\\\\xfc\\\\xb6\\\\xe0\\\\xb5\\\\xc4\\\\xbe\\\\xab\\\\xb2\\\\xca\\\\xd3\\\\xb0\\\\xc6\\\\xac!' 1
https://getcomics.info 1
点击-海量种子 1
btziyuan 1
[http://x-torrents.org] X-Torrents.org (ex X-Torrents.ru) 1
https://www.lspback.com 1
foxmoder996 1
https://share.dmhy.org/topics/list/user_id/712935 1
玛尔亲王@第一会所 1
rtjhuytu 1
淨空法師專集網站 1
b'\\\\xa1\\\\xb6\\\\xbd\\\\xcc\\\\xd3\\\\xfd\\\\xca\\\\xd6\\\\xc0\\\\xad\\\\xca\\\\xd6\\\\xa1\\\\xb7' 1
mc733+zgome 1
Goddess 1
NikeのB@第一会所 1
b'dvt\\\\xb0\\\\xc9' 1
微博:止于影书,公众号:影遇见书,@小鱼 1
free4 1
靜風@sis001 1
kaniuniu 1
dcsk_By_FDZone.org 1
sigma@www.mimip2p.com 1
看翍荭尘 1
bjiok 1
lins2b 1
小馬克_by_FDZone.ORG 1
FSFS555@第一会所 1
flowerff 1
lascruces 1
?nike? 1
SEX8.CC 1
b'\\\\xb3\\\\xc9\\\\xc8\\\\xcb\\\\xc2\\\\xdb\\\\xcc\\\\xb3\\\\xbf\\\\xaa\\\\xb7\\\\xc5\\\\xd7\\\\xa2\\\\xb2\\\\xe1' 1
dio889.net(第六天魔王)@最新AV海量免費播放~魔王在線 1
APKMAZA.CO 1
13121152@18p2p 1
UID 185363@www.mimip2p.com 1
b'\\\\xa4^\\\\xa4\\\\xa2\\\\xb5\\\\xbe@FDZone.org' 1
更多资源联系qq1273288348 1
https://nyaa.si/user/mrshowoff 1
https://boards.4channel.org/h/#s=hentai+upscales 1
mimu@18P2P 1
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' 1
殇情 1
风来西林 1
www.loliba.info 1
b'Nike\\\\xa4\\\\xce\\\\xa3\\\\xc2' 1
[www.pttime.org] PT时间 1
QxR 1
sunchiua_by_P2Pzone.org 1
wazx528 1
popgofansub 1
b'\\\\xc3\\\\xe2\\\\xb7\\\\xd1\\\\xb5\\\\xe7\\\\xd3\\\\xb0\\\\xcf\\\\xc2\\\\xd4\\\\xd8\\\\xbb\\\\xf9\\\\xb5\\\\xd8' 1
gremichaem 1
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' 1
sukebei.nyaa.si 1
pademon18p2p 1
aaamfk+zgome+bbryans 1
cyxy@http://38.114.38.172/forum/ 1
b'\\\\xd3\\\\xd7\\\\xc5\\\\xae\\\\xbc\\\\xab\\\\xc6\\\\xb7' 1
https://e-hentai.org/g/2375721/1b5e081312/ 1
18P2P_dioguitar23.co(第六天魔王)@最新AV海量免費播放~魔王在線 1
b'AV\\\\xce\\\\xc4\\\\x99n\\\\xa3\\\\xfcADULT INTEGRATED COMMUNITY' 1
UID 1357210@18P2P.com 1
fuckkkingou 1
闲云野鹤 1
LAPUMiA.NeT 1
adult_cn 1
psoke 1
18p2p@liyang8926 1
littlefatbee 1
秋叶TV 1
msy91 1
Niraya 1
https://www.kobo.com/ebook/that-time-i-got-reincarnated-as-a-slime-vol-13-light-novel 1
JPopsuki 2.0 941661648 1
yamyedye@18P2P 1
dansnow 1
H2CO3 1
b'\\\\x8e\\\\xf7\\\\x8e\\\\xf7@\\\\x88\\\\xc3\\\\x91\\\\xe9\\\\x9a\\\\xa0\\\\x8c\\\\xb4\\\\x91n' 1
kamigami 1
G@1024核工廠 1
The Seaside Corpse 1
b'\\\\xadw\\\\xbd\\\\xde_by_FDZone.ORG' 1
fangbayern 1
君乐 1
Doctor Who 1
第一流氓@18P2P 1
Deviloid.net 1
b'\\\\xc1\\\\xf9\\\\xd4\\\\xc2\\\\xc1\\\\xaa\\\\xc3\\\\xcb hgfhgf' 1
wcer@18p2p.com 1
https://www.yitarx.com 1
wuchengzhou9000@www.SexInSex.net 1
nwcd 1
p2p_user@mimip2p 1
zza@live.com 1
清风浪子@草榴社区 1
http://www.zone54.com 1
ssan998 1
xxfhd.com 1
mybmw320_by_SpeedPluss.ORG 1
woaibt@1024核工厂 1
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' 1
hegongc163 1
bigwai 1
t66y 1
cctc55 1
tto@18P2P 1
Antidot Team 1
Torrent Galaxy 1
萤火虫IT服务全国连锁 1
葬爱@18p2p 1
贴心话 1
xuerui810405 1
SoulSeek 1
abbt@18p2p.com 1
深深可许@第一会所 1
lixuhua 1
b'\\\\xcc\\\\x93\\\\x9fo' 1
animekayo.com 1
qiupianhao 1
173489627 1
wak11110@18P2P 1
[http://hdtracker.org] HD TRACKER 1
www.eien-acg.com 1
index0123 1
hndwje 1
http://www.meitubb.com/forum.php 1
最新地址 1
https://anidb.net/file/3082403 1
更多精彩 @ 卡卡拉 1
olo@第一会所 1
https://e-hentai.org/g/2255154/778b4d24e6/ 1
sujinding@第一会所 1
MKO 1
chleicool=fym0624=patpat608 1
撸二九论坛 1
flybird186 1
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' 1
https://www.omgyes.com 1
DVD 2008 1
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' 1
>亞捷視圖< 1
b'\\\\xb9\\\\xfd\\\\xc5\\\\xab\\\\xd6\\\\xc6\\\\xd4\\\\xec\\\\xb2\\\\xa9\\\\xbf\\\\xcd' 1
3267506 1
中国电信 1
9clonely 1
b'\\\\xd2\\\\xf9\\\\xc3\\\\xf1\\\\xcd\\\\xf2\\\\xcb\\\\xea' 1
幸运流星@四仔论坛 1
Lista Espiritualista 1
雪光梦想 1
https://exhentai.org/g/1964478/8ed0a899ca 1
olo@sis001 1
3zi@第一會所 1
Andy 1
b'\\\\xb7\\\\xd6\\\\xcf\\\\xed' 1
24262830. 1
食色性者 1
aj11@mimip2p.net 1
srwH 1
鴻仔 1
校园迷糊大王 1
WCG 1
b'(\\\\xd3\\\\xf4\\\\xc3\\\\xc6)\\\\xb0\\\\xae\\\\xbf\\\\xb4\\\\xb5\\\\xe7\\\\xd3\\\\xb0' 1
kiva@18p2p 1
b'\\\\xbb\\\\xd8\\\\xbc\\\\xd2001@18p2p' 1
ffxx 1
judexkwok(SIS) 1
chikan@T66Y 1
瑞倪维儿护肤专卖 1
auriga@18p2p 1
yinchong818@(sis) 1
ntlv0@hotmail.com 1
酷安 1
jav20s8.com/ 1
JPopsuki 2.0 14486345 1
若無其事@18p2p 1
b'stormly+taitan12+zhaoZero41+chinami2002+glen246+faberge@darkeagle-\\\\xbax\\\\x84\\\\xf0\\\\xaa\\\\xc0' 1
CMCT团队荣誉出品 1
kennyboy 1
2AV.COM 1
'" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = monotonic()\n", "def sources():\n", " sources = {}\n", " for sha1, torrent in torrents.items():\n", " source = torrent.dict.get(b'info').get(b'source')\n", " if source is None:\n", " source = torrent.dict.get(b'info').get(b'publisher')\n", " if source is None:\n", " source = torrent.dict.get(b'info').get(b'publisher-url')\n", " try:\n", " if type(source) is bytes:\n", " source = source.decode().strip()\n", " except UnicodeDecodeError:\n", " pass\n", " if source not in sources.keys():\n", " sources[source] = 1\n", " else:\n", " sources[source] += 1\n", " return sources\n", "sources = sources()\n", "sort = sorted(sources, reverse=True, key=lambda x:sources[x])\n", "sort.remove(None)\n", "print(monotonic()-s, \"s\", sources[None]/len(torrents)*100, \"brez ključa source, publisher ali publisher-url\", len(sources), \"virov\")\n", "from tabulate import tabulate\n", "tabulate([[x, sources[x]] for x in sort], tablefmt=\"html\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "4bd1f517", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "...\n", "8.8120769248344 s 284089 različnih tipov v 2515100 datotekah in 203.7606503055813 TiB\n" ] } ], "source": [ "s = monotonic()\n", "def removeminorities(population, minrepr=0, ostalo=\"ostalo\"):\n", " true = {ostalo: 0}\n", " for key, value in population.items():\n", " if value < minrepr:\n", " true[ostalo] += value\n", " else:\n", " true[key] = value\n", " return true\n", "from mimetypes import guess_type\n", "def ext(mime=False, minreprratio=0):\n", " bycount = {}\n", " bysize = {}\n", " bysizerepresentative = {}\n", " filescount = 0\n", " bytescount = 0\n", " for sha1, torrent in torrents.items():\n", " try:\n", " representatives = {}\n", " for path, size in torrent.paths():\n", " filescount += 1\n", " bytescount += size\n", " if mime:\n", " ext = guess_type(path.pop().decode(encoding=\"iso-8859-2\"))[0]\n", " else:\n", " ext = path.pop().split(b'.').pop().decode(encoding=\"iso-8859-2\").lower()\n", " if ext not in bycount.keys():\n", " bycount[ext] = 1\n", " else:\n", " bycount[ext] += 1\n", " if ext not in bysize.keys():\n", " bysize[ext] = size\n", " else:\n", " bysize[ext] += size\n", " if ext not in representatives.keys():\n", " representatives[ext] = size\n", " else:\n", " representatives[ext] += size\n", " except AttributeError:\n", " print(sha1.hex(), torrent)\n", " raise AttributeError\n", " try:\n", " representative = sorted(representatives, key=lambda x:representatives[x]).pop()\n", " except IndexError:\n", " print(sha1.hex(), torrent)\n", " raise IndexError\n", " if representative not in bysizerepresentative.keys():\n", " bysizerepresentative[representative] = 1\n", " else:\n", " bysizerepresentative[representative] += 1\n", " truebycount = removeminorities(bycount, minreprratio*filescount, \"ostale\")\n", " truebysize = removeminorities(bysize, minreprratio*bytescount, \"ostale\")\n", " truebysizerepresentative = removeminorities(bysizerepresentative, minreprratio*len(torrents), \"ostale\")\n", " for data in [truebycount, truebysize, truebysizerepresentative]:\n", " data = [(v, k) for k, v in data.items()]\n", " return truebycount, truebysize, truebysizerepresentative, len(bycount), filescount, bytescount\n", "print(\"...\")\n", "bycount, bysize, bysizerepresentative, kinds, filescount, bytescount = ext(False, 0.0005)\n", "print(monotonic()-s, \"s\", kinds, \"različnih tipov v\", filescount, \"datotekah in\", bytescount/(1024**4), \"TiB\")" ] }, { "cell_type": "code", "execution_count": 3, "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" } ], "source": [ "sortcount = sorted(bycount, reverse=False, key=lambda x: bycount[x])\n", "sortsize = sorted(bysize, reverse=False, key=lambda x: bysize[x])\n", "sortsizerepresentative = sorted(bysizerepresentative, reverse=False, key=lambda x: bysizerepresentative[x])\n", "from matplotlib import pyplot\n", "%matplotlib notebook\n", "for desc, data in {\"po številu datotek\": (sortcount, bycount), \"po velikosti datotek\": (sortsize, bysize), \"po številu po velikosti največjih datotek torrentov\": (sortsizerepresentative, bysizerepresentative)}.items():\n", " fig, axes = pyplot.subplots()\n", " # axes.pie([data[1][key] for key in data[0]], labels=data[0])\n", " axes.barh(data[0], [data[1][key] for key in data[0]])\n", " pyplot.xscale(\"log\")\n", " axes.set_title(desc)\n", " fig.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" } }, "nbformat": 4, "nbformat_minor": 5 }