huan.wang@yueguanjia.com vor 5 Jahren
Commit
1f53277ab9
100 geänderte Dateien mit 17427 neuen und 0 gelöschten Zeilen
  1. 3 0
      .idea/.gitignore
  2. 6 0
      .idea/inspectionProfiles/profiles_settings.xml
  3. 7 0
      .idea/misc.xml
  4. 8 0
      .idea/modules.xml
  5. 6 0
      .idea/vcs.xml
  6. 11 0
      .idea/zm_admin.iml
  7. 0 0
      admin/__init__.py
  8. 3 0
      admin/admin.py
  9. 5 0
      admin/apps.py
  10. 0 0
      admin/migrations/__init__.py
  11. 40 0
      admin/models.py
  12. 3 0
      admin/tests.py
  13. 3 0
      admin/views.py
  14. 0 0
      courses/__init__.py
  15. 3 0
      courses/admin.py
  16. 5 0
      courses/apps.py
  17. 0 0
      courses/migrations/__init__.py
  18. 97 0
      courses/models.py
  19. 3 0
      courses/tests.py
  20. 3 0
      courses/views.py
  21. 22 0
      manage.py
  22. 0 0
      system/__init__.py
  23. 3 0
      system/admin.py
  24. 5 0
      system/apps.py
  25. 0 0
      system/migrations/__init__.py
  26. 40 0
      system/models.py
  27. 3 0
      system/tests.py
  28. 3 0
      system/views.py
  29. 0 0
      user/__init__.py
  30. 3 0
      user/admin.py
  31. 5 0
      user/apps.py
  32. 0 0
      user/migrations/__init__.py
  33. 68 0
      user/models.py
  34. 3 0
      user/tests.py
  35. 3 0
      user/views.py
  36. 958 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/AUTHORS
  37. 1 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/INSTALLER
  38. 27 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/LICENSE
  39. 266 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/LICENSE.python
  40. 89 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/METADATA
  41. 4220 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/RECORD
  42. 5 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/WHEEL
  43. 3 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/entry_points.txt
  44. 1 0
      venv/Lib/site-packages/Django-3.0.4.dist-info/top_level.txt
  45. 1 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/INSTALLER
  46. 19 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/LICENSE
  47. 181 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/METADATA
  48. 49 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/RECORD
  49. 6 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/WHEEL
  50. 1 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/pbr.json
  51. 1 0
      venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/top_level.txt
  52. 1 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/INSTALLER
  53. 27 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/LICENSE
  54. 225 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/METADATA
  55. 24 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/RECORD
  56. 6 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/WHEEL
  57. 1 0
      venv/Lib/site-packages/asgiref-3.2.3.dist-info/top_level.txt
  58. 1 0
      venv/Lib/site-packages/asgiref/__init__.py
  59. 47 0
      venv/Lib/site-packages/asgiref/compatibility.py
  60. 86 0
      venv/Lib/site-packages/asgiref/current_thread_executor.py
  61. 111 0
      venv/Lib/site-packages/asgiref/local.py
  62. 154 0
      venv/Lib/site-packages/asgiref/server.py
  63. 304 0
      venv/Lib/site-packages/asgiref/sync.py
  64. 97 0
      venv/Lib/site-packages/asgiref/testing.py
  65. 128 0
      venv/Lib/site-packages/asgiref/timeout.py
  66. 145 0
      venv/Lib/site-packages/asgiref/wsgi.py
  67. 24 0
      venv/Lib/site-packages/django/__init__.py
  68. 9 0
      venv/Lib/site-packages/django/__main__.py
  69. 4 0
      venv/Lib/site-packages/django/apps/__init__.py
  70. 216 0
      venv/Lib/site-packages/django/apps/config.py
  71. 427 0
      venv/Lib/site-packages/django/apps/registry.py
  72. 5 0
      venv/Lib/site-packages/django/bin/django-admin.py
  73. 236 0
      venv/Lib/site-packages/django/conf/__init__.py
  74. 0 0
      venv/Lib/site-packages/django/conf/app_template/__init__.py-tpl
  75. 3 0
      venv/Lib/site-packages/django/conf/app_template/admin.py-tpl
  76. 5 0
      venv/Lib/site-packages/django/conf/app_template/apps.py-tpl
  77. 0 0
      venv/Lib/site-packages/django/conf/app_template/migrations/__init__.py-tpl
  78. 3 0
      venv/Lib/site-packages/django/conf/app_template/models.py-tpl
  79. 3 0
      venv/Lib/site-packages/django/conf/app_template/tests.py-tpl
  80. 3 0
      venv/Lib/site-packages/django/conf/app_template/views.py-tpl
  81. 639 0
      venv/Lib/site-packages/django/conf/global_settings.py
  82. 581 0
      venv/Lib/site-packages/django/conf/locale/__init__.py
  83. BIN
      venv/Lib/site-packages/django/conf/locale/af/LC_MESSAGES/django.mo
  84. 1249 0
      venv/Lib/site-packages/django/conf/locale/af/LC_MESSAGES/django.po
  85. BIN
      venv/Lib/site-packages/django/conf/locale/ar/LC_MESSAGES/django.mo
  86. 1322 0
      venv/Lib/site-packages/django/conf/locale/ar/LC_MESSAGES/django.po
  87. 0 0
      venv/Lib/site-packages/django/conf/locale/ar/__init__.py
  88. 21 0
      venv/Lib/site-packages/django/conf/locale/ar/formats.py
  89. BIN
      venv/Lib/site-packages/django/conf/locale/ast/LC_MESSAGES/django.mo
  90. 1237 0
      venv/Lib/site-packages/django/conf/locale/ast/LC_MESSAGES/django.po
  91. BIN
      venv/Lib/site-packages/django/conf/locale/az/LC_MESSAGES/django.mo
  92. 1278 0
      venv/Lib/site-packages/django/conf/locale/az/LC_MESSAGES/django.po
  93. 0 0
      venv/Lib/site-packages/django/conf/locale/az/__init__.py
  94. 32 0
      venv/Lib/site-packages/django/conf/locale/az/formats.py
  95. BIN
      venv/Lib/site-packages/django/conf/locale/be/LC_MESSAGES/django.mo
  96. 1329 0
      venv/Lib/site-packages/django/conf/locale/be/LC_MESSAGES/django.po
  97. BIN
      venv/Lib/site-packages/django/conf/locale/bg/LC_MESSAGES/django.mo
  98. 1252 0
      venv/Lib/site-packages/django/conf/locale/bg/LC_MESSAGES/django.po
  99. 0 0
      venv/Lib/site-packages/django/conf/locale/bg/__init__.py
  100. 0 0
      venv/Lib/site-packages/django/conf/locale/bg/formats.py

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+
+# Default ignored files
+/workspace.xml

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (zm_admin)" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/zm_admin.iml" filepath="$PROJECT_DIR$/.idea/zm_admin.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 11 - 0
.idea/zm_admin.iml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="TestRunnerService">
+    <option name="PROJECT_TEST_RUNNER" value="Unittests" />
+  </component>
+</module>

+ 0 - 0
admin/__init__.py


+ 3 - 0
admin/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
admin/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class AdminConfig(AppConfig):
+    name = 'admin'

+ 0 - 0
admin/migrations/__init__.py


+ 40 - 0
admin/models.py

@@ -0,0 +1,40 @@
+from django.db import models
+
+# Create your models here.
+
+
+class AdminPermission(models.Model):
+    path = models.CharField(max_length=100, blank=True, null=True)
+    component = models.CharField(max_length=200, blank=True, null=True)
+    name = models.CharField(max_length=50, blank=True, null=True)
+    showname = models.CharField(max_length=50, blank=True, null=True)
+    redirect = models.CharField(max_length=100, blank=True, null=True)
+    hidden = models.IntegerField(blank=True, null=True)
+    alwaysshow = models.IntegerField(db_column='alwaysShow', blank=True, null=True)  # Field name made lowercase.
+    meta_title = models.CharField(max_length=100, blank=True, null=True)
+    meta_icon = models.CharField(max_length=100, blank=True, null=True)
+    relation = models.CharField(max_length=50, blank=True, null=True)
+    parentid = models.IntegerField(blank=True, null=True)
+    seq = models.IntegerField(blank=True, null=True)
+    cache = models.IntegerField(blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'admin_permission'
+
+
+class AdminRole(models.Model):
+    name = models.CharField(max_length=20, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'admin_role'
+
+
+class AdminRolePermission(models.Model):
+    role_id = models.IntegerField(blank=True, null=True)
+    per_id = models.IntegerField(blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'admin_role_permission'

+ 3 - 0
admin/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
admin/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
courses/__init__.py


+ 3 - 0
courses/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
courses/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class CoursesConfig(AppConfig):
+    name = 'courses'

+ 0 - 0
courses/migrations/__init__.py


+ 97 - 0
courses/models.py

@@ -0,0 +1,97 @@
+from django.db import models
+
+# Create your models here.
+
+
+class Courses(models.Model):
+    code = models.CharField(max_length=20)
+    type = models.IntegerField(blank=True, null=True)
+    phase = models.IntegerField(blank=True, null=True)
+    name = models.CharField(max_length=100, blank=True, null=True)
+    desc = models.CharField(max_length=200, blank=True, null=True)
+    title_list = models.CharField(max_length=200, blank=True, null=True)
+    target = models.CharField(max_length=200, blank=True, null=True)
+    keynote_list = models.CharField(max_length=200, blank=True, null=True)
+    result = models.CharField(max_length=200, blank=True, null=True)
+    process_list = models.CharField(max_length=200, blank=True, null=True)
+    course_ware = models.CharField(max_length=200, blank=True, null=True)
+    course_video = models.CharField(max_length=200, blank=True, null=True)
+    attachment_list = models.CharField(max_length=200, blank=True, null=True)
+    practise = models.CharField(max_length=200, blank=True, null=True)
+    task = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses'
+
+
+class CoursesAttachment(models.Model):
+    name = models.CharField(max_length=50, blank=True, null=True)
+    href = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_attachment'
+
+
+class CoursesKeynote(models.Model):
+    name = models.CharField(max_length=50, blank=True, null=True)
+    content = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_keynote'
+
+
+class CoursesMap(models.Model):
+    code = models.CharField(max_length=50, blank=True, null=True)
+    name = models.CharField(max_length=50, blank=True, null=True)
+    desc = models.CharField(max_length=200, blank=True, null=True)
+    title = models.CharField(max_length=200, blank=True, null=True)
+    list_img = models.CharField(max_length=200, blank=True, null=True)
+    main_img = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_map'
+
+
+class CoursesMapDetail(models.Model):
+    map_id = models.IntegerField(blank=True, null=True)
+    courses_id = models.IntegerField(blank=True, null=True)
+    title = models.CharField(max_length=100, blank=True, null=True)
+    seq = models.IntegerField(blank=True, null=True)
+    init_img = models.CharField(max_length=200, blank=True, null=True)
+    finish_img = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_map_detail'
+
+
+class CoursesProcess(models.Model):
+    name = models.CharField(max_length=50, blank=True, null=True)
+    content = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_process'
+
+
+class CoursesTitle(models.Model):
+    name = models.CharField(max_length=50, blank=True, null=True)
+    img = models.CharField(max_length=200, blank=True, null=True)
+    content = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_title'
+
+
+class CoursesType(models.Model):
+    code = models.CharField(max_length=20, blank=True, null=True)
+    name = models.CharField(max_length=20, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'courses_type'

+ 3 - 0
courses/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
courses/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 22 - 0
manage.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+from builtins import ImportError
+
+
+def main():
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'zm_admin.settings')
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        )(exc)
+    execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+    main()

+ 0 - 0
system/__init__.py


+ 3 - 0
system/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
system/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SystemConfig(AppConfig):
+    name = 'system'

+ 0 - 0
system/migrations/__init__.py


+ 40 - 0
system/models.py

@@ -0,0 +1,40 @@
+from django.db import models
+
+# Create your models here.
+
+
+class SysPermission(models.Model):
+    path = models.CharField(max_length=100, blank=True, null=True)
+    component = models.CharField(max_length=200, blank=True, null=True)
+    name = models.CharField(max_length=50, blank=True, null=True)
+    showname = models.CharField(max_length=50, blank=True, null=True)
+    redirect = models.CharField(max_length=100, blank=True, null=True)
+    hidden = models.IntegerField(blank=True, null=True)
+    alwaysshow = models.IntegerField(db_column='alwaysShow', blank=True, null=True)  # Field name made lowercase.
+    meta_title = models.CharField(max_length=100, blank=True, null=True)
+    meta_icon = models.CharField(max_length=100, blank=True, null=True)
+    relation = models.CharField(max_length=50, blank=True, null=True)
+    parentid = models.IntegerField(blank=True, null=True)
+    seq = models.IntegerField(blank=True, null=True)
+    cache = models.IntegerField(blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'sys_permission'
+
+
+class SysRole(models.Model):
+    name = models.CharField(max_length=20, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'sys_role'
+
+
+class SysRolePermission(models.Model):
+    role_id = models.IntegerField(blank=True, null=True)
+    per_id = models.IntegerField(blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'sys_role_permission'

+ 3 - 0
system/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
system/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
user/__init__.py


+ 3 - 0
user/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
user/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class UserConfig(AppConfig):
+    name = 'user'

+ 0 - 0
user/migrations/__init__.py


+ 68 - 0
user/models.py

@@ -0,0 +1,68 @@
+from django.db import models
+
+# Create your models here.
+
+
+class User(models.Model):
+    name = models.CharField(max_length=50, blank=True, null=True)
+    email = models.CharField(max_length=50, blank=True, null=True)
+    phone = models.CharField(max_length=20, blank=True, null=True)
+    password = models.CharField(max_length=50, blank=True, null=True)
+    status = models.IntegerField(blank=True, null=True)
+    org = models.IntegerField(blank=True, null=True)
+    role = models.IntegerField(blank=True, null=True)
+    create_at = models.DateTimeField(blank=True, null=True)
+    update_at = models.DateTimeField(blank=True, null=True)
+    last_login_time = models.DateTimeField(blank=True, null=True)
+    introducer = models.IntegerField(blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'user'
+
+
+class UserProfiles(models.Model):
+    userid = models.IntegerField(blank=True, null=True)
+    gender = models.IntegerField(blank=True, null=True)
+    school = models.CharField(max_length=50, blank=True, null=True)
+    grade = models.IntegerField(blank=True, null=True)
+    provincial = models.CharField(max_length=50, blank=True, null=True)
+    city = models.CharField(max_length=50, blank=True, null=True)
+    street = models.CharField(max_length=150, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'user_profiles'
+
+
+class UserTask(models.Model):
+    user_id = models.IntegerField(blank=True, null=True)
+    map_id = models.IntegerField(blank=True, null=True)
+    courses_id = models.IntegerField(blank=True, null=True)
+    href = models.CharField(max_length=100, blank=True, null=True)
+    content = models.CharField(max_length=200, blank=True, null=True)
+    lecturer_id = models.IntegerField(blank=True, null=True)
+    remarks = models.CharField(max_length=200, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'user_task'
+
+
+class UserWechat(models.Model):
+    userid = models.IntegerField(blank=True, null=True)
+    openid = models.CharField(max_length=100, blank=True, null=True)
+    sessionkey = models.CharField(max_length=100, blank=True, null=True)
+    phone = models.CharField(max_length=15, blank=True, null=True)
+    nikename = models.CharField(max_length=100, blank=True, null=True)
+    gender = models.IntegerField(blank=True, null=True)
+    avatarurl = models.CharField(db_column='avatarUrl', max_length=100, blank=True, null=True)  # Field name made lowercase.
+    countrycode = models.CharField(db_column='countryCode', max_length=100, blank=True, null=True)  # Field name made lowercase.
+    country = models.CharField(max_length=50, blank=True, null=True)
+    province = models.CharField(max_length=50, blank=True, null=True)
+    city = models.CharField(max_length=50, blank=True, null=True)
+    language = models.CharField(max_length=50, blank=True, null=True)
+
+    class Meta:
+        managed = False
+        db_table = 'user_wechat'

+ 3 - 0
user/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
user/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 958 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/AUTHORS

@@ -0,0 +1,958 @@
+Django was originally created in late 2003 at World Online, the Web division
+of the Lawrence Journal-World newspaper in Lawrence, Kansas.
+
+Here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --
+people who have submitted patches, reported bugs, added translations, helped
+answer newbie questions, and generally made Django that much better:
+
+    Aaron Cannon <cannona@fireantproductions.com>
+    Aaron Swartz <http://www.aaronsw.com/>
+    Aaron T. Myers <atmyers@gmail.com>
+    Abeer Upadhyay <ab.esquarer@gmail.com>
+    Abhijeet Viswa <abhijeetviswa@gmail.com>
+    Abhinav Patil <https://github.com/ubadub/>
+    Abhishek Gautam <abhishekg1128@yahoo.com>
+    Adam Allred <adam.w.allred@gmail.com>
+    Adam Bogdał <adam@bogdal.pl>
+    Adam Donaghy
+    Adam Johnson <https://github.com/adamchainz>
+    Adam Malinowski <https://adammalinowski.co.uk/>
+    Adam Vandenberg
+    Adiyat Mubarak <adiyatmubarak@gmail.com>
+    Adnan Umer <u.adnan@outlook.com>
+    Adrian Holovaty <adrian@holovaty.com>
+    Adrien Lemaire <lemaire.adrien@gmail.com>
+    Afonso Fernández Nogueira <fonzzo.django@gmail.com>
+    AgarFu <heaven@croasanaso.sytes.net>
+    Ahmad Alhashemi <trans@ahmadh.com>
+    Ahmad Al-Ibrahim
+    Ahmed Eltawela <https://github.com/ahmedabt>
+    ajs <adi@sieker.info>
+    Akash Agrawal <akashrocksha@gmail.com>
+    Akis Kesoglou <akiskesoglou@gmail.com>
+    Aksel Ethem <aksel.ethem@gmail.com>
+    Akshesh Doshi <aksheshdoshi+django@gmail.com>
+    alang@bright-green.com
+    Alasdair Nicol <https://al.sdair.co.uk/>
+    Albert Wang <https://github.com/albertyw/>
+    Alcides Fonseca
+    Aleksandra Sendecka <asendecka@hauru.eu>
+    Aleksi Häkli <aleksi.hakli@iki.fi>
+    Alexander Dutton <dev@alexdutton.co.uk>
+    Alexander Myodov <alex@myodov.com>
+    Alexandr Tatarinov <tatarinov1997@gmail.com>
+    Alex Becker <https://alexcbecker.net/>
+    Alex Couper <http://alexcouper.com/>
+    Alex Dedul
+    Alex Gaynor <alex.gaynor@gmail.com>
+    Alex Hill <alex@hill.net.au>
+    Alex Ogier <alex.ogier@gmail.com>
+    Alex Robbins <alexander.j.robbins@gmail.com>
+    Alexey Boriskin <alex@boriskin.me>
+    Alexey Tsivunin <most-208@yandex.ru>
+    Aljosa Mohorovic <aljosa.mohorovic@gmail.com>
+    Amit Chakradeo <https://amit.chakradeo.net/>
+    Amit Ramon <amit.ramon@gmail.com>
+    Amit Upadhyay <http://www.amitu.com/blog/>
+    A. Murat Eren <meren@pardus.org.tr>
+    Ana Belen Sarabia <belensarabia@gmail.com>
+    Ana Krivokapic <https://github.com/infraredgirl>
+    Andi Albrecht <albrecht.andi@gmail.com>
+    André Ericson <de.ericson@gmail.com>
+    Andrei Kulakov <andrei.avk@gmail.com>
+    Andreas
+    Andreas Mock <andreas.mock@web.de>
+    Andreas Pelme <andreas@pelme.se>
+    Andrés Torres Marroquín <andres.torres.marroquin@gmail.com>
+    Andrew Brehaut <https://brehaut.net/blog>
+    Andrew Clark <amclark7@gmail.com>
+    Andrew Durdin <adurdin@gmail.com>
+    Andrew Godwin <andrew@aeracode.org>
+    Andrew Pinkham <http://AndrewsForge.com>
+    Andrews Medina <andrewsmedina@gmail.com>
+    Andriy Sokolovskiy <me@asokolovskiy.com>
+    Andy Dustman <farcepest@gmail.com>
+    Andy Gayton <andy-django@thecablelounge.com>
+    andy@jadedplanet.net
+    Anssi Kääriäinen <akaariai@gmail.com>
+    ant9000@netwise.it
+    Anthony Briggs <anthony.briggs@gmail.com>
+    Anton Samarchyan <desecho@gmail.com>
+    Antoni Aloy
+    Antonio Cavedoni <http://cavedoni.com/>
+    Antonis Christofides <anthony@itia.ntua.gr>
+    Antti Haapala <antti@industrialwebandmagic.com>
+    Antti Kaihola <http://djangopeople.net/akaihola/>
+    Anubhav Joshi <anubhav9042@gmail.com>
+    Aram Dulyan
+    arien <regexbot@gmail.com>
+    Armin Ronacher
+    Aron Podrigal <aronp@guaranteedplus.com>
+    Artem Gnilov <boobsd@gmail.com>
+    Arthur <avandorp@gmail.com>
+    Arthur Koziel <http://arthurkoziel.com>
+    Arthur Rio <arthur.rio44@gmail.com>
+    Arvis Bickovskis <viestards.lists@gmail.com>
+    Aryeh Leib Taurog <http://www.aryehleib.com/>
+    A S Alam <aalam@users.sf.net>
+    Asif Saif Uddin <auvipy@gmail.com>
+    atlithorn <atlithorn@gmail.com>
+    Audrey Roy <http://audreymroy.com/>
+    av0000@mail.ru
+    Axel Haustant <noirbizarre@gmail.com>
+    Aymeric Augustin <aymeric.augustin@m4x.org>
+    Bahadır Kandemir <bahadir@pardus.org.tr>
+    Baishampayan Ghose
+    Baptiste Mispelon <bmispelon@gmail.com>
+    Barry Pederson <bp@barryp.org>
+    Bartolome Sanchez Salado <i42sasab@uco.es>
+    Bartosz Grabski <bartosz.grabski@gmail.com>
+    Bashar Al-Abdulhadi
+    Bastian Kleineidam <calvin@debian.org>
+    Batiste Bieler <batiste.bieler@gmail.com>
+    Batman
+    Batuhan Taskaya <batuhanosmantaskaya@gmail.com>
+    Baurzhan Ismagulov <ibr@radix50.net>
+    Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
+    Ben Firshman <ben@firshman.co.uk>
+    Ben Godfrey <http://aftnn.org>
+    Benjamin Wohlwend <piquadrat@gmail.com>
+    Ben Khoo <khoobks@westnet.com.au>
+    Ben Slavin <benjamin.slavin@gmail.com>
+    Ben Sturmfels <ben@sturm.com.au>
+    Berker Peksag <berker.peksag@gmail.com>
+    Bernd Schlapsi
+    Bernhard Essl <me@bernhardessl.com>
+    berto
+    Bill Fenner <fenner@gmail.com>
+    Bjørn Stabell <bjorn@exoweb.net>
+    Bo Marchman <bo.marchman@gmail.com>
+    Bogdan Mateescu
+    Bojan Mihelac <bmihelac@mihelac.org>
+    Bouke Haarsma <bouke@haarsma.eu>
+    Božidar Benko <bbenko@gmail.com>
+    Brad Melin <melinbrad@gmail.com>
+    Brandon Chinn <https://brandonchinn178.github.io/>
+    Brant Harris
+    Brendan Hayward <brendanhayward85@gmail.com>
+    Brendan Quinn <brendan@cluefulmedia.com>
+    Brenton Simpson <http://theillustratedlife.com>
+    Brett Cannon <brett@python.org>
+    Brett Hoerner <bretthoerner@bretthoerner.com>
+    Brian Beck <http://blog.brianbeck.com/>
+    Brian Fabian Crain <http://www.bfc.do/>
+    Brian Harring <ferringb@gmail.com>
+    Brian Ray <http://brianray.chipy.org/>
+    Brian Rosner <brosner@gmail.com>
+    Bruce Kroeze <https://coderseye.com/>
+    Bruno Alla <alla.brunoo@gmail.com>
+    Bruno Renié <buburno@gmail.com>
+    brut.alll@gmail.com
+    Bryan Chow <bryan at verdjn dot com>
+    Bryan Veloso <bryan@revyver.com>
+    bthomas
+    btoll@bestweb.net
+    C8E
+    Caio Ariede <caio.ariede@gmail.com>
+    Calvin Spealman <ironfroggy@gmail.com>
+    Cameron Curry
+    Cameron Knight (ckknight)
+    Can Burak Çilingir <canburak@cs.bilgi.edu.tr>
+    Can Sarıgöl <ertugrulsarigol@gmail.com>
+    Carl Meyer <carl@oddbird.net>
+    Carles Pina i Estany <carles@pina.cat>
+    Carlos Eduardo de Paula <carlosedp@gmail.com>
+    Carlos Matías de la Torre <cmdelatorre@gmail.com>
+    Carlton Gibson <carlton.gibson@noumenal.es>
+    cedric@terramater.net
+    Chad Whitman <chad.whitman@icloud.com>
+    ChaosKCW
+    Charlie Leifer <coleifer@gmail.com>
+    charly.wilhelm@gmail.com
+    Chason Chaffin <chason@gmail.com>
+    Cheng Zhang
+    Chris Adams
+    Chris Beaven <smileychris@gmail.com>
+    Chris Bennett <chrisrbennett@yahoo.com>
+    Chris Cahoon <chris.cahoon@gmail.com>
+    Chris Chamberlin <dja@cdc.msbx.net>
+    Chris Jerdonek
+    Chris Jones <chris@brack3t.com>
+    Chris Lamb <chris@chris-lamb.co.uk>
+    Chris Streeter <chris@chrisstreeter.com>
+    Christian Barcenas <christian@cbarcenas.com>
+    Christian Metts
+    Christian Oudard <christian.oudard@gmail.com>
+    Christian Tanzer <tanzer@swing.co.at>
+    Christophe Pettus <xof@thebuild.com>
+    Christopher Adams <http://christopheradams.info>
+    Christopher Babiak <chrisbabiak@gmail.com>
+    Christopher Lenz <https://www.cmlenz.net/>
+    Christoph Mędrela <chris.medrela@gmail.com>
+    Chris Wagner <cw264701@ohio.edu>
+    Chris Wesseling <Chris.Wesseling@cwi.nl>
+    Chris Wilson <chris+github@qwirx.com>
+    Claude Paroz <claude@2xlibre.net>
+    Clint Ecker
+    colin@owlfish.com
+    Colin Wood <cwood06@gmail.com>
+    Collin Anderson <cmawebsite@gmail.com>
+    Collin Grady <collin@collingrady.com>
+    Craig Blaszczyk <masterjakul@gmail.com>
+    crankycoder@gmail.com
+    Curtis Maloney (FunkyBob) <curtis@tinbrain.net>
+    dackze+django@gmail.com
+    Dagur Páll Ammendrup <dagurp@gmail.com>
+    Dane Springmeyer
+    Dan Fairs <dan@fezconsulting.com>
+    Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
+    Daniel Duan <DaNmarner@gmail.com>
+    Daniele Procida <daniele@vurt.org>
+    Daniel Greenfeld
+    dAniel hAhler
+    Daniel Jilg <daniel@breakthesystem.org>
+    Daniel Lindsley <daniel@toastdriven.com>
+    Daniel Poelzleithner <https://poelzi.org/>
+    Daniel Pyrathon <pirosb3@gmail.com>
+    Daniel Roseman <http://roseman.org.uk/>
+    Daniel Tao <https://philosopherdeveloper.com/>
+    Daniel Wiesmann <daniel.wiesmann@gmail.com>
+    Danilo Bargen
+    Dan Johnson <danj.py@gmail.com>
+    Dan Palmer <dan@danpalmer.me>
+    Dan Poirier <poirier@pobox.com>
+    Dan Stephenson <http://dan.io/>
+    Dan Watson <http://danwatson.net/>
+    dave@thebarproject.com
+    David Ascher <https://ascher.ca/>
+    David Avsajanishvili <avsd05@gmail.com>
+    David Blewett <david@dawninglight.net>
+    David Brenneman <http://davidbrenneman.com>
+    David Cramer <dcramer@gmail.com>
+    David Danier <david.danier@team23.de>
+    David Eklund
+    David Foster <david@dafoster.net>
+    David Gouldin <dgouldin@gmail.com>
+    david@kazserve.org
+    David Krauth
+    David Larlet <https://larlet.fr/david/>
+    David Reynolds <david@reynoldsfamily.org.uk>
+    David Sanders <dsanders11@ucsbalum.com>
+    David Schein
+    David Tulig <david.tulig@gmail.com>
+    David Wobrock <david.wobrock@gmail.com>
+    Davide Ceretti <dav.ceretti@gmail.com>
+    Deepak Thukral <deep.thukral@gmail.com>
+    Denis Kuzmichyov <kuzmichyov@gmail.com>
+    Derek Willis <http://blog.thescoop.org/>
+    Deric Crago <deric.crago@gmail.com>
+    deric@monowerks.com
+    Deryck Hodge <http://www.devurandom.org/>
+    Dimitris Glezos <dimitris@glezos.com>
+    Dirk Datzert <dummy@habmalnefrage.de>
+    Dirk Eschler <dirk.eschler@gmx.net>
+    Dmitri Fedortchenko <zeraien@gmail.com>
+    Dmitry Jemerov <intelliyole@gmail.com>
+    dne@mayonnaise.net
+    Dolan Antenucci <antenucci.d@gmail.com>
+    Donald Harvey <donald@donaldharvey.co.uk>
+    Donald Stufft <donald@stufft.io>
+    Don Spaulding <donspauldingii@gmail.com>
+    Doug Beck <doug@douglasbeck.com>
+    Doug Napoleone <doug@dougma.com>
+    dready <wil@mojipage.com>
+    dusk@woofle.net
+    Ed Morley <https://github.com/edmorley>
+    eibaan@gmail.com
+    elky <http://elky.me/>
+    Emmanuelle Delescolle <https://github.com/nanuxbe>
+    Emil Stenström <em@kth.se>
+    enlight
+    Enrico <rico.bl@gmail.com>
+    Eric Boersma <eric.boersma@gmail.com>
+    Eric Brandwein <brandweineric@gmail.com>
+    Eric Floehr <eric@intellovations.com>
+    Eric Florenzano <floguy@gmail.com>
+    Eric Holscher <http://ericholscher.com>
+    Eric Moritz <http://eric.themoritzfamily.com/>
+    Eric Palakovich Carr <carreric@gmail.com>
+    Erik Karulf <erik@karulf.com>
+    Erik Romijn <django@solidlinks.nl>
+    eriks@win.tue.nl
+    Erwin Junge <erwin@junge.nl>
+    Esdras Beleza <linux@esdrasbeleza.com>
+    Espen Grindhaug <http://grindhaug.org/>
+    Eugene Lazutkin <http://lazutkin.com/blog/>
+    Evan Grim <https://github.com/egrim>
+    Fabrice Aneche <akh@nobugware.com>
+    favo@exoweb.net
+    fdr <drfarina@gmail.com>
+    Federico Capoano <nemesis@ninux.org>
+    Filip Noetzel <http://filip.noetzel.co.uk/>
+    Filip Wasilewski <filip.wasilewski@gmail.com>
+    Finn Gruwier Larsen <finn@gruwier.dk>
+    Flávio Juvenal da Silva Junior <flavio@vinta.com.br>
+    flavio.curella@gmail.com
+    Florian Apolloner <florian@apolloner.eu>
+    Florian Moussous <florian.moussous@gmail.com>
+    Francisco Albarran Cristobal <pahko.xd@gmail.com>
+    Francisco Couzo <franciscouzo@gmail.com>
+    François Freitag <mail@franek.fr>
+    Frank Tegtmeyer <fte@fte.to>
+    Frank Wierzbicki
+    Frank Wiles <frank@revsys.com>
+    František Malina <fmalina@gmail.com>
+    Fraser Nevett <mail@nevett.org>
+    Gabriel Grant <g@briel.ca>
+    Gabriel Hurley <gabriel@strikeawe.com>
+    gandalf@owca.info
+    Garry Lawrence
+    Garry Polley <garrympolley@gmail.com>
+    Garth Kidd <http://www.deadlybloodyserious.com/>
+    Gary Wilson <gary.wilson@gmail.com>
+    Gasper Koren
+    Gasper Zejn <zejn@kiberpipa.org>
+    Gavin Wahl <gavinwahl@gmail.com>
+    Ge Hanbin <xiaomiba0904@gmail.com>
+    geber@datacollect.com
+    Geert Vanderkelen
+    George Karpenkov <george@metaworld.ru>
+    George Song <george@damacy.net>
+    George Vilches <gav@thataddress.com>
+    Georg "Hugo" Bauer <gb@hugo.westfalen.de>
+    Georgi Stanojevski <glisha@gmail.com>
+    Gerardo Orozco <gerardo.orozco.mosqueda@gmail.com>
+    Gil Gonçalves <lursty@gmail.com>
+    Girish Kumar <girishkumarkh@gmail.com>
+    Gisle Aas <gisle@aas.no>
+    Glenn Maynard <glenn@zewt.org>
+    glin@seznam.cz
+    GomoX <gomo@datafull.com>
+    Gonzalo Saavedra <gonzalosaavedra@gmail.com>
+    Gopal Narayanan <gopastro@gmail.com>
+    Graham Carlyle <graham.carlyle@maplecroft.net>
+    Grant Jenks <contact@grantjenks.com>
+    Greg Chapple <gregchapple1@gmail.com>
+    Gregor Allensworth <greg.allensworth@gmail.com>
+    Gregor Müllegger <gregor@muellegger.de>
+    Grigory Fateyev <greg@dial.com.ru>
+    Grzegorz Ślusarek <grzegorz.slusarek@gmail.com>
+    Guilherme Mesquita Gondim <semente@taurinus.org>
+    Guillaume Pannatier <guillaume.pannatier@gmail.com>
+    Gustavo Picon
+    hambaloney
+    Hang Park <hangpark@kaist.ac.kr>
+    Hannes Ljungberg <hannes.ljungberg@gmail.com>
+    Hannes Struß <x@hannesstruss.de>
+    Hasan Ramezani <hasan.r67@gmail.com>
+    Hawkeye
+    Helen Sherwood-Taylor <helen@rrdlabs.co.uk>
+    Henrique Romano <onaiort@gmail.com>
+    Henry Dang <henrydangprg@gmail.com>
+    Hidde Bultsma
+    Himanshu Chauhan <hchauhan1404@outlook.com>
+    hipertracker@gmail.com
+    Hiroki Kiyohara <hirokiky@gmail.com>
+    Honza Král <honza.kral@gmail.com>
+    Horst Gutmann <zerok@zerokspot.com>
+    Hugo Osvaldo Barrera <hugo@barrera.io>
+    HyukJin Jang <wkdgurwls00@naver.com>
+    Hyun Mi Ae
+    Iacopo Spalletti <i.spalletti@nephila.it>
+    Ian A Wilson <http://ianawilson.com>
+    Ian Clelland <clelland@gmail.com>
+    Ian G. Kelly <ian.g.kelly@gmail.com>
+    Ian Holsman <http://feh.holsman.net/>
+    Ian Lee <IanLee1521@gmail.com>
+    Ibon <ibonso@gmail.com>
+    Idan Gazit <idan@gazit.me>
+    Idan Melamed
+    Ifedapo Olarewaju <ifedapoolarewaju@gmail.com>
+    Igor Kolar <ike@email.si>
+    Illia Volochii <illia.volochii@gmail.com>
+    Ilya Semenov <semenov@inetss.com>
+    Ingo Klöcker <djangoproject@ingo-kloecker.de>
+    I.S. van Oostveen <v.oostveen@idca.nl>
+    ivan.chelubeev@gmail.com
+    Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
+    Jaap Roes <jaap.roes@gmail.com>
+    Jack Moffitt <https://metajack.im/>
+    Jacob Burch <jacobburch@gmail.com>
+    Jacob Green
+    Jacob Kaplan-Moss <jacob@jacobian.org>
+    Jakub Paczkowski <jakub@paczkowski.eu>
+    Jakub Wilk <jwilk@jwilk.net>
+    Jakub Wiśniowski <restless.being@gmail.com>
+    james_027@yahoo.com
+    James Aylett
+    James Bennett <james@b-list.org>
+    James Murty
+    James Tauber <jtauber@jtauber.com>
+    James Timmins <jameshtimmins@gmail.com>
+    James Wheare <django@sparemint.com>
+    Jannis Leidel <jannis@leidel.info>
+    Janos Guljas
+    Jan Pazdziora
+    Jan Rademaker
+    Jarek Głowacki <jarekwg@gmail.com>
+    Jarek Zgoda <jarek.zgoda@gmail.com>
+    Jason Davies (Esaj) <https://www.jasondavies.com/>
+    Jason Huggins <http://www.jrandolph.com/blog/>
+    Jason McBrayer <http://www.carcosa.net/jason/>
+    jason.sidabras@gmail.com
+    Jason Yan <tailofthesun@gmail.com>
+    Javier Mansilla <javimansilla@gmail.com>
+    Jay Parlar <parlar@gmail.com>
+    Jay Welborn <jesse.welborn@gmail.com>
+    Jay Wineinger <jay.wineinger@gmail.com>
+    J. Clifford Dyer <jcd@sdf.lonestar.org>
+    jcrasta@gmail.com
+    jdetaeye
+    Jeff Anderson <jefferya@programmerq.net>
+    Jeff Balogh <jbalogh@mozilla.com>
+    Jeff Hui <jeffkhui@gmail.com>
+    Jeffrey Gelens <jeffrey@gelens.org>
+    Jeff Triplett <jeff.triplett@gmail.com>
+    Jeffrey Yancey <jeffrey.yancey@gmail.com>
+    Jens Diemer <django@htfx.de>
+    Jens Page
+    Jensen Cochran <jensen.cochran@gmail.com>
+    Jeong-Min Lee <falsetru@gmail.com>
+    Jérémie Blaser <blaserje@gmail.com>
+    Jeremy Bowman <https://github.com/jmbowman>
+    Jeremy Carbaugh <jcarbaugh@gmail.com>
+    Jeremy Dunck <jdunck@gmail.com>
+    Jeremy Lainé <jeremy.laine@m4x.org>
+    Jesse Young <adunar@gmail.com>
+    Jezeniel Zapanta <jezeniel.zapanta@gmail.com>
+    jhenry <jhenry@theonion.com>
+    Jim Dalton <jim.dalton@gmail.com>
+    Jimmy Song <jaejoon@gmail.com>
+    Jiri Barton
+    Joachim Jablon <ewjoachim@gmail.com>
+    Joao Oliveira <joaoxsouls@gmail.com>
+    Joao Pedro Silva <j.pedro004@gmail.com>
+    Joe Heck <http://www.rhonabwy.com/wp/>
+    Joel Bohman <mail@jbohman.com>
+    Joel Heenan <joelh-django@planetjoel.com>
+    Joel Watts <joel@joelwatts.com>
+    Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
+    Johan C. Stöver <johan@nilling.nl>
+    Johann Queuniet <johann.queuniet@adh.naellia.eu>
+    john@calixto.net
+    John D'Agostino <john.dagostino@gmail.com>
+    John D'Ambrosio <dambrosioj@gmail.com>
+    John Huddleston <huddlej@wwu.edu>
+    John Moses <moses.john.r@gmail.com>
+    John Paulett <john@paulett.org>
+    John Shaffer <jshaffer2112@gmail.com>
+    Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>
+    Jon Dufresne <jon.dufresne@gmail.com>
+    Jonas Haag <jonas@lophus.org>
+    Jonatas C. D. <jonatas.cd@gmail.com>
+    Jonathan Buchanan <jonathan.buchanan@gmail.com>
+    Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/>
+    Jonathan Feignberg <jdf@pobox.com>
+    Jonathan Slenders
+    Jordan Dimov <s3x3y1@gmail.com>
+    Jordi J. Tablada <jordi.joan@gmail.com>
+    Jorge Bastida <me@jorgebastida.com>
+    Jorge Gajon <gajon@gajon.org>
+    José Tomás Tocino García <josetomas.tocino@gmail.com>
+    Josef Rousek <josef.rousek@gmail.com>
+    Joseph Kocherhans <joseph@jkocherhans.com>
+    Josh Smeaton <josh.smeaton@gmail.com>
+    Joshua Cannon <joshdcannon@gmail.com>
+    Joshua Ginsberg <jag@flowtheory.net>
+    Jozko Skrablin <jozko.skrablin@gmail.com>
+    J. Pablo Fernandez <pupeno@pupeno.com>
+    jpellerin@gmail.com
+    Juan Catalano <catalanojuan@gmail.com>
+    Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
+    Juan Pedro Fisanotti <fisadev@gmail.com>
+    Julia Elman
+    Julia Matsieva <julia.matsieva@gmail.com>
+    Julian Bez
+    Julien Phalip <jphalip@gmail.com>
+    Junyoung Choi <cupjoo@gmail.com>
+    junzhang.jn@gmail.com
+    Jure Cuhalev <gandalf@owca.info>
+    Justin Bronn <jbronn@gmail.com>
+    Justine Tunney <jtunney@gmail.com>
+    Justin Lilly <justinlilly@gmail.com>
+    Justin Michalicek <jmichalicek@gmail.com>
+    Justin Myles Holmes <justin@slashrootcafe.com>
+    Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
+    Kadesarin Sanjek
+    Karderio <karderio@gmail.com>
+    Karen Tracey <kmtracey@gmail.com>
+    Karol Sikora <elektrrrus@gmail.com>
+    Katherine “Kati” Michel <kthrnmichel@gmail.com>
+    Kathryn Killebrew <kathryn.killebrew@gmail.com>
+    Katie Miller <katie@sub50.com>
+    Keith Bussell <kbussell@gmail.com>
+    Kenneth Love <kennethlove@gmail.com>
+    Kent Hauser <kent@khauser.net>
+    Kevin Grinberg <kevin@kevingrinberg.com>
+    Kevin Kubasik <kevin@kubasik.net>
+    Kevin McConnell <kevin.mcconnell@gmail.com>
+    Kieran Holland <http://www.kieranholland.com>
+    kilian <kilian.cavalotti@lip6.fr>
+    Klaas van Schelven <klaas@vanschelven.com>
+    knox <christobzr@gmail.com>
+    konrad@gwu.edu
+    Kowito Charoenratchatabhan <kowito@felspar.com>
+    Krišjānis Vaiders <krisjanisvaiders@gmail.com>
+    krzysiek.pawlik@silvermedia.pl
+    Krzysztof Jurewicz <krzysztof.jurewicz@gmail.com>
+    Krzysztof Kulewski <kulewski@gmail.com>
+    kurtiss@meetro.com
+    Lakin Wecker <lakin@structuredabstraction.com>
+    Lars Yencken <lars.yencken@gmail.com>
+    Lau Bech Lauritzen
+    Laurent Luce <https://www.laurentluce.com/>
+    Laurent Rahuel <laurent.rahuel@gmail.com>
+    lcordier@point45.com
+    Leah Culver <leah.culver@gmail.com>
+    Leandra Finger <leandra.finger@gmail.com>
+    Lee Reilly <lee@leereilly.net>
+    Lee Sanghyuck <shlee322@elab.kr>
+    Leo "hylje" Honkanen <sealage@gmail.com>
+    Leo Shklovskii
+    Leo Soto <leo.soto@gmail.com>
+    lerouxb@gmail.com
+    Lex Berezhny <lex@damoti.com>
+    Liang Feng <hutuworm@gmail.com>
+    limodou
+    Lincoln Smith <lincoln.smith@anu.edu.au>
+    Loek van Gent <loek@barakken.nl>
+    Loïc Bistuer <loic.bistuer@sixmedia.com>
+    Lowe Thiderman <lowe.thiderman@gmail.com>
+    Luan Pablo <luanpab@gmail.com>
+    Lucas Connors <https://www.revolutiontech.ca/>
+    Luciano Ramalho
+    Ludvig Ericson <ludvig.ericson@gmail.com>
+    Luis C. Berrocal <luis.berrocal.1942@gmail.com>
+    Łukasz Langa <lukasz@langa.pl>
+    Łukasz Rekucki <lrekucki@gmail.com>
+    Luke Granger-Brown <django@lukegb.com>
+    Luke Plant <L.Plant.98@cantab.net>
+    Maciej Fijalkowski
+    Maciej Wiśniowski <pigletto@gmail.com>
+    Mads Jensen <https://github.com/atombrella>
+    Makoto Tsuyuki <mtsuyuki@gmail.com>
+    Malcolm Tredinnick
+    Manuel Saelices <msaelices@yaco.es>
+    Manuzhai
+    Marc Aymerich Gubern
+    Marc Egli <frog32@me.com>
+    Marcel Telka <marcel@telka.sk>
+    Marc Fargas <telenieko@telenieko.com>
+    Marc Garcia <marc.garcia@accopensys.com>
+    Marcin Wróbel
+    Marc Remolt <m.remolt@webmasters.de>
+    Marc Tamlyn <marc.tamlyn@gmail.com>
+    Marc-Aurèle Brothier <ma.brothier@gmail.com>
+    Marian Andre <django@andre.sk>
+    Marijn Vriens <marijn@metronomo.cl>
+    Mario Gonzalez <gonzalemario@gmail.com>
+    Mariusz Felisiak <felisiak.mariusz@gmail.com>
+    Mark Biggers <biggers@utsl.com>
+    Mark Gensler <mark.gensler@protonmail.com>
+    mark@junklight.com
+    Mark Lavin <markdlavin@gmail.com>
+    Mark Sandstrom <mark@deliciouslynerdy.com>
+    Markus Amalthea Magnuson <markus.magnuson@gmail.com>
+    Markus Holtermann <https://markusholtermann.eu>
+    Marten Kenbeek <marten.knbk+django@gmail.com>
+    Marti Raudsepp <marti@juffo.org>
+    martin.glueck@gmail.com
+    Martin Green
+    Martin Kosír <martin@martinkosir.net>
+    Martin Mahner <https://www.mahner.org/>
+    Martin Maney <http://www.chipy.org/Martin_Maney>
+    Martin von Gagern <gagern@google.com>
+    Mart Sõmermaa <http://mrts.pri.ee/>
+    Marty Alchin <gulopine@gamemusic.org>
+    masonsimon+django@gmail.com
+    Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
+    Massimo Scamarcia <massimo.scamarcia@gmail.com>
+    Mathieu Agopian <mathieu.agopian@gmail.com>
+    Matías Bordese
+    Matt Boersma <matt@sprout.org>
+    Matt Croydon <http://www.postneo.com/>
+    Matt Deacalion Stevens <matt@dirtymonkey.co.uk>
+    Matt Dennenbaum
+    Matthew Flanagan <https://wadofstuff.blogspot.com/>
+    Matthew Schinckel <matt@schinckel.net>
+    Matthew Somerville <matthew-django@dracos.co.uk>
+    Matthew Tretter <m@tthewwithanm.com>
+    Matthew Wilkes <matt@matthewwilkes.name>
+    Matthias Kestenholz <mk@406.ch>
+    Matthias Pronk <django@masida.nl>
+    Matt Hoskins <skaffenuk@googlemail.com>
+    Matt McClanahan <https://mmcc.cx/>
+    Matt Riggott
+    Matt Robenolt <m@robenolt.com>
+    Mattia Larentis <mattia@laretis.eu>
+    Mattia Procopio <promat85@gmail.com>
+    Mattias Loverot <mattias@stubin.se>
+    mattycakes@gmail.com
+    Max Burstein <http://maxburstein.com>
+    Max Derkachev <mderk@yandex.ru>
+    Maxime Lorant <maxime.lorant@gmail.com>
+    Maxime Turcotte <maxocub@riseup.net>
+    Maximilian Merz <django@mxmerz.de>
+    Maximillian Dornseif <md@hudora.de>
+    mccutchen@gmail.com
+    Meir Kriheli <http://mksoft.co.il/>
+    Michael Hall <mhall1@ualberta.ca>
+    Michael Josephson <http://www.sdjournal.com/>
+    Michael Manfre <mmanfre@gmail.com>
+    michael.mcewan@gmail.com
+    Michael Placentra II <someone@michaelplacentra2.net>
+    Michael Radziej <mir@noris.de>
+    Michael Sanders <m.r.sanders@gmail.com>
+    Michael Schwarz <michi.schwarz@gmail.com>
+    Michael Sinov <sihaelov@gmail.com>
+    Michael Thornhill <michael.thornhill@gmail.com>
+    Michal Chruszcz <troll@pld-linux.org>
+    michal@plovarna.cz
+    Michał Modzelewski <michal.modzelewski@gmail.com>
+    Mihai Damian <yang_damian@yahoo.com>
+    Mihai Preda <mihai_preda@yahoo.com>
+    Mikaël Barbero <mikael.barbero nospam at nospam free.fr>
+    Mike Axiak <axiak@mit.edu>
+    Mike Grouchy <https://mikegrouchy.com/>
+    Mike Malone <mjmalone@gmail.com>
+    Mike Richardson
+    Mike Wiacek <mjwiacek@google.com>
+    Mikhail Korobov <kmike84@googlemail.com>
+    Mikko Hellsing <mikko@sorl.net>
+    Mikołaj Siedlarek <mikolaj.siedlarek@gmail.com>
+    milkomeda
+    Milton Waddams
+    mitakummaa@gmail.com
+    mmarshall
+    Moayad Mardini <moayad.m@gmail.com>
+    Morgan Aubert <morgan.aubert@zoho.com>
+    Moritz Sichert <moritz.sichert@googlemail.com>
+    Morten Bagai <m@bagai.com>
+    msaelices <msaelices@gmail.com>
+    msundstr
+    Mushtaq Ali <mushtaak@gmail.com>
+    Mykola Zamkovoi <nickzam@gmail.com>
+    Nadège Michel <michel.nadege@gmail.com>
+    Nagy Károly <charlie@rendszergazda.com>
+    Nasimul Haque <nasim.haque@gmail.com>
+    Nasir Hussain <nasirhjafri@gmail.com>
+    Natalia Bidart <nataliabidart@gmail.com>
+    Nate Bragg <jonathan.bragg@alum.rpi.edu>
+    Nathan Gaberel <nathan@gnab.fr>
+    Neal Norwitz <nnorwitz@google.com>
+    Nebojša Dorđević
+    Ned Batchelder <https://nedbatchelder.com/>
+    Nena Kojadin <nena@kiberpipa.org>
+    Niall Dalton <niall.dalton12@gmail.com>
+    Niall Kelly <duke.sam.vimes@gmail.com>
+    Nick Efford <nick@efford.org>
+    Nick Lane <nick.lane.au@gmail.com>
+    Nick Pope <nick@nickpope.me.uk>
+    Nick Presta <nick@nickpresta.ca>
+    Nick Sandford <nick.sandford@gmail.com>
+    Nick Sarbicki <nick.a.sarbicki@gmail.com>
+    Niclas Olofsson <n@niclasolofsson.se>
+    Nicola Larosa <nico@teknico.net>
+    Nicolas Lara <nicolaslara@gmail.com>
+    Nicolas Noé <nicolas@niconoe.eu>
+    Niran Babalola <niran@niran.org>
+    Nis Jørgensen <nis@superlativ.dk>
+    Nowell Strite <https://nowell.strite.org/>
+    Nuno Mariz <nmariz@gmail.com>
+    oggie rob <oz.robharvey@gmail.com>
+    oggy <ognjen.maric@gmail.com>
+    Oliver Beattie <oliver@obeattie.com>
+    Oliver Rutherfurd <http://rutherfurd.net/>
+    Olivier Sels <olivier.sels@gmail.com>
+    Olivier Tabone <olivier.tabone@ripplemotion.fr>
+    Orestis Markou <orestis@orestis.gr>
+    Orne Brocaar <http://brocaar.com/>
+    Oscar Ramirez <tuxskar@gmail.com>
+    Ossama M. Khayat <okhayat@yahoo.com>
+    Owen Griffiths
+    Pablo Martín <goinnn@gmail.com>
+    Panos Laganakos <panos.laganakos@gmail.com>
+    Pascal Hartig <phartig@rdrei.net>
+    Pascal Varet
+    Patrik Sletmo <patrik.sletmo@gmail.com>
+    Paul Bissex <http://e-scribe.com/>
+    Paul Collier <paul@paul-collier.com>
+    Paul Collins <paul.collins.iii@gmail.com>
+    Paul Donohue <django@PaulSD.com>
+    Paul Lanier <planier@google.com>
+    Paul McLanahan <paul@mclanahan.net>
+    Paul McMillan <Paul@McMillan.ws>
+    Paulo Poiati <paulogpoiati@gmail.com>
+    Paulo Scardine <paulo@scardine.com.br>
+    Paul Smith <blinkylights23@gmail.com>
+    Pavel Kulikov <kulikovpavel@gmail.com>
+    pavithran s <pavithran.s@gmail.com>
+    Pavlo Kapyshin <i@93z.org>
+    permonik@mesias.brnonet.cz
+    Petar Marić <http://www.petarmaric.com/>
+    Pete Crosier <pete.crosier@gmail.com>
+    peter@mymart.com
+    Peter Sheats <sheats@gmail.com>
+    Peter van Kampen
+    Peter Zsoldos <http://zsoldosp.eu>
+    Pete Shinners <pete@shinners.org>
+    Petr Marhoun <petr.marhoun@gmail.com>
+    pgross@thoughtworks.com
+    phaedo <http://phaedo.cx/>
+    phil.h.smith@gmail.com
+    Philip Lindborg <philip.lindborg@gmail.com>
+    Philippe Raoult <philippe.raoult@n2nsoft.com>
+    phil@produxion.net
+    Piotr Jakimiak <piotr.jakimiak@gmail.com>
+    Piotr Lewandowski <piotr.lewandowski@gmail.com>
+    plisk
+    polpak@yahoo.com
+    pradeep.gowda@gmail.com
+    Preston Holmes <preston@ptone.com>
+    Preston Timmons <prestontimmons@gmail.com>
+    Priyansh Saxena <askpriyansh@gmail.com>
+    Przemysław Buczkowski <przemub@przemub.pl>
+    Przemysław Suliga <http://suligap.net>
+    Rachel Tobin <rmtobin@me.com>
+    Rachel Willmer <http://www.willmer.com/kb/>
+    Radek Švarz <https://www.svarz.cz/translate/>
+    Raffaele Salmaso <raffaele@salmaso.org>
+    Rajesh Dhawan <rajesh.dhawan@gmail.com>
+    Ramez Ashraf <ramezashraf@gmail.com>
+    Ramin Farajpour Cami <ramin.blackhat@gmail.com>
+    Ramiro Morales <ramiro@rmorales.net>
+    Ramon Saraiva <ramonsaraiva@gmail.com>
+    Ram Rachum <ram@rachum.com>
+    Randy Barlow <randy@electronsweatshop.com>
+    Raphaël Barrois <raphael.barrois@m4x.org>
+    Raphael Michel <mail@raphaelmichel.de>
+    Raúl Cumplido <raulcumplido@gmail.com>
+    Rebecca Smith <rebkwok@gmail.com>
+    Remco Wendt <remco.wendt@gmail.com>
+    Renaud Parent <renaud.parent@gmail.com>
+    Renbi Yu <averybigant@gmail.com>
+    Reza Mohammadi <reza@zeerak.ir>
+    rhettg@gmail.com
+    Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
+    ricardojbarrios@gmail.com
+    Riccardo Di Virgilio
+    Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
+    Richard Davies <richard.davies@elastichosts.com>
+    Richard House <Richard.House@i-logue.com>
+    Rick Wagner <rwagner@physics.ucsd.edu>
+    Rigel Di Scala <rigel.discala@propylon.com>
+    Robert Coup
+    Robert Myers <myer0052@gmail.com>
+    Roberto Aguilar <roberto@baremetal.io>
+    Robert Rock Howard <http://djangomojo.com/>
+    Robert Wittams
+    Rob Golding-Day <rob@golding-day.com>
+    Rob Hudson <https://rob.cogit8.org/>
+    Rob Nguyen <tienrobertnguyenn@gmail.com>
+    Robin Munn <http://www.geekforgod.com/>
+    Rodrigo Pinheiro Marques de Araújo <fenrrir@gmail.com>
+    Romain Garrigues <romain.garrigues.cs@gmail.com>
+    Ronny Haryanto <https://ronny.haryan.to/>
+    Ross Poulton <ross@rossp.org>
+    Rozza <ross.lawley@gmail.com>
+    Rudolph Froger <rfroger@estrate.nl>
+    Rudy Mutter
+    Rune Rønde Laursen <runerl@skjoldhoej.dk>
+    Russell Cloran <russell@rucus.net>
+    Russell Keith-Magee <russell@keith-magee.com>
+    Russ Webber
+    Ryan Hall <ryanhall989@gmail.com>
+    ryankanno
+    Ryan Kelly <ryan@rfk.id.au>
+    Ryan Niemeyer <https://profiles.google.com/ryan.niemeyer/about>
+    Ryan Rubin <ryanmrubin@gmail.com>
+    Ryno Mathee <rmathee@gmail.com>
+    Sachin Jat <sanch.jat@gmail.com>
+    Sam Newman <http://www.magpiebrain.com/>
+    Sander Dijkhuis <sander.dijkhuis@gmail.com>
+    Sanket Saurav <sanketsaurav@gmail.com>
+    Sanyam Khurana <sanyam.khurana01@gmail.com>
+    Sarthak Mehrish <sarthakmeh03@gmail.com>
+    schwank@gmail.com
+    Scot Hacker <shacker@birdhouse.org>
+    Scott Barr <scott@divisionbyzero.com.au>
+    Scott Fitsimones <scott@airgara.ge>
+    Scott Pashley <github@scottpashley.co.uk>
+    scott@staplefish.com
+    Sean Brant
+    Sebastian Hillig <sebastian.hillig@gmail.com>
+    Sebastian Spiegel <https://www.tivix.com/>
+    Segyo Myung <myungsekyo@gmail.com>
+    Selwin Ong <selwin@ui.co.id>
+    Sengtha Chay <sengtha@e-khmer.com>
+    Senko Rašić <senko.rasic@dobarkod.hr>
+    serbaut@gmail.com
+    Sergei Maertens <sergeimaertens@gmail.com>
+    Sergey Fedoseev <fedoseev.sergey@gmail.com>
+    Sergey Kolosov <m17.admin@gmail.com>
+    Seth Hill <sethrh@gmail.com>
+    Shai Berger <shai@platonix.com>
+    Shannon -jj Behrens <https://www.jjinux.com/>
+    Shawn Milochik <shawn@milochik.com>
+    Silvan Spross <silvan.spross@gmail.com>
+    Simeon Visser <http://simeonvisser.com>
+    Simon Blanchard
+    Simon Charette <charette.s@gmail.com>
+    Simon Greenhill <dev@simon.net.nz>
+    Simon Litchfield <simon@quo.com.au>
+    Simon Meers <simon@simonmeers.com>
+    Simon Williams
+    Simon Willison <simon@simonwillison.net>
+    Sjoerd Job Postmus
+    Slawek Mikula <slawek dot mikula at gmail dot com>
+    sloonz <simon.lipp@insa-lyon.fr>
+    smurf@smurf.noris.de
+    sopel
+    Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
+    Stanislas Guerra <stan@slashdev.me>
+    Stanislaus Madueke
+    Stanislav Karpov <work@stkrp.ru>
+    starrynight <cmorgh@gmail.com>
+    Stefan R. Filipek
+    Stefane Fermgier <sf@fermigier.com>
+    Stefano Rivera <stefano@rivera.za.net>
+    Stéphane Raimbault <stephane.raimbault@gmail.com>
+    Stephan Jaekel <steph@rdev.info>
+    Stephen Burrows <stephen.r.burrows@gmail.com>
+    Steven L. Smith (fvox13) <steven@stevenlsmith.com>
+    Steven Noorbergen (Xaroth) <xaroth+django@xaroth.nl>
+    Stuart Langridge <https://www.kryogenix.org/>
+    Subhav Gautam <subhavgautam@yahoo.co.uk>
+    Sujay S Kumar <sujay.skumar141295@gmail.com>
+    Sune Kirkeby <https://ibofobi.dk/>
+    Sung-Jin Hong <serialx.net@gmail.com>
+    SuperJared
+    Susan Tan <susan.tan.fleckerl@gmail.com>
+    Sutrisno Efendi <kangfend@gmail.com>
+    Swaroop C H <http://www.swaroopch.info>
+    Szilveszter Farkas <szilveszter.farkas@gmail.com>
+    Taavi Teska <taaviteska@gmail.com>
+    Tai Lee <real.human@mrmachine.net>
+    Takashi Matsuo <matsuo.takashi@gmail.com>
+    Tareque Hossain <http://www.codexn.com>
+    Taylor Mitchell <taylor.mitchell@gmail.com>
+    Terry Huang <terryh.tp@gmail.com>
+    thebjorn <bp@datakortet.no>
+    Thejaswi Puthraya <thejaswi.puthraya@gmail.com>
+    Thijs van Dien <thijs@vandien.net>
+    Thom Wiggers
+    Thomas Chaumeny <t.chaumeny@gmail.com>
+    Thomas Güttler <hv@tbz-pariv.de>
+    Thomas Kerpe <thomas@kerpe.net>
+    Thomas Sorrel
+    Thomas Steinacher <http://www.eggdrop.ch/>
+    Thomas Stromberg <tstromberg@google.com>
+    Thomas Tanner <tanner@gmx.net>
+    tibimicu@gmx.net
+    Tim Allen <tim@pyphilly.org>
+    Tim Givois <tim.givois.mendez@gmail.com>
+    Tim Graham <timograham@gmail.com>
+    Tim Heap <tim@timheap.me>
+    Tim Saylor <tim.saylor@gmail.com>
+    Tobias Kunze <rixx@cutebit.de>
+    Tobias McNulty <https://www.caktusgroup.com/blog/>
+    tobias@neuyork.de
+    Todd O'Bryan <toddobryan@mac.com>
+    Tom Christie <tom@tomchristie.com>
+    Tom Forbes <tom@tomforb.es>
+    Tom Insam
+    Tom Tobin
+    Tomáš Ehrlich <tomas.ehrlich@gmail.com>
+    Tomáš Kopeček <permonik@m6.cz>
+    Tome Cvitan <tome@cvitan.com>
+    Tomek Paczkowski <tomek@hauru.eu>
+    Tomer Chachamu
+    Tommy Beadle <tbeadle@gmail.com>
+    Tore Lundqvist <tore.lundqvist@gmail.com>
+    torne-django@wolfpuppy.org.uk
+    Travis Cline <travis.cline@gmail.com>
+    Travis Pinney
+    Travis Swicegood <travis@domain51.com>
+    Travis Terry <tdterry7@gmail.com>
+    Trevor Caira <trevor@caira.com>
+    Trey Long <trey@ktrl.com>
+    tstromberg@google.com
+    tt@gurgle.no
+    Tyler Tarabula <tyler.tarabula@gmail.com>
+    Tyson Clugg <tyson@clugg.net>
+    Tyson Tate <tyson@fallingbullets.com>
+    Unai Zalakain <unai@gisa-elkartea.org>
+    Valentina Mukhamedzhanova <umirra@gmail.com>
+    valtron
+    Vasiliy Stavenko <stavenko@gmail.com>
+    Vasil Vangelovski
+    Vibhu Agarwal <vibhu-agarwal.github.io>
+    Victor Andrée
+    viestards.lists@gmail.com
+    Viktor Danyliuk <v.v.danyliuk@gmail.com>
+    Ville Säävuori <https://www.unessa.net/>
+    Vinay Karanam <https://github.com/vinayinvicible>
+    Vinay Sajip <vinay_sajip@yahoo.co.uk>
+    Vincent Foley <vfoleybourgon@yahoo.ca>
+    Vinny Do <vdo.code@gmail.com>
+    Vitaly Babiy <vbabiy86@gmail.com>
+    Vladimir Kuzma <vladimirkuzma.ch@gmail.com>
+    Vlado <vlado@labath.org>
+    Vsevolod Solovyov
+    Vytis Banaitis <vytis.banaitis@gmail.com>
+    wam-djangobug@wamber.net
+    Wang Chun <wangchun@exoweb.net>
+    Warren Smith <warren@wandrsmith.net>
+    Waylan Limberg <waylan@gmail.com>
+    Wiktor Kołodziej <wiktor@pykonik.org>
+    Wiley Kestner <wiley.kestner@gmail.com>
+    Wiliam Alves de Souza <wiliamsouza83@gmail.com>
+    Will Ayd <william.ayd@icloud.com>
+    William Schwartz <wkschwartz@gmail.com>
+    Will Hardy <django@willhardy.com.au>
+    Wilson Miner <wminer@gmail.com>
+    Wim Glenn <hey@wimglenn.com>
+    wojtek
+    Xia Kai <https://blog.xiaket.org/>
+    Yann Fouillat <gagaro42@gmail.com>
+    Yann Malet
+    Yasushi Masuda <whosaysni@gmail.com>
+    ye7cakf02@sneakemail.com
+    ymasuda@ethercube.com
+    Yoong Kang Lim <yoongkang.lim@gmail.com>
+    Yusuke Miyazaki <miyazaki.dev@gmail.com>
+    Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
+    Zachary Voase <zacharyvoase@gmail.com>
+    Zach Liu <zachliu@gmail.com>
+    Zach Thompson <zthompson47@gmail.com>
+    Zain Memon
+    Zak Johnson <zakj@nox.cx>
+    Žan Anderle <zan.anderle@gmail.com>
+    Zbigniew Siciarz <zbigniew@siciarz.net>
+    zegor
+    Zeynel Özdemir <ozdemir.zynl@gmail.com>
+    Zlatko Mašek <zlatko.masek@gmail.com>
+    <Please alphabetize new entries>
+
+A big THANK YOU goes to:
+
+    Rob Curley and Ralph Gage for letting us open-source Django.
+
+    Frank Wiles for making excellent arguments for open-sourcing, and for
+    his sage sysadmin advice.
+
+    Ian Bicking for convincing Adrian to ditch code generation.
+
+    Mark Pilgrim for "Dive Into Python" (https://www.diveinto.org/python3/).
+
+    Guido van Rossum for creating Python.

+ 1 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 27 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) Django Software Foundation and individual contributors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of Django nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 266 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/LICENSE.python

@@ -0,0 +1,266 @@
+Django is licensed under the three-clause BSD license; see the file
+LICENSE for details.
+
+Django includes code from the Python standard library, which is licensed under
+the Python license, a permissive open source license. The copyright and license
+is included below for compliance with Python's terms.
+
+----------------------------------------------------------------------
+
+Copyright (c) 2001-present Python Software Foundation; All Rights Reserved
+
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All
+Rights Reserved" are retained in Python alone or in any derivative version
+prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+ 89 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/METADATA

@@ -0,0 +1,89 @@
+Metadata-Version: 2.1
+Name: Django
+Version: 3.0.4
+Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design.
+Home-page: https://www.djangoproject.com/
+Author: Django Software Foundation
+Author-email: foundation@djangoproject.com
+License: BSD
+Project-URL: Documentation, https://docs.djangoproject.com/
+Project-URL: Funding, https://www.djangoproject.com/fundraising/
+Project-URL: Source, https://github.com/django/django
+Project-URL: Tracker, https://code.djangoproject.com/
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Framework :: Django
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Topic :: Internet :: WWW/HTTP
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
+Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=3.6
+Requires-Dist: pytz
+Requires-Dist: sqlparse (>=0.2.2)
+Requires-Dist: asgiref (~=3.2)
+Provides-Extra: argon2
+Requires-Dist: argon2-cffi (>=16.1.0) ; extra == 'argon2'
+Provides-Extra: bcrypt
+Requires-Dist: bcrypt ; extra == 'bcrypt'
+
+======
+Django
+======
+
+Django is a high-level Python Web framework that encourages rapid development
+and clean, pragmatic design. Thanks for checking it out.
+
+All documentation is in the "``docs``" directory and online at
+https://docs.djangoproject.com/en/stable/. If you're just getting started,
+here's how we recommend you read the docs:
+
+* First, read ``docs/intro/install.txt`` for instructions on installing Django.
+
+* Next, work through the tutorials in order (``docs/intro/tutorial01.txt``,
+  ``docs/intro/tutorial02.txt``, etc.).
+
+* If you want to set up an actual deployment server, read
+  ``docs/howto/deployment/index.txt`` for instructions.
+
+* You'll probably want to read through the topical guides (in ``docs/topics``)
+  next; from there you can jump to the HOWTOs (in ``docs/howto``) for specific
+  problems, and check out the reference (``docs/ref``) for gory details.
+
+* See ``docs/README`` for instructions on building an HTML version of the docs.
+
+Docs are updated rigorously. If you find any problems in the docs, or think
+they should be clarified in any way, please take 30 seconds to fill out a
+ticket here: https://code.djangoproject.com/newticket
+
+To get more help:
+
+* Join the ``#django`` channel on irc.freenode.net. Lots of helpful people hang
+  out there. See https://en.wikipedia.org/wiki/Wikipedia:IRC/Tutorial if you're
+  new to IRC.
+
+* Join the django-users mailing list, or read the archives, at
+  https://groups.google.com/group/django-users.
+
+To contribute to Django:
+
+* Check out https://docs.djangoproject.com/en/dev/internals/contributing/ for
+  information about getting involved.
+
+To run Django's test suite:
+
+* Follow the instructions in the "Unit tests" section of
+  ``docs/internals/contributing/writing-code/unit-tests.txt``, published online at
+  https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/#running-the-unit-tests
+
+

Datei-Diff unterdrückt, da er zu groß ist
+ 4220 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/RECORD


+ 5 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/WHEEL

@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.33.1)
+Root-Is-Purelib: true
+Tag: py3-none-any
+

+ 3 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/entry_points.txt

@@ -0,0 +1,3 @@
+[console_scripts]
+django-admin = django.core.management:execute_from_command_line
+

+ 1 - 0
venv/Lib/site-packages/Django-3.0.4.dist-info/top_level.txt

@@ -0,0 +1 @@
+django

+ 1 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 19 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2010, 2013 PyMySQL contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 181 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/METADATA

@@ -0,0 +1,181 @@
+Metadata-Version: 2.1
+Name: PyMySQL
+Version: 0.9.3
+Summary: Pure Python MySQL Driver
+Home-page: https://github.com/PyMySQL/PyMySQL/
+Author: yutaka.matsubara
+Author-email: yutaka.matsubara@gmail.com
+Maintainer: INADA Naoki
+Maintainer-email: songofacandy@gmail.com
+License: "MIT"
+Project-URL: Documentation, https://pymysql.readthedocs.io/
+Keywords: MySQL
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: Database
+Provides-Extra: rsa
+Requires-Dist: cryptography ; extra == 'rsa'
+
+.. image:: https://readthedocs.org/projects/pymysql/badge/?version=latest
+    :target: https://pymysql.readthedocs.io/
+    :alt: Documentation Status
+
+.. image:: https://badge.fury.io/py/PyMySQL.svg
+    :target: https://badge.fury.io/py/PyMySQL
+
+.. image:: https://travis-ci.org/PyMySQL/PyMySQL.svg?branch=master
+    :target: https://travis-ci.org/PyMySQL/PyMySQL
+
+.. image:: https://coveralls.io/repos/PyMySQL/PyMySQL/badge.svg?branch=master&service=github
+    :target: https://coveralls.io/github/PyMySQL/PyMySQL?branch=master
+
+.. image:: https://img.shields.io/badge/license-MIT-blue.svg
+    :target: https://github.com/PyMySQL/PyMySQL/blob/master/LICENSE
+
+
+PyMySQL
+=======
+
+.. contents:: Table of Contents
+   :local:
+
+This package contains a pure-Python MySQL client library, based on `PEP 249`_.
+
+Most public APIs are compatible with mysqlclient and MySQLdb.
+
+NOTE: PyMySQL doesn't support low level APIs `_mysql` provides like `data_seek`,
+`store_result`, and `use_result`. You should use high level APIs defined in `PEP 249`_.
+But some APIs like `autocommit` and `ping` are supported because `PEP 249`_ doesn't cover
+their usecase.
+
+.. _`PEP 249`: https://www.python.org/dev/peps/pep-0249/
+
+
+Requirements
+-------------
+
+* Python -- one of the following:
+
+  - CPython_ : 2.7 and >= 3.4
+  - PyPy_ : Latest version
+
+* MySQL Server -- one of the following:
+
+  - MySQL_ >= 5.5
+  - MariaDB_ >= 5.5
+
+.. _CPython: https://www.python.org/
+.. _PyPy: https://pypy.org/
+.. _MySQL: https://www.mysql.com/
+.. _MariaDB: https://mariadb.org/
+
+
+Installation
+------------
+
+Package is uploaded on `PyPI <https://pypi.org/project/PyMySQL>`_.
+
+You can install it with pip::
+
+    $ python3 -m pip install PyMySQL
+
+To use "sha256_password" or "caching_sha2_password" for authenticate,
+you need to install additional dependency::
+
+   $ python3 -m pip install PyMySQL[rsa]
+
+
+Documentation
+-------------
+
+Documentation is available online: https://pymysql.readthedocs.io/
+
+For support, please refer to the `StackOverflow
+<https://stackoverflow.com/questions/tagged/pymysql>`_.
+
+Example
+-------
+
+The following examples make use of a simple table
+
+.. code:: sql
+
+   CREATE TABLE `users` (
+       `id` int(11) NOT NULL AUTO_INCREMENT,
+       `email` varchar(255) COLLATE utf8_bin NOT NULL,
+       `password` varchar(255) COLLATE utf8_bin NOT NULL,
+       PRIMARY KEY (`id`)
+   ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
+   AUTO_INCREMENT=1 ;
+
+
+.. code:: python
+
+    import pymysql.cursors
+
+    # Connect to the database
+    connection = pymysql.connect(host='localhost',
+                                 user='user',
+                                 password='passwd',
+                                 db='db',
+                                 charset='utf8mb4',
+                                 cursorclass=pymysql.cursors.DictCursor)
+
+    try:
+        with connection.cursor() as cursor:
+            # Create a new record
+            sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
+            cursor.execute(sql, ('webmaster@python.org', 'very-secret'))
+
+        # connection is not autocommit by default. So you must commit to save
+        # your changes.
+        connection.commit()
+
+        with connection.cursor() as cursor:
+            # Read a single record
+            sql = "SELECT `id`, `password` FROM `users` WHERE `email`=%s"
+            cursor.execute(sql, ('webmaster@python.org',))
+            result = cursor.fetchone()
+            print(result)
+    finally:
+        connection.close()
+
+This example will print:
+
+.. code:: python
+
+    {'password': 'very-secret', 'id': 1}
+
+
+Resources
+---------
+
+* DB-API 2.0: https://www.python.org/dev/peps/pep-0249/
+
+* MySQL Reference Manuals: https://dev.mysql.com/doc/
+
+* MySQL client/server protocol:
+  https://dev.mysql.com/doc/internals/en/client-server-protocol.html
+
+* "Connector" channel in MySQL Community Slack:
+  https://lefred.be/mysql-community-on-slack/
+
+* PyMySQL mailing list: https://groups.google.com/forum/#!forum/pymysql-users
+
+License
+-------
+
+PyMySQL is released under the MIT License. See LICENSE for more information.
+
+

+ 49 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/RECORD

@@ -0,0 +1,49 @@
+PyMySQL-0.9.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+PyMySQL-0.9.3.dist-info/LICENSE,sha256=MUEg3GXwgA9ziksxQAx27hTezR--d86cNUCkIbhup7Y,1070
+PyMySQL-0.9.3.dist-info/METADATA,sha256=8_R1N3H_AmpUu72ctuiQVI1Pk2SMlb9sy1uGlnxXB4U,5212
+PyMySQL-0.9.3.dist-info/RECORD,,
+PyMySQL-0.9.3.dist-info/WHEEL,sha256=_wJFdOYk7i3xxT8ElOkUJvOdOvfNGbR9g-bf6UQT6sU,110
+PyMySQL-0.9.3.dist-info/pbr.json,sha256=Lqvh8-9N7qS6SLUlEJ5GDLWioQcvR9n1WWjMEfJ5mv8,47
+PyMySQL-0.9.3.dist-info/top_level.txt,sha256=IKlV-f4o90sOdnMd6HBvo0l2nqfJOGUzkwZeaEEGuRg,8
+pymysql/__init__.py,sha256=ESllVZVoMVkJ0w9FoaMMirjFbWNc6wmHEVHzGKEBefc,4732
+pymysql/__pycache__/__init__.cpython-38.pyc,,
+pymysql/__pycache__/_auth.cpython-38.pyc,,
+pymysql/__pycache__/_compat.cpython-38.pyc,,
+pymysql/__pycache__/_socketio.cpython-38.pyc,,
+pymysql/__pycache__/charset.cpython-38.pyc,,
+pymysql/__pycache__/connections.cpython-38.pyc,,
+pymysql/__pycache__/converters.cpython-38.pyc,,
+pymysql/__pycache__/cursors.cpython-38.pyc,,
+pymysql/__pycache__/err.cpython-38.pyc,,
+pymysql/__pycache__/optionfile.cpython-38.pyc,,
+pymysql/__pycache__/protocol.cpython-38.pyc,,
+pymysql/__pycache__/times.cpython-38.pyc,,
+pymysql/__pycache__/util.cpython-38.pyc,,
+pymysql/_auth.py,sha256=X2AiuevuDaD2L4wJO5J7rymvJJZm6mND7WYmeIb7wEk,7720
+pymysql/_compat.py,sha256=DSxMV2ib-rhIuQIKiXX44yds_0bN2M_RddfYQiSdB6U,481
+pymysql/_socketio.py,sha256=smsw4wudNM4CKl85uis8QHfjDhz2iXQRvl8QV4TmB1w,4049
+pymysql/charset.py,sha256=tNeEkuzFXM5zeuOYm_XSM8zdt5P_paV2SyUB9B2ibqI,10330
+pymysql/connections.py,sha256=98DHxN-h3tupGBIReR98E7LSTR7-OIYh3tulXGlGdvc,49041
+pymysql/constants/CLIENT.py,sha256=cPMxnQQbBG6xqaEDwqzggTfWIuJQ1Oy7HrIgw_vgpo4,853
+pymysql/constants/COMMAND.py,sha256=ypGdEUmi8m9cdBZ3rDU6mb7bsIyu9ldCDvc4pNF7V70,680
+pymysql/constants/CR.py,sha256=5ojVkbisyw7Qo_cTNpnHYvV6xHRZXK39Qqv8tjGbIbg,2228
+pymysql/constants/ER.py,sha256=8q1PZOxezbXbRaPZrHrQebyLDx4CvAUkBArJ9xBuW0Y,12297
+pymysql/constants/FIELD_TYPE.py,sha256=yHZLSyQewMxTDx4PLrI1H_iwH2FnsrgBZFa56UG2HiQ,372
+pymysql/constants/FLAG.py,sha256=Fy-PrCLnUI7fx_o5WypYnUAzWAM0E9d5yL8fFRVKffY,214
+pymysql/constants/SERVER_STATUS.py,sha256=KogVCOrV-S5aAFwyVKeKgua13nwdt1WFyHagjCZbcpM,334
+pymysql/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+pymysql/constants/__pycache__/CLIENT.cpython-38.pyc,,
+pymysql/constants/__pycache__/COMMAND.cpython-38.pyc,,
+pymysql/constants/__pycache__/CR.cpython-38.pyc,,
+pymysql/constants/__pycache__/ER.cpython-38.pyc,,
+pymysql/constants/__pycache__/FIELD_TYPE.cpython-38.pyc,,
+pymysql/constants/__pycache__/FLAG.cpython-38.pyc,,
+pymysql/constants/__pycache__/SERVER_STATUS.cpython-38.pyc,,
+pymysql/constants/__pycache__/__init__.cpython-38.pyc,,
+pymysql/converters.py,sha256=BWHMbquNFUKfFXyZh6Qwch6mYLyYSQeaeifL4VLuISc,12235
+pymysql/cursors.py,sha256=m6MhwWnm3CbTE4JAXzDuo6CYKC7W6JzsY4PN9eDmKJk,17238
+pymysql/err.py,sha256=PaXGLqOnDXJoeYjLbMZQE5UQ3MHFqiiHCzaDPP-_NJA,3716
+pymysql/optionfile.py,sha256=4yW8A7aAR2Aild7ibLOCzIlTCcYd90PtR8LRGJSZs8o,658
+pymysql/protocol.py,sha256=GH2yzGqPwqX2t2G87k3EJQt7bYQOLEN6QoN_m15c4Ak,12024
+pymysql/times.py,sha256=_qXgDaYwsHntvpIKSKXp1rrYIgtq6Z9pLyLnO2XNoL0,360
+pymysql/util.py,sha256=jKPts8cOMIXDndjsV3783VW-iq9uMxETWqfHP6Bd-Zo,180

+ 6 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/WHEEL

@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.32.3)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+

+ 1 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/pbr.json

@@ -0,0 +1 @@
+{"is_release": false, "git_version": "08bac52"}

+ 1 - 0
venv/Lib/site-packages/PyMySQL-0.9.3.dist-info/top_level.txt

@@ -0,0 +1 @@
+pymysql

+ 1 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 27 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) Django Software Foundation and individual contributors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of Django nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 225 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/METADATA

@@ -0,0 +1,225 @@
+Metadata-Version: 2.1
+Name: asgiref
+Version: 3.2.3
+Summary: ASGI specs, helper code, and adapters
+Home-page: http://github.com/django/asgiref/
+Author: Django Software Foundation
+Author-email: foundation@djangoproject.com
+License: BSD
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Topic :: Internet :: WWW/HTTP
+Description-Content-Type: text/x-rst
+Provides-Extra: tests
+Requires-Dist: pytest (~=4.3.0) ; extra == 'tests'
+Requires-Dist: pytest-asyncio (~=0.10.0) ; extra == 'tests'
+
+asgiref
+=======
+
+.. image:: https://api.travis-ci.org/django/asgiref.svg
+    :target: https://travis-ci.org/django/asgiref
+
+.. image:: https://img.shields.io/pypi/v/asgiref.svg
+    :target: https://pypi.python.org/pypi/asgiref
+
+ASGI is a standard for Python asynchronous web apps and servers to communicate
+with each other, and positioned as an asynchronous successor to WSGI. You can
+read more at https://asgi.readthedocs.io/en/latest/
+
+This package includes ASGI base libraries, such as:
+
+* Sync-to-async and async-to-sync function wrappers, ``asgiref.sync``
+* Server base classes, ``asgiref.server``
+* A WSGI-to-ASGI adapter, in ``asgiref.wsgi``
+
+
+Function wrappers
+-----------------
+
+These allow you to wrap or decorate async or sync functions to call them from
+the other style (so you can call async functions from a synchronous thread,
+or vice-versa).
+
+In particular:
+
+* AsyncToSync lets a synchronous subthread stop and wait while the async
+  function is called on the main thread's event loop, and then control is
+  returned to the thread when the async function is finished.
+
+* SyncToAsync lets async code call a synchronous function, which is run in
+  a threadpool and control returned to the async coroutine when the synchronous
+  function completes.
+
+The idea is to make it easier to call synchronous APIs from async code and
+asynchronous APIs from synchronous code so it's easier to transition code from
+one style to the other. In the case of Channels, we wrap the (synchronous)
+Django view system with SyncToAsync to allow it to run inside the (asynchronous)
+ASGI server.
+
+Note that exactly what threads things run in is very specific, and aimed to
+keep maximum compatibility with old synchronous code. See
+"Synchronous code & Threads" below for a full explanation.
+
+
+Threadlocal replacement
+-----------------------
+
+This is a drop-in replacement for ``threading.local`` that works with both
+threads and asyncio Tasks. Even better, it will proxy values through from a
+task-local context to a thread-local context when you use ``sync_to_async``
+to run things in a threadpool, and vice-versa for ``async_to_sync``.
+
+If you instead want true thread- and task-safety, you can set
+``thread_critical`` on the Local object to ensure this instead.
+
+
+Server base classes
+-------------------
+
+Includes a ``StatelessServer`` class which provides all the hard work of
+writing a stateless server (as in, does not handle direct incoming sockets
+but instead consumes external streams or sockets to work out what is happening).
+
+An example of such a server would be a chatbot server that connects out to
+a central chat server and provides a "connection scope" per user chatting to
+it. There's only one actual connection, but the server has to separate things
+into several scopes for easier writing of the code.
+
+You can see an example of this being used in `frequensgi <https://github.com/andrewgodwin/frequensgi>`_.
+
+
+WSGI-to-ASGI adapter
+--------------------
+
+Allows you to wrap a WSGI application so it appears as a valid ASGI application.
+
+Simply wrap it around your WSGI application like so::
+
+    asgi_application = WsgiToAsgi(wsgi_application)
+
+The WSGI application will be run in a synchronous threadpool, and the wrapped
+ASGI application will be one that accepts ``http`` class messages.
+
+Please note that not all extended features of WSGI may be supported (such as
+file handles for incoming POST bodies).
+
+
+Dependencies
+------------
+
+``asgiref`` requires Python 3.5 or higher.
+
+
+Contributing
+------------
+
+Please refer to the
+`main Channels contributing docs <https://github.com/django/channels/blob/master/CONTRIBUTING.rst>`_.
+
+
+Testing
+'''''''
+
+To run tests, make sure you have installed the ``tests`` extra with the package::
+
+    cd asgiref/
+    pip install -e .[tests]
+    pytest
+
+
+Building the documentation
+''''''''''''''''''''''''''
+
+The documentation uses `Sphinx <http://www.sphinx-doc.org>`_::
+
+    cd asgiref/docs/
+    pip install sphinx
+
+To build the docs, you can use the default tools::
+
+    sphinx-build -b html . _build/html  # or `make html`, if you've got make set up
+    cd _build/html
+    python -m http.server
+
+...or you can use ``sphinx-autobuild`` to run a server and rebuild/reload
+your documentation changes automatically::
+
+    pip install sphinx-autobuild
+    sphinx-autobuild . _build/html
+
+
+Implementation Details
+----------------------
+
+Synchronous code & threads
+''''''''''''''''''''''''''
+
+The ``asgiref.sync`` module provides two wrappers that let you go between
+asynchronous and synchronous code at will, while taking care of the rough edges
+for you.
+
+Unfortunately, the rough edges are numerous, and the code has to work especially
+hard to keep things in the same thread as much as possible. Notably, the
+restrictions we are working with are:
+
+* All synchronous code called through ``SyncToAsync`` and marked with
+  ``thread_sensitive`` should run in the same thread as each other (and if the
+  outer layer of the program is synchronous, the main thread)
+
+* If a thread already has a running async loop, ``AsyncToSync`` can't run things
+  on that loop if it's blocked on synchronous code that is above you in the
+  call stack.
+
+The first compromise you get to might be that ``thread_sensitive`` code should
+just run in the same thread and not spawn in a sub-thread, fulfilling the first
+restriction, but that immediately runs you into the second restriction.
+
+The only real solution is to essentially have a variant of ThreadPoolExecutor
+that executes any ``thread_sensitive`` code on the outermost synchronous
+thread - either the main thread, or a single spawned subthread.
+
+This means you now have two basic states:
+
+* If the outermost layer of your program is synchronous, then all async code
+  run through ``AsyncToSync`` will run in a per-call event loop in arbitary
+  sub-threads, while all ``thread_sensitive`` code will run in the main thread.
+
+* If the outermost layer of your program is asynchronous, then all async code
+  runs on the main thread's event loop, and all ``thread_sensitive`` synchronous
+  code will run in a single shared sub-thread.
+
+Cruicially, this means that in both cases there is a thread which is a shared
+resource that all ``thread_sensitive`` code must run on, and there is a chance
+that this thread is currently blocked on its own ``AsyncToSync`` call. Thus,
+``AsyncToSync`` needs to act as an executor for thread code while it's blocking.
+
+The ``CurrentThreadExecutor`` class provides this functionality; rather than
+simply waiting on a Future, you can call its ``run_until_future`` method and
+it will run submitted code until that Future is done. This means that code
+inside the call can then run code on your thread.
+
+
+Maintenance and Security
+------------------------
+
+To report security issues, please contact security@djangoproject.com. For GPG
+signatures and more security process information, see
+https://docs.djangoproject.com/en/dev/internals/security/.
+
+To report bugs or request new features, please open a new GitHub issue.
+
+This repository is part of the Channels project. For the shepherd and maintenance team, please see the
+`main Channels readme <https://github.com/django/channels/blob/master/README.rst>`_.
+
+

+ 24 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/RECORD

@@ -0,0 +1,24 @@
+asgiref-3.2.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+asgiref-3.2.3.dist-info/LICENSE,sha256=uEZBXRtRTpwd_xSiLeuQbXlLxUbKYSn5UKGM0JHipmk,1552
+asgiref-3.2.3.dist-info/METADATA,sha256=IVR7f6fGCRskC5rdQpyLEj3TU98OiwNN6e48kFNtzQo,8204
+asgiref-3.2.3.dist-info/RECORD,,
+asgiref-3.2.3.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110
+asgiref-3.2.3.dist-info/top_level.txt,sha256=bokQjCzwwERhdBiPdvYEZa4cHxT4NCeAffQNUqJ8ssg,8
+asgiref/__init__.py,sha256=mXL9_BE7rH9kYvnpTkBL-8cf36JOLKsKyqYTcb1wVkw,22
+asgiref/__pycache__/__init__.cpython-38.pyc,,
+asgiref/__pycache__/compatibility.cpython-38.pyc,,
+asgiref/__pycache__/current_thread_executor.cpython-38.pyc,,
+asgiref/__pycache__/local.cpython-38.pyc,,
+asgiref/__pycache__/server.cpython-38.pyc,,
+asgiref/__pycache__/sync.cpython-38.pyc,,
+asgiref/__pycache__/testing.cpython-38.pyc,,
+asgiref/__pycache__/timeout.cpython-38.pyc,,
+asgiref/__pycache__/wsgi.cpython-38.pyc,,
+asgiref/compatibility.py,sha256=MVH2bEdiCMMVTLbE-1V6KiU7q4LwqzP7PIufeXa-njM,1598
+asgiref/current_thread_executor.py,sha256=3dRFt3jAl_x1wr9prZZMut071pmdHdIwbTnUAYVejj4,2974
+asgiref/local.py,sha256=HQwOou8duBbyzqjPpKeTEgTLPIMzjAdasRI1y10f9L0,4420
+asgiref/server.py,sha256=iFJn_uD-poeHWgLOuSnKCVMS1HqqV-IOTOOC85fKr00,5915
+asgiref/sync.py,sha256=paTFi6m7u_RmZnag2eASmuGGNsPuYI8GmIcV7cNkn2I,11485
+asgiref/testing.py,sha256=3byNRV7Oto_Fg8Z-fErQJ3yGf7OQlcUexbN_cDQugzQ,3119
+asgiref/timeout.py,sha256=Emw-Oop1pRfSc5YSMEYHgEz1802mP6JdA6bxH37bby8,3914
+asgiref/wsgi.py,sha256=rxGUxQG4FsSJYXJekClLuAGM_rovnxfH1qrNt95CNaI,5606

+ 6 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/WHEEL

@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.33.6)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+

+ 1 - 0
venv/Lib/site-packages/asgiref-3.2.3.dist-info/top_level.txt

@@ -0,0 +1 @@
+asgiref

+ 1 - 0
venv/Lib/site-packages/asgiref/__init__.py

@@ -0,0 +1 @@
+__version__ = "3.2.3"

+ 47 - 0
venv/Lib/site-packages/asgiref/compatibility.py

@@ -0,0 +1,47 @@
+import asyncio
+import inspect
+
+
+def is_double_callable(application):
+    """
+    Tests to see if an application is a legacy-style (double-callable) application.
+    """
+    # Look for a hint on the object first
+    if getattr(application, "_asgi_single_callable", False):
+        return False
+    if getattr(application, "_asgi_double_callable", False):
+        return True
+    # Uninstanted classes are double-callable
+    if inspect.isclass(application):
+        return True
+    # Instanted classes depend on their __call__
+    if hasattr(application, "__call__"):
+        # We only check to see if its __call__ is a coroutine function -
+        # if it's not, it still might be a coroutine function itself.
+        if asyncio.iscoroutinefunction(application.__call__):
+            return False
+    # Non-classes we just check directly
+    return not asyncio.iscoroutinefunction(application)
+
+
+def double_to_single_callable(application):
+    """
+    Transforms a double-callable ASGI application into a single-callable one.
+    """
+
+    async def new_application(scope, receive, send):
+        instance = application(scope)
+        return await instance(receive, send)
+
+    return new_application
+
+
+def guarantee_single_callable(application):
+    """
+    Takes either a single- or double-callable application and always returns it
+    in single-callable style. Use this to add backwards compatibility for ASGI
+    2.0 applications to your server/test harness/etc.
+    """
+    if is_double_callable(application):
+        application = double_to_single_callable(application)
+    return application

+ 86 - 0
venv/Lib/site-packages/asgiref/current_thread_executor.py

@@ -0,0 +1,86 @@
+import queue
+import threading
+import time
+from concurrent.futures import Executor, Future
+
+
+class _WorkItem(object):
+    """
+    Represents an item needing to be run in the executor.
+    Copied from ThreadPoolExecutor (but it's private, so we're not going to rely on importing it)
+    """
+
+    def __init__(self, future, fn, args, kwargs):
+        self.future = future
+        self.fn = fn
+        self.args = args
+        self.kwargs = kwargs
+
+    def run(self):
+        if not self.future.set_running_or_notify_cancel():
+            return
+        try:
+            result = self.fn(*self.args, **self.kwargs)
+        except BaseException as exc:
+            self.future.set_exception(exc)
+            # Break a reference cycle with the exception 'exc'
+            self = None
+        else:
+            self.future.set_result(result)
+
+
+class CurrentThreadExecutor(Executor):
+    """
+    An Executor that actually runs code in the thread it is instantiated in.
+    Passed to other threads running async code, so they can run sync code in
+    the thread they came from.
+    """
+
+    def __init__(self):
+        self._work_thread = threading.current_thread()
+        self._work_queue = queue.Queue()
+        self._broken = False
+
+    def run_until_future(self, future):
+        """
+        Runs the code in the work queue until a result is available from the future.
+        Should be run from the thread the executor is initialised in.
+        """
+        # Check we're in the right thread
+        if threading.current_thread() != self._work_thread:
+            raise RuntimeError(
+                "You cannot run CurrentThreadExecutor from a different thread"
+            )
+        # Keep getting work items and checking the future
+        try:
+            while True:
+                # Get a work item and run it
+                try:
+                    work_item = self._work_queue.get(block=False)
+                except queue.Empty:
+                    # See if the future is done (we only exit if the work queue is empty)
+                    if future.done():
+                        return
+                    # Prevent hot-looping on nothing
+                    time.sleep(0.001)
+                else:
+                    work_item.run()
+                    del work_item
+        finally:
+            self._broken = True
+
+    def submit(self, fn, *args, **kwargs):
+        # Check they're not submitting from the same thread
+        if threading.current_thread() == self._work_thread:
+            raise RuntimeError(
+                "You cannot submit onto CurrentThreadExecutor from its own thread"
+            )
+        # Check they're not too late or the executor errored
+        if self._broken:
+            raise RuntimeError("CurrentThreadExecutor already quit or is broken")
+        # Add to work queue
+        f = Future()
+        work_item = _WorkItem(f, fn, args, kwargs)
+        self._work_queue.put(work_item)
+        # Return the future
+        return f

+ 111 - 0
venv/Lib/site-packages/asgiref/local.py

@@ -0,0 +1,111 @@
+import asyncio
+import sys
+import threading
+import time
+
+
+class Local:
+    """
+    A drop-in replacement for threading.locals that also works with asyncio
+    Tasks (via the current_task asyncio method), and passes locals through
+    sync_to_async and async_to_sync.
+
+    Specifically:
+     - Locals work per-coroutine on any thread not spawned using asgiref
+     - Locals work per-thread on any thread not spawned using asgiref
+     - Locals are shared with the parent coroutine when using sync_to_async
+     - Locals are shared with the parent thread when using async_to_sync
+       (and if that thread was launched using sync_to_async, with its parent
+       coroutine as well, with this working for indefinite levels of nesting)
+
+    Set thread_critical to True to not allow locals to pass from an async Task
+    to a thread it spawns. This is needed for code that truly needs
+    thread-safety, as opposed to things used for helpful context (e.g. sqlite
+    does not like being called from a different thread to the one it is from).
+    Thread-critical code will still be differentiated per-Task within a thread
+    as it is expected it does not like concurrent access.
+
+    This doesn't use contextvars as it needs to support 3.6. Once it can support
+    3.7 only, we can then reimplement the storage more nicely.
+    """
+
+    CLEANUP_INTERVAL = 60  # seconds
+
+    def __init__(self, thread_critical=False):
+        self._storage = {}
+        self._last_cleanup = time.time()
+        self._clean_lock = threading.Lock()
+        self._thread_critical = thread_critical
+
+    def _get_context_id(self):
+        """
+        Get the ID we should use for looking up variables
+        """
+        # Prevent a circular reference
+        from .sync import AsyncToSync, SyncToAsync
+
+        # First, pull the current task if we can
+        context_id = SyncToAsync.get_current_task()
+        # OK, let's try for a thread ID
+        if context_id is None:
+            context_id = threading.current_thread()
+        # If we're thread-critical, we stop here, as we can't share contexts.
+        if self._thread_critical:
+            return context_id
+        # Now, take those and see if we can resolve them through the launch maps
+        for i in range(sys.getrecursionlimit()):
+            try:
+                if isinstance(context_id, threading.Thread):
+                    # Threads have a source task in SyncToAsync
+                    context_id = SyncToAsync.launch_map[context_id]
+                else:
+                    # Tasks have a source thread in AsyncToSync
+                    context_id = AsyncToSync.launch_map[context_id]
+            except KeyError:
+                break
+        else:
+            # Catch infinite loops (they happen if you are screwing around
+            # with AsyncToSync implementations)
+            raise RuntimeError("Infinite launch_map loops")
+        return context_id
+
+    def _cleanup(self):
+        """
+        Cleans up any references to dead threads or tasks
+        """
+        for key in list(self._storage.keys()):
+            if isinstance(key, threading.Thread):
+                if not key.is_alive():
+                    del self._storage[key]
+            elif isinstance(key, asyncio.Task):
+                if key.done():
+                    del self._storage[key]
+        self._last_cleanup = time.time()
+
+    def _maybe_cleanup(self):
+        """
+        Cleans up if enough time has passed
+        """
+        if time.time() - self._last_cleanup > self.CLEANUP_INTERVAL:
+            with self._clean_lock:
+                self._cleanup()
+
+    def __getattr__(self, key):
+        context_id = self._get_context_id()
+        if key in self._storage.get(context_id, {}):
+            return self._storage[context_id][key]
+        else:
+            raise AttributeError("%r object has no attribute %r" % (self, key))
+
+    def __setattr__(self, key, value):
+        if key in ("_storage", "_last_cleanup", "_clean_lock", "_thread_critical"):
+            return super().__setattr__(key, value)
+        self._maybe_cleanup()
+        self._storage.setdefault(self._get_context_id(), {})[key] = value
+
+    def __delattr__(self, key):
+        context_id = self._get_context_id()
+        if key in self._storage.get(context_id, {}):
+            del self._storage[context_id][key]
+        else:
+            raise AttributeError("%r object has no attribute %r" % (self, key))

+ 154 - 0
venv/Lib/site-packages/asgiref/server.py

@@ -0,0 +1,154 @@
+import asyncio
+import logging
+import time
+import traceback
+
+logger = logging.getLogger(__name__)
+
+
+class StatelessServer:
+    """
+    Base server class that handles basic concepts like application instance
+    creation/pooling, exception handling, and similar, for stateless protocols
+    (i.e. ones without actual incoming connections to the process)
+
+    Your code should override the handle() method, doing whatever it needs to,
+    and calling get_or_create_application_instance with a unique `scope_id`
+    and `scope` for the scope it wants to get.
+
+    If an application instance is found with the same `scope_id`, you are
+    given its input queue, otherwise one is made for you with the scope provided
+    and you are given that fresh new input queue. Either way, you should do
+    something like:
+
+    input_queue = self.get_or_create_application_instance(
+        "user-123456",
+        {"type": "testprotocol", "user_id": "123456", "username": "andrew"},
+    )
+    input_queue.put_nowait(message)
+
+    If you try and create an application instance and there are already
+    `max_application` instances, the oldest/least recently used one will be
+    reclaimed and shut down to make space.
+
+    Application coroutines that error will be found periodically (every 100ms
+    by default) and have their exceptions printed to the console. Override
+    application_exception() if you want to do more when this happens.
+
+    If you override run(), make sure you handle things like launching the
+    application checker.
+    """
+
+    application_checker_interval = 0.1
+
+    def __init__(self, application, max_applications=1000):
+        # Parameters
+        self.application = application
+        self.max_applications = max_applications
+        # Initialisation
+        self.application_instances = {}
+
+    ### Mainloop and handling
+
+    def run(self):
+        """
+        Runs the asyncio event loop with our handler loop.
+        """
+        event_loop = asyncio.get_event_loop()
+        asyncio.ensure_future(self.application_checker())
+        try:
+            event_loop.run_until_complete(self.handle())
+        except KeyboardInterrupt:
+            logger.info("Exiting due to Ctrl-C/interrupt")
+
+    async def handle(self):
+        raise NotImplementedError("You must implement handle()")
+
+    async def application_send(self, scope, message):
+        """
+        Receives outbound sends from applications and handles them.
+        """
+        raise NotImplementedError("You must implement application_send()")
+
+    ### Application instance management
+
+    def get_or_create_application_instance(self, scope_id, scope):
+        """
+        Creates an application instance and returns its queue.
+        """
+        if scope_id in self.application_instances:
+            self.application_instances[scope_id]["last_used"] = time.time()
+            return self.application_instances[scope_id]["input_queue"]
+        # See if we need to delete an old one
+        while len(self.application_instances) > self.max_applications:
+            self.delete_oldest_application_instance()
+        # Make an instance of the application
+        input_queue = asyncio.Queue()
+        application_instance = self.application(scope=scope)
+        # Run it, and stash the future for later checking
+        future = asyncio.ensure_future(
+            application_instance(
+                receive=input_queue.get,
+                send=lambda message: self.application_send(scope, message),
+            )
+        )
+        self.application_instances[scope_id] = {
+            "input_queue": input_queue,
+            "future": future,
+            "scope": scope,
+            "last_used": time.time(),
+        }
+        return input_queue
+
+    def delete_oldest_application_instance(self):
+        """
+        Finds and deletes the oldest application instance
+        """
+        oldest_time = min(
+            details["last_used"] for details in self.application_instances.values()
+        )
+        for scope_id, details in self.application_instances.items():
+            if details["last_used"] == oldest_time:
+                self.delete_application_instance(scope_id)
+                # Return to make sure we only delete one in case two have
+                # the same oldest time
+                return
+
+    def delete_application_instance(self, scope_id):
+        """
+        Removes an application instance (makes sure its task is stopped,
+        then removes it from the current set)
+        """
+        details = self.application_instances[scope_id]
+        del self.application_instances[scope_id]
+        if not details["future"].done():
+            details["future"].cancel()
+
+    async def application_checker(self):
+        """
+        Goes through the set of current application instance Futures and cleans up
+        any that are done/prints exceptions for any that errored.
+        """
+        while True:
+            await asyncio.sleep(self.application_checker_interval)
+            for scope_id, details in list(self.application_instances.items()):
+                if details["future"].done():
+                    exception = details["future"].exception()
+                    if exception:
+                        await self.application_exception(exception, details)
+                    try:
+                        del self.application_instances[scope_id]
+                    except KeyError:
+                        # Exception handling might have already got here before us. That's fine.
+                        pass
+
+    async def application_exception(self, exception, application_details):
+        """
+        Called whenever an application coroutine has an exception.
+        """
+        logging.error(
+            "Exception inside application: %s\n%s%s",
+            exception,
+            "".join(traceback.format_tb(exception.__traceback__)),
+            "  {}".format(exception),
+        )

+ 304 - 0
venv/Lib/site-packages/asgiref/sync.py

@@ -0,0 +1,304 @@
+import asyncio
+import asyncio.coroutines
+import functools
+import os
+import sys
+import threading
+from concurrent.futures import Future, ThreadPoolExecutor
+
+from .current_thread_executor import CurrentThreadExecutor
+from .local import Local
+
+try:
+    import contextvars  # Python 3.7+ only.
+except ImportError:
+    contextvars = None
+
+
+class AsyncToSync:
+    """
+    Utility class which turns an awaitable that only works on the thread with
+    the event loop into a synchronous callable that works in a subthread.
+
+    If the call stack contains an async loop, the code runs there.
+    Otherwise, the code runs in a new loop in a new thread.
+
+    Either way, this thread then pauses and waits to run any thread_sensitive
+    code called from further down the call stack using SyncToAsync, before
+    finally exiting once the async task returns.
+    """
+
+    # Maps launched Tasks to the threads that launched them (for locals impl)
+    launch_map = {}
+
+    # Keeps track of which CurrentThreadExecutor to use. This uses an asgiref
+    # Local, not a threadlocal, so that tasks can work out what their parent used.
+    executors = Local()
+
+    def __init__(self, awaitable, force_new_loop=False):
+        self.awaitable = awaitable
+        if force_new_loop:
+            # They have asked that we always run in a new sub-loop.
+            self.main_event_loop = None
+        else:
+            try:
+                self.main_event_loop = asyncio.get_event_loop()
+            except RuntimeError:
+                # There's no event loop in this thread. Look for the threadlocal if
+                # we're inside SyncToAsync
+                self.main_event_loop = getattr(
+                    SyncToAsync.threadlocal, "main_event_loop", None
+                )
+
+    def __call__(self, *args, **kwargs):
+        # You can't call AsyncToSync from a thread with a running event loop
+        try:
+            event_loop = asyncio.get_event_loop()
+        except RuntimeError:
+            pass
+        else:
+            if event_loop.is_running():
+                raise RuntimeError(
+                    "You cannot use AsyncToSync in the same thread as an async event loop - "
+                    "just await the async function directly."
+                )
+        # Make a future for the return information
+        call_result = Future()
+        # Get the source thread
+        source_thread = threading.current_thread()
+        # Make a CurrentThreadExecutor we'll use to idle in this thread - we
+        # need one for every sync frame, even if there's one above us in the
+        # same thread.
+        if hasattr(self.executors, "current"):
+            old_current_executor = self.executors.current
+        else:
+            old_current_executor = None
+        current_executor = CurrentThreadExecutor()
+        self.executors.current = current_executor
+        # Use call_soon_threadsafe to schedule a synchronous callback on the
+        # main event loop's thread if it's there, otherwise make a new loop
+        # in this thread.
+        try:
+            if not (self.main_event_loop and self.main_event_loop.is_running()):
+                # Make our own event loop - in a new thread - and run inside that.
+                loop = asyncio.new_event_loop()
+                loop_executor = ThreadPoolExecutor(max_workers=1)
+                loop_future = loop_executor.submit(
+                    self._run_event_loop,
+                    loop,
+                    self.main_wrap(
+                        args, kwargs, call_result, source_thread, sys.exc_info()
+                    ),
+                )
+                if current_executor:
+                    # Run the CurrentThreadExecutor until the future is done
+                    current_executor.run_until_future(loop_future)
+                # Wait for future and/or allow for exception propagation
+                loop_future.result()
+            else:
+                # Call it inside the existing loop
+                self.main_event_loop.call_soon_threadsafe(
+                    self.main_event_loop.create_task,
+                    self.main_wrap(
+                        args, kwargs, call_result, source_thread, sys.exc_info()
+                    ),
+                )
+                if current_executor:
+                    # Run the CurrentThreadExecutor until the future is done
+                    current_executor.run_until_future(call_result)
+        finally:
+            # Clean up any executor we were running
+            if hasattr(self.executors, "current"):
+                del self.executors.current
+            if old_current_executor:
+                self.executors.current = old_current_executor
+        # Wait for results from the future.
+        return call_result.result()
+
+    def _run_event_loop(self, loop, coro):
+        """
+        Runs the given event loop (designed to be called in a thread).
+        """
+        asyncio.set_event_loop(loop)
+        try:
+            loop.run_until_complete(coro)
+        finally:
+            try:
+                if hasattr(loop, "shutdown_asyncgens"):
+                    loop.run_until_complete(loop.shutdown_asyncgens())
+            finally:
+                loop.close()
+                asyncio.set_event_loop(self.main_event_loop)
+
+    def __get__(self, parent, objtype):
+        """
+        Include self for methods
+        """
+        func = functools.partial(self.__call__, parent)
+        return functools.update_wrapper(func, self.awaitable)
+
+    async def main_wrap(self, args, kwargs, call_result, source_thread, exc_info):
+        """
+        Wraps the awaitable with something that puts the result into the
+        result/exception future.
+        """
+        current_task = SyncToAsync.get_current_task()
+        self.launch_map[current_task] = source_thread
+        try:
+            # If we have an exception, run the function inside the except block
+            # after raising it so exc_info is correctly populated.
+            if exc_info[1]:
+                try:
+                    raise exc_info[1]
+                except:
+                    result = await self.awaitable(*args, **kwargs)
+            else:
+                result = await self.awaitable(*args, **kwargs)
+        except Exception as e:
+            call_result.set_exception(e)
+        else:
+            call_result.set_result(result)
+        finally:
+            del self.launch_map[current_task]
+
+
+class SyncToAsync:
+    """
+    Utility class which turns a synchronous callable into an awaitable that
+    runs in a threadpool. It also sets a threadlocal inside the thread so
+    calls to AsyncToSync can escape it.
+
+    If thread_sensitive is passed, the code will run in the same thread as any
+    outer code. This is needed for underlying Python code that is not
+    threadsafe (for example, code which handles SQLite database connections).
+
+    If the outermost program is async (i.e. SyncToAsync is outermost), then
+    this will be a dedicated single sub-thread that all sync code runs in,
+    one after the other. If the outermost program is sync (i.e. AsyncToSync is
+    outermost), this will just be the main thread. This is achieved by idling
+    with a CurrentThreadExecutor while AsyncToSync is blocking its sync parent,
+    rather than just blocking.
+    """
+
+    # If they've set ASGI_THREADS, update the default asyncio executor for now
+    if "ASGI_THREADS" in os.environ:
+        loop = asyncio.get_event_loop()
+        loop.set_default_executor(
+            ThreadPoolExecutor(max_workers=int(os.environ["ASGI_THREADS"]))
+        )
+
+    # Maps launched threads to the coroutines that spawned them
+    launch_map = {}
+
+    # Storage for main event loop references
+    threadlocal = threading.local()
+
+    # Single-thread executor for thread-sensitive code
+    single_thread_executor = ThreadPoolExecutor(max_workers=1)
+
+    def __init__(self, func, thread_sensitive=False):
+        self.func = func
+        self._thread_sensitive = thread_sensitive
+        self._is_coroutine = asyncio.coroutines._is_coroutine
+        try:
+            self.__self__ = func.__self__
+        except AttributeError:
+            pass
+
+    async def __call__(self, *args, **kwargs):
+        loop = asyncio.get_event_loop()
+
+        # Work out what thread to run the code in
+        if self._thread_sensitive:
+            if hasattr(AsyncToSync.executors, "current"):
+                # If we have a parent sync thread above somewhere, use that
+                executor = AsyncToSync.executors.current
+            else:
+                # Otherwise, we run it in a fixed single thread
+                executor = self.single_thread_executor
+        else:
+            executor = None  # Use default
+
+        if contextvars is not None:
+            context = contextvars.copy_context()
+            child = functools.partial(self.func, *args, **kwargs)
+            func = context.run
+            args = (child,)
+            kwargs = {}
+        else:
+            func = self.func
+
+        # Run the code in the right thread
+        future = loop.run_in_executor(
+            executor,
+            functools.partial(
+                self.thread_handler,
+                loop,
+                self.get_current_task(),
+                sys.exc_info(),
+                func,
+                *args,
+                **kwargs
+            ),
+        )
+        return await asyncio.wait_for(future, timeout=None)
+
+    def __get__(self, parent, objtype):
+        """
+        Include self for methods
+        """
+        return functools.partial(self.__call__, parent)
+
+    def thread_handler(self, loop, source_task, exc_info, func, *args, **kwargs):
+        """
+        Wraps the sync application with exception handling.
+        """
+        # Set the threadlocal for AsyncToSync
+        self.threadlocal.main_event_loop = loop
+        # Set the task mapping (used for the locals module)
+        current_thread = threading.current_thread()
+        if AsyncToSync.launch_map.get(source_task) == current_thread:
+            # Our parent task was launched from this same thread, so don't make
+            # a launch map entry - let it shortcut over us! (and stop infinite loops)
+            parent_set = False
+        else:
+            self.launch_map[current_thread] = source_task
+            parent_set = True
+        # Run the function
+        try:
+            # If we have an exception, run the function inside the except block
+            # after raising it so exc_info is correctly populated.
+            if exc_info[1]:
+                try:
+                    raise exc_info[1]
+                except:
+                    return func(*args, **kwargs)
+            else:
+                return func(*args, **kwargs)
+        finally:
+            # Only delete the launch_map parent if we set it, otherwise it is
+            # from someone else.
+            if parent_set:
+                del self.launch_map[current_thread]
+
+    @staticmethod
+    def get_current_task():
+        """
+        Cross-version implementation of asyncio.current_task()
+
+        Returns None if there is no task.
+        """
+        try:
+            if hasattr(asyncio, "current_task"):
+                # Python 3.7 and up
+                return asyncio.current_task()
+            else:
+                # Python 3.6
+                return asyncio.Task.current_task()
+        except RuntimeError:
+            return None
+
+
+# Lowercase is more sensible for most things
+sync_to_async = SyncToAsync
+async_to_sync = AsyncToSync

+ 97 - 0
venv/Lib/site-packages/asgiref/testing.py

@@ -0,0 +1,97 @@
+import asyncio
+import time
+
+from .compatibility import guarantee_single_callable
+from .timeout import timeout as async_timeout
+
+
+class ApplicationCommunicator:
+    """
+    Runs an ASGI application in a test mode, allowing sending of
+    messages to it and retrieval of messages it sends.
+    """
+
+    def __init__(self, application, scope):
+        self.application = guarantee_single_callable(application)
+        self.scope = scope
+        self.input_queue = asyncio.Queue()
+        self.output_queue = asyncio.Queue()
+        self.future = asyncio.ensure_future(
+            self.application(scope, self.input_queue.get, self.output_queue.put)
+        )
+
+    async def wait(self, timeout=1):
+        """
+        Waits for the application to stop itself and returns any exceptions.
+        """
+        try:
+            async with async_timeout(timeout):
+                try:
+                    await self.future
+                    self.future.result()
+                except asyncio.CancelledError:
+                    pass
+        finally:
+            if not self.future.done():
+                self.future.cancel()
+                try:
+                    await self.future
+                except asyncio.CancelledError:
+                    pass
+
+    def stop(self, exceptions=True):
+        if not self.future.done():
+            self.future.cancel()
+        elif exceptions:
+            # Give a chance to raise any exceptions
+            self.future.result()
+
+    def __del__(self):
+        # Clean up on deletion
+        try:
+            self.stop(exceptions=False)
+        except RuntimeError:
+            # Event loop already stopped
+            pass
+
+    async def send_input(self, message):
+        """
+        Sends a single message to the application
+        """
+        # Give it the message
+        await self.input_queue.put(message)
+
+    async def receive_output(self, timeout=1):
+        """
+        Receives a single message from the application, with optional timeout.
+        """
+        # Make sure there's not an exception to raise from the task
+        if self.future.done():
+            self.future.result()
+        # Wait and receive the message
+        try:
+            async with async_timeout(timeout):
+                return await self.output_queue.get()
+        except asyncio.TimeoutError as e:
+            # See if we have another error to raise inside
+            if self.future.done():
+                self.future.result()
+            else:
+                self.future.cancel()
+                try:
+                    await self.future
+                except asyncio.CancelledError:
+                    pass
+            raise e
+
+    async def receive_nothing(self, timeout=0.1, interval=0.01):
+        """
+        Checks that there is no message to receive in the given time.
+        """
+        # `interval` has precedence over `timeout`
+        start = time.monotonic()
+        while time.monotonic() - start < timeout:
+            if not self.output_queue.empty():
+                return False
+            await asyncio.sleep(interval)
+        return self.output_queue.empty()

+ 128 - 0
venv/Lib/site-packages/asgiref/timeout.py

@@ -0,0 +1,128 @@
+# This code is originally sourced from the aio-libs project "async_timeout",
+# under the Apache 2.0 license. You may see the original project at
+# https://github.com/aio-libs/async-timeout
+
+# It is vendored here to reduce chain-dependencies on this library, and
+# modified slightly to remove some features we don't use.
+
+
+import asyncio
+import sys
+from types import TracebackType
+from typing import Any, Optional, Type  # noqa
+
+PY_37 = sys.version_info >= (3, 7)
+
+
+class timeout:
+    """timeout context manager.
+
+    Useful in cases when you want to apply timeout logic around block
+    of code or in cases when asyncio.wait_for is not suitable. For example:
+
+    >>> with timeout(0.001):
+    ...     async with aiohttp.get('https://github.com') as r:
+    ...         await r.text()
+
+
+    timeout - value in seconds or None to disable timeout logic
+    loop - asyncio compatible event loop
+    """
+
+    def __init__(
+        self,
+        timeout: Optional[float],
+        *,
+        loop: Optional[asyncio.AbstractEventLoop] = None
+    ) -> None:
+        self._timeout = timeout
+        if loop is None:
+            loop = asyncio.get_event_loop()
+        self._loop = loop
+        self._task = None  # type: Optional[asyncio.Task[Any]]
+        self._cancelled = False
+        self._cancel_handler = None  # type: Optional[asyncio.Handle]
+        self._cancel_at = None  # type: Optional[float]
+
+    def __enter__(self) -> "timeout":
+        return self._do_enter()
+
+    def __exit__(
+        self,
+        exc_type: Type[BaseException],
+        exc_val: BaseException,
+        exc_tb: TracebackType,
+    ) -> Optional[bool]:
+        self._do_exit(exc_type)
+        return None
+
+    async def __aenter__(self) -> "timeout":
+        return self._do_enter()
+
+    async def __aexit__(
+        self,
+        exc_type: Type[BaseException],
+        exc_val: BaseException,
+        exc_tb: TracebackType,
+    ) -> None:
+        self._do_exit(exc_type)
+
+    @property
+    def expired(self) -> bool:
+        return self._cancelled
+
+    @property
+    def remaining(self) -> Optional[float]:
+        if self._cancel_at is not None:
+            return max(self._cancel_at - self._loop.time(), 0.0)
+        else:
+            return None
+
+    def _do_enter(self) -> "timeout":
+        # Support Tornado 5- without timeout
+        # Details: https://github.com/python/asyncio/issues/392
+        if self._timeout is None:
+            return self
+
+        self._task = current_task(self._loop)
+        if self._task is None:
+            raise RuntimeError(
+                "Timeout context manager should be used " "inside a task"
+            )
+
+        if self._timeout <= 0:
+            self._loop.call_soon(self._cancel_task)
+            return self
+
+        self._cancel_at = self._loop.time() + self._timeout
+        self._cancel_handler = self._loop.call_at(self._cancel_at, self._cancel_task)
+        return self
+
+    def _do_exit(self, exc_type: Type[BaseException]) -> None:
+        if exc_type is asyncio.CancelledError and self._cancelled:
+            self._cancel_handler = None
+            self._task = None
+            raise asyncio.TimeoutError
+        if self._timeout is not None and self._cancel_handler is not None:
+            self._cancel_handler.cancel()
+            self._cancel_handler = None
+        self._task = None
+        return None
+
+    def _cancel_task(self) -> None:
+        if self._task is not None:
+            self._task.cancel()
+            self._cancelled = True
+
+
+def current_task(loop: asyncio.AbstractEventLoop) -> "asyncio.Task[Any]":
+    if PY_37:
+        task = asyncio.current_task(loop=loop)  # type: ignore
+    else:
+        task = asyncio.Task.current_task(loop=loop)
+    if task is None:
+        # this should be removed, tokio must use register_task and family API
+        if hasattr(loop, "current_task"):
+            task = loop.current_task()  # type: ignore
+
+    return task

+ 145 - 0
venv/Lib/site-packages/asgiref/wsgi.py

@@ -0,0 +1,145 @@
+from io import BytesIO
+from tempfile import SpooledTemporaryFile
+
+from asgiref.sync import AsyncToSync, sync_to_async
+
+
+class WsgiToAsgi:
+    """
+    Wraps a WSGI application to make it into an ASGI application.
+    """
+
+    def __init__(self, wsgi_application):
+        self.wsgi_application = wsgi_application
+
+    async def __call__(self, scope, receive, send):
+        """
+        ASGI application instantiation point.
+        We return a new WsgiToAsgiInstance here with the WSGI app
+        and the scope, ready to respond when it is __call__ed.
+        """
+        await WsgiToAsgiInstance(self.wsgi_application)(scope, receive, send)
+
+
+class WsgiToAsgiInstance:
+    """
+    Per-socket instance of a wrapped WSGI application
+    """
+
+    def __init__(self, wsgi_application):
+        self.wsgi_application = wsgi_application
+        self.response_started = False
+
+    async def __call__(self, scope, receive, send):
+        if scope["type"] != "http":
+            raise ValueError("WSGI wrapper received a non-HTTP scope")
+        self.scope = scope
+        with SpooledTemporaryFile(max_size=65536) as body:
+            # Alright, wait for the http.request messages
+            while True:
+                message = await receive()
+                if message["type"] != "http.request":
+                    raise ValueError("WSGI wrapper received a non-HTTP-request message")
+                body.write(message.get("body", b""))
+                if not message.get("more_body"):
+                    break
+            body.seek(0)
+            # Wrap send so it can be called from the subthread
+            self.sync_send = AsyncToSync(send)
+            # Call the WSGI app
+            await self.run_wsgi_app(body)
+
+    def build_environ(self, scope, body):
+        """
+        Builds a scope and request body into a WSGI environ object.
+        """
+        environ = {
+            "REQUEST_METHOD": scope["method"],
+            "SCRIPT_NAME": scope.get("root_path", ""),
+            "PATH_INFO": scope["path"],
+            "QUERY_STRING": scope["query_string"].decode("ascii"),
+            "SERVER_PROTOCOL": "HTTP/%s" % scope["http_version"],
+            "wsgi.version": (1, 0),
+            "wsgi.url_scheme": scope.get("scheme", "http"),
+            "wsgi.input": body,
+            "wsgi.errors": BytesIO(),
+            "wsgi.multithread": True,
+            "wsgi.multiprocess": True,
+            "wsgi.run_once": False,
+        }
+        # Get server name and port - required in WSGI, not in ASGI
+        if "server" in scope:
+            environ["SERVER_NAME"] = scope["server"][0]
+            environ["SERVER_PORT"] = str(scope["server"][1])
+        else:
+            environ["SERVER_NAME"] = "localhost"
+            environ["SERVER_PORT"] = "80"
+
+        if "client" in scope:
+            environ["REMOTE_ADDR"] = scope["client"][0]
+
+        # Go through headers and make them into environ entries
+        for name, value in self.scope.get("headers", []):
+            name = name.decode("latin1")
+            if name == "content-length":
+                corrected_name = "CONTENT_LENGTH"
+            elif name == "content-type":
+                corrected_name = "CONTENT_TYPE"
+            else:
+                corrected_name = "HTTP_%s" % name.upper().replace("-", "_")
+            # HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in case
+            value = value.decode("latin1")
+            if corrected_name in environ:
+                value = environ[corrected_name] + "," + value
+            environ[corrected_name] = value
+        return environ
+
+    def start_response(self, status, response_headers, exc_info=None):
+        """
+        WSGI start_response callable.
+        """
+        # Don't allow re-calling once response has begun
+        if self.response_started:
+            raise exc_info[1].with_traceback(exc_info[2])
+        # Don't allow re-calling without exc_info
+        if hasattr(self, "response_start") and exc_info is None:
+            raise ValueError(
+                "You cannot call start_response a second time without exc_info"
+            )
+        # Extract status code
+        status_code, _ = status.split(" ", 1)
+        status_code = int(status_code)
+        # Extract headers
+        headers = [
+            (name.lower().encode("ascii"), value.encode("ascii"))
+            for name, value in response_headers
+        ]
+        # Build and send response start message.
+        self.response_start = {
+            "type": "http.response.start",
+            "status": status_code,
+            "headers": headers,
+        }
+
+    @sync_to_async
+    def run_wsgi_app(self, body):
+        """
+        Called in a subthread to run the WSGI app. We encapsulate like
+        this so that the start_response callable is called in the same thread.
+        """
+        # Translate the scope and incoming request body into a WSGI environ
+        environ = self.build_environ(self.scope, body)
+        # Run the WSGI app
+        for output in self.wsgi_application(environ, self.start_response):
+            # If this is the first response, include the response headers
+            if not self.response_started:
+                self.response_started = True
+                self.sync_send(self.response_start)
+            self.sync_send(
+                {"type": "http.response.body", "body": output, "more_body": True}
+            )
+        # Close connection
+        if not self.response_started:
+            self.response_started = True
+            self.sync_send(self.response_start)
+        self.sync_send({"type": "http.response.body"})

+ 24 - 0
venv/Lib/site-packages/django/__init__.py

@@ -0,0 +1,24 @@
+from django.utils.version import get_version
+
+VERSION = (3, 0, 4, 'final', 0)
+
+__version__ = get_version(VERSION)
+
+
+def setup(set_prefix=True):
+    """
+    Configure the settings (this happens as a side effect of accessing the
+    first setting), configure logging and populate the app registry.
+    Set the thread-local urlresolvers script prefix if `set_prefix` is True.
+    """
+    from django.apps import apps
+    from django.conf import settings
+    from django.urls import set_script_prefix
+    from django.utils.log import configure_logging
+
+    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
+    if set_prefix:
+        set_script_prefix(
+            '/' if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
+        )
+    apps.populate(settings.INSTALLED_APPS)

+ 9 - 0
venv/Lib/site-packages/django/__main__.py

@@ -0,0 +1,9 @@
+"""
+Invokes django-admin when the django module is run as a script.
+
+Example: python -m django check
+"""
+from django.core import management
+
+if __name__ == "__main__":
+    management.execute_from_command_line()

+ 4 - 0
venv/Lib/site-packages/django/apps/__init__.py

@@ -0,0 +1,4 @@
+from .config import AppConfig
+from .registry import apps
+
+__all__ = ['AppConfig', 'apps']

+ 216 - 0
venv/Lib/site-packages/django/apps/config.py

@@ -0,0 +1,216 @@
+import os
+from importlib import import_module
+
+from django.core.exceptions import ImproperlyConfigured
+from django.utils.module_loading import module_has_submodule
+
+MODELS_MODULE_NAME = 'models'
+
+
+class AppConfig:
+    """Class representing a Django application and its configuration."""
+
+    def __init__(self, app_name, app_module):
+        # Full Python path to the application e.g. 'django.contrib.admin'.
+        self.name = app_name
+
+        # Root module for the application e.g. <module 'django.contrib.admin'
+        # from 'django/contrib/admin/__init__.py'>.
+        self.module = app_module
+
+        # Reference to the Apps registry that holds this AppConfig. Set by the
+        # registry when it registers the AppConfig instance.
+        self.apps = None
+
+        # The following attributes could be defined at the class level in a
+        # subclass, hence the test-and-set pattern.
+
+        # Last component of the Python path to the application e.g. 'admin'.
+        # This value must be unique across a Django project.
+        if not hasattr(self, 'label'):
+            self.label = app_name.rpartition(".")[2]
+
+        # Human-readable name for the application e.g. "Admin".
+        if not hasattr(self, 'verbose_name'):
+            self.verbose_name = self.label.title()
+
+        # Filesystem path to the application directory e.g.
+        # '/path/to/django/contrib/admin'.
+        if not hasattr(self, 'path'):
+            self.path = self._path_from_module(app_module)
+
+        # Module containing models e.g. <module 'django.contrib.admin.models'
+        # from 'django/contrib/admin/models.py'>. Set by import_models().
+        # None if the application doesn't have a models module.
+        self.models_module = None
+
+        # Mapping of lowercase model names to model classes. Initially set to
+        # None to prevent accidental access before import_models() runs.
+        self.models = None
+
+    def __repr__(self):
+        return '<%s: %s>' % (self.__class__.__name__, self.label)
+
+    def _path_from_module(self, module):
+        """Attempt to determine app's filesystem path from its module."""
+        # See #21874 for extended discussion of the behavior of this method in
+        # various cases.
+        # Convert paths to list because Python's _NamespacePath doesn't support
+        # indexing.
+        paths = list(getattr(module, '__path__', []))
+        if len(paths) != 1:
+            filename = getattr(module, '__file__', None)
+            if filename is not None:
+                paths = [os.path.dirname(filename)]
+            else:
+                # For unknown reasons, sometimes the list returned by __path__
+                # contains duplicates that must be removed (#25246).
+                paths = list(set(paths))
+        if len(paths) > 1:
+            raise ImproperlyConfigured(
+                "The app module %r has multiple filesystem locations (%r); "
+                "you must configure this app with an AppConfig subclass "
+                "with a 'path' class attribute." % (module, paths))
+        elif not paths:
+            raise ImproperlyConfigured(
+                "The app module %r has no filesystem location, "
+                "you must configure this app with an AppConfig subclass "
+                "with a 'path' class attribute." % (module,))
+        return paths[0]
+
+    @classmethod
+    def create(cls, entry):
+        """
+        Factory that creates an app config from an entry in INSTALLED_APPS.
+        """
+        try:
+            # If import_module succeeds, entry is a path to an app module,
+            # which may specify an app config class with default_app_config.
+            # Otherwise, entry is a path to an app config class or an error.
+            module = import_module(entry)
+
+        except ImportError:
+            # Track that importing as an app module failed. If importing as an
+            # app config class fails too, we'll trigger the ImportError again.
+            module = None
+
+            mod_path, _, cls_name = entry.rpartition('.')
+
+            # Raise the original exception when entry cannot be a path to an
+            # app config class.
+            if not mod_path:
+                raise
+
+        else:
+            try:
+                # If this works, the app module specifies an app config class.
+                entry = module.default_app_config
+            except AttributeError:
+                # Otherwise, it simply uses the default app config class.
+                return cls(entry, module)
+            else:
+                mod_path, _, cls_name = entry.rpartition('.')
+
+        # If we're reaching this point, we must attempt to load the app config
+        # class located at <mod_path>.<cls_name>
+        mod = import_module(mod_path)
+        try:
+            cls = getattr(mod, cls_name)
+        except AttributeError:
+            if module is None:
+                # If importing as an app module failed, check if the module
+                # contains any valid AppConfigs and show them as choices.
+                # Otherwise, that error probably contains the most informative
+                # traceback, so trigger it again.
+                candidates = sorted(
+                    repr(name) for name, candidate in mod.__dict__.items()
+                    if isinstance(candidate, type) and
+                    issubclass(candidate, AppConfig) and
+                    candidate is not AppConfig
+                )
+                if candidates:
+                    raise ImproperlyConfigured(
+                        "'%s' does not contain a class '%s'. Choices are: %s."
+                        % (mod_path, cls_name, ', '.join(candidates))
+                    )
+                import_module(entry)
+            else:
+                raise
+
+        # Check for obvious errors. (This check prevents duck typing, but
+        # it could be removed if it became a problem in practice.)
+        if not issubclass(cls, AppConfig):
+            raise ImproperlyConfigured(
+                "'%s' isn't a subclass of AppConfig." % entry)
+
+        # Obtain app name here rather than in AppClass.__init__ to keep
+        # all error checking for entries in INSTALLED_APPS in one place.
+        try:
+            app_name = cls.name
+        except AttributeError:
+            raise ImproperlyConfigured(
+                "'%s' must supply a name attribute." % entry)
+
+        # Ensure app_name points to a valid module.
+        try:
+            app_module = import_module(app_name)
+        except ImportError:
+            raise ImproperlyConfigured(
+                "Cannot import '%s'. Check that '%s.%s.name' is correct." % (
+                    app_name, mod_path, cls_name,
+                )
+            )
+
+        # Entry is a path to an app config class.
+        return cls(app_name, app_module)
+
+    def get_model(self, model_name, require_ready=True):
+        """
+        Return the model with the given case-insensitive model_name.
+
+        Raise LookupError if no model exists with this name.
+        """
+        if require_ready:
+            self.apps.check_models_ready()
+        else:
+            self.apps.check_apps_ready()
+        try:
+            return self.models[model_name.lower()]
+        except KeyError:
+            raise LookupError(
+                "App '%s' doesn't have a '%s' model." % (self.label, model_name))
+
+    def get_models(self, include_auto_created=False, include_swapped=False):
+        """
+        Return an iterable of models.
+
+        By default, the following models aren't included:
+
+        - auto-created models for many-to-many relations without
+          an explicit intermediate table,
+        - models that have been swapped out.
+
+        Set the corresponding keyword argument to True to include such models.
+        Keyword arguments aren't documented; they're a private API.
+        """
+        self.apps.check_models_ready()
+        for model in self.models.values():
+            if model._meta.auto_created and not include_auto_created:
+                continue
+            if model._meta.swapped and not include_swapped:
+                continue
+            yield model
+
+    def import_models(self):
+        # Dictionary of models for this app, primarily maintained in the
+        # 'all_models' attribute of the Apps this AppConfig is attached to.
+        self.models = self.apps.all_models[self.label]
+
+        if module_has_submodule(self.module, MODELS_MODULE_NAME):
+            models_module_name = '%s.%s' % (self.name, MODELS_MODULE_NAME)
+            self.models_module = import_module(models_module_name)
+
+    def ready(self):
+        """
+        Override this method in subclasses to run code when Django starts.
+        """

+ 427 - 0
venv/Lib/site-packages/django/apps/registry.py

@@ -0,0 +1,427 @@
+import functools
+import sys
+import threading
+import warnings
+from collections import Counter, defaultdict
+from functools import partial
+
+from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
+
+from .config import AppConfig
+
+
+class Apps:
+    """
+    A registry that stores the configuration of installed applications.
+
+    It also keeps track of models, e.g. to provide reverse relations.
+    """
+
+    def __init__(self, installed_apps=()):
+        # installed_apps is set to None when creating the master registry
+        # because it cannot be populated at that point. Other registries must
+        # provide a list of installed apps and are populated immediately.
+        if installed_apps is None and hasattr(sys.modules[__name__], 'apps'):
+            raise RuntimeError("You must supply an installed_apps argument.")
+
+        # Mapping of app labels => model names => model classes. Every time a
+        # model is imported, ModelBase.__new__ calls apps.register_model which
+        # creates an entry in all_models. All imported models are registered,
+        # regardless of whether they're defined in an installed application
+        # and whether the registry has been populated. Since it isn't possible
+        # to reimport a module safely (it could reexecute initialization code)
+        # all_models is never overridden or reset.
+        self.all_models = defaultdict(dict)
+
+        # Mapping of labels to AppConfig instances for installed apps.
+        self.app_configs = {}
+
+        # Stack of app_configs. Used to store the current state in
+        # set_available_apps and set_installed_apps.
+        self.stored_app_configs = []
+
+        # Whether the registry is populated.
+        self.apps_ready = self.models_ready = self.ready = False
+        # For the autoreloader.
+        self.ready_event = threading.Event()
+
+        # Lock for thread-safe population.
+        self._lock = threading.RLock()
+        self.loading = False
+
+        # Maps ("app_label", "modelname") tuples to lists of functions to be
+        # called when the corresponding model is ready. Used by this class's
+        # `lazy_model_operation()` and `do_pending_operations()` methods.
+        self._pending_operations = defaultdict(list)
+
+        # Populate apps and models, unless it's the master registry.
+        if installed_apps is not None:
+            self.populate(installed_apps)
+
+    def populate(self, installed_apps=None):
+        """
+        Load application configurations and models.
+
+        Import each application module and then each model module.
+
+        It is thread-safe and idempotent, but not reentrant.
+        """
+        if self.ready:
+            return
+
+        # populate() might be called by two threads in parallel on servers
+        # that create threads before initializing the WSGI callable.
+        with self._lock:
+            if self.ready:
+                return
+
+            # An RLock prevents other threads from entering this section. The
+            # compare and set operation below is atomic.
+            if self.loading:
+                # Prevent reentrant calls to avoid running AppConfig.ready()
+                # methods twice.
+                raise RuntimeError("populate() isn't reentrant")
+            self.loading = True
+
+            # Phase 1: initialize app configs and import app modules.
+            for entry in installed_apps:
+                if isinstance(entry, AppConfig):
+                    app_config = entry
+                else:
+                    app_config = AppConfig.create(entry)
+                if app_config.label in self.app_configs:
+                    raise ImproperlyConfigured(
+                        "Application labels aren't unique, "
+                        "duplicates: %s" % app_config.label)
+
+                self.app_configs[app_config.label] = app_config
+                app_config.apps = self
+
+            # Check for duplicate app names.
+            counts = Counter(
+                app_config.name for app_config in self.app_configs.values())
+            duplicates = [
+                name for name, count in counts.most_common() if count > 1]
+            if duplicates:
+                raise ImproperlyConfigured(
+                    "Application names aren't unique, "
+                    "duplicates: %s" % ", ".join(duplicates))
+
+            self.apps_ready = True
+
+            # Phase 2: import models modules.
+            for app_config in self.app_configs.values():
+                app_config.import_models()
+
+            self.clear_cache()
+
+            self.models_ready = True
+
+            # Phase 3: run ready() methods of app configs.
+            for app_config in self.get_app_configs():
+                app_config.ready()
+
+            self.ready = True
+            self.ready_event.set()
+
+    def check_apps_ready(self):
+        """Raise an exception if all apps haven't been imported yet."""
+        if not self.apps_ready:
+            from django.conf import settings
+            # If "not ready" is due to unconfigured settings, accessing
+            # INSTALLED_APPS raises a more helpful ImproperlyConfigured
+            # exception.
+            settings.INSTALLED_APPS
+            raise AppRegistryNotReady("Apps aren't loaded yet.")
+
+    def check_models_ready(self):
+        """Raise an exception if all models haven't been imported yet."""
+        if not self.models_ready:
+            raise AppRegistryNotReady("Models aren't loaded yet.")
+
+    def get_app_configs(self):
+        """Import applications and return an iterable of app configs."""
+        self.check_apps_ready()
+        return self.app_configs.values()
+
+    def get_app_config(self, app_label):
+        """
+        Import applications and returns an app config for the given label.
+
+        Raise LookupError if no application exists with this label.
+        """
+        self.check_apps_ready()
+        try:
+            return self.app_configs[app_label]
+        except KeyError:
+            message = "No installed app with label '%s'." % app_label
+            for app_config in self.get_app_configs():
+                if app_config.name == app_label:
+                    message += " Did you mean '%s'?" % app_config.label
+                    break
+            raise LookupError(message)
+
+    # This method is performance-critical at least for Django's test suite.
+    @functools.lru_cache(maxsize=None)
+    def get_models(self, include_auto_created=False, include_swapped=False):
+        """
+        Return a list of all installed models.
+
+        By default, the following models aren't included:
+
+        - auto-created models for many-to-many relations without
+          an explicit intermediate table,
+        - models that have been swapped out.
+
+        Set the corresponding keyword argument to True to include such models.
+        """
+        self.check_models_ready()
+
+        result = []
+        for app_config in self.app_configs.values():
+            result.extend(app_config.get_models(include_auto_created, include_swapped))
+        return result
+
+    def get_model(self, app_label, model_name=None, require_ready=True):
+        """
+        Return the model matching the given app_label and model_name.
+
+        As a shortcut, app_label may be in the form <app_label>.<model_name>.
+
+        model_name is case-insensitive.
+
+        Raise LookupError if no application exists with this label, or no
+        model exists with this name in the application. Raise ValueError if
+        called with a single argument that doesn't contain exactly one dot.
+        """
+        if require_ready:
+            self.check_models_ready()
+        else:
+            self.check_apps_ready()
+
+        if model_name is None:
+            app_label, model_name = app_label.split('.')
+
+        app_config = self.get_app_config(app_label)
+
+        if not require_ready and app_config.models is None:
+            app_config.import_models()
+
+        return app_config.get_model(model_name, require_ready=require_ready)
+
+    def register_model(self, app_label, model):
+        # Since this method is called when models are imported, it cannot
+        # perform imports because of the risk of import loops. It mustn't
+        # call get_app_config().
+        model_name = model._meta.model_name
+        app_models = self.all_models[app_label]
+        if model_name in app_models:
+            if (model.__name__ == app_models[model_name].__name__ and
+                    model.__module__ == app_models[model_name].__module__):
+                warnings.warn(
+                    "Model '%s.%s' was already registered. "
+                    "Reloading models is not advised as it can lead to inconsistencies, "
+                    "most notably with related models." % (app_label, model_name),
+                    RuntimeWarning, stacklevel=2)
+            else:
+                raise RuntimeError(
+                    "Conflicting '%s' models in application '%s': %s and %s." %
+                    (model_name, app_label, app_models[model_name], model))
+        app_models[model_name] = model
+        self.do_pending_operations(model)
+        self.clear_cache()
+
+    def is_installed(self, app_name):
+        """
+        Check whether an application with this name exists in the registry.
+
+        app_name is the full name of the app e.g. 'django.contrib.admin'.
+        """
+        self.check_apps_ready()
+        return any(ac.name == app_name for ac in self.app_configs.values())
+
+    def get_containing_app_config(self, object_name):
+        """
+        Look for an app config containing a given object.
+
+        object_name is the dotted Python path to the object.
+
+        Return the app config for the inner application in case of nesting.
+        Return None if the object isn't in any registered app config.
+        """
+        self.check_apps_ready()
+        candidates = []
+        for app_config in self.app_configs.values():
+            if object_name.startswith(app_config.name):
+                subpath = object_name[len(app_config.name):]
+                if subpath == '' or subpath[0] == '.':
+                    candidates.append(app_config)
+        if candidates:
+            return sorted(candidates, key=lambda ac: -len(ac.name))[0]
+
+    def get_registered_model(self, app_label, model_name):
+        """
+        Similar to get_model(), but doesn't require that an app exists with
+        the given app_label.
+
+        It's safe to call this method at import time, even while the registry
+        is being populated.
+        """
+        model = self.all_models[app_label].get(model_name.lower())
+        if model is None:
+            raise LookupError(
+                "Model '%s.%s' not registered." % (app_label, model_name))
+        return model
+
+    @functools.lru_cache(maxsize=None)
+    def get_swappable_settings_name(self, to_string):
+        """
+        For a given model string (e.g. "auth.User"), return the name of the
+        corresponding settings name if it refers to a swappable model. If the
+        referred model is not swappable, return None.
+
+        This method is decorated with lru_cache because it's performance
+        critical when it comes to migrations. Since the swappable settings don't
+        change after Django has loaded the settings, there is no reason to get
+        the respective settings attribute over and over again.
+        """
+        for model in self.get_models(include_swapped=True):
+            swapped = model._meta.swapped
+            # Is this model swapped out for the model given by to_string?
+            if swapped and swapped == to_string:
+                return model._meta.swappable
+            # Is this model swappable and the one given by to_string?
+            if model._meta.swappable and model._meta.label == to_string:
+                return model._meta.swappable
+        return None
+
+    def set_available_apps(self, available):
+        """
+        Restrict the set of installed apps used by get_app_config[s].
+
+        available must be an iterable of application names.
+
+        set_available_apps() must be balanced with unset_available_apps().
+
+        Primarily used for performance optimization in TransactionTestCase.
+
+        This method is safe in the sense that it doesn't trigger any imports.
+        """
+        available = set(available)
+        installed = {app_config.name for app_config in self.get_app_configs()}
+        if not available.issubset(installed):
+            raise ValueError(
+                "Available apps isn't a subset of installed apps, extra apps: %s"
+                % ", ".join(available - installed)
+            )
+
+        self.stored_app_configs.append(self.app_configs)
+        self.app_configs = {
+            label: app_config
+            for label, app_config in self.app_configs.items()
+            if app_config.name in available
+        }
+        self.clear_cache()
+
+    def unset_available_apps(self):
+        """Cancel a previous call to set_available_apps()."""
+        self.app_configs = self.stored_app_configs.pop()
+        self.clear_cache()
+
+    def set_installed_apps(self, installed):
+        """
+        Enable a different set of installed apps for get_app_config[s].
+
+        installed must be an iterable in the same format as INSTALLED_APPS.
+
+        set_installed_apps() must be balanced with unset_installed_apps(),
+        even if it exits with an exception.
+
+        Primarily used as a receiver of the setting_changed signal in tests.
+
+        This method may trigger new imports, which may add new models to the
+        registry of all imported models. They will stay in the registry even
+        after unset_installed_apps(). Since it isn't possible to replay
+        imports safely (e.g. that could lead to registering listeners twice),
+        models are registered when they're imported and never removed.
+        """
+        if not self.ready:
+            raise AppRegistryNotReady("App registry isn't ready yet.")
+        self.stored_app_configs.append(self.app_configs)
+        self.app_configs = {}
+        self.apps_ready = self.models_ready = self.loading = self.ready = False
+        self.clear_cache()
+        self.populate(installed)
+
+    def unset_installed_apps(self):
+        """Cancel a previous call to set_installed_apps()."""
+        self.app_configs = self.stored_app_configs.pop()
+        self.apps_ready = self.models_ready = self.ready = True
+        self.clear_cache()
+
+    def clear_cache(self):
+        """
+        Clear all internal caches, for methods that alter the app registry.
+
+        This is mostly used in tests.
+        """
+        # Call expire cache on each model. This will purge
+        # the relation tree and the fields cache.
+        self.get_models.cache_clear()
+        if self.ready:
+            # Circumvent self.get_models() to prevent that the cache is refilled.
+            # This particularly prevents that an empty value is cached while cloning.
+            for app_config in self.app_configs.values():
+                for model in app_config.get_models(include_auto_created=True):
+                    model._meta._expire_cache()
+
+    def lazy_model_operation(self, function, *model_keys):
+        """
+        Take a function and a number of ("app_label", "modelname") tuples, and
+        when all the corresponding models have been imported and registered,
+        call the function with the model classes as its arguments.
+
+        The function passed to this method must accept exactly n models as
+        arguments, where n=len(model_keys).
+        """
+        # Base case: no arguments, just execute the function.
+        if not model_keys:
+            function()
+        # Recursive case: take the head of model_keys, wait for the
+        # corresponding model class to be imported and registered, then apply
+        # that argument to the supplied function. Pass the resulting partial
+        # to lazy_model_operation() along with the remaining model args and
+        # repeat until all models are loaded and all arguments are applied.
+        else:
+            next_model, *more_models = model_keys
+
+            # This will be executed after the class corresponding to next_model
+            # has been imported and registered. The `func` attribute provides
+            # duck-type compatibility with partials.
+            def apply_next_model(model):
+                next_function = partial(apply_next_model.func, model)
+                self.lazy_model_operation(next_function, *more_models)
+            apply_next_model.func = function
+
+            # If the model has already been imported and registered, partially
+            # apply it to the function now. If not, add it to the list of
+            # pending operations for the model, where it will be executed with
+            # the model class as its sole argument once the model is ready.
+            try:
+                model_class = self.get_registered_model(*next_model)
+            except LookupError:
+                self._pending_operations[next_model].append(apply_next_model)
+            else:
+                apply_next_model(model_class)
+
+    def do_pending_operations(self, model):
+        """
+        Take a newly-prepared model and pass it to each function waiting for
+        it. This is called at the very end of Apps.register_model().
+        """
+        key = model._meta.app_label, model._meta.model_name
+        for function in self._pending_operations.pop(key, []):
+            function(model)
+
+
+apps = Apps(installed_apps=None)

+ 5 - 0
venv/Lib/site-packages/django/bin/django-admin.py

@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+from django.core import management
+
+if __name__ == "__main__":
+    management.execute_from_command_line()

+ 236 - 0
venv/Lib/site-packages/django/conf/__init__.py

@@ -0,0 +1,236 @@
+"""
+Settings and configuration for Django.
+
+Read values from the module specified by the DJANGO_SETTINGS_MODULE environment
+variable, and then from django.conf.global_settings; see the global_settings.py
+for a list of all possible variables.
+"""
+
+import importlib
+import os
+import time
+import traceback
+import warnings
+from pathlib import Path
+
+import django
+from django.conf import global_settings
+from django.core.exceptions import ImproperlyConfigured
+from django.utils.deprecation import RemovedInDjango31Warning
+from django.utils.functional import LazyObject, empty
+
+ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
+
+FILE_CHARSET_DEPRECATED_MSG = (
+    'The FILE_CHARSET setting is deprecated. Starting with Django 3.1, all '
+    'files read from disk must be UTF-8 encoded.'
+)
+
+
+class SettingsReference(str):
+    """
+    String subclass which references a current settings value. It's treated as
+    the value in memory but serializes to a settings.NAME attribute reference.
+    """
+    def __new__(self, value, setting_name):
+        return str.__new__(self, value)
+
+    def __init__(self, value, setting_name):
+        self.setting_name = setting_name
+
+
+class LazySettings(LazyObject):
+    """
+    A lazy proxy for either global Django settings or a custom settings object.
+    The user can manually configure settings prior to using them. Otherwise,
+    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
+    """
+    def _setup(self, name=None):
+        """
+        Load the settings module pointed to by the environment variable. This
+        is used the first time settings are needed, if the user hasn't
+        configured settings manually.
+        """
+        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
+        if not settings_module:
+            desc = ("setting %s" % name) if name else "settings"
+            raise ImproperlyConfigured(
+                "Requested %s, but settings are not configured. "
+                "You must either define the environment variable %s "
+                "or call settings.configure() before accessing settings."
+                % (desc, ENVIRONMENT_VARIABLE))
+
+        self._wrapped = Settings(settings_module)
+
+    def __repr__(self):
+        # Hardcode the class name as otherwise it yields 'Settings'.
+        if self._wrapped is empty:
+            return '<LazySettings [Unevaluated]>'
+        return '<LazySettings "%(settings_module)s">' % {
+            'settings_module': self._wrapped.SETTINGS_MODULE,
+        }
+
+    def __getattr__(self, name):
+        """Return the value of a setting and cache it in self.__dict__."""
+        if self._wrapped is empty:
+            self._setup(name)
+        val = getattr(self._wrapped, name)
+        self.__dict__[name] = val
+        return val
+
+    def __setattr__(self, name, value):
+        """
+        Set the value of setting. Clear all cached values if _wrapped changes
+        (@override_settings does this) or clear single values when set.
+        """
+        if name == '_wrapped':
+            self.__dict__.clear()
+        else:
+            self.__dict__.pop(name, None)
+        super().__setattr__(name, value)
+
+    def __delattr__(self, name):
+        """Delete a setting and clear it from cache if needed."""
+        super().__delattr__(name)
+        self.__dict__.pop(name, None)
+
+    def configure(self, default_settings=global_settings, **options):
+        """
+        Called to manually configure the settings. The 'default_settings'
+        parameter sets where to retrieve any unspecified values from (its
+        argument must support attribute access (__getattr__)).
+        """
+        if self._wrapped is not empty:
+            raise RuntimeError('Settings already configured.')
+        holder = UserSettingsHolder(default_settings)
+        for name, value in options.items():
+            if not name.isupper():
+                raise TypeError('Setting %r must be uppercase.' % name)
+            setattr(holder, name, value)
+        self._wrapped = holder
+
+    @property
+    def configured(self):
+        """Return True if the settings have already been configured."""
+        return self._wrapped is not empty
+
+    @property
+    def FILE_CHARSET(self):
+        stack = traceback.extract_stack()
+        # Show a warning if the setting is used outside of Django.
+        # Stack index: -1 this line, -2 the caller.
+        filename, _line_number, _function_name, _text = stack[-2]
+        if not filename.startswith(os.path.dirname(django.__file__)):
+            warnings.warn(
+                FILE_CHARSET_DEPRECATED_MSG,
+                RemovedInDjango31Warning,
+                stacklevel=2,
+            )
+        return self.__getattr__('FILE_CHARSET')
+
+
+class Settings:
+    def __init__(self, settings_module):
+        # update this dict from global settings (but only for ALL_CAPS settings)
+        for setting in dir(global_settings):
+            if setting.isupper():
+                setattr(self, setting, getattr(global_settings, setting))
+
+        # store the settings module in case someone later cares
+        self.SETTINGS_MODULE = settings_module
+
+        mod = importlib.import_module(self.SETTINGS_MODULE)
+
+        tuple_settings = (
+            "INSTALLED_APPS",
+            "TEMPLATE_DIRS",
+            "LOCALE_PATHS",
+        )
+        self._explicit_settings = set()
+        for setting in dir(mod):
+            if setting.isupper():
+                setting_value = getattr(mod, setting)
+
+                if (setting in tuple_settings and
+                        not isinstance(setting_value, (list, tuple))):
+                    raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting)
+                setattr(self, setting, setting_value)
+                self._explicit_settings.add(setting)
+
+        if not self.SECRET_KEY:
+            raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
+
+        if self.is_overridden('FILE_CHARSET'):
+            warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning)
+
+        if hasattr(time, 'tzset') and self.TIME_ZONE:
+            # When we can, attempt to validate the timezone. If we can't find
+            # this file, no check happens and it's harmless.
+            zoneinfo_root = Path('/usr/share/zoneinfo')
+            zone_info_file = zoneinfo_root.joinpath(*self.TIME_ZONE.split('/'))
+            if zoneinfo_root.exists() and not zone_info_file.exists():
+                raise ValueError("Incorrect timezone setting: %s" % self.TIME_ZONE)
+            # Move the time zone info into os.environ. See ticket #2315 for why
+            # we don't do this unconditionally (breaks Windows).
+            os.environ['TZ'] = self.TIME_ZONE
+            time.tzset()
+
+    def is_overridden(self, setting):
+        return setting in self._explicit_settings
+
+    def __repr__(self):
+        return '<%(cls)s "%(settings_module)s">' % {
+            'cls': self.__class__.__name__,
+            'settings_module': self.SETTINGS_MODULE,
+        }
+
+
+class UserSettingsHolder:
+    """Holder for user configured settings."""
+    # SETTINGS_MODULE doesn't make much sense in the manually configured
+    # (standalone) case.
+    SETTINGS_MODULE = None
+
+    def __init__(self, default_settings):
+        """
+        Requests for configuration variables not in this class are satisfied
+        from the module specified in default_settings (if possible).
+        """
+        self.__dict__['_deleted'] = set()
+        self.default_settings = default_settings
+
+    def __getattr__(self, name):
+        if not name.isupper() or name in self._deleted:
+            raise AttributeError
+        return getattr(self.default_settings, name)
+
+    def __setattr__(self, name, value):
+        self._deleted.discard(name)
+        if name == 'FILE_CHARSET':
+            warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning)
+        super().__setattr__(name, value)
+
+    def __delattr__(self, name):
+        self._deleted.add(name)
+        if hasattr(self, name):
+            super().__delattr__(name)
+
+    def __dir__(self):
+        return sorted(
+            s for s in [*self.__dict__, *dir(self.default_settings)]
+            if s not in self._deleted
+        )
+
+    def is_overridden(self, setting):
+        deleted = (setting in self._deleted)
+        set_locally = (setting in self.__dict__)
+        set_on_default = getattr(self.default_settings, 'is_overridden', lambda s: False)(setting)
+        return deleted or set_locally or set_on_default
+
+    def __repr__(self):
+        return '<%(cls)s>' % {
+            'cls': self.__class__.__name__,
+        }
+
+
+settings = LazySettings()

+ 0 - 0
venv/Lib/site-packages/django/conf/app_template/__init__.py-tpl


+ 3 - 0
venv/Lib/site-packages/django/conf/app_template/admin.py-tpl

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
venv/Lib/site-packages/django/conf/app_template/apps.py-tpl

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class {{ camel_case_app_name }}Config(AppConfig):
+    name = '{{ app_name }}'

+ 0 - 0
venv/Lib/site-packages/django/conf/app_template/migrations/__init__.py-tpl


+ 3 - 0
venv/Lib/site-packages/django/conf/app_template/models.py-tpl

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 3 - 0
venv/Lib/site-packages/django/conf/app_template/tests.py-tpl

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
venv/Lib/site-packages/django/conf/app_template/views.py-tpl

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 639 - 0
venv/Lib/site-packages/django/conf/global_settings.py

@@ -0,0 +1,639 @@
+"""
+Default Django settings. Override these with settings in the module pointed to
+by the DJANGO_SETTINGS_MODULE environment variable.
+"""
+
+
+# This is defined here as a do-nothing function because we can't import
+# django.utils.translation -- that module depends on the settings.
+def gettext_noop(s):
+    return s
+
+
+####################
+# CORE             #
+####################
+
+DEBUG = False
+
+# Whether the framework should propagate raw exceptions rather than catching
+# them. This is useful under some testing situations and should never be used
+# on a live site.
+DEBUG_PROPAGATE_EXCEPTIONS = False
+
+# People who get code error notifications.
+# In the format [('Full Name', 'email@example.com'), ('Full Name', 'anotheremail@example.com')]
+ADMINS = []
+
+# List of IP addresses, as strings, that:
+#   * See debug comments, when DEBUG is true
+#   * Receive x-headers
+INTERNAL_IPS = []
+
+# Hosts/domain names that are valid for this site.
+# "*" matches anything, ".example.com" matches example.com and all subdomains
+ALLOWED_HOSTS = []
+
+# Local time zone for this installation. All choices can be found here:
+# https://en.wikipedia.org/wiki/List_of_tz_zones_by_name (although not all
+# systems may support all possibilities). When USE_TZ is True, this is
+# interpreted as the default user time zone.
+TIME_ZONE = 'America/Chicago'
+
+# If you set this to True, Django will use timezone-aware datetimes.
+USE_TZ = False
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+# Languages we provide translations for, out of the box.
+LANGUAGES = [
+    ('af', gettext_noop('Afrikaans')),
+    ('ar', gettext_noop('Arabic')),
+    ('ast', gettext_noop('Asturian')),
+    ('az', gettext_noop('Azerbaijani')),
+    ('bg', gettext_noop('Bulgarian')),
+    ('be', gettext_noop('Belarusian')),
+    ('bn', gettext_noop('Bengali')),
+    ('br', gettext_noop('Breton')),
+    ('bs', gettext_noop('Bosnian')),
+    ('ca', gettext_noop('Catalan')),
+    ('cs', gettext_noop('Czech')),
+    ('cy', gettext_noop('Welsh')),
+    ('da', gettext_noop('Danish')),
+    ('de', gettext_noop('German')),
+    ('dsb', gettext_noop('Lower Sorbian')),
+    ('el', gettext_noop('Greek')),
+    ('en', gettext_noop('English')),
+    ('en-au', gettext_noop('Australian English')),
+    ('en-gb', gettext_noop('British English')),
+    ('eo', gettext_noop('Esperanto')),
+    ('es', gettext_noop('Spanish')),
+    ('es-ar', gettext_noop('Argentinian Spanish')),
+    ('es-co', gettext_noop('Colombian Spanish')),
+    ('es-mx', gettext_noop('Mexican Spanish')),
+    ('es-ni', gettext_noop('Nicaraguan Spanish')),
+    ('es-ve', gettext_noop('Venezuelan Spanish')),
+    ('et', gettext_noop('Estonian')),
+    ('eu', gettext_noop('Basque')),
+    ('fa', gettext_noop('Persian')),
+    ('fi', gettext_noop('Finnish')),
+    ('fr', gettext_noop('French')),
+    ('fy', gettext_noop('Frisian')),
+    ('ga', gettext_noop('Irish')),
+    ('gd', gettext_noop('Scottish Gaelic')),
+    ('gl', gettext_noop('Galician')),
+    ('he', gettext_noop('Hebrew')),
+    ('hi', gettext_noop('Hindi')),
+    ('hr', gettext_noop('Croatian')),
+    ('hsb', gettext_noop('Upper Sorbian')),
+    ('hu', gettext_noop('Hungarian')),
+    ('hy', gettext_noop('Armenian')),
+    ('ia', gettext_noop('Interlingua')),
+    ('id', gettext_noop('Indonesian')),
+    ('io', gettext_noop('Ido')),
+    ('is', gettext_noop('Icelandic')),
+    ('it', gettext_noop('Italian')),
+    ('ja', gettext_noop('Japanese')),
+    ('ka', gettext_noop('Georgian')),
+    ('kab', gettext_noop('Kabyle')),
+    ('kk', gettext_noop('Kazakh')),
+    ('km', gettext_noop('Khmer')),
+    ('kn', gettext_noop('Kannada')),
+    ('ko', gettext_noop('Korean')),
+    ('lb', gettext_noop('Luxembourgish')),
+    ('lt', gettext_noop('Lithuanian')),
+    ('lv', gettext_noop('Latvian')),
+    ('mk', gettext_noop('Macedonian')),
+    ('ml', gettext_noop('Malayalam')),
+    ('mn', gettext_noop('Mongolian')),
+    ('mr', gettext_noop('Marathi')),
+    ('my', gettext_noop('Burmese')),
+    ('nb', gettext_noop('Norwegian Bokmål')),
+    ('ne', gettext_noop('Nepali')),
+    ('nl', gettext_noop('Dutch')),
+    ('nn', gettext_noop('Norwegian Nynorsk')),
+    ('os', gettext_noop('Ossetic')),
+    ('pa', gettext_noop('Punjabi')),
+    ('pl', gettext_noop('Polish')),
+    ('pt', gettext_noop('Portuguese')),
+    ('pt-br', gettext_noop('Brazilian Portuguese')),
+    ('ro', gettext_noop('Romanian')),
+    ('ru', gettext_noop('Russian')),
+    ('sk', gettext_noop('Slovak')),
+    ('sl', gettext_noop('Slovenian')),
+    ('sq', gettext_noop('Albanian')),
+    ('sr', gettext_noop('Serbian')),
+    ('sr-latn', gettext_noop('Serbian Latin')),
+    ('sv', gettext_noop('Swedish')),
+    ('sw', gettext_noop('Swahili')),
+    ('ta', gettext_noop('Tamil')),
+    ('te', gettext_noop('Telugu')),
+    ('th', gettext_noop('Thai')),
+    ('tr', gettext_noop('Turkish')),
+    ('tt', gettext_noop('Tatar')),
+    ('udm', gettext_noop('Udmurt')),
+    ('uk', gettext_noop('Ukrainian')),
+    ('ur', gettext_noop('Urdu')),
+    ('uz', gettext_noop('Uzbek')),
+    ('vi', gettext_noop('Vietnamese')),
+    ('zh-hans', gettext_noop('Simplified Chinese')),
+    ('zh-hant', gettext_noop('Traditional Chinese')),
+]
+
+# Languages using BiDi (right-to-left) layout
+LANGUAGES_BIDI = ["he", "ar", "fa", "ur"]
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+LOCALE_PATHS = []
+
+# Settings for language cookie
+LANGUAGE_COOKIE_NAME = 'django_language'
+LANGUAGE_COOKIE_AGE = None
+LANGUAGE_COOKIE_DOMAIN = None
+LANGUAGE_COOKIE_PATH = '/'
+LANGUAGE_COOKIE_SECURE = False
+LANGUAGE_COOKIE_HTTPONLY = False
+LANGUAGE_COOKIE_SAMESITE = None
+
+
+# If you set this to True, Django will format dates, numbers and calendars
+# according to user current locale.
+USE_L10N = False
+
+# Not-necessarily-technical managers of the site. They get broken link
+# notifications and other various emails.
+MANAGERS = ADMINS
+
+# Default charset to use for all HttpResponse objects, if a MIME type isn't
+# manually specified. It's used to construct the Content-Type header.
+DEFAULT_CHARSET = 'utf-8'
+
+# Encoding of files read from disk (template and initial SQL files).
+FILE_CHARSET = 'utf-8'
+
+# Email address that error messages come from.
+SERVER_EMAIL = 'root@localhost'
+
+# Database connection info. If left empty, will default to the dummy backend.
+DATABASES = {}
+
+# Classes used to implement DB routing behavior.
+DATABASE_ROUTERS = []
+
+# The email backend to use. For possible shortcuts see django.core.mail.
+# The default is to use the SMTP backend.
+# Third-party backends can be specified by providing a Python path
+# to a module that defines an EmailBackend class.
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+
+# Host for sending email.
+EMAIL_HOST = 'localhost'
+
+# Port for sending email.
+EMAIL_PORT = 25
+
+# Whether to send SMTP 'Date' header in the local time zone or in UTC.
+EMAIL_USE_LOCALTIME = False
+
+# Optional SMTP authentication information for EMAIL_HOST.
+EMAIL_HOST_USER = ''
+EMAIL_HOST_PASSWORD = ''
+EMAIL_USE_TLS = False
+EMAIL_USE_SSL = False
+EMAIL_SSL_CERTFILE = None
+EMAIL_SSL_KEYFILE = None
+EMAIL_TIMEOUT = None
+
+# List of strings representing installed apps.
+INSTALLED_APPS = []
+
+TEMPLATES = []
+
+# Default form rendering class.
+FORM_RENDERER = 'django.forms.renderers.DjangoTemplates'
+
+# Default email address to use for various automated correspondence from
+# the site managers.
+DEFAULT_FROM_EMAIL = 'webmaster@localhost'
+
+# Subject-line prefix for email messages send with django.core.mail.mail_admins
+# or ...mail_managers.  Make sure to include the trailing space.
+EMAIL_SUBJECT_PREFIX = '[Django] '
+
+# Whether to append trailing slashes to URLs.
+APPEND_SLASH = True
+
+# Whether to prepend the "www." subdomain to URLs that don't have it.
+PREPEND_WWW = False
+
+# Override the server-derived value of SCRIPT_NAME
+FORCE_SCRIPT_NAME = None
+
+# List of compiled regular expression objects representing User-Agent strings
+# that are not allowed to visit any page, systemwide. Use this for bad
+# robots/crawlers. Here are a few examples:
+#     import re
+#     DISALLOWED_USER_AGENTS = [
+#         re.compile(r'^NaverBot.*'),
+#         re.compile(r'^EmailSiphon.*'),
+#         re.compile(r'^SiteSucker.*'),
+#         re.compile(r'^sohu-search'),
+#     ]
+DISALLOWED_USER_AGENTS = []
+
+ABSOLUTE_URL_OVERRIDES = {}
+
+# List of compiled regular expression objects representing URLs that need not
+# be reported by BrokenLinkEmailsMiddleware. Here are a few examples:
+#    import re
+#    IGNORABLE_404_URLS = [
+#        re.compile(r'^/apple-touch-icon.*\.png$'),
+#        re.compile(r'^/favicon.ico$'),
+#        re.compile(r'^/robots.txt$'),
+#        re.compile(r'^/phpmyadmin/'),
+#        re.compile(r'\.(cgi|php|pl)$'),
+#    ]
+IGNORABLE_404_URLS = []
+
+# A secret key for this particular Django installation. Used in secret-key
+# hashing algorithms. Set this in your settings, or Django will complain
+# loudly.
+SECRET_KEY = ''
+
+# Default file storage mechanism that holds media.
+DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
+
+# Absolute filesystem path to the directory that will hold user-uploaded files.
+# Example: "/var/www/example.com/media/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT.
+# Examples: "http://example.com/media/", "http://media.example.com/"
+MEDIA_URL = ''
+
+# Absolute path to the directory static files should be collected to.
+# Example: "/var/www/example.com/static/"
+STATIC_ROOT = None
+
+# URL that handles the static files served from STATIC_ROOT.
+# Example: "http://example.com/static/", "http://static.example.com/"
+STATIC_URL = None
+
+# List of upload handler classes to be applied in order.
+FILE_UPLOAD_HANDLERS = [
+    'django.core.files.uploadhandler.MemoryFileUploadHandler',
+    'django.core.files.uploadhandler.TemporaryFileUploadHandler',
+]
+
+# Maximum size, in bytes, of a request before it will be streamed to the
+# file system instead of into memory.
+FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440  # i.e. 2.5 MB
+
+# Maximum size in bytes of request data (excluding file uploads) that will be
+# read before a SuspiciousOperation (RequestDataTooBig) is raised.
+DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440  # i.e. 2.5 MB
+
+# Maximum number of GET/POST parameters that will be read before a
+# SuspiciousOperation (TooManyFieldsSent) is raised.
+DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000
+
+# Directory in which upload streamed files will be temporarily saved. A value of
+# `None` will make Django use the operating system's default temporary directory
+# (i.e. "/tmp" on *nix systems).
+FILE_UPLOAD_TEMP_DIR = None
+
+# The numeric mode to set newly-uploaded files to. The value should be a mode
+# you'd pass directly to os.chmod; see https://docs.python.org/library/os.html#files-and-directories.
+FILE_UPLOAD_PERMISSIONS = 0o644
+
+# The numeric mode to assign to newly-created directories, when uploading files.
+# The value should be a mode as you'd pass to os.chmod;
+# see https://docs.python.org/library/os.html#files-and-directories.
+FILE_UPLOAD_DIRECTORY_PERMISSIONS = None
+
+# Python module path where user will place custom format definition.
+# The directory where this setting is pointing should contain subdirectories
+# named as the locales, containing a formats.py file
+# (i.e. "myproject.locale" for myproject/locale/en/formats.py etc. use)
+FORMAT_MODULE_PATH = None
+
+# Default formatting for date objects. See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+DATE_FORMAT = 'N j, Y'
+
+# Default formatting for datetime objects. See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+DATETIME_FORMAT = 'N j, Y, P'
+
+# Default formatting for time objects. See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+TIME_FORMAT = 'P'
+
+# Default formatting for date objects when only the year and month are relevant.
+# See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+YEAR_MONTH_FORMAT = 'F Y'
+
+# Default formatting for date objects when only the month and day are relevant.
+# See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+MONTH_DAY_FORMAT = 'F j'
+
+# Default short formatting for date objects. See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+SHORT_DATE_FORMAT = 'm/d/Y'
+
+# Default short formatting for datetime objects.
+# See all available format strings here:
+# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+SHORT_DATETIME_FORMAT = 'm/d/Y P'
+
+# Default formats to be used when parsing dates from input boxes, in order
+# See all available format string here:
+# https://docs.python.org/library/datetime.html#strftime-behavior
+# * Note that these format strings are different from the ones to display dates
+DATE_INPUT_FORMATS = [
+    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y',  # '2006-10-25', '10/25/2006', '10/25/06'
+    '%b %d %Y', '%b %d, %Y',             # 'Oct 25 2006', 'Oct 25, 2006'
+    '%d %b %Y', '%d %b, %Y',             # '25 Oct 2006', '25 Oct, 2006'
+    '%B %d %Y', '%B %d, %Y',             # 'October 25 2006', 'October 25, 2006'
+    '%d %B %Y', '%d %B, %Y',             # '25 October 2006', '25 October, 2006'
+]
+
+# Default formats to be used when parsing times from input boxes, in order
+# See all available format string here:
+# https://docs.python.org/library/datetime.html#strftime-behavior
+# * Note that these format strings are different from the ones to display dates
+TIME_INPUT_FORMATS = [
+    '%H:%M:%S',     # '14:30:59'
+    '%H:%M:%S.%f',  # '14:30:59.000200'
+    '%H:%M',        # '14:30'
+]
+
+# Default formats to be used when parsing dates and times from input boxes,
+# in order
+# See all available format string here:
+# https://docs.python.org/library/datetime.html#strftime-behavior
+# * Note that these format strings are different from the ones to display dates
+DATETIME_INPUT_FORMATS = [
+    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
+    '%Y-%m-%d %H:%M:%S.%f',  # '2006-10-25 14:30:59.000200'
+    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
+    '%Y-%m-%d',              # '2006-10-25'
+    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
+    '%m/%d/%Y %H:%M:%S.%f',  # '10/25/2006 14:30:59.000200'
+    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
+    '%m/%d/%Y',              # '10/25/2006'
+    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
+    '%m/%d/%y %H:%M:%S.%f',  # '10/25/06 14:30:59.000200'
+    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
+    '%m/%d/%y',              # '10/25/06'
+]
+
+# First day of week, to be used on calendars
+# 0 means Sunday, 1 means Monday...
+FIRST_DAY_OF_WEEK = 0
+
+# Decimal separator symbol
+DECIMAL_SEPARATOR = '.'
+
+# Boolean that sets whether to add thousand separator when formatting numbers
+USE_THOUSAND_SEPARATOR = False
+
+# Number of digits that will be together, when splitting them by
+# THOUSAND_SEPARATOR. 0 means no grouping, 3 means splitting by thousands...
+NUMBER_GROUPING = 0
+
+# Thousand separator symbol
+THOUSAND_SEPARATOR = ','
+
+# The tablespaces to use for each model when not specified otherwise.
+DEFAULT_TABLESPACE = ''
+DEFAULT_INDEX_TABLESPACE = ''
+
+# Default X-Frame-Options header value
+X_FRAME_OPTIONS = 'DENY'
+
+USE_X_FORWARDED_HOST = False
+USE_X_FORWARDED_PORT = False
+
+# The Python dotted path to the WSGI application that Django's internal server
+# (runserver) will use. If `None`, the return value of
+# 'django.core.wsgi.get_wsgi_application' is used, thus preserving the same
+# behavior as previous versions of Django. Otherwise this should point to an
+# actual WSGI application object.
+WSGI_APPLICATION = None
+
+# If your Django app is behind a proxy that sets a header to specify secure
+# connections, AND that proxy ensures that user-submitted headers with the
+# same name are ignored (so that people can't spoof it), set this value to
+# a tuple of (header_name, header_value). For any requests that come in with
+# that header/value, request.is_secure() will return True.
+# WARNING! Only set this if you fully understand what you're doing. Otherwise,
+# you may be opening yourself up to a security risk.
+SECURE_PROXY_SSL_HEADER = None
+
+##############
+# MIDDLEWARE #
+##############
+
+# List of middleware to use. Order is important; in the request phase, these
+# middleware will be applied in the order given, and in the response
+# phase the middleware will be applied in reverse order.
+MIDDLEWARE = []
+
+############
+# SESSIONS #
+############
+
+# Cache to store session data if using the cache session backend.
+SESSION_CACHE_ALIAS = 'default'
+# Cookie name. This can be whatever you want.
+SESSION_COOKIE_NAME = 'sessionid'
+# Age of cookie, in seconds (default: 2 weeks).
+SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
+# A string like "example.com", or None for standard domain cookie.
+SESSION_COOKIE_DOMAIN = None
+# Whether the session cookie should be secure (https:// only).
+SESSION_COOKIE_SECURE = False
+# The path of the session cookie.
+SESSION_COOKIE_PATH = '/'
+# Whether to use the HttpOnly flag.
+SESSION_COOKIE_HTTPONLY = True
+# Whether to set the flag restricting cookie leaks on cross-site requests.
+# This can be 'Lax', 'Strict', or None to disable the flag.
+SESSION_COOKIE_SAMESITE = 'Lax'
+# Whether to save the session data on every request.
+SESSION_SAVE_EVERY_REQUEST = False
+# Whether a user's session cookie expires when the Web browser is closed.
+SESSION_EXPIRE_AT_BROWSER_CLOSE = False
+# The module to store session data
+SESSION_ENGINE = 'django.contrib.sessions.backends.db'
+# Directory to store session files if using the file session module. If None,
+# the backend will use a sensible default.
+SESSION_FILE_PATH = None
+# class to serialize session data
+SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
+
+#########
+# CACHE #
+#########
+
+# The cache backends to use.
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
+    }
+}
+CACHE_MIDDLEWARE_KEY_PREFIX = ''
+CACHE_MIDDLEWARE_SECONDS = 600
+CACHE_MIDDLEWARE_ALIAS = 'default'
+
+##################
+# AUTHENTICATION #
+##################
+
+AUTH_USER_MODEL = 'auth.User'
+
+AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend']
+
+LOGIN_URL = '/accounts/login/'
+
+LOGIN_REDIRECT_URL = '/accounts/profile/'
+
+LOGOUT_REDIRECT_URL = None
+
+# The number of days a password reset link is valid for
+PASSWORD_RESET_TIMEOUT_DAYS = 3
+
+# the first hasher in this list is the preferred algorithm.  any
+# password using different algorithms will be converted automatically
+# upon login
+PASSWORD_HASHERS = [
+    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
+    'django.contrib.auth.hashers.Argon2PasswordHasher',
+    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
+]
+
+AUTH_PASSWORD_VALIDATORS = []
+
+###########
+# SIGNING #
+###########
+
+SIGNING_BACKEND = 'django.core.signing.TimestampSigner'
+
+########
+# CSRF #
+########
+
+# Dotted path to callable to be used as view when a request is
+# rejected by the CSRF middleware.
+CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure'
+
+# Settings for CSRF cookie.
+CSRF_COOKIE_NAME = 'csrftoken'
+CSRF_COOKIE_AGE = 60 * 60 * 24 * 7 * 52
+CSRF_COOKIE_DOMAIN = None
+CSRF_COOKIE_PATH = '/'
+CSRF_COOKIE_SECURE = False
+CSRF_COOKIE_HTTPONLY = False
+CSRF_COOKIE_SAMESITE = 'Lax'
+CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
+CSRF_TRUSTED_ORIGINS = []
+CSRF_USE_SESSIONS = False
+
+############
+# MESSAGES #
+############
+
+# Class to use as messages backend
+MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'
+
+# Default values of MESSAGE_LEVEL and MESSAGE_TAGS are defined within
+# django.contrib.messages to avoid imports in this settings file.
+
+###########
+# LOGGING #
+###########
+
+# The callable to use to configure logging
+LOGGING_CONFIG = 'logging.config.dictConfig'
+
+# Custom logging configuration.
+LOGGING = {}
+
+# Default exception reporter filter class used in case none has been
+# specifically assigned to the HttpRequest instance.
+DEFAULT_EXCEPTION_REPORTER_FILTER = 'django.views.debug.SafeExceptionReporterFilter'
+
+###########
+# TESTING #
+###########
+
+# The name of the class to use to run the test suite
+TEST_RUNNER = 'django.test.runner.DiscoverRunner'
+
+# Apps that don't need to be serialized at test database creation time
+# (only apps with migrations are to start with)
+TEST_NON_SERIALIZED_APPS = []
+
+############
+# FIXTURES #
+############
+
+# The list of directories to search for fixtures
+FIXTURE_DIRS = []
+
+###############
+# STATICFILES #
+###############
+
+# A list of locations of additional static files
+STATICFILES_DIRS = []
+
+# The default file storage backend used during the build process
+STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
+
+# List of finder classes that know how to find static files in
+# various locations.
+STATICFILES_FINDERS = [
+    'django.contrib.staticfiles.finders.FileSystemFinder',
+    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+    # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
+]
+
+##############
+# MIGRATIONS #
+##############
+
+# Migration module overrides for apps, by app label.
+MIGRATION_MODULES = {}
+
+#################
+# SYSTEM CHECKS #
+#################
+
+# List of all issues generated by system checks that should be silenced. Light
+# issues like warnings, infos or debugs will not generate a message. Silencing
+# serious issues like errors and criticals does not result in hiding the
+# message, but Django will not stop you from e.g. running server.
+SILENCED_SYSTEM_CHECKS = []
+
+#######################
+# SECURITY MIDDLEWARE #
+#######################
+SECURE_BROWSER_XSS_FILTER = False
+SECURE_CONTENT_TYPE_NOSNIFF = True
+SECURE_HSTS_INCLUDE_SUBDOMAINS = False
+SECURE_HSTS_PRELOAD = False
+SECURE_HSTS_SECONDS = 0
+SECURE_REDIRECT_EXEMPT = []
+SECURE_REFERRER_POLICY = None
+SECURE_SSL_HOST = None
+SECURE_SSL_REDIRECT = False

+ 581 - 0
venv/Lib/site-packages/django/conf/locale/__init__.py

@@ -0,0 +1,581 @@
+"""
+LANG_INFO is a dictionary structure to provide meta information about languages.
+
+About name_local: capitalize it as if your language name was appearing
+inside a sentence in your language.
+The 'fallback' key can be used to specify a special fallback logic which doesn't
+follow the traditional 'fr-ca' -> 'fr' fallback logic.
+"""
+
+LANG_INFO = {
+    'af': {
+        'bidi': False,
+        'code': 'af',
+        'name': 'Afrikaans',
+        'name_local': 'Afrikaans',
+    },
+    'ar': {
+        'bidi': True,
+        'code': 'ar',
+        'name': 'Arabic',
+        'name_local': 'العربيّة',
+    },
+    'ast': {
+        'bidi': False,
+        'code': 'ast',
+        'name': 'Asturian',
+        'name_local': 'asturianu',
+    },
+    'az': {
+        'bidi': True,
+        'code': 'az',
+        'name': 'Azerbaijani',
+        'name_local': 'Azərbaycanca',
+    },
+    'be': {
+        'bidi': False,
+        'code': 'be',
+        'name': 'Belarusian',
+        'name_local': 'беларуская',
+    },
+    'bg': {
+        'bidi': False,
+        'code': 'bg',
+        'name': 'Bulgarian',
+        'name_local': 'български',
+    },
+    'bn': {
+        'bidi': False,
+        'code': 'bn',
+        'name': 'Bengali',
+        'name_local': 'বাংলা',
+    },
+    'br': {
+        'bidi': False,
+        'code': 'br',
+        'name': 'Breton',
+        'name_local': 'brezhoneg',
+    },
+    'bs': {
+        'bidi': False,
+        'code': 'bs',
+        'name': 'Bosnian',
+        'name_local': 'bosanski',
+    },
+    'ca': {
+        'bidi': False,
+        'code': 'ca',
+        'name': 'Catalan',
+        'name_local': 'català',
+    },
+    'cs': {
+        'bidi': False,
+        'code': 'cs',
+        'name': 'Czech',
+        'name_local': 'česky',
+    },
+    'cy': {
+        'bidi': False,
+        'code': 'cy',
+        'name': 'Welsh',
+        'name_local': 'Cymraeg',
+    },
+    'da': {
+        'bidi': False,
+        'code': 'da',
+        'name': 'Danish',
+        'name_local': 'dansk',
+    },
+    'de': {
+        'bidi': False,
+        'code': 'de',
+        'name': 'German',
+        'name_local': 'Deutsch',
+    },
+    'dsb': {
+        'bidi': False,
+        'code': 'dsb',
+        'name': 'Lower Sorbian',
+        'name_local': 'dolnoserbski',
+    },
+    'el': {
+        'bidi': False,
+        'code': 'el',
+        'name': 'Greek',
+        'name_local': 'Ελληνικά',
+    },
+    'en': {
+        'bidi': False,
+        'code': 'en',
+        'name': 'English',
+        'name_local': 'English',
+    },
+    'en-au': {
+        'bidi': False,
+        'code': 'en-au',
+        'name': 'Australian English',
+        'name_local': 'Australian English',
+    },
+    'en-gb': {
+        'bidi': False,
+        'code': 'en-gb',
+        'name': 'British English',
+        'name_local': 'British English',
+    },
+    'eo': {
+        'bidi': False,
+        'code': 'eo',
+        'name': 'Esperanto',
+        'name_local': 'Esperanto',
+    },
+    'es': {
+        'bidi': False,
+        'code': 'es',
+        'name': 'Spanish',
+        'name_local': 'español',
+    },
+    'es-ar': {
+        'bidi': False,
+        'code': 'es-ar',
+        'name': 'Argentinian Spanish',
+        'name_local': 'español de Argentina',
+    },
+    'es-co': {
+        'bidi': False,
+        'code': 'es-co',
+        'name': 'Colombian Spanish',
+        'name_local': 'español de Colombia',
+    },
+    'es-mx': {
+        'bidi': False,
+        'code': 'es-mx',
+        'name': 'Mexican Spanish',
+        'name_local': 'español de Mexico',
+    },
+    'es-ni': {
+        'bidi': False,
+        'code': 'es-ni',
+        'name': 'Nicaraguan Spanish',
+        'name_local': 'español de Nicaragua',
+    },
+    'es-ve': {
+        'bidi': False,
+        'code': 'es-ve',
+        'name': 'Venezuelan Spanish',
+        'name_local': 'español de Venezuela',
+    },
+    'et': {
+        'bidi': False,
+        'code': 'et',
+        'name': 'Estonian',
+        'name_local': 'eesti',
+    },
+    'eu': {
+        'bidi': False,
+        'code': 'eu',
+        'name': 'Basque',
+        'name_local': 'Basque',
+    },
+    'fa': {
+        'bidi': True,
+        'code': 'fa',
+        'name': 'Persian',
+        'name_local': 'فارسی',
+    },
+    'fi': {
+        'bidi': False,
+        'code': 'fi',
+        'name': 'Finnish',
+        'name_local': 'suomi',
+    },
+    'fr': {
+        'bidi': False,
+        'code': 'fr',
+        'name': 'French',
+        'name_local': 'français',
+    },
+    'fy': {
+        'bidi': False,
+        'code': 'fy',
+        'name': 'Frisian',
+        'name_local': 'frysk',
+    },
+    'ga': {
+        'bidi': False,
+        'code': 'ga',
+        'name': 'Irish',
+        'name_local': 'Gaeilge',
+    },
+    'gd': {
+        'bidi': False,
+        'code': 'gd',
+        'name': 'Scottish Gaelic',
+        'name_local': 'Gàidhlig',
+    },
+    'gl': {
+        'bidi': False,
+        'code': 'gl',
+        'name': 'Galician',
+        'name_local': 'galego',
+    },
+    'he': {
+        'bidi': True,
+        'code': 'he',
+        'name': 'Hebrew',
+        'name_local': 'עברית',
+    },
+    'hi': {
+        'bidi': False,
+        'code': 'hi',
+        'name': 'Hindi',
+        'name_local': 'हिंदी',
+    },
+    'hr': {
+        'bidi': False,
+        'code': 'hr',
+        'name': 'Croatian',
+        'name_local': 'Hrvatski',
+    },
+    'hsb': {
+        'bidi': False,
+        'code': 'hsb',
+        'name': 'Upper Sorbian',
+        'name_local': 'hornjoserbsce',
+    },
+    'hu': {
+        'bidi': False,
+        'code': 'hu',
+        'name': 'Hungarian',
+        'name_local': 'Magyar',
+    },
+    'hy': {
+        'bidi': False,
+        'code': 'hy',
+        'name': 'Armenian',
+        'name_local': 'հայերեն',
+    },
+    'ia': {
+        'bidi': False,
+        'code': 'ia',
+        'name': 'Interlingua',
+        'name_local': 'Interlingua',
+    },
+    'io': {
+        'bidi': False,
+        'code': 'io',
+        'name': 'Ido',
+        'name_local': 'ido',
+    },
+    'id': {
+        'bidi': False,
+        'code': 'id',
+        'name': 'Indonesian',
+        'name_local': 'Bahasa Indonesia',
+    },
+    'is': {
+        'bidi': False,
+        'code': 'is',
+        'name': 'Icelandic',
+        'name_local': 'Íslenska',
+    },
+    'it': {
+        'bidi': False,
+        'code': 'it',
+        'name': 'Italian',
+        'name_local': 'italiano',
+    },
+    'ja': {
+        'bidi': False,
+        'code': 'ja',
+        'name': 'Japanese',
+        'name_local': '日本語',
+    },
+    'ka': {
+        'bidi': False,
+        'code': 'ka',
+        'name': 'Georgian',
+        'name_local': 'ქართული',
+    },
+    'kab': {
+        'bidi': False,
+        'code': 'kab',
+        'name': 'Kabyle',
+        'name_local': 'taqbaylit',
+    },
+    'kk': {
+        'bidi': False,
+        'code': 'kk',
+        'name': 'Kazakh',
+        'name_local': 'Қазақ',
+    },
+    'km': {
+        'bidi': False,
+        'code': 'km',
+        'name': 'Khmer',
+        'name_local': 'Khmer',
+    },
+    'kn': {
+        'bidi': False,
+        'code': 'kn',
+        'name': 'Kannada',
+        'name_local': 'Kannada',
+    },
+    'ko': {
+        'bidi': False,
+        'code': 'ko',
+        'name': 'Korean',
+        'name_local': '한국어',
+    },
+    'lb': {
+        'bidi': False,
+        'code': 'lb',
+        'name': 'Luxembourgish',
+        'name_local': 'Lëtzebuergesch',
+    },
+    'lt': {
+        'bidi': False,
+        'code': 'lt',
+        'name': 'Lithuanian',
+        'name_local': 'Lietuviškai',
+    },
+    'lv': {
+        'bidi': False,
+        'code': 'lv',
+        'name': 'Latvian',
+        'name_local': 'latviešu',
+    },
+    'mk': {
+        'bidi': False,
+        'code': 'mk',
+        'name': 'Macedonian',
+        'name_local': 'Македонски',
+    },
+    'ml': {
+        'bidi': False,
+        'code': 'ml',
+        'name': 'Malayalam',
+        'name_local': 'Malayalam',
+    },
+    'mn': {
+        'bidi': False,
+        'code': 'mn',
+        'name': 'Mongolian',
+        'name_local': 'Mongolian',
+    },
+    'mr': {
+        'bidi': False,
+        'code': 'mr',
+        'name': 'Marathi',
+        'name_local': 'मराठी',
+    },
+    'my': {
+        'bidi': False,
+        'code': 'my',
+        'name': 'Burmese',
+        'name_local': 'မြန်မာဘာသာ',
+    },
+    'nb': {
+        'bidi': False,
+        'code': 'nb',
+        'name': 'Norwegian Bokmal',
+        'name_local': 'norsk (bokmål)',
+    },
+    'ne': {
+        'bidi': False,
+        'code': 'ne',
+        'name': 'Nepali',
+        'name_local': 'नेपाली',
+    },
+    'nl': {
+        'bidi': False,
+        'code': 'nl',
+        'name': 'Dutch',
+        'name_local': 'Nederlands',
+    },
+    'nn': {
+        'bidi': False,
+        'code': 'nn',
+        'name': 'Norwegian Nynorsk',
+        'name_local': 'norsk (nynorsk)',
+    },
+    'no': {
+        'bidi': False,
+        'code': 'no',
+        'name': 'Norwegian',
+        'name_local': 'norsk',
+    },
+    'os': {
+        'bidi': False,
+        'code': 'os',
+        'name': 'Ossetic',
+        'name_local': 'Ирон',
+    },
+    'pa': {
+        'bidi': False,
+        'code': 'pa',
+        'name': 'Punjabi',
+        'name_local': 'Punjabi',
+    },
+    'pl': {
+        'bidi': False,
+        'code': 'pl',
+        'name': 'Polish',
+        'name_local': 'polski',
+    },
+    'pt': {
+        'bidi': False,
+        'code': 'pt',
+        'name': 'Portuguese',
+        'name_local': 'Português',
+    },
+    'pt-br': {
+        'bidi': False,
+        'code': 'pt-br',
+        'name': 'Brazilian Portuguese',
+        'name_local': 'Português Brasileiro',
+    },
+    'ro': {
+        'bidi': False,
+        'code': 'ro',
+        'name': 'Romanian',
+        'name_local': 'Română',
+    },
+    'ru': {
+        'bidi': False,
+        'code': 'ru',
+        'name': 'Russian',
+        'name_local': 'Русский',
+    },
+    'sk': {
+        'bidi': False,
+        'code': 'sk',
+        'name': 'Slovak',
+        'name_local': 'Slovensky',
+    },
+    'sl': {
+        'bidi': False,
+        'code': 'sl',
+        'name': 'Slovenian',
+        'name_local': 'Slovenščina',
+    },
+    'sq': {
+        'bidi': False,
+        'code': 'sq',
+        'name': 'Albanian',
+        'name_local': 'shqip',
+    },
+    'sr': {
+        'bidi': False,
+        'code': 'sr',
+        'name': 'Serbian',
+        'name_local': 'српски',
+    },
+    'sr-latn': {
+        'bidi': False,
+        'code': 'sr-latn',
+        'name': 'Serbian Latin',
+        'name_local': 'srpski (latinica)',
+    },
+    'sv': {
+        'bidi': False,
+        'code': 'sv',
+        'name': 'Swedish',
+        'name_local': 'svenska',
+    },
+    'sw': {
+        'bidi': False,
+        'code': 'sw',
+        'name': 'Swahili',
+        'name_local': 'Kiswahili',
+    },
+    'ta': {
+        'bidi': False,
+        'code': 'ta',
+        'name': 'Tamil',
+        'name_local': 'தமிழ்',
+    },
+    'te': {
+        'bidi': False,
+        'code': 'te',
+        'name': 'Telugu',
+        'name_local': 'తెలుగు',
+    },
+    'th': {
+        'bidi': False,
+        'code': 'th',
+        'name': 'Thai',
+        'name_local': 'ภาษาไทย',
+    },
+    'tr': {
+        'bidi': False,
+        'code': 'tr',
+        'name': 'Turkish',
+        'name_local': 'Türkçe',
+    },
+    'tt': {
+        'bidi': False,
+        'code': 'tt',
+        'name': 'Tatar',
+        'name_local': 'Татарча',
+    },
+    'udm': {
+        'bidi': False,
+        'code': 'udm',
+        'name': 'Udmurt',
+        'name_local': 'Удмурт',
+    },
+    'uk': {
+        'bidi': False,
+        'code': 'uk',
+        'name': 'Ukrainian',
+        'name_local': 'Українська',
+    },
+    'ur': {
+        'bidi': True,
+        'code': 'ur',
+        'name': 'Urdu',
+        'name_local': 'اردو',
+    },
+    'uz': {
+        'bidi': False,
+        'code': 'uz',
+        'name': 'Uzbek',
+        'name_local': 'oʻzbek tili',
+    },
+    'vi': {
+        'bidi': False,
+        'code': 'vi',
+        'name': 'Vietnamese',
+        'name_local': 'Tiếng Việt',
+    },
+    'zh-cn': {
+        'fallback': ['zh-hans'],
+    },
+    'zh-hans': {
+        'bidi': False,
+        'code': 'zh-hans',
+        'name': 'Simplified Chinese',
+        'name_local': '简体中文',
+    },
+    'zh-hant': {
+        'bidi': False,
+        'code': 'zh-hant',
+        'name': 'Traditional Chinese',
+        'name_local': '繁體中文',
+    },
+    'zh-hk': {
+        'fallback': ['zh-hant'],
+    },
+    'zh-mo': {
+        'fallback': ['zh-hant'],
+    },
+    'zh-my': {
+        'fallback': ['zh-hans'],
+    },
+    'zh-sg': {
+        'fallback': ['zh-hans'],
+    },
+    'zh-tw': {
+        'fallback': ['zh-hant'],
+    },
+}

BIN
venv/Lib/site-packages/django/conf/locale/af/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1249 - 0
venv/Lib/site-packages/django/conf/locale/af/LC_MESSAGES/django.po


BIN
venv/Lib/site-packages/django/conf/locale/ar/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1322 - 0
venv/Lib/site-packages/django/conf/locale/ar/LC_MESSAGES/django.po


+ 0 - 0
venv/Lib/site-packages/django/conf/locale/ar/__init__.py


+ 21 - 0
venv/Lib/site-packages/django/conf/locale/ar/formats.py

@@ -0,0 +1,21 @@
+# This file is distributed under the same license as the Django package.
+#
+# The *_FORMAT strings use the Django date format syntax,
+# see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+DATE_FORMAT = 'j F، Y'
+TIME_FORMAT = 'g:i A'
+# DATETIME_FORMAT =
+YEAR_MONTH_FORMAT = 'F Y'
+MONTH_DAY_FORMAT = 'j F'
+SHORT_DATE_FORMAT = 'd‏/m‏/Y'
+# SHORT_DATETIME_FORMAT =
+# FIRST_DAY_OF_WEEK =
+
+# The *_INPUT_FORMATS strings use the Python strftime format syntax,
+# see https://docs.python.org/library/datetime.html#strftime-strptime-behavior
+# DATE_INPUT_FORMATS =
+# TIME_INPUT_FORMATS =
+# DATETIME_INPUT_FORMATS =
+DECIMAL_SEPARATOR = ','
+THOUSAND_SEPARATOR = '.'
+# NUMBER_GROUPING =

BIN
venv/Lib/site-packages/django/conf/locale/ast/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1237 - 0
venv/Lib/site-packages/django/conf/locale/ast/LC_MESSAGES/django.po


BIN
venv/Lib/site-packages/django/conf/locale/az/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1278 - 0
venv/Lib/site-packages/django/conf/locale/az/LC_MESSAGES/django.po


+ 0 - 0
venv/Lib/site-packages/django/conf/locale/az/__init__.py


+ 32 - 0
venv/Lib/site-packages/django/conf/locale/az/formats.py

@@ -0,0 +1,32 @@
+# This file is distributed under the same license as the Django package.
+#
+# The *_FORMAT strings use the Django date format syntax,
+# see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
+DATE_FORMAT = 'j E Y'
+TIME_FORMAT = 'G:i'
+DATETIME_FORMAT = 'j E Y, G:i'
+YEAR_MONTH_FORMAT = 'F Y'
+MONTH_DAY_FORMAT = 'j F'
+SHORT_DATE_FORMAT = 'd.m.Y'
+SHORT_DATETIME_FORMAT = 'd.m.Y H:i'
+FIRST_DAY_OF_WEEK = 1  # Monday
+
+# The *_INPUT_FORMATS strings use the Python strftime format syntax,
+# see https://docs.python.org/library/datetime.html#strftime-strptime-behavior
+DATE_INPUT_FORMATS = [
+    '%d.%m.%Y',  # '25.10.2006'
+    '%d.%m.%y',  # '25.10.06'
+]
+DATETIME_INPUT_FORMATS = [
+    '%d.%m.%Y %H:%M:%S',     # '25.10.2006 14:30:59'
+    '%d.%m.%Y %H:%M:%S.%f',  # '25.10.2006 14:30:59.000200'
+    '%d.%m.%Y %H:%M',        # '25.10.2006 14:30'
+    '%d.%m.%Y',              # '25.10.2006'
+    '%d.%m.%y %H:%M:%S',     # '25.10.06 14:30:59'
+    '%d.%m.%y %H:%M:%S.%f',  # '25.10.06 14:30:59.000200'
+    '%d.%m.%y %H:%M',        # '25.10.06 14:30'
+    '%d.%m.%y',              # '25.10.06'
+]
+DECIMAL_SEPARATOR = ','
+THOUSAND_SEPARATOR = '\xa0'  # non-breaking space
+NUMBER_GROUPING = 3

BIN
venv/Lib/site-packages/django/conf/locale/be/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1329 - 0
venv/Lib/site-packages/django/conf/locale/be/LC_MESSAGES/django.po


BIN
venv/Lib/site-packages/django/conf/locale/bg/LC_MESSAGES/django.mo


Datei-Diff unterdrückt, da er zu groß ist
+ 1252 - 0
venv/Lib/site-packages/django/conf/locale/bg/LC_MESSAGES/django.po


+ 0 - 0
venv/Lib/site-packages/django/conf/locale/bg/__init__.py


+ 0 - 0
venv/Lib/site-packages/django/conf/locale/bg/formats.py


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.