├── .gitattributes ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── app ├── __init__.py ├── forms.py ├── migrations │ └── __init__.py ├── models.py ├── static │ └── app │ │ ├── content │ │ ├── bootstrap.css │ │ ├── bootstrap.min.css │ │ └── site.css │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ │ ├── img │ │ ├── STB13_Ken_06.png │ │ ├── container.png │ │ ├── github.png │ │ ├── linux-web-app.png │ │ └── overview.png │ │ └── scripts │ │ ├── _references.js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── jquery-1.10.2.intellisense.js │ │ ├── jquery-1.10.2.js │ │ ├── jquery-1.10.2.min.js │ │ ├── jquery-1.10.2.min.map │ │ ├── jquery.validate-vsdoc.js │ │ ├── jquery.validate.js │ │ ├── jquery.validate.min.js │ │ ├── jquery.validate.unobtrusive.js │ │ ├── jquery.validate.unobtrusive.min.js │ │ ├── modernizr-2.6.2.js │ │ ├── respond.js │ │ └── respond.min.js ├── templates │ └── app │ │ ├── index.html │ │ └── layout.html ├── tests.py └── views.py ├── db.sqlite3 ├── djangoapp ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── init.sh ├── manage.py ├── readme.html ├── requirements.txt ├── sshd_config └── static ├── admin ├── css │ ├── base.css │ ├── changelists.css │ ├── dashboard.css │ ├── fonts.css │ ├── forms.css │ ├── login.css │ ├── rtl.css │ └── widgets.css ├── fonts │ ├── LICENSE.txt │ ├── README.txt │ ├── Roboto-Bold-webfont.woff │ ├── Roboto-Light-webfont.woff │ └── Roboto-Regular-webfont.woff ├── img │ ├── LICENSE │ ├── README.txt │ ├── calendar-icons.svg │ ├── gis │ │ ├── move_vertex_off.svg │ │ └── move_vertex_on.svg │ ├── icon-addlink.svg │ ├── icon-alert.svg │ ├── icon-calendar.svg │ ├── icon-changelink.svg │ ├── icon-clock.svg │ ├── icon-deletelink.svg │ ├── icon-no.svg │ ├── icon-unknown-alt.svg │ ├── icon-unknown.svg │ ├── icon-yes.svg │ ├── inline-delete.svg │ ├── search.svg │ ├── selector-icons.svg │ ├── sorting-icons.svg │ ├── tooltag-add.svg │ └── tooltag-arrowright.svg └── js │ ├── SelectBox.js │ ├── SelectFilter2.js │ ├── actions.js │ ├── actions.min.js │ ├── admin │ ├── DateTimeShortcuts.js │ └── RelatedObjectLookups.js │ ├── calendar.js │ ├── cancel.js │ ├── change_form.js │ ├── collapse.js │ ├── collapse.min.js │ ├── core.js │ ├── inlines.js │ ├── inlines.min.js │ ├── jquery.init.js │ ├── popup_response.js │ ├── prepopulate.js │ ├── prepopulate.min.js │ ├── prepopulate_init.js │ ├── timeparse.js │ ├── urlify.js │ └── vendor │ ├── jquery │ ├── LICENSE-JQUERY.txt │ ├── jquery.js │ └── jquery.min.js │ └── xregexp │ ├── LICENSE-XREGEXP.txt │ ├── xregexp.js │ └── xregexp.min.js └── app ├── content ├── bootstrap.css ├── bootstrap.min.css └── site.css ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf └── glyphicons-halflings-regular.woff ├── img ├── container.png ├── github.png ├── linux-web-app.png └── overview.png └── scripts ├── _references.js ├── bootstrap.js ├── bootstrap.min.js ├── jquery-1.10.2.intellisense.js ├── jquery-1.10.2.js ├── jquery-1.10.2.min.js ├── jquery-1.10.2.min.map ├── jquery.validate-vsdoc.js ├── jquery.validate.js ├── jquery.validate.min.js ├── jquery.validate.unobtrusive.js ├── jquery.validate.unobtrusive.min.js ├── modernizr-2.6.2.js ├── respond.js └── respond.min.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.sh text eol=lf 3 | *.py text 4 | sshd_config text 5 | Dockerfile text 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | *debug.config 177 | 178 | # RIA/Silverlight projects 179 | Generated_Code/ 180 | 181 | # Backup & report files from converting an old project file 182 | # to a newer Visual Studio version. Backup files are not needed, 183 | # because we have git ;-) 184 | _UpgradeReport_Files/ 185 | Backup*/ 186 | UpgradeLog*.XML 187 | UpgradeLog*.htm 188 | 189 | # SQL Server files 190 | *.mdf 191 | *.ldf 192 | 193 | # Business Intelligence projects 194 | *.rdl.data 195 | *.bim.layout 196 | *.bim_*.settings 197 | 198 | # Microsoft Fakes 199 | FakesAssemblies/ 200 | 201 | # Node.js Tools for Visual Studio 202 | .ntvs_analysis.dat 203 | 204 | # Visual Studio 6 build log 205 | *.plg 206 | 207 | # Visual Studio 6 workspace options file 208 | *.opt 209 | 210 | # LightSwitch generated files 211 | GeneratedArtifacts/ 212 | _Pvt_Extensions/ 213 | ModelManifest.xml 214 | 215 | 216 | # Byte-compiled / optimized / DLL files 217 | __pycache__/ 218 | *.py[cod] 219 | *$py.class 220 | 221 | # C extensions 222 | *.so 223 | 224 | # Distribution / packaging 225 | .Python 226 | env/ 227 | build/ 228 | develop-eggs/ 229 | dist/ 230 | downloads/ 231 | eggs/ 232 | .eggs/ 233 | lib/ 234 | lib64/ 235 | parts/ 236 | sdist/ 237 | var/ 238 | *.egg-info/ 239 | .installed.cfg 240 | *.egg 241 | 242 | # PyInstaller 243 | # Usually these files are written by a python script from a template 244 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 245 | *.manifest 246 | *.spec 247 | 248 | # Installer logs 249 | pip-log.txt 250 | pip-delete-this-directory.txt 251 | 252 | # Unit test / coverage reports 253 | htmlcov/ 254 | .tox/ 255 | .coverage 256 | .coverage.* 257 | .cache 258 | nosetests.xml 259 | coverage.xml 260 | *,cover 261 | .hypothesis/ 262 | 263 | # Translations 264 | *.mo 265 | *.pot 266 | 267 | # Django stuff: 268 | *.log 269 | 270 | # Sphinx documentation 271 | docs/_build/ 272 | 273 | # PyBuilder 274 | target/ -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM tiangolo/uwsgi-nginx-flask:python3.6 3 | 4 | RUN mkdir /code 5 | WORKDIR /code 6 | ADD requirements.txt /code/ 7 | RUN pip install -r requirements.txt --no-cache-dir 8 | ADD . /code/ 9 | 10 | # ssh 11 | ENV SSH_PASSWD "root:Docker!" 12 | RUN apt-get update \ 13 | && apt-get install -y --no-install-recommends dialog \ 14 | && apt-get update \ 15 | && apt-get install -y --no-install-recommends openssh-server \ 16 | && echo "$SSH_PASSWD" | chpasswd 17 | 18 | COPY sshd_config /etc/ssh/ 19 | COPY init.sh /usr/local/bin/ 20 | 21 | RUN chmod u+x /usr/local/bin/init.sh 22 | EXPOSE 8000 2222 23 | #CMD ["python", "/code/manage.py", "runserver", "0.0.0.0:8000"] 24 | ENTRYPOINT ["init.sh"] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django starter app for Web App on Linux 2 | 3 | A simple Python Django application running in a Docker container. The custom image uses port 8000. 4 | 5 | ## Setting up custom image for web App on Linux 6 | - Create a Web App on Linux using CLI or Azure portal 7 | - Configure your web app to custom image 8 | - Add an App Setting ```WEBSITES_PORT = 8000 ``` for your app 9 | - Browse your site 10 | 11 | # Contributing 12 | 13 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 14 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 15 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 16 | 17 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 18 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 19 | provided by the bot. You will only need to do this once across all repos using our CLA. 20 | 21 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 23 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 24 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Package for the application. 3 | """ 4 | -------------------------------------------------------------------------------- /app/forms.py: -------------------------------------------------------------------------------- 1 | """ 2 | Definition of forms. 3 | """ 4 | 5 | from django import forms 6 | from django.contrib.auth.forms import AuthenticationForm 7 | -------------------------------------------------------------------------------- /app/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Definition of models. 3 | """ 4 | 5 | from django.db import models 6 | 7 | # Create your models here. 8 | -------------------------------------------------------------------------------- /app/static/app/content/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Set width on the form input elements since they're 100% wide by default */ 13 | input, 14 | select, 15 | textarea { 16 | max-width: 280px; 17 | } 18 | 19 | /* styles for validation helpers */ 20 | .field-validation-error { 21 | color: #b94a48; 22 | } 23 | 24 | .field-validation-valid { 25 | display: none; 26 | } 27 | 28 | input.input-validation-error { 29 | border: 1px solid #b94a48; 30 | } 31 | 32 | input[type="checkbox"].input-validation-error { 33 | border: 0 none; 34 | } 35 | 36 | .validation-summary-errors { 37 | color: #b94a48; 38 | } 39 | 40 | .validation-summary-valid { 41 | display: none; 42 | } 43 | 44 | .flex { 45 | display: -webkit-box; 46 | display: -moz-box; 47 | display: -ms-flexbox; 48 | display: -webkit-flex; 49 | display: flex; 50 | } 51 | .flex .thumbnail { 52 | height: 100%; 53 | display: flex; 54 | flex-direction: column; 55 | } 56 | .flex .caption:last-child { 57 | margin-top: auto; 58 | padding: 9px !important; /* overwrite inline style injected by JS */ 59 | } 60 | .no-flexbox .hero-feature { 61 | display: -webkit-box; 62 | display: -moz-box; 63 | display: -ms-flexbox; 64 | display: -webkit-flex; 65 | display: flex; 66 | } 67 | .no-flexbox .flex .thumbnail { 68 | height: auto !important; 69 | padding-bottom: 50px; 70 | } 71 | .no-flexbox .flex .caption:last-child { 72 | position: absolute; 73 | bottom: 0; 74 | width: 80%; 75 | } 76 | -------------------------------------------------------------------------------- /app/static/app/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/static/app/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/static/app/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/static/app/img/STB13_Ken_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/img/STB13_Ken_06.png -------------------------------------------------------------------------------- /app/static/app/img/container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/img/container.png -------------------------------------------------------------------------------- /app/static/app/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/img/github.png -------------------------------------------------------------------------------- /app/static/app/img/linux-web-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/img/linux-web-app.png -------------------------------------------------------------------------------- /app/static/app/img/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/img/overview.png -------------------------------------------------------------------------------- /app/static/app/scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/app/static/app/scripts/_references.js -------------------------------------------------------------------------------- /app/static/app/scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(c){var b=a(c),d=b.data(e),f=a.proxy(n,c);if(!d){d={options:{errorClass:"input-validation-error",errorElement:"span",errorPlacement:a.proxy(m,c),invalidHandler:a.proxy(l,c),messages:{},rules:{},success:a.proxy(k,c)},attachValidation:function(){b.unbind("reset."+e,f).bind("reset."+e,f).validate(this.options)},validate:function(){b.validate();return b.valid()}};b.data(e,d)}return d}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(b){var c=a(b).parents("form").andSelf().add(a(b).find("form")).filter("form");a(b).find(":input").filter("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});c.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); 20 | -------------------------------------------------------------------------------- /app/static/app/scripts/respond.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia = window.matchMedia || (function(doc, undefined){ 18 | 19 | var bool, 20 | docElem = doc.documentElement, 21 | refNode = docElem.firstElementChild || docElem.firstChild, 22 | // fakeBody required for 23 | fakeBody = doc.createElement('body'), 24 | div = doc.createElement('div'); 25 | 26 | div.id = 'mq-test-1'; 27 | div.style.cssText = "position:absolute;top:-100em"; 28 | fakeBody.style.background = "none"; 29 | fakeBody.appendChild(div); 30 | 31 | return function(q){ 32 | 33 | div.innerHTML = '­'; 34 | 35 | docElem.insertBefore(fakeBody, refNode); 36 | bool = div.offsetWidth == 42; 37 | docElem.removeChild(fakeBody); 38 | 39 | return { matches: bool, media: q }; 40 | }; 41 | 42 | })(document); 43 | 44 | 45 | 46 | 47 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 48 | (function( win ){ 49 | //exposed namespace 50 | win.respond = {}; 51 | 52 | //define update even in native-mq-supporting browsers, to avoid errors 53 | respond.update = function(){}; 54 | 55 | //expose media query support flag for external use 56 | respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches; 57 | 58 | //if media queries are supported, exit here 59 | if( respond.mediaQueriesSupported ){ return; } 60 | 61 | //define vars 62 | var doc = win.document, 63 | docElem = doc.documentElement, 64 | mediastyles = [], 65 | rules = [], 66 | appendedEls = [], 67 | parsedSheets = {}, 68 | resizeThrottle = 30, 69 | head = doc.getElementsByTagName( "head" )[0] || docElem, 70 | base = doc.getElementsByTagName( "base" )[0], 71 | links = head.getElementsByTagName( "link" ), 72 | requestQueue = [], 73 | 74 | //loop stylesheets, send text content to translate 75 | ripCSS = function(){ 76 | var sheets = links, 77 | sl = sheets.length, 78 | i = 0, 79 | //vars for loop: 80 | sheet, href, media, isCSS; 81 | 82 | for( ; i < sl; i++ ){ 83 | sheet = sheets[ i ], 84 | href = sheet.href, 85 | media = sheet.media, 86 | isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; 87 | 88 | //only links plz and prevent re-parsing 89 | if( !!href && isCSS && !parsedSheets[ href ] ){ 90 | // selectivizr exposes css through the rawCssText expando 91 | if (sheet.styleSheet && sheet.styleSheet.rawCssText) { 92 | translate( sheet.styleSheet.rawCssText, href, media ); 93 | parsedSheets[ href ] = true; 94 | } else { 95 | if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) 96 | || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){ 97 | requestQueue.push( { 98 | href: href, 99 | media: media 100 | } ); 101 | } 102 | } 103 | } 104 | } 105 | makeRequests(); 106 | }, 107 | 108 | //recurse through request queue, get css text 109 | makeRequests = function(){ 110 | if( requestQueue.length ){ 111 | var thisRequest = requestQueue.shift(); 112 | 113 | ajax( thisRequest.href, function( styles ){ 114 | translate( styles, thisRequest.href, thisRequest.media ); 115 | parsedSheets[ thisRequest.href ] = true; 116 | makeRequests(); 117 | } ); 118 | } 119 | }, 120 | 121 | //find media blocks in css text, convert to style blocks 122 | translate = function( styles, href, media ){ 123 | var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ), 124 | ql = qs && qs.length || 0, 125 | //try to get CSS path 126 | href = href.substring( 0, href.lastIndexOf( "/" )), 127 | repUrls = function( css ){ 128 | return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" ); 129 | }, 130 | useMedia = !ql && media, 131 | //vars used in loop 132 | i = 0, 133 | j, fullq, thisq, eachq, eql; 134 | 135 | //if path exists, tack on trailing slash 136 | if( href.length ){ href += "/"; } 137 | 138 | //if no internal queries exist, but media attr does, use that 139 | //note: this currently lacks support for situations where a media attr is specified on a link AND 140 | //its associated stylesheet has internal CSS media queries. 141 | //In those cases, the media attribute will currently be ignored. 142 | if( useMedia ){ 143 | ql = 1; 144 | } 145 | 146 | 147 | for( ; i < ql; i++ ){ 148 | j = 0; 149 | 150 | //media attr 151 | if( useMedia ){ 152 | fullq = media; 153 | rules.push( repUrls( styles ) ); 154 | } 155 | //parse for styles 156 | else{ 157 | fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1; 158 | rules.push( RegExp.$2 && repUrls( RegExp.$2 ) ); 159 | } 160 | 161 | eachq = fullq.split( "," ); 162 | eql = eachq.length; 163 | 164 | for( ; j < eql; j++ ){ 165 | thisq = eachq[ j ]; 166 | mediastyles.push( { 167 | media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all", 168 | rules : rules.length - 1, 169 | hasquery: thisq.indexOf("(") > -1, 170 | minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 171 | maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ) 172 | } ); 173 | } 174 | } 175 | 176 | applyMedia(); 177 | }, 178 | 179 | lastCall, 180 | 181 | resizeDefer, 182 | 183 | // returns the value of 1em in pixels 184 | getEmValue = function() { 185 | var ret, 186 | div = doc.createElement('div'), 187 | body = doc.body, 188 | fakeUsed = false; 189 | 190 | div.style.cssText = "position:absolute;font-size:1em;width:1em"; 191 | 192 | if( !body ){ 193 | body = fakeUsed = doc.createElement( "body" ); 194 | body.style.background = "none"; 195 | } 196 | 197 | body.appendChild( div ); 198 | 199 | docElem.insertBefore( body, docElem.firstChild ); 200 | 201 | ret = div.offsetWidth; 202 | 203 | if( fakeUsed ){ 204 | docElem.removeChild( body ); 205 | } 206 | else { 207 | body.removeChild( div ); 208 | } 209 | 210 | //also update eminpx before returning 211 | ret = eminpx = parseFloat(ret); 212 | 213 | return ret; 214 | }, 215 | 216 | //cached container for 1em value, populated the first time it's needed 217 | eminpx, 218 | 219 | //enable/disable styles 220 | applyMedia = function( fromResize ){ 221 | var name = "clientWidth", 222 | docElemProp = docElem[ name ], 223 | currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp, 224 | styleBlocks = {}, 225 | lastLink = links[ links.length-1 ], 226 | now = (new Date()).getTime(); 227 | 228 | //throttle resize calls 229 | if( fromResize && lastCall && now - lastCall < resizeThrottle ){ 230 | clearTimeout( resizeDefer ); 231 | resizeDefer = setTimeout( applyMedia, resizeThrottle ); 232 | return; 233 | } 234 | else { 235 | lastCall = now; 236 | } 237 | 238 | for( var i in mediastyles ){ 239 | var thisstyle = mediastyles[ i ], 240 | min = thisstyle.minw, 241 | max = thisstyle.maxw, 242 | minnull = min === null, 243 | maxnull = max === null, 244 | em = "em"; 245 | 246 | if( !!min ){ 247 | min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 248 | } 249 | if( !!max ){ 250 | max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 251 | } 252 | 253 | // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true 254 | if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){ 255 | if( !styleBlocks[ thisstyle.media ] ){ 256 | styleBlocks[ thisstyle.media ] = []; 257 | } 258 | styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] ); 259 | } 260 | } 261 | 262 | //remove any existing respond style element(s) 263 | for( var i in appendedEls ){ 264 | if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){ 265 | head.removeChild( appendedEls[ i ] ); 266 | } 267 | } 268 | 269 | //inject active styles, grouped by media type 270 | for( var i in styleBlocks ){ 271 | var ss = doc.createElement( "style" ), 272 | css = styleBlocks[ i ].join( "\n" ); 273 | 274 | ss.type = "text/css"; 275 | ss.media = i; 276 | 277 | //originally, ss was appended to a documentFragment and sheets were appended in bulk. 278 | //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one! 279 | head.insertBefore( ss, lastLink.nextSibling ); 280 | 281 | if ( ss.styleSheet ){ 282 | ss.styleSheet.cssText = css; 283 | } 284 | else { 285 | ss.appendChild( doc.createTextNode( css ) ); 286 | } 287 | 288 | //push to appendedEls to track for later removal 289 | appendedEls.push( ss ); 290 | } 291 | }, 292 | //tweaked Ajax functions from Quirksmode 293 | ajax = function( url, callback ) { 294 | var req = xmlHttp(); 295 | if (!req){ 296 | return; 297 | } 298 | req.open( "GET", url, true ); 299 | req.onreadystatechange = function () { 300 | if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){ 301 | return; 302 | } 303 | callback( req.responseText ); 304 | } 305 | if ( req.readyState == 4 ){ 306 | return; 307 | } 308 | req.send( null ); 309 | }, 310 | //define ajax obj 311 | xmlHttp = (function() { 312 | var xmlhttpmethod = false; 313 | try { 314 | xmlhttpmethod = new XMLHttpRequest(); 315 | } 316 | catch( e ){ 317 | xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" ); 318 | } 319 | return function(){ 320 | return xmlhttpmethod; 321 | }; 322 | })(); 323 | 324 | //translate CSS 325 | ripCSS(); 326 | 327 | //expose update for re-running respond later on 328 | respond.update = ripCSS; 329 | 330 | //adjust on resize 331 | function callMedia(){ 332 | applyMedia( true ); 333 | } 334 | if( win.addEventListener ){ 335 | win.addEventListener( "resize", callMedia, false ); 336 | } 337 | else if( win.attachEvent ){ 338 | win.attachEvent( "onresize", callMedia ); 339 | } 340 | })(this); 341 | -------------------------------------------------------------------------------- /app/static/app/scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); -------------------------------------------------------------------------------- /app/templates/app/index.html: -------------------------------------------------------------------------------- 1 | {% extends "app/layout.html" %} 2 | 3 | {% block content %} 4 | 5 | 12 | 13 | {% load static %} 14 |
    15 |
    16 | 17 | 22 | 23 |

    Build, deploy and scale applications faster

    24 |

    25 | Learn more 26 |

    27 |
    28 |
    29 | 30 |
    31 |

    Get started with App Service on Linux

    32 |
    33 |
    34 |
    35 |
    36 |
    37 | {% load static %} 38 | 39 |
    40 |

    Overview

    41 |
    42 | 50 |

    51 | Try for Free! 52 |

    53 |
    54 |
    55 | 56 |
    57 |
    58 | {% load static %} 59 | 60 |
    61 |

    Bring your own Docker Container

    62 |
    63 |
    64 | 71 |

    72 | WebCast 73 |

    74 |
    75 |
    76 | 77 |
    78 |
    79 | {% load static %} 80 | 81 |
    82 |

    Use Built-in images

    83 |
    84 | 92 |

    93 | Tutorial 94 |

    95 |
    96 |
    97 | 98 |
    99 |
    100 | {% load static %} 101 | 102 |
    103 |

    Samples and Resources

    104 |
    105 | 113 |

    114 | UserVoice 115 |

    116 |
    117 |
    118 | 119 |
    120 |
    121 | 122 |
    123 | 124 | {% endblock %} 125 | -------------------------------------------------------------------------------- /app/templates/app/layout.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Azure App Service 7 | {% load staticfiles %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 32 | 33 |
    34 | {% block content %}{% endblock %} 35 |
    36 |
    37 |

    © {{ year }} - Azure App Service

    38 |
    39 |
    40 | 41 | 42 | 43 | 44 | {% block scripts %}{% endblock %} 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates writing tests using the unittest module. These will pass 3 | when you run "manage.py test". 4 | """ 5 | 6 | import django 7 | from django.test import TestCase 8 | 9 | # TODO: Configure your database in settings.py and sync before running tests. 10 | 11 | class ViewTest(TestCase): 12 | """Tests for the application views.""" 13 | 14 | if django.VERSION[:2] >= (1, 7): 15 | # Django 1.7 requires an explicit setup() when running tests in PTVS 16 | @classmethod 17 | def setUpClass(cls): 18 | super(ViewTest, cls).setUpClass() 19 | django.setup() 20 | 21 | def test_home(self): 22 | """Tests the home page.""" 23 | response = self.client.get('/') 24 | self.assertContains(response, 'Home Page', 1, 200) 25 | 26 | def test_contact(self): 27 | """Tests the contact page.""" 28 | response = self.client.get('/contact') 29 | self.assertContains(response, 'Contact', 3, 200) 30 | 31 | def test_about(self): 32 | """Tests the about page.""" 33 | response = self.client.get('/about') 34 | self.assertContains(response, 'About', 3, 200) 35 | -------------------------------------------------------------------------------- /app/views.py: -------------------------------------------------------------------------------- 1 | """ 2 | Definition of views. 3 | """ 4 | 5 | from django.shortcuts import render 6 | from django.http import HttpRequest 7 | from django.template import RequestContext 8 | from datetime import datetime 9 | 10 | def home(request): 11 | """Renders the home page.""" 12 | assert isinstance(request, HttpRequest) 13 | return render( 14 | request, 15 | 'app/index.html', 16 | { 17 | 'title':'Home Page', 18 | 'year':datetime.now().year, 19 | } 20 | ) 21 | 22 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/db.sqlite3 -------------------------------------------------------------------------------- /djangoapp/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Package for djangoapp. 3 | """ 4 | -------------------------------------------------------------------------------- /djangoapp/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for djangoapp project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.9.1. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.9/ref/settings/ 11 | """ 12 | 13 | import os 14 | import posixpath 15 | 16 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 17 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = '9fe591ea-db8e-4192-9ffa-ab00cfe35a85' 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | ALLOWED_HOSTS = ['*'] 30 | 31 | 32 | # Application definition 33 | 34 | INSTALLED_APPS = [ 35 | 'app', 36 | # Add your apps here to enable them 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | ] 44 | 45 | MIDDLEWARE_CLASSES = [ 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 52 | 'django.contrib.messages.middleware.MessageMiddleware', 53 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 54 | ] 55 | 56 | ROOT_URLCONF = 'djangoapp.urls' 57 | 58 | TEMPLATES = [ 59 | { 60 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 61 | 'DIRS': [], 62 | 'APP_DIRS': True, 63 | 'OPTIONS': { 64 | 'context_processors': [ 65 | 'django.template.context_processors.debug', 66 | 'django.template.context_processors.request', 67 | 'django.contrib.auth.context_processors.auth', 68 | 'django.contrib.messages.context_processors.messages', 69 | ], 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = 'djangoapp.wsgi.application' 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 79 | 80 | DATABASES = { 81 | 'default': { 82 | 'ENGINE': 'django.db.backends.sqlite3', 83 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 84 | } 85 | } 86 | 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 103 | }, 104 | ] 105 | 106 | 107 | # Internationalization 108 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 109 | 110 | LANGUAGE_CODE = 'en-us' 111 | 112 | TIME_ZONE = 'UTC' 113 | 114 | USE_I18N = True 115 | 116 | USE_L10N = True 117 | 118 | USE_TZ = True 119 | 120 | 121 | # Static files (CSS, JavaScript, Images) 122 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 123 | 124 | STATIC_URL = '/static/' 125 | 126 | STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static'])) 127 | -------------------------------------------------------------------------------- /djangoapp/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | Definition of urls for djangoapp. 3 | """ 4 | 5 | from datetime import datetime 6 | from django.conf.urls import url 7 | import django.contrib.auth.views 8 | 9 | import app.forms 10 | import app.views 11 | 12 | # Uncomment the next lines to enable the admin: 13 | # from django.conf.urls import include 14 | # from django.contrib import admin 15 | # admin.autodiscover() 16 | 17 | urlpatterns = [ 18 | # Examples: 19 | url(r'^$', app.views.home, name='home'), 20 | # Uncomment the admin/doc line below to enable admin documentation: 21 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 22 | 23 | # Uncomment the next line to enable the admin: 24 | # url(r'^admin/', include(admin.site.urls)), 25 | ] 26 | -------------------------------------------------------------------------------- /djangoapp/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for djangoapp project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoapp.settings") 19 | 20 | # This application object is used by any WSGI server configured to use this 21 | # file. This includes Django's development server, if the WSGI_APPLICATION 22 | # setting points here. 23 | from django.core.wsgi import get_wsgi_application 24 | application = get_wsgi_application() 25 | 26 | # Apply WSGI middleware here. 27 | # from helloworld.wsgi import HelloWorldApplication 28 | # application = HelloWorldApplication(application) 29 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo "Starting SSH ..." 5 | service ssh start 6 | 7 | python /code/manage.py runserver 0.0.0.0:8000 8 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Command-line utility for administrative tasks. 4 | """ 5 | 6 | import os 7 | import sys 8 | 9 | if __name__ == "__main__": 10 | os.environ.setdefault( 11 | "DJANGO_SETTINGS_MODULE", 12 | "djangoapp.settings" 13 | ) 14 | 15 | from django.core.management import execute_from_command_line 16 | 17 | execute_from_command_line(sys.argv) 18 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django >=1.9, <2 2 | -------------------------------------------------------------------------------- /sshd_config: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/ssh/sshd_config 3 | # 4 | 5 | Port 2222 6 | ListenAddress 0.0.0.0 7 | LoginGraceTime 180 8 | X11Forwarding yes 9 | Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr 10 | MACs hmac-sha1,hmac-sha1-96 11 | StrictModes yes 12 | SyslogFacility DAEMON 13 | PasswordAuthentication yes 14 | PermitEmptyPasswords no 15 | PermitRootLogin yes -------------------------------------------------------------------------------- /static/admin/css/changelists.css: -------------------------------------------------------------------------------- 1 | /* CHANGELISTS */ 2 | 3 | #changelist { 4 | position: relative; 5 | width: 100%; 6 | } 7 | 8 | #changelist table { 9 | width: 100%; 10 | } 11 | 12 | .change-list .hiddenfields { display:none; } 13 | 14 | .change-list .filtered table { 15 | border-right: none; 16 | } 17 | 18 | .change-list .filtered { 19 | min-height: 400px; 20 | } 21 | 22 | .change-list .filtered .results, .change-list .filtered .paginator, 23 | .filtered #toolbar, .filtered div.xfull { 24 | margin-right: 280px; 25 | width: auto; 26 | } 27 | 28 | .change-list .filtered table tbody th { 29 | padding-right: 1em; 30 | } 31 | 32 | #changelist-form .results { 33 | overflow-x: auto; 34 | } 35 | 36 | #changelist .toplinks { 37 | border-bottom: 1px solid #ddd; 38 | } 39 | 40 | #changelist .paginator { 41 | color: #666; 42 | border-bottom: 1px solid #eee; 43 | background: #fff; 44 | overflow: hidden; 45 | } 46 | 47 | /* CHANGELIST TABLES */ 48 | 49 | #changelist table thead th { 50 | padding: 0; 51 | white-space: nowrap; 52 | vertical-align: middle; 53 | } 54 | 55 | #changelist table thead th.action-checkbox-column { 56 | width: 1.5em; 57 | text-align: center; 58 | } 59 | 60 | #changelist table tbody td.action-checkbox { 61 | text-align: center; 62 | } 63 | 64 | #changelist table tfoot { 65 | color: #666; 66 | } 67 | 68 | /* TOOLBAR */ 69 | 70 | #changelist #toolbar { 71 | padding: 8px 10px; 72 | margin-bottom: 15px; 73 | border-top: 1px solid #eee; 74 | border-bottom: 1px solid #eee; 75 | background: #f8f8f8; 76 | color: #666; 77 | } 78 | 79 | #changelist #toolbar form input { 80 | border-radius: 4px; 81 | font-size: 14px; 82 | padding: 5px; 83 | color: #333; 84 | } 85 | 86 | #changelist #toolbar form #searchbar { 87 | height: 19px; 88 | border: 1px solid #ccc; 89 | padding: 2px 5px; 90 | margin: 0; 91 | vertical-align: top; 92 | font-size: 13px; 93 | } 94 | 95 | #changelist #toolbar form #searchbar:focus { 96 | border-color: #999; 97 | } 98 | 99 | #changelist #toolbar form input[type="submit"] { 100 | border: 1px solid #ccc; 101 | padding: 2px 10px; 102 | margin: 0; 103 | vertical-align: middle; 104 | background: #fff; 105 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; 106 | cursor: pointer; 107 | color: #333; 108 | } 109 | 110 | #changelist #toolbar form input[type="submit"]:focus, 111 | #changelist #toolbar form input[type="submit"]:hover { 112 | border-color: #999; 113 | } 114 | 115 | #changelist #changelist-search img { 116 | vertical-align: middle; 117 | margin-right: 4px; 118 | } 119 | 120 | /* FILTER COLUMN */ 121 | 122 | #changelist-filter { 123 | position: absolute; 124 | top: 0; 125 | right: 0; 126 | z-index: 1000; 127 | width: 240px; 128 | background: #f8f8f8; 129 | border-left: none; 130 | margin: 0; 131 | } 132 | 133 | #changelist-filter h2 { 134 | font-size: 14px; 135 | text-transform: uppercase; 136 | letter-spacing: 0.5px; 137 | padding: 5px 15px; 138 | margin-bottom: 12px; 139 | border-bottom: none; 140 | } 141 | 142 | #changelist-filter h3 { 143 | font-weight: 400; 144 | font-size: 14px; 145 | padding: 0 15px; 146 | margin-bottom: 10px; 147 | } 148 | 149 | #changelist-filter ul { 150 | margin: 5px 0; 151 | padding: 0 15px 15px; 152 | border-bottom: 1px solid #eaeaea; 153 | } 154 | 155 | #changelist-filter ul:last-child { 156 | border-bottom: none; 157 | padding-bottom: none; 158 | } 159 | 160 | #changelist-filter li { 161 | list-style-type: none; 162 | margin-left: 0; 163 | padding-left: 0; 164 | } 165 | 166 | #changelist-filter a { 167 | display: block; 168 | color: #999; 169 | text-overflow: ellipsis; 170 | overflow-x: hidden; 171 | } 172 | 173 | #changelist-filter li.selected { 174 | border-left: 5px solid #eaeaea; 175 | padding-left: 10px; 176 | margin-left: -15px; 177 | } 178 | 179 | #changelist-filter li.selected a { 180 | color: #5b80b2; 181 | } 182 | 183 | #changelist-filter a:focus, #changelist-filter a:hover, 184 | #changelist-filter li.selected a:focus, 185 | #changelist-filter li.selected a:hover { 186 | color: #036; 187 | } 188 | 189 | /* DATE DRILLDOWN */ 190 | 191 | .change-list ul.toplinks { 192 | display: block; 193 | float: left; 194 | padding: 0; 195 | margin: 0; 196 | width: 100%; 197 | } 198 | 199 | .change-list ul.toplinks li { 200 | padding: 3px 6px; 201 | font-weight: bold; 202 | list-style-type: none; 203 | display: inline-block; 204 | } 205 | 206 | .change-list ul.toplinks .date-back a { 207 | color: #999; 208 | } 209 | 210 | .change-list ul.toplinks .date-back a:focus, 211 | .change-list ul.toplinks .date-back a:hover { 212 | color: #036; 213 | } 214 | 215 | /* PAGINATOR */ 216 | 217 | .paginator { 218 | font-size: 13px; 219 | padding-top: 10px; 220 | padding-bottom: 10px; 221 | line-height: 22px; 222 | margin: 0; 223 | border-top: 1px solid #ddd; 224 | } 225 | 226 | .paginator a:link, .paginator a:visited { 227 | padding: 2px 6px; 228 | background: #79aec8; 229 | text-decoration: none; 230 | color: #fff; 231 | } 232 | 233 | .paginator a.showall { 234 | padding: 0; 235 | border: none; 236 | background: none; 237 | color: #5b80b2; 238 | } 239 | 240 | .paginator a.showall:focus, .paginator a.showall:hover { 241 | background: none; 242 | color: #036; 243 | } 244 | 245 | .paginator .end { 246 | margin-right: 6px; 247 | } 248 | 249 | .paginator .this-page { 250 | padding: 2px 6px; 251 | font-weight: bold; 252 | font-size: 13px; 253 | vertical-align: top; 254 | } 255 | 256 | .paginator a:focus, .paginator a:hover { 257 | color: white; 258 | background: #036; 259 | } 260 | 261 | /* ACTIONS */ 262 | 263 | .filtered .actions { 264 | margin-right: 280px; 265 | border-right: none; 266 | } 267 | 268 | #changelist table input { 269 | margin: 0; 270 | vertical-align: baseline; 271 | } 272 | 273 | #changelist table tbody tr.selected { 274 | background-color: #FFFFCC; 275 | } 276 | 277 | #changelist .actions { 278 | padding: 10px; 279 | background: #fff; 280 | border-top: none; 281 | border-bottom: none; 282 | line-height: 24px; 283 | color: #999; 284 | } 285 | 286 | #changelist .actions.selected { 287 | background: #fffccf; 288 | border-top: 1px solid #fffee8; 289 | border-bottom: 1px solid #edecd6; 290 | } 291 | 292 | #changelist .actions span.all, 293 | #changelist .actions span.action-counter, 294 | #changelist .actions span.clear, 295 | #changelist .actions span.question { 296 | font-size: 13px; 297 | margin: 0 0.5em; 298 | display: none; 299 | } 300 | 301 | #changelist .actions:last-child { 302 | border-bottom: none; 303 | } 304 | 305 | #changelist .actions select { 306 | vertical-align: top; 307 | height: 24px; 308 | background: none; 309 | color: #000; 310 | border: 1px solid #ccc; 311 | border-radius: 4px; 312 | font-size: 14px; 313 | padding: 0 0 0 4px; 314 | margin: 0; 315 | margin-left: 10px; 316 | } 317 | 318 | #changelist .actions select:focus { 319 | border-color: #999; 320 | } 321 | 322 | #changelist .actions label { 323 | display: inline-block; 324 | vertical-align: middle; 325 | font-size: 13px; 326 | } 327 | 328 | #changelist .actions .button { 329 | font-size: 13px; 330 | border: 1px solid #ccc; 331 | border-radius: 4px; 332 | background: #fff; 333 | box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; 334 | cursor: pointer; 335 | height: 24px; 336 | line-height: 1; 337 | padding: 4px 8px; 338 | margin: 0; 339 | color: #333; 340 | } 341 | 342 | #changelist .actions .button:focus, #changelist .actions .button:hover { 343 | border-color: #999; 344 | } 345 | -------------------------------------------------------------------------------- /static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | overflow: hidden; 25 | text-overflow: ellipsis; 26 | -o-text-overflow: ellipsis; 27 | } 28 | -------------------------------------------------------------------------------- /static/admin/css/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Roboto'; 3 | src: url('../fonts/Roboto-Bold-webfont.woff'); 4 | font-weight: 700; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'Roboto'; 10 | src: url('../fonts/Roboto-Regular-webfont.woff'); 11 | font-weight: 400; 12 | font-style: normal; 13 | } 14 | 15 | @font-face { 16 | font-family: 'Roboto'; 17 | src: url('../fonts/Roboto-Light-webfont.woff'); 18 | font-weight: 300; 19 | font-style: normal; 20 | } 21 | -------------------------------------------------------------------------------- /static/admin/css/forms.css: -------------------------------------------------------------------------------- 1 | @import url('widgets.css'); 2 | 3 | /* FORM ROWS */ 4 | 5 | .form-row { 6 | overflow: hidden; 7 | padding: 10px; 8 | font-size: 13px; 9 | border-bottom: 1px solid #eee; 10 | } 11 | 12 | .form-row img, .form-row input { 13 | vertical-align: middle; 14 | } 15 | 16 | .form-row label input[type="checkbox"] { 17 | margin-top: 0; 18 | vertical-align: 0; 19 | } 20 | 21 | form .form-row p { 22 | padding-left: 0; 23 | } 24 | 25 | .hidden { 26 | display: none; 27 | } 28 | 29 | /* FORM LABELS */ 30 | 31 | label { 32 | font-weight: normal; 33 | color: #666; 34 | font-size: 13px; 35 | } 36 | 37 | .required label, label.required { 38 | font-weight: bold; 39 | color: #333; 40 | } 41 | 42 | /* RADIO BUTTONS */ 43 | 44 | form ul.radiolist li { 45 | list-style-type: none; 46 | } 47 | 48 | form ul.radiolist label { 49 | float: none; 50 | display: inline; 51 | } 52 | 53 | form ul.radiolist input[type="radio"] { 54 | margin: -2px 4px 0 0; 55 | padding: 0; 56 | } 57 | 58 | form ul.inline { 59 | margin-left: 0; 60 | padding: 0; 61 | } 62 | 63 | form ul.inline li { 64 | float: left; 65 | padding-right: 7px; 66 | } 67 | 68 | /* ALIGNED FIELDSETS */ 69 | 70 | .aligned label { 71 | display: block; 72 | padding: 4px 10px 0 0; 73 | float: left; 74 | width: 160px; 75 | word-wrap: break-word; 76 | line-height: 1; 77 | } 78 | 79 | .aligned label:not(.vCheckboxLabel):after { 80 | content: ''; 81 | display: inline-block; 82 | vertical-align: middle; 83 | height: 26px; 84 | } 85 | 86 | .aligned label + p, .aligned label + div.help, .aligned label + div.readonly { 87 | padding: 6px 0; 88 | margin-top: 0; 89 | margin-bottom: 0; 90 | margin-left: 170px; 91 | } 92 | 93 | .aligned ul label { 94 | display: inline; 95 | float: none; 96 | width: auto; 97 | } 98 | 99 | .aligned .form-row input { 100 | margin-bottom: 0; 101 | } 102 | 103 | .colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { 104 | width: 350px; 105 | } 106 | 107 | form .aligned ul { 108 | margin-left: 160px; 109 | padding-left: 10px; 110 | } 111 | 112 | form .aligned ul.radiolist { 113 | display: inline-block; 114 | margin: 0; 115 | padding: 0; 116 | } 117 | 118 | form .aligned p.help, 119 | form .aligned div.help { 120 | clear: left; 121 | margin-top: 0; 122 | margin-left: 160px; 123 | padding-left: 10px; 124 | } 125 | 126 | form .aligned label + p.help, 127 | form .aligned label + div.help { 128 | margin-left: 0; 129 | padding-left: 0; 130 | } 131 | 132 | form .aligned p.help:last-child, 133 | form .aligned div.help:last-child { 134 | margin-bottom: 0; 135 | padding-bottom: 0; 136 | } 137 | 138 | form .aligned input + p.help, 139 | form .aligned textarea + p.help, 140 | form .aligned select + p.help, 141 | form .aligned input + div.help, 142 | form .aligned textarea + div.help, 143 | form .aligned select + div.help { 144 | margin-left: 160px; 145 | padding-left: 10px; 146 | } 147 | 148 | form .aligned ul li { 149 | list-style: none; 150 | } 151 | 152 | form .aligned table p { 153 | margin-left: 0; 154 | padding-left: 0; 155 | } 156 | 157 | .aligned .vCheckboxLabel { 158 | float: none; 159 | width: auto; 160 | display: inline-block; 161 | vertical-align: -3px; 162 | padding: 0 0 5px 5px; 163 | } 164 | 165 | .aligned .vCheckboxLabel + p.help, 166 | .aligned .vCheckboxLabel + div.help { 167 | margin-top: -4px; 168 | } 169 | 170 | .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { 171 | width: 610px; 172 | } 173 | 174 | .checkbox-row p.help, 175 | .checkbox-row div.help { 176 | margin-left: 0; 177 | padding-left: 0; 178 | } 179 | 180 | fieldset .field-box { 181 | float: left; 182 | margin-right: 20px; 183 | } 184 | 185 | /* WIDE FIELDSETS */ 186 | 187 | .wide label { 188 | width: 200px; 189 | } 190 | 191 | form .wide p, 192 | form .wide input + p.help, 193 | form .wide input + div.help { 194 | margin-left: 200px; 195 | } 196 | 197 | form .wide p.help, 198 | form .wide div.help { 199 | padding-left: 38px; 200 | } 201 | 202 | form div.help ul { 203 | padding-left: 0; 204 | margin-left: 0; 205 | } 206 | 207 | .colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { 208 | width: 450px; 209 | } 210 | 211 | /* COLLAPSED FIELDSETS */ 212 | 213 | fieldset.collapsed * { 214 | display: none; 215 | } 216 | 217 | fieldset.collapsed h2, fieldset.collapsed { 218 | display: block; 219 | } 220 | 221 | fieldset.collapsed { 222 | border: 1px solid #eee; 223 | border-radius: 4px; 224 | overflow: hidden; 225 | } 226 | 227 | fieldset.collapsed h2 { 228 | background: #f8f8f8; 229 | color: #666; 230 | } 231 | 232 | fieldset .collapse-toggle { 233 | color: #fff; 234 | } 235 | 236 | fieldset.collapsed .collapse-toggle { 237 | background: transparent; 238 | display: inline; 239 | color: #447e9b; 240 | } 241 | 242 | /* MONOSPACE TEXTAREAS */ 243 | 244 | fieldset.monospace textarea { 245 | font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; 246 | } 247 | 248 | /* SUBMIT ROW */ 249 | 250 | .submit-row { 251 | padding: 12px 14px; 252 | margin: 0 0 20px; 253 | background: #f8f8f8; 254 | border: 1px solid #eee; 255 | border-radius: 4px; 256 | text-align: right; 257 | overflow: hidden; 258 | } 259 | 260 | body.popup .submit-row { 261 | overflow: auto; 262 | } 263 | 264 | .submit-row input { 265 | height: 35px; 266 | line-height: 15px; 267 | margin: 0 0 0 5px; 268 | } 269 | 270 | .submit-row input.default { 271 | margin: 0 0 0 8px; 272 | text-transform: uppercase; 273 | } 274 | 275 | .submit-row p { 276 | margin: 0.3em; 277 | } 278 | 279 | .submit-row p.deletelink-box { 280 | float: left; 281 | margin: 0; 282 | } 283 | 284 | .submit-row a.deletelink { 285 | display: block; 286 | background: #ba2121; 287 | border-radius: 4px; 288 | padding: 10px 15px; 289 | height: 15px; 290 | line-height: 15px; 291 | color: #fff; 292 | } 293 | 294 | .submit-row a.deletelink:focus, 295 | .submit-row a.deletelink:hover, 296 | .submit-row a.deletelink:active { 297 | background: #a41515; 298 | } 299 | 300 | /* CUSTOM FORM FIELDS */ 301 | 302 | .vSelectMultipleField { 303 | vertical-align: top; 304 | } 305 | 306 | .vCheckboxField { 307 | border: none; 308 | } 309 | 310 | .vDateField, .vTimeField { 311 | margin-right: 2px; 312 | margin-bottom: 4px; 313 | } 314 | 315 | .vDateField { 316 | min-width: 6.85em; 317 | } 318 | 319 | .vTimeField { 320 | min-width: 4.7em; 321 | } 322 | 323 | .vURLField { 324 | width: 30em; 325 | } 326 | 327 | .vLargeTextField, .vXMLLargeTextField { 328 | width: 48em; 329 | } 330 | 331 | .flatpages-flatpage #id_content { 332 | height: 40.2em; 333 | } 334 | 335 | .module table .vPositiveSmallIntegerField { 336 | width: 2.2em; 337 | } 338 | 339 | .vTextField { 340 | width: 20em; 341 | } 342 | 343 | .vIntegerField { 344 | width: 5em; 345 | } 346 | 347 | .vBigIntegerField { 348 | width: 10em; 349 | } 350 | 351 | .vForeignKeyRawIdAdminField { 352 | width: 5em; 353 | } 354 | 355 | /* INLINES */ 356 | 357 | .inline-group { 358 | padding: 0; 359 | margin: 0 0 30px; 360 | } 361 | 362 | .inline-group thead th { 363 | padding: 8px 10px; 364 | } 365 | 366 | .inline-group .aligned label { 367 | width: 160px; 368 | } 369 | 370 | .inline-related { 371 | position: relative; 372 | } 373 | 374 | .inline-related h3 { 375 | margin: 0; 376 | color: #666; 377 | padding: 5px; 378 | font-size: 13px; 379 | background: #f8f8f8; 380 | border-top: 1px solid #eee; 381 | border-bottom: 1px solid #eee; 382 | } 383 | 384 | .inline-related h3 span.delete { 385 | float: right; 386 | } 387 | 388 | .inline-related h3 span.delete label { 389 | margin-left: 2px; 390 | font-size: 11px; 391 | } 392 | 393 | .inline-related fieldset { 394 | margin: 0; 395 | background: #fff; 396 | border: none; 397 | width: 100%; 398 | } 399 | 400 | .inline-related fieldset.module h3 { 401 | margin: 0; 402 | padding: 2px 5px 3px 5px; 403 | font-size: 11px; 404 | text-align: left; 405 | font-weight: bold; 406 | background: #bcd; 407 | color: #fff; 408 | } 409 | 410 | .inline-group .tabular fieldset.module { 411 | border: none; 412 | } 413 | 414 | .inline-related.tabular fieldset.module table { 415 | width: 100%; 416 | } 417 | 418 | .last-related fieldset { 419 | border: none; 420 | } 421 | 422 | .inline-group .tabular tr.has_original td { 423 | padding-top: 2em; 424 | } 425 | 426 | .inline-group .tabular tr td.original { 427 | padding: 2px 0 0 0; 428 | width: 0; 429 | _position: relative; 430 | } 431 | 432 | .inline-group .tabular th.original { 433 | width: 0px; 434 | padding: 0; 435 | } 436 | 437 | .inline-group .tabular td.original p { 438 | position: absolute; 439 | left: 0; 440 | height: 1.1em; 441 | padding: 2px 9px; 442 | overflow: hidden; 443 | font-size: 9px; 444 | font-weight: bold; 445 | color: #666; 446 | _width: 700px; 447 | } 448 | 449 | .inline-group ul.tools { 450 | padding: 0; 451 | margin: 0; 452 | list-style: none; 453 | } 454 | 455 | .inline-group ul.tools li { 456 | display: inline; 457 | padding: 0 5px; 458 | } 459 | 460 | .inline-group div.add-row, 461 | .inline-group .tabular tr.add-row td { 462 | color: #666; 463 | background: #f8f8f8; 464 | padding: 8px 10px; 465 | border-bottom: 1px solid #eee; 466 | } 467 | 468 | .inline-group .tabular tr.add-row td { 469 | padding: 8px 10px; 470 | border-bottom: 1px solid #eee; 471 | } 472 | 473 | .inline-group ul.tools a.add, 474 | .inline-group div.add-row a, 475 | .inline-group .tabular tr.add-row td a { 476 | background: url(../img/icon-addlink.svg) 0 1px no-repeat; 477 | padding-left: 16px; 478 | font-size: 12px; 479 | } 480 | 481 | .empty-form { 482 | display: none; 483 | } 484 | 485 | /* RELATED FIELD ADD ONE / LOOKUP */ 486 | 487 | .add-another, .related-lookup { 488 | margin-left: 5px; 489 | display: inline-block; 490 | vertical-align: middle; 491 | background-repeat: no-repeat; 492 | background-size: 14px; 493 | } 494 | 495 | .add-another { 496 | width: 16px; 497 | height: 16px; 498 | background-image: url(../img/icon-addlink.svg); 499 | } 500 | 501 | .related-lookup { 502 | width: 16px; 503 | height: 16px; 504 | background-image: url(../img/search.svg); 505 | } 506 | 507 | form .related-widget-wrapper ul { 508 | display: inline-block; 509 | margin-left: 0; 510 | padding-left: 0; 511 | } 512 | 513 | .clearable-file-input input { 514 | margin-top: 0; 515 | } 516 | -------------------------------------------------------------------------------- /static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #f8f8f8; 5 | } 6 | 7 | .login #header { 8 | height: auto; 9 | padding: 5px 16px; 10 | } 11 | 12 | .login #header h1 { 13 | font-size: 18px; 14 | } 15 | 16 | .login #header h1 a { 17 | color: #fff; 18 | } 19 | 20 | .login #content { 21 | padding: 20px 20px 0; 22 | } 23 | 24 | .login #container { 25 | background: #fff; 26 | border: 1px solid #eaeaea; 27 | border-radius: 4px; 28 | overflow: hidden; 29 | width: 28em; 30 | min-width: 300px; 31 | margin: 100px auto; 32 | } 33 | 34 | .login #content-main { 35 | width: 100%; 36 | } 37 | 38 | .login .form-row { 39 | padding: 4px 0; 40 | float: left; 41 | width: 100%; 42 | border-bottom: none; 43 | } 44 | 45 | .login .form-row label { 46 | padding-right: 0.5em; 47 | line-height: 2em; 48 | font-size: 1em; 49 | clear: both; 50 | color: #333; 51 | } 52 | 53 | .login .form-row #id_username, .login .form-row #id_password { 54 | clear: both; 55 | padding: 8px; 56 | width: 100%; 57 | -webkit-box-sizing: border-box; 58 | -moz-box-sizing: border-box; 59 | box-sizing: border-box; 60 | } 61 | 62 | .login span.help { 63 | font-size: 10px; 64 | display: block; 65 | } 66 | 67 | .login .submit-row { 68 | clear: both; 69 | padding: 1em 0 0 9.4em; 70 | margin: 0; 71 | border: none; 72 | background: none; 73 | text-align: left; 74 | } 75 | 76 | .login .password-reset-link { 77 | text-align: center; 78 | } 79 | -------------------------------------------------------------------------------- /static/admin/css/rtl.css: -------------------------------------------------------------------------------- 1 | body { 2 | direction: rtl; 3 | } 4 | 5 | /* LOGIN */ 6 | 7 | .login .form-row { 8 | float: right; 9 | } 10 | 11 | .login .form-row label { 12 | float: right; 13 | padding-left: 0.5em; 14 | padding-right: 0; 15 | text-align: left; 16 | } 17 | 18 | .login .submit-row { 19 | clear: both; 20 | padding: 1em 9.4em 0 0; 21 | } 22 | 23 | /* GLOBAL */ 24 | 25 | th { 26 | text-align: right; 27 | } 28 | 29 | .module h2, .module caption { 30 | text-align: right; 31 | } 32 | 33 | .module ul, .module ol { 34 | margin-left: 0; 35 | margin-right: 1.5em; 36 | } 37 | 38 | .addlink, .changelink { 39 | padding-left: 0; 40 | padding-right: 16px; 41 | background-position: 100% 1px; 42 | } 43 | 44 | .deletelink { 45 | padding-left: 0; 46 | padding-right: 16px; 47 | background-position: 100% 1px; 48 | } 49 | 50 | .object-tools { 51 | float: left; 52 | } 53 | 54 | thead th:first-child, 55 | tfoot td:first-child { 56 | border-left: none; 57 | } 58 | 59 | /* LAYOUT */ 60 | 61 | #user-tools { 62 | right: auto; 63 | left: 0; 64 | text-align: left; 65 | } 66 | 67 | div.breadcrumbs { 68 | text-align: right; 69 | } 70 | 71 | #content-main { 72 | float: right; 73 | } 74 | 75 | #content-related { 76 | float: left; 77 | margin-left: -300px; 78 | margin-right: auto; 79 | } 80 | 81 | .colMS { 82 | margin-left: 300px; 83 | margin-right: 0; 84 | } 85 | 86 | /* SORTABLE TABLES */ 87 | 88 | table thead th.sorted .sortoptions { 89 | float: left; 90 | } 91 | 92 | thead th.sorted .text { 93 | padding-right: 0; 94 | padding-left: 42px; 95 | } 96 | 97 | /* dashboard styles */ 98 | 99 | .dashboard .module table td a { 100 | padding-left: .6em; 101 | padding-right: 16px; 102 | } 103 | 104 | /* changelists styles */ 105 | 106 | .change-list .filtered table { 107 | border-left: none; 108 | border-right: 0px none; 109 | } 110 | 111 | #changelist-filter { 112 | right: auto; 113 | left: 0; 114 | border-left: none; 115 | border-right: none; 116 | } 117 | 118 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 119 | margin-right: 0; 120 | margin-left: 280px; 121 | } 122 | 123 | #changelist-filter li.selected { 124 | border-left: none; 125 | padding-left: 10px; 126 | margin-left: 0; 127 | border-right: 5px solid #eaeaea; 128 | padding-right: 10px; 129 | margin-right: -15px; 130 | } 131 | 132 | .filtered .actions { 133 | margin-left: 280px; 134 | margin-right: 0; 135 | } 136 | 137 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 138 | border-right: none; 139 | border-left: none; 140 | } 141 | 142 | /* FORMS */ 143 | 144 | .aligned label { 145 | padding: 0 0 3px 1em; 146 | float: right; 147 | } 148 | 149 | .submit-row { 150 | text-align: left 151 | } 152 | 153 | .submit-row p.deletelink-box { 154 | float: right; 155 | } 156 | 157 | .submit-row input.default { 158 | margin-left: 0; 159 | } 160 | 161 | .vDateField, .vTimeField { 162 | margin-left: 2px; 163 | } 164 | 165 | .aligned .form-row input { 166 | margin-left: 5px; 167 | } 168 | 169 | form .aligned p.help, form .aligned div.help { 170 | clear: right; 171 | } 172 | 173 | form ul.inline li { 174 | float: right; 175 | padding-right: 0; 176 | padding-left: 7px; 177 | } 178 | 179 | input[type=submit].default, .submit-row input.default { 180 | float: left; 181 | } 182 | 183 | fieldset .field-box { 184 | float: right; 185 | margin-left: 20px; 186 | margin-right: 0; 187 | } 188 | 189 | .errorlist li { 190 | background-position: 100% 12px; 191 | padding: 0; 192 | } 193 | 194 | .errornote { 195 | background-position: 100% 12px; 196 | padding: 10px 12px; 197 | } 198 | 199 | /* WIDGETS */ 200 | 201 | .calendarnav-previous { 202 | top: 0; 203 | left: auto; 204 | right: 10px; 205 | } 206 | 207 | .calendarnav-next { 208 | top: 0; 209 | right: auto; 210 | left: 10px; 211 | } 212 | 213 | .calendar caption, .calendarbox h2 { 214 | text-align: center; 215 | } 216 | 217 | .selector { 218 | float: right; 219 | } 220 | 221 | .selector .selector-filter { 222 | text-align: right; 223 | } 224 | 225 | .inline-deletelink { 226 | float: left; 227 | } 228 | 229 | form .form-row p.datetime { 230 | overflow: hidden; 231 | } 232 | 233 | .related-widget-wrapper { 234 | float: right; 235 | } 236 | 237 | /* MISC */ 238 | 239 | .inline-related h2, .inline-group h2 { 240 | text-align: right 241 | } 242 | 243 | .inline-related h3 span.delete { 244 | padding-right: 20px; 245 | padding-left: inherit; 246 | left: 10px; 247 | right: inherit; 248 | float:left; 249 | } 250 | 251 | .inline-related h3 span.delete label { 252 | margin-left: inherit; 253 | margin-right: 2px; 254 | } 255 | 256 | /* IE7 specific bug fixes */ 257 | 258 | div.colM { 259 | position: relative; 260 | } 261 | 262 | .submit-row input { 263 | float: left; 264 | } 265 | -------------------------------------------------------------------------------- /static/admin/css/widgets.css: -------------------------------------------------------------------------------- 1 | /* SELECTOR (FILTER INTERFACE) */ 2 | 3 | .selector { 4 | width: 800px; 5 | float: left; 6 | } 7 | 8 | .selector select { 9 | width: 380px; 10 | height: 17.2em; 11 | } 12 | 13 | .selector-available, .selector-chosen { 14 | float: left; 15 | width: 380px; 16 | text-align: center; 17 | margin-bottom: 5px; 18 | } 19 | 20 | .selector-chosen select { 21 | border-top: none; 22 | } 23 | 24 | .selector-available h2, .selector-chosen h2 { 25 | border: 1px solid #ccc; 26 | border-radius: 4px 4px 0 0; 27 | } 28 | 29 | .selector-chosen h2 { 30 | background: #79aec8; 31 | color: #fff; 32 | } 33 | 34 | .selector .selector-available h2 { 35 | background: #f8f8f8; 36 | color: #666; 37 | } 38 | 39 | .selector .selector-filter { 40 | background: white; 41 | border: 1px solid #ccc; 42 | border-width: 0 1px; 43 | padding: 8px; 44 | color: #999; 45 | font-size: 10px; 46 | margin: 0; 47 | text-align: left; 48 | } 49 | 50 | .selector .selector-filter label, 51 | .inline-group .aligned .selector .selector-filter label { 52 | float: left; 53 | margin: 7px 0 0; 54 | width: 18px; 55 | height: 18px; 56 | padding: 0; 57 | overflow: hidden; 58 | line-height: 1; 59 | } 60 | 61 | .selector .selector-available input { 62 | width: 320px; 63 | margin-left: 8px; 64 | } 65 | 66 | .selector ul.selector-chooser { 67 | float: left; 68 | width: 22px; 69 | background-color: #eee; 70 | border-radius: 10px; 71 | margin: 10em 5px 0 5px; 72 | padding: 0; 73 | } 74 | 75 | .selector-chooser li { 76 | margin: 0; 77 | padding: 3px; 78 | list-style-type: none; 79 | } 80 | 81 | .selector select { 82 | padding: 0 10px; 83 | margin: 0 0 10px; 84 | border-radius: 0 0 4px 4px; 85 | } 86 | 87 | .selector-add, .selector-remove { 88 | width: 16px; 89 | height: 16px; 90 | display: block; 91 | text-indent: -3000px; 92 | overflow: hidden; 93 | cursor: default; 94 | opacity: 0.3; 95 | } 96 | 97 | .active.selector-add, .active.selector-remove { 98 | opacity: 1; 99 | } 100 | 101 | .active.selector-add:hover, .active.selector-remove:hover { 102 | cursor: pointer; 103 | } 104 | 105 | .selector-add { 106 | background: url(../img/selector-icons.svg) 0 -96px no-repeat; 107 | } 108 | 109 | .active.selector-add:focus, .active.selector-add:hover { 110 | background-position: 0 -112px; 111 | } 112 | 113 | .selector-remove { 114 | background: url(../img/selector-icons.svg) 0 -64px no-repeat; 115 | } 116 | 117 | .active.selector-remove:focus, .active.selector-remove:hover { 118 | background-position: 0 -80px; 119 | } 120 | 121 | a.selector-chooseall, a.selector-clearall { 122 | display: inline-block; 123 | height: 16px; 124 | text-align: left; 125 | margin: 1px auto 3px; 126 | overflow: hidden; 127 | font-weight: bold; 128 | line-height: 16px; 129 | color: #666; 130 | text-decoration: none; 131 | opacity: 0.3; 132 | } 133 | 134 | a.active.selector-chooseall:focus, a.active.selector-clearall:focus, 135 | a.active.selector-chooseall:hover, a.active.selector-clearall:hover { 136 | color: #447e9b; 137 | } 138 | 139 | a.active.selector-chooseall, a.active.selector-clearall { 140 | opacity: 1; 141 | } 142 | 143 | a.active.selector-chooseall:hover, a.active.selector-clearall:hover { 144 | cursor: pointer; 145 | } 146 | 147 | a.selector-chooseall { 148 | padding: 0 18px 0 0; 149 | background: url(../img/selector-icons.svg) right -160px no-repeat; 150 | cursor: default; 151 | } 152 | 153 | a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { 154 | background-position: 100% -176px; 155 | } 156 | 157 | a.selector-clearall { 158 | padding: 0 0 0 18px; 159 | background: url(../img/selector-icons.svg) 0 -128px no-repeat; 160 | cursor: default; 161 | } 162 | 163 | a.active.selector-clearall:focus, a.active.selector-clearall:hover { 164 | background-position: 0 -144px; 165 | } 166 | 167 | /* STACKED SELECTORS */ 168 | 169 | .stacked { 170 | float: left; 171 | width: 490px; 172 | } 173 | 174 | .stacked select { 175 | width: 480px; 176 | height: 10.1em; 177 | } 178 | 179 | .stacked .selector-available, .stacked .selector-chosen { 180 | width: 480px; 181 | } 182 | 183 | .stacked .selector-available { 184 | margin-bottom: 0; 185 | } 186 | 187 | .stacked .selector-available input { 188 | width: 422px; 189 | } 190 | 191 | .stacked ul.selector-chooser { 192 | height: 22px; 193 | width: 50px; 194 | margin: 0 0 10px 40%; 195 | background-color: #eee; 196 | border-radius: 10px; 197 | } 198 | 199 | .stacked .selector-chooser li { 200 | float: left; 201 | padding: 3px 3px 3px 5px; 202 | } 203 | 204 | .stacked .selector-chooseall, .stacked .selector-clearall { 205 | display: none; 206 | } 207 | 208 | .stacked .selector-add { 209 | background: url(../img/selector-icons.svg) 0 -32px no-repeat; 210 | cursor: default; 211 | } 212 | 213 | .stacked .active.selector-add { 214 | background-position: 0 -48px; 215 | cursor: pointer; 216 | } 217 | 218 | .stacked .selector-remove { 219 | background: url(../img/selector-icons.svg) 0 0 no-repeat; 220 | cursor: default; 221 | } 222 | 223 | .stacked .active.selector-remove { 224 | background-position: 0 -16px; 225 | cursor: pointer; 226 | } 227 | 228 | .selector .help-icon { 229 | background: url(../img/icon-unknown.svg) 0 0 no-repeat; 230 | display: inline-block; 231 | vertical-align: middle; 232 | margin: -2px 0 0 2px; 233 | width: 13px; 234 | height: 13px; 235 | } 236 | 237 | .selector .selector-chosen .help-icon { 238 | background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat; 239 | } 240 | 241 | .selector .search-label-icon { 242 | background: url(../img/search.svg) 0 0 no-repeat; 243 | display: inline-block; 244 | height: 18px; 245 | width: 18px; 246 | } 247 | 248 | /* DATE AND TIME */ 249 | 250 | p.datetime { 251 | line-height: 20px; 252 | margin: 0; 253 | padding: 0; 254 | color: #666; 255 | font-weight: bold; 256 | } 257 | 258 | .datetime span { 259 | white-space: nowrap; 260 | font-weight: normal; 261 | font-size: 11px; 262 | color: #ccc; 263 | } 264 | 265 | .datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { 266 | min-width: 0; 267 | margin-left: 5px; 268 | margin-bottom: 4px; 269 | } 270 | 271 | table p.datetime { 272 | font-size: 11px; 273 | margin-left: 0; 274 | padding-left: 0; 275 | } 276 | 277 | .datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon { 278 | position: relative; 279 | display: inline-block; 280 | vertical-align: middle; 281 | height: 16px; 282 | width: 16px; 283 | overflow: hidden; 284 | } 285 | 286 | .datetimeshortcuts .clock-icon { 287 | background: url(../img/icon-clock.svg) 0 0 no-repeat; 288 | } 289 | 290 | .datetimeshortcuts a:focus .clock-icon, 291 | .datetimeshortcuts a:hover .clock-icon { 292 | background-position: 0 -16px; 293 | } 294 | 295 | .datetimeshortcuts .date-icon { 296 | background: url(../img/icon-calendar.svg) 0 0 no-repeat; 297 | top: -1px; 298 | } 299 | 300 | .datetimeshortcuts a:focus .date-icon, 301 | .datetimeshortcuts a:hover .date-icon { 302 | background-position: 0 -16px; 303 | } 304 | 305 | .timezonewarning { 306 | font-size: 11px; 307 | color: #999; 308 | } 309 | 310 | /* URL */ 311 | 312 | p.url { 313 | line-height: 20px; 314 | margin: 0; 315 | padding: 0; 316 | color: #666; 317 | font-size: 11px; 318 | font-weight: bold; 319 | } 320 | 321 | .url a { 322 | font-weight: normal; 323 | } 324 | 325 | /* FILE UPLOADS */ 326 | 327 | p.file-upload { 328 | line-height: 20px; 329 | margin: 0; 330 | padding: 0; 331 | color: #666; 332 | font-size: 11px; 333 | font-weight: bold; 334 | } 335 | 336 | .aligned p.file-upload { 337 | margin-left: 170px; 338 | } 339 | 340 | .file-upload a { 341 | font-weight: normal; 342 | } 343 | 344 | .file-upload .deletelink { 345 | margin-left: 5px; 346 | } 347 | 348 | span.clearable-file-input label { 349 | color: #333; 350 | font-size: 11px; 351 | display: inline; 352 | float: none; 353 | } 354 | 355 | /* CALENDARS & CLOCKS */ 356 | 357 | .calendarbox, .clockbox { 358 | margin: 5px auto; 359 | font-size: 12px; 360 | width: 19em; 361 | text-align: center; 362 | background: white; 363 | border: 1px solid #ddd; 364 | border-radius: 4px; 365 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); 366 | overflow: hidden; 367 | position: relative; 368 | } 369 | 370 | .clockbox { 371 | width: auto; 372 | } 373 | 374 | .calendar { 375 | margin: 0; 376 | padding: 0; 377 | } 378 | 379 | .calendar table { 380 | margin: 0; 381 | padding: 0; 382 | border-collapse: collapse; 383 | background: white; 384 | width: 100%; 385 | } 386 | 387 | .calendar caption, .calendarbox h2 { 388 | margin: 0; 389 | text-align: center; 390 | border-top: none; 391 | background: #f5dd5d; 392 | font-weight: 700; 393 | font-size: 12px; 394 | color: #333; 395 | } 396 | 397 | .calendar th { 398 | padding: 8px 5px; 399 | background: #f8f8f8; 400 | border-bottom: 1px solid #ddd; 401 | font-weight: 400; 402 | font-size: 12px; 403 | text-align: center; 404 | color: #666; 405 | } 406 | 407 | .calendar td { 408 | font-weight: 400; 409 | font-size: 12px; 410 | text-align: center; 411 | padding: 0; 412 | border-top: 1px solid #eee; 413 | border-bottom: none; 414 | } 415 | 416 | .calendar td.selected a { 417 | background: #79aec8; 418 | color: #fff; 419 | } 420 | 421 | .calendar td.nonday { 422 | background: #f8f8f8; 423 | } 424 | 425 | .calendar td.today a { 426 | font-weight: 700; 427 | } 428 | 429 | .calendar td a, .timelist a { 430 | display: block; 431 | font-weight: 400; 432 | padding: 6px; 433 | text-decoration: none; 434 | color: #444; 435 | } 436 | 437 | .calendar td a:focus, .timelist a:focus, 438 | .calendar td a:hover, .timelist a:hover { 439 | background: #79aec8; 440 | color: white; 441 | } 442 | 443 | .calendar td a:active, .timelist a:active { 444 | background: #417690; 445 | color: white; 446 | } 447 | 448 | .calendarnav { 449 | font-size: 10px; 450 | text-align: center; 451 | color: #ccc; 452 | margin: 0; 453 | padding: 1px 3px; 454 | } 455 | 456 | .calendarnav a:link, #calendarnav a:visited, 457 | #calendarnav a:focus, #calendarnav a:hover { 458 | color: #999; 459 | } 460 | 461 | .calendar-shortcuts { 462 | background: white; 463 | font-size: 11px; 464 | line-height: 11px; 465 | border-top: 1px solid #eee; 466 | padding: 8px 0; 467 | color: #ccc; 468 | } 469 | 470 | .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { 471 | display: block; 472 | position: absolute; 473 | top: 8px; 474 | width: 15px; 475 | height: 15px; 476 | text-indent: -9999px; 477 | padding: 0; 478 | } 479 | 480 | .calendarnav-previous { 481 | left: 10px; 482 | background: url(../img/calendar-icons.svg) 0 0 no-repeat; 483 | } 484 | 485 | .calendarbox .calendarnav-previous:focus, 486 | .calendarbox .calendarnav-previous:hover { 487 | background-position: 0 -15px; 488 | } 489 | 490 | .calendarnav-next { 491 | right: 10px; 492 | background: url(../img/calendar-icons.svg) 0 -30px no-repeat; 493 | } 494 | 495 | .calendarbox .calendarnav-next:focus, 496 | .calendarbox .calendarnav-next:hover { 497 | background-position: 0 -45px; 498 | } 499 | 500 | .calendar-cancel { 501 | margin: 0; 502 | padding: 4px 0; 503 | font-size: 12px; 504 | background: #eee; 505 | border-top: 1px solid #ddd; 506 | color: #333; 507 | } 508 | 509 | .calendar-cancel:focus, .calendar-cancel:hover { 510 | background: #ddd; 511 | } 512 | 513 | .calendar-cancel a { 514 | color: black; 515 | display: block; 516 | } 517 | 518 | ul.timelist, .timelist li { 519 | list-style-type: none; 520 | margin: 0; 521 | padding: 0; 522 | } 523 | 524 | .timelist a { 525 | padding: 2px; 526 | } 527 | 528 | /* EDIT INLINE */ 529 | 530 | .inline-deletelink { 531 | float: right; 532 | text-indent: -9999px; 533 | background: url(../img/inline-delete.svg) 0 0 no-repeat; 534 | width: 16px; 535 | height: 16px; 536 | border: 0px none; 537 | } 538 | 539 | .inline-deletelink:focus, .inline-deletelink:hover { 540 | cursor: pointer; 541 | } 542 | 543 | /* RELATED WIDGET WRAPPER */ 544 | .related-widget-wrapper { 545 | float: left; /* display properly in form rows with multiple fields */ 546 | overflow: hidden; /* clear floated contents */ 547 | } 548 | 549 | .related-widget-wrapper-link { 550 | opacity: 0.3; 551 | } 552 | 553 | .related-widget-wrapper-link:link { 554 | opacity: .8; 555 | } 556 | 557 | .related-widget-wrapper-link:link:focus, 558 | .related-widget-wrapper-link:link:hover { 559 | opacity: 1; 560 | } 561 | 562 | select + .related-widget-wrapper-link, 563 | .related-widget-wrapper-link + .related-widget-wrapper-link { 564 | margin-left: 7px; 565 | } 566 | -------------------------------------------------------------------------------- /static/admin/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /static/admin/fonts/README.txt: -------------------------------------------------------------------------------- 1 | Roboto webfont source: https://www.google.com/fonts/specimen/Roboto 2 | Weights used in this project: Light (300), Regular (400), Bold (700) 3 | -------------------------------------------------------------------------------- /static/admin/fonts/Roboto-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/admin/fonts/Roboto-Bold-webfont.woff -------------------------------------------------------------------------------- /static/admin/fonts/Roboto-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/admin/fonts/Roboto-Light-webfont.woff -------------------------------------------------------------------------------- /static/admin/fonts/Roboto-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/admin/fonts/Roboto-Regular-webfont.woff -------------------------------------------------------------------------------- /static/admin/img/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Code Charm Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /static/admin/img/README.txt: -------------------------------------------------------------------------------- 1 | All icons are taken from Font Awesome (http://fontawesome.io/) project. 2 | The Font Awesome font is licensed under the SIL OFL 1.1: 3 | - http://scripts.sil.org/OFL 4 | 5 | SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG 6 | Font-Awesome-SVG-PNG is licensed under the MIT license (see file license 7 | in current folder). 8 | -------------------------------------------------------------------------------- /static/admin/img/calendar-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/admin/img/gis/move_vertex_off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/admin/img/gis/move_vertex_on.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/admin/img/icon-addlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/admin/img/icon-changelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static/admin/img/icon-deletelink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-no.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-unknown-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/icon-yes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/inline-delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/selector-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /static/admin/img/sorting-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /static/admin/img/tooltag-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/img/tooltag-arrowright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /static/admin/js/SelectBox.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | var SelectBox = { 4 | cache: {}, 5 | init: function(id) { 6 | var box = document.getElementById(id); 7 | var node; 8 | SelectBox.cache[id] = []; 9 | var cache = SelectBox.cache[id]; 10 | var boxOptions = box.options; 11 | var boxOptionsLength = boxOptions.length; 12 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 13 | node = boxOptions[i]; 14 | cache.push({value: node.value, text: node.text, displayed: 1}); 15 | } 16 | }, 17 | redisplay: function(id) { 18 | // Repopulate HTML select box from cache 19 | var box = document.getElementById(id); 20 | var node; 21 | $(box).empty(); // clear all options 22 | var new_options = box.outerHTML.slice(0, -9); // grab just the opening tag 23 | var cache = SelectBox.cache[id]; 24 | for (var i = 0, j = cache.length; i < j; i++) { 25 | node = cache[i]; 26 | if (node.displayed) { 27 | var new_option = new Option(node.text, node.value, false, false); 28 | // Shows a tooltip when hovering over the option 29 | new_option.setAttribute("title", node.text); 30 | new_options += new_option.outerHTML; 31 | } 32 | } 33 | new_options += ''; 34 | box.outerHTML = new_options; 35 | }, 36 | filter: function(id, text) { 37 | // Redisplay the HTML select box, displaying only the choices containing ALL 38 | // the words in text. (It's an AND search.) 39 | var tokens = text.toLowerCase().split(/\s+/); 40 | var node, token; 41 | var cache = SelectBox.cache[id]; 42 | for (var i = 0, j = cache.length; i < j; i++) { 43 | node = cache[i]; 44 | node.displayed = 1; 45 | var node_text = node.text.toLowerCase(); 46 | var numTokens = tokens.length; 47 | for (var k = 0; k < numTokens; k++) { 48 | token = tokens[k]; 49 | if (node_text.indexOf(token) === -1) { 50 | node.displayed = 0; 51 | break; // Once the first token isn't found we're done 52 | } 53 | } 54 | } 55 | SelectBox.redisplay(id); 56 | }, 57 | delete_from_cache: function(id, value) { 58 | var node, delete_index = null; 59 | var cache = SelectBox.cache[id]; 60 | for (var i = 0, j = cache.length; i < j; i++) { 61 | node = cache[i]; 62 | if (node.value === value) { 63 | delete_index = i; 64 | break; 65 | } 66 | } 67 | cache.splice(delete_index, 1); 68 | }, 69 | add_to_cache: function(id, option) { 70 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); 71 | }, 72 | cache_contains: function(id, value) { 73 | // Check if an item is contained in the cache 74 | var node; 75 | var cache = SelectBox.cache[id]; 76 | for (var i = 0, j = cache.length; i < j; i++) { 77 | node = cache[i]; 78 | if (node.value === value) { 79 | return true; 80 | } 81 | } 82 | return false; 83 | }, 84 | move: function(from, to) { 85 | var from_box = document.getElementById(from); 86 | var option; 87 | var boxOptions = from_box.options; 88 | var boxOptionsLength = boxOptions.length; 89 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 90 | option = boxOptions[i]; 91 | var option_value = option.value; 92 | if (option.selected && SelectBox.cache_contains(from, option_value)) { 93 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); 94 | SelectBox.delete_from_cache(from, option_value); 95 | } 96 | } 97 | SelectBox.redisplay(from); 98 | SelectBox.redisplay(to); 99 | }, 100 | move_all: function(from, to) { 101 | var from_box = document.getElementById(from); 102 | var option; 103 | var boxOptions = from_box.options; 104 | var boxOptionsLength = boxOptions.length; 105 | for (var i = 0, j = boxOptionsLength; i < j; i++) { 106 | option = boxOptions[i]; 107 | var option_value = option.value; 108 | if (SelectBox.cache_contains(from, option_value)) { 109 | SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); 110 | SelectBox.delete_from_cache(from, option_value); 111 | } 112 | } 113 | SelectBox.redisplay(from); 114 | SelectBox.redisplay(to); 115 | }, 116 | sort: function(id) { 117 | SelectBox.cache[id].sort(function(a, b) { 118 | a = a.text.toLowerCase(); 119 | b = b.text.toLowerCase(); 120 | try { 121 | if (a > b) { 122 | return 1; 123 | } 124 | if (a < b) { 125 | return -1; 126 | } 127 | } 128 | catch (e) { 129 | // silently fail on IE 'unknown' exception 130 | } 131 | return 0; 132 | } ); 133 | }, 134 | select_all: function(id) { 135 | var box = document.getElementById(id); 136 | var boxOptions = box.options; 137 | var boxOptionsLength = boxOptions.length; 138 | for (var i = 0; i < boxOptionsLength; i++) { 139 | boxOptions[i].selected = 'selected'; 140 | } 141 | } 142 | }; 143 | window.SelectBox = SelectBox; 144 | })(django.jQuery); 145 | -------------------------------------------------------------------------------- /static/admin/js/actions.js: -------------------------------------------------------------------------------- 1 | /*global gettext, interpolate, ngettext*/ 2 | (function($) { 3 | 'use strict'; 4 | var lastChecked; 5 | 6 | $.fn.actions = function(opts) { 7 | var options = $.extend({}, $.fn.actions.defaults, opts); 8 | var actionCheckboxes = $(this); 9 | var list_editable_changed = false; 10 | var showQuestion = function() { 11 | $(options.acrossClears).hide(); 12 | $(options.acrossQuestions).show(); 13 | $(options.allContainer).hide(); 14 | }, 15 | showClear = function() { 16 | $(options.acrossClears).show(); 17 | $(options.acrossQuestions).hide(); 18 | $(options.actionContainer).toggleClass(options.selectedClass); 19 | $(options.allContainer).show(); 20 | $(options.counterContainer).hide(); 21 | }, 22 | reset = function() { 23 | $(options.acrossClears).hide(); 24 | $(options.acrossQuestions).hide(); 25 | $(options.allContainer).hide(); 26 | $(options.counterContainer).show(); 27 | }, 28 | clearAcross = function() { 29 | reset(); 30 | $(options.acrossInput).val(0); 31 | $(options.actionContainer).removeClass(options.selectedClass); 32 | }, 33 | checker = function(checked) { 34 | if (checked) { 35 | showQuestion(); 36 | } else { 37 | reset(); 38 | } 39 | $(actionCheckboxes).prop("checked", checked) 40 | .parent().parent().toggleClass(options.selectedClass, checked); 41 | }, 42 | updateCounter = function() { 43 | var sel = $(actionCheckboxes).filter(":checked").length; 44 | // data-actions-icnt is defined in the generated HTML 45 | // and contains the total amount of objects in the queryset 46 | var actions_icnt = $('.action-counter').data('actionsIcnt'); 47 | $(options.counterContainer).html(interpolate( 48 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { 49 | sel: sel, 50 | cnt: actions_icnt 51 | }, true)); 52 | $(options.allToggle).prop("checked", function() { 53 | var value; 54 | if (sel === actionCheckboxes.length) { 55 | value = true; 56 | showQuestion(); 57 | } else { 58 | value = false; 59 | clearAcross(); 60 | } 61 | return value; 62 | }); 63 | }; 64 | // Show counter by default 65 | $(options.counterContainer).show(); 66 | // Check state of checkboxes and reinit state if needed 67 | $(this).filter(":checked").each(function(i) { 68 | $(this).parent().parent().toggleClass(options.selectedClass); 69 | updateCounter(); 70 | if ($(options.acrossInput).val() === 1) { 71 | showClear(); 72 | } 73 | }); 74 | $(options.allToggle).show().click(function() { 75 | checker($(this).prop("checked")); 76 | updateCounter(); 77 | }); 78 | $("a", options.acrossQuestions).click(function(event) { 79 | event.preventDefault(); 80 | $(options.acrossInput).val(1); 81 | showClear(); 82 | }); 83 | $("a", options.acrossClears).click(function(event) { 84 | event.preventDefault(); 85 | $(options.allToggle).prop("checked", false); 86 | clearAcross(); 87 | checker(0); 88 | updateCounter(); 89 | }); 90 | lastChecked = null; 91 | $(actionCheckboxes).click(function(event) { 92 | if (!event) { event = window.event; } 93 | var target = event.target ? event.target : event.srcElement; 94 | if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) { 95 | var inrange = false; 96 | $(lastChecked).prop("checked", target.checked) 97 | .parent().parent().toggleClass(options.selectedClass, target.checked); 98 | $(actionCheckboxes).each(function() { 99 | if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) { 100 | inrange = (inrange) ? false : true; 101 | } 102 | if (inrange) { 103 | $(this).prop("checked", target.checked) 104 | .parent().parent().toggleClass(options.selectedClass, target.checked); 105 | } 106 | }); 107 | } 108 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked); 109 | lastChecked = target; 110 | updateCounter(); 111 | }); 112 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { 113 | list_editable_changed = true; 114 | }); 115 | $('form#changelist-form button[name="index"]').click(function(event) { 116 | if (list_editable_changed) { 117 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); 118 | } 119 | }); 120 | $('form#changelist-form input[name="_save"]').click(function(event) { 121 | var action_changed = false; 122 | $('select option:selected', options.actionContainer).each(function() { 123 | if ($(this).val()) { 124 | action_changed = true; 125 | } 126 | }); 127 | if (action_changed) { 128 | if (list_editable_changed) { 129 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); 130 | } else { 131 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); 132 | } 133 | } 134 | }); 135 | }; 136 | /* Setup plugin defaults */ 137 | $.fn.actions.defaults = { 138 | actionContainer: "div.actions", 139 | counterContainer: "span.action-counter", 140 | allContainer: "div.actions span.all", 141 | acrossInput: "div.actions input.select-across", 142 | acrossQuestions: "div.actions span.question", 143 | acrossClears: "div.actions span.clear", 144 | allToggle: "#action-toggle", 145 | selectedClass: "selected" 146 | }; 147 | $(document).ready(function() { 148 | var $actionsEls = $('tr input.action-select'); 149 | if ($actionsEls.length > 0) { 150 | $actionsEls.actions(); 151 | } 152 | }); 153 | })(django.jQuery); 154 | -------------------------------------------------------------------------------- /static/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(e){var b=a.extend({},a.fn.actions.defaults,e),g=a(this),k=!1,l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).show();a(b.allContainer).hide()},m=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},n=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},p=function(){n(); 2 | a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)},q=function(c){c?l():n();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length,d=a(".action-counter").data("actionsIcnt");a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:d},!0));a(b.allToggle).prop("checked",function(){var a;c===g.length?(a=!0,l()):(a=!1,p());return a})};a(b.counterContainer).show(); 3 | a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);h();1===a(b.acrossInput).val()&&m()});a(b.allToggle).show().click(function(){q(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);m()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);p();q(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&& 4 | a.data(f)!==a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked);a(g).each(function(){if(a.data(this)===a.data(f)||a.data(this)===a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){k=!0});a('form#changelist-form button[name="index"]').click(function(a){if(k)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))}); 5 | a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return k?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})}; 6 | a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"};a(document).ready(function(){var e=a("tr input.action-select");0' + gettext("Show") + 11 | ')'); 12 | } 13 | }); 14 | // Add toggle to anchor tag 15 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 16 | if ($(this).closest("fieldset").hasClass("collapsed")) { 17 | // Show 18 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 19 | } else { 20 | // Hide 21 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 22 | } 23 | return false; 24 | }); 25 | }); 26 | })(django.jQuery); 27 | -------------------------------------------------------------------------------- /static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(b,c){0===a(c).find("div.errors").length&&a(c).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(b){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return!1})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /static/admin/js/core.js: -------------------------------------------------------------------------------- 1 | // Core javascript helper functions 2 | 3 | // basic browser identification & version 4 | var isOpera = (navigator.userAgent.indexOf("Opera") >= 0) && parseFloat(navigator.appVersion); 5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); 6 | 7 | // Cross-browser event handlers. 8 | function addEvent(obj, evType, fn) { 9 | 'use strict'; 10 | if (obj.addEventListener) { 11 | obj.addEventListener(evType, fn, false); 12 | return true; 13 | } else if (obj.attachEvent) { 14 | var r = obj.attachEvent("on" + evType, fn); 15 | return r; 16 | } else { 17 | return false; 18 | } 19 | } 20 | 21 | function removeEvent(obj, evType, fn) { 22 | 'use strict'; 23 | if (obj.removeEventListener) { 24 | obj.removeEventListener(evType, fn, false); 25 | return true; 26 | } else if (obj.detachEvent) { 27 | obj.detachEvent("on" + evType, fn); 28 | return true; 29 | } else { 30 | return false; 31 | } 32 | } 33 | 34 | function cancelEventPropagation(e) { 35 | 'use strict'; 36 | if (!e) { 37 | e = window.event; 38 | } 39 | e.cancelBubble = true; 40 | if (e.stopPropagation) { 41 | e.stopPropagation(); 42 | } 43 | } 44 | 45 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); 46 | function quickElement() { 47 | 'use strict'; 48 | var obj = document.createElement(arguments[0]); 49 | if (arguments[2]) { 50 | var textNode = document.createTextNode(arguments[2]); 51 | obj.appendChild(textNode); 52 | } 53 | var len = arguments.length; 54 | for (var i = 3; i < len; i += 2) { 55 | obj.setAttribute(arguments[i], arguments[i + 1]); 56 | } 57 | arguments[1].appendChild(obj); 58 | return obj; 59 | } 60 | 61 | // "a" is reference to an object 62 | function removeChildren(a) { 63 | 'use strict'; 64 | while (a.hasChildNodes()) { 65 | a.removeChild(a.lastChild); 66 | } 67 | } 68 | 69 | // ---------------------------------------------------------------------------- 70 | // Find-position functions by PPK 71 | // See http://www.quirksmode.org/js/findpos.html 72 | // ---------------------------------------------------------------------------- 73 | function findPosX(obj) { 74 | 'use strict'; 75 | var curleft = 0; 76 | if (obj.offsetParent) { 77 | while (obj.offsetParent) { 78 | curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); 79 | obj = obj.offsetParent; 80 | } 81 | // IE offsetParent does not include the top-level 82 | if (isIE && obj.parentElement) { 83 | curleft += obj.offsetLeft - obj.scrollLeft; 84 | } 85 | } else if (obj.x) { 86 | curleft += obj.x; 87 | } 88 | return curleft; 89 | } 90 | 91 | function findPosY(obj) { 92 | 'use strict'; 93 | var curtop = 0; 94 | if (obj.offsetParent) { 95 | while (obj.offsetParent) { 96 | curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); 97 | obj = obj.offsetParent; 98 | } 99 | // IE offsetParent does not include the top-level 100 | if (isIE && obj.parentElement) { 101 | curtop += obj.offsetTop - obj.scrollTop; 102 | } 103 | } else if (obj.y) { 104 | curtop += obj.y; 105 | } 106 | return curtop; 107 | } 108 | 109 | //----------------------------------------------------------------------------- 110 | // Date object extensions 111 | // ---------------------------------------------------------------------------- 112 | (function() { 113 | 'use strict'; 114 | Date.prototype.getTwelveHours = function() { 115 | var hours = this.getHours(); 116 | if (hours === 0) { 117 | return 12; 118 | } 119 | else { 120 | return hours <= 12 ? hours : hours - 12; 121 | } 122 | }; 123 | 124 | Date.prototype.getTwoDigitMonth = function() { 125 | return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); 126 | }; 127 | 128 | Date.prototype.getTwoDigitDate = function() { 129 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); 130 | }; 131 | 132 | Date.prototype.getTwoDigitTwelveHour = function() { 133 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); 134 | }; 135 | 136 | Date.prototype.getTwoDigitHour = function() { 137 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); 138 | }; 139 | 140 | Date.prototype.getTwoDigitMinute = function() { 141 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); 142 | }; 143 | 144 | Date.prototype.getTwoDigitSecond = function() { 145 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); 146 | }; 147 | 148 | Date.prototype.getHourMinute = function() { 149 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); 150 | }; 151 | 152 | Date.prototype.getHourMinuteSecond = function() { 153 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); 154 | }; 155 | 156 | Date.prototype.getFullMonthName = function() { 157 | return typeof window.CalendarNamespace === "undefined" 158 | ? this.getTwoDigitMonth() 159 | : window.CalendarNamespace.monthsOfYear[this.getMonth()]; 160 | }; 161 | 162 | Date.prototype.strftime = function(format) { 163 | var fields = { 164 | B: this.getFullMonthName(), 165 | c: this.toString(), 166 | d: this.getTwoDigitDate(), 167 | H: this.getTwoDigitHour(), 168 | I: this.getTwoDigitTwelveHour(), 169 | m: this.getTwoDigitMonth(), 170 | M: this.getTwoDigitMinute(), 171 | p: (this.getHours() >= 12) ? 'PM' : 'AM', 172 | S: this.getTwoDigitSecond(), 173 | w: '0' + this.getDay(), 174 | x: this.toLocaleDateString(), 175 | X: this.toLocaleTimeString(), 176 | y: ('' + this.getFullYear()).substr(2, 4), 177 | Y: '' + this.getFullYear(), 178 | '%': '%' 179 | }; 180 | var result = '', i = 0; 181 | while (i < format.length) { 182 | if (format.charAt(i) === '%') { 183 | result = result + fields[format.charAt(i + 1)]; 184 | ++i; 185 | } 186 | else { 187 | result = result + format.charAt(i); 188 | } 189 | ++i; 190 | } 191 | return result; 192 | }; 193 | 194 | // ---------------------------------------------------------------------------- 195 | // String object extensions 196 | // ---------------------------------------------------------------------------- 197 | String.prototype.pad_left = function(pad_length, pad_string) { 198 | var new_string = this; 199 | for (var i = 0; new_string.length < pad_length; i++) { 200 | new_string = pad_string + new_string; 201 | } 202 | return new_string; 203 | }; 204 | 205 | String.prototype.strptime = function(format) { 206 | var split_format = format.split(/[.\-/]/); 207 | var date = this.split(/[.\-/]/); 208 | var i = 0; 209 | var day, month, year; 210 | while (i < split_format.length) { 211 | switch (split_format[i]) { 212 | case "%d": 213 | day = date[i]; 214 | break; 215 | case "%m": 216 | month = date[i] - 1; 217 | break; 218 | case "%Y": 219 | year = date[i]; 220 | break; 221 | case "%y": 222 | year = date[i]; 223 | break; 224 | } 225 | ++i; 226 | } 227 | // Create Date object from UTC since the parsed value is supposed to be 228 | // in UTC, not local time. Also, the calendar uses UTC functions for 229 | // date extraction. 230 | return new Date(Date.UTC(year, month, day)); 231 | }; 232 | 233 | })(); 234 | // ---------------------------------------------------------------------------- 235 | // Get the computed style for and element 236 | // ---------------------------------------------------------------------------- 237 | function getStyle(oElm, strCssRule) { 238 | 'use strict'; 239 | var strValue = ""; 240 | if(document.defaultView && document.defaultView.getComputedStyle) { 241 | strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); 242 | } 243 | else if(oElm.currentStyle) { 244 | strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { 245 | return p1.toUpperCase(); 246 | }); 247 | strValue = oElm.currentStyle[strCssRule]; 248 | } 249 | return strValue; 250 | } 251 | -------------------------------------------------------------------------------- /static/admin/js/inlines.min.js: -------------------------------------------------------------------------------- 1 | (function(c){c.fn.formset=function(b){var a=c.extend({},c.fn.formset.defaults,b),d=c(this);b=d.parent();var k=function(a,g,l){var b=new RegExp("("+g+"-(\\d+|__prefix__))");g=g+"-"+l;c(a).prop("for")&&c(a).prop("for",c(a).prop("for").replace(b,g));a.id&&(a.id=a.id.replace(b,g));a.name&&(a.name=a.name.replace(b,g))},e=c("#id_"+a.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),l=parseInt(e.val(),10),g=c("#id_"+a.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off"),h=""===g.val()||0'+a.addText+""),m=b.find("tr:last a")):(d.filter(":last").after('"),m=d.filter(":last").next().find("a")));m.click(function(b){b.preventDefault();b=c("#"+a.prefix+"-empty"); 3 | var f=b.clone(!0);f.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+l);f.is("tr")?f.children(":last").append('"):f.is("ul")||f.is("ol")?f.append('
  • '+a.deleteText+"
  • "):f.children(":first").append(''+a.deleteText+"");f.find("*").each(function(){k(this,a.prefix,e.val())});f.insertBefore(c(b)); 4 | c(e).val(parseInt(e.val(),10)+1);l+=1;""!==g.val()&&0>=g.val()-e.val()&&m.parent().hide();f.find("a."+a.deleteCssClass).click(function(b){b.preventDefault();f.remove();--l;a.removed&&a.removed(f);c(document).trigger("formset:removed",[f,a.prefix]);b=c("."+a.formCssClass);c("#id_"+a.prefix+"-TOTAL_FORMS").val(b.length);(""===g.val()||0 0) { 26 | values.push(field.val()); 27 | } 28 | }); 29 | prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); 30 | }; 31 | 32 | prepopulatedField.data('_changed', false); 33 | prepopulatedField.change(function() { 34 | prepopulatedField.data('_changed', true); 35 | }); 36 | 37 | if (!prepopulatedField.val()) { 38 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); 39 | } 40 | }); 41 | }; 42 | })(django.jQuery); 43 | -------------------------------------------------------------------------------- /static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(c){c.fn.prepopulate=function(e,f,g){return this.each(function(){var a=c(this),b=function(){if(!a.data("_changed")){var b=[];c.each(e,function(a,d){d=c(d);0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /static/app/content/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Set width on the form input elements since they're 100% wide by default */ 13 | input, 14 | select, 15 | textarea { 16 | max-width: 280px; 17 | } 18 | 19 | /* styles for validation helpers */ 20 | .field-validation-error { 21 | color: #b94a48; 22 | } 23 | 24 | .field-validation-valid { 25 | display: none; 26 | } 27 | 28 | input.input-validation-error { 29 | border: 1px solid #b94a48; 30 | } 31 | 32 | input[type="checkbox"].input-validation-error { 33 | border: 0 none; 34 | } 35 | 36 | .validation-summary-errors { 37 | color: #b94a48; 38 | } 39 | 40 | .validation-summary-valid { 41 | display: none; 42 | } -------------------------------------------------------------------------------- /static/app/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/app/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/app/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/app/img/container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/img/container.png -------------------------------------------------------------------------------- /static/app/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/img/github.png -------------------------------------------------------------------------------- /static/app/img/linux-web-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/img/linux-web-app.png -------------------------------------------------------------------------------- /static/app/img/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/img/overview.png -------------------------------------------------------------------------------- /static/app/scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/docker-django-webapp-linux/54349c4b56197906f44954e3bedf6176f62cab82/static/app/scripts/_references.js -------------------------------------------------------------------------------- /static/app/scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(c){var b=a(c),d=b.data(e),f=a.proxy(n,c);if(!d){d={options:{errorClass:"input-validation-error",errorElement:"span",errorPlacement:a.proxy(m,c),invalidHandler:a.proxy(l,c),messages:{},rules:{},success:a.proxy(k,c)},attachValidation:function(){b.unbind("reset."+e,f).bind("reset."+e,f).validate(this.options)},validate:function(){b.validate();return b.valid()}};b.data(e,d)}return d}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(b){var c=a(b).parents("form").andSelf().add(a(b).find("form")).filter("form");a(b).find(":input").filter("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});c.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); 20 | -------------------------------------------------------------------------------- /static/app/scripts/respond.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia = window.matchMedia || (function(doc, undefined){ 18 | 19 | var bool, 20 | docElem = doc.documentElement, 21 | refNode = docElem.firstElementChild || docElem.firstChild, 22 | // fakeBody required for 23 | fakeBody = doc.createElement('body'), 24 | div = doc.createElement('div'); 25 | 26 | div.id = 'mq-test-1'; 27 | div.style.cssText = "position:absolute;top:-100em"; 28 | fakeBody.style.background = "none"; 29 | fakeBody.appendChild(div); 30 | 31 | return function(q){ 32 | 33 | div.innerHTML = '­'; 34 | 35 | docElem.insertBefore(fakeBody, refNode); 36 | bool = div.offsetWidth == 42; 37 | docElem.removeChild(fakeBody); 38 | 39 | return { matches: bool, media: q }; 40 | }; 41 | 42 | })(document); 43 | 44 | 45 | 46 | 47 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 48 | (function( win ){ 49 | //exposed namespace 50 | win.respond = {}; 51 | 52 | //define update even in native-mq-supporting browsers, to avoid errors 53 | respond.update = function(){}; 54 | 55 | //expose media query support flag for external use 56 | respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches; 57 | 58 | //if media queries are supported, exit here 59 | if( respond.mediaQueriesSupported ){ return; } 60 | 61 | //define vars 62 | var doc = win.document, 63 | docElem = doc.documentElement, 64 | mediastyles = [], 65 | rules = [], 66 | appendedEls = [], 67 | parsedSheets = {}, 68 | resizeThrottle = 30, 69 | head = doc.getElementsByTagName( "head" )[0] || docElem, 70 | base = doc.getElementsByTagName( "base" )[0], 71 | links = head.getElementsByTagName( "link" ), 72 | requestQueue = [], 73 | 74 | //loop stylesheets, send text content to translate 75 | ripCSS = function(){ 76 | var sheets = links, 77 | sl = sheets.length, 78 | i = 0, 79 | //vars for loop: 80 | sheet, href, media, isCSS; 81 | 82 | for( ; i < sl; i++ ){ 83 | sheet = sheets[ i ], 84 | href = sheet.href, 85 | media = sheet.media, 86 | isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; 87 | 88 | //only links plz and prevent re-parsing 89 | if( !!href && isCSS && !parsedSheets[ href ] ){ 90 | // selectivizr exposes css through the rawCssText expando 91 | if (sheet.styleSheet && sheet.styleSheet.rawCssText) { 92 | translate( sheet.styleSheet.rawCssText, href, media ); 93 | parsedSheets[ href ] = true; 94 | } else { 95 | if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) 96 | || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){ 97 | requestQueue.push( { 98 | href: href, 99 | media: media 100 | } ); 101 | } 102 | } 103 | } 104 | } 105 | makeRequests(); 106 | }, 107 | 108 | //recurse through request queue, get css text 109 | makeRequests = function(){ 110 | if( requestQueue.length ){ 111 | var thisRequest = requestQueue.shift(); 112 | 113 | ajax( thisRequest.href, function( styles ){ 114 | translate( styles, thisRequest.href, thisRequest.media ); 115 | parsedSheets[ thisRequest.href ] = true; 116 | makeRequests(); 117 | } ); 118 | } 119 | }, 120 | 121 | //find media blocks in css text, convert to style blocks 122 | translate = function( styles, href, media ){ 123 | var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ), 124 | ql = qs && qs.length || 0, 125 | //try to get CSS path 126 | href = href.substring( 0, href.lastIndexOf( "/" )), 127 | repUrls = function( css ){ 128 | return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" ); 129 | }, 130 | useMedia = !ql && media, 131 | //vars used in loop 132 | i = 0, 133 | j, fullq, thisq, eachq, eql; 134 | 135 | //if path exists, tack on trailing slash 136 | if( href.length ){ href += "/"; } 137 | 138 | //if no internal queries exist, but media attr does, use that 139 | //note: this currently lacks support for situations where a media attr is specified on a link AND 140 | //its associated stylesheet has internal CSS media queries. 141 | //In those cases, the media attribute will currently be ignored. 142 | if( useMedia ){ 143 | ql = 1; 144 | } 145 | 146 | 147 | for( ; i < ql; i++ ){ 148 | j = 0; 149 | 150 | //media attr 151 | if( useMedia ){ 152 | fullq = media; 153 | rules.push( repUrls( styles ) ); 154 | } 155 | //parse for styles 156 | else{ 157 | fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1; 158 | rules.push( RegExp.$2 && repUrls( RegExp.$2 ) ); 159 | } 160 | 161 | eachq = fullq.split( "," ); 162 | eql = eachq.length; 163 | 164 | for( ; j < eql; j++ ){ 165 | thisq = eachq[ j ]; 166 | mediastyles.push( { 167 | media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all", 168 | rules : rules.length - 1, 169 | hasquery: thisq.indexOf("(") > -1, 170 | minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 171 | maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ) 172 | } ); 173 | } 174 | } 175 | 176 | applyMedia(); 177 | }, 178 | 179 | lastCall, 180 | 181 | resizeDefer, 182 | 183 | // returns the value of 1em in pixels 184 | getEmValue = function() { 185 | var ret, 186 | div = doc.createElement('div'), 187 | body = doc.body, 188 | fakeUsed = false; 189 | 190 | div.style.cssText = "position:absolute;font-size:1em;width:1em"; 191 | 192 | if( !body ){ 193 | body = fakeUsed = doc.createElement( "body" ); 194 | body.style.background = "none"; 195 | } 196 | 197 | body.appendChild( div ); 198 | 199 | docElem.insertBefore( body, docElem.firstChild ); 200 | 201 | ret = div.offsetWidth; 202 | 203 | if( fakeUsed ){ 204 | docElem.removeChild( body ); 205 | } 206 | else { 207 | body.removeChild( div ); 208 | } 209 | 210 | //also update eminpx before returning 211 | ret = eminpx = parseFloat(ret); 212 | 213 | return ret; 214 | }, 215 | 216 | //cached container for 1em value, populated the first time it's needed 217 | eminpx, 218 | 219 | //enable/disable styles 220 | applyMedia = function( fromResize ){ 221 | var name = "clientWidth", 222 | docElemProp = docElem[ name ], 223 | currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp, 224 | styleBlocks = {}, 225 | lastLink = links[ links.length-1 ], 226 | now = (new Date()).getTime(); 227 | 228 | //throttle resize calls 229 | if( fromResize && lastCall && now - lastCall < resizeThrottle ){ 230 | clearTimeout( resizeDefer ); 231 | resizeDefer = setTimeout( applyMedia, resizeThrottle ); 232 | return; 233 | } 234 | else { 235 | lastCall = now; 236 | } 237 | 238 | for( var i in mediastyles ){ 239 | var thisstyle = mediastyles[ i ], 240 | min = thisstyle.minw, 241 | max = thisstyle.maxw, 242 | minnull = min === null, 243 | maxnull = max === null, 244 | em = "em"; 245 | 246 | if( !!min ){ 247 | min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 248 | } 249 | if( !!max ){ 250 | max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 251 | } 252 | 253 | // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true 254 | if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){ 255 | if( !styleBlocks[ thisstyle.media ] ){ 256 | styleBlocks[ thisstyle.media ] = []; 257 | } 258 | styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] ); 259 | } 260 | } 261 | 262 | //remove any existing respond style element(s) 263 | for( var i in appendedEls ){ 264 | if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){ 265 | head.removeChild( appendedEls[ i ] ); 266 | } 267 | } 268 | 269 | //inject active styles, grouped by media type 270 | for( var i in styleBlocks ){ 271 | var ss = doc.createElement( "style" ), 272 | css = styleBlocks[ i ].join( "\n" ); 273 | 274 | ss.type = "text/css"; 275 | ss.media = i; 276 | 277 | //originally, ss was appended to a documentFragment and sheets were appended in bulk. 278 | //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one! 279 | head.insertBefore( ss, lastLink.nextSibling ); 280 | 281 | if ( ss.styleSheet ){ 282 | ss.styleSheet.cssText = css; 283 | } 284 | else { 285 | ss.appendChild( doc.createTextNode( css ) ); 286 | } 287 | 288 | //push to appendedEls to track for later removal 289 | appendedEls.push( ss ); 290 | } 291 | }, 292 | //tweaked Ajax functions from Quirksmode 293 | ajax = function( url, callback ) { 294 | var req = xmlHttp(); 295 | if (!req){ 296 | return; 297 | } 298 | req.open( "GET", url, true ); 299 | req.onreadystatechange = function () { 300 | if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){ 301 | return; 302 | } 303 | callback( req.responseText ); 304 | } 305 | if ( req.readyState == 4 ){ 306 | return; 307 | } 308 | req.send( null ); 309 | }, 310 | //define ajax obj 311 | xmlHttp = (function() { 312 | var xmlhttpmethod = false; 313 | try { 314 | xmlhttpmethod = new XMLHttpRequest(); 315 | } 316 | catch( e ){ 317 | xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" ); 318 | } 319 | return function(){ 320 | return xmlhttpmethod; 321 | }; 322 | })(); 323 | 324 | //translate CSS 325 | ripCSS(); 326 | 327 | //expose update for re-running respond later on 328 | respond.update = ripCSS; 329 | 330 | //adjust on resize 331 | function callMedia(){ 332 | applyMedia( true ); 333 | } 334 | if( win.addEventListener ){ 335 | win.addEventListener( "resize", callMedia, false ); 336 | } 337 | else if( win.attachEvent ){ 338 | win.attachEvent( "onresize", callMedia ); 339 | } 340 | })(this); 341 | -------------------------------------------------------------------------------- /static/app/scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); --------------------------------------------------------------------------------