├── .gitignore ├── LICENSE ├── README.md ├── apps └── unstuck │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ └── __init__.py │ ├── models.py │ ├── static │ └── unstuck │ │ └── unstuck.css │ ├── templates │ └── unstuck │ │ └── main.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── config ├── __init__.py ├── asgi.py ├── settings │ ├── __init__.py │ ├── base.py │ ├── development.py │ ├── production.py │ └── test.py ├── urls.py └── wsgi.py ├── docs ├── app-management.md ├── background-tasks.md ├── caching.md ├── files.md ├── flatpages.md ├── i18n.md ├── images.md ├── middleware.md ├── registration.md ├── secure-access.md ├── settings.md ├── templates.md ├── username.md └── where-does-the-code-go.md ├── manage.py ├── poetry.lock ├── pyproject.toml ├── static └── foundation │ ├── foundation-float.css │ ├── foundation-float.css.map │ ├── foundation-float.min.css │ ├── foundation-float.min.css.map │ ├── foundation-prototype.css │ ├── foundation-prototype.css.map │ ├── foundation-prototype.min.css │ ├── foundation-prototype.min.css.map │ ├── foundation-rtl.css │ ├── foundation-rtl.css.map │ ├── foundation-rtl.min.css │ ├── foundation-rtl.min.css.map │ ├── foundation.cjs.js │ ├── foundation.cjs.js.map │ ├── foundation.css │ ├── foundation.css.map │ ├── foundation.d.ts │ ├── foundation.es6.js │ ├── foundation.es6.js.map │ ├── foundation.esm.js │ ├── foundation.esm.js.map │ ├── foundation.js │ ├── foundation.js.map │ ├── foundation.min.css │ ├── foundation.min.css.map │ ├── foundation.min.js │ ├── foundation.min.js.map │ └── plugins │ ├── foundation.abide.js │ ├── foundation.abide.js.map │ ├── foundation.abide.min.js │ ├── foundation.abide.min.js.map │ ├── foundation.accordion.js │ ├── foundation.accordion.js.map │ ├── foundation.accordion.min.js │ ├── foundation.accordion.min.js.map │ ├── foundation.accordionMenu.js │ ├── foundation.accordionMenu.js.map │ ├── foundation.accordionMenu.min.js │ ├── foundation.accordionMenu.min.js.map │ ├── foundation.core.js │ ├── foundation.core.js.map │ ├── foundation.core.min.js │ ├── foundation.core.min.js.map │ ├── foundation.drilldown.js │ ├── foundation.drilldown.js.map │ ├── foundation.drilldown.min.js │ ├── foundation.drilldown.min.js.map │ ├── foundation.dropdown.js │ ├── foundation.dropdown.js.map │ ├── foundation.dropdown.min.js │ ├── foundation.dropdown.min.js.map │ ├── foundation.dropdownMenu.js │ ├── foundation.dropdownMenu.js.map │ ├── foundation.dropdownMenu.min.js │ ├── foundation.dropdownMenu.min.js.map │ ├── foundation.equalizer.js │ ├── foundation.equalizer.js.map │ ├── foundation.equalizer.min.js │ ├── foundation.equalizer.min.js.map │ ├── foundation.interchange.js │ ├── foundation.interchange.js.map │ ├── foundation.interchange.min.js │ ├── foundation.interchange.min.js.map │ ├── foundation.magellan.js │ ├── foundation.magellan.js.map │ ├── foundation.magellan.min.js │ ├── foundation.magellan.min.js.map │ ├── foundation.offcanvas.js │ ├── foundation.offcanvas.js.map │ ├── foundation.offcanvas.min.js │ ├── foundation.offcanvas.min.js.map │ ├── foundation.orbit.js │ ├── foundation.orbit.js.map │ ├── foundation.orbit.min.js │ ├── foundation.orbit.min.js.map │ ├── foundation.responsiveAccordionTabs.js │ ├── foundation.responsiveAccordionTabs.js.map │ ├── foundation.responsiveAccordionTabs.min.js │ ├── foundation.responsiveAccordionTabs.min.js.map │ ├── foundation.responsiveMenu.js │ ├── foundation.responsiveMenu.js.map │ ├── foundation.responsiveMenu.min.js │ ├── foundation.responsiveMenu.min.js.map │ ├── foundation.responsiveToggle.js │ ├── foundation.responsiveToggle.js.map │ ├── foundation.responsiveToggle.min.js │ ├── foundation.responsiveToggle.min.js.map │ ├── foundation.reveal.js │ ├── foundation.reveal.js.map │ ├── foundation.reveal.min.js │ ├── foundation.reveal.min.js.map │ ├── foundation.slider.js │ ├── foundation.slider.js.map │ ├── foundation.slider.min.js │ ├── foundation.slider.min.js.map │ ├── foundation.smoothScroll.js │ ├── foundation.smoothScroll.js.map │ ├── foundation.smoothScroll.min.js │ ├── foundation.smoothScroll.min.js.map │ ├── foundation.sticky.js │ ├── foundation.sticky.js.map │ ├── foundation.sticky.min.js │ ├── foundation.sticky.min.js.map │ ├── foundation.tabs.js │ ├── foundation.tabs.js.map │ ├── foundation.tabs.min.js │ ├── foundation.tabs.min.js.map │ ├── foundation.toggler.js │ ├── foundation.toggler.js.map │ ├── foundation.toggler.min.js │ ├── foundation.toggler.min.js.map │ ├── foundation.tooltip.js │ ├── foundation.tooltip.js.map │ ├── foundation.tooltip.min.js │ ├── foundation.tooltip.min.js.map │ ├── foundation.util.box.js │ ├── foundation.util.box.js.map │ ├── foundation.util.box.min.js │ ├── foundation.util.box.min.js.map │ ├── foundation.util.imageLoader.js │ ├── foundation.util.imageLoader.js.map │ ├── foundation.util.imageLoader.min.js │ ├── foundation.util.imageLoader.min.js.map │ ├── foundation.util.keyboard.js │ ├── foundation.util.keyboard.js.map │ ├── foundation.util.keyboard.min.js │ ├── foundation.util.keyboard.min.js.map │ ├── foundation.util.mediaQuery.js │ ├── foundation.util.mediaQuery.js.map │ ├── foundation.util.mediaQuery.min.js │ ├── foundation.util.mediaQuery.min.js.map │ ├── foundation.util.motion.js │ ├── foundation.util.motion.js.map │ ├── foundation.util.motion.min.js │ ├── foundation.util.motion.min.js.map │ ├── foundation.util.nest.js │ ├── foundation.util.nest.js.map │ ├── foundation.util.nest.min.js │ ├── foundation.util.nest.min.js.map │ ├── foundation.util.timer.js │ ├── foundation.util.timer.js.map │ ├── foundation.util.timer.min.js │ ├── foundation.util.timer.min.js.map │ ├── foundation.util.touch.js │ ├── foundation.util.touch.js.map │ ├── foundation.util.touch.min.js │ ├── foundation.util.touch.min.js.map │ ├── foundation.util.triggers.js │ ├── foundation.util.triggers.js.map │ ├── foundation.util.triggers.min.js │ └── foundation.util.triggers.min.js.map └── templates └── base.html /.gitignore: -------------------------------------------------------------------------------- 1 | /config/settings/local.py 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Johannes Spielmann 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-unstuck 2 | Suggestions for overcoming common challenges in Django projects 3 | 4 | There are some challenges that come up in every Django project. Some of them right at the start: How do I organize my 5 | apps? Where do I put the base template, and all the other templates? Should I do internationalization right away? 6 | Other problems only crop up a little later: how do I manage production settings? How do I make sure permissions are 7 | checked correctly? How do I make menus appear correctly? 8 | Some may appear at any point in time: how do I add content pages? What code goes into models/controllers/views? 9 | 10 | In this repository, we try to find ways to get unstuck from these challenges. Some people may call the things we do here 11 | “best practices” or “patterns” or “recipes” or “ideas” or “opinions”. These are just things we’ve found to work in 12 | these situations many times. Some of our solutions are more directly applicable, others are more guideline-style. 13 | 14 | You can also join us on [Discord](https://discord.gg/bUsu9B6Ek6) or on [Telegram](https://t.me/djangoRhein). 15 | 16 | Here are the things we have ideas for: 17 | 18 | [comment]: <> ( * [Splitting settings: local, dev, testing and production](docs/settings.md)) 19 | 20 | * [App management and placement and settings (and urlpatterns)](docs/app-management.md) 21 | * [Username vs email address](docs/username.md) (WIP) 22 | * [Registration in general](docs/registration.md) (WIP) 23 | * [Background tasks and long-running processes and Caching](docs/background-tasks.md) (WIP) 24 | * [Templates: Placement, folders, blocks and inheritance and namespaces](docs/templates.md) 25 | * [Should you do i18n and l10n right away?](docs/i18n.md) 26 | * [When and how to start caching (memcached, redis etc.)](docs/caching.md) (WIP) 27 | * [Where does your code go: models, views or managers or somewhere else?](docs/where-does-the-code-go.md) (WIP) 28 | * [When to use Middlewares and context processors and what are they?](docs/middleware.md) (WIP) 29 | * [How to secure access: security middlewares or login_required (white vs black list)](docs/secure-access.md) (WIP) 30 | * [How to create files and store them in file models](docs/files.md) (WIP) 31 | * [What to do about image scaling and thumbnailing (and hosting)?](docs/images.md) (WIP) 32 | * [How to serve content: coded pages, flatpages or Wagtail?](docs/flatpages.md) (WIP) 33 | 34 | 35 | # The project itself 36 | 37 | This repository also contains a project called "Django Unstuck" that adheres to the guidelines in the documentation. 38 | -------------------------------------------------------------------------------- /apps/unstuck/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shezi/django-unstuck/ea83d2966c3f90d99af7eed5a379fc838175f79e/apps/unstuck/__init__.py -------------------------------------------------------------------------------- /apps/unstuck/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /apps/unstuck/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class UnstuckConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "unstuck" 7 | -------------------------------------------------------------------------------- /apps/unstuck/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shezi/django-unstuck/ea83d2966c3f90d99af7eed5a379fc838175f79e/apps/unstuck/migrations/__init__.py -------------------------------------------------------------------------------- /apps/unstuck/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /apps/unstuck/static/unstuck/unstuck.css: -------------------------------------------------------------------------------- 1 | /* empty for now */ 2 | -------------------------------------------------------------------------------- /apps/unstuck/templates/unstuck/main.html: -------------------------------------------------------------------------------- 1 | {# empty for now #} 2 | -------------------------------------------------------------------------------- /apps/unstuck/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /apps/unstuck/urls.py: -------------------------------------------------------------------------------- 1 | app_name = "unstuck" 2 | 3 | urlpatterns = [] 4 | -------------------------------------------------------------------------------- /apps/unstuck/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shezi/django-unstuck/ea83d2966c3f90d99af7eed5a379fc838175f79e/config/__init__.py -------------------------------------------------------------------------------- /config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for unstuck project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /config/settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shezi/django-unstuck/ea83d2966c3f90d99af7eed5a379fc838175f79e/config/settings/__init__.py -------------------------------------------------------------------------------- /config/settings/base.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for unstuck project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.2.3. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.2/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | 15 | import sys 16 | 17 | 18 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 19 | BASE_DIR = Path(__file__).resolve().parent.parent.parent 20 | 21 | sys.path.append(str(BASE_DIR / "apps")) 22 | 23 | 24 | # Quick-start development settings - unsuitable for production 25 | # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ 26 | 27 | # SECURITY WARNING: keep the secret key used in production secret! 28 | SECRET_KEY = "django-insecure-#q*z-dhdg*w9ctbt@e!v=@6s+#9ogdabnt=us1ygu_s83qnhgq" 29 | 30 | # SECURITY WARNING: don't run with debug turned on in production! 31 | DEBUG = True 32 | 33 | ALLOWED_HOSTS = [] 34 | 35 | 36 | # Application definition 37 | 38 | INSTALLED_APPS = [ 39 | "django.contrib.admin", 40 | "django.contrib.auth", 41 | "django.contrib.contenttypes", 42 | "django.contrib.sessions", 43 | "django.contrib.messages", 44 | "django.contrib.staticfiles", 45 | ] 46 | 47 | MIDDLEWARE = [ 48 | "django.middleware.security.SecurityMiddleware", 49 | "django.contrib.sessions.middleware.SessionMiddleware", 50 | "django.middleware.common.CommonMiddleware", 51 | "django.middleware.csrf.CsrfViewMiddleware", 52 | "django.contrib.auth.middleware.AuthenticationMiddleware", 53 | "django.contrib.messages.middleware.MessageMiddleware", 54 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 55 | ] 56 | 57 | ROOT_URLCONF = "unstuck.urls" 58 | 59 | TEMPLATES = [ 60 | { 61 | "BACKEND": "django.template.backends.django.DjangoTemplates", 62 | "DIRS": [BASE_DIR / "templates"], 63 | "APP_DIRS": True, 64 | "OPTIONS": { 65 | "context_processors": [ 66 | "django.template.context_processors.debug", 67 | "django.template.context_processors.request", 68 | "django.contrib.auth.context_processors.auth", 69 | "django.contrib.messages.context_processors.messages", 70 | ], 71 | }, 72 | }, 73 | ] 74 | 75 | WSGI_APPLICATION = "unstuck.wsgi.application" 76 | 77 | 78 | # Database 79 | # https://docs.djangoproject.com/en/3.2/ref/settings/#databases 80 | 81 | DATABASES = { 82 | "default": { 83 | "ENGINE": "django.db.backends.sqlite3", 84 | "NAME": BASE_DIR / "db.sqlite3", 85 | } 86 | } 87 | 88 | 89 | # Password validation 90 | # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators 91 | 92 | AUTH_PASSWORD_VALIDATORS = [ 93 | { 94 | "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", 95 | }, 96 | { 97 | "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", 98 | }, 99 | { 100 | "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", 101 | }, 102 | { 103 | "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", 104 | }, 105 | ] 106 | 107 | 108 | # Internationalization 109 | # https://docs.djangoproject.com/en/3.2/topics/i18n/ 110 | 111 | LANGUAGE_CODE = "en-us" 112 | 113 | TIME_ZONE = "UTC" 114 | 115 | USE_I18N = True 116 | 117 | USE_L10N = True 118 | 119 | USE_TZ = True 120 | 121 | 122 | # Static files (CSS, JavaScript, Images) 123 | # https://docs.djangoproject.com/en/3.2/howto/static-files/ 124 | 125 | STATIC_URL = "/static/" 126 | 127 | # Default primary key field type 128 | # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field 129 | 130 | DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" 131 | -------------------------------------------------------------------------------- /config/settings/development.py: -------------------------------------------------------------------------------- 1 | # Django-Unstuck development settings 2 | 3 | from .base import * 4 | 5 | 6 | try: 7 | from .local import * 8 | except ImportError: 9 | pass 10 | -------------------------------------------------------------------------------- /config/settings/production.py: -------------------------------------------------------------------------------- 1 | # Django-Unstuck PRODUCTION settings 2 | 3 | from .base import * 4 | 5 | 6 | try: 7 | from .local import * 8 | except ImportError: 9 | pass 10 | -------------------------------------------------------------------------------- /config/settings/test.py: -------------------------------------------------------------------------------- 1 | # Django-Unstuck test settings 2 | 3 | from .base import * 4 | 5 | 6 | try: 7 | from .local import * 8 | except ImportError: 9 | pass 10 | -------------------------------------------------------------------------------- /config/urls.py: -------------------------------------------------------------------------------- 1 | """unstuck URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | urlpatterns = [ 20 | path("admin/", admin.site.urls), 21 | path("", include("unstuck.urls")) 22 | ] 23 | -------------------------------------------------------------------------------- /config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for unstuck project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /docs/app-management.md: -------------------------------------------------------------------------------- 1 | # App management and placement and settings (and urlpatterns) 2 | 3 | When you start a new project, using the standard django template, you're given a project structure that is good for 4 | starter projects. But it has shortcomings, too: there are duplicate names, some of the names are unclear, configuration 5 | and code (and other things) are mixed. 6 | 7 | We will try to separate these parts and make them more identifiable and easier to navigate. 8 | 9 | # The challenge 10 | 11 | Organize your project such that: 12 | 13 | * everything has its place 14 | * what belongs together, stays together 15 | * code/URLs are easily found 16 | * settings are flexible 17 | 18 | 19 | # Solutions 20 | 21 | We're going to change the project structure in three steps: configuration, apps and URLs 22 | 23 | ## Step 1: configuration 24 | 25 | We want to separate the configuration into a directory that contains all of the configuration and is properly named. The 26 | final layout will look like this: 27 | 28 | ``` 29 | project_root/ 30 | config/ 31 | asgi.py 32 | wsgi.py 33 | urls.py 34 | settings/ 35 | base.py 36 | development.py 37 | production.py 38 | test.py 39 | local.py 40 | ``` 41 | 42 | This way, all configuration stays together. Also, this directory contains all configuration which is necessary and 43 | specific to _this project_. 44 | 45 | So, create a config directory. Below that, a settings directory. Put the configuration in config directory. Move your 46 | project settings to `config/settings/base.py`. 47 | 48 | Create files for `development.py`, `production.py` and `test.py` and add this content to each: 49 | 50 | ```python 51 | from .base import * 52 | 53 | # add your configuration here 54 | 55 | try: 56 | from .local import * 57 | except ImportError: 58 | # you can add a message here if you want 59 | pass 60 | ``` 61 | 62 | A small adjustment is needed in `base.py`. We have changed the path of the settings relative to the project root, so we 63 | have to fix that. Adjust your `base.py` like this: 64 | 65 | ```python 66 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 67 | BASE_DIR = Path(__file__).resolve().parent.parent.parent 68 | 69 | ROOT_URLCONF = 'config.urls' 70 | WSGI_APPLICATION = 'config.wsgi.application' 71 | ``` 72 | 73 | Just add one more `.parent` there and adjust the paths. 74 | 75 | Now we need to use these settings in the contexts we want them to. Usually, in `manage.py` we refer to 76 | `config.settings.development`, while in `asgi.py/wsgi.py` we refer to `config.settings.production`. These are sane 77 | defaults for each entry point, but can be overriden by environment variables if necessary. 78 | 79 | What have we achieved? We have one common settings file `base.py` and three environment-specific files. You can now add 80 | the configuration that is specific for a certain environment into the respective file. 81 | Finally, you can create a `local.py` that will override any of these settings. If you add `config/settings/local.py` to 82 | your `.gitignore`, you can safely put _machine-specific_ and sensitive configuration in there, without fear of 83 | accidentally committing it. 84 | 85 | Side-note/Example: One thing I like to add to my development settings is 86 | ```python 87 | AUTH_PASSWORD_VALIDATORS = [] 88 | ``` 89 | This makes it easier in development to have simple passwords. 90 | 91 | ## Step 2: apps 92 | 93 | We're going to put all the apps in a directory. This makes it easier to find them, they will not be mixed in with other 94 | things (like static files, documentation, tools/scripts, etc). 95 | 96 | Our structure will look like this: 97 | ``` 98 | project_root/ 99 | apps/ 100 | your_app/ 101 | ... 102 | config/ 103 | ... 104 | static/ 105 | ... 106 | templates/ 107 | ... 108 | ``` 109 | 110 | As you can see, the project root directory now contains clear folders with specific, different contents. All the apps 111 | stay together, and name clashes are minimized. 112 | 113 | So create the `apps/` directory. To make apps findable without a prefix, we need to add the `apps/` directory to the 114 | python search path. A good place to do this is right at the beginning of our settings. That way, we can make sure that 115 | whenever Django starts, the path is set correctly. 116 | 117 | Add this to `config/settings/base.py`: 118 | 119 | ```python 120 | import sys 121 | sys.path.append(str(BASE_DIR / "apps")) 122 | ``` 123 | 124 | Finally, move all your apps into the `apps/` directory. No further changes are necessary inside the apps. 125 | 126 | You can now name your main app the same as your project. 127 | 128 | 129 | ## Step 3: urlpatterns 130 | 131 | Each app gets urlpatterns and gets added to the project URLs right away. That way, you can make sure you easily add new 132 | URLs to each app, and each app has its own URLs. 133 | 134 | Simply put a file called `urls.py` into each of your apps, with this content: 135 | 136 | ```python 137 | 138 | app_name = "" 139 | 140 | urlpatterns = [] 141 | ``` 142 | 143 | Then, add each app to your `config/urls.py`, like this: 144 | ```python 145 | from django.contrib import admin 146 | from django.urls import path, include 147 | 148 | from demoapi import views 149 | 150 | urlpatterns = [ 151 | path("your_app_path/", include("your_app.urls")), 152 | path('admin/', admin.site.urls), 153 | ] 154 | ``` 155 | 156 | Do this, whenever you start an app, and do it for every app! After some time, this will become automatic for you. This 157 | way, we make sure all URLs are defined in their respective apps, and each app can have URLs without further 158 | configuration. 159 | 160 | ## Step 4: Success! 161 | 162 | Our final structure looks like this: 163 | 164 | ``` 165 | project_root/ 166 | apps/ 167 | your_app/ 168 | ... 169 | config/ 170 | settings/ 171 | base.py 172 | development.py 173 | production.py 174 | test.py 175 | asgi.py 176 | wsgi.py 177 | urls.py 178 | static/ 179 | ... 180 | templates/ 181 | ... 182 | ``` 183 | 184 | We have achieved our goals! 185 | 186 | * everything has its place 187 | * what belongs together, stays together 188 | * code/URLs are easily found 189 | * settings are flexible 190 | 191 | 192 | Hooray! 193 | -------------------------------------------------------------------------------- /docs/background-tasks.md: -------------------------------------------------------------------------------- 1 | # Background tasks and long-running processes and Caching 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/caching.md: -------------------------------------------------------------------------------- 1 | # When and how to start caching (memcached, redis etc.) 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/files.md: -------------------------------------------------------------------------------- 1 | # How to create files and store them in file models 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/flatpages.md: -------------------------------------------------------------------------------- 1 | # How to serve content: coded pages, flatpages or Wagtail? 2 | 3 | Short answer: probably Wagtail. 4 | 5 | # The challenge 6 | 7 | # Solutions 8 | 9 | -------------------------------------------------------------------------------- /docs/i18n.md: -------------------------------------------------------------------------------- 1 | # Should you do i18n and l10n right away? 2 | 3 | Yes! 4 | 5 | 6 | # Why? 7 | 8 | If there is _any_ chance your project might need to go multi-lingual at some point, do your self the favor and start with 9 | doing i18n as soon as you can. The first step is the simplest anyway: just add `trans` tags to your templates and 10 | `gettext` markers to the strings in your code. You don't have to do anything else. If you have i18n disabled, these will 11 | do nothing, you'll see your strings as before. But once you start doing translations, you won't have to go through _every 12 | file_ in your project multiple times (because you missed lots of strings on the first go), which is both boring and 13 | error-prone. 14 | 15 | Just do yourself the favor and start right away. 16 | 17 | 18 | # Projects that will go multi-lingual at some point 19 | 20 | You might think your project doesn't need this. You may be right. But you're probably wrong. Here are some kinds of 21 | projects that will profit from i18n at some point: 22 | 23 | * a project that is open source: Open-Source users are all around the world. You don't even have to do translations 24 | yourself! 25 | * a project that has more than one user in more than one location: One of your users will tell their friends about it 26 | and they'll be non-native language speakers. 27 | * a commercial project: you want money from users? Show them the right language! 28 | 29 | So, sure, if you're writing a website for some newspaper in some small-time town in Kansas, you might get away without 30 | doing i18n. But even then, your site might be so successful that others want to copy it, _and then what?_ 31 | -------------------------------------------------------------------------------- /docs/images.md: -------------------------------------------------------------------------------- 1 | # What to do about image scaling and thumbnailing (and hosting)? 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/middleware.md: -------------------------------------------------------------------------------- 1 | # When to use Middlewares and context processors and what are they? 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/registration.md: -------------------------------------------------------------------------------- 1 | # Registration in general 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/secure-access.md: -------------------------------------------------------------------------------- 1 | # How to secure access: security middlewares or login_required (white vs black list) 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/settings.md: -------------------------------------------------------------------------------- 1 | # Splitting settings: local, dev, testing and production 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/templates.md: -------------------------------------------------------------------------------- 1 | # Templates and Statics: Placement, folders, blocks and inheritance and namespaces 2 | 3 | Once a Django site gets to a certain size, templates abound. Each and every app has them, your project has some of its 4 | own, it will overwrite some of the standard templates, and you'll have snippets for all kinds of things. 5 | 6 | One problem with these templates is that they all live in the same global namespace. When you refer to 7 | `"main_page.html"`, it could be in any of the apps you have or in any of the template directories you configured. If 8 | there is more than one such file, which one you'll get depends on the _order of the template directories_ in your 9 | settings. Such a brittle system! 10 | 11 | Static files are completely identical to template files. So when we talk about templates here, just apply the same 12 | things to static files. 13 | 14 | # The challenge 15 | 16 | All templates live in one big namespace. 17 | Yet there are many places in the filesystem. 18 | 19 | We have to: 20 | 21 | * Decide where a template file goes and what it is called! 22 | * Identify what a template belongs to! 23 | * Make sure namespace clashes are minimal! 24 | 25 | # Solutions 26 | 27 | ## Step 1: Your main template directory 28 | 29 | Your project should have exactly one main template directory. It should be in your main project directory and it should 30 | be called `templates`. This makes your project structure look like this: 31 | 32 | ``` 33 | project_root/ 34 | apps/ 35 | your_app/ 36 | ... 37 | config/ 38 | ... 39 | static/ 40 | ... 41 | templates/ 42 | snippets/ 43 | base.html 44 | ``` 45 | 46 | (Refer to [App Management](app-management.md#structure) for the rest of the project structure.) 47 | 48 | This directory must be put into the configuration: 49 | 50 | ```python 51 | EMPLATES = [ 52 | { 53 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 54 | 'DIRS': [BASE_DIR / "templates"], # <----- 55 | 'APP_DIRS': True, 56 | 'OPTIONS': { 57 | 'context_processors': [ 58 | 'django.template.context_processors.debug', 59 | 'django.template.context_processors.request', 60 | 'django.contrib.auth.context_processors.auth', 61 | 'django.contrib.messages.context_processors.messages', 62 | ], 63 | }, 64 | }, 65 | ] 66 | ``` 67 | 68 | In this directory we will put all templates that belong to _the project_ itself, instead of a single app. These will be 69 | the main base templates, utilities and snippets, and overrides. 70 | 71 | The main base template is called `base.html` and will be the _base_ for most other templates. You might have other base 72 | templates, such as `base_wide.html` or `base_narrow.html`. All error templates go into this directory as well. 73 | Adjacent to these base templates will be some snippets. I like to call their directory `snippets/`, but you might have 74 | an app with that name, so you might have to choose a different name. In there, you put small parts of the project that 75 | you'll want to reuse in different places. Two prime candidates are the sidebar menu (which might be in different base's), 76 | and the pagination snippet. We used to have form rendering snippets in there as well, but there are other solutions for 77 | those today. 78 | 79 | One more thing that needs to go into the main template directory is _overrides_. When you use apps that can be 80 | customized with your own templates, create the necessary files in this main directory. Most sites will use Django's 81 | built-in login views (see also [Registration](registration.md)), so you'll simply put `registration/login.html` and 82 | `registration/logged_out.html` in here for custom login and logged-out views. 83 | 84 | 85 | 86 | ## Step 2: in-app template directories 87 | 88 | As you've seen above, we have configured in-app template directories, as should be the case. Django loads these after 89 | the configured specific directories, so our main directory is safe. 90 | 91 | The in-app folders contain everything for that specific app. Each item in there should be tied either directly to a view 92 | or to some other template. 93 | We must make sure that inside of in-app template directores, everything goes into a sub-folder with the app name to make 94 | sure we do not clash with other apps or our main directory. Each template should be named the same as the view that it 95 | is loaded from, so we can connect the two more easily. And finally, the url-pattern for that view should have the same 96 | name, too. That way you can always find one from the other. 97 | 98 | You should never need to include things from another app. If that is the case, think about whether you should migrate 99 | that specific thing to the main directory. 100 | 101 | 102 | ## Step 3: Success! 103 | 104 | Our final structure looks like this: 105 | 106 | ``` 107 | project_root/ 108 | apps/ 109 | your_app/ 110 | templates/ 111 | your_app/ 112 | item_list.html 113 | ... 114 | static/ 115 | your_app/ 116 | css/ 117 | ... 118 | ... 119 | config/ 120 | ... 121 | static/ 122 | ... 123 | templates/ 124 | snippets/ 125 | base.html 126 | ``` 127 | 128 | With this structure, we achieve our goals: We know where each template file goes and what we should call it. At the same 129 | time, we can easily find what a template file belongs to by looking at its name and placement. We are avoiding namespace 130 | clashes by choosing app-name paths that should be unique in the project. 131 | 132 | Hooray! 133 | 134 | 135 | ## Step X: Snippets 136 | 137 | You must build a collection of snippets! There are just things that come up in every Django project, and the more 138 | snippets you have collected, the better you can react to those eventualities. My collection includes things such as 139 | log-in pages, menu structures, pagination snippets, form-rendering snippets and other things. 140 | 141 | (At some point, we might have some of these snippets in here.) 142 | -------------------------------------------------------------------------------- /docs/username.md: -------------------------------------------------------------------------------- 1 | # Username vs email address 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /docs/where-does-the-code-go.md: -------------------------------------------------------------------------------- 1 | # Where does your code go: models, views or managers or somewhere else? 2 | 3 | # The challenge 4 | 5 | # Solutions 6 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.development') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "asgiref" 3 | version = "3.3.4" 4 | description = "ASGI specs, helper code, and adapters" 5 | category = "main" 6 | optional = false 7 | python-versions = ">=3.6" 8 | 9 | [package.extras] 10 | tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] 11 | 12 | [[package]] 13 | name = "django" 14 | version = "3.2.3" 15 | description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." 16 | category = "main" 17 | optional = false 18 | python-versions = ">=3.6" 19 | 20 | [package.dependencies] 21 | asgiref = ">=3.3.2,<4" 22 | pytz = "*" 23 | sqlparse = ">=0.2.2" 24 | 25 | [package.extras] 26 | argon2 = ["argon2-cffi (>=19.1.0)"] 27 | bcrypt = ["bcrypt"] 28 | 29 | [[package]] 30 | name = "pytz" 31 | version = "2021.1" 32 | description = "World timezone definitions, modern and historical" 33 | category = "main" 34 | optional = false 35 | python-versions = "*" 36 | 37 | [[package]] 38 | name = "sqlparse" 39 | version = "0.4.1" 40 | description = "A non-validating SQL parser." 41 | category = "main" 42 | optional = false 43 | python-versions = ">=3.5" 44 | 45 | [metadata] 46 | lock-version = "1.1" 47 | python-versions = "^3.9" 48 | content-hash = "37775a3a7cec1190376f6505d6447ac4c33ab8c80df5e272db7e50473ce6302f" 49 | 50 | [metadata.files] 51 | asgiref = [ 52 | {file = "asgiref-3.3.4-py3-none-any.whl", hash = "sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee"}, 53 | {file = "asgiref-3.3.4.tar.gz", hash = "sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78"}, 54 | ] 55 | django = [ 56 | {file = "Django-3.2.3-py3-none-any.whl", hash = "sha256:7e0a1393d18c16b503663752a8b6790880c5084412618990ce8a81cc908b4962"}, 57 | {file = "Django-3.2.3.tar.gz", hash = "sha256:13ac78dbfd189532cad8f383a27e58e18b3d33f80009ceb476d7fcbfc5dcebd8"}, 58 | ] 59 | pytz = [ 60 | {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, 61 | {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, 62 | ] 63 | sqlparse = [ 64 | {file = "sqlparse-0.4.1-py3-none-any.whl", hash = "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0"}, 65 | {file = "sqlparse-0.4.1.tar.gz", hash = "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"}, 66 | ] 67 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "django-unstuck" 3 | version = "0.0.0" 4 | description = "" 5 | authors = ["Johannes Spielmann "] 6 | license = "BSD 3-Clause License" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.9" 10 | Django = "^3.2.3" 11 | 12 | [tool.poetry.dev-dependencies] 13 | 14 | [build-system] 15 | requires = ["poetry-core>=1.0.0"] 16 | build-backend = "poetry.core.masonry.api" 17 | -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.accordion.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("./foundation.core"),require("./foundation.util.keyboard"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.core","./foundation.util.keyboard","jquery"],t):"object"==typeof exports?exports["foundation.accordion"]=t(require("./foundation.core"),require("./foundation.util.keyboard"),require("jquery")):(e.__FOUNDATION_EXTERNAL__=e.__FOUNDATION_EXTERNAL__||{},e.__FOUNDATION_EXTERNAL__["foundation.accordion"]=t(e.__FOUNDATION_EXTERNAL__["foundation.core"],e.__FOUNDATION_EXTERNAL__["foundation.util.keyboard"],e.jQuery))}(window,function(n,o,i){return c={},a.m=r={"./foundation.core":function(e,t){e.exports=n},"./foundation.util.keyboard":function(e,t){e.exports=o},"./js/entries/plugins/foundation.accordion.js":function(e,t,n){"use strict";n.r(t);var o=n("./foundation.core");n.d(t,"Foundation",function(){return o.Foundation});var i=n("./js/foundation.accordion.js");n.d(t,"Accordion",function(){return i.Accordion}),o.Foundation.plugin(i.Accordion,"Accordion")},"./js/foundation.accordion.js":function(e,t,n){"use strict";n.r(t),n.d(t,"Accordion",function(){return f});var o=n("jquery"),r=n.n(o),c=n("./foundation.core"),i=n("./foundation.util.keyboard");function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t){for(var n=0;n');u.options.submenuToggle?(n.addClass("has-submenu-toggle"),n.children("a").after('")):n.attr({"aria-controls":i,"aria-expanded":o,id:e}),t.attr({"aria-labelledby":e,"aria-hidden":!o,role:"group",id:i})}),this.$element.find("li").attr({role:"treeitem"});var e=this.$element.find(".is-active");e.length&&e.each(function(){u.down(a()(this))}),this._events()}},{key:"_events",value:function(){var r=this;this.$element.find("li").each(function(){var n=a()(this).children("[data-submenu]");n.length&&(r.options.submenuToggle?a()(this).children(".submenu-toggle").off("click.zf.accordionMenu").on("click.zf.accordionMenu",function(e){r.toggle(n)}):a()(this).children("a").off("click.zf.accordionMenu").on("click.zf.accordionMenu",function(e){e.preventDefault(),r.toggle(n)}))}).on("keydown.zf.accordionMenu",function(n){var t,i,o=a()(this),u=o.parent("ul").children("li"),e=o.children("[data-submenu]");u.each(function(e){if(a()(this).is(o))return t=u.eq(Math.max(0,e-1)).find("a").first(),i=u.eq(Math.min(e+1,u.length-1)).find("a").first(),a()(this).children("[data-submenu]:visible").length&&(i=o.find("li:first-child").find("a").first()),a()(this).is(":first-child")?t=o.parents("li").first().find("a").first():t.parents("li").first().children("[data-submenu]:visible").length&&(t=t.parents("li").find("li:last-child").find("a").first()),void(a()(this).is(":last-child")&&(i=o.parents("li").first().next("li").find("a").first()))}),s.Keyboard.handleKey(n,"AccordionMenu",{open:function(){e.is(":hidden")&&(r.down(e),e.find("li").first().find("a").first().focus())},close:function(){e.length&&!e.is(":hidden")?r.up(e):o.parent("[data-submenu]").length&&(r.up(o.parent("[data-submenu]")),o.parents("li").first().find("a").first().focus())},up:function(){return t.focus(),!0},down:function(){return i.focus(),!0},toggle:function(){return!r.options.submenuToggle&&(o.children("[data-submenu]").length?(r.toggle(o.children("[data-submenu]")),!0):void 0)},closeAll:function(){r.hideAll()},handled:function(e){e&&n.preventDefault()}})})}},{key:"hideAll",value:function(){this.up(this.$element.find("[data-submenu]"))}},{key:"showAll",value:function(){this.down(this.$element.find("[data-submenu]"))}},{key:"toggle",value:function(e){e.is(":animated")||(e.is(":hidden")?this.down(e):this.up(e))}},{key:"down",value:function(e){var n=this;if(!this.options.multiOpen){var t=e.parentsUntil(this.$element).add(e).add(e.find(".is-active")),i=this.$element.find(".is-active").not(t);this.up(i)}e.addClass("is-active").attr({"aria-hidden":!1}),this.options.submenuToggle?e.prev(".submenu-toggle").attr({"aria-expanded":!0}):e.parent(".is-accordion-submenu-parent").attr({"aria-expanded":!0}),e.slideDown(this.options.slideSpeed,function(){n.$element.trigger("down.zf.accordionMenu",[e])})}},{key:"up",value:function(e){var n=this,t=e.find("[data-submenu]"),i=e.add(t);t.slideUp(0),i.removeClass("is-active").attr("aria-hidden",!0),this.options.submenuToggle?i.prev(".submenu-toggle").attr("aria-expanded",!1):i.parent(".is-accordion-submenu-parent").attr("aria-expanded",!1),e.slideUp(this.options.slideSpeed,function(){n.$element.trigger("up.zf.accordionMenu",[e])})}},{key:"_destroy",value:function(){this.$element.find("[data-submenu]").slideDown(0).css("display",""),this.$element.find("a").off("click.zf.accordionMenu"),this.$element.find("[data-is-parent-link]").detach(),this.options.submenuToggle&&(this.$element.find(".has-submenu-toggle").removeClass("has-submenu-toggle"),this.$element.find(".submenu-toggle").remove()),o.Nest.Burn(this.$element,"accordion")}}]),t}();p.defaults={parentLink:!1,slideSpeed:250,submenuToggle:!1,submenuToggleText:"Toggle menu",multiOpen:!0}},2:function(e,n,t){e.exports=t("./js/entries/plugins/foundation.accordionMenu.js")},jquery:function(e,n){e.exports=u}},r.c=s,r.d=function(e,n,t){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(n,e){if(1&e&&(n=r(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var t=Object.create(null);if(r.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var i in n)r.d(t,i,function(e){return n[e]}.bind(null,i));return t},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=2);function r(e){if(s[e])return s[e].exports;var n=s[e]={i:e,l:!1,exports:{}};return a[e].call(n.exports,n,n.exports,r),n.l=!0,n.exports}var a,s}); 2 | //# sourceMappingURL=foundation.accordionMenu.min.js.map 3 | -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.dropdownMenu.min.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n(require("./foundation.core"),require("./foundation.util.box"),require("./foundation.util.keyboard"),require("./foundation.util.nest"),require("./foundation.util.touch"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.core","./foundation.util.box","./foundation.util.keyboard","./foundation.util.nest","./foundation.util.touch","jquery"],n):"object"==typeof exports?exports["foundation.dropdownMenu"]=n(require("./foundation.core"),require("./foundation.util.box"),require("./foundation.util.keyboard"),require("./foundation.util.nest"),require("./foundation.util.touch"),require("jquery")):(e.__FOUNDATION_EXTERNAL__=e.__FOUNDATION_EXTERNAL__||{},e.__FOUNDATION_EXTERNAL__["foundation.dropdownMenu"]=n(e.__FOUNDATION_EXTERNAL__["foundation.core"],e.__FOUNDATION_EXTERNAL__["foundation.util.box"],e.__FOUNDATION_EXTERNAL__["foundation.util.keyboard"],e.__FOUNDATION_EXTERNAL__["foundation.util.nest"],e.__FOUNDATION_EXTERNAL__["foundation.util.touch"],e.jQuery))}(window,function(t,o,i,r,s,u){return l={},a.m=d={"./foundation.core":function(e,n){e.exports=t},"./foundation.util.box":function(e,n){e.exports=o},"./foundation.util.keyboard":function(e,n){e.exports=i},"./foundation.util.nest":function(e,n){e.exports=r},"./foundation.util.touch":function(e,n){e.exports=s},"./js/entries/plugins/foundation.dropdownMenu.js":function(e,n,t){"use strict";t.r(n);var o=t("./foundation.core");t.d(n,"Foundation",function(){return o.Foundation});var i=t("./js/foundation.dropdownMenu.js");t.d(n,"DropdownMenu",function(){return i.DropdownMenu}),o.Foundation.plugin(i.DropdownMenu,"DropdownMenu")},"./js/foundation.dropdownMenu.js":function(e,n,t){"use strict";t.r(n),t.d(n,"DropdownMenu",function(){return m});var o=t("jquery"),f=t.n(o),i=t("./foundation.core"),p=t("./foundation.util.keyboard"),r=t("./foundation.util.nest"),s=t("./foundation.util.box"),u=t("./foundation.util.touch");function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function d(e,n){for(var t=0;t a:first").focus(),n.preventDefault())}function d(){var e=i.parent("ul").parent("li");e.children("a:first").focus(),c._hide(e),n.preventDefault()}var l={open:a,close:function(){c._hide(c.$element),c.$menuItems.eq(0).children("a").focus(),n.preventDefault()}};e?c._isVertical()?c._isRtl()?f.a.extend(l,{down:s,up:u,next:d,previous:a}):f.a.extend(l,{down:s,up:u,next:a,previous:d}):c._isRtl()?f.a.extend(l,{next:u,previous:s,down:a,up:d}):f.a.extend(l,{next:s,previous:u,down:a,up:d}):c._isRtl()?f.a.extend(l,{next:d,previous:a,down:s,up:u}):f.a.extend(l,{next:a,previous:d,down:s,up:u}),p.Keyboard.handleKey(n,"DropdownMenu",l)})}},{key:"_addBodyHandler",value:function(){var n=this,e=f()(document.body);this._removeBodyHandler(),e.on("click.zf.dropdownMenu tap.zf.dropdownMenu",function(e){!f()(e.target).closest(n.$element).length&&(n._hide(),n._removeBodyHandler())})}},{key:"_removeBodyHandler",value:function(){f()(document.body).off("click.zf.dropdownMenu tap.zf.dropdownMenu")}},{key:"_show",value:function(t){var e=this.$tabs.index(this.$tabs.filter(function(e,n){return 0n.$slides.filter(".is-active").data("slide"),i=n.$slides.eq(t);n.changeSlide(e,i,t)}),this.options.accessible&&this.$wrapper.add(this.$bullets).on("keydown.zf.orbit",function(t){o.Keyboard.handleKey(t,"Orbit",{next:function(){n.changeSlide(!0)},previous:function(){n.changeSlide(!1)},handled:function(){r()(t.target).is(n.$bullets)&&n.$bullets.filter(".is-active").focus()}})})}}},{key:"_reset",value:function(){void 0!==this.$slides&&1"),o=new e.plugin(n,this.options);for(var i in o.options)if(o.options.hasOwnProperty(i)&&"zfPlugin"!==i){var r=o.options[i];this.allOptions[i]=r}o.destroy()}catch(t){}}}},{key:"_events",value:function(){this._changedZfMediaQueryHandler=this._checkMediaQueries.bind(this),l()(window).on("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}},{key:"_checkMediaQueries",value:function(){var e,n=this;l.a.each(this.rules,function(t){a.MediaQuery.atLeast(t)&&(e=t)}),e&&(this.currentPlugin instanceof this.rules[e].plugin||(l.a.each(y,function(t,e){n.$element.removeClass(e.cssClass)}),this.$element.addClass(this.rules[e].cssClass),this.currentPlugin&&(!this.currentPlugin.$element.data("zfPlugin")&&this.storezfData&&this.currentPlugin.$element.data("zfPlugin",this.storezfData),this.currentPlugin.destroy()),this._handleMarkup(this.rules[e].cssClass),this.currentRule=this.rules[e],this.currentPlugin=new this.currentRule.plugin(this.$element,this.options),this.storezfData=this.currentPlugin.$element.data("zfPlugin")))}},{key:"_handleMarkup",value:function(t){var n=this,e="accordion",o=l()("[data-tabs-content="+this.$element.attr("id")+"]");if(o.length&&(e="tabs"),e!==t){var i=n.allOptions.linkClass?n.allOptions.linkClass:"tabs-title",r=n.allOptions.panelClass?n.allOptions.panelClass:"tabs-panel";this.$element.removeAttr("role");var a=this.$element.children("."+i+",[data-accordion-item]").removeClass(i).removeClass("accordion-item").removeAttr("data-accordion-item"),s=a.children("a").removeClass("accordion-title");if("tabs"===e?(o=o.children("."+r).removeClass(r).removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby")).children("a").removeAttr("role").removeAttr("aria-controls").removeAttr("aria-selected"):o=a.children("[data-tab-content]").removeClass("accordion-content"),o.css({display:"",visibility:""}),a.css({display:"",visibility:""}),"accordion"===t)o.each(function(t,e){l()(e).appendTo(a.get(t)).addClass("accordion-content").attr("data-tab-content","").removeClass("is-active").css({height:""}),l()("[data-tabs-content="+n.$element.attr("id")+"]").after('
').detach(),a.addClass("accordion-item").attr("data-accordion-item",""),s.addClass("accordion-title")});else if("tabs"===t){var u=l()("[data-tabs-content="+n.$element.attr("id")+"]"),c=l()("#tabs-placeholder-"+n.$element.attr("id"));c.length?(u=l()('
').insertAfter(c).attr("data-tabs-content",n.$element.attr("id")),c.remove()):u=l()('
').insertAfter(n.$element).attr("data-tabs-content",n.$element.attr("id")),o.each(function(t,e){var n=l()(e).appendTo(u).addClass(r),o=s.get(t).hash.slice(1),i=l()(e).attr("id")||Object(d.GetYoDigits)(6,"accordion");o!==i&&(""!==o?l()(e).attr("id",o):(o=i,l()(e).attr("id",o),l()(s.get(t)).attr("href",l()(s.get(t)).attr("href").replace("#","")+"#"+o))),l()(a.get(t)).hasClass("is-active")&&n.addClass("is-active")}),a.addClass(i)}}}},{key:"open",value:function(t){var e;if(this.currentRule&&"function"==typeof this.currentRule.open)return(e=this.currentRule).open.apply(e,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"close",value:function(t){var e;if(this.currentRule&&"function"==typeof this.currentRule.close)return(e=this.currentRule).close.apply(e,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"toggle",value:function(t){var e;if(this.currentRule&&"function"==typeof this.currentRule.toggle)return(e=this.currentRule).toggle.apply(e,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"_destroy",value:function(){this.currentPlugin&&this.currentPlugin.destroy(),l()(window).off("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}}]),o}();b.defaults={}},11:function(t,e,n){t.exports=n("./js/entries/plugins/foundation.responsiveAccordionTabs.js")},jquery:function(t,e){t.exports=a}},s.c=c,s.d=function(t,e,n){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(e,t){if(1&t&&(e=s(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(s.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)s.d(n,o,function(t){return e[t]}.bind(null,o));return n},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=11);function s(t){if(c[t])return c[t].exports;var e=c[t]={i:t,l:!1,exports:{}};return u[t].call(e.exports,e,e.exports,s),e.l=!0,e.exports}var u,c}); 2 | //# sourceMappingURL=foundation.responsiveAccordionTabs.min.js.map 3 | -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.responsiveMenu.min.js: -------------------------------------------------------------------------------- 1 | !function(n,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("./foundation.accordionMenu"),require("./foundation.core"),require("./foundation.drilldown"),require("./foundation.dropdownMenu"),require("./foundation.util.mediaQuery"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.accordionMenu","./foundation.core","./foundation.drilldown","./foundation.dropdownMenu","./foundation.util.mediaQuery","jquery"],e):"object"==typeof exports?exports["foundation.responsiveMenu"]=e(require("./foundation.accordionMenu"),require("./foundation.core"),require("./foundation.drilldown"),require("./foundation.dropdownMenu"),require("./foundation.util.mediaQuery"),require("jquery")):(n.__FOUNDATION_EXTERNAL__=n.__FOUNDATION_EXTERNAL__||{},n.__FOUNDATION_EXTERNAL__["foundation.responsiveMenu"]=e(n.__FOUNDATION_EXTERNAL__["foundation.accordionMenu"],n.__FOUNDATION_EXTERNAL__["foundation.core"],n.__FOUNDATION_EXTERNAL__["foundation.drilldown"],n.__FOUNDATION_EXTERNAL__["foundation.dropdownMenu"],n.__FOUNDATION_EXTERNAL__["foundation.util.mediaQuery"],n.jQuery))}(window,function(t,o,r,i,u,s){return c={},a.m=f={"./foundation.accordionMenu":function(n,e){n.exports=t},"./foundation.core":function(n,e){n.exports=o},"./foundation.drilldown":function(n,e){n.exports=r},"./foundation.dropdownMenu":function(n,e){n.exports=i},"./foundation.util.mediaQuery":function(n,e){n.exports=u},"./js/entries/plugins/foundation.responsiveMenu.js":function(n,e,t){"use strict";t.r(e);var o=t("./foundation.core");t.d(e,"Foundation",function(){return o.Foundation});var r=t("./js/foundation.responsiveMenu.js");t.d(e,"ResponsiveMenu",function(){return r.ResponsiveMenu}),o.Foundation.plugin(r.ResponsiveMenu,"ResponsiveMenu")},"./js/foundation.responsiveMenu.js":function(n,e,t){"use strict";t.r(e),t.d(e,"ResponsiveMenu",function(){return h});var o=t("jquery"),u=t.n(o),s=t("./foundation.util.mediaQuery"),a=t("./foundation.core"),r=t("./foundation.dropdownMenu"),i=t("./foundation.drilldown"),f=t("./foundation.accordionMenu");function c(n){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n})(n)}function d(n,e){for(var t=0;t').appendTo(document.head);var e,t=i()(".foundation-mq").css("font-family");for(var n in e=function(e){var t={};return"string"==typeof e&&(e=e.trim().slice(1,-1))?t=e.split("&").reduce(function(e,t){var n=t.replace(/\+/g," ").split("="),r=n[0],i=n[1];return r=decodeURIComponent(r),i=void 0===i?null:decodeURIComponent(i),e.hasOwnProperty(r)?Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]:e[r]=i,e},{}):t}(t),this.queries=[],e)e.hasOwnProperty(n)&&this.queries.push({name:n,value:"only screen and (min-width: ".concat(e[n],")")});this.current=this._getCurrentSize(),this._watcher()}},_reInit:function(){this.isInitialized=!1,this._init()},atLeast:function(e){var t=this.get(e);return!!t&&window.matchMedia(t).matches},only:function(e){return e===this._getCurrentSize()},upTo:function(e){var t=this.next(e);return!t||!this.atLeast(t)},is:function(e){var t=u(e.trim().split(" ").filter(function(e){return!!e.length}),2),n=t[0],r=t[1],i=void 0===r?"":r;if("only"===i)return this.only(n);if(!i||"up"===i)return this.atLeast(n);if("down"===i)return this.upTo(n);throw new Error('\n Invalid breakpoint passed to MediaQuery.is().\n Expected a breakpoint name formatted like " ", got "'.concat(e,'".\n '))},get:function(e){for(var t in this.queries)if(this.queries.hasOwnProperty(t)){var n=this.queries[t];if(e===n.name)return n.value}return null},next:function(t){var n=this,e=this.queries.findIndex(function(e){return n._getQueryName(e)===t});if(-1===e)throw new Error('\n Unknown breakpoint "'.concat(t,'" passed to MediaQuery.next().\n Ensure it is present in your Sass "$breakpoints" setting.\n '));var r=this.queries[e+1];return r?r.name:null},_getQueryName:function(e){if("string"==typeof e)return e;if("object"===o(e))return e.name;throw new TypeError('\n Invalid value passed to MediaQuery._getQueryName().\n Expected a breakpoint name (String) or a breakpoint query (Object), got "'.concat(e,'" (').concat(o(e),")\n "))},_getCurrentSize:function(){for(var e,t=0;tli, > li > ul, .menu, .menu > li, [data-submenu] > li')\n .removeClass(`${subMenuClass} ${subItemClass} ${hasSubClass} is-submenu-item submenu is-active`)\n .removeAttr('data-submenu').css('display', '');\n\n }\n}\n\nexport {Nest};\n","module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;"],"sourceRoot":""} -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.nest.min.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n(require("./foundation.core"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.core","jquery"],n):"object"==typeof exports?exports["foundation.util.nest"]=n(require("./foundation.core"),require("jquery")):(e.__FOUNDATION_EXTERNAL__=e.__FOUNDATION_EXTERNAL__||{},e.__FOUNDATION_EXTERNAL__["foundation.util.nest"]=n(e.__FOUNDATION_EXTERNAL__["foundation.core"],e.jQuery))}(window,function(t,r){return i={},o.m=u={"./foundation.core":function(e,n){e.exports=t},"./js/entries/plugins/foundation.util.nest.js":function(e,n,t){"use strict";t.r(n);var r=t("./foundation.core");t.d(n,"Foundation",function(){return r.Foundation});var o=t("./js/foundation.util.nest.js");t.d(n,"Nest",function(){return o.Nest}),r.Foundation.Nest=o.Nest},"./js/foundation.util.nest.js":function(e,n,t){"use strict";t.r(n),t.d(n,"Nest",function(){return o});var r=t("jquery"),s=t.n(r),o={Feather:function(e,n){var t=1li, > li > ul, .menu, .menu > li, [data-submenu] > li").removeClass("".concat(t," ").concat(r," ").concat(o," is-submenu-item submenu is-active")).removeAttr("data-submenu").css("display","")}}},26:function(e,n,t){e.exports=t("./js/entries/plugins/foundation.util.nest.js")},jquery:function(e,n){e.exports=r}},o.c=i,o.d=function(e,n,t){o.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(n,e){if(1&e&&(n=o(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var r in n)o.d(t,r,function(e){return n[e]}.bind(null,r));return t},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="",o(o.s=26);function o(e){if(i[e])return i[e].exports;var n=i[e]={i:e,l:!1,exports:{}};return u[e].call(n.exports,n,n.exports,o),n.l=!0,n.exports}var u,i}); 2 | //# sourceMappingURL=foundation.util.nest.min.js.map 3 | -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.nest.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/universalModuleDefinition","webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/bootstrap","webpack:/__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"__FOUNDATION_EXTERNAL__\",\"foundation.core\"],\"amd\":\"./foundation.core\",\"commonjs\":\"./foundation.core\",\"commonjs2\":\"./foundation.core\"}","webpack://__FOUNDATION_EXTERNAL__.[name]/js/entries/plugins/foundation.util.nest.js","webpack://__FOUNDATION_EXTERNAL__.[name]/js/foundation.util.nest.js","webpack:/__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"jQuery\"],\"amd\":\"jquery\",\"commonjs\":\"jquery\",\"commonjs2\":\"jquery\"}"],"names":["root","factory","exports","module","require","define","amd","window","__WEBPACK_EXTERNAL_MODULE__foundation_core__","__WEBPACK_EXTERNAL_MODULE_jquery__","installedModules","__webpack_require__","m","r","__webpack_exports__","_foundation_core__WEBPACK_IMPORTED_MODULE_0__","d","_foundation_util_nest__WEBPACK_IMPORTED_MODULE_1__","Foundation","Nest","jquery__WEBPACK_IMPORTED_MODULE_0__","jquery__WEBPACK_IMPORTED_MODULE_0___default","n","Feather","menu","type","arguments","length","undefined","attr","find","role","items","subMenuClass","concat","subItemClass","hasSubClass","applyAria","each","$item","$","this","$sub","children","addClass","aria-haspopup","aria-label","text","aria-expanded","data-submenu","aria-hidden","parent","Burn","removeClass","removeAttr","css","c","name","getter","o","Object","defineProperty","enumerable","get","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","object","property","prototype","hasOwnProperty","call","p","s","moduleId","i","l","modules"],"mappings":"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","file":"foundation.util.nest.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"./foundation.core\", \"jquery\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"foundation.util.nest\"] = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse\n\t\troot[\"__FOUNDATION_EXTERNAL__\"] = root[\"__FOUNDATION_EXTERNAL__\"] || {}, root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.util.nest\"] = factory(root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.core\"], root[\"jQuery\"]);\n})(window, function(__WEBPACK_EXTERNAL_MODULE__foundation_core__, __WEBPACK_EXTERNAL_MODULE_jquery__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 26);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__foundation_core__;","import { Foundation } from './foundation.core';\n\nimport { Nest } from '../../foundation.util.nest';\n\nFoundation.Nest = Nest;\n\nexport { Foundation, Nest };\n","'use strict';\n\nimport $ from 'jquery';\n\nconst Nest = {\n Feather(menu, type = 'zf') {\n menu.attr('role', 'menubar');\n menu.find('a').attr({'role': 'menuitem'});\n\n var items = menu.find('li').attr({'role': 'none'}),\n subMenuClass = `is-${type}-submenu`,\n subItemClass = `${subMenuClass}-item`,\n hasSubClass = `is-${type}-submenu-parent`,\n applyAria = (type !== 'accordion'); // Accordions handle their own ARIA attriutes.\n\n items.each(function() {\n var $item = $(this),\n $sub = $item.children('ul');\n\n if ($sub.length) {\n $item.addClass(hasSubClass);\n if(applyAria) {\n $item.attr({\n 'aria-haspopup': true,\n 'aria-label': $item.children('a:first').text()\n });\n // Note: Drilldowns behave differently in how they hide, and so need\n // additional attributes. We should look if this possibly over-generalized\n // utility (Nest) is appropriate when we rework menus in 6.4\n if(type === 'drilldown') {\n $item.attr({'aria-expanded': false});\n }\n }\n $sub\n .addClass(`submenu ${subMenuClass}`)\n .attr({\n 'data-submenu': '',\n 'role': 'menubar'\n });\n if(type === 'drilldown') {\n $sub.attr({'aria-hidden': true});\n }\n }\n\n if ($item.parent('[data-submenu]').length) {\n $item.addClass(`is-submenu-item ${subItemClass}`);\n }\n });\n\n return;\n },\n\n Burn(menu, type) {\n var //items = menu.find('li'),\n subMenuClass = `is-${type}-submenu`,\n subItemClass = `${subMenuClass}-item`,\n hasSubClass = `is-${type}-submenu-parent`;\n\n menu\n .find('>li, > li > ul, .menu, .menu > li, [data-submenu] > li')\n .removeClass(`${subMenuClass} ${subItemClass} ${hasSubClass} is-submenu-item submenu is-active`)\n .removeAttr('data-submenu').css('display', '');\n\n }\n}\n\nexport {Nest};\n","module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;"]} -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.timer.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(require("./foundation.core"), require("jquery")); 4 | else if(typeof define === 'function' && define.amd) 5 | define(["./foundation.core", "jquery"], factory); 6 | else if(typeof exports === 'object') 7 | exports["foundation.util.timer"] = factory(require("./foundation.core"), require("jquery")); 8 | else 9 | root["__FOUNDATION_EXTERNAL__"] = root["__FOUNDATION_EXTERNAL__"] || {}, root["__FOUNDATION_EXTERNAL__"]["foundation.util.timer"] = factory(root["__FOUNDATION_EXTERNAL__"]["foundation.core"], root["jQuery"]); 10 | })(window, function(__WEBPACK_EXTERNAL_MODULE__foundation_core__, __WEBPACK_EXTERNAL_MODULE_jquery__) { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // define getter function for harmony exports 47 | /******/ __webpack_require__.d = function(exports, name, getter) { 48 | /******/ if(!__webpack_require__.o(exports, name)) { 49 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 50 | /******/ } 51 | /******/ }; 52 | /******/ 53 | /******/ // define __esModule on exports 54 | /******/ __webpack_require__.r = function(exports) { 55 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 56 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 57 | /******/ } 58 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 59 | /******/ }; 60 | /******/ 61 | /******/ // create a fake namespace object 62 | /******/ // mode & 1: value is a module id, require it 63 | /******/ // mode & 2: merge all properties of value into the ns 64 | /******/ // mode & 4: return value when already ns object 65 | /******/ // mode & 8|1: behave like require 66 | /******/ __webpack_require__.t = function(value, mode) { 67 | /******/ if(mode & 1) value = __webpack_require__(value); 68 | /******/ if(mode & 8) return value; 69 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 70 | /******/ var ns = Object.create(null); 71 | /******/ __webpack_require__.r(ns); 72 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 73 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 74 | /******/ return ns; 75 | /******/ }; 76 | /******/ 77 | /******/ // getDefaultExport function for compatibility with non-harmony modules 78 | /******/ __webpack_require__.n = function(module) { 79 | /******/ var getter = module && module.__esModule ? 80 | /******/ function getDefault() { return module['default']; } : 81 | /******/ function getModuleExports() { return module; }; 82 | /******/ __webpack_require__.d(getter, 'a', getter); 83 | /******/ return getter; 84 | /******/ }; 85 | /******/ 86 | /******/ // Object.prototype.hasOwnProperty.call 87 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 88 | /******/ 89 | /******/ // __webpack_public_path__ 90 | /******/ __webpack_require__.p = ""; 91 | /******/ 92 | /******/ 93 | /******/ // Load entry module and return exports 94 | /******/ return __webpack_require__(__webpack_require__.s = 27); 95 | /******/ }) 96 | /************************************************************************/ 97 | /******/ ({ 98 | 99 | /***/ "./foundation.core": 100 | /*!****************************************************************************************************************************************************************!*\ 101 | !*** external {"root":["__FOUNDATION_EXTERNAL__","foundation.core"],"amd":"./foundation.core","commonjs":"./foundation.core","commonjs2":"./foundation.core"} ***! 102 | \****************************************************************************************************************************************************************/ 103 | /*! no static exports found */ 104 | /***/ (function(module, exports) { 105 | 106 | module.exports = __WEBPACK_EXTERNAL_MODULE__foundation_core__; 107 | 108 | /***/ }), 109 | 110 | /***/ "./js/entries/plugins/foundation.util.timer.js": 111 | /*!*****************************************************!*\ 112 | !*** ./js/entries/plugins/foundation.util.timer.js ***! 113 | \*****************************************************/ 114 | /*! exports provided: Foundation, Timer */ 115 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 116 | 117 | "use strict"; 118 | __webpack_require__.r(__webpack_exports__); 119 | /* harmony import */ var _foundation_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./foundation.core */ "./foundation.core"); 120 | /* harmony import */ var _foundation_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_foundation_core__WEBPACK_IMPORTED_MODULE_0__); 121 | /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Foundation", function() { return _foundation_core__WEBPACK_IMPORTED_MODULE_0__["Foundation"]; }); 122 | 123 | /* harmony import */ var _foundation_util_timer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../foundation.util.timer */ "./js/foundation.util.timer.js"); 124 | /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Timer", function() { return _foundation_util_timer__WEBPACK_IMPORTED_MODULE_1__["Timer"]; }); 125 | 126 | 127 | 128 | _foundation_core__WEBPACK_IMPORTED_MODULE_0__["Foundation"].Timer = _foundation_util_timer__WEBPACK_IMPORTED_MODULE_1__["Timer"]; 129 | 130 | 131 | /***/ }), 132 | 133 | /***/ "./js/foundation.util.timer.js": 134 | /*!*************************************!*\ 135 | !*** ./js/foundation.util.timer.js ***! 136 | \*************************************/ 137 | /*! exports provided: Timer */ 138 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 139 | 140 | "use strict"; 141 | __webpack_require__.r(__webpack_exports__); 142 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timer", function() { return Timer; }); 143 | /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery"); 144 | /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); 145 | 146 | 147 | 148 | 149 | function Timer(elem, options, cb) { 150 | var _this = this, 151 | duration = options.duration, 152 | //options is an object for easily adding features later. 153 | nameSpace = Object.keys(elem.data())[0] || 'timer', 154 | remain = -1, 155 | start, 156 | timer; 157 | 158 | this.isPaused = false; 159 | 160 | this.restart = function () { 161 | remain = -1; 162 | clearTimeout(timer); 163 | this.start(); 164 | }; 165 | 166 | this.start = function () { 167 | this.isPaused = false; // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. 168 | 169 | clearTimeout(timer); 170 | remain = remain <= 0 ? duration : remain; 171 | elem.data('paused', false); 172 | start = Date.now(); 173 | timer = setTimeout(function () { 174 | if (options.infinite) { 175 | _this.restart(); //rerun the timer. 176 | 177 | } 178 | 179 | if (cb && typeof cb === 'function') { 180 | cb(); 181 | } 182 | }, remain); 183 | elem.trigger("timerstart.zf.".concat(nameSpace)); 184 | }; 185 | 186 | this.pause = function () { 187 | this.isPaused = true; //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things. 188 | 189 | clearTimeout(timer); 190 | elem.data('paused', true); 191 | var end = Date.now(); 192 | remain = remain - (end - start); 193 | elem.trigger("timerpaused.zf.".concat(nameSpace)); 194 | }; 195 | } 196 | 197 | 198 | 199 | /***/ }), 200 | 201 | /***/ 27: 202 | /*!***********************************************************!*\ 203 | !*** multi ./js/entries/plugins/foundation.util.timer.js ***! 204 | \***********************************************************/ 205 | /*! no static exports found */ 206 | /***/ (function(module, exports, __webpack_require__) { 207 | 208 | module.exports = __webpack_require__(/*! /Users/joeworkman/Development/foundation-sites/js/entries/plugins/foundation.util.timer.js */"./js/entries/plugins/foundation.util.timer.js"); 209 | 210 | 211 | /***/ }), 212 | 213 | /***/ "jquery": 214 | /*!********************************************************************************************!*\ 215 | !*** external {"root":["jQuery"],"amd":"jquery","commonjs":"jquery","commonjs2":"jquery"} ***! 216 | \********************************************************************************************/ 217 | /*! no static exports found */ 218 | /***/ (function(module, exports) { 219 | 220 | module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__; 221 | 222 | /***/ }) 223 | 224 | /******/ }); 225 | }); 226 | //# sourceMappingURL=foundation.util.timer.js.map -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.timer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/universalModuleDefinition","webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/bootstrap","webpack://__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"__FOUNDATION_EXTERNAL__\",\"foundation.core\"],\"amd\":\"./foundation.core\",\"commonjs\":\"./foundation.core\",\"commonjs2\":\"./foundation.core\"}","webpack://__FOUNDATION_EXTERNAL__.[name]/./js/entries/plugins/foundation.util.timer.js","webpack://__FOUNDATION_EXTERNAL__.[name]/./js/foundation.util.timer.js","webpack://__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"jQuery\"],\"amd\":\"jquery\",\"commonjs\":\"jquery\",\"commonjs2\":\"jquery\"}"],"names":["Foundation","Timer","elem","options","cb","_this","duration","nameSpace","Object","keys","data","remain","start","timer","isPaused","restart","clearTimeout","Date","now","setTimeout","infinite","trigger","pause","end"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE;AACzE,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA,8D;;;;;;;;;;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEAA,2DAAU,CAACC,KAAX,GAAmBA,4DAAnB;;;;;;;;;;;;;ACJA;AAAA;AAAA;AAAA;AAAa;;AAEb;;AAEA,SAASA,KAAT,CAAeC,IAAf,EAAqBC,OAArB,EAA8BC,EAA9B,EAAkC;AAChC,MAAIC,KAAK,GAAG,IAAZ;AAAA,MACIC,QAAQ,GAAGH,OAAO,CAACG,QADvB;AAAA,MACgC;AAC5BC,WAAS,GAAGC,MAAM,CAACC,IAAP,CAAYP,IAAI,CAACQ,IAAL,EAAZ,EAAyB,CAAzB,KAA+B,OAF/C;AAAA,MAGIC,MAAM,GAAG,CAAC,CAHd;AAAA,MAIIC,KAJJ;AAAA,MAKIC,KALJ;;AAOA,OAAKC,QAAL,GAAgB,KAAhB;;AAEA,OAAKC,OAAL,GAAe,YAAW;AACxBJ,UAAM,GAAG,CAAC,CAAV;AACAK,gBAAY,CAACH,KAAD,CAAZ;AACA,SAAKD,KAAL;AACD,GAJD;;AAMA,OAAKA,KAAL,GAAa,YAAW;AACtB,SAAKE,QAAL,GAAgB,KAAhB,CADsB,CAEtB;;AACAE,gBAAY,CAACH,KAAD,CAAZ;AACAF,UAAM,GAAGA,MAAM,IAAI,CAAV,GAAcL,QAAd,GAAyBK,MAAlC;AACAT,QAAI,CAACQ,IAAL,CAAU,QAAV,EAAoB,KAApB;AACAE,SAAK,GAAGK,IAAI,CAACC,GAAL,EAAR;AACAL,SAAK,GAAGM,UAAU,CAAC,YAAU;AAC3B,UAAGhB,OAAO,CAACiB,QAAX,EAAoB;AAClBf,aAAK,CAACU,OAAN,GADkB,CACF;;AACjB;;AACD,UAAIX,EAAE,IAAI,OAAOA,EAAP,KAAc,UAAxB,EAAoC;AAAEA,UAAE;AAAK;AAC9C,KALiB,EAKfO,MALe,CAAlB;AAMAT,QAAI,CAACmB,OAAL,yBAA8Bd,SAA9B;AACD,GAdD;;AAgBA,OAAKe,KAAL,GAAa,YAAW;AACtB,SAAKR,QAAL,GAAgB,IAAhB,CADsB,CAEtB;;AACAE,gBAAY,CAACH,KAAD,CAAZ;AACAX,QAAI,CAACQ,IAAL,CAAU,QAAV,EAAoB,IAApB;AACA,QAAIa,GAAG,GAAGN,IAAI,CAACC,GAAL,EAAV;AACAP,UAAM,GAAGA,MAAM,IAAIY,GAAG,GAAGX,KAAV,CAAf;AACAV,QAAI,CAACmB,OAAL,0BAA+Bd,SAA/B;AACD,GARD;AASD;;;;;;;;;;;;;;;;;;;;;;;;;AC7CD,oD","file":"foundation.util.timer.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"./foundation.core\", \"jquery\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"foundation.util.timer\"] = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse\n\t\troot[\"__FOUNDATION_EXTERNAL__\"] = root[\"__FOUNDATION_EXTERNAL__\"] || {}, root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.util.timer\"] = factory(root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.core\"], root[\"jQuery\"]);\n})(window, function(__WEBPACK_EXTERNAL_MODULE__foundation_core__, __WEBPACK_EXTERNAL_MODULE_jquery__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 27);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__foundation_core__;","import { Foundation } from './foundation.core';\n\nimport { Timer } from '../../foundation.util.timer';\n\nFoundation.Timer = Timer;\n\nexport { Foundation, Timer };\n","'use strict';\n\nimport $ from 'jquery';\n\nfunction Timer(elem, options, cb) {\n var _this = this,\n duration = options.duration,//options is an object for easily adding features later.\n nameSpace = Object.keys(elem.data())[0] || 'timer',\n remain = -1,\n start,\n timer;\n\n this.isPaused = false;\n\n this.restart = function() {\n remain = -1;\n clearTimeout(timer);\n this.start();\n }\n\n this.start = function() {\n this.isPaused = false;\n // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.\n clearTimeout(timer);\n remain = remain <= 0 ? duration : remain;\n elem.data('paused', false);\n start = Date.now();\n timer = setTimeout(function(){\n if(options.infinite){\n _this.restart();//rerun the timer.\n }\n if (cb && typeof cb === 'function') { cb(); }\n }, remain);\n elem.trigger(`timerstart.zf.${nameSpace}`);\n }\n\n this.pause = function() {\n this.isPaused = true;\n //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.\n clearTimeout(timer);\n elem.data('paused', true);\n var end = Date.now();\n remain = remain - (end - start);\n elem.trigger(`timerpaused.zf.${nameSpace}`);\n }\n}\n\nexport {Timer};\n","module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;"],"sourceRoot":""} -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.timer.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("./foundation.core"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.core","jquery"],e):"object"==typeof exports?exports["foundation.util.timer"]=e(require("./foundation.core"),require("jquery")):(t.__FOUNDATION_EXTERNAL__=t.__FOUNDATION_EXTERNAL__||{},t.__FOUNDATION_EXTERNAL__["foundation.util.timer"]=e(t.__FOUNDATION_EXTERNAL__["foundation.core"],t.jQuery))}(window,function(n,r){return u={},o.m=i={"./foundation.core":function(t,e){t.exports=n},"./js/entries/plugins/foundation.util.timer.js":function(t,e,n){"use strict";n.r(e);var r=n("./foundation.core");n.d(e,"Foundation",function(){return r.Foundation});var o=n("./js/foundation.util.timer.js");n.d(e,"Timer",function(){return o.Timer}),r.Foundation.Timer=o.Timer},"./js/foundation.util.timer.js":function(t,e,n){"use strict";n.r(e),n.d(e,"Timer",function(){return r});n("jquery");function r(e,t,n){var r,o,i=this,u=t.duration,a=Object.keys(e.data())[0]||"timer",f=-1;this.isPaused=!1,this.restart=function(){f=-1,clearTimeout(o),this.start()},this.start=function(){this.isPaused=!1,clearTimeout(o),f=f<=0?u:f,e.data("paused",!1),r=Date.now(),o=setTimeout(function(){t.infinite&&i.restart(),n&&"function"==typeof n&&n()},f),e.trigger("timerstart.zf.".concat(a))},this.pause=function(){this.isPaused=!0,clearTimeout(o),e.data("paused",!0);var t=Date.now();f-=t-r,e.trigger("timerpaused.zf.".concat(a))}}},27:function(t,e,n){t.exports=n("./js/entries/plugins/foundation.util.timer.js")},jquery:function(t,e){t.exports=r}},o.c=u,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)o.d(n,r,function(t){return e[t]}.bind(null,r));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=27);function o(t){if(u[t])return u[t].exports;var e=u[t]={i:t,l:!1,exports:{}};return i[t].call(e.exports,e,e.exports,o),e.l=!0,e.exports}var i,u}); 2 | //# sourceMappingURL=foundation.util.timer.min.js.map 3 | -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.timer.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/universalModuleDefinition","webpack://__FOUNDATION_EXTERNAL__.[name]/webpack/bootstrap","webpack:/__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"__FOUNDATION_EXTERNAL__\",\"foundation.core\"],\"amd\":\"./foundation.core\",\"commonjs\":\"./foundation.core\",\"commonjs2\":\"./foundation.core\"}","webpack://__FOUNDATION_EXTERNAL__.[name]/js/entries/plugins/foundation.util.timer.js","webpack://__FOUNDATION_EXTERNAL__.[name]/js/foundation.util.timer.js","webpack:/__FOUNDATION_EXTERNAL__.[name]/external {\"root\":[\"jQuery\"],\"amd\":\"jquery\",\"commonjs\":\"jquery\",\"commonjs2\":\"jquery\"}"],"names":["root","factory","exports","module","require","define","amd","window","__WEBPACK_EXTERNAL_MODULE__foundation_core__","__WEBPACK_EXTERNAL_MODULE_jquery__","installedModules","__webpack_require__","m","r","__webpack_exports__","_foundation_core__WEBPACK_IMPORTED_MODULE_0__","d","_foundation_util_timer__WEBPACK_IMPORTED_MODULE_1__","Foundation","Timer","elem","options","cb","start","timer","_this","this","duration","nameSpace","Object","keys","data","remain","isPaused","restart","clearTimeout","Date","now","setTimeout","infinite","trigger","concat","pause","end","c","name","getter","o","defineProperty","enumerable","get","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","call","p","s","moduleId","i","l","modules"],"mappings":"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","file":"foundation.util.timer.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"./foundation.core\", \"jquery\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"foundation.util.timer\"] = factory(require(\"./foundation.core\"), require(\"jquery\"));\n\telse\n\t\troot[\"__FOUNDATION_EXTERNAL__\"] = root[\"__FOUNDATION_EXTERNAL__\"] || {}, root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.util.timer\"] = factory(root[\"__FOUNDATION_EXTERNAL__\"][\"foundation.core\"], root[\"jQuery\"]);\n})(window, function(__WEBPACK_EXTERNAL_MODULE__foundation_core__, __WEBPACK_EXTERNAL_MODULE_jquery__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 27);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__foundation_core__;","import { Foundation } from './foundation.core';\n\nimport { Timer } from '../../foundation.util.timer';\n\nFoundation.Timer = Timer;\n\nexport { Foundation, Timer };\n","'use strict';\n\nimport $ from 'jquery';\n\nfunction Timer(elem, options, cb) {\n var _this = this,\n duration = options.duration,//options is an object for easily adding features later.\n nameSpace = Object.keys(elem.data())[0] || 'timer',\n remain = -1,\n start,\n timer;\n\n this.isPaused = false;\n\n this.restart = function() {\n remain = -1;\n clearTimeout(timer);\n this.start();\n }\n\n this.start = function() {\n this.isPaused = false;\n // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.\n clearTimeout(timer);\n remain = remain <= 0 ? duration : remain;\n elem.data('paused', false);\n start = Date.now();\n timer = setTimeout(function(){\n if(options.infinite){\n _this.restart();//rerun the timer.\n }\n if (cb && typeof cb === 'function') { cb(); }\n }, remain);\n elem.trigger(`timerstart.zf.${nameSpace}`);\n }\n\n this.pause = function() {\n this.isPaused = true;\n //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.\n clearTimeout(timer);\n elem.data('paused', true);\n var end = Date.now();\n remain = remain - (end - start);\n elem.trigger(`timerpaused.zf.${nameSpace}`);\n }\n}\n\nexport {Timer};\n","module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;"]} -------------------------------------------------------------------------------- /static/foundation/plugins/foundation.util.touch.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("./foundation.core"),require("jquery")):"function"==typeof define&&define.amd?define(["./foundation.core","jquery"],t):"object"==typeof exports?exports["foundation.util.touch"]=t(require("./foundation.core"),require("jquery")):(e.__FOUNDATION_EXTERNAL__=e.__FOUNDATION_EXTERNAL__||{},e.__FOUNDATION_EXTERNAL__["foundation.util.touch"]=t(e.__FOUNDATION_EXTERNAL__["foundation.core"],e.jQuery))}(window,function(n,o){return r={},i.m=u={"./foundation.core":function(e,t){e.exports=n},"./js/entries/plugins/foundation.util.touch.js":function(e,t,n){"use strict";n.r(t);var o=n("jquery"),i=n.n(o),u=n("./js/foundation.util.touch.js");n.d(t,"Touch",function(){return u.Touch});var r=n("./foundation.core");n.d(t,"Foundation",function(){return r.Foundation}),u.Touch.init(i.a),window.Foundation.Touch=u.Touch},"./js/foundation.util.touch.js":function(e,t,n){"use strict";n.r(t),n.d(t,"Touch",function(){return f});var o=n("jquery"),i=n.n(o);function u(e,t){for(var n=0;n=i.a.spotSwipe.moveThreshold&&s<=i.a.spotSwipe.timeThreshold&&(t=0 5 | 6 | 7 | 8 | 9 | 10 | {% block title %}{% endblock title %}Unstuck! 11 | 12 | {% block extra_css %}{% endblock extra_css %} 13 | {# #} 14 | 15 | 16 | 17 |
18 |
19 |
20 | {% include 'snippets/base_menu.html' %} 21 |
22 |
23 | 24 |
25 |
26 |
27 | 28 | Tuque! 29 |
30 | 31 | {% if messages %} 32 |
33 | {% for message in messages %} 34 |
35 |

{{ message }}

36 |
37 | {% endfor %} 38 |
39 | {% endif %} 40 | 41 |
42 |
43 |
44 | {% block content %} 45 | {% endblock content %} 46 |
47 |
48 |
49 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | {% endspaceless %} 59 | --------------------------------------------------------------------------------