diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..f5fc6c77 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,21 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3" + +sphinx: + configuration: source/conf.py + +python: + install: + - requirements: requirements.txt + +# Build PDF & ePub +formats: + - epub + - pdf + +submodules: + include: all diff --git a/Makefile.in b/Makefile.in index 62b6c557..36ab1cbe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -31,6 +31,9 @@ user = @user@ DNSTAP_SRC=@DNSTAP_SRC@ DNSTAP_OBJ=@DNSTAP_OBJ@ +SPHINXOPTS = -N -q +SPHINXBUILD = sphinx-build + # override $U variable which is used by autotools for deansification (for # K&R C compilers), but causes problems if $U is defined in the env). U= @@ -54,6 +57,10 @@ YACC = @YACC@ LEX = @LEX@ PROTOC_C = @PROTOC_C@ +DATE != date +'%b %e, %y' +PROJECT = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) EDIT = $(SED) \ @@ -73,7 +80,10 @@ EDIT = $(SED) \ -e 's,@shell\@,$(SHELL),g' \ -e 's,@ratelimit_default\@,@ratelimit_default@,g' \ -e 's,@dnstap_socket_path\@,@opt_dnstap_socket_path@,g' \ - -e 's,@user\@,$(user),g' + -e 's,@user\@,$(user),g' \ + -e 's/@project\@/$(PROJECT)/g' \ + -e 's/@version\@/$(VERSION)/g' \ + -e 's/@date\@/$(DATE)/g' TARGETS=nsd nsd-checkconf nsd-checkzone nsd-control nsd.conf.sample nsd-control-setup.sh contrib/nsd.openrc contrib/nsd-tmpfiles.conf MANUALS=nsd.8 nsd-checkconf.8 nsd-checkzone.8 nsd-control.8 nsd.conf.5 @@ -87,7 +97,31 @@ NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc NSD_CONTROL_OBJ=$(COMMON_OBJ) nsd-control.o CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o verify.o zonec.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_util.o cutest_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.o NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o verify.o server.o zonec.o nsd-mem.o -all: $(TARGETS) $(MANUALS) + +.PHONY: all html man + +all: $(TARGETS) $(MANUALS) + +doc/manual/conf.py: doc/manual/conf.py.in + $(EDIT) $(srcdir)/doc/manual/conf.py.in > doc/manual/conf.py + +doc/manual/manpages/nsd.conf.5.html: nsd.conf.5 + mandoc -T html -O fragment nsd.conf.5 > doc/manual/manpages/nsd.conf.5.html + +doc/manual/manpages/nsd.8.html: nsd.8 + mandoc -T html -O fragment nsd.8 > doc/manual/manpages/nsd.8.html + +doc/manual/manpages/nsd-checkconf.8.html: nsd-checkconf.8 + mandoc -T html -O fragment nsd-checkconf.8 > doc/manual/manpages/nsd-checkconf.8.html + +doc/manual/manpages/nsd-checkzone.8.html: nsd-checkzone.8 + mandoc -T html -O fragment nsd-checkzone.8 > doc/manual/manpages/nsd-checkzone.8.html + +doc/manual/manpages/nsd-control.8.html: nsd-control.8 + mandoc -T html -O fragment nsd-control.8 > doc/manual/manpages/nsd-control.8.html + +html: doc/manual/conf.py doc/manual/manpages/nsd.conf.5.html doc/manual/manpages/nsd.8.html doc/manual/manpages/nsd-checkconf.8.html doc/manual/manpages/nsd-checkzone.8.html doc/manual/manpages/nsd-control.8.html + $(SPHINXBUILD) -M html $(srcdir)/doc/manual doc/manual $(SPHINXOPTS) $(ALL_OBJ): $(COMPILE) -c $< @@ -101,23 +135,23 @@ nsd.conf.sample: $(srcdir)/nsd.conf.sample.in config.h rm -f nsd.conf.sample $(EDIT) $(srcdir)/nsd.conf.sample.in | $(AWK) '/RRLconfig'@ratelimit@'/ { while($$0 !~ /.*RRLend.*/) { getline; } getline; } {print} ' > nsd.conf.sample -nsd.conf.5: $(srcdir)/nsd.conf.5.in config.h +nsd.conf.5: $(srcdir)/nsd.conf.5.in config.h rm -f nsd.conf.5 $(EDIT) $(srcdir)/nsd.conf.5.in | $(AWK) '/rrlstart'@ratelimit@'/ { while($$0 !~ /.*rrlend.*/) { getline; } getline; } {print} ' > nsd.conf.5 -nsd.8: $(srcdir)/nsd.8.in config.h +nsd.8: $(srcdir)/nsd.8.in config.h rm -f nsd.8 $(EDIT) $(srcdir)/nsd.8.in > nsd.8 -nsd-checkconf.8: $(srcdir)/nsd-checkconf.8.in config.h +nsd-checkconf.8: $(srcdir)/nsd-checkconf.8.in config.h rm -f nsd-checkconf.8 $(EDIT) $(srcdir)/nsd-checkconf.8.in > nsd-checkconf.8 -nsd-checkzone.8: $(srcdir)/nsd-checkzone.8.in config.h +nsd-checkzone.8: $(srcdir)/nsd-checkzone.8.in config.h rm -f nsd-checkzone.8 $(EDIT) $(srcdir)/nsd-checkzone.8.in > nsd-checkzone.8 -nsd-control.8: $(srcdir)/nsd-control.8.in config.h +nsd-control.8: $(srcdir)/nsd-control.8.in config.h rm -f nsd-control.8 $(EDIT) $(srcdir)/nsd-control.8.in > nsd-control.8 @@ -202,6 +236,8 @@ audit: nsd nsd-checkconf nsd-checkzone nsd-control nsd-mem checksec .clean: rm -f *.o $(TARGETS) $(MANUALS) cutest popen3_echo xfr-inspect nsd-mem + rm -f doc/manual/conf.py doc/manual/manpages/nsd.conf.5.html doc/manual/manpages/nsd.8.html doc/manual/manpages/nsd-checkconf.8.html doc/manual/manpages/nsd-checkzone.8.html doc/manual/manpages/nsd-control.8.html + rm -rf doc/manual/doctrees doc/manual/html .distclean: .clean rm -f Makefile config.h config.log config.status dnstap/dnstap_config.h diff --git a/doc/manual/catalog-zones.rst b/doc/manual/catalog-zones.rst new file mode 100644 index 00000000..b8813c08 --- /dev/null +++ b/doc/manual/catalog-zones.rst @@ -0,0 +1,213 @@ +Catalog zones +============= + +Since version 4.9.0, NSD has support for Catalog zones version "2" as specified +in `RFC 9432 `_. NSD can be a producer +of catalog zones as well as a catalog zone consumer, but it is limited to +process only a single consumer zone. + +Setting up NSD as a catalog consumer +------------------------------------ + +NSD will process a zone as a catalog consumer zone if the zone has the +``catalog: consumer`` option set. An example catalog consumer configuration +could look like this: + +.. code:: bash + + pattern: + name: "member-zone-config" + request-xfr: 198.51.100.1 NOKEY + allow-notify: 198.51.100.1 NOKEY + + key: + name: tsig-key.name + algorithm: hmac-sha256 + secret: "SXMgdGhpcyBhIHNlY3JldCBvciBqdXN0IHRleHQ/Pz8=" + + tls-auth: + name: primary.example + auth-domain-name: primary.example + + zone: + name: "catalog1.invalid" + catalog: consumer + catalog-member-pattern: "member-zone-config" + + request-xfr: 192.0.2.1@853 tsig-key.name primary.example + allow-notify: 192.0.2.1 tsig-key.name + + allow-query: BLOCKED + +The consumer zone ``catalog1.invalid`` is configured in the example as a +secondary zone. It transfers the catalog from the primary at ``192.0.2.1``. +The transfer is mutually authenticated :doc:`using TSIG`. + +The content of catalog zones are only relevant for the name servers handling +those zones. They contain a list of zones that are served from the name +servers and it is likely undesirable to expose that content. We have protected +the zone against queries from third-parties by setting the ``allow-query: +BLOCKED`` option. The transfer is protected against on-path eavesdroppers by +doing it over :doc:`authenticated TLS`. + +.. Note:: Using privacy preserving option is RECOMMENDED for catalog zones + (See `RFC 9432 Sections 6 and 7 + `_). + +.. Note:: Catalog consumer zones do not need to be secondary, they may also + process just zone files. + +NSD supports the `group property +`_. Member +zones from the catalog will be added with the pattern given by the group +property of that member. If a member does not have a group property or its +value is invalid or doesn't match a pattern, the pattern given by the +``catalog-member-pattern:`` option will be used. + +Using nsd-control to get catalog zone status +-------------------------------------------- + +The status of catalog zones and catalog member zones can be consulted with +:command:`nsd-control zonestatus`. + +.. code:: bash + + $ nsd-control zonestatus + + zone: catalog1.invalid + catalog: consumer (serial: 1708341939, # members: 2) + state: ok + served-serial: "1708341939 since 2024-02-19T15:19:44" + commit-serial: "1708341939 since 2024-02-19T15:19:44" + wait: "3461 sec between attempts" + + zone: example.net + pattern: member-zone-config + catalog-member-id: a5b75379.zones.catalog1.invalid. + state: ok + served-serial: "2024013019 since 2024-02-19T14:25:43" + commit-serial: "2024013019 since 2024-02-19T14:25:43" + wait: "7195 sec between attempts" + + zone: example.org + pattern: group1 + catalog-member-id: 96143f7d.zones.catalog1.invalid. + state: ok + served-serial: "2024013016 since 2024-02-19T14:18:10" + commit-serial: "2024013016 since 2024-02-19T14:18:10" + wait: "6544 sec between attempts" + +The first ``zone:`` entry in the example output above shows the status our +configured consumer zone ``catalog1.invalid``. Besides its role (``consumer`` +or ``producer``) it show the last SOA serial number that was successfully +processed, and the number of member zones that were added by processing the +consumer zone. + +.. Note:: If the catalog zone has become invalid and isn't processed + anymore, :command:`nsd-control zonestatus` will show the reason why. + +:command:`nsd-control zonestatus` will also show the ``catalog-member-id`` of +catalog member zones. In the example output of :command:`nsd-control +zonestatus` above we can see that ``example.net`` and ``example.org`` are +member zones from ``catalog1.invalid``. Apparently the ``example.net`` member +did not have a valid group property, because it has been added with the default +``catalog-member-pattern:`` ``member-zone-config``. + +Setting up NSD as a catalog producer +------------------------------------ +A catalog producer zone can be configured in NSD by setting the ``catalog: +producer`` option. Unlike consumer zones, multiple producer zones may be +configured. NSD creates the content of producer zones and therefore producer +zones cannot be configured as secondary zones. Likewise, ``zonefile:`` options +are only used to write the zone, never to read it. + +An example catalog producer configuration could look like this: + +.. code:: bash + + server: + interface: 192.0.2.1@853 + tls-port: 853 + tls-service-key: "primary.example.key.pem" + tls-service-pem: "primary.example.cert.pem" + + pattern: + name: "group0" + catalog-producer-zone: "catalog1.invalid" + + pattern: + name: "group1" + catalog-producer-zone: "catalog1.invalid" + + key: + name: tsig-key.name + algorithm: hmac-sha256 + secret: "SXMgdGhpcyBhIHNlY3JldCBvciBqdXN0IHRleHQ/Pz8=" + + zone: + name: "catalog1.invalid" + catalog: producer + + store-ixfr: yes + provide-xfr: 203.0.113.1@853 tsig-key.name + notify: 203.0.113.1 tsig-key.name + + allow-query: BLOCKED + +The producer zone is configured as a primary and allows (in our example) +transfer of the zone over TLS only. Also, just like with the consumer zone +configuration example above, queries to this zone are ``BLOCKED`` to comply +with `RECOMMENDED `_ privacy +and security considerations. We also recommend - for primary zones in general - +to serve *incremental* transfers (configured with ``store-ixfr: yes``). + +Zones can be added as member zones, by adding them to NSD with +:command:`nsd-control addzone` with a pattern that has the name of the producer +zone as value of a ``catalog-producer-zone:`` option. In the example +configuration above, patterns ``"group0"`` and ``"group1"`` both have that +option. + +Here is an example on how to do that: + +.. code:: bash + + $ nsd-control addzone example.net group0 + ok + $ nsd-control addzone example.org group1 + ok + +Like with consumer zones and consumer member zones, :command:`nsd-control +zonestatus` can be used to check on the status of catalog producer zones and +its members: + +.. code:: bash + + $ nsd-control zonestatus + + zone: catalog1.invalid + catalog: producer (serial: 1708341939, # members: 2) + state: primary + + zone: example.net + pattern: group0 + catalog-member-id: a5b75379.zones.catalog1.invalid. + state: primary + + zone: example.org + pattern: group1 + catalog-member-id: 96143f7d.zones.catalog1.invalid. + state: primary + +Like with other zones added with :command:`nsd-control addzone`, the member +zones are persistently added to the zone list file (see the ``zonelistfile:`` +configure option). The content of the catalog producer zone is not persistent +and will be reconstructed from the member zone entries in the zone list file. + +.. code:: bash + + $ cat /var/db/nsd/zone.list + # NSD zone list + # name pattern + cat example.net group0 a5b75379 + cat example.org group1 96143f7d + diff --git a/doc/manual/conf.py.in b/doc/manual/conf.py.in new file mode 100644 index 00000000..ed3126f7 --- /dev/null +++ b/doc/manual/conf.py.in @@ -0,0 +1,298 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import os +import datetime +import sphinx_rtd_theme +import requests + +# -- Project information ----------------------------------------------------- + +# PACKAGE_* macros are defined by AC_INIT in configure.ac. + +project = '@project@' +year = datetime.datetime.now().year +copyright = f'2001–{year}, NLnet Labs' +author = 'NLnet Labs' + +# The short X.Y version +version = '@version@' +# The full version, including alpha/beta/rc tags +release = '@version@' + +try: + response_versions = requests.get( + f"https://readthedocs.org/api/v2/version/?project__slug=nsd&active=true", + timeout=2, + ).json() + versions = [ + (version["slug"], f"/{version['project']['language']}/{version['slug']}/") + for version in response_versions["results"] + ] +except Exception: + versions = [] + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.todo', + 'sphinx.ext.ifconfig', + 'sphinx_tabs.tabs', + 'sphinx_copybutton', + 'sphinx.ext.intersphinx', + 'sphinx.ext.autosectionlabel', + 'notfound.extension', + 'sphinxcontrib.jquery', + 'sphinx_rtd_theme', +] + +intersphinx_mapping = { + 'nsd': ('https://nsd.docs.nlnetlabs.nl/en/latest/', None) +} + +autosectionlabel_prefix_document = True + +# -- Sphinx Tabs configuration ----------------------------------------------- + +sphinx_tabs_disable_tab_closing = True + +# Add any paths that contain templates here, relative to this directory. +#templates_path = ['../templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +html_logo = 'resources/nsd-duotone-white.png' +html_favicon = 'resources/favicon.ico' +html_theme_options = { + 'logo_only': True, + 'display_version': True, +} + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['resources'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# Set canonical URL from the Read the Docs Domain +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "") +scheme = "https" + +html_context = { + 'html_theme': html_theme, + 'current_version': version, + 'version_slug': version, + + 'PRODUCTION_DOMAIN': "readthedocs.org", + 'versions': versions, + # "downloads": downloads, + # "subprojects": subprojects, + + 'slug': "nsd", + 'rtd_language': language, + 'canonical_url': html_baseurl, + + 'conf_py_path': "/source/", + + 'github_user': "NLnetLabs", + 'github_repo': "nsd", + 'github_version': os.environ.get("READTHEDOCS_GIT_IDENTIFIER", "main"), + 'display_github': True, + 'READTHEDOCS': True, + 'using_theme': False, + 'new_theme': True, + 'source_suffix': ".rst", + 'docsearch_disabled': False, + } + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'NSDUserManualdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'NSDUserManual.tex', 'NSD User Manual', + 'NLnet Labs', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# >> we do manpages, but we use mandoc to generate the body for maximum +# compatibility and convenience + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +#man_pages = [ +# ('man/nsd', 'nsd', 'Name Server Daemon (NSD)', +# "NSD was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS file in the distribution for further details.", 8), +# ('man/nsd-checkconf', 'nsd-checkconf', 'NSD configuration file checker.', +# "NSD was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS file in the distribution for further details.", 8), +# ('man/nsd-checkzone', 'nsd-checkzone', 'NSD zone file syntax checker.', +# "NSD was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS file in the distribution for further details.", 8), +# ('man/nsd.conf', 'nsd.conf', 'NSD configuration file.', +# "NSD was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS file in the distribution for further details.", 5), +# ('man/nsd-control', 'nsd-control', 'NSD remote server control utility.', +# "NSD was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS file in the distribution for further details.", 8) +#] +#manpages_url = '{page}.html' + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'NSDUserManual', 'NSD User Manual', + author, 'NSDUserManual', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + +# -- Extension interface -------------------------------------------------- +from sphinx import addnodes +def parse_cmd_args_node(env, sig, signode): + try: + cmd, args = sig.strip().split(' ', 1) + except ValueError: + cmd, args = sig, None + # distinguish cmd from its args + signode += addnodes.desc_name(cmd, cmd) + if args: + args = ' ' + args + signode += addnodes.desc_addname(args, args) + return cmd +# define new directive/role that can be used as .. subcmd::/:subcmd: +def setup(app): + app.add_object_type('subcmd', 'subcmd', + objname='module sub-command', + indextemplate='pair: %s; module sub-command', + parse_node=parse_cmd_args_node) + app.add_css_file('css/dark.css') + app.add_css_file('css/light.css') + + +# -- Export variables to be used in RST -------------------------------------- + +rst_epilog = ".. |pidfile| replace:: @pidfile@\n" \ + ".. |configdir| replace:: @configdir@\n" \ + ".. |configfile| replace:: @nsdconfigfile@" diff --git a/doc/manual/configuration.rst b/doc/manual/configuration.rst new file mode 100644 index 00000000..efa1c279 --- /dev/null +++ b/doc/manual/configuration.rst @@ -0,0 +1,295 @@ +Configuration +============= + +NSD has a vast array of configuration options for advanced use cases. To +configure the application, a ``nsd.conf`` configuration file used. The file +format has attributes and values, and some attributes have attributes inside +them. + +.. Note:: The instructions in this page assume that NSD is already installed. + +The configuration file +---------------------- + + +The configuration NSD uses is specified in the configuration file, which can be supplied to NSD using the :option:`-c` option. In the :doc:`reference` an example ``nsd.conf`` can be found as well as the complete documentation of all the configurable options. The same example and reference can be found on your system using the ``man nsd.conf`` command. + + +The basic rules are of the config file are: + + - The used notation is ``attribute: value`` + - Comments start with ``#`` and extend to the end of a line + - Empty lines are ignored, as is whitespace at the beginning of a line + - Quotes can be used, for names containing spaces, e.g. ``"file name.zone"`` + + +Below we'll give an example config file, which specifies options for the NSD server, zone files, primaries and secondaries. This provide basic config which can be used for as a starting point. + +Note that for the remainder we assume the default location of NSD is ``/etc/nsd`` though this may vary on your system. + +The example configuration below specifies options for the NSD server, zone +files, primaries and secondaries. + +Here is an example config for ``example.com``: + +.. code:: bash + + server: + # use this number of cpu cores + server-count: 1 + # We recommend leaving this empty, otherwise use "/var/db/nsd/nsd.db" + database: "" + # the default file used for the nsd-control addzone and delzone commands + # zonelistfile: "/var/db/nsd/zone.list" + # The unprivileged user that will run NSD, can also be set to "" if + # user privilige protection is not needed + username: nsd + # Default file where all the log messages go + logfile: "/var/log/nsd.log" + # Use this pid file instead of the platform specific default + pidfile: "/var/run/nsd.pid" + # Enable if privilege "jail" is needed for unprivileged user. Note + # that other file paths may break when using chroot + # chroot: "/etc/nsd/" + # The default zone transfer file + # xfrdfile: "/var/db/nsd/xfrd.state" + # The default working directory before accessing zone files + # zonesdir: "/etc/nsd" + + remote-control: + # this allows the use of 'nsd-control' to control NSD. The default is "no" + control-enable: yes + # the interface NSD listens to for nsd-control. The default is 127.0.0.1 + control-interface: 127.0.0.1 + # the key files that allow the use of 'nsd-control'. The default path is "/etc/nsd/". Create these using the 'nsd-control-setup' utility + server-key-file: /etc/nsd/nsd_server.key + server-cert-file: /etc/nsd/nsd_server.pem + control-key-file: /etc/nsd/nsd_control.key + control-cert-file: /etc/nsd/nsd_control.pem + + zone: + name: example.com + zonefile: /etc/nsd/example.com.zone + +We recommend not using the database (so using ``database: ""``) as this is will slow down NSD operation. Depending on your needs, we also recommend keeping the ``server-count`` lower or equal to the number of CPU cores your system has. + +Optionally, you can control NSD (from the same or even a different device) by using the entries under the `remote-control` clause in the config. Using this tool, NSD can be controlled (find the reference of all the options :doc:`here`) which makes controlling NSD much easier. If your install does not come with the keys needed for remote-control use pre-made, you can generate the keys using the :command:`nsd-control-setup` command, which will create them for you. In the section below we will go into more detail about this option. + +You can test the config with :command:`nsd-checkconf`. This tool will tell you what is wrong with the config and where the error occurs. + +If you are happy with the config and any modifications you may have done, you can create the zone to go with the file we mentioned in the config. We show an example zone at :doc:`the zonefile example`. + + +Setting up a secondary zone +--------------------------- + +If your needs go further than just a few zones that are managed locally, NSD has got you covered. We won't go into the theoretical details of primaries and secondaries here (we recommend `this blog `_), but we will show how to configure it. + + +The example for a secondary looks like this: + +.. code:: bash + + zone: + # this server is the primary, 192.0.2.1 is the secondary. + name: primaryzone.com + zonefile: /etc/nsd/primaryone.com.zone + notify: 192.0.2.1 NOKEY # NOKEY for testing purposes only + provide-xfr: 192.0.2.1 NOKEY # NOKEY for testing purposes only + + zone: + # this server is secondary, 192.0.2.2 is primary. + name: secondaryzone.com + zonefile: /etc/nsd/secondaryzone.com.zone + allow-notify: 192.0.2.2 NOKEY # NOKEY for testing purposes only + request-xfr: 192.0.2.2 NOKEY # NOKEY for testing purposes only + +.. note:: + + Note that the ``NOKEY`` keyword above are for testing purposes only, as this can introduce vulnerabilities when used in production environments. + + + +For a secondary zone we list the primaries by IP address. Below is an example +of a secondary zone with two primary servers. If a primary only supports AXFR +transfers and not IXFR transfers (like NSD), specify the primary as +``request-xfr: AXFR ``. By default, all zone transfer requests +are made over TCP. If you want the IXFR request be transmitted over UDP, use +``request-xfr: UDP ``. + +.. code-block:: text + + zone: + name: "example.com" + zonefile: "example.com.zone" + allow-notify: 168.192.185.33 NOKEY + request-xfr: 168.192.185.33 NOKEY + allow-notify: 168.192.199.2 NOKEY + request-xfr: 168.192.199.2 NOKEY + +By default, a secondary will fallback to AXFR requests if the primary told us it +does not support IXFR. You can configure the secondary not to do AXFR fallback +with: + +.. code-block:: text + + allow-axfr-fallback: "no" + +For a primary zone, list the secondary servers, by IP address or subnet. Below +is an example of a primary zone with two secondary servers: + +.. code-block:: text + + zone: + name: "example.com" + zonefile: "example.com.zone" + notify: 168.192.133.75 NOKEY + provide-xfr: 168.192.133.75 NOKEY + notify: 168.192.5.44 NOKEY + provide-xfr: 168.192.5.44 NOKEY + +You also can set the outgoing interface for notifies and zone transfer requests +to satisfy access control lists at the other end: + +.. code-block:: text + + outgoing-interface: 168.192.5.69 + +By default, NSD will retry a notify up to five times. You can override that +value with: + +.. code-block:: text + + notify-retry: 5 + +Zone transfers can be secured with TSIG keys, replace NOKEY with the name of the +TSIG key to use. See :doc:`Using TSIG` for details. + +Since NSD is written to be run on the root name servers, the config file can to +contain something like: + +.. code-block:: text + + zone: + name: "." + zonefile: "root.zone" + provide-xfr: 0.0.0.0/0 NOKEY # allow axfr for everyone. + provide-xfr: ::0/0 NOKEY + +You should only do that if you're intending to run a root server, NSD is not +suited for running a ``.`` cache. Therefore if you choose to serve the ``.`` +zone you have to make sure that the complete root zone is timely and fully +updated. + +To prevent misconfiguration, NSD configure has the +``--enable-root-server`` option, that is by default disabled. + +In the config file, you can use patterns. A pattern can have the same +configuration statements that a zone can have. And then you can +``include-pattern: `` in a zone (or in another pattern) to +apply those settings. This can be used to organise the settings. + + +Remote controlling NSD +---------------------- + +The :command:`nsd-control` tool is also controlled from the ``nsd.conf`` config +file (and it's manpage is found :doc:`here`). It uses TLS encrypted transport to 127.0.0.1, and if you want to use it +you have to setup the keys and also edit the config file. You can leave the +remote-control disabled (the secure default), or opt to turn it on: + +.. code-block:: text + + # generate keys + nsd-control-setup + +.. code-block:: text + + # edit nsd.conf to add this + remote-control: + control-enable: yes + +By default :command:`nsd-control` is limited to localhost, as well as encrypted, +but some people may want to remotely administer their nameserver. To control NSD remotely, configure :command:`nsd-control` to listen to the public IP address with +``control-interface: `` after the control-enable statement. + +Furthermore, you copy the key files :file:`/etc/nsd/nsd_server.pem` +:file:`/etc/nsd/nsd_control.*` to a remote host on the internet; on that host +you can run :command:`nsd-control` with :option:`-c` ```` +which references same IP address ``control-interface`` and references the copies +of the key files with ``server-cert-file``, ``control-key-file`` and +``control-cert-file`` config lines after the ``control-enable`` statement. The +nsd-server authenticates the nsd-control client, and also the +:command:`nsd-control` client authenticates the nsd-server. + + +Starting up the first time +-------------------------- + +When you are done with the configuration file, check the syntax using + +.. code-block:: text + + nsd-checkconf + +The zone files are read by the daemon, which builds :file:`nsd.db` with their +contents. You can start the daemon in a number of ways: + +.. code-block:: text + + nsd -c + nsd-control start # which execs nsd via the remote-control configuration + nsd # which will use the default configuration file + +To check if the daemon is running look with :command:`ps`, :command:`top`, or if +you enabled :command:`nsd-control`: + +.. code-block:: text + + nsd-control status + +To reload changed zone files after you edited them, without stopping the daemon, +use this to check if files are modified: + +.. code-block:: text + + kill -HUP `cat ` + or "nsd-control reload" if you have remote-control enabled + +With :command:`nsd-control` you can also reread the config file, in case of new +zones, etc. + +.. code-block:: text + + nsd-control reconfig + +To restart the daemon: + +.. code-block:: text + + /etc/rc.d/nsd restart # or your system(d) equivalent + +To shut it down (for example on the system shutdown) do: + +.. code-block:: text + + kill -TERM + or nsd-control stop + +NSD will automatically keep track of secondary zones and update them when +needed. When primary zones are updated and reloaded notifications are sent to +secondary servers. + +The zone transfers are applied to :file:`nsd.db` by the daemon. To write +changed contents of the zone files for secondary zones to disk in the text-based +zone file format, issue :command:`nsd-control` write. + +NSD will send notifications to secondary zones if a primary zone is updated. NSD +will check for updates at primary servers periodically and transfer the updated +zone by AXFR/IXFR and reload the new zone contents. + +If you wish exert manual control use :command:`nsd-control notify`, +:command:`transfer` and :command:`force_transfer` commands. The transfer +command will check for new versions of the secondary zones hosted by this NSD. +The notify command will send notifications to the secondary servers configured +in ``notify:`` statements. diff --git a/doc/manual/index.rst b/doc/manual/index.rst new file mode 100644 index 00000000..fefe50f1 --- /dev/null +++ b/doc/manual/index.rst @@ -0,0 +1,70 @@ +Name Server Daemon (NSD) by NLnet Labs +====================================== + +Welcome to the documentation of the NLnet Labs Name Server Daemon (NSD), an +authoritative DNS name server. It has been developed for operations in +environments where speed, reliability, stability and security are of high +importance. + +NSD is designed with a pure philosophy that prioritises raw performance. This +means that if you serve hundreds of thousands or even millions of queries per +second, NSD is the leading implementation in the world. This authoritative DNS +name server strives to be a reference implementation for emerging standards of +the Internet Engineering Task Force (IETF). NSD is distributed free of charge in +open source form under the BSD license. For most platforms, `packages +`_ are available. + +This documentation is an open source project maintained by NLnet Labs. is edited +via text files in the `reStructuredText +`_ markup language and then +compiled into a static website/offline document using the open source `Sphinx +`_ and `ReadTheDocs `_ +tools. + +We always appreciate your feedback and improvements. You can submit an issue or +pull request on the `GitHub repository +`_, or post a message on the +`NSD users `_ mailing +list. All the contents are under the permissive Creative Commons Attribution 3.0 +(`CC-BY 3.0 `_) license, with +attribution to NLnet Labs. + +.. toctree:: + :maxdepth: 2 + :caption: Getting Started + + installation + configuration + zonefile + catalog-zones + +.. toctree:: + :maxdepth: 2 + :caption: Running + + running/logging + running/using-tsig + running/zone-expiry + running/interfaces + running/tuning + +.. toctree:: + :maxdepth: 1 + :caption: Manual Pages + + manpages/nsd + manpages/nsd-checkconf + manpages/nsd-checkzone + manpages/nsd.conf + manpages/nsd-control + +.. toctree:: + :maxdepth: 2 + :caption: Reference + + reference/configure-options + reference/log-diagnosis + +.. history +.. authors +.. license diff --git a/doc/manual/installation.rst b/doc/manual/installation.rst new file mode 100644 index 00000000..2158f32d --- /dev/null +++ b/doc/manual/installation.rst @@ -0,0 +1,140 @@ +Installation +------------ + +To install your own copy of NSD you have two options: use the version provided +by your package manager, or download the source and building it yourself. + +Installing via the `package manager +`_ is the easiest option, and on most +systems even trivial. The downside is the distributed version can be outdated +for some distributions or not have all the compile-time options included that +you want. Building and compiling NSD yourself ensures that you have the latest +version and all the compile-time options you desire. + +Introduction +============ + +NSD consists of two programs: the zone compiler ``zonec`` and the name server +``nsd`` itself. The name server works with an intermediate database prepared by +the zone compiler from standard zone files. + +For NSD operation this means that zones have to be compiled by ``zonec`` before +NSD can use them. All this can be controlled via ``rc.d`` (SIGTERM, SIGHUP) or +:command:`nsd-control`, and uses a simple configuration file ``nsd.conf``. + +Installing with a package manager +================================= + +Most package managers maintain a version of NSD, although this version can be +outdated if this package has not been updated recently. If you like to upgrade +to the latest version, we recommend :ref:`compiling NSD yourself`. + + +Debian/Ubuntu +************* + +Installing NSD with the built-in package manager should be as easy as: + +.. code-block:: bash + + sudo apt update + sudo apt install nsd + +This gives you a compiled and running version of NSD ready to :doc:`be +configured`. + + +Building from source/Compiling +============================== + +Ubuntu 20.04 LTS +************* + +First of all, we need our copy of the NSD code. `On our website +`_ you can find the latest version and +the changelog. In this example we'll use version 4.3.7. Please note that this is not the latest version currently. + +.. code-block:: bash + + wget https://nlnetlabs.nl/downloads/nsd/nsd-4.3.7.tar.gz + tar xzf nsd-4.3.7.tar.gz + + +We'll need some tools, such as a compiler and the :command:`make` program. + +.. code-block:: bash + + sudo apt update + sudo apt install -y build-essential + + +The library components NSD needs are: ``libssl`` and ``libevent``, of which we need +the "dev" version. + +.. code-block:: bash + + sudo apt install -y libssl-dev + sudo apt install -y libevent-dev + + +We'll also need the tools to build the actual program. For this, NSD uses +:command:`make` and internally it uses ``flex`` and ``yacc``, which we need to +download as well. + +.. code-block:: bash + + sudo apt install -y bison + sudo apt install -y flex + + +With all the requirements met, we can now start the compilation process in the +NSD directory. The first step here is configuring. With :option:`./configure +-h` you can look at the extensive list of configurables for NSD. A nice +feature is that :command:`configure` will tell you what it's missing during +configuration. + +.. code-block:: bash + + ./configure + +If :command:`configure` gives no errors, we can continue to actually try compiling +NSD using :command:`make`; compilation might take a while. + +.. code-block:: bash + + make + +After successfully compiling, we can install NSD to make it available for +the machine. + +.. code-block:: bash + + sudo make install + +We now have fully compiled and installed version of NSD, and can continue +to testing it. + + +Testing +======= + +A simple test to determine if the installation was successful is to invoke the +:command:`nsd` command with the :option:`-V` option, which is the "version" +option. This shows the version and build options used and proves installation +was successful. + +.. code-block:: bash + + nsd -v + +If all the previous steps were successful we can continue to configuring our NSD +instance. + +Another handy trick you can use during testing is to run NSD in the foreground +using the :option:`-d` option and increase the verbosity level using the +:option:`-V 3` option. This allows you to see steps NSD takes and also where it +fails. + +Now that NSD is installed we can :doc:`continue to configuring +it`. diff --git a/doc/manual/manpages/nsd-checkconf.rst b/doc/manual/manpages/nsd-checkconf.rst new file mode 100644 index 00000000..eb35c298 --- /dev/null +++ b/doc/manual/manpages/nsd-checkconf.rst @@ -0,0 +1,5 @@ +nsd-checkconf(8) +================ + +.. raw:: html + :file: nsd-checkconf.8.html diff --git a/doc/manual/manpages/nsd-checkzone.rst b/doc/manual/manpages/nsd-checkzone.rst new file mode 100644 index 00000000..cdaeffcb --- /dev/null +++ b/doc/manual/manpages/nsd-checkzone.rst @@ -0,0 +1,5 @@ +nsd-checkzone(8) +================ + +.. raw:: html + :file: nsd-checkzone.8.html diff --git a/doc/manual/manpages/nsd-control.rst b/doc/manual/manpages/nsd-control.rst new file mode 100644 index 00000000..58517dd7 --- /dev/null +++ b/doc/manual/manpages/nsd-control.rst @@ -0,0 +1,5 @@ +nsd-control(8) +============== + +.. raw:: html + :file: nsd-control.8.html diff --git a/doc/manual/manpages/nsd.conf.rst b/doc/manual/manpages/nsd.conf.rst new file mode 100644 index 00000000..28462115 --- /dev/null +++ b/doc/manual/manpages/nsd.conf.rst @@ -0,0 +1,5 @@ +nsd.conf(5) +=========== + +.. raw:: html + :file: nsd.conf.5.html diff --git a/doc/manual/manpages/nsd.rst b/doc/manual/manpages/nsd.rst new file mode 100644 index 00000000..590db114 --- /dev/null +++ b/doc/manual/manpages/nsd.rst @@ -0,0 +1,5 @@ +nsd(8) +====== + +.. raw:: html + :file: nsd.8.html diff --git a/doc/manual/reference/configure-options.rst b/doc/manual/reference/configure-options.rst new file mode 100644 index 00000000..4e40ab15 --- /dev/null +++ b/doc/manual/reference/configure-options.rst @@ -0,0 +1,104 @@ +Configure Options +================= + +NSD can be configured using GNU autoconf's configure script. In addition to +standard configure options, one may use the following: + +CC=compiler + Specify the C compiler. The default is gcc or cc. The compiler must support + ANSI C89. + +CPPFLAGS=flags + Specify the C preprocessor flags. Such as ``-I``. + +CFLAGS=flags + Specify the C compiler flags. These include code generation, optimisation, + warning, and debugging flags. These flags are also passed to the linker. + + The default for gcc is ``-g -O2``. + +LD=linker + Specify the linker (defaults to the C compiler). + +LDFLAGS=flags + Specify linker flags. + +LIBS=libs + Specify additional libraries to link with. + +--enable-root-server + Configure NSD as a root server. Unless this option is specified, NSD will + refuse to serve the ``.`` zone as a misconfiguration safeguard. + +--disable-ipv6 + Disables IPv6 support in NSD. + +--enable-checking + Enable some internal development checks. Useful if you want to modify NSD. + This option enables the standard C "assert" macro and compiler warnings. + + This will instruct NSD to be stricter when validating its input. This could + lead to a reduced service level. + +--enable-bind8-stats + Enables BIND8-like statistics. + +--enable-ratelimit + Enables rate limiting, based on query name, type and source. + +--enable-draft-rrtypes + Enables draft RRtypes. + +--with-configdir=dir + Specified, NSD configuration directory, default :file:`/etc/nsd`. + +--with-nsd_conf_file=path + Pathname to the NSD configuration file, default :file:`/etc/nsd/nsd.conf`. + +--with-pidfile=path + Pathname to the NSD pidfile, default is platform specific, mostly + :file:`/var/run/nsd.pid`. + +--with-dbfile=path + Pathname to the NSD database, default is :file:`/etc/nsd/nsd.db`. + +--with-zonesdir=dir + NSD default location for master zone files, default :file:`/etc/nsd/`. + +--with-user=username + User name or ID to answer the queries with, default is ``nsd``. + +--with-facility=facility + Specify the syslog facility to use. The default is LOG_DAEMON. See the + syslog(3) manual page for the available facilities. + +--with-libevent=path + Specity the location of the ``libevent`` library (or libev). + ``--with-libevent=no`` uses a builtin portable implementation (select()). + +--with-ssl=path + Specify the location of the OpenSSL libraries. OpenSSL 0.9.7 or higher is + required for TSIG support. + +--with-start_priority=number + Startup priority for NSD. + +--with-kill_priority=number + Shutdown priority for NSD. + +--with-tcp-timeout=number + Set the default TCP timeout (in seconds). The default is 120 seconds. + +--disable-nsec3 + Disable NSEC3 support. With NSEC3 support enabled, very large zones, also + non-NSEC3 zones, use about 20% more memory. + +--disable-minimal-responses + Disable minimal responses. If disabled, responses are more likely to get + truncated, resulting in TCP fallback. When enabled (by default) NSD will + leave out RRsets to make responses fit inside one datagram, but for shorter + responses the full normal response is carried. + +--disable-largefile + Disable large file support (64 bit file lengths). Makes off_t a 32bit length + during compilation. diff --git a/doc/manual/reference/log-diagnosis.rst b/doc/manual/reference/log-diagnosis.rst new file mode 100644 index 00000000..70418986 --- /dev/null +++ b/doc/manual/reference/log-diagnosis.rst @@ -0,0 +1,38 @@ +Diagnosing NSD Log Entries +========================== + +NSD will print log messages to the system log (or ``logfile:`` configuration +entry). Some of these messages are covered here. + +Reload process failed with status , continuing with old database + This log message indicates the reload process of NSD has failed for some + reason. This can be anything from a missing database file to internal + errors. + +snipping off trailing partial part of + The file :file:`ixfr.db` contains only part of expected data. The corruption + is removed by snipping off the trailing part. + +memory recyclebin holds bytes + This is printed for every reload. NSD allocates and deallocates memory to + service IXFR updates. The recycle bin holds deallocated memory ready for + future use. If the number grows too large, a restart resets it. + +xfrd: max number of tcp connections (32) reached + This line is printed when more than 32 zones need a zone transfer at the + same time. The value is a compile constant (``xfrd-tcp.h``), but if this + happens often for you, we could make this a config option. NSD will reuse + existing TCP connections to the same primary (determined by IP address) to + transfer up to 64k zones from that primary. Thus this error should only + happen with more than 32 primaries or more than 64\*32=2M zones that need to + be updated at the same time. + + If this happens, more zones have to wait until a zone transfer completes + (or is aborted) before they can have a zone transfer too. This waiting + list has no size limit. + +error: NSEC3PARAM entry has unknown hash algo + This error means that the zone has NSEC3 chain(s) with hash algorithms that + are not supported by this version of NSD, and thus cannot be served by NSD. + If there are also no NSECs or NSEC3 chain(s) with known hash algorithms, NSD + will not be able to serve DNSSEC authenticated denials for the zone. \ No newline at end of file diff --git a/doc/manual/requirements.txt b/doc/manual/requirements.txt new file mode 100644 index 00000000..c47fd3be --- /dev/null +++ b/doc/manual/requirements.txt @@ -0,0 +1,7 @@ +sphinx==5.0.2 +sphinx-version-warning==1.1.2 +sphinx-tabs==3.4.4 +sphinx-copybutton==0.5.2 +sphinx-rtd-theme +sphinx-notfound-page +requests diff --git a/doc/manual/resources/css/dark.css b/doc/manual/resources/css/dark.css new file mode 100644 index 00000000..82b97485 --- /dev/null +++ b/doc/manual/resources/css/dark.css @@ -0,0 +1,3648 @@ +@media (prefers-color-scheme: dark) { + /* + _______ + / \ + .==. .==. + (( ))==(( )) + / "==" "=="\ + /____|| || ||___\ + ________ ____ ________ ___ ___ + | ___ \ / \ | ___ \ | | / / + | | \ \ / /\ \ | | \ \| |_/ / + | | ) / /__\ \ | |__/ /| ___ \ + | |__/ / ______ \| ____ \| | \ \ + _______|_______/__/ ____ \__\__|___\__\__|___\__\____ + | ___ \ | ____/ / \ | ___ \ | ____| ___ \ + | | \ \| |___ / /\ \ | | \ \| |___| | \ \ + | |__/ /| ____/ /__\ \ | | ) | ____| |__/ / + | ____ \| |__/ ______ \| |__/ /| |___| ____ \ + |__| \__\____/__/ \__\_______/ |______|__| \__\ + https://darkreader.org + */ + + /*! Dark reader generated CSS | Licensed under MIT https://github.com/darkreader/darkreader/blob/master/LICENSE */ + + /* User-Agent Style */ + html { + background-color: #181a1b !important; + } + html, body, input, textarea, select, button { + background-color: #181a1b; + } + html, body, input, textarea, select, button { + border-color: #736b5e; + color: #e8e6e3; + } + a { + color: #3391ff; + } + table { + border-color: #545b5e; + } + ::placeholder { + color: #b2aba1; + } + input:-webkit-autofill, + textarea:-webkit-autofill, + select:-webkit-autofill { + background-color: #555b00 !important; + color: #e8e6e3 !important; + } + ::selection { + background-color: #004daa !important; + color: #e8e6e3 !important; + } + ::-moz-selection { + background-color: #004daa !important; + color: #e8e6e3 !important; + } + pre.man { + font-size: 0.9em; + } + /* Invert Style */ + .jfk-bubble.gtx-bubble, .captcheck_answer_label > input + img, span#closed_text > img[src^="https://www.gstatic.com/images/branding/googlelogo"], span[data-href^="https://www.hcaptcha.com/"] > #icon, #bit-notification-bar-iframe, ::-webkit-calendar-picker-indicator { + filter: invert(100%) hue-rotate(180deg) contrast(90%) !important; + } + + /* Variables Style */ + :root { + --darkreader-neutral-background: #131516; + --darkreader-neutral-text: #d8d4cf; + --darkreader-selection-background: #004daa; + --darkreader-selection-text: #e8e6e3; + } + + /* Modified CSS */ + a:active, + a:hover { + outline-color: initial; + } + abbr[title] { + border-bottom-color: initial; + } + ins { + background-image: initial; + background-color: rgb(112, 112, 0); + text-decoration-color: initial; + } + ins, + mark { + color: rgb(232, 230, 227); + } + mark { + background-image: initial; + background-color: rgb(204, 204, 0); + } + dl, + ol, + ul { + list-style-image: none; + } + li { + list-style-image: initial; + } + img { + border-color: initial; + } + .chromeframe { + background-image: initial; + background-color: rgb(53, 57, 59); + color: rgb(232, 230, 227); + } + .ir { + border-color: initial; + background-color: transparent; + } + .visuallyhidden { + border-color: initial; + } + .fa-border { + border-color: rgb(53, 57, 59); + } + .fa-inverse { + color: rgb(232, 230, 227); + } + .sr-only { + border-color: initial; + } + .fa::before, + .icon::before, + .rst-content .admonition-title::before, + .rst-content .code-block-caption .headerlink::before, + .rst-content .eqno .headerlink::before, + .rst-content code.download span:first-child::before, + .rst-content dl dt .headerlink::before, + .rst-content h1 .headerlink::before, + .rst-content h2 .headerlink::before, + .rst-content h3 .headerlink::before, + .rst-content h4 .headerlink::before, + .rst-content h5 .headerlink::before, + .rst-content h6 .headerlink::before, + .rst-content p.caption .headerlink::before, + .rst-content p .headerlink::before, + .rst-content table > caption .headerlink::before, + .rst-content tt.download span:first-child::before, + .wy-dropdown .caret::before, + .wy-inline-validate.wy-inline-validate-danger .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-info .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-success .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-warning .wy-input-context::before, + .wy-menu-vertical li.current > a button.toctree-expand::before, + .wy-menu-vertical li.on a button.toctree-expand::before, + .wy-menu-vertical li button.toctree-expand::before { + text-decoration-color: inherit; + } + .rst-content .code-block-caption a .headerlink, + .rst-content .eqno a .headerlink, + .rst-content a .admonition-title, + .rst-content code.download a span:first-child, + .rst-content dl dt a .headerlink, + .rst-content h1 a .headerlink, + .rst-content h2 a .headerlink, + .rst-content h3 a .headerlink, + .rst-content h4 a .headerlink, + .rst-content h5 a .headerlink, + .rst-content h6 a .headerlink, + .rst-content p.caption a .headerlink, + .rst-content p a .headerlink, + .rst-content table > caption a .headerlink, + .rst-content tt.download a span:first-child, + .wy-menu-vertical li.current > a button.toctree-expand, + .wy-menu-vertical li.on a button.toctree-expand, + .wy-menu-vertical li a button.toctree-expand, + a .fa, + a .icon, + a .rst-content .admonition-title, + a .rst-content .code-block-caption .headerlink, + a .rst-content .eqno .headerlink, + a .rst-content code.download span:first-child, + a .rst-content dl dt .headerlink, + a .rst-content h1 .headerlink, + a .rst-content h2 .headerlink, + a .rst-content h3 .headerlink, + a .rst-content h4 .headerlink, + a .rst-content h5 .headerlink, + a .rst-content h6 .headerlink, + a .rst-content p.caption .headerlink, + a .rst-content p .headerlink, + a .rst-content table > caption .headerlink, + a .rst-content tt.download span:first-child, + a .wy-menu-vertical li button.toctree-expand { + text-decoration-color: inherit; + } + .rst-content .admonition, + .rst-content .admonition-todo, + .rst-content .attention, + .rst-content .caution, + .rst-content .danger, + .rst-content .error, + .rst-content .hint, + .rst-content .important, + .rst-content .note, + .rst-content .seealso, + .rst-content .tip, + .rst-content .warning, + .wy-alert { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .rst-content .admonition-title, + .wy-alert-title { + color: rgb(232, 230, 227); + background-image: initial; + background-color: rgb(29, 91, 131); + } + .rst-content .danger, + .rst-content .error, + .rst-content .wy-alert-danger.admonition, + .rst-content .wy-alert-danger.admonition-todo, + .rst-content .wy-alert-danger.attention, + .rst-content .wy-alert-danger.caution, + .rst-content .wy-alert-danger.hint, + .rst-content .wy-alert-danger.important, + .rst-content .wy-alert-danger.note, + .rst-content .wy-alert-danger.seealso, + .rst-content .wy-alert-danger.tip, + .rst-content .wy-alert-danger.warning, + .wy-alert.wy-alert-danger { + background-image: initial; + background-color: rgb(52, 12, 8); + } + .rst-content .danger .admonition-title, + .rst-content .danger .wy-alert-title, + .rst-content .error .admonition-title, + .rst-content .error .wy-alert-title, + .rst-content .wy-alert-danger.admonition-todo .admonition-title, + .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, + .rst-content .wy-alert-danger.admonition .admonition-title, + .rst-content .wy-alert-danger.admonition .wy-alert-title, + .rst-content .wy-alert-danger.attention .admonition-title, + .rst-content .wy-alert-danger.attention .wy-alert-title, + .rst-content .wy-alert-danger.caution .admonition-title, + .rst-content .wy-alert-danger.caution .wy-alert-title, + .rst-content .wy-alert-danger.hint .admonition-title, + .rst-content .wy-alert-danger.hint .wy-alert-title, + .rst-content .wy-alert-danger.important .admonition-title, + .rst-content .wy-alert-danger.important .wy-alert-title, + .rst-content .wy-alert-danger.note .admonition-title, + .rst-content .wy-alert-danger.note .wy-alert-title, + .rst-content .wy-alert-danger.seealso .admonition-title, + .rst-content .wy-alert-danger.seealso .wy-alert-title, + .rst-content .wy-alert-danger.tip .admonition-title, + .rst-content .wy-alert-danger.tip .wy-alert-title, + .rst-content .wy-alert-danger.warning .admonition-title, + .rst-content .wy-alert-danger.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-danger .admonition-title, + .wy-alert.wy-alert-danger .rst-content .admonition-title, + .wy-alert.wy-alert-danger .wy-alert-title { + background-image: initial; + background-color: rgb(108, 22, 13); + } + .rst-content .admonition-todo, + .rst-content .attention, + .rst-content .caution, + .rst-content .warning, + .rst-content .wy-alert-warning.admonition, + .rst-content .wy-alert-warning.danger, + .rst-content .wy-alert-warning.error, + .rst-content .wy-alert-warning.hint, + .rst-content .wy-alert-warning.important, + .rst-content .wy-alert-warning.note, + .rst-content .wy-alert-warning.seealso, + .rst-content .wy-alert-warning.tip, + .wy-alert.wy-alert-warning { + background-image: initial; + background-color: rgb(82, 53, 0); + } + .rst-content .admonition-todo .admonition-title, + .rst-content .admonition-todo .wy-alert-title, + .rst-content .attention .admonition-title, + .rst-content .attention .wy-alert-title, + .rst-content .caution .admonition-title, + .rst-content .caution .wy-alert-title, + .rst-content .warning .admonition-title, + .rst-content .warning .wy-alert-title, + .rst-content .wy-alert-warning.admonition .admonition-title, + .rst-content .wy-alert-warning.admonition .wy-alert-title, + .rst-content .wy-alert-warning.danger .admonition-title, + .rst-content .wy-alert-warning.danger .wy-alert-title, + .rst-content .wy-alert-warning.error .admonition-title, + .rst-content .wy-alert-warning.error .wy-alert-title, + .rst-content .wy-alert-warning.hint .admonition-title, + .rst-content .wy-alert-warning.hint .wy-alert-title, + .rst-content .wy-alert-warning.important .admonition-title, + .rst-content .wy-alert-warning.important .wy-alert-title, + .rst-content .wy-alert-warning.note .admonition-title, + .rst-content .wy-alert-warning.note .wy-alert-title, + .rst-content .wy-alert-warning.seealso .admonition-title, + .rst-content .wy-alert-warning.seealso .wy-alert-title, + .rst-content .wy-alert-warning.tip .admonition-title, + .rst-content .wy-alert-warning.tip .wy-alert-title, + .rst-content .wy-alert.wy-alert-warning .admonition-title, + .wy-alert.wy-alert-warning .rst-content .admonition-title, + .wy-alert.wy-alert-warning .wy-alert-title { + background-image: initial; + background-color: rgb(123, 65, 14); + } + .rst-content .note, + .rst-content .seealso, + .rst-content .wy-alert-info.admonition, + .rst-content .wy-alert-info.admonition-todo, + .rst-content .wy-alert-info.attention, + .rst-content .wy-alert-info.caution, + .rst-content .wy-alert-info.danger, + .rst-content .wy-alert-info.error, + .rst-content .wy-alert-info.hint, + .rst-content .wy-alert-info.important, + .rst-content .wy-alert-info.tip, + .rst-content .wy-alert-info.warning, + .wy-alert.wy-alert-info { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .rst-content .note .admonition-title, + .rst-content .note .wy-alert-title, + .rst-content .seealso .admonition-title, + .rst-content .seealso .wy-alert-title, + .rst-content .wy-alert-info.admonition-todo .admonition-title, + .rst-content .wy-alert-info.admonition-todo .wy-alert-title, + .rst-content .wy-alert-info.admonition .admonition-title, + .rst-content .wy-alert-info.admonition .wy-alert-title, + .rst-content .wy-alert-info.attention .admonition-title, + .rst-content .wy-alert-info.attention .wy-alert-title, + .rst-content .wy-alert-info.caution .admonition-title, + .rst-content .wy-alert-info.caution .wy-alert-title, + .rst-content .wy-alert-info.danger .admonition-title, + .rst-content .wy-alert-info.danger .wy-alert-title, + .rst-content .wy-alert-info.error .admonition-title, + .rst-content .wy-alert-info.error .wy-alert-title, + .rst-content .wy-alert-info.hint .admonition-title, + .rst-content .wy-alert-info.hint .wy-alert-title, + .rst-content .wy-alert-info.important .admonition-title, + .rst-content .wy-alert-info.important .wy-alert-title, + .rst-content .wy-alert-info.tip .admonition-title, + .rst-content .wy-alert-info.tip .wy-alert-title, + .rst-content .wy-alert-info.warning .admonition-title, + .rst-content .wy-alert-info.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-info .admonition-title, + .wy-alert.wy-alert-info .rst-content .admonition-title, + .wy-alert.wy-alert-info .wy-alert-title { + background-image: initial; + background-color: rgb(29, 91, 131); + } + .rst-content .hint, + .rst-content .important, + .rst-content .tip, + .rst-content .wy-alert-success.admonition, + .rst-content .wy-alert-success.admonition-todo, + .rst-content .wy-alert-success.attention, + .rst-content .wy-alert-success.caution, + .rst-content .wy-alert-success.danger, + .rst-content .wy-alert-success.error, + .rst-content .wy-alert-success.note, + .rst-content .wy-alert-success.seealso, + .rst-content .wy-alert-success.warning, + .wy-alert.wy-alert-success { + background-image: initial; + background-color: rgb(9, 66, 58); + } + .rst-content .hint .admonition-title, + .rst-content .hint .wy-alert-title, + .rst-content .important .admonition-title, + .rst-content .important .wy-alert-title, + .rst-content .tip .admonition-title, + .rst-content .tip .wy-alert-title, + .rst-content .wy-alert-success.admonition-todo .admonition-title, + .rst-content .wy-alert-success.admonition-todo .wy-alert-title, + .rst-content .wy-alert-success.admonition .admonition-title, + .rst-content .wy-alert-success.admonition .wy-alert-title, + .rst-content .wy-alert-success.attention .admonition-title, + .rst-content .wy-alert-success.attention .wy-alert-title, + .rst-content .wy-alert-success.caution .admonition-title, + .rst-content .wy-alert-success.caution .wy-alert-title, + .rst-content .wy-alert-success.danger .admonition-title, + .rst-content .wy-alert-success.danger .wy-alert-title, + .rst-content .wy-alert-success.error .admonition-title, + .rst-content .wy-alert-success.error .wy-alert-title, + .rst-content .wy-alert-success.note .admonition-title, + .rst-content .wy-alert-success.note .wy-alert-title, + .rst-content .wy-alert-success.seealso .admonition-title, + .rst-content .wy-alert-success.seealso .wy-alert-title, + .rst-content .wy-alert-success.warning .admonition-title, + .rst-content .wy-alert-success.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-success .admonition-title, + .wy-alert.wy-alert-success .rst-content .admonition-title, + .wy-alert.wy-alert-success .wy-alert-title { + background-image: initial; + background-color: rgb(21, 150, 125); + } + .rst-content .wy-alert-neutral.admonition, + .rst-content .wy-alert-neutral.admonition-todo, + .rst-content .wy-alert-neutral.attention, + .rst-content .wy-alert-neutral.caution, + .rst-content .wy-alert-neutral.danger, + .rst-content .wy-alert-neutral.error, + .rst-content .wy-alert-neutral.hint, + .rst-content .wy-alert-neutral.important, + .rst-content .wy-alert-neutral.note, + .rst-content .wy-alert-neutral.seealso, + .rst-content .wy-alert-neutral.tip, + .rst-content .wy-alert-neutral.warning, + .wy-alert.wy-alert-neutral { + background-image: initial; + background-color: rgb(27, 36, 36); + } + .rst-content .wy-alert-neutral.admonition-todo .admonition-title, + .rst-content .wy-alert-neutral.admonition-todo .wy-alert-title, + .rst-content .wy-alert-neutral.admonition .admonition-title, + .rst-content .wy-alert-neutral.admonition .wy-alert-title, + .rst-content .wy-alert-neutral.attention .admonition-title, + .rst-content .wy-alert-neutral.attention .wy-alert-title, + .rst-content .wy-alert-neutral.caution .admonition-title, + .rst-content .wy-alert-neutral.caution .wy-alert-title, + .rst-content .wy-alert-neutral.danger .admonition-title, + .rst-content .wy-alert-neutral.danger .wy-alert-title, + .rst-content .wy-alert-neutral.error .admonition-title, + .rst-content .wy-alert-neutral.error .wy-alert-title, + .rst-content .wy-alert-neutral.hint .admonition-title, + .rst-content .wy-alert-neutral.hint .wy-alert-title, + .rst-content .wy-alert-neutral.important .admonition-title, + .rst-content .wy-alert-neutral.important .wy-alert-title, + .rst-content .wy-alert-neutral.note .admonition-title, + .rst-content .wy-alert-neutral.note .wy-alert-title, + .rst-content .wy-alert-neutral.seealso .admonition-title, + .rst-content .wy-alert-neutral.seealso .wy-alert-title, + .rst-content .wy-alert-neutral.tip .admonition-title, + .rst-content .wy-alert-neutral.tip .wy-alert-title, + .rst-content .wy-alert-neutral.warning .admonition-title, + .rst-content .wy-alert-neutral.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-neutral .admonition-title, + .wy-alert.wy-alert-neutral .rst-content .admonition-title, + .wy-alert.wy-alert-neutral .wy-alert-title { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(40, 43, 45); + } + .rst-content .wy-alert-neutral.admonition-todo a, + .rst-content .wy-alert-neutral.admonition a, + .rst-content .wy-alert-neutral.attention a, + .rst-content .wy-alert-neutral.caution a, + .rst-content .wy-alert-neutral.danger a, + .rst-content .wy-alert-neutral.error a, + .rst-content .wy-alert-neutral.hint a, + .rst-content .wy-alert-neutral.important a, + .rst-content .wy-alert-neutral.note a, + .rst-content .wy-alert-neutral.seealso a, + .rst-content .wy-alert-neutral.tip a, + .rst-content .wy-alert-neutral.warning a, + .wy-alert.wy-alert-neutral a { + color: rgb(84, 164, 217); + } + .wy-tray-container li { + background-image: initial; + background-color: transparent; + color: rgb(232, 230, 227); + box-shadow: rgba(0, 0, 0, 0.1) 0px 5px 5px 0px; + } + .wy-tray-container li.wy-tray-item-success { + background-image: initial; + background-color: rgb(31, 139, 77); + } + .wy-tray-container li.wy-tray-item-info { + background-image: initial; + background-color: rgb(33, 102, 148); + } + .wy-tray-container li.wy-tray-item-warning { + background-image: initial; + background-color: rgb(178, 94, 20); + } + .wy-tray-container li.wy-tray-item-danger { + background-image: initial; + background-color: rgb(162, 33, 20); + } + .btn { + color: rgb(232, 230, 227); + border-color: rgba(140, 130, 115, 0.1); + background-color: rgb(31, 139, 77); + text-decoration-color: initial; + box-shadow: rgba(24, 26, 27, 0.5) 0px 1px 2px -1px inset, + rgba(0, 0, 0, 0.1) 0px -2px 0px 0px inset; + } + .btn-hover { + background-image: initial; + background-color: rgb(37, 114, 165); + color: rgb(232, 230, 227); + } + .btn:hover { + background-image: initial; + background-color: rgb(35, 156, 86); + color: rgb(232, 230, 227); + } + .btn:focus { + background-image: initial; + background-color: rgb(35, 156, 86); + outline-color: initial; + } + .btn:active { + box-shadow: rgba(0, 0, 0, 0.05) 0px -1px 0px 0px inset, + rgba(0, 0, 0, 0.1) 0px 2px 0px 0px inset; + } + .btn:visited { + color: rgb(232, 230, 227); + } + .btn-disabled, + .btn-disabled:active, + .btn-disabled:focus, + .btn-disabled:hover, + .btn:disabled { + background-image: none; + box-shadow: none; + } + .btn-info { + background-color: rgb(33, 102, 148) !important; + } + .btn-info:hover { + background-color: rgb(37, 114, 165) !important; + } + .btn-neutral { + background-color: rgb(27, 36, 36) !important; + color: rgb(192, 186, 178) !important; + } + .btn-neutral:hover { + color: rgb(192, 186, 178); + background-color: rgb(34, 44, 44) !important; + } + .btn-neutral:visited { + color: rgb(192, 186, 178) !important; + } + .btn-success { + background-color: rgb(31, 139, 77) !important; + } + .btn-success:hover { + background-color: rgb(27, 122, 68) !important; + } + .btn-danger { + background-color: rgb(162, 33, 20) !important; + } + .btn-danger:hover { + background-color: rgb(149, 30, 18) !important; + } + .btn-warning { + background-color: rgb(178, 94, 20) !important; + } + .btn-warning:hover { + background-color: rgb(165, 87, 18) !important; + } + .btn-invert { + background-color: rgb(26, 28, 29); + } + .btn-invert:hover { + background-color: rgb(35, 38, 40) !important; + } + .btn-link { + color: rgb(84, 164, 217); + box-shadow: none; + background-color: transparent !important; + border-color: transparent !important; + } + .btn-link:active, + .btn-link:hover { + box-shadow: none; + background-color: transparent !important; + color: rgb(79, 162, 216) !important; + } + .btn-link:visited { + color: rgb(164, 103, 188); + } + .wy-dropdown-menu { + background-image: initial; + background-color: rgb(26, 28, 29); + border-color: rgb(60, 65, 67); + box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 2px 0px; + } + .wy-dropdown-menu > dd > a { + color: rgb(192, 186, 178); + } + .wy-dropdown-menu > dd > a:hover { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + .wy-dropdown-menu > dd.divider { + border-top-color: rgb(60, 65, 67); + } + .wy-dropdown-menu > dd.call-to-action { + background-image: initial; + background-color: rgb(40, 43, 45); + } + .wy-dropdown-menu > dd.call-to-action:hover { + background-image: initial; + background-color: rgb(40, 43, 45); + } + .wy-dropdown-menu > dd.call-to-action .btn { + color: rgb(232, 230, 227); + } + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + .wy-dropdown-arrow::before { + border-bottom-color: rgb(51, 55, 57); + border-left-color: transparent; + border-right-color: transparent; + } + fieldset, + legend { + border-color: initial; + } + label { + color: rgb(200, 195, 188); + } + .wy-control-group.wy-control-group-required > label::after { + color: rgb(233, 88, 73); + } + .wy-form-message-inline { + color: rgb(168, 160, 149); + } + .wy-form-message { + color: rgb(168, 160, 149); + } + input[type="color"], input[type="date"], input[type="datetime-local"], input[type="datetime"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"] { + border-color: rgb(62, 68, 70); + box-shadow: rgb(43, 47, 49) 0px 1px 3px inset; + } + input[type="color"]:focus, input[type="date"]:focus, input[type="datetime-local"]:focus, input[type="datetime"]:focus, input[type="email"]:focus, input[type="month"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus { + outline-color: initial; + border-color: rgb(123, 114, 101); + } + input.no-focus:focus { + border-color: rgb(62, 68, 70) !important; + } + input[type="checkbox"]:focus, input[type="file"]:focus, input[type="radio"]:focus { + outline-color: rgb(13, 113, 167); + } + input[type="color"][disabled], input[type="date"][disabled], input[type="datetime-local"][disabled], input[type="datetime"][disabled], input[type="email"][disabled], input[type="month"][disabled], input[type="number"][disabled], input[type="password"][disabled], input[type="search"][disabled], input[type="tel"][disabled], input[type="text"][disabled], input[type="time"][disabled], input[type="url"][disabled], input[type="week"][disabled] { + background-color: rgb(27, 29, 30); + } + input:focus:invalid, + select:focus:invalid, + textarea:focus:invalid { + color: rgb(233, 88, 73); + border-color: rgb(149, 31, 18); + } + input:focus:invalid:focus, + select:focus:invalid:focus, + textarea:focus:invalid:focus { + border-color: rgb(149, 31, 18); + } + input[type="checkbox"]:focus:invalid:focus, input[type="file"]:focus:invalid:focus, input[type="radio"]:focus:invalid:focus { + outline-color: rgb(149, 31, 18); + } + select, + textarea { + border-color: rgb(62, 68, 70); + box-shadow: rgb(43, 47, 49) 0px 1px 3px inset; + } + select { + border-color: rgb(62, 68, 70); + background-color: rgb(24, 26, 27); + } + select:focus, + textarea:focus { + outline-color: initial; + } + input[readonly], + select[disabled], + select[readonly], + textarea[disabled], + textarea[readonly] { + background-color: rgb(27, 29, 30); + } + .wy-checkbox, + .wy-radio { + color: rgb(192, 186, 178); + } + .wy-input-prefix .wy-input-context, + .wy-input-suffix .wy-input-context { + background-color: rgb(27, 36, 36); + border-color: rgb(62, 68, 70); + color: rgb(168, 160, 149); + } + .wy-input-suffix .wy-input-context { + border-left-color: initial; + } + .wy-input-prefix .wy-input-context { + border-right-color: initial; + } + .wy-switch::before { + background-image: initial; + background-color: rgb(53, 57, 59); + } + .wy-switch::after { + background-image: initial; + background-color: rgb(82, 88, 92); + } + .wy-switch span { + color: rgb(200, 195, 188); + } + .wy-switch.active::before { + background-image: initial; + background-color: rgb(24, 106, 58); + } + .wy-switch.active::after { + background-image: initial; + background-color: rgb(31, 139, 77); + } + .wy-control-group.wy-control-group-error .wy-form-message, + .wy-control-group.wy-control-group-error > label { + color: rgb(233, 88, 73); + } + .wy-control-group.wy-control-group-error input[type="color"], .wy-control-group.wy-control-group-error input[type="date"], .wy-control-group.wy-control-group-error input[type="datetime-local"], .wy-control-group.wy-control-group-error input[type="datetime"], .wy-control-group.wy-control-group-error input[type="email"], .wy-control-group.wy-control-group-error input[type="month"], .wy-control-group.wy-control-group-error input[type="number"], .wy-control-group.wy-control-group-error input[type="password"], .wy-control-group.wy-control-group-error input[type="search"], .wy-control-group.wy-control-group-error input[type="tel"], .wy-control-group.wy-control-group-error input[type="text"], .wy-control-group.wy-control-group-error input[type="time"], .wy-control-group.wy-control-group-error input[type="url"], .wy-control-group.wy-control-group-error input[type="week"], + .wy-control-group.wy-control-group-error textarea { + border-color: rgb(149, 31, 18); + } + .wy-inline-validate.wy-inline-validate-success .wy-input-context { + color: rgb(92, 218, 145); + } + .wy-inline-validate.wy-inline-validate-danger .wy-input-context { + color: rgb(233, 88, 73); + } + .wy-inline-validate.wy-inline-validate-warning .wy-input-context { + color: rgb(232, 138, 54); + } + .wy-inline-validate.wy-inline-validate-info .wy-input-context { + color: rgb(84, 164, 217); + } + .rst-content table.docutils caption, + .rst-content table.field-list caption, + .wy-table caption { + color: rgb(232, 230, 227); + } + .rst-content table.docutils thead, + .rst-content table.field-list thead, + .wy-table thead { + color: rgb(232, 230, 227); + } + .rst-content table.docutils thead th, + .rst-content table.field-list thead th, + .wy-table thead th { + border-bottom-color: rgb(56, 61, 63); + } + .rst-content table.docutils td, + .rst-content table.field-list td, + .wy-table td { + background-color: transparent; + } + .wy-table-secondary { + color: rgb(152, 143, 129); + } + .wy-table-tertiary { + color: rgb(152, 143, 129); + } + .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td, + .wy-table-backed, + .wy-table-odd td, + .wy-table-striped tr:nth-child(2n-1) td { + background-color: rgb(27, 36, 36); + } + .rst-content table.docutils, + .wy-table-bordered-all { + border-color: rgb(56, 61, 63); + } + .rst-content table.docutils td, + .wy-table-bordered-all td { + border-bottom-color: rgb(56, 61, 63); + border-left-color: rgb(56, 61, 63); + } + .wy-table-bordered { + border-color: rgb(56, 61, 63); + } + .wy-table-bordered-rows td { + border-bottom-color: rgb(56, 61, 63); + } + .wy-table-horizontal td, + .wy-table-horizontal th { + border-bottom-color: rgb(56, 61, 63); + } + a { + color: rgb(84, 164, 217); + text-decoration-color: initial; + } + a:hover { + color: rgb(68, 156, 214); + } + a:visited { + color: rgb(164, 103, 188); + } + body { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(33, 35, 37); + } + .wy-text-strike { + text-decoration-color: initial; + } + .wy-text-warning { + color: rgb(232, 138, 54) !important; + } + a.wy-text-warning:hover { + color: rgb(236, 157, 87) !important; + } + .wy-text-info { + color: rgb(84, 164, 217) !important; + } + a.wy-text-info:hover { + color: rgb(79, 162, 216) !important; + } + .wy-text-success { + color: rgb(92, 218, 145) !important; + } + a.wy-text-success:hover { + color: rgb(73, 214, 133) !important; + } + .wy-text-danger { + color: rgb(233, 88, 73) !important; + } + a.wy-text-danger:hover { + color: rgb(237, 118, 104) !important; + } + .wy-text-neutral { + color: rgb(192, 186, 178) !important; + } + a.wy-text-neutral:hover { + color: rgb(176, 169, 159) !important; + } + hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(56, 61, 63); + } + .rst-content code, + .rst-content tt, + code { + background-image: initial; + background-color: rgb(24, 26, 27); + border-color: rgb(56, 61, 63); + color: rgb(233, 88, 73); + } + .rst-content .section ul, + .rst-content .toctree-wrapper ul, + .rst-content section ul, + .wy-plain-list-disc, + article ul { + list-style-image: initial; + } + .rst-content .section ul li, + .rst-content .toctree-wrapper ul li, + .rst-content section ul li, + .wy-plain-list-disc li, + article ul li { + list-style-image: initial; + } + .rst-content .section ul li li, + .rst-content .toctree-wrapper ul li li, + .rst-content section ul li li, + .wy-plain-list-disc li li, + article ul li li { + list-style-image: initial; + } + .rst-content .section ul li li li, + .rst-content .toctree-wrapper ul li li li, + .rst-content section ul li li li, + .wy-plain-list-disc li li li, + article ul li li li { + list-style-image: initial; + } + .rst-content .section ul li ol li, + .rst-content .toctree-wrapper ul li ol li, + .rst-content section ul li ol li, + .wy-plain-list-disc li ol li, + article ul li ol li { + list-style-image: initial; + } + .rst-content .section ol, + .rst-content .section ol.arabic, + .rst-content .toctree-wrapper ol, + .rst-content .toctree-wrapper ol.arabic, + .rst-content section ol, + .rst-content section ol.arabic, + .wy-plain-list-decimal, + article ol { + list-style-image: initial; + } + .rst-content .section ol.arabic li, + .rst-content .section ol li, + .rst-content .toctree-wrapper ol.arabic li, + .rst-content .toctree-wrapper ol li, + .rst-content section ol.arabic li, + .rst-content section ol li, + .wy-plain-list-decimal li, + article ol li { + list-style-image: initial; + } + .rst-content .section ol.arabic li ul li, + .rst-content .section ol li ul li, + .rst-content .toctree-wrapper ol.arabic li ul li, + .rst-content .toctree-wrapper ol li ul li, + .rst-content section ol.arabic li ul li, + .rst-content section ol li ul li, + .wy-plain-list-decimal li ul li, + article ol li ul li { + list-style-image: initial; + } + .rst-content .wy-breadcrumbs li tt, + .wy-breadcrumbs li .rst-content tt, + .wy-breadcrumbs li code { + border-color: initial; + background-image: none; + background-color: initial; + } + .rst-content .wy-breadcrumbs li tt.literal, + .wy-breadcrumbs li .rst-content tt.literal, + .wy-breadcrumbs li code.literal { + color: rgb(192, 186, 178); + } + .wy-breadcrumbs-extra { + color: rgb(184, 178, 169); + } + .wy-menu a:hover { + text-decoration-color: initial; + } + .wy-menu-horiz li:hover { + background-image: initial; + background-color: rgba(24, 26, 27, 0.1); + } + .wy-menu-horiz li.divide-left { + border-left-color: rgb(119, 110, 98); + } + .wy-menu-horiz li.divide-right { + border-right-color: rgb(119, 110, 98); + } + .wy-menu-vertical header, + .wy-menu-vertical p.caption { + color: rgb(94, 170, 219); + } + .wy-menu-vertical li.divide-top { + border-top-color: rgb(119, 110, 98); + } + .wy-menu-vertical li.divide-bottom { + border-bottom-color: rgb(119, 110, 98); + } + .wy-menu-vertical li.current { + background-image: initial; + background-color: rgb(40, 43, 45); + } + .wy-menu-vertical li.current a { + color: rgb(152, 143, 129); + border-right-color: rgb(63, 69, 71); + } + .wy-menu-vertical li.current a:hover { + background-image: initial; + background-color: rgb(47, 51, 53); + } + .rst-content .wy-menu-vertical li tt, + .wy-menu-vertical li .rst-content tt, + .wy-menu-vertical li code { + border-color: initial; + background-image: inherit; + background-color: inherit; + color: inherit; + } + .wy-menu-vertical li button.toctree-expand { + color: rgb(183, 177, 168); + border-color: initial; + background-image: none; + background-color: initial; + } + .wy-menu-vertical li.current > a, + .wy-menu-vertical li.on a { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(26, 28, 29); + border-color: initial; + } + .wy-menu-vertical li.current > a:hover, + .wy-menu-vertical li.on a:hover { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .wy-menu-vertical li.current > a:hover button.toctree-expand, + .wy-menu-vertical li.on a:hover button.toctree-expand { + color: rgb(152, 143, 129); + } + .wy-menu-vertical li.current > a button.toctree-expand, + .wy-menu-vertical li.on a button.toctree-expand { + color: rgb(200, 195, 188); + } + .wy-menu-vertical li.toctree-l1.current > a { + border-bottom-color: rgb(63, 69, 71); + border-top-color: rgb(63, 69, 71); + } + .wy-menu-vertical li.toctree-l2 a, + .wy-menu-vertical li.toctree-l3 a, + .wy-menu-vertical li.toctree-l4 a, + .wy-menu-vertical li.toctree-l5 a, + .wy-menu-vertical li.toctree-l6 a, + .wy-menu-vertical li.toctree-l7 a, + .wy-menu-vertical li.toctree-l8 a, + .wy-menu-vertical li.toctree-l9 a, + .wy-menu-vertical li.toctree-l10 a { + color: rgb(192, 186, 178); + } + .wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand, + .wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand { + color: rgb(152, 143, 129); + } + .wy-menu-vertical li.toctree-l2.current > a, + .wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a { + background-image: initial; + background-color: rgb(54, 59, 61); + } + .wy-menu-vertical li.toctree-l2 button.toctree-expand { + color: rgb(174, 167, 156); + } + .wy-menu-vertical li.toctree-l3.current > a, + .wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a { + background-image: initial; + background-color: rgb(61, 66, 69); + } + .wy-menu-vertical li.toctree-l3 button.toctree-expand { + color: rgb(166, 158, 146); + } + .wy-menu-vertical li ul li a { + color: rgb(208, 204, 198); + } + .wy-menu-vertical a { + color: rgb(208, 204, 198); + } + .wy-menu-vertical a:hover { + background-color: rgb(57, 62, 64); + } + .wy-menu-vertical a:hover button.toctree-expand { + color: rgb(208, 204, 198); + } + .wy-menu-vertical a:active { + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + .wy-menu-vertical a:active button.toctree-expand { + color: rgb(232, 230, 227); + } + .wy-side-nav-search { + background-color: rgb(33, 102, 148); + color: rgb(230, 228, 225); + } + .wy-side-nav-search input[type="text"] { + border-color: rgb(35, 111, 160); + } + .wy-side-nav-search img { + background-color: rgb(33, 102, 148); + } + .wy-side-nav-search .wy-dropdown > a, + .wy-side-nav-search > a { + color: rgb(230, 228, 225); + } + .wy-side-nav-search .wy-dropdown > a:hover, + .wy-side-nav-search > a:hover { + background-image: initial; + background-color: rgba(24, 26, 27, 0.1); + } + .wy-side-nav-search .wy-dropdown > a img.logo, + .wy-side-nav-search > a img.logo { + background-image: initial; + background-color: transparent; + } + .wy-side-nav-search > div.version { + color: rgba(232, 230, 227, 0.3); + } + .wy-nav .wy-menu-vertical header { + color: rgb(84, 164, 217); + } + .wy-nav .wy-menu-vertical a { + color: rgb(184, 178, 169); + } + .wy-nav .wy-menu-vertical a:hover { + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + .wy-body-for-nav { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .wy-nav-side { + color: rgb(169, 161, 150); + background-image: initial; + background-color: rgb(38, 41, 43); + } + .wy-nav-top { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + .wy-nav-top a { + color: rgb(232, 230, 227); + } + .wy-nav-top img { + background-color: rgb(33, 102, 148); + } + .wy-nav-content-wrap { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .wy-body-mask { + background-image: initial; + background-color: rgba(0, 0, 0, 0.2); + } + footer { + color: rgb(152, 143, 129); + } + .rst-content footer span.commit tt, + footer span.commit .rst-content tt, + footer span.commit code { + background-image: none; + background-color: initial; + border-color: initial; + color: rgb(152, 143, 129); + } + #search-results .search li { + border-bottom-color: rgb(56, 61, 63); + } + #search-results .search li:first-child { + border-top-color: rgb(56, 61, 63); + } + #search-results .context { + color: rgb(152, 143, 129); + } + @media screen and (max-width: 768px) { + .wy-body-for-nav { + background-image: initial; + background-color: rgb(26, 28, 29); + } + } + @media screen and (min-width: 1100px) { + .wy-nav-content-wrap { + background-image: initial; + background-color: rgba(0, 0, 0, 0.05); + } + .wy-nav-content { + background-image: initial; + background-color: rgb(26, 28, 29); + } + } + .rst-versions { + color: rgb(230, 228, 225); + background-image: initial; + background-color: rgb(23, 24, 25); + } + .rst-versions a { + color: rgb(84, 164, 217); + text-decoration-color: initial; + } + .rst-versions .rst-current-version { + background-color: rgb(29, 31, 32); + color: rgb(92, 218, 145); + } + .rst-content .code-block-caption .rst-versions .rst-current-version .headerlink, + .rst-content .eqno .rst-versions .rst-current-version .headerlink, + .rst-content .rst-versions .rst-current-version .admonition-title, + .rst-content code.download .rst-versions .rst-current-version span:first-child, + .rst-content dl dt .rst-versions .rst-current-version .headerlink, + .rst-content h1 .rst-versions .rst-current-version .headerlink, + .rst-content h2 .rst-versions .rst-current-version .headerlink, + .rst-content h3 .rst-versions .rst-current-version .headerlink, + .rst-content h4 .rst-versions .rst-current-version .headerlink, + .rst-content h5 .rst-versions .rst-current-version .headerlink, + .rst-content h6 .rst-versions .rst-current-version .headerlink, + .rst-content p .rst-versions .rst-current-version .headerlink, + .rst-content table > caption .rst-versions .rst-current-version .headerlink, + .rst-content tt.download .rst-versions .rst-current-version span:first-child, + .rst-versions .rst-current-version .fa, + .rst-versions .rst-current-version .icon, + .rst-versions .rst-current-version .rst-content .admonition-title, + .rst-versions .rst-current-version .rst-content .code-block-caption .headerlink, + .rst-versions .rst-current-version .rst-content .eqno .headerlink, + .rst-versions .rst-current-version .rst-content code.download span:first-child, + .rst-versions .rst-current-version .rst-content dl dt .headerlink, + .rst-versions .rst-current-version .rst-content h1 .headerlink, + .rst-versions .rst-current-version .rst-content h2 .headerlink, + .rst-versions .rst-current-version .rst-content h3 .headerlink, + .rst-versions .rst-current-version .rst-content h4 .headerlink, + .rst-versions .rst-current-version .rst-content h5 .headerlink, + .rst-versions .rst-current-version .rst-content h6 .headerlink, + .rst-versions .rst-current-version .rst-content p .headerlink, + .rst-versions .rst-current-version .rst-content table > caption .headerlink, + .rst-versions .rst-current-version .rst-content tt.download span:first-child, + .rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand, + .wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand { + color: rgb(230, 228, 225); + } + .rst-versions .rst-current-version.rst-out-of-date { + background-color: rgb(162, 33, 20); + color: rgb(232, 230, 227); + } + .rst-versions .rst-current-version.rst-active-old-version { + background-color: rgb(192, 156, 11); + color: rgb(232, 230, 227); + } + .rst-versions .rst-other-versions { + color: rgb(152, 143, 129); + } + .rst-versions .rst-other-versions hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(119, 111, 98); + } + .rst-versions .rst-other-versions dd a { + color: rgb(230, 228, 225); + } + .rst-versions.rst-badge { + border-color: initial; + } + .rst-content abbr[title] { + text-decoration-color: initial; + } + .rst-content.style-external-links a.reference.external::after { + color: rgb(184, 178, 169); + } + .rst-content div[class^="highlight"], + .rst-content pre.literal-block { + border-color: rgb(56, 61, 63); + } + .rst-content div[class^="highlight"] div[class^="highlight"], .rst-content pre.literal-block div[class^="highlight"] { + border-color: initial; + } + .rst-content .linenodiv pre { + border-right-color: rgb(54, 59, 61); + } + .rst-content div.highlight span.linenos { + border-right-color: rgb(54, 59, 61); + } + .rst-content .admonition table { + border-color: rgba(140, 130, 115, 0.1); + } + .rst-content .admonition table td, + .rst-content .admonition table th { + background-image: initial !important; + background-color: transparent !important; + border-color: rgba(140, 130, 115, 0.1) !important; + } + .rst-content .section ol.loweralpha, + .rst-content .section ol.loweralpha > li, + .rst-content .toctree-wrapper ol.loweralpha, + .rst-content .toctree-wrapper ol.loweralpha > li, + .rst-content section ol.loweralpha, + .rst-content section ol.loweralpha > li { + list-style-image: initial; + } + .rst-content .section ol.upperalpha, + .rst-content .section ol.upperalpha > li, + .rst-content .toctree-wrapper ol.upperalpha, + .rst-content .toctree-wrapper ol.upperalpha > li, + .rst-content section ol.upperalpha, + .rst-content section ol.upperalpha > li { + list-style-image: initial; + } + .rst-content .toc-backref { + color: rgb(192, 186, 178); + } + .rst-content .btn:focus { + outline-color: initial; + } + .rst-content .sidebar { + background-image: initial; + background-color: rgb(27, 36, 36); + border-color: rgb(56, 61, 63); + } + .rst-content .sidebar .sidebar-title { + background-image: initial; + background-color: rgb(40, 43, 45); + } + .rst-content .highlighted { + background-image: initial; + background-color: rgb(192, 156, 11); + box-shadow: rgb(192, 156, 11) 0px 0px 0px 2px; + } + html.writer-html4 .rst-content table.docutils.citation, + html.writer-html4 .rst-content table.docutils.footnote { + background-image: none; + background-color: initial; + border-color: initial; + } + html.writer-html4 .rst-content table.docutils.citation td, + html.writer-html4 .rst-content table.docutils.citation tr, + html.writer-html4 .rst-content table.docutils.footnote td, + html.writer-html4 .rst-content table.docutils.footnote tr { + border-color: initial; + background-color: transparent !important; + } + .rst-content table.docutils.footnote, + html.writer-html4 .rst-content table.docutils.citation, + html.writer-html5 .rst-content dl.footnote { + color: rgb(152, 143, 129); + } + .rst-content table.docutils.footnote code, + .rst-content table.docutils.footnote tt, + html.writer-html4 .rst-content table.docutils.citation code, + html.writer-html4 .rst-content table.docutils.citation tt, + html.writer-html5 .rst-content dl.footnote code, + html.writer-html5 .rst-content dl.footnote tt { + color: rgb(178, 172, 162); + } + .rst-content table.docutils th { + border-color: rgb(56, 61, 63); + } + html.writer-html5 .rst-content table.docutils th { + border-color: rgb(56, 61, 63); + } + .rst-content table.field-list, + .rst-content table.field-list td { + border-color: initial; + } + .rst-content code, + .rst-content tt { + color: rgb(232, 230, 227); + } + .rst-content code.literal, + .rst-content tt.literal { + color: rgb(233, 88, 73); + } + .rst-content code.xref, + .rst-content tt.xref, + a .rst-content code, + a .rst-content tt { + color: rgb(192, 186, 178); + } + .rst-content a code, + .rst-content a tt { + color: rgb(84, 164, 217); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt { + background-image: initial; + background-color: rgb(32, 35, 36); + color: rgb(84, 164, 217); + border-top-color: rgb(28, 89, 128); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt::before, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt::before { + color: rgb(109, 178, 223); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt .headerlink, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt .headerlink { + color: rgb(192, 186, 178); + } + html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list) > dt, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list) > dt { + border-top-color: initial; + border-right-color: initial; + border-bottom-color: initial; + border-left-color: rgb(62, 68, 70); + background-image: initial; + background-color: rgb(32, 35, 37); + color: rgb(178, 172, 162); + } + html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list) > dt .headerlink, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list) > dt .headerlink { + color: rgb(192, 186, 178); + } + html.writer-html4 .rst-content dl:not(.docutils) code.descclassname, + html.writer-html4 .rst-content dl:not(.docutils) code.descname, + html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname, + html.writer-html4 .rst-content dl:not(.docutils) tt.descname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname { + background-color: transparent; + border-color: initial; + } + html.writer-html4 .rst-content dl:not(.docutils) .optional, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional { + color: rgb(232, 230, 227); + } + html.writer-html4 .rst-content dl:not(.docutils) .descclassname, + html.writer-html4 .rst-content dl:not(.docutils) .descname, + html.writer-html4 .rst-content dl:not(.docutils) .sig-name, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descclassname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name { + color: rgb(232, 230, 227); + } + .rst-content .viewcode-back, + .rst-content .viewcode-link { + color: rgb(92, 218, 145); + } + .rst-content code.download, + .rst-content tt.download { + background-image: inherit; + background-color: inherit; + color: inherit; + border-color: inherit; + } + .rst-content .guilabel { + border-color: rgb(27, 84, 122); + background-image: initial; + background-color: rgb(32, 35, 36); + } + span[id*="MathJax-Span"] { + color: rgb(192, 186, 178); + } + td.linenos .normal { + color: inherit; + background-color: transparent; + } + span.linenos { + color: inherit; + background-color: transparent; + } + td.linenos .special { + color: rgb(232, 230, 227); + background-color: rgb(89, 89, 0); + } + span.linenos.special { + color: rgb(232, 230, 227); + background-color: rgb(89, 89, 0); + } + .highlight .hll { + background-color: rgb(82, 82, 0); + } + .highlight { + background-image: initial; + background-color: rgb(61, 82, 0); + } + .highlight .c { + color: rgb(119, 179, 195); + } + .highlight .err { + border-color: rgb(179, 0, 0); + } + .highlight .k { + color: rgb(126, 255, 163); + } + .highlight .o { + color: rgb(168, 160, 149); + } + .highlight .ch { + color: rgb(119, 179, 195); + } + .highlight .cm { + color: rgb(119, 179, 195); + } + .highlight .cp { + color: rgb(126, 255, 163); + } + .highlight .cpf { + color: rgb(119, 179, 195); + } + .highlight .c1 { + color: rgb(119, 179, 195); + } + .highlight .cs { + color: rgb(119, 179, 195); + background-color: rgb(60, 0, 0); + } + .highlight .gd { + color: rgb(255, 92, 92); + } + .highlight .gr { + color: rgb(255, 26, 26); + } + .highlight .gh { + color: rgb(127, 174, 255); + } + .highlight .gi { + color: rgb(92, 255, 92); + } + .highlight .go { + color: rgb(200, 195, 188); + } + .highlight .gp { + color: rgb(246, 147, 68); + } + .highlight .gu { + color: rgb(255, 114, 255); + } + .highlight .gt { + color: rgb(71, 160, 255); + } + .highlight .kc { + color: rgb(126, 255, 163); + } + .highlight .kd { + color: rgb(126, 255, 163); + } + .highlight .kn { + color: rgb(126, 255, 163); + } + .highlight .kp { + color: rgb(126, 255, 163); + } + .highlight .kr { + color: rgb(126, 255, 163); + } + .highlight .kt { + color: rgb(255, 137, 103); + } + .highlight .m { + color: rgb(125, 222, 174); + } + .highlight .s { + color: rgb(123, 166, 202); + } + .highlight .na { + color: rgb(123, 166, 202); + } + .highlight .nb { + color: rgb(126, 255, 163); + } + .highlight .nc { + color: rgb(81, 194, 242); + } + .highlight .no { + color: rgb(103, 177, 215); + } + .highlight .nd { + color: rgb(178, 172, 162); + } + .highlight .ni { + color: rgb(217, 100, 73); + } + .highlight .ne { + color: rgb(126, 255, 163); + } + .highlight .nf { + color: rgb(131, 186, 249); + } + .highlight .nl { + color: rgb(137, 193, 255); + } + .highlight .nn { + color: rgb(81, 194, 242); + } + .highlight .nt { + color: rgb(138, 191, 249); + } + .highlight .nv { + color: rgb(190, 103, 215); + } + .highlight .ow { + color: rgb(126, 255, 163); + } + .highlight .w { + color: rgb(189, 183, 175); + } + .highlight .mb { + color: rgb(125, 222, 174); + } + .highlight .mf { + color: rgb(125, 222, 174); + } + .highlight .mh { + color: rgb(125, 222, 174); + } + .highlight .mi { + color: rgb(125, 222, 174); + } + .highlight .mo { + color: rgb(125, 222, 174); + } + .highlight .sa { + color: rgb(123, 166, 202); + } + .highlight .sb { + color: rgb(123, 166, 202); + } + .highlight .sc { + color: rgb(123, 166, 202); + } + .highlight .dl { + color: rgb(123, 166, 202); + } + .highlight .sd { + color: rgb(123, 166, 202); + } + .highlight .s2 { + color: rgb(123, 166, 202); + } + .highlight .se { + color: rgb(123, 166, 202); + } + .highlight .sh { + color: rgb(123, 166, 202); + } + .highlight .si { + color: rgb(117, 168, 209); + } + .highlight .sx { + color: rgb(246, 147, 68); + } + .highlight .sr { + color: rgb(133, 182, 224); + } + .highlight .s1 { + color: rgb(123, 166, 202); + } + .highlight .ss { + color: rgb(188, 230, 128); + } + .highlight .bp { + color: rgb(126, 255, 163); + } + .highlight .fm { + color: rgb(131, 186, 249); + } + .highlight .vc { + color: rgb(190, 103, 215); + } + .highlight .vg { + color: rgb(190, 103, 215); + } + .highlight .vi { + color: rgb(190, 103, 215); + } + .highlight .vm { + color: rgb(190, 103, 215); + } + .highlight .il { + color: rgb(125, 222, 174); + } + [role="tablist"] { + border-bottom-color: rgb(70, 76, 79); + } + .sphinx-tabs-tab { + color: rgb(119, 182, 226); + background-color: rgba(24, 26, 27, 0); border-color: initial; + } + .sphinx-tabs-tab[aria-selected="true"] { + border-color: rgb(70, 76, 79) rgb(70, 76, 79) rgb(48, 52, 54); + background-color: rgb(24, 26, 27); + } + .sphinx-tabs-panel { + border-right-color: rgb(70, 76, 79); + border-bottom-color: rgb(70, 76, 79); + border-left-color: rgb(70, 76, 79); + border-top-color: initial; + background-image: initial; + background-color: rgb(24, 26, 27); + } + a.copybtn { + border-color: initial; + } + .o-tooltip--left::after { + background-image: initial; + background-color: rgb(96, 104, 108); + color: rgb(232, 230, 227); + } + @media (prefers-color-scheme: dark) { + html { + background-color: rgb(19, 21, 22) !important; + } + html, + body, + input, + textarea, + select, + button { + background-color: rgb(19, 21, 22); + } + html, + body, + input, + textarea, + select, + button { + border-color: rgb(106, 98, 87); + color: rgb(216, 212, 207); + } + a { + color: rgb(61, 165, 255); + } + table { + border-color: rgb(111, 103, 91); + } + ::placeholder { + color: rgb(178, 171, 161); + } + input:-webkit-autofill, + textarea:-webkit-autofill, + select:-webkit-autofill { + background-color: rgb(68, 73, 0) !important; + color: rgb(216, 212, 207) !important; + } + ::selection { + background-color: rgb(0, 62, 136) !important; + color: rgb(216, 212, 207) !important; + } + :root { + --darkreader-neutral-background: #131516; + --darkreader-text--darkreader-neutral-text: #cdc8c2; + --darkreader-selection-background: #004daa; + --darkreader-selection-text: #e8e6e3; + } + a:active, + a:hover { + outline-color: initial; + } + abbr[title] { + border-bottom-color: initial; + } + ins { + background-image: initial; + background-color: rgb(90, 90, 0); + text-decoration-color: initial; + } + ins, + mark { + color: rgb(216, 212, 207); + } + mark { + background-image: initial; + background-color: rgb(163, 163, 0); + } + dl, + ol, + ul { + list-style-image: none; + } + li { + list-style-image: initial; + } + img { + border-color: initial; + } + .chromeframe { + background-image: initial; + background-color: rgb(42, 46, 47); + color: rgb(216, 212, 207); + } + .ir { + border-color: initial; + background-color: transparent; + } + .visuallyhidden { + border-color: initial; + } + .fa-border { + border-color: rgb(122, 113, 100); + } + .fa-inverse { + color: rgb(216, 212, 207); + } + .sr-only { + border-color: initial; + } + .fa::before, + .icon::before, + .rst-content .admonition-title::before, + .rst-content .code-block-caption .headerlink::before, + .rst-content code.download span:first-child::before, + .rst-content dl dt .headerlink::before, + .rst-content h1 .headerlink::before, + .rst-content h2 .headerlink::before, + .rst-content h3 .headerlink::before, + .rst-content h4 .headerlink::before, + .rst-content h5 .headerlink::before, + .rst-content h6 .headerlink::before, + .rst-content p.caption .headerlink::before, + .rst-content table > caption .headerlink::before, + .rst-content tt.download span:first-child::before, + .wy-dropdown .caret::before, + .wy-inline-validate.wy-inline-validate-danger .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-info .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-success .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-warning .wy-input-context::before, + .wy-menu-vertical li.current > a span.toctree-expand::before, + .wy-menu-vertical li.on a span.toctree-expand::before, + .wy-menu-vertical li span.toctree-expand::before { + text-decoration-color: inherit; + } + .rst-content .code-block-caption a .headerlink, + .rst-content a .admonition-title, + .rst-content code.download a span:first-child, + .rst-content dl dt a .headerlink, + .rst-content h1 a .headerlink, + .rst-content h2 a .headerlink, + .rst-content h3 a .headerlink, + .rst-content h4 a .headerlink, + .rst-content h5 a .headerlink, + .rst-content h6 a .headerlink, + .rst-content p.caption a .headerlink, + .rst-content table > caption a .headerlink, + .rst-content tt.download a span:first-child, + .wy-menu-vertical li.current > a span.toctree-expand, + .wy-menu-vertical li.on a span.toctree-expand, + .wy-menu-vertical li a span.toctree-expand, + a .fa, + a .icon, + a .rst-content .admonition-title, + a .rst-content .code-block-caption .headerlink, + a .rst-content code.download span:first-child, + a .rst-content dl dt .headerlink, + a .rst-content h1 .headerlink, + a .rst-content h2 .headerlink, + a .rst-content h3 .headerlink, + a .rst-content h4 .headerlink, + a .rst-content h5 .headerlink, + a .rst-content h6 .headerlink, + a .rst-content p.caption .headerlink, + a .rst-content table > caption .headerlink, + a .rst-content tt.download span:first-child, + a .wy-menu-vertical li span.toctree-expand { + text-decoration-color: inherit; + } + .rst-content .admonition, + .rst-content .admonition-todo, + .rst-content .attention, + .rst-content .caution, + .rst-content .danger, + .rst-content .error, + .rst-content .hint, + .rst-content .important, + .rst-content .note, + .rst-content .seealso, + .rst-content .tip, + .rst-content .warning, + .wy-alert { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .rst-content .admonition-title, + .wy-alert-title { + color: rgb(216, 212, 207); + background-image: initial; + background-color: rgb(23, 73, 105); + } + .rst-content .danger, + .rst-content .error, + .rst-content .wy-alert-danger.admonition, + .rst-content .wy-alert-danger.admonition-todo, + .rst-content .wy-alert-danger.attention, + .rst-content .wy-alert-danger.caution, + .rst-content .wy-alert-danger.hint, + .rst-content .wy-alert-danger.important, + .rst-content .wy-alert-danger.note, + .rst-content .wy-alert-danger.seealso, + .rst-content .wy-alert-danger.tip, + .rst-content .wy-alert-danger.warning, + .wy-alert.wy-alert-danger { + background-image: initial; + background-color: rgb(42, 10, 6); + } + .rst-content .danger .admonition-title, + .rst-content .danger .wy-alert-title, + .rst-content .error .admonition-title, + .rst-content .error .wy-alert-title, + .rst-content .wy-alert-danger.admonition-todo .admonition-title, + .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, + .rst-content .wy-alert-danger.admonition .admonition-title, + .rst-content .wy-alert-danger.admonition .wy-alert-title, + .rst-content .wy-alert-danger.attention .admonition-title, + .rst-content .wy-alert-danger.attention .wy-alert-title, + .rst-content .wy-alert-danger.caution .admonition-title, + .rst-content .wy-alert-danger.caution .wy-alert-title, + .rst-content .wy-alert-danger.hint .admonition-title, + .rst-content .wy-alert-danger.hint .wy-alert-title, + .rst-content .wy-alert-danger.important .admonition-title, + .rst-content .wy-alert-danger.important .wy-alert-title, + .rst-content .wy-alert-danger.note .admonition-title, + .rst-content .wy-alert-danger.note .wy-alert-title, + .rst-content .wy-alert-danger.seealso .admonition-title, + .rst-content .wy-alert-danger.seealso .wy-alert-title, + .rst-content .wy-alert-danger.tip .admonition-title, + .rst-content .wy-alert-danger.tip .wy-alert-title, + .rst-content .wy-alert-danger.warning .admonition-title, + .rst-content .wy-alert-danger.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-danger .admonition-title, + .wy-alert.wy-alert-danger .rst-content .admonition-title, + .wy-alert.wy-alert-danger .wy-alert-title { + background-image: initial; + background-color: rgb(86, 18, 10); + } + .rst-content .admonition-todo, + .rst-content .attention, + .rst-content .caution, + .rst-content .warning, + .rst-content .wy-alert-warning.admonition, + .rst-content .wy-alert-warning.danger, + .rst-content .wy-alert-warning.error, + .rst-content .wy-alert-warning.hint, + .rst-content .wy-alert-warning.important, + .rst-content .wy-alert-warning.note, + .rst-content .wy-alert-warning.seealso, + .rst-content .wy-alert-warning.tip, + .wy-alert.wy-alert-warning { + background-image: initial; + background-color: rgb(66, 42, 0); + } + .rst-content .admonition-todo .admonition-title, + .rst-content .admonition-todo .wy-alert-title, + .rst-content .attention .admonition-title, + .rst-content .attention .wy-alert-title, + .rst-content .caution .admonition-title, + .rst-content .caution .wy-alert-title, + .rst-content .warning .admonition-title, + .rst-content .warning .wy-alert-title, + .rst-content .wy-alert-warning.admonition .admonition-title, + .rst-content .wy-alert-warning.admonition .wy-alert-title, + .rst-content .wy-alert-warning.danger .admonition-title, + .rst-content .wy-alert-warning.danger .wy-alert-title, + .rst-content .wy-alert-warning.error .admonition-title, + .rst-content .wy-alert-warning.error .wy-alert-title, + .rst-content .wy-alert-warning.hint .admonition-title, + .rst-content .wy-alert-warning.hint .wy-alert-title, + .rst-content .wy-alert-warning.important .admonition-title, + .rst-content .wy-alert-warning.important .wy-alert-title, + .rst-content .wy-alert-warning.note .admonition-title, + .rst-content .wy-alert-warning.note .wy-alert-title, + .rst-content .wy-alert-warning.seealso .admonition-title, + .rst-content .wy-alert-warning.seealso .wy-alert-title, + .rst-content .wy-alert-warning.tip .admonition-title, + .rst-content .wy-alert-warning.tip .wy-alert-title, + .rst-content .wy-alert.wy-alert-warning .admonition-title, + .wy-alert.wy-alert-warning .rst-content .admonition-title, + .wy-alert.wy-alert-warning .wy-alert-title { + background-image: initial; + background-color: rgb(98, 52, 11); + } + .rst-content .note, + .rst-content .seealso, + .rst-content .wy-alert-info.admonition, + .rst-content .wy-alert-info.admonition-todo, + .rst-content .wy-alert-info.attention, + .rst-content .wy-alert-info.caution, + .rst-content .wy-alert-info.danger, + .rst-content .wy-alert-info.error, + .rst-content .wy-alert-info.hint, + .rst-content .wy-alert-info.important, + .rst-content .wy-alert-info.tip, + .rst-content .wy-alert-info.warning, + .wy-alert.wy-alert-info { + background-image: initial; + background-color: rgb(26, 28, 29); + } + .rst-content .note .admonition-title, + .rst-content .note .wy-alert-title, + .rst-content .seealso .admonition-title, + .rst-content .seealso .wy-alert-title, + .rst-content .wy-alert-info.admonition-todo .admonition-title, + .rst-content .wy-alert-info.admonition-todo .wy-alert-title, + .rst-content .wy-alert-info.admonition .admonition-title, + .rst-content .wy-alert-info.admonition .wy-alert-title, + .rst-content .wy-alert-info.attention .admonition-title, + .rst-content .wy-alert-info.attention .wy-alert-title, + .rst-content .wy-alert-info.caution .admonition-title, + .rst-content .wy-alert-info.caution .wy-alert-title, + .rst-content .wy-alert-info.danger .admonition-title, + .rst-content .wy-alert-info.danger .wy-alert-title, + .rst-content .wy-alert-info.error .admonition-title, + .rst-content .wy-alert-info.error .wy-alert-title, + .rst-content .wy-alert-info.hint .admonition-title, + .rst-content .wy-alert-info.hint .wy-alert-title, + .rst-content .wy-alert-info.important .admonition-title, + .rst-content .wy-alert-info.important .wy-alert-title, + .rst-content .wy-alert-info.tip .admonition-title, + .rst-content .wy-alert-info.tip .wy-alert-title, + .rst-content .wy-alert-info.warning .admonition-title, + .rst-content .wy-alert-info.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-info .admonition-title, + .wy-alert.wy-alert-info .rst-content .admonition-title, + .wy-alert.wy-alert-info .wy-alert-title { + background-image: initial; + background-color: rgb(23, 73, 105); + } + .rst-content .hint, + .rst-content .important, + .rst-content .tip, + .rst-content .wy-alert-success.admonition, + .rst-content .wy-alert-success.admonition-todo, + .rst-content .wy-alert-success.attention, + .rst-content .wy-alert-success.caution, + .rst-content .wy-alert-success.danger, + .rst-content .wy-alert-success.error, + .rst-content .wy-alert-success.note, + .rst-content .wy-alert-success.seealso, + .rst-content .wy-alert-success.warning, + .wy-alert.wy-alert-success { + background-image: initial; + background-color: rgb(7, 53, 46); + } + .rst-content .hint .admonition-title, + .rst-content .hint .wy-alert-title, + .rst-content .important .admonition-title, + .rst-content .important .wy-alert-title, + .rst-content .tip .admonition-title, + .rst-content .tip .wy-alert-title, + .rst-content .wy-alert-success.admonition-todo .admonition-title, + .rst-content .wy-alert-success.admonition-todo .wy-alert-title, + .rst-content .wy-alert-success.admonition .admonition-title, + .rst-content .wy-alert-success.admonition .wy-alert-title, + .rst-content .wy-alert-success.attention .admonition-title, + .rst-content .wy-alert-success.attention .wy-alert-title, + .rst-content .wy-alert-success.caution .admonition-title, + .rst-content .wy-alert-success.caution .wy-alert-title, + .rst-content .wy-alert-success.danger .admonition-title, + .rst-content .wy-alert-success.danger .wy-alert-title, + .rst-content .wy-alert-success.error .admonition-title, + .rst-content .wy-alert-success.error .wy-alert-title, + .rst-content .wy-alert-success.note .admonition-title, + .rst-content .wy-alert-success.note .wy-alert-title, + .rst-content .wy-alert-success.seealso .admonition-title, + .rst-content .wy-alert-success.seealso .wy-alert-title, + .rst-content .wy-alert-success.warning .admonition-title, + .rst-content .wy-alert-success.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-success .admonition-title, + .wy-alert.wy-alert-success .rst-content .admonition-title, + .wy-alert.wy-alert-success .wy-alert-title { + background-image: initial; + background-color: rgb(17, 120, 100); + } + .rst-content .wy-alert-neutral.admonition, + .rst-content .wy-alert-neutral.admonition-todo, + .rst-content .wy-alert-neutral.attention, + .rst-content .wy-alert-neutral.caution, + .rst-content .wy-alert-neutral.danger, + .rst-content .wy-alert-neutral.error, + .rst-content .wy-alert-neutral.hint, + .rst-content .wy-alert-neutral.important, + .rst-content .wy-alert-neutral.note, + .rst-content .wy-alert-neutral.seealso, + .rst-content .wy-alert-neutral.tip, + .rst-content .wy-alert-neutral.warning, + .wy-alert.wy-alert-neutral { + background-image: initial; + background-color: rgb(22, 29, 29); + } + .rst-content .wy-alert-neutral.admonition-todo .admonition-title, + .rst-content .wy-alert-neutral.admonition-todo .wy-alert-title, + .rst-content .wy-alert-neutral.admonition .admonition-title, + .rst-content .wy-alert-neutral.admonition .wy-alert-title, + .rst-content .wy-alert-neutral.attention .admonition-title, + .rst-content .wy-alert-neutral.attention .wy-alert-title, + .rst-content .wy-alert-neutral.caution .admonition-title, + .rst-content .wy-alert-neutral.caution .wy-alert-title, + .rst-content .wy-alert-neutral.danger .admonition-title, + .rst-content .wy-alert-neutral.danger .wy-alert-title, + .rst-content .wy-alert-neutral.error .admonition-title, + .rst-content .wy-alert-neutral.error .wy-alert-title, + .rst-content .wy-alert-neutral.hint .admonition-title, + .rst-content .wy-alert-neutral.hint .wy-alert-title, + .rst-content .wy-alert-neutral.important .admonition-title, + .rst-content .wy-alert-neutral.important .wy-alert-title, + .rst-content .wy-alert-neutral.note .admonition-title, + .rst-content .wy-alert-neutral.note .wy-alert-title, + .rst-content .wy-alert-neutral.seealso .admonition-title, + .rst-content .wy-alert-neutral.seealso .wy-alert-title, + .rst-content .wy-alert-neutral.tip .admonition-title, + .rst-content .wy-alert-neutral.tip .wy-alert-title, + .rst-content .wy-alert-neutral.warning .admonition-title, + .rst-content .wy-alert-neutral.warning .wy-alert-title, + .rst-content .wy-alert.wy-alert-neutral .admonition-title, + .wy-alert.wy-alert-neutral .rst-content .admonition-title, + .wy-alert.wy-alert-neutral .wy-alert-title { + color: rgb(188, 182, 173); + background-image: initial; + background-color: rgb(32, 35, 36); + } + .rst-content .wy-alert-neutral.admonition-todo a, + .rst-content .wy-alert-neutral.admonition a, + .rst-content .wy-alert-neutral.attention a, + .rst-content .wy-alert-neutral.caution a, + .rst-content .wy-alert-neutral.danger a, + .rst-content .wy-alert-neutral.error a, + .rst-content .wy-alert-neutral.hint a, + .rst-content .wy-alert-neutral.important a, + .rst-content .wy-alert-neutral.note a, + .rst-content .wy-alert-neutral.seealso a, + .rst-content .wy-alert-neutral.tip a, + .rst-content .wy-alert-neutral.warning a, + .wy-alert.wy-alert-neutral a { + color: rgb(94, 169, 219); + } + .wy-tray-container li { + background-image: initial; + background-color: transparent; + color: rgb(216, 212, 207); + box-shadow: rgba(0, 0, 0, 0.1) 0px 5px 5px 0px; + } + .wy-tray-container li.wy-tray-item-success { + background-image: initial; + background-color: rgb(25, 111, 62); + } + .wy-tray-container li.wy-tray-item-info { + background-image: initial; + background-color: rgb(26, 82, 118); + } + .wy-tray-container li.wy-tray-item-warning { + background-image: initial; + background-color: rgb(142, 75, 16); + } + .wy-tray-container li.wy-tray-item-danger { + background-image: initial; + background-color: rgb(130, 26, 16); + } + .btn { + color: rgb(216, 212, 207); + border-color: rgba(84, 91, 95, 0.1); + background-color: rgb(25, 111, 62); + text-decoration-color: initial; + box-shadow: rgba(19, 21, 22, 0.5) 0px 1px 2px -1px inset, + rgba(0, 0, 0, 0.1) 0px -2px 0px 0px inset; + } + .btn-hover { + background-image: initial; + background-color: rgb(30, 91, 132); + color: rgb(216, 212, 207); + } + .btn:hover { + background-image: initial; + background-color: rgb(28, 125, 69); + color: rgb(216, 212, 207); + } + .btn:focus { + background-image: initial; + background-color: rgb(28, 125, 69); + outline-color: initial; + } + .btn:active { + box-shadow: rgba(0, 0, 0, 0.05) 0px -1px 0px 0px inset, + rgba(0, 0, 0, 0.1) 0px 2px 0px 0px inset; + } + .btn:visited { + color: rgb(216, 212, 207); + } + .btn-disabled, + .btn-disabled:active, + .btn-disabled:focus, + .btn-disabled:hover, + .btn:disabled { + background-image: none; + box-shadow: none; + } + .btn-info { + background-color: rgb(26, 82, 118) !important; + } + .btn-info:hover { + background-color: rgb(30, 91, 132) !important; + } + .btn-neutral { + background-color: rgb(22, 29, 29) !important; + color: rgb(188, 182, 173) !important; + } + .btn-neutral:hover { + color: rgb(188, 182, 173); + background-color: rgb(27, 35, 35) !important; + } + .btn-neutral:visited { + color: rgb(188, 182, 173) !important; + } + .btn-success { + background-color: rgb(25, 111, 62) !important; + } + .btn-success:hover { + background-color: rgb(22, 98, 54) !important; + } + .btn-danger { + background-color: rgb(130, 26, 16) !important; + } + .btn-danger:hover { + background-color: rgb(119, 24, 14) !important; + } + .btn-warning { + background-color: rgb(142, 75, 16) !important; + } + .btn-warning:hover { + background-color: rgb(132, 70, 14) !important; + } + .btn-invert { + background-color: rgb(21, 22, 23); + } + .btn-invert:hover { + background-color: rgb(28, 31, 32) !important; + } + .btn-link { + color: rgb(94, 169, 219); + box-shadow: none; + background-color: transparent !important; + border-color: transparent !important; + } + .btn-link:active, + .btn-link:hover { + box-shadow: none; + background-color: transparent !important; + color: rgb(90, 168, 218) !important; + } + .btn-link:visited { + color: rgb(170, 113, 192); + } + .wy-dropdown-menu { + background-image: initial; + background-color: rgb(21, 22, 23); + border-color: rgb(119, 111, 98); + box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 2px 0px; + } + .wy-dropdown-menu > dd > a { + color: rgb(188, 182, 173); + } + .wy-dropdown-menu > dd > a:hover { + background-image: initial; + background-color: rgb(26, 82, 118); + color: rgb(216, 212, 207); + } + .wy-dropdown-menu > dd.divider { + border-top-color: rgb(119, 111, 98); + } + .wy-dropdown-menu > dd.call-to-action { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .wy-dropdown-menu > dd.call-to-action:hover { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .wy-dropdown-menu > dd.call-to-action .btn { + color: rgb(216, 212, 207); + } + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu { + background-image: initial; + background-color: rgb(21, 22, 23); + } + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover { + background-image: initial; + background-color: rgb(26, 82, 118); + color: rgb(216, 212, 207); + } + .wy-dropdown-arrow::before { + border-bottom-color: rgb(122, 113, 100); + border-left-color: transparent; + border-right-color: transparent; + } + fieldset, + legend { + border-color: initial; + } + label { + color: rgb(193, 188, 180); + } + .wy-control-group.wy-control-group-required > label::after { + color: rgb(234, 96, 82); + } + .wy-form-message-inline { + color: rgb(171, 164, 153); + } + .wy-form-message { + color: rgb(171, 164, 153); + } + input[type="color"], input[type="date"], input[type="datetime-local"], input[type="datetime"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"] { + border-color: rgb(118, 110, 97); + box-shadow: rgb(35, 38, 39) 0px 1px 3px inset; + } + input[type="color"]:focus, input[type="date"]:focus, input[type="datetime-local"]:focus, input[type="datetime"]:focus, input[type="email"]:focus, input[type="month"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus { + outline-color: initial; + border-color: rgb(103, 96, 85); + } + input.no-focus:focus { + border-color: rgb(118, 110, 97) !important; + } + input[type="checkbox"]:focus, input[type="file"]:focus, input[type="radio"]:focus { + outline-color: rgb(15, 126, 186); + } + input[type="color"][disabled], input[type="date"][disabled], input[type="datetime-local"][disabled], input[type="datetime"][disabled], input[type="email"][disabled], input[type="month"][disabled], input[type="number"][disabled], input[type="password"][disabled], input[type="search"][disabled], input[type="tel"][disabled], input[type="text"][disabled], input[type="time"][disabled], input[type="url"][disabled], input[type="week"][disabled] { + background-color: rgb(21, 23, 24); + } + input:focus:invalid, + select:focus:invalid, + textarea:focus:invalid { + color: rgb(234, 96, 82); + border-color: rgb(183, 38, 22); + } + input:focus:invalid:focus, + select:focus:invalid:focus, + textarea:focus:invalid:focus { + border-color: rgb(183, 38, 22); + } + input[type="checkbox"]:focus:invalid:focus, input[type="file"]:focus:invalid:focus, input[type="radio"]:focus:invalid:focus { + outline-color: rgb(183, 38, 22); + } + select, + textarea { + border-color: rgb(118, 110, 97); + box-shadow: rgb(35, 38, 39) 0px 1px 3px inset; + } + select { + border-color: rgb(118, 110, 97); + background-color: rgb(19, 21, 22); + } + select:focus, + textarea:focus { + outline-color: initial; + } + input[readonly], + select[disabled], + select[readonly], + textarea[disabled], + textarea[readonly] { + background-color: rgb(21, 23, 24); + } + .wy-checkbox, + .wy-radio { + color: rgb(188, 182, 173); + } + .wy-input-prefix .wy-input-context, + .wy-input-suffix .wy-input-context { + background-color: rgb(22, 29, 29); + border-color: rgb(118, 110, 97); + color: rgb(171, 164, 153); + } + .wy-input-suffix .wy-input-context { + border-left-color: initial; + } + .wy-input-prefix .wy-input-context { + border-right-color: initial; + } + .wy-switch::before { + background-image: initial; + background-color: rgb(42, 46, 47); + } + .wy-switch::after { + background-image: initial; + background-color: rgb(66, 71, 74); + } + .wy-switch span { + color: rgb(193, 188, 180); + } + .wy-switch.active::before { + background-image: initial; + background-color: rgb(19, 85, 46); + } + .wy-switch.active::after { + background-image: initial; + background-color: rgb(25, 111, 62); + } + .wy-control-group.wy-control-group-error .wy-form-message, + .wy-control-group.wy-control-group-error > label { + color: rgb(234, 96, 82); + } + .wy-control-group.wy-control-group-error input[type="color"], .wy-control-group.wy-control-group-error input[type="date"], .wy-control-group.wy-control-group-error input[type="datetime-local"], .wy-control-group.wy-control-group-error input[type="datetime"], .wy-control-group.wy-control-group-error input[type="email"], .wy-control-group.wy-control-group-error input[type="month"], .wy-control-group.wy-control-group-error input[type="number"], .wy-control-group.wy-control-group-error input[type="password"], .wy-control-group.wy-control-group-error input[type="search"], .wy-control-group.wy-control-group-error input[type="tel"], .wy-control-group.wy-control-group-error input[type="text"], .wy-control-group.wy-control-group-error input[type="time"], .wy-control-group.wy-control-group-error input[type="url"], .wy-control-group.wy-control-group-error input[type="week"], + .wy-control-group.wy-control-group-error textarea { + border-color: rgb(183, 38, 22); + } + .wy-inline-validate.wy-inline-validate-success .wy-input-context { + color: rgb(99, 220, 150); + } + .wy-inline-validate.wy-inline-validate-danger .wy-input-context { + color: rgb(234, 96, 82); + } + .wy-inline-validate.wy-inline-validate-warning .wy-input-context { + color: rgb(234, 146, 69); + } + .wy-inline-validate.wy-inline-validate-info .wy-input-context { + color: rgb(94, 169, 219); + } + .rst-content table.docutils caption, + .rst-content table.field-list caption, + .wy-table caption { + color: rgb(216, 212, 207); + } + .rst-content table.docutils thead, + .rst-content table.field-list thead, + .wy-table thead { + color: rgb(216, 212, 207); + } + .rst-content table.docutils thead th, + .rst-content table.field-list thead th, + .wy-table thead th { + border-bottom-color: rgb(120, 112, 99); + } + .rst-content table.docutils td, + .rst-content table.field-list td, + .wy-table td { + background-color: transparent; + } + .wy-table-secondary { + color: rgb(160, 151, 139); + } + .wy-table-tertiary { + color: rgb(160, 151, 139); + } + .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td, + .wy-table-backed, + .wy-table-odd td, + .wy-table-striped tr:nth-child(2n-1) td { + background-color: rgb(22, 29, 29); + } + .rst-content table.docutils, + .wy-table-bordered-all { + border-color: rgb(120, 112, 99); + } + .rst-content table.docutils td, + .wy-table-bordered-all td { + border-bottom-color: rgb(120, 112, 99); + border-left-color: rgb(120, 112, 99); + } + .wy-table-bordered { + border-color: rgb(120, 112, 99); + } + .wy-table-bordered-rows td { + border-bottom-color: rgb(120, 112, 99); + } + .wy-table-horizontal td, + .wy-table-horizontal th { + border-bottom-color: rgb(120, 112, 99); + } + a { + color: rgb(94, 169, 219); + text-decoration-color: initial; + } + a:hover { + color: rgb(82, 164, 217); + } + a:visited { + color: rgb(170, 113, 192); + } + body { + color: rgb(188, 182, 173); + background-image: initial; + background-color: rgb(26, 29, 30); + } + .wy-text-strike { + text-decoration-color: initial; + } + .wy-text-warning { + color: rgb(234, 146, 69) !important; + } + a.wy-text-warning:hover { + color: rgb(237, 160, 92) !important; + } + .wy-text-info { + color: rgb(94, 169, 219) !important; + } + a.wy-text-info:hover { + color: rgb(90, 168, 218) !important; + } + .wy-text-success { + color: rgb(99, 220, 150) !important; + } + a.wy-text-success:hover { + color: rgb(86, 217, 142) !important; + } + .wy-text-danger { + color: rgb(234, 96, 82) !important; + } + a.wy-text-danger:hover { + color: rgb(237, 118, 104) !important; + } + .wy-text-neutral { + color: rgb(188, 182, 173) !important; + } + a.wy-text-neutral:hover { + color: rgb(177, 170, 160) !important; + } + hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(120, 112, 99); + } + .rst-content code, + .rst-content tt, + code { + background-image: initial; + background-color: rgb(19, 21, 22); + border-color: rgb(120, 112, 99); + color: rgb(234, 96, 82); + } + .rst-content .section ul, + .rst-content .toctree-wrapper ul, + .wy-plain-list-disc, + article ul { + list-style-image: initial; + } + .rst-content .section ul li, + .rst-content .toctree-wrapper ul li, + .wy-plain-list-disc li, + article ul li { + list-style-image: initial; + } + .rst-content .section ul li li, + .rst-content .toctree-wrapper ul li li, + .wy-plain-list-disc li li, + article ul li li { + list-style-image: initial; + } + .rst-content .section ul li li li, + .rst-content .toctree-wrapper ul li li li, + .wy-plain-list-disc li li li, + article ul li li li { + list-style-image: initial; + } + .rst-content .section ul li ol li, + .rst-content .toctree-wrapper ul li ol li, + .wy-plain-list-disc li ol li, + article ul li ol li { + list-style-image: initial; + } + .rst-content .section ol, + .rst-content ol.arabic, + .wy-plain-list-decimal, + article ol { + list-style-image: initial; + } + .rst-content .section ol li, + .rst-content ol.arabic li, + .wy-plain-list-decimal li, + article ol li { + list-style-image: initial; + } + .rst-content .section ol li ul li, + .rst-content ol.arabic li ul li, + .wy-plain-list-decimal li ul li, + article ol li ul li { + list-style-image: initial; + } + .rst-content .wy-breadcrumbs li tt, + .wy-breadcrumbs li .rst-content tt, + .wy-breadcrumbs li code { + border-color: initial; + background-image: none; + background-color: initial; + } + .rst-content .wy-breadcrumbs li tt.literal, + .wy-breadcrumbs li .rst-content tt.literal, + .wy-breadcrumbs li code.literal { + color: rgb(188, 182, 173); + } + .wy-breadcrumbs-extra { + color: rgb(182, 176, 167); + } + .wy-menu a:hover { + text-decoration-color: initial; + } + .wy-menu-horiz li:hover { + background-image: initial; + background-color: rgba(19, 21, 22, 0.1); + } + .wy-menu-horiz li.divide-left { + border-left-color: rgb(104, 97, 86); + } + .wy-menu-horiz li.divide-right { + border-right-color: rgb(104, 97, 86); + } + .wy-menu-vertical header, + .wy-menu-vertical p.caption { + color: rgb(101, 173, 220); + } + .wy-menu-vertical li.divide-top { + border-top-color: rgb(104, 97, 86); + } + .wy-menu-vertical li.divide-bottom { + border-bottom-color: rgb(104, 97, 86); + } + .wy-menu-vertical li.current { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .wy-menu-vertical li.current a { + color: rgb(160, 151, 139); + border-right-color: rgb(118, 110, 97); + } + .wy-menu-vertical li.current a:hover { + background-image: initial; + background-color: rgb(38, 41, 42); + } + .rst-content .wy-menu-vertical li tt, + .wy-menu-vertical li .rst-content tt, + .wy-menu-vertical li code { + border-color: initial; + background-image: inherit; + background-color: inherit; + color: inherit; + } + .wy-menu-vertical li span.toctree-expand { + color: rgb(182, 175, 166); + } + .wy-menu-vertical li.current > a, + .wy-menu-vertical li.on a { + color: rgb(188, 182, 173); + background-image: initial; + background-color: rgb(21, 22, 23); + border-color: initial; + } + .wy-menu-vertical li.current > a:hover, + .wy-menu-vertical li.on a:hover { + background-image: initial; + background-color: rgb(21, 22, 23); + } + .wy-menu-vertical li.current > a:hover span.toctree-expand, + .wy-menu-vertical li.on a:hover span.toctree-expand { + color: rgb(160, 151, 139); + } + .wy-menu-vertical li.current > a span.toctree-expand, + .wy-menu-vertical li.on a span.toctree-expand { + color: rgb(193, 188, 180); + } + .wy-menu-vertical li.toctree-l1.current > a { + border-bottom-color: rgb(118, 110, 97); + border-top-color: rgb(118, 110, 97); + } + .wy-menu-vertical li.toctree-l2 a, + .wy-menu-vertical li.toctree-l3 a, + .wy-menu-vertical li.toctree-l4 a, + .wy-menu-vertical li.toctree-l5 a, + .wy-menu-vertical li.toctree-l6 a, + .wy-menu-vertical li.toctree-l7 a, + .wy-menu-vertical li.toctree-l8 a, + .wy-menu-vertical li.toctree-l9 a, + .wy-menu-vertical li.toctree-l10 a { + color: rgb(188, 182, 173); + } + .wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand, + .wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand { + color: rgb(160, 151, 139); + } + .wy-menu-vertical li.toctree-l2.current > a, + .wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a { + background-image: initial; + background-color: rgb(43, 47, 49); + } + .wy-menu-vertical li.toctree-l2 span.toctree-expand { + color: rgb(175, 168, 158); + } + .wy-menu-vertical li.toctree-l3.current > a, + .wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a { + background-image: initial; + background-color: rgb(49, 53, 55); + } + .wy-menu-vertical li.toctree-l3 span.toctree-expand { + color: rgb(169, 162, 151); + } + .wy-menu-vertical li ul li a { + color: rgb(199, 194, 187); + } + .wy-menu-vertical a { + color: rgb(199, 194, 187); + } + .wy-menu-vertical a:hover { + background-color: rgb(46, 49, 51); + } + .wy-menu-vertical a:hover span.toctree-expand { + color: rgb(199, 194, 187); + } + .wy-menu-vertical a:active { + background-color: rgb(26, 82, 118); + color: rgb(216, 212, 207); + } + .wy-menu-vertical a:active span.toctree-expand { + color: rgb(216, 212, 207); + } + .wy-side-nav-search { + background-color: rgb(26, 82, 118); + color: rgb(215, 211, 206); + } + .wy-side-nav-search input[type="text"] { + border-color: rgb(35, 112, 161); + } + .wy-side-nav-search img { + background-color: rgb(26, 82, 118); + } + .wy-side-nav-search .wy-dropdown > a, + .wy-side-nav-search > a { + color: rgb(215, 211, 206); + } + .wy-side-nav-search .wy-dropdown > a:hover, + .wy-side-nav-search > a:hover { + background-image: initial; + background-color: rgba(19, 21, 22, 0.1); + } + .wy-side-nav-search .wy-dropdown > a img.logo, + .wy-side-nav-search > a img.logo { + background-image: initial; + background-color: transparent; + } + .wy-side-nav-search > div.version { + color: rgba(216, 212, 207, 0.3); + } + .wy-nav .wy-menu-vertical header { + color: rgb(94, 169, 219); + } + .wy-nav .wy-menu-vertical a { + color: rgb(182, 176, 167); + } + .wy-nav .wy-menu-vertical a:hover { + background-color: rgb(26, 82, 118); + color: rgb(216, 212, 207); + } + .wy-body-for-nav { + background-image: initial; + background-color: rgb(21, 22, 23); + } + .wy-nav-side { + color: rgb(172, 164, 154); + background-image: initial; + background-color: rgb(30, 33, 34); + } + .wy-nav-top { + background-image: initial; + background-color: rgb(26, 82, 118); + color: rgb(216, 212, 207); + } + .wy-nav-top a { + color: rgb(216, 212, 207); + } + .wy-nav-top img { + background-color: rgb(26, 82, 118); + } + .wy-nav-content-wrap { + background-image: initial; + background-color: rgb(21, 22, 23); + } + .wy-body-mask { + background-image: initial; + background-color: rgba(0, 0, 0, 0.2); + } + footer { + color: rgb(160, 151, 139); + } + .rst-content footer span.commit tt, + footer span.commit .rst-content tt, + footer span.commit code { + background-image: none; + background-color: initial; + border-color: initial; + color: rgb(160, 151, 139); + } + #search-results .search li { + border-bottom-color: rgb(120, 112, 99); + } + #search-results .search li:first-child { + border-top-color: rgb(120, 112, 99); + } + #search-results .context { + color: rgb(160, 151, 139); + } + .wy-body-for-nav { + background-image: initial; + background-color: rgb(21, 22, 23); + } + @media screen and (min-width: 1100px) { + .wy-nav-content-wrap { + background-image: initial; + background-color: rgba(0, 0, 0, 0.05); + } + .wy-nav-content { + background-image: initial; + background-color: rgb(21, 22, 23); + } + } + .rst-versions { + color: rgb(215, 211, 206); + background-image: initial; + background-color: rgb(18, 20, 20); + } + .rst-versions a { + color: rgb(94, 169, 219); + text-decoration-color: initial; + } + .rst-versions .rst-current-version { + background-color: rgb(23, 25, 26); + color: rgb(99, 220, 150); + } + .rst-content .code-block-caption .rst-versions .rst-current-version .headerlink, + .rst-content .rst-versions .rst-current-version .admonition-title, + .rst-content code.download .rst-versions .rst-current-version span:first-child, + .rst-content dl dt .rst-versions .rst-current-version .headerlink, + .rst-content h1 .rst-versions .rst-current-version .headerlink, + .rst-content h2 .rst-versions .rst-current-version .headerlink, + .rst-content h3 .rst-versions .rst-current-version .headerlink, + .rst-content h4 .rst-versions .rst-current-version .headerlink, + .rst-content h5 .rst-versions .rst-current-version .headerlink, + .rst-content h6 .rst-versions .rst-current-version .headerlink, + .rst-content p.caption .rst-versions .rst-current-version .headerlink, + .rst-content table > caption .rst-versions .rst-current-version .headerlink, + .rst-content tt.download .rst-versions .rst-current-version span:first-child, + .rst-versions .rst-current-version .fa, + .rst-versions .rst-current-version .icon, + .rst-versions .rst-current-version .rst-content .admonition-title, + .rst-versions .rst-current-version .rst-content .code-block-caption .headerlink, + .rst-versions .rst-current-version .rst-content code.download span:first-child, + .rst-versions .rst-current-version .rst-content dl dt .headerlink, + .rst-versions .rst-current-version .rst-content h1 .headerlink, + .rst-versions .rst-current-version .rst-content h2 .headerlink, + .rst-versions .rst-current-version .rst-content h3 .headerlink, + .rst-versions .rst-current-version .rst-content h4 .headerlink, + .rst-versions .rst-current-version .rst-content h5 .headerlink, + .rst-versions .rst-current-version .rst-content h6 .headerlink, + .rst-versions .rst-current-version .rst-content p.caption .headerlink, + .rst-versions .rst-current-version .rst-content table > caption .headerlink, + .rst-versions .rst-current-version .rst-content tt.download span:first-child, + .rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand, + .wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand { + color: rgb(215, 211, 206); + } + .rst-versions .rst-current-version.rst-out-of-date { + background-color: rgb(130, 26, 16); + color: rgb(216, 212, 207); + } + .rst-versions .rst-current-version.rst-active-old-version { + background-color: rgb(154, 125, 9); + color: rgb(216, 212, 207); + } + .rst-versions .rst-other-versions { + color: rgb(160, 151, 139); + } + .rst-versions .rst-other-versions hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(104, 97, 86); + } + .rst-versions .rst-other-versions dd a { + color: rgb(215, 211, 206); + } + .rst-versions.rst-badge { + border-color: initial; + } + .rst-content abbr[title] { + text-decoration-color: initial; + } + .rst-content.style-external-links a.reference.external::after { + color: rgb(182, 176, 167); + } + .rst-content div[class^="highlight"], + .rst-content pre.literal-block { + border-color: rgb(120, 112, 99); + } + .rst-content div[class^="highlight"] div[class^="highlight"], .rst-content pre.literal-block div[class^="highlight"] { + border-color: initial; + } + .rst-content .linenodiv pre { + border-right-color: rgb(121, 112, 99); + } + .rst-content .admonition table { + border-color: rgba(84, 91, 95, 0.1); + } + .rst-content .admonition table td, + .rst-content .admonition table th { + background-image: initial !important; + background-color: transparent !important; + border-color: rgba(84, 91, 95, 0.1) !important; + } + .rst-content .section ol.loweralpha, + .rst-content .section ol.loweralpha > li { + list-style-image: initial; + } + .rst-content .section ol.upperalpha, + .rst-content .section ol.upperalpha > li { + list-style-image: initial; + } + .rst-content .toc-backref { + color: rgb(188, 182, 173); + } + .rst-content .sidebar { + background-image: initial; + background-color: rgb(22, 29, 29); + border-color: rgb(120, 112, 99); + } + .rst-content .sidebar .sidebar-title { + background-image: initial; + background-color: rgb(32, 35, 36); + } + .rst-content .highlighted { + background-image: initial; + background-color: rgb(154, 125, 9); + box-shadow: rgb(154, 125, 9) 0px 0px 0px 2px; + } + html.writer-html4 .rst-content table.docutils.citation, + html.writer-html4 .rst-content table.docutils.footnote { + background-image: none; + background-color: initial; + border-color: initial; + } + html.writer-html4 .rst-content table.docutils.citation td, + html.writer-html4 .rst-content table.docutils.citation tr, + html.writer-html4 .rst-content table.docutils.footnote td, + html.writer-html4 .rst-content table.docutils.footnote tr { + border-color: initial; + background-color: transparent !important; + } + .rst-content table.docutils.footnote, + html.writer-html4 .rst-content table.docutils.citation, + html.writer-html5 .rst-content dl.footnote { + color: rgb(160, 151, 139); + } + .rst-content table.docutils.footnote code, + .rst-content table.docutils.footnote tt, + html.writer-html4 .rst-content table.docutils.citation code, + html.writer-html4 .rst-content table.docutils.citation tt, + html.writer-html5 .rst-content dl.footnote code, + html.writer-html5 .rst-content dl.footnote tt { + color: rgb(178, 172, 162); + } + .rst-content table.docutils th { + border-color: rgb(120, 112, 99); + } + html.writer-html5 .rst-content table.docutils th { + border-color: rgb(120, 112, 99); + } + .rst-content table.field-list, + .rst-content table.field-list td { + border-color: initial; + } + .rst-content code, + .rst-content tt { + color: rgb(216, 212, 207); + } + .rst-content code.literal, + .rst-content tt.literal { + color: rgb(234, 96, 82); + } + .rst-content code.xref, + .rst-content tt.xref, + a .rst-content code, + a .rst-content tt { + color: rgb(188, 182, 173); + } + .rst-content a code, + .rst-content a tt { + color: rgb(94, 169, 219); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt { + background-image: initial; + background-color: rgb(26, 28, 29); + color: rgb(94, 169, 219); + border-top-color: rgb(37, 119, 171); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt::before, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt::before { + color: rgb(111, 179, 223); + } + html.writer-html4 .rst-content dl:not(.docutils) > dt .headerlink, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt .headerlink { + color: rgb(188, 182, 173); + } + html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list) > dt, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list) > dt { + border-top-color: initial; + border-right-color: initial; + border-bottom-color: initial; + border-left-color: rgb(118, 110, 97); + background-image: initial; + background-color: rgb(26, 28, 29); + color: rgb(178, 172, 162); + } + html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list) > dt .headerlink, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list) > dt .headerlink { + color: rgb(188, 182, 173); + } + html.writer-html4 .rst-content dl:not(.docutils) code.descclassname, + html.writer-html4 .rst-content dl:not(.docutils) code.descname, + html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname, + html.writer-html4 .rst-content dl:not(.docutils) tt.descname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname { + background-color: transparent; + border-color: initial; + } + html.writer-html4 .rst-content dl:not(.docutils) .optional, + html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional { + color: rgb(216, 212, 207); + } + .rst-content .viewcode-back, + .rst-content .viewcode-link { + color: rgb(99, 220, 150); + } + .rst-content code.download, + .rst-content tt.download { + background-image: inherit; + background-color: inherit; + color: inherit; + border-color: inherit; + } + .rst-content .guilabel { + border-color: rgb(38, 119, 172); + background-image: initial; + background-color: rgb(26, 28, 29); + } + span[id*="MathJax-Span"] { + color: rgb(188, 182, 173); + } + td.linenos .normal { + color: inherit; + background-color: transparent; + } + span.linenos { + color: inherit; + background-color: transparent; + } + td.linenos .special { + color: rgb(216, 212, 207); + background-color: rgb(71, 71, 0); + } + span.linenos.special { + color: rgb(216, 212, 207); + background-color: rgb(71, 71, 0); + } + .highlight .hll { + background-color: rgb(66, 66, 0); + } + .highlight { + background-image: initial; + background-color: rgb(49, 66, 0); + } + .highlight .c { + color: rgb(124, 182, 197); + } + .highlight .err { + border-color: rgb(201, 0, 0); + } + .highlight .k { + color: rgb(114, 255, 154); + } + .highlight .o { + color: rgb(171, 164, 153); + } + .highlight .ch { + color: rgb(124, 182, 197); + } + .highlight .cm { + color: rgb(124, 182, 197); + } + .highlight .cp { + color: rgb(114, 255, 154); + } + .highlight .cpf { + color: rgb(124, 182, 197); + } + .highlight .c1 { + color: rgb(124, 182, 197); + } + .highlight .cs { + color: rgb(124, 182, 197); + background-color: rgb(48, 0, 0); + } + .highlight .gd { + color: rgb(255, 90, 90); + } + .highlight .gr { + color: rgb(255, 44, 44); + } + .highlight .gh { + color: rgb(114, 185, 255); + } + .highlight .gi { + color: rgb(90, 255, 90); + } + .highlight .go { + color: rgb(193, 188, 180); + } + .highlight .gp { + color: rgb(246, 151, 75); + } + .highlight .gu { + color: rgb(255, 105, 255); + } + .highlight .gt { + color: rgb(75, 173, 255); + } + .highlight .kc { + color: rgb(114, 255, 154); + } + .highlight .kd { + color: rgb(114, 255, 154); + } + .highlight .kn { + color: rgb(114, 255, 154); + } + .highlight .kp { + color: rgb(114, 255, 154); + } + .highlight .kr { + color: rgb(114, 255, 154); + } + .highlight .kt { + color: rgb(255, 133, 98); + } + .highlight .m { + color: rgb(123, 222, 173); + } + .highlight .s { + color: rgb(126, 170, 203); + } + .highlight .na { + color: rgb(126, 170, 203); + } + .highlight .nb { + color: rgb(114, 255, 154); + } + .highlight .nc { + color: rgb(86, 196, 242); + } + .highlight .no { + color: rgb(108, 180, 216); + } + .highlight .nd { + color: rgb(178, 172, 162); + } + .highlight .ni { + color: rgb(220, 111, 85); + } + .highlight .ne { + color: rgb(114, 255, 154); + } + .highlight .nf { + color: rgb(120, 189, 248); + } + .highlight .nl { + color: rgb(121, 194, 255); + } + .highlight .nn { + color: rgb(86, 196, 242); + } + .highlight .nt { + color: rgb(125, 192, 248); + } + .highlight .nv { + color: rgb(192, 108, 216); + } + .highlight .ow { + color: rgb(114, 255, 154); + } + .highlight .w { + color: rgb(186, 180, 171); + } + .highlight .mb { + color: rgb(123, 222, 173); + } + .highlight .mf { + color: rgb(123, 222, 173); + } + .highlight .mh { + color: rgb(123, 222, 173); + } + .highlight .mi { + color: rgb(123, 222, 173); + } + .highlight .mo { + color: rgb(123, 222, 173); + } + .highlight .sa { + color: rgb(126, 170, 203); + } + .highlight .sb { + color: rgb(126, 170, 203); + } + .highlight .sc { + color: rgb(126, 170, 203); + } + .highlight .dl { + color: rgb(126, 170, 203); + } + .highlight .sd { + color: rgb(126, 170, 203); + } + .highlight .s2 { + color: rgb(126, 170, 203); + } + .highlight .se { + color: rgb(126, 170, 203); + } + .highlight .sh { + color: rgb(126, 170, 203); + } + .highlight .si { + color: rgb(120, 172, 210); + } + .highlight .sx { + color: rgb(246, 151, 75); + } + .highlight .sr { + color: rgb(129, 182, 223); + } + .highlight .s1 { + color: rgb(126, 170, 203); + } + .highlight .ss { + color: rgb(186, 229, 123); + } + .highlight .bp { + color: rgb(114, 255, 154); + } + .highlight .fm { + color: rgb(120, 189, 248); + } + .highlight .vc { + color: rgb(192, 108, 216); + } + .highlight .vg { + color: rgb(192, 108, 216); + } + .highlight .vi { + color: rgb(192, 108, 216); + } + .highlight .vm { + color: rgb(192, 108, 216); + } + .highlight .il { + color: rgb(123, 222, 173); + } + [role="tablist"] { + border-bottom-color: rgb(115, 107, 95); + } + .sphinx-tabs-tab { + color: rgb(118, 181, 226); + background-color: rgba(19, 21, 22, 0); border-color: initial; + } + .sphinx-tabs-tab[aria-selected="true"] { + border-color: rgb(115, 107, 95) rgb(115, 107, 95) rgb(123, 114, 101); + background-color: rgb(19, 21, 22); + } + .sphinx-tabs-panel { + border-right-color: rgb(115, 107, 95); + border-bottom-color: rgb(115, 107, 95); + border-left-color: rgb(115, 107, 95); + border-top-color: initial; + background-image: initial; + background-color: rgb(19, 21, 22); + } + .rst-other-versions a { + border-color: initial; + } + .ethical-sidebar .ethical-image-link, + .ethical-footer .ethical-image-link { + border-color: initial; + } + .ethical-sidebar, + .ethical-footer { + background-color: rgb(27, 29, 30); + border-color: rgb(118, 110, 97); + color: rgb(211, 208, 202); + } + .ethical-sidebar ul { + list-style-image: initial; + } + .ethical-sidebar ul li { + background-color: rgb(4, 62, 97); + color: rgb(216, 212, 207); + } + .ethical-sidebar a, + .ethical-sidebar a:visited, + .ethical-sidebar a:hover, + .ethical-sidebar a:active, + .ethical-footer a, + .ethical-footer a:visited, + .ethical-footer a:hover, + .ethical-footer a:active { + color: rgb(211, 208, 202); + text-decoration-color: initial !important; + border-bottom-color: initial !important; + } + .ethical-callout a { + color: rgb(166, 159, 147) !important; + text-decoration-color: initial !important; + } + .ethical-fixedfooter { + background-color: rgb(27, 29, 30); + border-top-color: rgb(117, 109, 96); + color: rgb(188, 182, 173); + } + .ethical-fixedfooter .ethical-text::before { + background-color: rgb(49, 112, 51); + color: rgb(216, 212, 207); + } + .ethical-fixedfooter .ethical-callout { + color: rgb(171, 164, 153); + } + .ethical-fixedfooter a, + .ethical-fixedfooter a:hover, + .ethical-fixedfooter a:active, + .ethical-fixedfooter a:visited { + color: rgb(188, 182, 173); + text-decoration-color: initial; + } + .ethical-rtd .ethical-sidebar { + color: rgb(182, 176, 167); + } + .ethical-alabaster a.ethical-image-link { + border-color: initial !important; + } + .ethical-dark-theme .ethical-sidebar { + background-color: rgb(46, 50, 52); + border-color: rgb(114, 106, 93); + color: rgb(189, 183, 174) !important; + } + .ethical-dark-theme a, + .ethical-dark-theme a:visited { + color: rgb(205, 200, 194) !important; + border-bottom-color: initial !important; + } + .ethical-dark-theme .ethical-callout a { + color: rgb(182, 176, 167) !important; + } + .keep-us-sustainable { + border-color: rgb(104, 158, 45); + } + .keep-us-sustainable a, + .keep-us-sustainable a:hover, + .keep-us-sustainable a:visited { + text-decoration-color: initial; + } + .wy-nav-side .keep-us-sustainable { + color: rgb(182, 176, 167); + } + .wy-nav-side .keep-us-sustainable a { + color: rgb(209, 205, 199); + } + [data-ea-publisher].loaded a, + [data-ea-type].loaded a { + text-decoration-color: initial; + } + [data-ea-publisher].loaded .ea-content, + [data-ea-type].loaded .ea-content { + background-image: initial; + background-color: rgba(0, 0, 0, 0.03); + color: rgb(181, 174, 164); + } + [data-ea-publisher].loaded .ea-content a:link, + [data-ea-type].loaded .ea-content a:link { + color: rgb(181, 174, 164); + } + [data-ea-publisher].loaded .ea-content a:visited, + [data-ea-type].loaded .ea-content a:visited { + color: rgb(181, 174, 164); + } + [data-ea-publisher].loaded .ea-content a:hover, + [data-ea-type].loaded .ea-content a:hover { + color: rgb(192, 186, 178); + } + [data-ea-publisher].loaded .ea-content a:active, + [data-ea-type].loaded .ea-content a:active { + color: rgb(192, 186, 178); + } + [data-ea-publisher].loaded .ea-content a strong, + [data-ea-publisher].loaded .ea-content a b, + [data-ea-type].loaded .ea-content a strong, + [data-ea-type].loaded .ea-content a b { + color: rgb(64, 180, 248); + } + [data-ea-publisher].loaded .ea-callout a:link, + [data-ea-type].loaded .ea-callout a:link { + color: rgb(169, 162, 151); + } + [data-ea-publisher].loaded .ea-callout a:visited, + [data-ea-type].loaded .ea-callout a:visited { + color: rgb(169, 162, 151); + } + [data-ea-publisher].loaded .ea-callout a:hover, + [data-ea-type].loaded .ea-callout a:hover { + color: rgb(181, 174, 164); + } + [data-ea-publisher].loaded .ea-callout a:active, + [data-ea-type].loaded .ea-callout a:active { + color: rgb(181, 174, 164); + } + [data-ea-publisher].loaded .ea-callout a strong, + [data-ea-publisher].loaded .ea-callout a b, + [data-ea-type].loaded .ea-callout a strong, + [data-ea-type].loaded .ea-callout a b { + color: rgb(64, 180, 248); + } + [data-ea-publisher].loaded.dark .ea-content, + [data-ea-type].loaded.dark .ea-content { + background-image: initial; + background-color: rgba(19, 21, 22, 0.05); + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.dark .ea-content a:link, + [data-ea-type].loaded.dark .ea-content a:link { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.dark .ea-content a:visited, + [data-ea-type].loaded.dark .ea-content a:visited { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.dark .ea-content a:hover, + [data-ea-type].loaded.dark .ea-content a:hover { + color: rgb(212, 208, 202); + } + [data-ea-publisher].loaded.dark .ea-content a:active, + [data-ea-type].loaded.dark .ea-content a:active { + color: rgb(212, 208, 202); + } + [data-ea-publisher].loaded.dark .ea-content a strong, + [data-ea-publisher].loaded.dark .ea-content a b, + [data-ea-type].loaded.dark .ea-content a strong, + [data-ea-type].loaded.dark .ea-content a b { + color: rgb(85, 188, 249); + } + [data-ea-publisher].loaded.dark .ea-callout a:link, + [data-ea-type].loaded.dark .ea-callout a:link { + color: rgb(189, 184, 175); + } + [data-ea-publisher].loaded.dark .ea-callout a:visited, + [data-ea-type].loaded.dark .ea-callout a:visited { + color: rgb(189, 184, 175); + } + [data-ea-publisher].loaded.dark .ea-callout a:hover, + [data-ea-type].loaded.dark .ea-callout a:hover { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.dark .ea-callout a:active, + [data-ea-type].loaded.dark .ea-callout a:active { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.dark .ea-callout a strong, + [data-ea-publisher].loaded.dark .ea-callout a b, + [data-ea-type].loaded.dark .ea-callout a strong, + [data-ea-type].loaded.dark .ea-callout a b { + color: rgb(85, 188, 249); + } + @media (prefers-color-scheme: dark) { + [data-ea-publisher].loaded.adaptive .ea-content, + [data-ea-type].loaded.adaptive .ea-content { + background-image: initial; + background-color: rgba(19, 21, 22, 0.05); + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.adaptive .ea-content a:link, + [data-ea-type].loaded.adaptive .ea-content a:link { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.adaptive .ea-content a:visited, + [data-ea-type].loaded.adaptive .ea-content a:visited { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.adaptive .ea-content a:hover, + [data-ea-type].loaded.adaptive .ea-content a:hover { + color: rgb(212, 208, 202); + } + [data-ea-publisher].loaded.adaptive .ea-content a:active, + [data-ea-type].loaded.adaptive .ea-content a:active { + color: rgb(212, 208, 202); + } + [data-ea-publisher].loaded.adaptive .ea-content a strong, + [data-ea-publisher].loaded.adaptive .ea-content a b, + [data-ea-type].loaded.adaptive .ea-content a strong, + [data-ea-type].loaded.adaptive .ea-content a b { + color: rgb(85, 188, 249); + } + [data-ea-publisher].loaded.adaptive .ea-callout a:link, + [data-ea-type].loaded.adaptive .ea-callout a:link { + color: rgb(189, 184, 175); + } + [data-ea-publisher].loaded.adaptive .ea-callout a:visited, + [data-ea-type].loaded.adaptive .ea-callout a:visited { + color: rgb(189, 184, 175); + } + [data-ea-publisher].loaded.adaptive .ea-callout a:hover, + [data-ea-type].loaded.adaptive .ea-callout a:hover { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.adaptive .ea-callout a:active, + [data-ea-type].loaded.adaptive .ea-callout a:active { + color: rgb(200, 196, 189); + } + [data-ea-publisher].loaded.adaptive .ea-callout a strong, + [data-ea-publisher].loaded.adaptive .ea-callout a b, + [data-ea-type].loaded.adaptive .ea-callout a strong, + [data-ea-type].loaded.adaptive .ea-callout a b { + color: rgb(85, 188, 249); + } + } + [data-ea-publisher].loaded .ea-content, + [data-ea-type].loaded .ea-content { + border-color: initial; + box-shadow: rgba(0, 0, 0, 0.15) 0px 2px 3px; + } + [data-ea-publisher].loaded.raised .ea-content, + [data-ea-type].loaded.raised .ea-content { + border-color: initial; + box-shadow: rgba(0, 0, 0, 0.15) 0px 2px 3px; + } + [data-ea-publisher].loaded.bordered .ea-content, + [data-ea-type].loaded.bordered .ea-content { + border-color: rgba(84, 91, 95, 0.04); + box-shadow: none; + } + [data-ea-publisher].loaded.bordered.dark .ea-content, + [data-ea-type].loaded.bordered.dark .ea-content { + border-color: rgba(123, 114, 101, 0.07); + } + @media (prefers-color-scheme: dark) { + [data-ea-publisher].loaded.bordered.adaptive .ea-content, + [data-ea-type].loaded.bordered.adaptive .ea-content { + border-color: rgba(123, 114, 101, 0.07); + } + } + [data-ea-publisher].loaded.flat .ea-content, + [data-ea-type].loaded.flat .ea-content { + border-color: initial; + box-shadow: none; + } + .vimvixen-hint { + background-color: rgb(98, 66, 0) !important; + border-color: rgb(170, 138, 15) !important; + color: rgb(237, 221, 175) !important; + } + #edge-translate-panel-body { + color: var(--darkreader-text--darkreader-neutral-text) !important; + } + } + @media (prefers-color-scheme: light) { + .wy-menu-vertical li.toctree-l2.current a, + .wy-menu-vertical li.toctree-l3.current a { + background-color: rgb(54, 59, 61); + } + } + .rst-other-versions a { + border-color: initial; + } + .ethical-sidebar .ethical-image-link, + .ethical-footer .ethical-image-link { + border-color: initial; + } + .ethical-sidebar, + .ethical-footer { + background-color: rgb(34, 36, 38); + border-color: rgb(62, 68, 70); + color: rgb(226, 223, 219); + } + .ethical-sidebar ul { + list-style-image: initial; + } + .ethical-sidebar ul li { + background-color: rgb(5, 77, 121); + color: rgb(232, 230, 227); + } + .ethical-sidebar a, + .ethical-sidebar a:visited, + .ethical-sidebar a:hover, + .ethical-sidebar a:active, + .ethical-footer a, + .ethical-footer a:visited, + .ethical-footer a:hover, + .ethical-footer a:active { + color: rgb(226, 223, 219); + text-decoration-color: initial !important; + border-bottom-color: initial !important; + } + .ethical-callout a { + color: rgb(161, 153, 141) !important; + text-decoration-color: initial !important; + } + .ethical-fixedfooter { + background-color: rgb(34, 36, 38); + border-top-color: rgb(66, 72, 74); + color: rgb(192, 186, 178); + } + .ethical-fixedfooter .ethical-text::before { + background-color: rgb(61, 140, 64); + color: rgb(232, 230, 227); + } + .ethical-fixedfooter .ethical-callout { + color: rgb(168, 160, 149); + } + .ethical-fixedfooter a, + .ethical-fixedfooter a:hover, + .ethical-fixedfooter a:active, + .ethical-fixedfooter a:visited { + color: rgb(192, 186, 178); + text-decoration-color: initial; + } + .ethical-rtd .ethical-sidebar { + color: rgb(184, 178, 169); + } + .ethical-alabaster a.ethical-image-link { + border-color: initial !important; + } + .ethical-dark-theme .ethical-sidebar { + background-color: rgb(58, 62, 65); + border-color: rgb(75, 81, 84); + color: rgb(193, 188, 180) !important; + } + .ethical-dark-theme a, + .ethical-dark-theme a:visited { + color: rgb(216, 213, 208) !important; + border-bottom-color: initial !important; + } + .ethical-dark-theme .ethical-callout a { + color: rgb(184, 178, 169) !important; + } + .keep-us-sustainable { + border-color: rgb(87, 133, 38); + } + .keep-us-sustainable a, + .keep-us-sustainable a:hover, + .keep-us-sustainable a:visited { + text-decoration-color: initial; + } + .wy-nav-side .keep-us-sustainable { + color: rgb(184, 178, 169); + } + .wy-nav-side .keep-us-sustainable a { + color: rgb(222, 219, 215); + } + + /* Override Style */ + .vimvixen-hint { + background-color: #7b5300 !important; + border-color: #d8b013 !important; + color: #f3e8c8 !important; + } + ::placeholder { + opacity: 0.5 !important; + } + a[href="https://coinmarketcap.com/"] > svg[width="94"][height="16"] > path { + fill: var(--darkreader-neutral-text) !important; + } + #edge-translate-panel-body, + .MuiTypography-body1 { + color: var(--darkreader-neutral-text) !important; + } + gr-main-header { + background-color: #0f3a48 !important; + } + embed[type="application/pdf"] { filter: invert(100%) contrast(90%); } +} diff --git a/doc/manual/resources/css/light.css b/doc/manual/resources/css/light.css new file mode 100644 index 00000000..53599fd7 --- /dev/null +++ b/doc/manual/resources/css/light.css @@ -0,0 +1,10 @@ +@media (prefers-color-scheme: light) { + + .wy-menu-vertical li.toctree-l2.current a, + .wy-menu-vertical li.toctree-l3.current a { + background-color: #c9c9c9; + } + pre.man { + font-size: 0.9em; + } +} diff --git a/doc/manual/resources/favicon.ico b/doc/manual/resources/favicon.ico new file mode 100644 index 00000000..de06a94b Binary files /dev/null and b/doc/manual/resources/favicon.ico differ diff --git a/doc/manual/resources/nsd-duotone-white.png b/doc/manual/resources/nsd-duotone-white.png new file mode 100644 index 00000000..2432e865 Binary files /dev/null and b/doc/manual/resources/nsd-duotone-white.png differ diff --git a/doc/manual/resources/nsd-duotone-white.svg b/doc/manual/resources/nsd-duotone-white.svg new file mode 100644 index 00000000..71e99395 --- /dev/null +++ b/doc/manual/resources/nsd-duotone-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/doc/manual/running/interfaces.rst b/doc/manual/running/interfaces.rst new file mode 100644 index 00000000..a1291019 --- /dev/null +++ b/doc/manual/running/interfaces.rst @@ -0,0 +1,28 @@ +Interfaces +========== + +NSD will by default bind itself to the system default interface and service IPv4 +and if available also IPv6. It is possible to service only IPv4 or IPv6 using +the :option:`-4`, :option:`-6` command line options, or the ``ip4-only`` and +``ip6-only`` config file options. + +The command line option :option:`-a` and config file option ip-address can be +given to bind to specific interfaces. Multiple interfaces can be specified, +which is useful for two reasons: + +- The specific interface bound will result in the OS bypassing routing tables + for the interface selection. This results in a small performance gain. It is + not the performance gain that is the problem: sometimes the routing tables can + give the wrong answer, see the next point. +- The answer will be routed via the interface the query came from. This makes + sure that the return address on the DNS replies is the same as the query was + sent to. Many resolvers require the source address of the replies to be + correct. The ``ip-address:`` option is easier than configuring the OS routing + table to return the DNS replies via the correct interface. + +The above means that even for systems with multiple interfaces where you intend +to provide DNS service to all interfaces, it is prudent to specify all the +interfaces as ``ip-address`` config file options. + +With the config file option ``ip-transparent`` you can allow NSD to bind to +non-local addresses. \ No newline at end of file diff --git a/doc/manual/running/logging.rst b/doc/manual/running/logging.rst new file mode 100644 index 00000000..39f091d3 --- /dev/null +++ b/doc/manual/running/logging.rst @@ -0,0 +1,27 @@ +Logging +======= + +NSD does not provide any DNS logging. We believe that this is a separate task +and has to be done independently from the core operation. This decision was taken +in order to keep NSD focused and minimise its complexity. +It is better to leave logging and tracing to separate dedicated tools. Do note, +however, that NSD can be compiled with support for DNSTAP (see ``nsd.conf(5)``). + +The `CAIDA dnsstat tool `_ can +easily be configured and/or modified to suit local statistics requirements +without any danger of affecting the name server itself. We have run ``dnsstat`` +on the same machine as NSD, and we would recommend using a multiprocessor if +performance is an issue. Of course, ``dnsstat`` can also run on a separate +machine that has MAC layer access to the network of the server. + +The :command:`nsd-control` tool can output some statistics, with +:command:`nsd-control stats` and :command:`nsd-control stats_noreset`. In +`contrib/nsd_munin_ +`_ there is a +Munin grapher plugin that uses it. The output of :command:`nsd-control stats` +is easy to read (text only) with scripts. The output values are documented on +the :command:`nsd-control` man page. + +Another available tool is `dnstop +`_, which displays DNS +statistics on your network. diff --git a/doc/manual/running/tuning.rst b/doc/manual/running/tuning.rst new file mode 100644 index 00000000..1db997fb --- /dev/null +++ b/doc/manual/running/tuning.rst @@ -0,0 +1,128 @@ +Tuning +====== + +In version 4.3.0 of NSD, additional functionality was added to increase +performance even more. Most notably, this includes processor affinity. + +NSD is performant by design because it matters when operators serve hundreds of +thousands or even millions of queries per second. We strive to make the right +choices by default, like enabling the use of ``libevent`` at the configure stage +to ensure the most efficient event mechanism is used on a given platform. e.g. +``epoll`` on Linux and ``kqueue`` on FreeBSD. Switches are available for +operators who know the implementation on their system behaves correctly, like +enabling the use of ``recvmmsg`` at the configure stage +(:option:`--enable-recvmmsg`) to read multiple messages from a socket in one +system call. + +By default NSD forks (only) one server. Modern computer systems however, may +have more than one processor, and usually have more than one core per processor. +The easiest way to scale up performance is to simply fork more servers by +configuring server-count: to match the number of cores available in the system +so that more queries can be answered simultaneously. If the operating system +supports it, ensure ``reuseport:`` is set to ``yes`` to distribute incoming +packets evenly across server processes to balance the load. + +A couple of other options that the operator may want to consider: + +1. Memory usage can be lowered (around 50%) by using zone files and disable + the on-disk database by setting ``database: ""``. +2. TCP capacity can be significantly increased by setting ``tcp-count: 1000`` + and ``tcp-timeout: 3``. Set ``tcp-reject-overflow: yes`` to prevent the + kernel connection queue from growing. + +Processor Affinity +------------------ + +The aforementioned settings provide an easy way to increase performance without +the need for in-depth knowledge of the hardware. For operators that require even +more throughput ``cpu-affinity`` is available. + +The operating system’s scheduling-algorithm determines which core a given task +is allocated to. Processors build up state — e.g. by keeping frequently accessed +data in cache memory — for the task that it is currently executing. Whenever a +task switches cores, performance is degraded because the core it switched to has +yet to build up said state. While this scheduling-algorithm works just fine for +general-purpose computing, operators may want to designate a set of cores for +best performance. The ``cpu-affinity`` family of configuration options was added +to NSD specifically for that purpose. + +Processor affinity is currently supported on Linux and FreeBSD. Other operating +systems may be supported in the future, but not all operating systems that can +run NSD support CPU pinning. To fully benefit from this feature, one must first +determine which cores should be allocated to NSD. This requires some knowledge +of the underlying hardware, but generally speaking every process should run on a +dedicated core and the use of Hyper-Threading cores should be avoided to prevent +resource contention. List every core designated to NSD in ``cpu-affinity`` and +bind each server process to a specific core using ``server--cpu-affinity`` +and ``xfrd-cpu-affinity`` to improve L1/L2 cache hit rates and reduce pipeline +stalls/flushes. + +.. code:: text + + server: + server-count: 2 + cpu-affinity: 0 1 2 + server-1-cpu-affinity: 0 + server-2-cpu-affinity: 1 + xfrd-cpu-affinity: 2 + +Partition Sockets +----------------- + +``ip-address:`` options in the ``server:`` clause can be configured per server +or set of servers. Sockets configured for a specific server are closed by other +servers on startup. This improves performance if a large number of sockets are +scanned using ``select/poll`` and avoids waking up multiple servers when a +packet comes in, known as the `thundering herd problem +`_. Though both problems +are solved using a modern kernel and a modern I/O event mechanism, there is one +other reason to partition sockets, explained below. + +.. code:: text + + server: + ip-address: 192.0.2.1 servers=1 + +Bind to Device +-------------- + +``ip-address:`` options in the server: clause can now also be configured to bind +directly to the network interface device on Linux (``bindtodevice=yes``) and to +use a specific routing table on FreeBSD (``setfib=``). These were added to +ensure UDP responses go out over the same interface the query came in on if +there are multiple interfaces configured on the same subnet, but there may be +some performance benefits as well as the kernel does not have to go through the +network interface selection process. + +.. code:: text + + server: + ip-address: 192.0.2.1 bindtodevice=yes setfib= + +.. Note:: FreeBSD does not create extra routing tables on demand. Consult the + FreeBSD Handbook, forums, etc. for information on how to configure + multiple routing tables. + +Combining Options +----------------- + +Field tests have shown best performance is achieved by combining the +aforementioned options so that each network interface is essentially bound to a +specific core. To do so, use one IP address per server process, pin that process +to a designated core and bind directly to the network interface device. + +.. code:: text + + server: + server-count: 2 + cpu-affinity: 0 1 2 + server-1-cpu-affinity: 0 + server-2-cpu-affinity: 1 + xfrd-cpu-affinity: 2 + ip-address: 192.0.2.1 servers=1 bindtodevice=yes setfib=1 + ip-address: 192.0.2.2 servers=2 bindtodevice=yes setfib=2 + +The above snippet serves as an example on how to use the configuration options. +Which cores, IP addresses and routing tables are best used depends entirely on +the hardware and network layout. Be sure to test extensively before using the +options. \ No newline at end of file diff --git a/doc/manual/running/using-tsig.rst b/doc/manual/running/using-tsig.rst new file mode 100644 index 00000000..59c946b8 --- /dev/null +++ b/doc/manual/running/using-tsig.rst @@ -0,0 +1,36 @@ +Using Transaction Signature (TSIG) +================================== + +NSD supports Transaction Signature (TSIG) for zone transfer and for notify +sending and receiving, for any query to the server. + +TSIG keys are based on shared secrets. These must be configured in the config +file. To keep the secret in a separate file use ``include: "filename"`` to +include that file. + +An example TSIG key named :file:`sec1_key`: + +.. code:: text + + key: + name: "sec1_key" + algorithm: hmac-md5 + secret: "6KM6qiKfwfEpamEq72HQdA==" + +This key can then be used for any query to the NSD server. NSD will check if the +signature is valid, and if so, return a signed answer. Unsigned queries will be +given unsigned replies. + +The key can be used to restrict the access control lists, for example to only +allow zone transfer with the key, by listing the key name on the access control +line. + +.. code:: text + + # provides AXFR to the subnet when TSIG is used. + provide-xfr: 10.11.12.0/24 sec1_key + # allow only notifications that are signed + allow-notify: 192.168.0.0/16 sec1_key + +If the TSIG key name is used in ``notify`` or ``request-xfr`` lines, the key is +used to sign the request/notification messages. \ No newline at end of file diff --git a/doc/manual/running/zone-expiry.rst b/doc/manual/running/zone-expiry.rst new file mode 100644 index 00000000..19317e28 --- /dev/null +++ b/doc/manual/running/zone-expiry.rst @@ -0,0 +1,40 @@ +Zone Expiry of Secondary Zones +============================== + +NSD will keep track of the status of secondary zones, according to the timing +values in the SOA record for the zone. When the refresh time of a zone is +reached, the serial number is checked and a zone transfer is started if the zone +has changed. Each primary server is tried in turn. + +Primary zones cannot expire so they are always served. Zones are interpreted +as primary zones if they have no ``request-xfr:`` statements in the config file. + +After the expire timeout (from the SOA record at the zone apex) is reached, the +zone becomes expired. NSD will return ``SERVFAIL`` for expired zones, and will +attempt to perform a zone transfer from any of the primaries. After a zone +transfer succeeds, or if the primary indicates that the SOA serial number is +still the same, the zone returns to an operational state. + +In contrast with e.g. BIND, the inception time for a secondary zone is stored on +disk (in ``xfrdfile: "xfrd.state"``), together with timeouts. If a secondary +zone acquisition time is recent enough, NSD can start serving a +zone immediately on loading, without querying the primary server. + +If a secondary zone has expired and no primaries can be reached, but NSD +should still serve the zone, delete the :file:`xfrd.state` +file, but leave the zone file for the zone intact. Make sure to stop NSD before +you delete the file, as NSD writes it on exit. Upon loading NSD will treat the +zone file that you as operator have provided as recent and will serve the zone. +Even though NSD will start to serve the zone immediately, the zone will expire +after the timeout is reached again. NSD will also attempt to confirm that you +have provided the correct data by polling the primaries. So when the primary +servers come back up, it will transfer the updated zone within seconds. + +It is possible to provide zone files for both primary and secondary +zones via alternative means (say from email or rsync). Reload with SIGHUP or +:command:`nsd-control reload` to read the new zone file contents into the name +database. When this is done the new zone will be served. For primary zones, NSD +will issue notifications to all configured ``notify:`` targets. For secondary +zones the above happens; NSD attempts to validate the zone from the primary +(checking its SOA serial number). diff --git a/doc/manual/zonefile.rst b/doc/manual/zonefile.rst new file mode 100644 index 00000000..ca743757 --- /dev/null +++ b/doc/manual/zonefile.rst @@ -0,0 +1,39 @@ +Zonefile example +================ + +On this page we give an example of a basic zone file and it's contents. + +We recommend using the :command:`nsd-checkzone` tool to verify that you have a working zone. + +Creating a zone +--------------- + +A minimal zone needs exactly one SOA (Source Of Authority) and one or more NS (Name Server) records. Refer to appropriate documentation of you need to learn about DNS basics. + +.. code:: bash + + $ORIGIN example.com. + $TTL 86400 ; default time-to-live for this zone + + example.com. IN SOA ns.example.com. noc.dns.example.org. ( + 2020080302 ;Serial + 7200 ;Refresh + 3600 ;Retry + 1209600 ;Expire + 3600 ;Negative response caching TTL + ) + + ; The nameservers that are authoritative for this zone. + NS example.com. + + ; A and AAAA records are for IPv4 and IPv6 addresses respectively + example.com. A 192.0.2.1 + AAAA 2001:db8::3 + + ; A CNAME redirects from www.example.com to example.com + www CNAME example.com. + + mail MX 10 example.com. + + +.. could add this structure eventually: