"},onSelect:function(){}};for(var c in e)e.hasOwnProperty(c)&&(l[c]=e[c]);for(var a="object"==typeof l.selector?[l.selector]:document.querySelectorAll(l.selector),u=0;u0?i.sc.scrollTop=n+i.sc.suggestionHeight+s-i.sc.maxHeight:0>n&&(i.sc.scrollTop=n+s)}else i.sc.scrollTop=0},o(window,"resize",i.updateSC),document.body.appendChild(i.sc),n("autocomplete-suggestion","mouseleave",function(){var e=i.sc.querySelector(".autocomplete-suggestion.selected");e&&setTimeout(function(){e.className=e.className.replace("selected","")},20)},i.sc),n("autocomplete-suggestion","mouseover",function(){var e=i.sc.querySelector(".autocomplete-suggestion.selected");e&&(e.className=e.className.replace("selected","")),this.className+=" selected"},i.sc),n("autocomplete-suggestion","mousedown",function(e){if(t(this,"autocomplete-suggestion")){var o=this.getAttribute("data-val");i.value=o,l.onSelect(e,o,this),i.sc.style.display="none"}},i.sc),i.blurHandler=function(){try{var e=document.querySelector(".autocomplete-suggestions:hover")}catch(t){var e=0}e?i!==document.activeElement&&setTimeout(function(){i.focus()},20):(i.last_val=i.value,i.sc.style.display="none",setTimeout(function(){i.sc.style.display="none"},350))},o(i,"blur",i.blurHandler);var r=function(e){var t=i.value;if(i.cache[t]=e,e.length&&t.length>=l.minChars){for(var o="",s=0;st||t>40)&&13!=t&&27!=t){var o=i.value;if(o.length>=l.minChars){if(o!=i.last_val){if(i.last_val=o,clearTimeout(i.timer),l.cache){if(o in i.cache)return void r(i.cache[o]);for(var s=1;s{if(null===e.firstChild)return null;if(e.firstChild===e.lastChild)return e.removeChild(e.firstChild);const t=document.createElement("span");return t.appendChild(e),t})),{fragment:T(t,(e=>e))}),a=Object.assign(T(n,(e=>null===e.firstChild?null:e.firstChild===e.lastChild?e.removeChild(e.firstChild):e)),{fragment:T(n,(e=>{const t=document.createDocumentFragment();for(;e.firstChild;)t.appendChild(e.firstChild);return t}))}),s=60,i=62,o=47,c=45,l=33,f=61,u=10,d=11,p=12,b=13,h=14,k=17,g=22,m=23,w=26,x="http://www.w3.org/2000/svg",C="http://www.w3.org/1999/xlink",y="http://www.w3.org/XML/1998/namespace",v="http://www.w3.org/2000/xmlns/",A=new Map(["attributeName","attributeType","baseFrequency","baseProfile","calcMode","clipPathUnits","diffuseConstant","edgeMode","filterUnits","glyphRef","gradientTransform","gradientUnits","kernelMatrix","kernelUnitLength","keyPoints","keySplines","keyTimes","lengthAdjust","limitingConeAngle","markerHeight","markerUnits","markerWidth","maskContentUnits","maskUnits","numOctaves","pathLength","patternContentUnits","patternTransform","patternUnits","pointsAtX","pointsAtY","pointsAtZ","preserveAlpha","preserveAspectRatio","primitiveUnits","refX","refY","repeatCount","repeatDur","requiredExtensions","requiredFeatures","specularConstant","specularExponent","spreadMethod","startOffset","stdDeviation","stitchTiles","surfaceScale","systemLanguage","tableValues","targetX","targetY","textLength","viewBox","viewTarget","xChannelSelector","yChannelSelector","zoomAndPan"].map((e=>[e.toLowerCase(),e]))),N=new Map([["xlink:actuate",C],["xlink:arcrole",C],["xlink:href",C],["xlink:role",C],["xlink:show",C],["xlink:title",C],["xlink:type",C],["xml:lang",y],["xml:space",y],["xmlns",v],["xmlns:xlink",v]]);function T(e,t){return function({raw:n}){let r,a,x,C,y=1,v="",A=0;for(let e=0,t=arguments.length;e0){const r=arguments[e];switch(y){case w:if(null!=r){const e=`${r}`;if(E(a))v+=e.replace(/[<]/g,L);else{if(new RegExp(`${a}[\\s>/]`,"i").test(v.slice(-a.length-2)+e))throw new Error("unsafe raw text");v+=e}}break;case 1:null==r||(r instanceof Node||"string"!=typeof r&&r[Symbol.iterator]||/(?:^|>)$/.test(n[e-1])&&/^(?:<|$)/.test(t)?(v+="\x3c!--::"+e+"--\x3e",A|=128):v+=`${r}`.replace(/[<&]/g,L));break;case 9:{let a;if(y=p,/^[\s>]/.test(t)){if(null==r||!1===r){v=v.slice(0,x-n[e-1].length);break}if(!0===r||""==(a=`${r}`)){v+="''";break}if("style"===n[e-1].slice(x,C)&&M(r)||"function"==typeof r){v+="::"+e,A|=1;break}}if(void 0===a&&(a=`${r}`),""===a)throw new Error("unsafe unquoted empty string");v+=a.replace(/^['"]|[\s>&]/g,L);break}case p:v+=`${r}`.replace(/[\s>&]/g,L);break;case d:v+=`${r}`.replace(/['&]/g,L);break;case u:v+=`${r}`.replace(/["&]/g,L);break;case 6:if(M(r)){v+="::"+e+"=''",A|=1;break}throw new Error("invalid binding");case k:break;default:throw new Error("invalid binding")}}for(let e=0,n=t.length;e=0;--r)a=t.insertBefore(n[r],a);else for(const r of n)null!=r&&t.insertBefore(r instanceof Node?r:document.createTextNode(r),e);else t.insertBefore(document.createTextNode(n),e);R.push(e)}}}for(const e of R)e.parentNode.removeChild(e);return t(N)}}function L(e){return`${e.charCodeAt(0).toString()};`}function S(e){return 65<=e&&e<=90||97<=e&&e<=122}function U(e){return 9===e||10===e||12===e||32===e||13===e}function M(e){return e&&e.toString===Object.prototype.toString}function $(e){return"script"===e||"style"===e||E(e)}function E(e){return"textarea"===e||"title"===e}function j(e,t,n){return e.slice(t,n).toLowerCase()}function O(e,t,n){e.namespaceURI===x&&(t=t.toLowerCase(),t=A.get(t)||t,N.has(t))?e.setAttributeNS(N.get(t),t,n):e.setAttribute(t,n)}function P(e,t){e.namespaceURI===x&&(t=t.toLowerCase(),t=A.get(t)||t,N.has(t))?e.removeAttributeNS(N.get(t),t):e.removeAttribute(t)}function B(e,t){for(const n in t){const r=t[n];n.startsWith("--")?e.setProperty(n,r):e[n]=r}}e.html=r,e.svg=a,e.version="0.3.1",Object.defineProperty(e,"__esModule",{value:!0})}));
3 |
--------------------------------------------------------------------------------
/plan/static/js/navigation.js:
--------------------------------------------------------------------------------
1 | /* This file is part of the plan timetable generator, see LICENSE for details. */
2 |
3 | document.addEventListener(
4 | "keyup",
5 | function (e) {
6 | var link,
7 | inputs = ["INPUT", "TEXTAREA", "BUTTON", "SELECT"],
8 | scroll =
9 | document.documentElement.scrollWidth >
10 | document.documentElement.clientWidth;
11 | if (inputs.indexOf(event.target.tagName) >= 0) {
12 | return true;
13 | }
14 | if (e.keyCode == 74 || (!scroll && e.keyCode == 37)) {
15 | // j or ←
16 | link = document.getElementById("previous");
17 | } else if (e.keyCode == 75 || (!scroll && e.keyCode == 39)) {
18 | // k or →
19 | link = document.getElementById("next");
20 | }
21 | if (link && link.href) {
22 | document.location = link.href;
23 | }
24 | },
25 | false,
26 | );
27 |
--------------------------------------------------------------------------------
/plan/static/js/toggle.js:
--------------------------------------------------------------------------------
1 | /* This file is part of the plan timetable generator, see LICENSE for details. */
2 |
3 | (function () {
4 | function init() {
5 | document.removeEventListener("DOMContentLoaded", arguments.callee, false);
6 |
7 | for (var group of document.querySelectorAll("[data-toggle-container]")) {
8 | group.style.display = "block";
9 | group.querySelectorAll("[data-toggle]").forEach((toggle) => {
10 | toggle.style.cursor = "pointer";
11 | toggle.addEventListener(
12 | "click",
13 | ((inputs, event) => {
14 | event.preventDefault();
15 |
16 | inputs.forEach((input) => {
17 | const targetState = event.target.dataset.toggle == "true";
18 | if (input.checked != targetState && input.offsetParent !== null) {
19 | input.click();
20 | }
21 | });
22 | }).bind(null, group.querySelectorAll('input[type="checkbox"]')),
23 | );
24 | });
25 | }
26 | }
27 |
28 | if (document.readyState === "loading") {
29 | document.addEventListener("DOMContentLoaded", init, false);
30 | } else {
31 | init();
32 | }
33 | })();
34 |
--------------------------------------------------------------------------------
/plan/static/map/auditorier_dragvoll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adamcik/plan/433a4bf1b9a28daabd5fd4714259c43736b7ec94/plan/static/map/auditorier_dragvoll.png
--------------------------------------------------------------------------------
/plan/static/map/auditorier_gloshaugen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adamcik/plan/433a4bf1b9a28daabd5fd4714259c43736b7ec94/plan/static/map/auditorier_gloshaugen.png
--------------------------------------------------------------------------------
/plan/static/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adamcik/plan/433a4bf1b9a28daabd5fd4714259c43736b7ec94/plan/static/screenshot.png
--------------------------------------------------------------------------------
/plan/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends "base_site.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block title %}
6 | {{ block.super }} - {% trans "Page not found" %}
7 | {% endblock %}
8 |
9 | {% block hd %}
10 | {{ block.super }}
11 |
{% trans "Page not found" %}
12 | {% endblock %}
13 |
14 | {% block bd %}
15 |
16 |
17 | {% url 'frontpage' as frontpage_url %}
18 |
19 | {% blocktrans with request_path|default:"-" as path %}
20 | {{ path }} could not be found. Try going back or
21 | starting over from the frontpage.
22 | {% endblocktrans %}
23 |
17 |
18 | {% trans "An error has occurred, sorry about the inconvenience." %}
19 | {% trans "The server administrator has already been notified of this error." %}
20 |
59 | {% blocktrans with INSTITUTION as institution and INSTITUTION_SITE as url %}
60 | All lecture times and course data have been automatically retrieved
61 | from {{ institution }}. This data may not
62 | reflect the actual lecture times due to changes or erroneous imports.
63 | The service is provided as is, please ensure that the data is correct
64 | before relying on it.
65 | {% endblocktrans %}
66 |
15 |
16 | {% blocktrans %}
17 | Sorry, but the generator has been set up to limit
18 | timetables to {{ max }} courses.
19 | {% endblocktrans %}
20 |
21 | {% endif %}
22 | {% if courses %}
23 |
24 |
25 | {% trans "Adding the following courses failed:" %}
26 |
27 |
28 | {% for c in courses %}
29 |
{{ c }}
30 | {% endfor %}
31 |
32 | {% endif %}
33 |
34 | {% url 'schedule-advanced' year type slug as adavanced_url %}
35 | {% blocktrans %}
36 | Back to your schedule.
37 | {% endblocktrans %}
38 |
39 |
40 |
41 | {% blocktrans with INSTITUTION_SITE as url %}
42 | Please check that the courses that failed can be found at
43 | {{ url }} for this semster.
44 | {% endblocktrans %}
45 |
6 | Vil du drive med IT-systemer på høyt nivå med lav terskel?
7 | IT-komiteen
8 | søker nye medlemmer!
9 |
10 | Er ikke data noe for deg, finn andre verv på samfundet.no eller
11 | uka.no.
12 |
17 | {% trans "Multiple courses can be added at once by separating course codes with spaces." %}
18 |
19 |
20 |
21 | {% blocktrans with request.META.HTTP_HOST as host %}
22 | For quick access to your schedule simply go to
23 | {{ host }}{{ shortcut_url }}
24 | {% endblocktrans %}
25 |
26 |
27 |
28 | {% blocktrans %}
29 | Did you know that you can choose to hide lectures that you don't want to be shown under
30 | advanced options?
31 | {% endblocktrans %}
32 |
33 |
34 |
35 | {% blocktrans %}
36 | Did you know that you can select which groups (paralleller) you
37 | want to attend, and than you can select more than one group?
38 | {% endblocktrans %}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | {% blocktrans %}
47 | Did you know that you can change which names are used for courses under
48 | advanced options?
49 | {% endblocktrans %}
50 |
51 |
52 |
53 | {% blocktrans %}
54 | Calendar export:
55 | lectures,
56 | exams or
57 | both combined.
58 | {% endblocktrans %}
59 |
60 | {% trans "Simply download or copy the link to the calendar you want and add it to any application that supports the Ical format." %}
61 |