1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 14:54:22 +00:00
This commit is contained in:
Steffo99 2021-12-14 13:01:46 +00:00
commit 7de80cf469
120 changed files with 30595 additions and 0 deletions

4
.buildinfo Normal file
View file

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: ad1ce6c4619f178b93d80c102b76293c
tags: 645f666f9bcd5a90fca523b33c5a78b7

0
.nojekyll Normal file
View file

BIN
_images/admin_details.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
_images/admin_edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
_images/admin_list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
_images/admin_login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
_images/admin_resources.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
_images/admin_site.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
_images/bluelib_amber.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
_images/bluelib_hacker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
_images/bluelib_paper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
_images/bluelib_sophon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
_images/breadcrumbs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
_images/dependabot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
_images/diagram_modules.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
_images/diagram_proxy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
_images/diagram_tags.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
_images/frontend_group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
_images/frontend_login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
_images/google_docs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
_images/group_members.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
_images/hist_example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
_images/jupyter_collab.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
_images/libreoffice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
_images/list_box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
_images/login_royalblue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
_images/notebook_lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
_images/resource_panel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
_images/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
_images/wolfram_cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -0,0 +1,32 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/8_appendice/index.rst
.. only:: html
************
Bibliografia
************
.. [matplotlib:histograms] Matplotlib. **Histograms**. https://web.archive.org/web/20210815080710/https://matplotlib.org/stable/gallery/statistics/hist.html
.. [jupyter:ifaq] Project Jupyter. **Institutional FAQ**. https://web.archive.org/web/20200317115530/https://jupyterhub.readthedocs.io/en/stable/getting-started/institutional-faq.html
.. [jupyter:hub] Project Jupyter. **JupyterHub**. https://web.archive.org/web/20211115163603/https://jupyterhub.readthedocs.io/en/stable/
.. [jupyter:kernels] Project Jupyter. **Jupyter kernels**. https://web.archive.org/web/20211118154819/https://github.com/jupyter/jupyter/wiki/Jupyter-kernels
.. [jupyter:collaboration] Project Jupyter. **Real Time Collaboration**. https://web.archive.org/web/20211118174617/https://jupyterlab.readthedocs.io/en/stable/user/rtc.html
.. [wiki:eln] English Wikipedia. **Electronic lab notebook**. https://en.wikipedia.org/w/index.php?title=Electronic_lab_notebook&oldid=993314047
.. [overleaf:learn30mins] Overleaf. **Learn LaTeX in 30 minutes**. https://web.archive.org/web/20211116220924/https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes
.. [so:survey2021] Stack Overflow. **2021 Developer Survey**. https://web.archive.org/web/20211126152610/https://insights.stackoverflow.com/survey/2021
.. [docker:overview] Docker. **Overview**. https://web.archive.org/web/20211121165850/https://docs.docker.com/get-started/overview/
.. [docker:networking] Docker. **Networking overview**. https://web.archive.org/web/20211111155419/https://docs.docker.com/network/
.. [docker:volumes] Docker. **Use volumes**. https://web.archive.org/web/20211121172749/https://docs.docker.com/storage/volumes/
.. [github:features] GitHub. **Features**. https://web.archive.org/web/20211124034005/https://github.com/features

View file

@ -0,0 +1,82 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/8_conclusione/index.rst
.. index::
pair: Sophon; futuro
*******************
Il futuro di Sophon
*******************
Lo sviluppo di Sophon lascia aperte innumerevoli strade per la sua espansione con funzionalità aggiuntive.
Si conclude la tesi analizzandone alcune.
Repository GitHub di Sophon
===========================
È stato creato un `repository per il progetto su GitHub <https://github.com/Steffo99/sophon>`_.
Oltre al codice sorgente, esso include `un issue tracker <https://github.com/Steffo99/sophon/issues>`_, all'interno del quale viene tenuto traccia di tutte le proposte di funzionalità aggiuntive.
Si elencano alcune delle funzionalità proposte.
.. index::
pair: Sophon; documento
Nuova entità: il documento
--------------------------
Si propone di sviluppare una nuova entità, il *documento*, che permetterebbe agli utenti di Sophon di creare testi in Markdown senza uscire dall'interfaccia web, e di renderli disponibili basandosi sul sistema di permessi di Sophon.
.. figure:: diagram_documents.png
Schema del database se venisse aggiunta l'entità "Documento".
.. index::
pair: Sophon; tag
Sistema per organizzazione delle entità
---------------------------------------
Si propone di realizzare dei sistemi che permettano di catalogare e raggruppare le entità di ogni tipo attraverso parole chiave (*tag*) selezionabili dal creatore della relativa entità.
Un esempio di tag potrebbe essere ``[Tesi]``, utilizzabile per i progetti relativi alle tesi degli studenti di un corso.
.. figure:: diagram_tags.png
:scale: 25%
Un esempio di come potrebbero funzionare i tag applicati ai progetti.
.. index::
single: activity log
single: registro delle attività
Registro delle attività
-----------------------
Si propone di creare un registro, detto *delle attività* o in inglese *activity log*, all'interno del quale siano registrate tutte le azioni effettuate sulle entità del progetto.
Ciò favorirebbe la accountability tra gli utenti di Sophon, in quanto diverrebbe possibile identificare il responsabile di certe azioni distruttive, come l'eliminazione di un intero gruppo.
.. figure:: diagram_activity_log.png
:scale: 35%
Un esempio di come potrebbe funzionare il registro delle attività.
.. index::
pair: Sophon; federazione tra istanze
Federazione tra istanze
-----------------------
L'ultima proposta, molto ambiziosa, sarebbe quella di permettere la *federazione* tra le varie istanze Sophon, consentendo la condivisione di risorse attraverso più istituzioni senza dover creare utenti "locali" per ciascun collaboratore.
.. figure:: diagram_federation.png
:scale: 50%
Un diagramma di esempio di possibile federazione di Sophon.

View file

@ -0,0 +1,26 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/1_requirements.rst
.. index::
pair: Sophon; requisiti di installazione
Requisiti dell'host
===================
- Una connessione ad Internet (solo in fase di installazione)
- `GNU Wget`_ (solo in fase di installazione)
- Un nome di dominio
- Un webserver (ad esempio, `Apache HTTPd`_)
- Un certificato SSL valido *(opzionale, ma raccomandato)*
- `Docker Engine`_
- `Docker Compose`_
.. hint::
È possibile ottenere gratuitamente un certificato SSL utilizzando `Letsencrypt`_!
.. _GNU Wget: https://www.gnu.org/software/wget/
.. _Apache HTTPd: https://httpd.apache.org/
.. _Docker Engine: https://docs.docker.com/engine/
.. _Docker Compose: https://docs.docker.com/compose/
.. _Letsencrypt: https://letsencrypt.org/

View file

@ -0,0 +1,32 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/2_preparing_compose.rst
Preparazione di Docker Compose
==============================
Come ``root``, si crei una nuova cartella sul proprio sistema operativo in cui archiviare le risorse relative a Sophon:
.. code-block:: console
root:~# mkdir -p /dock/sophon
Successivamente, si scarichi il file ``docker-compose.yml`` all'interno della cartella dal repository di Sophon:
.. code-block:: console
root:~# cd /dock/sophon
root:/dock/sophon# wget "https://raw.githubusercontent.com/Steffo99/sophon/main/docker-compose.yml"
--2021-11-02 18:03:05-- https://raw.githubusercontent.com/Steffo99/sophon/main/docker-compose.yml
SSL_INIT
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133,
185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com) 185.199.108.133:443...
connected.
HTTP request sent, awaiting response... 200 OK
Length: 2957 (2.9K) [text/plain]
Saving to: docker-compose.yml
docker-compose.yml 100%[===================>] 2.89K --.-KB/s in 0s
2021-11-02 18:03:05 (48.0 MB/s) - docker-compose.yml saved [2957/2957]

View file

@ -0,0 +1,19 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/3_configuring_dns.rst
Configurazione DNS
==================
Si scelga il dominio (o sottodominio) sul quale si vuole che Sophon sia accessibile e si aggiungano i seguenti record DNS, sostituendo il dominio ``ilmiosophon.it`` con il proprio nome di dominio, e gli indirizzi IPv4 e IPv6 del server al posto di ``0.0.0.0`` e ``1234::1234``:
.. code-block:: text
*.ilmiosophon.it 1800 IN A 0.0.0.0
*.ilmiosophon.it 1800 IN AAAA 1234::1234
ilmiosophon.it 1800 IN A 0.0.0.0
ilmiosophon.it 1800 IN AAAA 1234::1234
Sophon sarà quindi accessibile ai seguenti indirizzi:
- l'interfaccia web al dominio base (``https://ilmiosophon.it/``);
- l'API al dominio base prefisso con ``api.`` (``https://api.ilmiosophon.it/``);
- i notebook al dominio base prefissi con lo slug del notebook (``https://ilmionotebook.ilmiosophon.it/``).

View file

@ -0,0 +1,199 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/4_configuring_compose.rst
Configurazione ``docker-compose.yml``
=====================================
Si configuri con l'editor di testo preferito il file ``docker-compose.yml`` con le impostazioni desiderate.
.. code-block:: console
root:/dock/sophon# open docker-compose.yml
In particolare, tutte le impostazioni precedute da ``# INSTALL`` vanno obbligatoriamente modificate.
.. envvar:: DJANGO_SECRET_KEY
Specifica la chiave segreta da usare per i cookie di sessione.
.. code-block:: yaml
- DJANGO_SECRET_KEY=do-not-use-this-key-in-production-or-you-will-get-hacked
.. warning::
Cambiare la chiave segreta una volta installato Sophon invaliderà tutti gli accessi effettuati dagli utenti.
.. danger::
La chiave segreta è un dato estremamente riservato: chiunque sia a conoscenza della chiave segreta potrà effettuare l'accesso come qualsiasi utente!
.. seealso::
`SECRET_KEY <https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-SECRET_KEY>`_ nella documentazione di Django.
.. envvar:: DJANGO_PROXY_BASE_DOMAIN
Specifica il dominio che dovrà essere usato come radice per il proxy, ovvero il dominio per il quale si è configurato il DNS in precedenza.
Se non è specificato, Sophon verrà eseguito in `modalità sviluppo <Modalità sviluppo>`.
.. code-block:: yaml
- DJANGO_PROXY_BASE_DOMAIN=ilmiosophon.it
.. envvar:: DJANGO_PROXY_PROTOCOL
Specifica il protocollo che dovrà essere usato nei mapping del proxy.
Si consiglia di utilizzare ``https``, ma è un valore valido anche ``http``.
.. code-block:: yaml
- DJANGO_PROXY_PROTOCOL=https
.. envvar:: DJANGO_ALLOWED_HOSTS
Specifica i domini da cui possono provenire le richieste alla pagina di amministrazione.
Per specificare più domini, è necessario separarli con dei pipe ``|`` .
Eccetto in configurazioni speciali, deve essere uguale al dominio prefisso da ``api.``.
.. code-block:: yaml
- DJANGO_ALLOWED_HOSTS=api.ilmiosophon.it
.. seealso::
`ALLOWED_HOSTS <https://docs.djangoproject.com/en/3.2/ref/settings/#allowed-hosts>`_ nella documentazione di Django.
.. envvar:: DJANGO_ALLOWED_ORIGINS
Specifica i domini da cui possono provenire le richieste all'API.
Per specificare più domini, è necessario separarli con dei pipe ``|`` .
Eccetto in configurazioni speciali, deve contenere il proprio dominio prefisso dal protocollo, e in aggiunta il dominio speciale ``https://sophon.steffo.eu``, necessario per permettere l'accesso dall'interfaccia web "universale" di Sophon.
.. code-block:: yaml
- DJANGO_ALLOWED_ORIGINS=https://ilmiosophon.it|https://sophon.steffo.eu
.. seealso::
L'header `Access-Control-Allow-Origin <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin>`_ su MDN.
.. envvar:: DJANGO_STATIC_URL
Specifica l'URL a cui saranno accessibili i file statici di Sophon.
Eccetto in configurazioni speciali, deve essere uguale alla seguente stringa, con le parole in maiuscolo sostituite rispettivamente dal protocollo e dal dominio selezionato: ``PROTOCOLLO://static.DOMINIO/django-static/``.
.. code-block:: yaml
- DJANGO_ALLOWED_ORIGINS=http://static.ilmiosophon.it/django-static/
.. warning::
Ci si assicuri che sia presente uno slash al termine della stringa, oppure il pannello di amministrazione non sarà visualizzato correttamente!
.. seealso::
`STATIC_URL <https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-STATIC_URL>`_ nella documentazione di Django
.. envvar:: DJANGO_LANGUAGE_CODE
Specifica la lingua che deve usare Sophon nei messaggi di errore.
Usa il formato `language code`_ di Django.
.. code-block:: yaml
- DJANGO_LANGUAGE_CODE=en-us
.. seealso::
`LANGUAGE_CODE <https://docs.djangoproject.com/en/3.2/ref/settings/#language-code>`_ nella documentazione di Django
.. _language code: https://docs.djangoproject.com/en/3.2/topics/i18n/#term-language-code
.. envvar:: DJANGO_TIME_ZONE
Specifica il fuso orario che deve usare Sophon nell'interfaccia di amministrazione.
Usa il formato `tzdata`_.
.. code-block:: yaml
- DJANGO_TIME_ZONE=Europe/Paris
.. hint::
Il fuso orario italiano è ``Europe/Rome``.
.. _tzdata: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
.. envvar:: DJANGO_SU_USERNAME
Specifica il nome del :ref:`superutente <Livelli di accesso>` che verrà automaticamente creato qualora il database non contenga altri utenti.
.. code-block:: yaml
- DJANGO_SU_USERNAME=root
.. envvar:: DJANGO_SU_EMAIL
Specifica l'email del :ref:`superutente <Livelli di accesso>` che verrà automaticamente creato qualora il database non contenga altri utenti.
.. code-block:: yaml
- DJANGO_SU_USERNAME=django@example.org
.. note::
Attualmente, l'email non è utilizzata, ma è richiesta da Django per la creazione di un nuovo utente.
.. envvar:: DJANGO_SU_PASSWORD
Specifica la password del :ref:`superutente <Livelli di accesso>` che verrà automaticamente creato qualora il database non contenga altri utenti.
.. code-block:: yaml
- DJANGO_SU_PASSWORD=square
.. warning::
La password è un dato estremamente riservato, in quanto chiunque ne venga a conoscenza potrà accedere a Sophon con pieni privilegi!
.. envvar:: REACT_APP_DEFAULT_INSTANCE
Specifica il valore con cui precompilare il campo "selezione istanza" dell'interfaccia web di Sophon.
Eccetto in configurazioni speciali, deve essere uguale al dominio prefisso dal protocollo e da ``api.``.
.. code-block:: yaml
- REACT_APP_DEFAULT_INSTANCE=https://api.ilmiosophon.it
.. envvar:: APACHE_PROXY_BASE_DOMAIN
Specifica il dominio che dovrà essere usato come radice per il proxy, ovvero il ``DOMINIO`` per il quale si è configurato il DNS in precedenza.
Deve essere uguale a :envvar:`DJANGO_PROXY_BASE_DOMAIN`.
.. code-block:: yaml
- APACHE_PROXY_BASE_DOMAIN=ilmiosophon.it

View file

@ -0,0 +1,50 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/5_pulling_images.rst
Download delle immagini Docker
==============================
Si utilizzi `Docker Compose`_ per scaricare le `immagini`_ Docker necessarie all'avvio di Sophon:
.. code-block:: console
root:/dock/sophon# docker compose pull
[+] Running 4/4
⠿ proxy Pulled 1.5s
⠿ frontend Pulled 1.4s
⠿ db Pulled 1.9s
⠿ backend Pulled 1.6s
Inoltre, si scarichi manualmente l':ref:`immagine del Notebook` che può essere avviata da Sophon:
.. code-block:: console
root:/dock/sophon# docker image pull "ghcr.io/steffo99/sophon-jupyter:latest"
latest: Pulling from steffo99/sophon-jupyter
7b1a6ab2e44d: Already exists
578d7ac380c6: Pull complete
37f1e0b584f6: Pull complete
3c7282703390: Pull complete
b38aa558f711: Pull complete
1412103d568f: Pull complete
67419a9a821e: Pull complete
37e6cc015184: Pull complete
7d9316e2b57c: Pull complete
a7f024508c72: Pull complete
f3eae3c301a1: Pull complete
d3e2107efade: Pull complete
d94bc6f8f069: Pull complete
1e1dc3e818ad: Pull complete
c975ee664182: Pull complete
101cfcc0e15b: Pull complete
bf991a0d7538: Pull complete
4c044af18c7e: Pull complete
605d8c6e8eba: Pull complete
ed06f2ae4a88: Pull complete
ed8b1c841d10: Pull complete
468fe9a390ae: Pull complete
Digest: sha256:5d42e5e40e406130c688914d6a58aa94769eab03620b53e0fd409a7fb2682a01
Status: Downloaded newer image for ghcr.io/steffo99/sophon-jupyter:latest
ghcr.io/steffo99/sophon-jupyter:latest
.. _Docker Compose: https://docs.docker.com/compose/
.. _immagini: https://docs.docker.com/engine/reference/commandline/images/

View file

@ -0,0 +1,27 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/6_starting_sophon.rst
.. index::
pair: Sophon; avvio
Avvio di Sophon
===============
Si utilizzi `Docker Compose`_ per eseguire le `immagini`_ di Sophon precedentemente scaricate:
.. code-block:: console
root:/dock/sophon# docker compose up -d
[+] Running 4/4
⠿ Container sophon-db-1 Started 11.3s
⠿ Container sophon-frontend-1 Started 11.7s
⠿ Container sophon-backend-1 Started 10.1s
⠿ Container sophon-proxy-1 Started 11.5s
Si verifichi che i container si siano avviati correttamente con:
.. code-block:: console
root:/dock/sophon# docker compose logs
.. _Docker Compose: https://docs.docker.com/compose/
.. _immagini: https://docs.docker.com/engine/reference/commandline/images/

View file

@ -0,0 +1,64 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/7_host_reverse_proxy.rst
Configurazione del webserver dell'host
======================================
Si configuri il webserver dell'host per inoltrare tutto il traffico dalla porta 443 (o 80, se si è selezionato ``http`` in :envvar:`DJANGO_PROXY_PROTOCOL`) alla porta locale 30033.
Sono allegate le istruzioni per il webserver `Apache HTTPd`_; possono essere però adattate se si vuole usare un webserver diverso, come `NGINX`_ o `caddy`_.
.. _Apache HTTPd: https://httpd.apache.org/
.. _nginx: https://www.nginx.com/
.. _caddy: https://caddyserver.com/
Con Apache HTTPd
----------------
Ci si assicuri che `mod_rewrite`_, `mod_proxy`_, `mod_proxy_http`_ e `mod_proxy_wstunnel`_ siano attivati.
Si aggiungano i seguenti ``VirtualHost`` alla configurazione:
.. code-block:: apacheconf
<VirtualHost *:80>
ServerName "ilmiosophon.it"
ServerAlias "*.ilmiosophon.it"
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
.. code-block:: apacheconf
<VirtualHost *:443>
ServerName "ilmiosophon.it"
ServerAlias "*.ilmiosophon.it"
SSLEngine on
SSLCertificateFile "/SOSTITUISCIMI/CON/IL/PERCORSO/ALLA/FULL/CHAIN/SSL"
SSLCertificateKeyFile "/SOSTITUISCIMI/CON/IL/PERCORSO/ALLA/CHIAVE/PRIVATA/SSL"
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:30033/$1 [P,L]
RewriteRule /(.*) http://127.0.0.1:30033/$1 [P,L]
Protocols h2 http/1.1
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
Infine, si riavvii `Apache HTTPd`_:
.. code-block:: console
root:/dock/sophon# systemctl restart httpd
.. _mod_rewrite: https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
.. _mod_proxy: https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
.. _mod_proxy_http: https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html
.. _mod_proxy_wstunnel: https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

View file

@ -0,0 +1,6 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/8_final_check.rst
Verificare il funzionamento
===========================
Se tutto è stato configurato correttamente, l'interfaccia web Sophon dovrebbe essere raggiungibile al dominio selezionato (``https://ilmiosophon.it``), e dovrebbe essere possibile effettuare il login con le credenziali configurate del primo :ref:`superutente <Livelli di accesso>`.

View file

@ -0,0 +1,23 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/6_installazione/index.rst
.. index::
pair: Sophon; installazione
***********************
Installazione di Sophon
***********************
Questo capitolo descrive la procedura da seguire per installare Sophon.
.. toctree::
1_requirements
2_preparing_compose
3_configuring_dns
4_configuring_compose
5_pulling_images
6_starting_sophon
7_host_reverse_proxy
8_final_check

View file

@ -0,0 +1,48 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/2_introduzione/index.rst
.. index::
pair: tesi; introduzione
**********************
Introduzione alla tesi
**********************
Nel mondo della ricerca universitaria, è frequente la collaborazione tra più colleghi su uno stesso progetto, condividendo dati e materiale al fine di ottenere risultati più efficientemente.
Negli ultimi decenni, le possibilità per effettuare ricerca collaborativa si sono moltiplicate, grazie principalmente allo sviluppo della rete Internet, che permette comunicazione immediata tra istituzioni di tutto il mondo.
Internet infatti ha portato alla creazione di strumenti informatici per facilitare la comunicazione e collaborazione remota, come email, chat, strumenti di revisione bozze e sistemi di controllo versione.
Parallelamente a questi strumenti, sono stati sviluppati degli ambienti di lavoro a supporto della ricerca, che permettono la creazione di documenti interattivi, detti `notebook <Notebook computazionali>`, che combinano analisi di dati ad elementi multimediali come testo formattato, immagini e grafici.
Il più popolare di questi ambienti di lavoro è l'ambiente computazionale `Jupyter`, che all'interno del notebook permette l'utilizzo di molteplici linguaggi di programmazione, sia per l'elaborazione dei dati, sia per la stesura del testo.
Jupyter però ha alcuni problemi: è complesso da installare e mantenere, e non implementa di default molte funzionalità per la collaborazione, la confidenzialità e l'autenticazione, che devono quindi essere implementate da strumenti esterni.
.. index::
pair: tesi; obiettivo
Obiettivo della tesi
====================
L'obiettivo di questa tesi è quello di descrivere lo sviluppo dell'applicativo "*Sophon*", realizzato con il fine di semplificare l'utilizzo di `Jupyter` in ambiente universitario.
.. index::
pair: tesi; struttura
Struttura della tesi
====================
La tesi è strutturata nel seguente modo:
#. nel primo capitolo, :ref:`Sinossi`, viene descritto molto brevemente il progetto realizzato;
#. nel secondo capitolo, :ref:`Introduzione alla tesi`, viene introdotto il contesto della tesi, la tesi stessa e i suoi contenuti;
#. nel terzo capitolo, :ref:`Ricerca collaborativa`, viene presentata in dettaglio la situazione attuale della ricerca collaborativa;
#. nel quarto capitolo, :ref:`Progettazione di Sophon`, viene descritta la progettazione avvenuta, entrando nei dettagli dei requisiti, della suddivisione in moduli e delle astrazioni create;
#. nel quinto capitolo, :ref:`Realizzazione di Sophon`, vengono trattate le specifiche tecniche implementative del progetto;
#. nel sesto capitolo, :ref:`Risultati ottenuti`, viene mostrato il risultato finale del processo di sviluppo;
#. nel settimo capitolo, :ref:`Il futuro di Sophon`, vengono tratte le conclusioni della tesi.
In aggiunta, nell'appendice, è disponibile una guida tecnica all':ref:`Installazione di Sophon`.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,207 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/3_presentazione/index.rst
.. index::
single: ricerca collaborativa
*********************
Ricerca collaborativa
*********************
Nelle scienze, sia teoriche, sia sperimentali, si verifica spesso la necessità di dover prendere appunti e condividere appunti sulla ricerca effettuata.
Mentre in passato a tale scopo venivano utilizzati quaderni di carta (detti anche *"blocchi note laboratoriali"* [wiki:eln]_), con la nascita dell'informatica si iniziarono ad utilizzare strumenti digitali, più comodi ed efficienti: inizialmente, semplici sistemi di composizione tipografica come *TeX*, poi editor :abbr:`WYSIWYG (What You See Is What You Get)` come *Microsoft Word*, arrivando infine negli ultimi anni ai più avanzati e interattivi `notebook computazionali <Notebook computazionali>`.
.. index::
pair: sistemi; composizione tipografica
Sistemi di composizione tipografica
===================================
I primi sistemi utilizzati in ambito accademico per la creazione di documenti erano molto semplici: si limitavano a descrivere come dovevano apparire i contenuti sul foglio stampato attraverso istruzioni molto simili a quelle di un linguaggio di programmazione.
Sono esempi di sistemi di composizione tipografica `TeX <https://www.tug.org/begin.html>`_, usato ancora oggi in combinazione con il sistema `LaTeX <https://www.latex-project.org//>`_ per comporre documenti accademici come paper e tesi (inclusa questa), e `roff <https://en.wikipedia.org/wiki/Roff_(software)>`_, su cui si basa oggi lo strumento `groff <https://it.wikipedia.org/wiki/Groff_(software)>`_ per comporre le pagine di manuale dei sistemi operativi Unix-like.
Un esempio di documento LaTeX [overleaf:learn30mins]_ è il seguente:
.. code-block:: latex
\documentclass{article}
\begin{document}
First document.
This is a simple example, with no extra parameters or packages included.
\end{document}
.. index::
pair: editor; WYSIWYG
Editor WYSIWYG
==============
Con l'evolversi dei sistemi operativi, in particolare con la diffusione dei sistemi operativi a finestre, sono stati sviluppati software detti "editor di testo :abbr:`WYSIWYG (What You See Is What You Get)`", che permettono di scrivere documenti avendo un'anteprima istantanea del testo inserito.
Essendo molto più intuitivi da usare dei loro predecessori, ne hanno preso rapidamente il posto in tutto il mondo, di fatto limitando l'uso dei `sistemi di composizione tipografica <Sistemi di composizione tipografica>` ad ambiti in cui era necessaria una formattazione avanzata dei documenti.
Alcuni esempi moderni di editor :abbr:`WYSIWYG (What You See Is What You Get)` sono `Microsoft Word <https://www.microsoft.com/it-it/microsoft-365/word>`_ e `LibreOffice Writer <https://it.libreoffice.org/scopri/writer/>`_.
.. figure:: libreoffice.png
Modifica di un documento su LibreOffice 7.2.2.2.
.. index::
pair: editor; web-based
Web-based editor
================
Il paradigma web "2.0" ha portato miglioramenti significativi agli editor :abbr:`WYSIWYG (What You See Is What You Get)`, rendendoli utilizzabili online come software-as-a-service direttamente da un browser.
Ciò ha semplificato il processo di collaborazione sui documenti: non è più necessario inviare ai collaboratori tutte le revisioni dei documenti, ma è possibile semplicemente condividergli un link, al quale sarà possibile accedere al documento.
Da questa funzionalità ne è poi derivata un'altra, che ha rivoluzionato la scrittura di testi: la possibilità di collaborare online con gli altri autori, vedendo le loro modifiche in tempo reale.
Il più importante di questi editor è `Google Docs <https://docs.google.com/>`_, rilasciato nel 2009; la sua popolarità ha portato allo sviluppo di alternative come `Office 365 <https://www.office.com/>`_, una versione web di `Microsoft Word <Editor WYSIWYG>`.
.. figure:: google_docs.png
Un esempio di collaborazione su un documento Google Docs.
.. index::
single: notebook; computazionali
pair: notebook; celle
Notebook computazionali
=======================
In parallelo ai `web-based editor <Web-based editor>`, ha preso piede nel mondo della ricerca scientifica una nuova tipologia di documento: il notebook computazionale.
I *notebook computazionali* sono un tipo di documento interattivo che permette contemporaneamente di analizzare dati, elaborarli e documentare elaborazioni effettuate e risultati ottenuti.
Essi sono composti da tante **celle**, ciascuna contenente codice in un determinato linguaggio di programmazione o di marcatura, il quale è eseguito, mostrandone poi i risultati all'utente, sotto forma di testo, equazioni, immagini, grafici, o anche widget interattivi come slider o aree di input testo.
Alcuni esempi di software per la scrittura di notebook computazionali sono `Jupyter <https://jupyter.org/>`_, `Wolfram Mathematica <https://www.wolfram.com/mathematica/>`_, `MATLAB Live Editor <https://it.mathworks.com/products/matlab/live-editor.html>`_...
.. figure:: wolfram_cloud.png
Un esempio di notebook Mathematica, scritto su Wolfram Cloud.
.. index::
single: Jupyter
Jupyter
=======
*Jupyter* è un software open-source che permette la scrittura e la visualizzazione di `notebook computazionali <Notebook computazionali>`.
Come tutti i notebook computazionali è strutturato in celle, le quali possono contenere testo, dati oppure codice di programmazione con relativo output.
Prende ispirazione dai `web-based editor <Web-based editor>`, permettendo agli utenti di modificare i notebook direttamente da un browser web, e include rudimentali funzionalità di collaborazione in tempo reale [jupyter:collaboration]_.
.. figure:: hist_example.png
:scale: 100%
Un esempio di notebook Jupyter con una cella di testo e una cella di Python che emette un grafico [matplotlib:histograms]_.
.. index::
pair: Jupyter; componenti
Componenti di Jupyter
---------------------
Jupyter è composto da 3 componenti: un `kernel <Kernel Jupyter>`, un `server <server Jupyter>` e un `client <client Jupyter>`.
.. index::
pair: Jupyter; kernel
single: IPython
Kernel Jupyter
^^^^^^^^^^^^^^
Il kernel è la parte di Jupyter che si occupa di eseguire le celle del notebook, restituendone i risultati al `server <server Jupyter>`.
Per ogni linguaggio di programmazione che si desidera utilizzare nel notebook è necessario il relativo **kernel**: il kernel predefinito di Jupyter è `IPython <https://ipython.org/>`_, che permette di utilizzare il linguaggio di programmazione `Python <https://www.python.org/>`_; sono però disponibili tanti altri kernel, tra cui uno per `Julia <https://julialang.org/>`_ e uno per `R <https://www.r-project.org/>`_ [jupyter:kernels]_.
.. index::
pair: Jupyter; server
Server Jupyter
^^^^^^^^^^^^^^
Il **server** è la parte di Jupyter che gestisce le interazioni del `client <client Jupyter>` con il notebook, inoltrandole al `kernel <kernel Jupyter>` appropriato se necessario.
Il server ufficiale di Jupyter è `Jupyter Server <https://github.com/jupyter-server/jupyter_server>`_.
.. index::
pair: Jupyter; client
single: Jupyter; Jupyter Notebook
single: Jupyter; JupyterLab
Client Jupyter
^^^^^^^^^^^^^^
Il **client** è la parte di Jupyter che mostra in un formato user-friendly il contenuto del notebook e gli permette di interagirvi, comunicando le interazioni al `server <server Jupyter>`.
Esistono due client ufficiali per Jupyter: il client di vecchia generazione `Jupyter Notebook <https://github.com/jupyter/notebook>`_ e il client di nuova generazione `JupyterLab <https://github.com/jupyterlab>`_, entrambi web-based.
.. index::
pair: Jupyter; hosting
Hosting di Jupyter
------------------
Essendo `server <server Jupyter>` e `client <client Jupyter>` separati, è possibile eseguire il server su una macchina e il client su un'altra.
È possibile selezionare la macchina su cui eseguire il server in tre modi diversi, elencati nelle prossime sezioni, ciascuno con alcuni vantaggi e svantaggi.
Hosting locale
^^^^^^^^^^^^^^
È possibile installare il server Jupyter **sul proprio computer**.
Così facendo, le celle saranno eseguite con le risorse del proprio computer, e il notebook sarà accessibile solo dal computer che sta eseguendo il server.
È un ottimo modo per lavorare su progetti personali, in quanto offre la massima personalizzazione attraverso un sistema di plugin installabili, e per lavorare offline, in quanto è l'unico modo di usare il server senza connessione ad Internet.
In base al proprio sistema operativo, però, potrebbe risultare difficile da installare, e in base alla propria configurazione di rete, la collaborazione realtime su un progetto potrebbe essere impossibile.
.. index::
single: Google Colaboratory
single: SageMaker Notebook
Come software-as-a-service
^^^^^^^^^^^^^^^^^^^^^^^^^^
È possibile utilizzare un server Jupyter **gestito da un cloud provider** ed utilizzare le risorse da esso fornite per eseguire le celle.
Un esempio di cloud provider che fornisce questo servizio è Google, con `Google Colaboratory <https://colab.research.google.com/#>`_.
Usare il modello :abbr:`SaaS (Software as a Service)` è il modo più semplice per usare Jupyter, in quanto non richiede di effettuare alcuna installazione sul proprio computer, e in genere permette di collaborare online con altri utenti.
Di contro, però, Jupyter sulle piattaforme :abbr:`SaaS (Software as a Service)` non permette l'installazione di plugin, limitando la personalizzazione, e, se si necessitano più risorse di quelle offerte gratuitamente dai provider, si rischiano canoni mensili elevati.
.. index::
single: Jupyter; JupyterHub
Hosting on-premises
^^^^^^^^^^^^^^^^^^^
È possibile configurare un **server della propria istituzione** in modo tale che esegua uno o più `server Jupyter <Server Jupyter>` a cui si connetteranno i `client <client Jupyter>`.
A tale scopo, è disponibile il progetto `JupyterHub <https://jupyter.org/hub>`_, in grado di gestire migliaia di utenti simultanei [jupyter:ifaq]_, ciascuno con il proprio notebook.
È performante ed efficace, e in base alla configurazione scelta dall'amministratore, può permettere agli utenti di personalizzare il loro ambiente di lavoro con plugin.
L'interfaccia di gestione utenti e notebook è però molto essenziale, e in aggiunta non supporta nativamente la collaborazione real-time su un singolo notebook, preferendo il modello *"tanti server Jupyter da utente singolo"* [jupyter:hub]_.

View file

@ -0,0 +1,292 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/7_utilizzo/index.rst
.. index::
pair: Sophon; utilizzare
******************
Risultati ottenuti
******************
Al termine del periodo di sviluppo, il software ha soddisfatto `tutti i requisiti prefissati <Requisiti del progetto>`.
In particolare:
* tutte le funzionalità desiderate sono state sviluppate, raggiungendo la feature parity con JupyterHub;
* il software ha ampio spazio per eventuali `estensioni <Estendibilità>` grazie alle numerosi classi astratte sviluppate;
* l'isolamento tra notebook e l'autenticazione all'accesso è stata realizzata, garantendo la `sicurezza <Sicurezza>` dei dati;
* l'interfaccia web è sufficientemente `intuitiva <Intuitività>` per permetterne un utilizzo e apprendimento autonomo;
* è possibile `personalizzare <Personalizzabilità>` i dettagli del software con il brand della propria istituzione;
* più utenti possono `collaborare <Possibilità di collaborazione>` simultaneamente all'interno dello stesso notebook;
* il software è stato pubblicato su `GitHub` come progetto `open source <Open source>`;
* da dispositivi mobili, l'interfaccia grafica di Sophon risulta interamente utilizzabile, raggiungendo il requisito di `responsività <Responsività>`, anche se la modifica di notebook computazionali con JupyterLab potrebbe risultare difficile su schermi con risoluzione molto ridotta;
* l'interfaccia web soddisfa i requisiti di `accessibilità <Accessibilità>` fissati;
* il software è sufficientemente stabile per l'utilizzo in produzione, permettendone il suo utilizzo all'interno dell'Università;
* le `istruzioni per l'installazione <Installazione di Sophon>` sono state scritte, permettendo ad altri interessati di installare Sophon.
Stato finale del modulo backend
===============================
Il modulo backend terminato espone una web API all'indirizzo :samp:`api.{BASE_DOMAIN}` con i seguenti endpoints.
.. http:post:: /api/auth/token/
:synopsis: Richiesta token autenticazione
Effettua l'accesso in cambio di un token di autenticazione.
:json string username: Username dell'utente.
:json string password: Password dell'utente.
:status 200: Login riuscito.
.. http:post:: /api/auth/session/
:synopsis: Richiesta cookies autenticazione
Effettua l'accesso, salvando i dati di autenticazione nei cookie.
:json string username: Username dell'utente.
:json string password: Password dell'utente.
:status 200: Login riuscito.
.. http:any:: /api/core/groups/
:synopsis: Gruppi di ricerca
Accede ai `gruppi di ricerca <Gruppi di ricerca in Sophon>`, permettendone la visualizzazione (``GET``), la creazione (``POST``), la modifica (``PUT``) e l'eliminazione (``DELETE``), a condizione che si sia autorizzati ad effettuare l'operazione.
:json string slug: Slug del gruppo di ricerca.
:json string name: Nome del gruppo di ricerca.
:json string description: Descrizione del gruppo di ricerca.
:json string access: `Modalità di accesso <Membri e modalità di accesso>` al gruppo.
:json integer owner: ID del creatore del gruppo.
:json integer[] members: Elenco dei membri degli ID dei membri del gruppo.
:status 200: Operazione effettuata.
:status 201: Risorsa creata.
:status 204: Risorsa eliminata.
:status 401: Accesso non effettuato.
:status 403: Operazione non permessa.
:status 404: Risorsa non esistente.
.. http:get:: /api/core/users/by-id/
:synopsis: Utenti in ordine di ID
Accede agli `utenti <Utenti in Sophon>` dell'istanza Sophon usando il loro ID come chiave, permettendone la visualizzazione.
:json integer id: ID dell'utente.
:json string username: Username dell'utente.
:json string first_name: Nome dell'utente (non utilizzato se non specificato manualmente nell'interfaccia di amministrazione).
:json string last_name: Cognome dell'utente (non utilizzato se non specificato manualmente nell'interfaccia di amministrazione).
:json string email: Email dell'utente (non utilizzata se non specificata manualmente nell'interfaccia di amministrazione).
:status 200: Operazione effettuata.
.. http:get:: /api/core/users/by-username/
:synopsis: Utenti in ordine di username
Accede agli `utenti <Utenti in Sophon>` dell'istanza Sophon usando il loro username come chiave, permettendone la visualizzazione.
:json string id: ID dell'utente.
:json string username: Username dell'utente.
:json string first_name: Nome dell'utente (non utilizzato se non specificato manualmente nell'interfaccia di amministrazione).
:json string last_name: Cognome dell'utente (non utilizzato se non specificato manualmente nell'interfaccia di amministrazione).
:json string email: Email dell'utente (non utilizzata se non specificata manualmente nell'interfaccia di amministrazione).
:status 200: Operazione effettuata.
.. http:any:: /api/projects/by-slug/
:synopsis: Tutti i progetti
Accede a tutti i `progetti di ricerca <Progetti di ricerca in Sophon>` dell'istanza Sophon, permettendone la visualizzazione (``GET``), la creazione (``POST``), la modifica (``PUT``) e l'eliminazione (``DELETE``), a condizione che si sia autorizzati ad effettuare l'operazione.
:json string slug: Slug del progetto.
:json string name: Nome del progetto.
:json string description: Descrizione del progetto.
:json string visibility: `Visibilità <Visibilità dei progetti>` del progetto.
:json string group: Slug del gruppo a cui appartiene il progetto.
:status 200: Operazione effettuata.
:status 201: Risorsa creata.
:status 204: Risorsa eliminata.
:status 401: Accesso non effettuato.
:status 403: Operazione non permessa.
:status 404: Risorsa non esistente.
.. http:any:: /api/projects/by-group/(str:group_slug)/
:synopsis: Progetti di un determinato gruppo
Accede ai `progetti di ricerca <Progetti di ricerca in Sophon>` appartenenti a un certo gruppo, permettendone la visualizzazione (``GET``), la creazione (``POST``), la modifica (``PUT``) e l'eliminazione (``DELETE``), a condizione che si sia autorizzati ad effettuare l'operazione.
:param group_slug: Slug del gruppo di cui si vogliono ottenere i progetti.
:json string slug: Slug del progetto.
:json string name: Nome del progetto.
:json string description: Descrizione del progetto.
:json string visibility: `Visibilità <Visibilità dei progetti>` del progetto.
:json string group: Slug del gruppo a cui appartiene il progetto.
:status 200: Operazione effettuata.
:status 201: Risorsa creata.
:status 204: Risorsa eliminata.
:status 401: Accesso non effettuato.
:status 403: Operazione non permessa.
:status 404: Risorsa non esistente.
.. http:any:: /api/notebooks/by-slug/
:synopsis: Tutti i notebook
Accede a tutti i `notebook <Notebook in Sophon>` dell'istanza Sophon, permettendone la visualizzazione (``GET``), la creazione (``POST``), la modifica (``PUT``) e l'eliminazione (``DELETE``), a condizione che si sia autorizzati ad effettuare l'operazione.
.. note::
Questo endpoint non restituisce i dettagli di connessione al notebook; a tale scopo, è necessario utilizzare :http:any:`/api/notebooks/by-project/(str:project_slug)/`.
:json string slug: Slug del notebook.
:json string name: Nome del notebook.
:json boolean is_running: Se il notebook è `avviato <Stato del notebook>` oppure no.
:json integer locked_by: ID dell'utente che ha `bloccato <Blocco di un notebook>` il notebook.
:json string container_image: Il nome dell'`immagine <Immagine del notebook>` del notebook.
:json string project: Slug del progetto a cui appartiene il notebook.
:status 200: Operazione effettuata.
:status 201: Risorsa creata.
:status 204: Risorsa eliminata.
:status 401: Accesso non effettuato.
:status 403: Operazione non permessa.
:status 404: Risorsa non esistente.
.. http:any:: /api/notebooks/by-project/(str:project_slug)/
:synopsis: Notebook di un determinato progetto
Accede ai `notebook <Notebook in Sophon>` appartenenti a un certo progetto, permettendone la visualizzazione (``GET``), la creazione (``POST``), la modifica (``PUT``) e l'eliminazione (``DELETE``), a condizione che si sia autorizzati ad effettuare l'operazione.
:json string slug: Slug del notebook.
:json string name: Nome del notebook.
:json boolean is_running: Se il notebook è `avviato <Stato del notebook>` oppure no.
:json integer locked_by: ID dell'utente che ha `bloccato <Blocco di un notebook>` il notebook.
:json string container_image: Il nome dell'`immagine <Immagine del notebook>` del notebook.
:json string project: Slug del progetto a cui appartiene il notebook.
:json string jupyter_token: Token per l'autenticazione sul `modulo Jupyter <Modulo Jupyter>`.
:json string legacy_notebook_url: URL per la connessione all'interfaccia legacy "*Jupyter Notebook*" del notebook.
:json string lab_url: URL per la connessione all'interfaccia `JupyterLab <Client Jupyter>` del notebook.
:status 200: Operazione effettuata.
:status 201: Risorsa creata.
:status 204: Risorsa eliminata.
:status 401: Accesso non effettuato.
:status 403: Operazione non permessa.
:status 404: Risorsa non esistente.
Pagina di amministrazione esposta
---------------------------------
In aggiunta alla web API, Sophon espone la :ref:`pagina di amministrazione <Pagina di amministrazione>` Django al seguente URL.
.. http:get:: /admin/
:synopsis: Pagina di amministrazione
La pagina di amministrazione Django, personalizzata per Sophon.
:status 200: Accesso riuscito.
La prima pagina richiede l'accesso con credenziali di un `superutente <Livelli di accesso>`.
.. figure:: admin_login.png
:scale: 80%
Schermata di login della pagina di amministrazione.
Una volta effettuato l'accesso, all'interno della pagina è possibile modificare ogni genere di `entità <Entità di Sophon>` presente nell'istanza.
.. figure:: admin_resources.png
:scale: 50%
Elenco delle entità presenti all'interno dell'istanza.
.. figure:: admin_list.png
:scale: 50%
Elenco dei notebook presenti all'interno dell'istanza di dimostrazione.
.. figure:: admin_edit.png
:scale: 50%
Pagina di modifica di uno dei notebook dell'istanza di dimostrazione.
.. figure:: admin_details.png
:scale: 50%
Pagina di modifica dei dettagli dell'istanza Sophon.
Stato finale del modulo frontend
================================
Il modulo frontend terminato espone una :abbr:`SPA (single page app)` all'indirizzo :samp:`{BASE_DOMAIN}`.
.. figure:: frontend_instance.png
:scale: 50%
Pagina di selezione istanza.
.. figure:: frontend_login.png
:scale: 50%
Pagina di login all'istanza Sophon di dimostrazione, che utilizza il tema "Royal Blue".
.. figure:: frontend_group.png
:scale: 50%
Pagina di selezione e creazione gruppi di ricerca.
.. figure:: frontend_project.png
:scale: 50%
Pagina di selezione e creazione progetti di ricerca.
.. figure:: frontend_notebook.png
:scale: 50%
Pagina di selezione, creazione e avvio notebook.
.. figure:: frontend_nbdetails.png
:scale: 50%
Pagina di dettagli di un notebook, che permette l'accesso al modulo Jupyter.
Stato finale del modulo Jupyter
===============================
Il modulo Jupyter terminato espone un'istanza collaborativa di `JupyterLab <Client Jupyter>` all'indirizzo :samp:`{NOTEBOOK_SLUG}.{BASE_DOMAIN}`.
.. figure:: jupyter_collab.png
:scale: 30%
Stato finale del modulo proxy
=============================
Il modulo proxy terminato effettua correttamente proxying tra gli altri moduli.

View file

@ -0,0 +1,13 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/1_sinossi/index.rst
.. index::
pair: tesi; sinossi
Sinossi
*******
La tesi descrive lo sviluppo di **Sophon**, software che permette a gruppi di ricerca di collaborare in sicurezza da remoto all'interno di ambienti `Jupyter` eseguiti sui server della loro organizzazione.
.. figure:: screenshot.png
Cattura schermo dell'interfaccia grafica di Sophon.

37
_sources/index.rst.txt Normal file
View file

@ -0,0 +1,37 @@
:github_url: https://github.com/Steffo99/sophon/blob/main/thesis/source/index.rst
##############################################################################
Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca
##############################################################################
.. toctree::
:maxdepth: 6
:numbered: 2
:caption: Contenuti
docs/sinossi/index
docs/introduzione/index
docs/ricercacollaborativa/index
docs/progetto/index
docs/realizzazione/index
docs/risultato/index
docs/conclusione/index
docs/bibliografia/index
.. toctree::
:maxdepth: 6
:numbered: 2
:caption: Appendice
docs/installazione/index
.. only:: html
Collegamenti utili
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`routingtable`
* :ref:`search`

294
_static/base-stemmer.js Normal file
View file

@ -0,0 +1,294 @@
/**@constructor*/
BaseStemmer = function() {
this.setCurrent = function(value) {
this.current = value;
this.cursor = 0;
this.limit = this.current.length;
this.limit_backward = 0;
this.bra = this.cursor;
this.ket = this.limit;
};
this.getCurrent = function() {
return this.current;
};
this.copy_from = function(other) {
this.current = other.current;
this.cursor = other.cursor;
this.limit = other.limit;
this.limit_backward = other.limit_backward;
this.bra = other.bra;
this.ket = other.ket;
};
this.in_grouping = function(s, min, max) {
if (this.cursor >= this.limit) return false;
var ch = this.current.charCodeAt(this.cursor);
if (ch > max || ch < min) return false;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) return false;
this.cursor++;
return true;
};
this.in_grouping_b = function(s, min, max) {
if (this.cursor <= this.limit_backward) return false;
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch > max || ch < min) return false;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) return false;
this.cursor--;
return true;
};
this.out_grouping = function(s, min, max) {
if (this.cursor >= this.limit) return false;
var ch = this.current.charCodeAt(this.cursor);
if (ch > max || ch < min) {
this.cursor++;
return true;
}
ch -= min;
if ((s[ch >>> 3] & (0X1 << (ch & 0x7))) == 0) {
this.cursor++;
return true;
}
return false;
};
this.out_grouping_b = function(s, min, max) {
if (this.cursor <= this.limit_backward) return false;
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch > max || ch < min) {
this.cursor--;
return true;
}
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) {
this.cursor--;
return true;
}
return false;
};
this.eq_s = function(s)
{
if (this.limit - this.cursor < s.length) return false;
if (this.current.slice(this.cursor, this.cursor + s.length) != s)
{
return false;
}
this.cursor += s.length;
return true;
};
this.eq_s_b = function(s)
{
if (this.cursor - this.limit_backward < s.length) return false;
if (this.current.slice(this.cursor - s.length, this.cursor) != s)
{
return false;
}
this.cursor -= s.length;
return true;
};
/** @return {number} */ this.find_among = function(v)
{
var i = 0;
var j = v.length;
var c = this.cursor;
var l = this.limit;
var common_i = 0;
var common_j = 0;
var first_key_inspected = false;
while (true)
{
var k = i + ((j - i) >>> 1);
var diff = 0;
var common = common_i < common_j ? common_i : common_j; // smaller
// w[0]: string, w[1]: substring_i, w[2]: result, w[3]: function (optional)
var w = v[k];
var i2;
for (i2 = common; i2 < w[0].length; i2++)
{
if (c + common == l)
{
diff = -1;
break;
}
diff = this.current.charCodeAt(c + common) - w[0].charCodeAt(i2);
if (diff != 0) break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0) break; // v->s has been inspected
if (j == i) break; // only one item in v
// - but now we need to go round once more to get
// v->s inspected. This looks messy, but is actually
// the optimal approach.
if (first_key_inspected) break;
first_key_inspected = true;
}
}
do {
var w = v[i];
if (common_i >= w[0].length)
{
this.cursor = c + w[0].length;
if (w.length < 4) return w[2];
var res = w[3](this);
this.cursor = c + w[0].length;
if (res) return w[2];
}
i = w[1];
} while (i >= 0);
return 0;
};
// find_among_b is for backwards processing. Same comments apply
this.find_among_b = function(v)
{
var i = 0;
var j = v.length
var c = this.cursor;
var lb = this.limit_backward;
var common_i = 0;
var common_j = 0;
var first_key_inspected = false;
while (true)
{
var k = i + ((j - i) >> 1);
var diff = 0;
var common = common_i < common_j ? common_i : common_j;
var w = v[k];
var i2;
for (i2 = w[0].length - 1 - common; i2 >= 0; i2--)
{
if (c - common == lb)
{
diff = -1;
break;
}
diff = this.current.charCodeAt(c - 1 - common) - w[0].charCodeAt(i2);
if (diff != 0) break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0) break;
if (j == i) break;
if (first_key_inspected) break;
first_key_inspected = true;
}
}
do {
var w = v[i];
if (common_i >= w[0].length)
{
this.cursor = c - w[0].length;
if (w.length < 4) return w[2];
var res = w[3](this);
this.cursor = c - w[0].length;
if (res) return w[2];
}
i = w[1];
} while (i >= 0);
return 0;
};
/* to replace chars between c_bra and c_ket in this.current by the
* chars in s.
*/
this.replace_s = function(c_bra, c_ket, s)
{
var adjustment = s.length - (c_ket - c_bra);
this.current = this.current.slice(0, c_bra) + s + this.current.slice(c_ket);
this.limit += adjustment;
if (this.cursor >= c_ket) this.cursor += adjustment;
else if (this.cursor > c_bra) this.cursor = c_bra;
return adjustment;
};
this.slice_check = function()
{
if (this.bra < 0 ||
this.bra > this.ket ||
this.ket > this.limit ||
this.limit > this.current.length)
{
return false;
}
return true;
};
this.slice_from = function(s)
{
var result = false;
if (this.slice_check())
{
this.replace_s(this.bra, this.ket, s);
result = true;
}
return result;
};
this.slice_del = function()
{
return this.slice_from("");
};
this.insert = function(c_bra, c_ket, s)
{
var adjustment = this.replace_s(c_bra, c_ket, s);
if (c_bra <= this.bra) this.bra += adjustment;
if (c_bra <= this.ket) this.ket += adjustment;
};
this.slice_to = function()
{
var result = '';
if (this.slice_check())
{
result = this.current.slice(this.bra, this.ket);
}
return result;
};
this.assign_to = function()
{
return this.current.slice(0, this.limit);
};
};

905
_static/basic.css Normal file
View file

@ -0,0 +1,905 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
dl.footnote > dt,
dl.citation > dt {
float: left;
margin-right: 0.5em;
}
dl.footnote > dd,
dl.citation > dd {
margin-bottom: 0em;
}
dl.footnote > dd:after,
dl.citation > dd:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dt:after {
content: ":";
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd > :first-child {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
margin: 1em 0;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: absolute;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View file

@ -0,0 +1 @@
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

4
_static/css/theme.css Normal file

File diff suppressed because one or more lines are too long

323
_static/doctools.js Normal file
View file

@ -0,0 +1,323 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box, textarea, dropdown or button
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
&& !event.shiftKey) {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
break;
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
break;
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View file

@ -0,0 +1,12 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '',
LANGUAGE: 'it',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false
};

BIN
_static/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

996
_static/italian-stemmer.js Normal file
View file

@ -0,0 +1,996 @@
// Generated by Snowball 2.1.0 - https://snowballstem.org/
/**@constructor*/
ItalianStemmer = function() {
var base = new BaseStemmer();
/** @const */ var a_0 = [
["", -1, 7],
["qu", 0, 6],
["\u00E1", 0, 1],
["\u00E9", 0, 2],
["\u00ED", 0, 3],
["\u00F3", 0, 4],
["\u00FA", 0, 5]
];
/** @const */ var a_1 = [
["", -1, 3],
["I", 0, 1],
["U", 0, 2]
];
/** @const */ var a_2 = [
["la", -1, -1],
["cela", 0, -1],
["gliela", 0, -1],
["mela", 0, -1],
["tela", 0, -1],
["vela", 0, -1],
["le", -1, -1],
["cele", 6, -1],
["gliele", 6, -1],
["mele", 6, -1],
["tele", 6, -1],
["vele", 6, -1],
["ne", -1, -1],
["cene", 12, -1],
["gliene", 12, -1],
["mene", 12, -1],
["sene", 12, -1],
["tene", 12, -1],
["vene", 12, -1],
["ci", -1, -1],
["li", -1, -1],
["celi", 20, -1],
["glieli", 20, -1],
["meli", 20, -1],
["teli", 20, -1],
["veli", 20, -1],
["gli", 20, -1],
["mi", -1, -1],
["si", -1, -1],
["ti", -1, -1],
["vi", -1, -1],
["lo", -1, -1],
["celo", 31, -1],
["glielo", 31, -1],
["melo", 31, -1],
["telo", 31, -1],
["velo", 31, -1]
];
/** @const */ var a_3 = [
["ando", -1, 1],
["endo", -1, 1],
["ar", -1, 2],
["er", -1, 2],
["ir", -1, 2]
];
/** @const */ var a_4 = [
["ic", -1, -1],
["abil", -1, -1],
["os", -1, -1],
["iv", -1, 1]
];
/** @const */ var a_5 = [
["ic", -1, 1],
["abil", -1, 1],
["iv", -1, 1]
];
/** @const */ var a_6 = [
["ica", -1, 1],
["logia", -1, 3],
["osa", -1, 1],
["ista", -1, 1],
["iva", -1, 9],
["anza", -1, 1],
["enza", -1, 5],
["ice", -1, 1],
["atrice", 7, 1],
["iche", -1, 1],
["logie", -1, 3],
["abile", -1, 1],
["ibile", -1, 1],
["usione", -1, 4],
["azione", -1, 2],
["uzione", -1, 4],
["atore", -1, 2],
["ose", -1, 1],
["ante", -1, 1],
["mente", -1, 1],
["amente", 19, 7],
["iste", -1, 1],
["ive", -1, 9],
["anze", -1, 1],
["enze", -1, 5],
["ici", -1, 1],
["atrici", 25, 1],
["ichi", -1, 1],
["abili", -1, 1],
["ibili", -1, 1],
["ismi", -1, 1],
["usioni", -1, 4],
["azioni", -1, 2],
["uzioni", -1, 4],
["atori", -1, 2],
["osi", -1, 1],
["anti", -1, 1],
["amenti", -1, 6],
["imenti", -1, 6],
["isti", -1, 1],
["ivi", -1, 9],
["ico", -1, 1],
["ismo", -1, 1],
["oso", -1, 1],
["amento", -1, 6],
["imento", -1, 6],
["ivo", -1, 9],
["it\u00E0", -1, 8],
["ist\u00E0", -1, 1],
["ist\u00E8", -1, 1],
["ist\u00EC", -1, 1]
];
/** @const */ var a_7 = [
["isca", -1, 1],
["enda", -1, 1],
["ata", -1, 1],
["ita", -1, 1],
["uta", -1, 1],
["ava", -1, 1],
["eva", -1, 1],
["iva", -1, 1],
["erebbe", -1, 1],
["irebbe", -1, 1],
["isce", -1, 1],
["ende", -1, 1],
["are", -1, 1],
["ere", -1, 1],
["ire", -1, 1],
["asse", -1, 1],
["ate", -1, 1],
["avate", 16, 1],
["evate", 16, 1],
["ivate", 16, 1],
["ete", -1, 1],
["erete", 20, 1],
["irete", 20, 1],
["ite", -1, 1],
["ereste", -1, 1],
["ireste", -1, 1],
["ute", -1, 1],
["erai", -1, 1],
["irai", -1, 1],
["isci", -1, 1],
["endi", -1, 1],
["erei", -1, 1],
["irei", -1, 1],
["assi", -1, 1],
["ati", -1, 1],
["iti", -1, 1],
["eresti", -1, 1],
["iresti", -1, 1],
["uti", -1, 1],
["avi", -1, 1],
["evi", -1, 1],
["ivi", -1, 1],
["isco", -1, 1],
["ando", -1, 1],
["endo", -1, 1],
["Yamo", -1, 1],
["iamo", -1, 1],
["avamo", -1, 1],
["evamo", -1, 1],
["ivamo", -1, 1],
["eremo", -1, 1],
["iremo", -1, 1],
["assimo", -1, 1],
["ammo", -1, 1],
["emmo", -1, 1],
["eremmo", 54, 1],
["iremmo", 54, 1],
["immo", -1, 1],
["ano", -1, 1],
["iscano", 58, 1],
["avano", 58, 1],
["evano", 58, 1],
["ivano", 58, 1],
["eranno", -1, 1],
["iranno", -1, 1],
["ono", -1, 1],
["iscono", 65, 1],
["arono", 65, 1],
["erono", 65, 1],
["irono", 65, 1],
["erebbero", -1, 1],
["irebbero", -1, 1],
["assero", -1, 1],
["essero", -1, 1],
["issero", -1, 1],
["ato", -1, 1],
["ito", -1, 1],
["uto", -1, 1],
["avo", -1, 1],
["evo", -1, 1],
["ivo", -1, 1],
["ar", -1, 1],
["ir", -1, 1],
["er\u00E0", -1, 1],
["ir\u00E0", -1, 1],
["er\u00F2", -1, 1],
["ir\u00F2", -1, 1]
];
/** @const */ var /** Array<int> */ g_v = [17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1];
/** @const */ var /** Array<int> */ g_AEIO = [17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2];
/** @const */ var /** Array<int> */ g_CG = [17];
var /** number */ I_p2 = 0;
var /** number */ I_p1 = 0;
var /** number */ I_pV = 0;
/** @return {boolean} */
function r_prelude() {
var /** number */ among_var;
var /** number */ v_1 = base.cursor;
while(true)
{
var /** number */ v_2 = base.cursor;
lab0: {
base.bra = base.cursor;
among_var = base.find_among(a_0);
if (among_var == 0)
{
break lab0;
}
base.ket = base.cursor;
switch (among_var) {
case 1:
if (!base.slice_from("\u00E0"))
{
return false;
}
break;
case 2:
if (!base.slice_from("\u00E8"))
{
return false;
}
break;
case 3:
if (!base.slice_from("\u00EC"))
{
return false;
}
break;
case 4:
if (!base.slice_from("\u00F2"))
{
return false;
}
break;
case 5:
if (!base.slice_from("\u00F9"))
{
return false;
}
break;
case 6:
if (!base.slice_from("qU"))
{
return false;
}
break;
case 7:
if (base.cursor >= base.limit)
{
break lab0;
}
base.cursor++;
break;
}
continue;
}
base.cursor = v_2;
break;
}
base.cursor = v_1;
while(true)
{
var /** number */ v_3 = base.cursor;
lab1: {
golab2: while(true)
{
var /** number */ v_4 = base.cursor;
lab3: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab3;
}
base.bra = base.cursor;
lab4: {
var /** number */ v_5 = base.cursor;
lab5: {
if (!(base.eq_s("u")))
{
break lab5;
}
base.ket = base.cursor;
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab5;
}
if (!base.slice_from("U"))
{
return false;
}
break lab4;
}
base.cursor = v_5;
if (!(base.eq_s("i")))
{
break lab3;
}
base.ket = base.cursor;
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab3;
}
if (!base.slice_from("I"))
{
return false;
}
}
base.cursor = v_4;
break golab2;
}
base.cursor = v_4;
if (base.cursor >= base.limit)
{
break lab1;
}
base.cursor++;
}
continue;
}
base.cursor = v_3;
break;
}
return true;
};
/** @return {boolean} */
function r_mark_regions() {
I_pV = base.limit;
I_p1 = base.limit;
I_p2 = base.limit;
var /** number */ v_1 = base.cursor;
lab0: {
lab1: {
var /** number */ v_2 = base.cursor;
lab2: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab2;
}
lab3: {
var /** number */ v_3 = base.cursor;
lab4: {
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab4;
}
golab5: while(true)
{
lab6: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab6;
}
break golab5;
}
if (base.cursor >= base.limit)
{
break lab4;
}
base.cursor++;
}
break lab3;
}
base.cursor = v_3;
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab2;
}
golab7: while(true)
{
lab8: {
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab8;
}
break golab7;
}
if (base.cursor >= base.limit)
{
break lab2;
}
base.cursor++;
}
}
break lab1;
}
base.cursor = v_2;
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab0;
}
lab9: {
var /** number */ v_6 = base.cursor;
lab10: {
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab10;
}
golab11: while(true)
{
lab12: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab12;
}
break golab11;
}
if (base.cursor >= base.limit)
{
break lab10;
}
base.cursor++;
}
break lab9;
}
base.cursor = v_6;
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab0;
}
if (base.cursor >= base.limit)
{
break lab0;
}
base.cursor++;
}
}
I_pV = base.cursor;
}
base.cursor = v_1;
var /** number */ v_8 = base.cursor;
lab13: {
golab14: while(true)
{
lab15: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab15;
}
break golab14;
}
if (base.cursor >= base.limit)
{
break lab13;
}
base.cursor++;
}
golab16: while(true)
{
lab17: {
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab17;
}
break golab16;
}
if (base.cursor >= base.limit)
{
break lab13;
}
base.cursor++;
}
I_p1 = base.cursor;
golab18: while(true)
{
lab19: {
if (!(base.in_grouping(g_v, 97, 249)))
{
break lab19;
}
break golab18;
}
if (base.cursor >= base.limit)
{
break lab13;
}
base.cursor++;
}
golab20: while(true)
{
lab21: {
if (!(base.out_grouping(g_v, 97, 249)))
{
break lab21;
}
break golab20;
}
if (base.cursor >= base.limit)
{
break lab13;
}
base.cursor++;
}
I_p2 = base.cursor;
}
base.cursor = v_8;
return true;
};
/** @return {boolean} */
function r_postlude() {
var /** number */ among_var;
while(true)
{
var /** number */ v_1 = base.cursor;
lab0: {
base.bra = base.cursor;
among_var = base.find_among(a_1);
if (among_var == 0)
{
break lab0;
}
base.ket = base.cursor;
switch (among_var) {
case 1:
if (!base.slice_from("i"))
{
return false;
}
break;
case 2:
if (!base.slice_from("u"))
{
return false;
}
break;
case 3:
if (base.cursor >= base.limit)
{
break lab0;
}
base.cursor++;
break;
}
continue;
}
base.cursor = v_1;
break;
}
return true;
};
/** @return {boolean} */
function r_RV() {
if (!(I_pV <= base.cursor))
{
return false;
}
return true;
};
/** @return {boolean} */
function r_R1() {
if (!(I_p1 <= base.cursor))
{
return false;
}
return true;
};
/** @return {boolean} */
function r_R2() {
if (!(I_p2 <= base.cursor))
{
return false;
}
return true;
};
/** @return {boolean} */
function r_attached_pronoun() {
var /** number */ among_var;
base.ket = base.cursor;
if (base.find_among_b(a_2) == 0)
{
return false;
}
base.bra = base.cursor;
among_var = base.find_among_b(a_3);
if (among_var == 0)
{
return false;
}
if (!r_RV())
{
return false;
}
switch (among_var) {
case 1:
if (!base.slice_del())
{
return false;
}
break;
case 2:
if (!base.slice_from("e"))
{
return false;
}
break;
}
return true;
};
/** @return {boolean} */
function r_standard_suffix() {
var /** number */ among_var;
base.ket = base.cursor;
among_var = base.find_among_b(a_6);
if (among_var == 0)
{
return false;
}
base.bra = base.cursor;
switch (among_var) {
case 1:
if (!r_R2())
{
return false;
}
if (!base.slice_del())
{
return false;
}
break;
case 2:
if (!r_R2())
{
return false;
}
if (!base.slice_del())
{
return false;
}
var /** number */ v_1 = base.limit - base.cursor;
lab0: {
base.ket = base.cursor;
if (!(base.eq_s_b("ic")))
{
base.cursor = base.limit - v_1;
break lab0;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_1;
break lab0;
}
if (!base.slice_del())
{
return false;
}
}
break;
case 3:
if (!r_R2())
{
return false;
}
if (!base.slice_from("log"))
{
return false;
}
break;
case 4:
if (!r_R2())
{
return false;
}
if (!base.slice_from("u"))
{
return false;
}
break;
case 5:
if (!r_R2())
{
return false;
}
if (!base.slice_from("ente"))
{
return false;
}
break;
case 6:
if (!r_RV())
{
return false;
}
if (!base.slice_del())
{
return false;
}
break;
case 7:
if (!r_R1())
{
return false;
}
if (!base.slice_del())
{
return false;
}
var /** number */ v_2 = base.limit - base.cursor;
lab1: {
base.ket = base.cursor;
among_var = base.find_among_b(a_4);
if (among_var == 0)
{
base.cursor = base.limit - v_2;
break lab1;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_2;
break lab1;
}
if (!base.slice_del())
{
return false;
}
switch (among_var) {
case 1:
base.ket = base.cursor;
if (!(base.eq_s_b("at")))
{
base.cursor = base.limit - v_2;
break lab1;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_2;
break lab1;
}
if (!base.slice_del())
{
return false;
}
break;
}
}
break;
case 8:
if (!r_R2())
{
return false;
}
if (!base.slice_del())
{
return false;
}
var /** number */ v_3 = base.limit - base.cursor;
lab2: {
base.ket = base.cursor;
if (base.find_among_b(a_5) == 0)
{
base.cursor = base.limit - v_3;
break lab2;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_3;
break lab2;
}
if (!base.slice_del())
{
return false;
}
}
break;
case 9:
if (!r_R2())
{
return false;
}
if (!base.slice_del())
{
return false;
}
var /** number */ v_4 = base.limit - base.cursor;
lab3: {
base.ket = base.cursor;
if (!(base.eq_s_b("at")))
{
base.cursor = base.limit - v_4;
break lab3;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_4;
break lab3;
}
if (!base.slice_del())
{
return false;
}
base.ket = base.cursor;
if (!(base.eq_s_b("ic")))
{
base.cursor = base.limit - v_4;
break lab3;
}
base.bra = base.cursor;
if (!r_R2())
{
base.cursor = base.limit - v_4;
break lab3;
}
if (!base.slice_del())
{
return false;
}
}
break;
}
return true;
};
/** @return {boolean} */
function r_verb_suffix() {
if (base.cursor < I_pV)
{
return false;
}
var /** number */ v_2 = base.limit_backward;
base.limit_backward = I_pV;
base.ket = base.cursor;
if (base.find_among_b(a_7) == 0)
{
base.limit_backward = v_2;
return false;
}
base.bra = base.cursor;
if (!base.slice_del())
{
return false;
}
base.limit_backward = v_2;
return true;
};
/** @return {boolean} */
function r_vowel_suffix() {
var /** number */ v_1 = base.limit - base.cursor;
lab0: {
base.ket = base.cursor;
if (!(base.in_grouping_b(g_AEIO, 97, 242)))
{
base.cursor = base.limit - v_1;
break lab0;
}
base.bra = base.cursor;
if (!r_RV())
{
base.cursor = base.limit - v_1;
break lab0;
}
if (!base.slice_del())
{
return false;
}
base.ket = base.cursor;
if (!(base.eq_s_b("i")))
{
base.cursor = base.limit - v_1;
break lab0;
}
base.bra = base.cursor;
if (!r_RV())
{
base.cursor = base.limit - v_1;
break lab0;
}
if (!base.slice_del())
{
return false;
}
}
var /** number */ v_2 = base.limit - base.cursor;
lab1: {
base.ket = base.cursor;
if (!(base.eq_s_b("h")))
{
base.cursor = base.limit - v_2;
break lab1;
}
base.bra = base.cursor;
if (!(base.in_grouping_b(g_CG, 99, 103)))
{
base.cursor = base.limit - v_2;
break lab1;
}
if (!r_RV())
{
base.cursor = base.limit - v_2;
break lab1;
}
if (!base.slice_del())
{
return false;
}
}
return true;
};
this.stem = /** @return {boolean} */ function() {
var /** number */ v_1 = base.cursor;
r_prelude();
base.cursor = v_1;
r_mark_regions();
base.limit_backward = base.cursor; base.cursor = base.limit;
var /** number */ v_3 = base.limit - base.cursor;
r_attached_pronoun();
base.cursor = base.limit - v_3;
var /** number */ v_4 = base.limit - base.cursor;
lab0: {
lab1: {
var /** number */ v_5 = base.limit - base.cursor;
lab2: {
if (!r_standard_suffix())
{
break lab2;
}
break lab1;
}
base.cursor = base.limit - v_5;
if (!r_verb_suffix())
{
break lab0;
}
}
}
base.cursor = base.limit - v_4;
var /** number */ v_6 = base.limit - base.cursor;
r_vowel_suffix();
base.cursor = base.limit - v_6;
base.cursor = base.limit_backward;
var /** number */ v_7 = base.cursor;
r_postlude();
base.cursor = v_7;
return true;
};
/**@return{string}*/
this['stemWord'] = function(/**string*/word) {
base.setCurrent(word);
this.stem();
return base.getCurrent();
};
};

10872
_static/jquery-3.5.1.js vendored Normal file

File diff suppressed because it is too large Load diff

2
_static/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

1
_static/js/badge_only.js Normal file
View file

@ -0,0 +1 @@
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});

4
_static/js/html5shiv-printshiv.min.js vendored Normal file
View file

@ -0,0 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);

4
_static/js/html5shiv.min.js vendored Normal file
View file

@ -0,0 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);

1
_static/js/theme.js Normal file

File diff suppressed because one or more lines are too long

117
_static/language_data.js Normal file

File diff suppressed because one or more lines are too long

BIN
_static/minus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
_static/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

74
_static/pygments.css Normal file
View file

@ -0,0 +1,74 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */

529
_static/searchtools.js Normal file
View file

@ -0,0 +1,529 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
htmlToText : function(htmlString) {
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var htmlElement = $(htmlString, virtualDocument);
htmlElement.find('.headerlink').remove();
docContent = htmlElement.find('[role=main]')[0];
if(docContent === undefined) {
console.warn("Content block not found. Sphinx search tries to obtain it " +
"via '[role=main]'. Could you check your theme or template.");
return "";
}
return docContent.textContent || docContent.innerText;
},
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li></li>');
var requestUrl = "";
var linkUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
}
listItem.append($('<a/>').attr('href',
linkUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
var summary = Search.makeSearchSummary(data, searchterms, hlterms);
if (summary) {
listItem.append(summary);
}
}
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}});
} else {
// no source available, just display title
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) {
var match = objects[prefix][iMatch];
var name = match[4];
var fullname = (prefix ? prefix + '.' : '') + name;
var fullnameLower = fullname.toLowerCase()
if (fullnameLower.indexOf(object) > -1) {
var score = 0;
var parts = fullnameLower.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
return results;
},
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
*/
escapeRegExp : function(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// add support for partial matches
if (word.length > 2) {
var word_regex = this.escapeRegExp(word);
for (var w in terms) {
if (w.match(word_regex) && !terms[word]) {
_o.push({files: terms[w], score: Scorer.partialTerm})
}
}
for (var w in titleterms) {
if (w.match(word_regex) && !titleterms[word]) {
_o.push({files: titleterms[w], score: Scorer.partialTitle})
}
}
}
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {};
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap && fileMap[file].indexOf(word) === -1)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
var filteredTermCount = // as search terms with length < 3 are discarded: ignore
searchterms.filter(function(term){return term.length > 2}).length
if (
fileMap[file].length != searchterms.length &&
fileMap[file].length != filteredTermCount
) continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(htmlText, keywords, hlwords) {
var text = Search.htmlToText(htmlText);
if (text == "") {
return null;
}
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<p class="context"></p>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

63
_static/translations.js Normal file
View file

@ -0,0 +1,63 @@
Documentation.addTranslations({
"locale": "it",
"messages": {
"%(filename)s &#8212; %(docstitle)s": "%(filename)s &#8212; %(docstitle)s",
"&#169; <a href=\"%(path)s\">Copyright</a> %(copyright)s.": "&#169; <a href=\"%(path)s\">Copyright</a> %(copyright)s.",
"&#169; Copyright %(copyright)s.": "&#169; Copyright %(copyright)s.",
", in ": ", in ",
"About these documents": "A proposito di questi documenti",
"Automatically generated list of changes in version %(version)s": "Lista delle modifiche generata automaticamente nella versione %(version)s",
"C API changes": "Modifiche nelle API C",
"Changes in Version %(version)s &#8212; %(docstitle)s": "Cambiamenti nella Versione %(version)s &#8212; %(docstitle)s",
"Collapse sidebar": "Comprimi la barra laterale",
"Complete Table of Contents": "Tabella dei contenuti completa",
"Contents": "Contenuti",
"Copyright": "Copyright",
"Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "Espandi la barra laterale",
"Full index on one page": "Indice completo in una pagina",
"General Index": "Indice generale",
"Global Module Index": "Indice dei moduli",
"Go": "Vai",
"Hide Search Matches": "Nascondi i risultati della ricerca",
"Index": "Indice",
"Index &ndash; %(key)s": "Indice &ndash; %(key)s",
"Index pages by letter": "Indice delle pagine per lettera",
"Indices and tables:": "Indici e tabelle:",
"Last updated on %(last_updated)s.": "Ultimo aggiornamento %(last_updated)s.",
"Library changes": "Modifiche nella libreria",
"Navigation": "Navigazione",
"Next topic": "Argomento successivo",
"Other changes": "Altre modifiche",
"Overview": "Sintesi",
"Permalink to this definition": "Link a questa definizione",
"Permalink to this headline": "Link a questa intestazione",
"Please activate JavaScript to enable the search\n functionality.": "Attiva JavaScript per abilitare la funzione\u23ce\ndi ricerca.",
"Preparing search...": "Preparo la ricerca...",
"Previous topic": "Argomento precedente",
"Quick search": "Ricerca veloce",
"Search": "Cerca",
"Search Page": "Cerca",
"Search Results": "Risultati della ricerca",
"Search finished, found %s page(s) matching the search query.": "Ricerca completata, trovata/e %s pagina/e corrispondenti.",
"Search within %(docstitle)s": "Cerca in %(docstitle)s",
"Searching": "Cerca",
"Searching for multiple words only shows matches that contain\n all words.": "",
"Show Source": "Mostra sorgente",
"Table of Contents": "",
"This Page": "Questa pagina",
"Welcome! This is": "Benvenuto! Questa \u00e8",
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "La tua ricerca non corrisponde a nessun documento. Verifica che tutte le parole siano scritte correttamente e di aver scelto un numero sufficiente di categorie.",
"all functions, classes, terms": "tutte le funzioni, classi e moduli",
"can be huge": "pu\u00f2 essere enorme",
"last updated": "ultimo aggiornamento",
"lists all sections and subsections": "elenca l'insieme delle sezioni e sottosezioni",
"next chapter": "capitolo successivo",
"previous chapter": "capitolo precedente",
"quick access to all modules": "accesso veloce ai moduli",
"search": "cerca",
"search this documentation": "cerca in questa documentazione",
"the documentation for": "la documentazione per"
},
"plural_expr": "(n != 1)"
});

2042
_static/underscore-1.13.1.js Normal file

File diff suppressed because it is too large Load diff

6
_static/underscore.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,155 @@
<!DOCTYPE html>
<html class="writer-html5" lang="it" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>8. Bibliografia &mdash; Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/translations.js"></script>
<script src="../../_static/js/theme.js"></script>
<link rel="index" title="Indice analitico" href="../../genindex.html" />
<link rel="search" title="Cerca" href="../../search.html" />
<link rel="next" title="1. Installazione di Sophon" href="../installazione/index.html" />
<link rel="prev" title="7. Il futuro di Sophon" href="../conclusione/index.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #051836" >
<a href="../../index.html" class="icon icon-home"> Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Cerca documenti" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Menu di navigazione">
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../sinossi/index.html">1. Sinossi</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduzione/index.html">2. Introduzione alla tesi</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ricercacollaborativa/index.html">3. Ricerca collaborativa</a></li>
<li class="toctree-l1"><a class="reference internal" href="../progetto/index.html">4. Progettazione di Sophon</a></li>
<li class="toctree-l1"><a class="reference internal" href="../realizzazione/index.html">5. Realizzazione di Sophon</a></li>
<li class="toctree-l1"><a class="reference internal" href="../risultato/index.html">6. Risultati ottenuti</a></li>
<li class="toctree-l1"><a class="reference internal" href="../conclusione/index.html">7. Il futuro di Sophon</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">8. Bibliografia</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Appendice</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../installazione/index.html">1. Installazione di Sophon</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Menu navigazione dispositivi mobili" style="background: #051836" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Naviga tra le pagine">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html" class="icon icon-home"></a> &raquo;</li>
<li><span class="section-number">8. </span>Bibliografia</li>
<li class="wy-breadcrumbs-aside">
<!-- User defined GitHub URL -->
<a href="https://github.com/Steffo99/sophon/blob/main/thesis/source/8_appendice/index.rst" class="fa fa-github"> Modifica su GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="bibliografia">
<h1><span class="section-number">8. </span>Bibliografia<a class="headerlink" href="#bibliografia" title="Link a questa intestazione"></a></h1>
</section>
<dl class="citation">
<dt class="label" id="matplotlib-histograms"><span class="brackets">matplotlib:histograms</span></dt>
<dd><p>Matplotlib. <strong>Histograms</strong>. <a class="reference external" href="https://web.archive.org/web/20210815080710/https://matplotlib.org/stable/gallery/statistics/hist.html">https://web.archive.org/web/20210815080710/https://matplotlib.org/stable/gallery/statistics/hist.html</a></p>
</dd>
<dt class="label" id="jupyter-ifaq"><span class="brackets">jupyter:ifaq</span></dt>
<dd><p>Project Jupyter. <strong>Institutional FAQ</strong>. <a class="reference external" href="https://web.archive.org/web/20200317115530/https://jupyterhub.readthedocs.io/en/stable/getting-started/institutional-faq.html">https://web.archive.org/web/20200317115530/https://jupyterhub.readthedocs.io/en/stable/getting-started/institutional-faq.html</a></p>
</dd>
<dt class="label" id="jupyter-hub"><span class="brackets">jupyter:hub</span></dt>
<dd><p>Project Jupyter. <strong>JupyterHub</strong>. <a class="reference external" href="https://web.archive.org/web/20211115163603/https://jupyterhub.readthedocs.io/en/stable/">https://web.archive.org/web/20211115163603/https://jupyterhub.readthedocs.io/en/stable/</a></p>
</dd>
<dt class="label" id="jupyter-kernels"><span class="brackets">jupyter:kernels</span></dt>
<dd><p>Project Jupyter. <strong>Jupyter kernels</strong>. <a class="reference external" href="https://web.archive.org/web/20211118154819/https://github.com/jupyter/jupyter/wiki/Jupyter-kernels">https://web.archive.org/web/20211118154819/https://github.com/jupyter/jupyter/wiki/Jupyter-kernels</a></p>
</dd>
<dt class="label" id="jupyter-collaboration"><span class="brackets">jupyter:collaboration</span></dt>
<dd><p>Project Jupyter. <strong>Real Time Collaboration</strong>. <a class="reference external" href="https://web.archive.org/web/20211118174617/https://jupyterlab.readthedocs.io/en/stable/user/rtc.html">https://web.archive.org/web/20211118174617/https://jupyterlab.readthedocs.io/en/stable/user/rtc.html</a></p>
</dd>
<dt class="label" id="wiki-eln"><span class="brackets">wiki:eln</span></dt>
<dd><p>English Wikipedia. <strong>Electronic lab notebook</strong>. <a class="reference external" href="https://en.wikipedia.org/w/index.php?title=Electronic_lab_notebook&amp;oldid=993314047">https://en.wikipedia.org/w/index.php?title=Electronic_lab_notebook&amp;oldid=993314047</a></p>
</dd>
<dt class="label" id="overleaf-learn30mins"><span class="brackets">overleaf:learn30mins</span></dt>
<dd><p>Overleaf. <strong>Learn LaTeX in 30 minutes</strong>. <a class="reference external" href="https://web.archive.org/web/20211116220924/https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes">https://web.archive.org/web/20211116220924/https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes</a></p>
</dd>
<dt class="label" id="so-survey2021"><span class="brackets">so:survey2021</span></dt>
<dd><p>Stack Overflow. <strong>2021 Developer Survey</strong>. <a class="reference external" href="https://web.archive.org/web/20211126152610/https://insights.stackoverflow.com/survey/2021">https://web.archive.org/web/20211126152610/https://insights.stackoverflow.com/survey/2021</a></p>
</dd>
<dt class="label" id="docker-overview"><span class="brackets">docker:overview</span></dt>
<dd><p>Docker. <strong>Overview</strong>. <a class="reference external" href="https://web.archive.org/web/20211121165850/https://docs.docker.com/get-started/overview/">https://web.archive.org/web/20211121165850/https://docs.docker.com/get-started/overview/</a></p>
</dd>
<dt class="label" id="docker-networking"><span class="brackets">docker:networking</span></dt>
<dd><p>Docker. <strong>Networking overview</strong>. <a class="reference external" href="https://web.archive.org/web/20211111155419/https://docs.docker.com/network/">https://web.archive.org/web/20211111155419/https://docs.docker.com/network/</a></p>
</dd>
<dt class="label" id="docker-volumes"><span class="brackets">docker:volumes</span></dt>
<dd><p>Docker. <strong>Use volumes</strong>. <a class="reference external" href="https://web.archive.org/web/20211121172749/https://docs.docker.com/storage/volumes/">https://web.archive.org/web/20211121172749/https://docs.docker.com/storage/volumes/</a></p>
</dd>
<dt class="label" id="github-features"><span class="brackets">github:features</span></dt>
<dd><p>GitHub. <strong>Features</strong>. <a class="reference external" href="https://web.archive.org/web/20211124034005/https://github.com/features">https://web.archive.org/web/20211124034005/https://github.com/features</a></p>
</dd>
</dl>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Piè di pagina">
<a href="../conclusione/index.html" class="btn btn-neutral float-left" title="7. Il futuro di Sophon" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Precedente</a>
<a href="../installazione/index.html" class="btn btn-neutral float-right" title="1. Installazione di Sophon" accesskey="n" rel="next">Prossimo <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Stefano Pigozzi.</p>
</div>
Realizzato con <a href="https://www.sphinx-doc.org/">Sphinx</a> e il tema
<a href="https://github.com/readthedocs/sphinx_rtd_theme">tema</a>
fornito da <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

176
docs/conclusione/index.html Normal file
View file

@ -0,0 +1,176 @@
<!DOCTYPE html>
<html class="writer-html5" lang="it" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>7. Il futuro di Sophon &mdash; Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/translations.js"></script>
<script src="../../_static/js/theme.js"></script>
<link rel="index" title="Indice analitico" href="../../genindex.html" />
<link rel="search" title="Cerca" href="../../search.html" />
<link rel="next" title="8. Bibliografia" href="../bibliografia/index.html" />
<link rel="prev" title="6. Risultati ottenuti" href="../risultato/index.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #051836" >
<a href="../../index.html" class="icon icon-home"> Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Cerca documenti" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Menu di navigazione">
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../sinossi/index.html">1. Sinossi</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduzione/index.html">2. Introduzione alla tesi</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ricercacollaborativa/index.html">3. Ricerca collaborativa</a></li>
<li class="toctree-l1"><a class="reference internal" href="../progetto/index.html">4. Progettazione di Sophon</a></li>
<li class="toctree-l1"><a class="reference internal" href="../realizzazione/index.html">5. Realizzazione di Sophon</a></li>
<li class="toctree-l1"><a class="reference internal" href="../risultato/index.html">6. Risultati ottenuti</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">7. Il futuro di Sophon</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#repository-github-di-sophon">7.1. Repository GitHub di Sophon</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#nuova-entita-il-documento">Nuova entità: il documento</a></li>
<li class="toctree-l3"><a class="reference internal" href="#sistema-per-organizzazione-delle-entita">Sistema per organizzazione delle entità</a></li>
<li class="toctree-l3"><a class="reference internal" href="#registro-delle-attivita">Registro delle attività</a></li>
<li class="toctree-l3"><a class="reference internal" href="#federazione-tra-istanze">Federazione tra istanze</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../bibliografia/index.html">8. Bibliografia</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Appendice</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../installazione/index.html">1. Installazione di Sophon</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Menu navigazione dispositivi mobili" style="background: #051836" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Progettazione e sviluppo di Sophon, applicativo cloud a supporto della ricerca</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Naviga tra le pagine">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html" class="icon icon-home"></a> &raquo;</li>
<li><span class="section-number">7. </span>Il futuro di Sophon</li>
<li class="wy-breadcrumbs-aside">
<!-- User defined GitHub URL -->
<a href="https://github.com/Steffo99/sophon/blob/main/thesis/source/8_conclusione/index.rst" class="fa fa-github"> Modifica su GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="il-futuro-di-sophon">
<span id="index-0"></span><h1><span class="section-number">7. </span>Il futuro di Sophon<a class="headerlink" href="#il-futuro-di-sophon" title="Link a questa intestazione"></a></h1>
<p>Lo sviluppo di Sophon lascia aperte innumerevoli strade per la sua espansione con funzionalità aggiuntive.</p>
<p>Si conclude la tesi analizzandone alcune.</p>
<section id="repository-github-di-sophon">
<h2><span class="section-number">7.1. </span>Repository GitHub di Sophon<a class="headerlink" href="#repository-github-di-sophon" title="Link a questa intestazione"></a></h2>
<p>È stato creato un <a class="reference external" href="https://github.com/Steffo99/sophon">repository per il progetto su GitHub</a>.</p>
<p>Oltre al codice sorgente, esso include <a class="reference external" href="https://github.com/Steffo99/sophon/issues">un issue tracker</a>, all'interno del quale viene tenuto traccia di tutte le proposte di funzionalità aggiuntive.</p>
<p>Si elencano alcune delle funzionalità proposte.</p>
<section id="nuova-entita-il-documento">
<span id="index-1"></span><h3>Nuova entità: il documento<a class="headerlink" href="#nuova-entita-il-documento" title="Link a questa intestazione"></a></h3>
<p>Si propone di sviluppare una nuova entità, il <em>documento</em>, che permetterebbe agli utenti di Sophon di creare testi in Markdown senza uscire dall'interfaccia web, e di renderli disponibili basandosi sul sistema di permessi di Sophon.</p>
<figure class="align-default" id="id1">
<img alt="../../_images/diagram_documents.png" src="../../_images/diagram_documents.png" />
<figcaption>
<p><span class="caption-number">Figura 7.1.1 </span><span class="caption-text">Schema del database se venisse aggiunta l'entità &quot;Documento&quot;.</span><a class="headerlink" href="#id1" title="Link a questa immagine"></a></p>
</figcaption>
</figure>
</section>
<section id="sistema-per-organizzazione-delle-entita">
<span id="index-2"></span><h3>Sistema per organizzazione delle entità<a class="headerlink" href="#sistema-per-organizzazione-delle-entita" title="Link a questa intestazione"></a></h3>
<p>Si propone di realizzare dei sistemi che permettano di catalogare e raggruppare le entità di ogni tipo attraverso parole chiave (<em>tag</em>) selezionabili dal creatore della relativa entità.</p>
<p>Un esempio di tag potrebbe essere <code class="docutils literal notranslate"><span class="pre">[Tesi]</span></code>, utilizzabile per i progetti relativi alle tesi degli studenti di un corso.</p>
<figure class="align-default" id="id2">
<a class="reference internal image-reference" href="../../_images/diagram_tags.png"><img alt="../../_images/diagram_tags.png" src="../../_images/diagram_tags.png" style="width: 392.0px; height: 440.0px;" /></a>
<figcaption>
<p><span class="caption-number">Figura 7.1.2 </span><span class="caption-text">Un esempio di come potrebbero funzionare i tag applicati ai progetti.</span><a class="headerlink" href="#id2" title="Link a questa immagine"></a></p>
</figcaption>
</figure>
</section>
<section id="registro-delle-attivita">
<span id="index-3"></span><h3>Registro delle attività<a class="headerlink" href="#registro-delle-attivita" title="Link a questa intestazione"></a></h3>
<p>Si propone di creare un registro, detto <em>delle attività</em> o in inglese <em>activity log</em>, all'interno del quale siano registrate tutte le azioni effettuate sulle entità del progetto.</p>
<p>Ciò favorirebbe la accountability tra gli utenti di Sophon, in quanto diverrebbe possibile identificare il responsabile di certe azioni distruttive, come l'eliminazione di un intero gruppo.</p>
<figure class="align-default" id="id3">
<a class="reference internal image-reference" href="../../_images/diagram_activity_log.png"><img alt="../../_images/diagram_activity_log.png" src="../../_images/diagram_activity_log.png" style="width: 470.74999999999994px; height: 420.0px;" /></a>
<figcaption>
<p><span class="caption-number">Figura 7.1.3 </span><span class="caption-text">Un esempio di come potrebbe funzionare il registro delle attività.</span><a class="headerlink" href="#id3" title="Link a questa immagine"></a></p>
</figcaption>
</figure>
</section>
<section id="federazione-tra-istanze">
<span id="index-4"></span><h3>Federazione tra istanze<a class="headerlink" href="#federazione-tra-istanze" title="Link a questa intestazione"></a></h3>
<p>L'ultima proposta, molto ambiziosa, sarebbe quella di permettere la <em>federazione</em> tra le varie istanze Sophon, consentendo la condivisione di risorse attraverso più istituzioni senza dover creare utenti &quot;locali&quot; per ciascun collaboratore.</p>
<figure class="align-default" id="id4">
<a class="reference internal image-reference" href="../../_images/diagram_federation.png"><img alt="../../_images/diagram_federation.png" src="../../_images/diagram_federation.png" style="width: 708.0px; height: 708.0px;" /></a>
<figcaption>
<p><span class="caption-number">Figura 7.1.4 </span><span class="caption-text">Un diagramma di esempio di possibile federazione di Sophon.</span><a class="headerlink" href="#id4" title="Link a questa immagine"></a></p>
</figcaption>
</figure>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Piè di pagina">
<a href="../risultato/index.html" class="btn btn-neutral float-left" title="6. Risultati ottenuti" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Precedente</a>
<a href="../bibliografia/index.html" class="btn btn-neutral float-right" title="8. Bibliografia" accesskey="n" rel="next">Prossimo <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Stefano Pigozzi.</p>
</div>
Realizzato con <a href="https://www.sphinx-doc.org/">Sphinx</a> e il tema
<a href="https://github.com/readthedocs/sphinx_rtd_theme">tema</a>
fornito da <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more