diff --git a/.config/wandb/settings b/.config/wandb/settings
new file mode 100644
index 0000000000000000000000000000000000000000..8dae664872e647e4bf829a45038781fb33b43d92
--- /dev/null
+++ b/.config/wandb/settings
@@ -0,0 +1,2 @@
+[default]
+
diff --git a/.local/share/jupyter/nbextensions/freeze/main.js b/.local/share/jupyter/nbextensions/freeze/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..ff5361833e9c47cbf771addef2743e39bad7acd3
--- /dev/null
+++ b/.local/share/jupyter/nbextensions/freeze/main.js
@@ -0,0 +1,205 @@
+define([
+ 'base/js/namespace',
+ 'base/js/events',
+ 'notebook/js/codecell',
+ 'notebook/js/textcell',
+ 'jquery'
+], function (
+ Jupyter,
+ events,
+ codecell,
+ textcell,
+ $
+) {
+ 'use strict';
+
+ var CodeCell = codecell.CodeCell;
+ var MarkdownCell = textcell.MarkdownCell;
+
+ var mod_name = 'Freeze';
+ var log_prefix = '[' + mod_name + ']';
+
+ // defaults, overridden by server's config
+ var options = {
+ readonly_color: '#fffef0',
+ frozen_color: '#f0feff'
+ };
+
+ function patch_MarkdownCell_unrender () {
+ console.log('[Freeze] patching MarkdownCell.prototype.unrender');
+ var old_unrender = MarkdownCell.prototype.unrender;
+
+ MarkdownCell.prototype.unrender = function () {
+ // console.log('[Freeze] patched unrender applied');
+ if (this.metadata.run_control === undefined ||
+ !this.metadata.run_control.frozen
+ ) {
+ old_unrender.apply(this, arguments);
+ }
+ };
+ }
+
+ function patch_CodeCell_execute () {
+ console.log('[Freeze] patching CodeCell.prototype.execute');
+ var old_execute = CodeCell.prototype.execute;
+
+ CodeCell.prototype.execute = function () {
+ if (this.metadata.run_control === undefined ||
+ !this.metadata.run_control.frozen
+ ) {
+ old_execute.apply(this, arguments);
+ }
+ };
+ }
+
+ // Migrate old metadata format to new notebook-defined metadata.editable
+ function migrate_state (cell) {
+ if (cell.metadata.run_control !== undefined) {
+ if (cell instanceof CodeCell || cell instanceof MarkdownCell) {
+ if (cell.metadata.run_control.read_only === true) {
+ cell.metadata.editable = false;
+ }
+ }
+ else {
+ // remove metadata irrelevant to non-code/markdown cells
+ delete cell.metadata.run_control.frozen;
+ }
+ // remove old key replaced by metadata.editable
+ delete cell.metadata.run_control.read_only;
+ // remove whole object if it's now empty
+ if (Object.keys(cell.metadata.run_control).length === 0) {
+ delete cell.metadata.run_control;
+ }
+ }
+ }
+
+ function get_state (cell) {
+ if (cell.metadata.editable === false && (cell instanceof CodeCell || cell instanceof MarkdownCell)) {
+ if (cell.metadata.run_control !== undefined && cell.metadata.run_control.frozen) {
+ return 'frozen';
+ }
+ return 'readonly';
+ }
+ return 'normal';
+ }
+
+ function set_state(cell, state) {
+ if (!(cell instanceof CodeCell || cell instanceof MarkdownCell)) {
+ return;
+ }
+
+ state = state || 'normal';
+ var bg;
+ switch (state) {
+ case 'normal':
+ cell.metadata.editable = true;
+ cell.metadata.deletable = true;
+ if (cell.metadata.run_control !== undefined) {
+ delete cell.metadata.run_control.frozen;
+ }
+ bg = "";
+ break;
+ case 'read_only':
+ case 'readonly':
+ cell.metadata.editable = false;
+ cell.metadata.deletable = false;
+ if (cell.metadata.run_control !== undefined) {
+ delete cell.metadata.run_control.frozen;
+ }
+ bg = options.readonly_color;
+ break;
+ case 'frozen':
+ cell.metadata.editable = false;
+ cell.metadata.deletable = false;
+ $.extend(true, cell.metadata, {run_control: {frozen: true}});
+ bg = options.frozen_color;
+ break;
+ }
+ // remove whole object if it's now empty
+ if (cell.metadata.run_control !== undefined && Object.keys(cell.metadata.run_control).length === 0) {
+ delete cell.metadata.run_control;
+ }
+ cell.code_mirror.setOption('readOnly', !cell.metadata.editable);
+ var prompt = cell.element.find('div.input_area');
+ prompt.css("background-color", bg);
+ }
+
+ function set_state_selected (state) {
+ var cells = Jupyter.notebook.get_selected_cells();
+ for (var i = 0; i < cells.length; i++) {
+ set_state(cells[i], state);
+ }
+ }
+
+ function button_callback(state) {
+ set_state_selected(state);
+ var dirty_state = {value: true};
+ events.trigger("set_dirty.Notebook", dirty_state);
+ }
+
+ function make_normal_selected () {
+ button_callback('normal');
+ }
+
+ function make_read_only_selected () {
+ button_callback('read_only');
+ }
+
+ function make_frozen_selected () {
+ button_callback('frozen');
+ }
+
+ function initialize_states () {
+ var cells = Jupyter.notebook.get_cells();
+ for (var i = 0; i < cells.length; i++) {
+ var cell = cells[i];
+ migrate_state(cell);
+ var state = get_state(cell);
+ set_state(cell, state);
+ }
+ }
+
+ function load_extension () {
+ Jupyter.toolbar.add_buttons_group([
+ Jupyter.keyboard_manager.actions.register ({
+ help : 'lift restrictions from selected cells',
+ icon : 'fa-unlock-alt',
+ handler : make_normal_selected
+ }, 'make-cells-normal', mod_name),
+ Jupyter.keyboard_manager.actions.register({
+ help : 'make selected cells read-only',
+ icon: 'fa-lock',
+ handler : make_read_only_selected
+ }, 'make-cells-read-only', mod_name),
+ Jupyter.keyboard_manager.actions.register({
+ help : 'freeze selected cells',
+ icon : 'fa-asterisk',
+ handler : make_frozen_selected
+ }, 'freeze-cells', mod_name)
+ ]);
+
+ patch_CodeCell_execute();
+ patch_MarkdownCell_unrender();
+
+ Jupyter.notebook.config.loaded.then(function on_config_loaded () {
+ $.extend(true, options, Jupyter.notebook.config.data[mod_name]);
+ }, function on_config_load_error (reason) {
+ console.warn(log_prefix, 'Using defaults after error loading config:', reason);
+ }).then(function do_stuff_with_config () {
+ events.on("notebook_loaded.Notebook", initialize_states);
+ if (Jupyter.notebook !== undefined && Jupyter.notebook._fully_loaded) {
+ // notebook already loaded, so we missed the event, so update all
+ initialize_states();
+ }
+ }).catch(function on_error (reason) {
+ console.error(log_prefix, 'Error:', reason);
+ });
+ }
+
+ return {
+ get_state : get_state,
+ set_state : set_state,
+ load_jupyter_extension : load_extension,
+ load_ipython_extension : load_extension
+ };
+});
diff --git a/.local/share/jupyter/nbextensions/gist_it/main.js b/.local/share/jupyter/nbextensions/gist_it/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..79c119e024e04de11ec4febcc6e24750eda0cadc
--- /dev/null
+++ b/.local/share/jupyter/nbextensions/gist_it/main.js
@@ -0,0 +1,481 @@
+/**
+ *
+// Avoid server side code :
+// https://github.com/ipython/ipython/issues/2780
+ *
+ * This essentially boils down to the following:
+ * Github authentication requires some server-side code for any 'app' which
+ * wants to authenticate over the Github API.
+ * When registering an app with Github, Github provides the app with what they
+ * call a 'client secret'.
+ * The client secret is then incorporated into the app, and the app sends it to
+ * Github as part of the authentication process, thus proving to Github's
+ * servers that the communicating app was written by someone with appropriate
+ * credentials.
+ *
+ * The issue with writing a single Github app for Gist-ing notebooks, is that
+ * it would need to include such a client secret. Since this would be part of
+ * the extension source code, anyone could use the client secret, potentially
+ * gaining the permissions that any given user has granted to the app.
+ *
+ * As a result, we only support:
+ * - anonymous (non-authenticated) API usage
+ * - client-side authentication using a personal access token
+ * (see https://github.com/settings/tokens)
+ */
+
+define([
+ 'jquery',
+ 'base/js/namespace',
+ 'base/js/dialog'
+], function (
+ $,
+ Jupyter,
+ dialog
+) {
+ "use strict";
+
+ // define default values for config parameters
+ var params = {
+ gist_it_default_to_public: false,
+ gist_it_personal_access_token: '',
+ github_endpoint: 'github.com'
+ };
+
+ var initialize = function () {
+ update_params();
+ Jupyter.toolbar.add_buttons_group([
+ Jupyter.keyboard_manager.actions.register ({
+ help : 'Create/Edit Gist of Notebook',
+ icon : 'fa-github',
+ handler: show_gist_editor_modal
+ }, 'create-gist-from-notebook', 'gist_it')
+ ]);
+ };
+
+ // update params with any specified in the server's config file
+ var update_params = function() {
+ var config = Jupyter.notebook.config;
+ for (var key in params) {
+ if (config.data.hasOwnProperty(key))
+ params[key] = config.data[key];
+ }
+ default_metadata.data.public = Boolean(config.data.gist_it_default_to_public);
+ };
+
+ var default_metadata = {
+ id: '',
+ data: {
+ description: Jupyter.notebook.notebook_path,
+ public: false
+ }
+ };
+
+ function ensure_default_metadata () {
+ Jupyter.notebook.metadata.gist = $.extend(
+ true, // deep-copy
+ default_metadata, //defaults
+ Jupyter.notebook.metadata.gist // overrides
+ );
+ }
+
+ var add_auth_token = function add_auth_token (xhr) {
+ var token = '';
+ if (params.gist_it_personal_access_token !== '') {
+ token = params.gist_it_personal_access_token;
+ }
+ if (token !== '') {
+ xhr.setRequestHeader("Authorization", "token " + token);
+ }
+ };
+
+ function build_alert(alert_class) {
+ return $('
')
+ .addClass('alert alert-dismissable')
+ .addClass(alert_class)
+ .append(
+ $('')
+ .append($('').html('×'))
+ );
+ }
+
+ function gist_error (jqXHR, textStatus, errorThrown) {
+ console.log('github ajax error:', jqXHR, textStatus, errorThrown);
+ var alert = build_alert('alert-danger')
+ .hide()
+ .append(
+ $('').text('The ajax request to Github went wrong:')
+ )
+ .append(
+ $('').text(jqXHR.responseJSON ? JSON.stringify(jqXHR.responseJSON, null, 2) : errorThrown)
+ );
+ $('#gist_modal').find('.modal-body').append(alert);
+ alert.slideDown('fast');
+ }
+
+ function gist_success (response, textStatus, jqXHR) {
+ // if (Jupyter.notebook.metadata.gist.id === response.id) return;
+
+ Jupyter.notebook.metadata.gist.id = response.id;
+ Jupyter.notebook.metadata._draft = $.extend(
+ true, // deep copy
+ Jupyter.notebook.metadata._draft, // defaults
+ {nbviewer_url: response.html_url} // overrides
+ );
+
+ var d = new Date();
+ var msg_head = d.toLocaleString() + ': Gist ';
+ var msg_tail = response.history.length === 1 ? ' published' : ' updated to revision ' + response.history.length;
+ var alert = build_alert('alert-success')
+ .hide()
+ .append(msg_head)
+ .append(
+ $('')
+ .attr('href', response.html_url)
+ .attr('target', '_blank')
+ .text(response.id)
+ )
+ .append(msg_tail);
+ $('#gist_modal').find('.modal-body').append(alert);
+ alert.slideDown('fast');
+ }
+
+ function get_github_endpoint() {
+ return params.github_endpoint !== '' ? params.github_endpoint : 'github.com';
+ }
+
+ function get_api_endpoint() {
+ const github_endpoint = get_github_endpoint();
+ if (github_endpoint === 'github.com') {
+ return 'https://api.'+ github_endpoint;
+ } else {
+ // Github Enterprise
+ // https://developer.github.com/enterprise/2.18/v3/enterprise-admin/#endpoint-urls
+ return 'https://' + github_endpoint + '/api/v3'
+ }
+ }
+
+ function gist_id_updated_callback(gist_editor) {
+ if (gist_editor === undefined) gist_editor = $('#gist_editor');
+
+ var id_input = gist_editor.find('#gist_id');
+ var id = id_input.val();
+
+ var help_block = gist_editor.find('#gist_id ~ .help-block');
+ var help_block_base_text = 'Set the gist id to update an existing gist, ' +
+ 'or leave blank to create a new one.';
+
+ var gist_it_button = $('#gist_modal').find('.btn-primary');
+
+ id_input.parent()
+ .removeClass('has-success has-error has-warning')
+ .find('#gist_id ~ .form-control-feedback > i.fa')
+ .removeClass('fa-pencil-square fa-exclamation-circle fa-question-circle');
+
+ if (id === '') {
+ $('#gist_id ~ .form-control-feedback > i.fa')
+ .addClass('fa-plus-circle');
+ help_block.html(
+ '' + help_block_base_text + '
' +
+ ' a new gist will be created
'
+ );
+ gist_it_button.prop('disabled', false);
+ }
+ else {
+ $('#gist_id ~ .form-control-feedback > i.fa')
+ .addClass('fa-circle-o-notch fa-spin');
+ // List commits as a way of checking whether the gist exists.
+ // Listing commits appears to give the most concise response.
+
+ $.ajax({
+ url: get_api_endpoint() +'/gists/' + id + '/commits',
+ dataType: 'json',
+ beforeSend: add_auth_token,
+ error: function(jqXHR, textStatus, errorThrown) {
+ jqXHR.errorThrown = errorThrown;
+ },
+ complete: function(jqXHR, textStatus) {
+ var success = textStatus === 'success';
+ var error = !success && jqXHR.status === 404 && jqXHR.responseJSON !== undefined;
+ var warning = !success && !error;
+
+ var help_block_html = '' + help_block_base_text + '
';
+
+ gist_it_button.prop('disabled', error);
+ if (success) {
+ var single = (jqXHR.responseJSON.length === 1);
+ help_block_html += '' +
+ '' +
+ ' gist ' +
+ '' + id + ' will be updated' +
+ ' (' + jqXHR.responseJSON.length +
+ ' revision' + (single ? '' : 's') +
+ ' exist' + (single ? 's' : '') + ' so far)' +
+ '
';
+ }
+ else if (error) {
+ help_block_html += '' +
+ '' +
+ ' no gist exists with the specified id (given current access token)'+
+ '
';
+ }
+ else {
+ help_block_html += '' +
+ '' +
+ ' can\'t list commits for the specified gist id - you may have problems updating it!' +
+ '
';
+ help_block_html += 'The ajax request to Github went wrong:
' +
+ '';
+ if (jqXHR.responseJSON) {
+ help_block_html += JSON.stringify(jqXHR.responseJSON, null, 2);
+ }
+ else {
+ help_block_html += jqXHR.errorThrown || textStatus;
+ }
+ help_block_html += '
';
+ console.log('non-404 github ajax error:', jqXHR, textStatus);
+ }
+ help_block.html(help_block_html);
+
+ id_input.parent()
+ .toggleClass('has-success', success)
+ .toggleClass('has-error', error)
+ .toggleClass('has-warning', warning)
+ .find('#gist_id ~ .form-control-feedback > i.fa')
+ .removeClass('fa-circle-o-notch fa-spin')
+ .toggleClass('fa-pencil-square', success)
+ .toggleClass('fa-exclamation-circle', error)
+ .toggleClass('fa-question-circle', warning);
+ }
+ });
+ }
+ }
+
+ function update_gist_editor (gist_editor) {
+ if (gist_editor === undefined) gist_editor = $('#gist_editor');
+
+ var id_input = gist_editor.find('#gist_id');
+
+ var have_auth = params.gist_it_personal_access_token !== '';
+ var id = '';
+ var is_public = true;
+ if (have_auth) {
+ id = Jupyter.notebook.metadata.gist.id;
+ is_public = Jupyter.notebook.metadata.gist.data.public;
+ id_input.val(id);
+ }
+ id_input.closest('.form-group').toggle(have_auth);
+
+ gist_editor.find('#gist_public')
+ .prop('checked', is_public)
+ .prop('readonly', !have_auth);
+
+ gist_editor.find('#gist_description')
+ .val(Jupyter.notebook.metadata.gist.data.description);
+
+ if (have_auth) {
+ gist_id_updated_callback(gist_editor);
+ }
+ }
+
+ function build_gist_editor () {
+ ensure_default_metadata();
+
+ var gist_editor = $('#gist_editor');
+
+ if (gist_editor.length > 0) return gist_editor;
+
+ gist_editor = $('').attr('id', 'gist_editor').append(controls);
+
+ var id = params.gist_it_personal_access_token !== '' ? Jupyter.notebook.metadata.gist.id : '';
+ var controls = $('')
+ .appendTo(gist_editor)
+ .addClass('form-horizontal');
+
+ $('')
+ .addClass('has-feedback')
+ .hide()
+ .appendTo(controls)
+ .append(
+ $('')
+ .attr('for', 'gist_id')
+ .text('Gist id')
+ )
+ .append(
+ $('')
+ .addClass('form-control')
+ .attr('id', 'gist_id')
+ .val(Jupyter.notebook.metadata.gist.id)
+ )
+ .append(
+ $('')
+ .addClass('form-control-feedback')
+ .append(
+ $('')
+ .addClass('fa fa-lg')
+ )
+ )
+ .append(
+ $('')
+ .addClass('help-block')
+ );
+ $('')
+ .appendTo(controls)
+ .append(
+ $('')
+ .addClass('checkbox')
+ .append(
+ $('