diff --git a/iflpanel/tahta/assets/css/dev.css b/iflpanel/tahta/assets/css/dev.css
new file mode 100644
index 0000000..400f86e
--- /dev/null
+++ b/iflpanel/tahta/assets/css/dev.css
@@ -0,0 +1,23 @@
+@charset "UTF-8";
+/* 2023 Aliberk Sandıkçı*/
+#ders-programi {
+ display: none;
+ flex-direction: column;
+ padding: 0px 100px;
+ padding-top: 10px;
+}
+#ders-programi img {
+ max-width: 1309px;
+ max-height: 601px;
+ aspect-ratio: 1309/601;
+}
+
+.min,
+.sec,
+.msec {
+ display: flex;
+ width: 7vw;
+ justify-content: center;
+}
+
+/*# sourceMappingURL=dev.css.map */
diff --git a/iflpanel/tahta/assets/css/dev.css.map b/iflpanel/tahta/assets/css/dev.css.map
new file mode 100644
index 0000000..eed168e
--- /dev/null
+++ b/iflpanel/tahta/assets/css/dev.css.map
@@ -0,0 +1 @@
+{"version":3,"sourceRoot":"","sources":["../scss/dev.scss"],"names":[],"mappings":";AAAA;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAAA;AAAA;EAGE;EACA;EACA","file":"dev.css"}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/css/main.css b/iflpanel/tahta/assets/css/main.css
new file mode 100644
index 0000000..136d240
--- /dev/null
+++ b/iflpanel/tahta/assets/css/main.css
@@ -0,0 +1,278 @@
+@charset "UTF-8";
+/* 2023 Aliberk Sandıkçı*/
+/* 2023 Aliberk Sandıkçı*/
+@keyframes rain {
+ 0% {
+ background-color: white;
+ }
+ 25% {
+ background-color: red;
+ }
+ 50% {
+ background-color: green;
+ }
+ 100% {
+ background-color: yellow;
+ }
+}
+* {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+}
+
+body,
+html {
+ display: flex;
+ flex-direction: column;
+ margin: 0px;
+ height: 100%;
+ width: 100%;
+ background-color: black;
+ color: aliceblue;
+ font-family: "Montserrat", Arial, Helvetica, sans-serif;
+}
+
+section#top {
+ display: flex;
+ justify-content: space-around;
+ user-select: none;
+ width: 100%;
+ height: 100px;
+}
+section#top .class {
+ margin: 5px;
+ min-width: 20vw;
+ margin-right: auto;
+ font-weight: 800;
+ font-style: oblique;
+}
+section#top .clock {
+ display: flex;
+}
+section#top .clock #time {
+ display: flex;
+ align-items: center;
+ align-self: center;
+ align-content: center;
+ justify-items: center;
+ justify-self: center;
+ justify-content: center;
+ font-size: 80px;
+}
+section#top .settings-box {
+ min-width: 20vw;
+ margin-left: auto;
+ text-align: right;
+}
+section#top .settings-box button {
+ height: 30px;
+ width: 30px;
+ line-height: 20px;
+}
+section#top .settings-box #settings {
+ display: none;
+ flex-direction: column;
+ align-items: end;
+ font-size: small;
+ margin-top: 5px;
+}
+section#top .settings-box #settings form {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ background-color: grey;
+}
+section#top .settings-box #settings form .cell {
+ float: left;
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 1vh;
+}
+section#top .settings-box #settings form .cell input[type=checkbox] {
+ appearance: none;
+ background-color: #fff;
+ margin: 0;
+ width: 1.15em;
+ height: 1.15em;
+ border: 0.15em solid darkslateblue;
+ border-radius: 0.15em;
+ transform: translateY(-0.075em);
+ display: grid;
+ place-content: center;
+ outline: 0px solid white;
+ outline-offset: 0px;
+}
+section#top .settings-box #settings form .cell input[type=checkbox]::before {
+ content: "";
+ width: 0.65em;
+ height: 0.65em;
+ transform: scale(0);
+ transition: 120ms transform ease-in-out;
+ box-shadow: inset 1em 1em green;
+ transform-origin: bottom left;
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
+}
+section#top .settings-box #settings form .cell input[type=checkbox]:checked::before {
+ transform: scale(1);
+}
+section#top .settings-box #settings form .cell input[type=checkbox]:focus {
+ outline: max(2px, 0.15em) solid white;
+ outline-offset: max(2px, 0.15em);
+}
+section#top .settings-box #settings form .cell label {
+ padding-left: 5px;
+ display: block;
+ text-align: left;
+ align-self: center;
+}
+section#mid {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ user-select: none;
+}
+section#mid #timers {
+ display: none;
+ flex-direction: column;
+}
+section#mid #timers #timers-menu ul {
+ display: flex;
+ justify-content: center;
+ padding: 0;
+}
+section#mid #timers #timers-menu ul li {
+ list-style-type: none;
+ box-sizing: border-box;
+}
+section#mid #timers #timers-menu ul li .pushable {
+ position: relative;
+ border: none;
+ background: transparent;
+ padding: 0;
+ cursor: pointer;
+ outline-offset: 4px;
+ transition: filter 250ms;
+}
+section#mid #timers #timers-menu ul li .shadow {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: hsla(0, 0%, 0%, 0.25);
+ will-change: transform;
+ transform: translateY(2px);
+ transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);
+}
+section#mid #timers #timers-menu ul li .edge {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(to left, hsl(235, 84%, 26%) 0%, hsl(235, 84%, 26%) 8%, hsl(235, 84%, 26%) 92%, hsl(235, 84%, 26%) 100%);
+}
+section#mid #timers #timers-menu ul li .front {
+ display: block;
+ position: relative;
+ padding: 12px 42px;
+ color: white;
+ background: hsl(188, 88%, 29%);
+ will-change: transform;
+ transform: translateY(-4px);
+ transition: transform 600ms cubic-bezier(0.3, 0.7, 0.4, 1);
+}
+section#mid #timers #timers-menu ul li .pushable:hover {
+ filter: brightness(110%);
+}
+section#mid #timers #timers-menu ul li .pushable:hover .front {
+ transform: translateY(-6px);
+ transition: transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5);
+}
+section#mid #timers #timers-menu ul li .pushable:active .front {
+ transform: translateY(-2px);
+ transition: transform 34ms;
+}
+section#mid #timers #timers-menu ul li .pushable:hover .shadow {
+ transform: translateY(4px);
+ transition: transform 250ms cubic-bezier(0.3, 0.7, 0.4, 1.5);
+}
+section#mid #timers #timers-menu ul li .pushable:active .shadow {
+ transform: translateY(1px);
+ transition: transform 34ms;
+}
+section#mid #timers #timers-menu ul li .pushable:focus:not(:focus-visible) {
+ outline: none;
+}
+section#mid #timers #timers-menu ul li .pushable-f .front,
+section#mid #timers #timers-menu ul li .pushable-f .edge,
+section#mid #timers #timers-menu ul li .pushable-f .shadow {
+ border-top-left-radius: 13px;
+ border-bottom-left-radius: 13px;
+}
+section#mid #timers #timers-menu ul li .pushable-f .edge {
+ background: linear-gradient(to left, hsl(235, 84%, 26%) 0%, hsl(235, 84%, 26%) 8%, hsl(235, 84%, 26%) 92%, hsl(193, 100%, 30%) 100%);
+}
+section#mid #timers #timers-menu ul li .pushable-l .front,
+section#mid #timers #timers-menu ul li .pushable-l .edge,
+section#mid #timers #timers-menu ul li .pushable-l .shadow {
+ border-top-right-radius: 13px;
+ border-bottom-right-radius: 13px;
+}
+section#mid #timers #timers-menu ul li .pushable-l .edge {
+ background: linear-gradient(to left, hsl(193, 100%, 30%) 0%, hsl(235, 84%, 26%) 8%, hsl(235, 84%, 26%) 92%, hsl(235, 84%, 26%) 100%);
+}
+section#mid #timers #timers-menu ul li .front {
+ font-size: medium;
+ font-weight: 500;
+}
+section#mid #timers #stopwatch {
+ display: none;
+ flex-direction: column;
+}
+section#mid #timers #stopwatch .timer {
+ font-size: 100px;
+ display: flex;
+ align-self: center;
+}
+section#mid #timers #stopwatch .timer .min,
+section#mid #timers #stopwatch .timer .sec,
+section#mid #timers #stopwatch .timer .msec {
+ width: 10vw;
+}
+section#mid #timers #timer {
+ display: none;
+ flex-direction: column;
+}
+section#mid #timers #timer .timer {
+ font-size: xx-large;
+}
+section#mid #yemek-listesi {
+ display: none;
+ flex-direction: column;
+}
+section#mid #animations {
+ display: none;
+ flex-direction: column;
+}
+section#bottom {
+ margin-top: auto;
+}
+section#bottom #rainbow {
+ width: 100%;
+ height: 20px;
+ animation: rain 4.72s ease infinite;
+}
+
+.kronometre {
+ text-align: center;
+ margin: auto;
+ font-size: 50px;
+}
+
+/*# sourceMappingURL=main.css.map */
diff --git a/iflpanel/tahta/assets/css/main.css.map b/iflpanel/tahta/assets/css/main.css.map
new file mode 100644
index 0000000..dff5235
--- /dev/null
+++ b/iflpanel/tahta/assets/css/main.css.map
@@ -0,0 +1 @@
+{"version":3,"sourceRoot":"","sources":["../scss/main.scss","../scss/_animation.scss","../scss/_button.scss"],"names":[],"mappings":";AAAA;ACAA;AAEA;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;ADZJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;;;AAMA;EACE;EACA;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAWZ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGE;EACE;EACA;EACA;;AAEA;EAEE;EACA;;AEnKV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA,YACE;;AAGJ;EACE;EACA;EACA;EACA;EACA;EAEA;;AAOF;EACE;EACA;EACA;EAGA;EACA;EACA;EACA;EACA,YACE;;AAGJ;EACE;;AAGF;EACE;EACA,YACE;;AAGJ;EACE;EACA;;AAGF;EACE;EACA,YACE;;AAGJ;EACE;EACA;;AAGF;EACE;;AAKA;AAAA;AAAA;EAGE;EACA;;AAGF;EACE;;AAUF;AAAA;AAAA;EAIE;EACA;;AAGF;EACE;;AFwDM;EACE;EACA;;AAOR;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;AAAA;AAAA;EAGE;;AAKN;EACE;EACA;;AAEA;EACE;;AAMN;EACE;EACA;;AAGF;EACE;EACA;;AAMJ;EACE;;AAEA;EACE;EACA;EACA;;;AAKN;EACE;EACA;EACA","file":"main.css"}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/js/dev.js b/iflpanel/tahta/assets/js/dev.js
new file mode 100644
index 0000000..47acc79
--- /dev/null
+++ b/iflpanel/tahta/assets/js/dev.js
@@ -0,0 +1,2 @@
+// 2023 © Aliberk Sandıkçı
+// Temporary Development File
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/js/initialize.js b/iflpanel/tahta/assets/js/initialize.js
new file mode 100644
index 0000000..84ef7e4
--- /dev/null
+++ b/iflpanel/tahta/assets/js/initialize.js
@@ -0,0 +1,120 @@
+// 2023 © Aliberk Sandıkçı
+// Initialize Variables / Arrays / Maps and first functions
+// Import after utils, updates, and mid js files!
+
+// CONSTANT VARIABLES
+const allButtons = [
+ "timers-button",
+ "yemekhane-button",
+ "ders-programi",
+ "animation-button",
+ "settings-button",
+ "stopwatch-button",
+ "timer-button"
+];
+
+const allCheckboxes = [
+ "chx-clockSecond",
+ "chx-timerMsec",
+ "chx-devVersion",
+ "chx-yksTimer",
+ "chx-fullscreenClock",
+ "chx-hideHeader",
+];
+
+const midItems = ["timers", "yemek-listesi", "animations", "ders-programi"];
+const timersItems = ["stopwatch", "timer"];
+
+const schoolPeriods = {
+ ["lessonStarts"]: ["08-40", "09-30", "10-20", "11-10", "12-00", "13-30", "14-20", "15-10"],
+ ["lessonEnds"]: ["09-20", "10-10", "11-00", "11-50", "12-40", "14-10", "15-00", "15-50"],
+};
+
+// VARIABLES
+var specialPeriods = {
+ ["launchStart"]: "12-40",
+ ["schoolEnds"]: "15-50",
+};
+
+var localSettings = {
+ ["local-grade"]: "Sınıf",
+ ["local-class"]: "Şube",
+}
+
+var curVals = [
+ "clockSecond",
+ "timerMsec",
+ "devVersion",
+ "yksTimer",
+ "fullscreenClock",
+ "hideHeader",
+]
+
+var curSeconds;
+var curMin;
+var curHour;
+
+const confs = new Map();
+
+FirstInitialization();
+var t = setInterval(DEVupdateSettings, 100);
+var t2 = setInterval(updateComponents, 100);
+
+
+function FirstInitialization() {
+ getVariablesToConfig();
+ getFormInputs();
+ getURLSettings();
+ updateFormInputs();
+
+ // Update Beginning Components
+ console.log(confs.get("local-grade"));
+ setToID("grade", confs.get("local-grade"), "Sınıf");
+ setToID("class", confs.get("local-class"), "Şube");
+
+ updateComponents();
+}
+
+
+function getVariablesToConfig() {
+ addObjectToConfig(localSettings, 1);
+}
+
+function getFormInputs() {
+ allCheckboxes.forEach(element => {
+ let chx = document.getElementById(element);
+ if (chx.checked) {
+ confs.set(element.slice(4), "1");
+ } else {
+ confs.set(element.slice(4), "0");
+ }
+ });
+}
+
+function getURLSettings() {
+ const queryString = window.location.search;
+ const urlParams = new URLSearchParams(queryString);
+
+ addArrayToConfig(allCheckboxes, urlParams);
+ addArrayToConfig(curVals, urlParams);
+ addObjectToConfig(localSettings, urlParams);
+ addObjectToConfig(specialPeriods, urlParams);
+}
+
+
+/**
+ * Update form inputs with local variables and user changed options
+ */
+function updateFormInputs() {
+ confs.forEach((val, key) => {
+ if (allCheckboxes.includes("chx-" + key)) {
+ if (val == "0") {
+ document.getElementById("chx-" + key).checked = false;
+ } else {
+ document.getElementById("chx-" + key).checked = true;
+ }
+ }
+ });
+}
+
+
diff --git a/iflpanel/tahta/assets/js/old_main.js b/iflpanel/tahta/assets/js/old_main.js
new file mode 100644
index 0000000..754fdb1
--- /dev/null
+++ b/iflpanel/tahta/assets/js/old_main.js
@@ -0,0 +1,139 @@
+// 2023 Aliberk Sandıkçı
+
+// VARIABLES
+var FlagSecond = 0;
+var FlagSettings = 0;
+var FlagTimers = 1;
+var MidItems = ["timers", "stopwatch", "timer", "yemek-listesi", "animations"]
+
+// RUN FUNCTIONS ON START
+updateTime();
+if (FlagSettings) { toggleSettings() }
+if (FlagTimers) { toggleTimers() }
+
+// RUN FUNCTIONS PERIODICALLY
+var t = setInterval(updateTime, 1000);
+
+
+//
+// MAIN FUNCTIONS
+//
+
+function updateTime() {
+ var d = new Date();
+ var curHour = getDigits(d.getHours(), 2);
+ var curMin = getDigits(d.getMinutes(), 2);
+ var curSeconds = getDigits(d.getSeconds(), 2);
+
+ if (FlagSecond) {
+ document.getElementById("time").innerHTML = curHour + "." + curMin + "." + curSeconds;
+ } else {
+ document.getElementById("time").innerHTML = curHour + "." + curMin;
+ }
+
+ if (curHour == 12 && (curMin >= 24 && curMin <= 30)) {
+ document.getElementById("time").style.color = "red";
+ document.getElementById("rainbow").style.display = "inherit";
+ } else {
+ document.getElementById("time").style.color = "inherit";
+ document.getElementById("rainbow").style.display = "none";
+ }
+}
+
+function toggleClockSeconds() {
+ let chx = document.getElementById("chx-clockSecond");
+ if (chx.checked) {
+ FlagSecond = 1;
+ } else {
+ FlagSecond = 0;
+ }
+ updateTime();
+}
+
+function toggleDevVersion() {
+ let chx = document.getElementById("chx-devVersion");
+ if (chx.checked) {
+ window.location.replace("dev.html" + window.location.search);
+ } else {
+ window.location.replace("index.html" + window.location.search);
+ }
+}
+
+function toggleSettings() {
+ let settings = document.getElementById("settings");
+ console.log(settings.style.display);
+ if (settings.style.display == "flex") {
+ settings.style.display = "none";
+ } else {
+ settings.style.display = "flex";
+ }
+}
+
+function toggleTimers(typ = "display") {
+ switch (typ) {
+ case "stopwatch":
+ hideMidAll("stopwatch", "timers");
+ toggleItem("id", "stopwatch");
+ break;
+ case "timer":
+ hideMidAll("timer", "timers");
+ toggleItem("id", "timer");
+ break;
+ default: // "display"
+ hideMidAll("timers");
+ toggleItem("id", "timers");
+ break;
+ }
+}
+
+function toggleYemekListesi() {
+ hideMidAll("yemek-listesi");
+ toggleItem("id", "yemek-listesi");
+}
+
+function toggleAnimations() {
+ hideMidAll("animations");
+ toggleItem("id", "animations");
+}
+
+
+// -----------------------------------------
+// UTILITIES
+//
+
+function getDigits(str, num) {
+ return ("0" + str).slice(-num);
+}
+
+/**
+ *
+ * @param {...any} except
+ */
+function hideMidAll(...except) {
+ MidItems.forEach(element => {
+ if (!except.includes(element)) {
+ document.getElementById(element).style.display = "none";
+ }
+ });
+}
+
+/** type: id, class
+ *
+ * name: id or class name
+ */
+function toggleItem(type, name) {
+ switch (type) {
+ case "id":
+ let item = document.getElementById(name);
+ if (item.style.display == "flex") {
+ item.style.display = "none";
+ } else {
+ item.style.display = "flex";
+ }
+ break;
+
+ default:
+ console.error("no toggle item except ids!");
+ break;
+ }
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/js/old_stopwatch.js b/iflpanel/tahta/assets/js/old_stopwatch.js
new file mode 100644
index 0000000..1f51c49
--- /dev/null
+++ b/iflpanel/tahta/assets/js/old_stopwatch.js
@@ -0,0 +1,91 @@
+var curAction = "wait";
+var previousAction = "wait"
+var startTime = new Date();
+var curTime = new Date();
+var timeMS = 0;
+var FlagMilisecond = 1;
+var timer = document.getElementById("stopwatch").getElementsByClassName("timer")[0];
+
+tick();
+
+// NOT OPTIMIZED, place in start switch
+var t = setInterval(tick, 10);
+
+
+
+function Stopwatch(action) {
+ switch (action) {
+ case "start":
+ console.log("start function started");
+ if (previousAction == "start") { break; }
+ startTime = new Date();
+ curAction = "increase";
+ tick();
+ previousAction = "start";
+ break;
+ case "stop":
+ curAction = "stop";
+ tick();
+ previousAction = "stop";
+ break;
+
+ default:
+ // console.error("no action (old script)");
+ break;
+ }
+}
+
+function updateMsec() {
+ timer.getElementsByClassName("msec")[0].innerHTML = getDigits(Math.floor((timeMS / 10) % 100), 2);
+}
+
+function updateSec() {
+ timer.getElementsByClassName("sec")[0].innerHTML = getDigits(Math.floor((timeMS / 1000) % 60), 2);
+}
+
+function updateMin() {
+ timer.getElementsByClassName("min")[0].innerHTML = getDigits(Math.floor((timeMS / 1000 / 60) << 0), 2);
+}
+
+
+function getDigits(str, num) {
+ return ("0" + str).slice(-num);
+}
+
+function tick() {
+ switch (curAction) {
+ case "increase":
+ curTime = new Date();
+ timeMS = (curTime.getTime() - startTime.getTime());
+ if (FlagMilisecond) {
+ updateMsec();
+ }
+ updateSec();
+ updateMin();
+ break;
+ case "stop":
+ timer.getElementsByClassName("min")[0].innerHTML = "00";
+ timer.getElementsByClassName("sec")[0].innerHTML = "00";
+ timer.getElementsByClassName("msec")[0].innerHTML = "00";
+ curAction = "wait";
+ previousAction = "stop"
+ break;
+ default:
+ // console.error("no action (old script)");
+ break;
+ }
+}
+
+function toggleTimerMsec() {
+ let chx = document.getElementById("chx-timerMsec");
+ if (chx.checked) {
+ FlagMilisecond = 1;
+ timer.getElementsByClassName("msec")[0].style.display = "flex";
+ document.getElementById("stopwatch-msec-dot").style.display = "flex";
+ } else {
+ FlagMilisecond = 0;
+ timer.getElementsByClassName("msec")[0].style.display = "none";
+ document.getElementById("stopwatch-msec-dot").style.display = "none";
+ }
+ tick();
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/js/timers.js b/iflpanel/tahta/assets/js/timers.js
new file mode 100644
index 0000000..307dc3a
--- /dev/null
+++ b/iflpanel/tahta/assets/js/timers.js
@@ -0,0 +1,81 @@
+// OLD TIMER SCRIPT !!!
+
+
+var curAction = "wait";
+var previousAction = "wait"
+var startTime = new Date();
+var curTime = new Date();
+var timeMS = 0;
+var FlagMilisecond = 1;
+var timer = document.getElementById("stopwatch").getElementsByClassName("timer")[0];
+
+tick();
+
+// NOT OPTIMIZED, place in start switch
+var t = setInterval(tick, 10);
+
+
+
+function Stopwatch(action) {
+ switch (action) {
+ case "start":
+ console.log("start function started");
+ if (previousAction == "start") { break; }
+ startTime = new Date();
+ curAction = "increase";
+ tick();
+ previousAction = "start";
+ break;
+ case "stop":
+ curAction = "stop";
+ tick();
+ previousAction = "stop";
+ break;
+
+ default:
+ console.warn("Stopwatch() is working, possible unoptimized, WIP!");
+ break;
+ }
+}
+
+function updateMsec() {
+ timer.getElementsByClassName("msec")[0].innerHTML = getDigits(Math.floor((timeMS / 10) % 100), 2);
+}
+
+function updateSec() {
+ timer.getElementsByClassName("sec")[0].innerHTML = getDigits(Math.floor((timeMS / 1000) % 60), 2);
+}
+
+function updateMin() {
+ timer.getElementsByClassName("min")[0].innerHTML = getDigits(Math.floor((timeMS / 1000 / 60) << 0), 2);
+}
+
+
+// no need, already in utils.js
+// function getDigits(str, num) {
+// return ("0" + str).slice(-num);
+// }
+
+function tick() {
+ switch (curAction) {
+ case "increase":
+ curTime = new Date();
+ timeMS = (curTime.getTime() - startTime.getTime());
+ if (confs.get('timerMsec') == "1") {
+ updateMsec();
+ }
+ updateSec();
+ updateMin();
+ break;
+ case "stop":
+ timer.getElementsByClassName("min")[0].innerHTML = "00";
+ timer.getElementsByClassName("sec")[0].innerHTML = "00";
+ timer.getElementsByClassName("msec")[0].innerHTML = "00";
+ curAction = "wait";
+ previousAction = "stop"
+ break;
+ default:
+ console.warn("tick() is working, possible unoptimized, WIP!");
+ break;
+ }
+}
diff --git a/iflpanel/tahta/assets/js/updates.js b/iflpanel/tahta/assets/js/updates.js
new file mode 100644
index 0000000..8b4e841
--- /dev/null
+++ b/iflpanel/tahta/assets/js/updates.js
@@ -0,0 +1,47 @@
+/**
+ * Update components with conf variables each second
+ */
+function updateComponents() {
+ setToID("time", updateTime());
+
+ if (curHour == 12 && (curMin >= 24 && curMin <= 30)) {
+ document.getElementById("time").style.color = "red";
+ document.getElementById("rainbow").style.display = "inherit";
+ } else {
+ document.getElementById("time").style.color = "inherit";
+ document.getElementById("rainbow").style.display = "none";
+ }
+
+ let timer = document.getElementById("stopwatch").getElementsByClassName("timer")[0];
+ if (confs.get("timerMsec") == 1) {
+ timer.getElementsByClassName("msec")[0].style.display = "flex";
+ document.getElementById("stopwatch-msec-dot").style.display = "flex";
+ } else {
+ timer.getElementsByClassName("msec")[0].style.display = "none";
+ document.getElementById("stopwatch-msec-dot").style.display = "none";
+ }
+}
+
+function updateTime() {
+ var d = new Date();
+ curHour = getDigits(d.getHours(), 2);
+ curMin = getDigits(d.getMinutes(), 2);
+ curSeconds = getDigits(d.getSeconds(), 2);
+
+ if (confs.get("clockSecond") == "1") {
+ return curHour + "." + curMin + "." + curSeconds;
+ } else {
+ return curHour + "." + curMin;
+ }
+}
+
+function DEVupdateSettings() {
+ let devData =
+ "confs: " + JSON.stringify(confs, (key, value) => (value instanceof Map ? [...value] : value)) + "
" +
+ "schoolPeriods: " + JSON.stringify(schoolPeriods, (key, value) => (value instanceof Map ? [...value] : value)) + "
" +
+ "specialPeriods: " + JSON.stringify(specialPeriods, (key, value) => (value instanceof Map ? [...value] : value)) + "
" +
+ "info: " + navigator.userAgent + "
" +
+ "local-settings:" + (urlParams = new URLSearchParams(window.location.search)) + "
";
+
+ document.getElementById("DEV").innerHTML = devData;
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/js/utils.js b/iflpanel/tahta/assets/js/utils.js
new file mode 100644
index 0000000..5d4ce75
--- /dev/null
+++ b/iflpanel/tahta/assets/js/utils.js
@@ -0,0 +1,130 @@
+function getDigits(str, num) {
+ return ("0" + str).slice(-num);
+}
+
+/**
+ *
+ * @param {Object} obj
+ * @param {URLSearchParams} params
+ */
+function addObjectToConfig(obj, params) {
+ Object.entries(obj).forEach(element => {
+ const [key, value] = element;
+ if (params == 1) {
+ confs.set(key, value);
+ }
+ else if (params.has(key)) {
+ confs.set(key, params.get(key));
+ }
+ });
+}
+
+/**
+ *
+ * @param {Array} arr
+ * @param {URLSearchParams} params
+ */
+function addArrayToConfig(arr, params) {
+ arr.forEach(element => {
+ if (params.has(element)) {
+ confs.set(element, params.get(element));
+ }
+ });
+}
+
+/**
+ *
+ * @param {string} id id to be updated
+ * @param {string} config config to update with
+ * @param {any} type type
+ */
+function setToID(id, config, type = 0) {
+ let obj = document.getElementById(id)
+ if (obj.innerHTML != config && type == 0) {
+ document.getElementById(id).innerHTML = config;
+ } else if (typeof type === 'string') {
+ if (config == type) {
+ document.getElementById(id).innerHTML = "" + config + "";
+ } else if (config != type) {
+ document.getElementById(id).innerHTML = config;
+ }
+ }
+}
+
+/**
+ * Hides all elements with matching id in a list
+ * @param {Array} elements element ids to hide
+ * @param {...any} except hide elements except these
+ */
+function hideAllExcept(elements, ...except) {
+ elements.forEach(element => {
+ if (!except.includes(element)) {
+ document.getElementById(element).style.display = "none";
+ }
+ });
+}
+
+/**
+ * @param {String} type id or class for getting elements to toggle
+ * @param {String} name id or class name
+ * @param {String} display display type, defaults to flex
+ */
+function toggleItemDisplay(type, name = "no", display = "flex") {
+ switch (type) {
+ case "auto":
+ if (name == "no") {
+ // console.log(1, event.srcElement.id); // DEPRECATED !
+ console.alert('dont use type auto for item display! WIP')
+ // get id with button/checkbox name! and auto detect
+ }
+ break;
+ case "id":
+ let item = document.getElementById(name);
+ if (item.style.display == display) {
+ item.style.display = "none";
+ } else {
+ item.style.display = display;
+ }
+ if (midItems.includes(name)) {
+ hideAllExcept(midItems, name);
+ } else if (timersItems.includes(name)) {
+ hideAllExcept(timersItems, name);
+ }
+ break;
+ default:
+ console.error("no toggle item except ids!");
+ break;
+ }
+}
+
+function toggleConf(type, name = "no") {
+ switch (type) {
+ case "auto":
+ // AUTO DETECT type, id etc.
+ alert("dont use auto for toggleConf");
+ break;
+ case "id-chx":
+ if (name != "no") {
+ let chx = document.getElementById("chx-" + name);
+ if (chx.checked) {
+ confs.set(name, 1);
+ } else {
+ confs.set(name, 0);
+ }
+ }
+ break;
+ default:
+ console.error("unvalid type");
+ break;
+ }
+}
+
+function toggleDevVersion() {
+ let chx = document.getElementById("chx-devVersion");
+
+ if (chx.checked) {
+ window.location.replace("dev.html" + window.location.search);
+ } else {
+ window.location.replace("index.html" + window.location.search);
+ }
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/scss/_animation.scss b/iflpanel/tahta/assets/scss/_animation.scss
new file mode 100644
index 0000000..4783659
--- /dev/null
+++ b/iflpanel/tahta/assets/scss/_animation.scss
@@ -0,0 +1,19 @@
+/* 2023 Aliberk Sandıkçı*/
+
+@keyframes rain {
+ 0% {
+ background-color: white;
+ }
+
+ 25% {
+ background-color: red;
+ }
+
+ 50% {
+ background-color: green;
+ }
+
+ 100% {
+ background-color: yellow;
+ }
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/scss/_button.scss b/iflpanel/tahta/assets/scss/_button.scss
new file mode 100644
index 0000000..c57f944
--- /dev/null
+++ b/iflpanel/tahta/assets/scss/_button.scss
@@ -0,0 +1,122 @@
+// CREDIT: https://www.joshwcomeau.com/animation/3d-button/
+
+@mixin button-effect {
+ .pushable {
+ position: relative;
+ border: none;
+ background: transparent;
+ padding: 0;
+ cursor: pointer;
+ outline-offset: 4px;
+ transition: filter 250ms;
+ }
+
+ .shadow {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ // border-radius: 12px;
+ background: hsl(0deg 0% 0% / 0.25);
+ will-change: transform;
+ transform: translateY(2px);
+ transition:
+ transform 600ms cubic-bezier(.3, .7, .4, 1);
+ }
+
+ .edge {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ // border-radius: 12px;
+ background: linear-gradient(to left,
+ hsl(235, 84%, 26%) 0%,
+ hsl(235, 84%, 26%) 8%,
+ hsl(235, 84%, 26%) 92%,
+ hsl(235, 84%, 26%) 100%);
+ }
+
+ .front {
+ display: block;
+ position: relative;
+ padding: 12px 42px;
+ // border-radius: 12px;
+ // font-size: 1.25rem;
+ color: white;
+ background: hsl(188, 88%, 29%);
+ will-change: transform;
+ transform: translateY(-4px);
+ transition:
+ transform 600ms cubic-bezier(.3, .7, .4, 1);
+ }
+
+ .pushable:hover {
+ filter: brightness(110%);
+ }
+
+ .pushable:hover .front {
+ transform: translateY(-6px);
+ transition:
+ transform 250ms cubic-bezier(.3, .7, .4, 1.5);
+ }
+
+ .pushable:active .front {
+ transform: translateY(-2px);
+ transition: transform 34ms;
+ }
+
+ .pushable:hover .shadow {
+ transform: translateY(4px);
+ transition:
+ transform 250ms cubic-bezier(.3, .7, .4, 1.5);
+ }
+
+ .pushable:active .shadow {
+ transform: translateY(1px);
+ transition: transform 34ms;
+ }
+
+ .pushable:focus:not(:focus-visible) {
+ outline: none;
+ }
+
+ .pushable-f {
+
+ .front,
+ .edge,
+ .shadow {
+ border-top-left-radius: 13px;
+ border-bottom-left-radius: 13px;
+ }
+
+ .edge {
+ background: linear-gradient(to left,
+ hsl(235, 84%, 26%) 0%,
+ hsl(235, 84%, 26%) 8%,
+ hsl(235, 84%, 26%) 92%,
+ hsl(193, 100%, 30%) 100%);
+ }
+ }
+
+ .pushable-l {
+
+ .front,
+ .edge,
+ .shadow {
+
+ border-top-right-radius: 13px;
+ border-bottom-right-radius: 13px;
+ }
+
+ .edge {
+ background: linear-gradient(to left,
+ hsl(193, 100%, 30%) 0%,
+ hsl(235, 84%, 26%) 8%,
+ hsl(235, 84%, 26%) 92%,
+ hsl(235, 84%, 26%) 100%);
+ }
+ }
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/scss/dev.scss b/iflpanel/tahta/assets/scss/dev.scss
new file mode 100644
index 0000000..2358c9c
--- /dev/null
+++ b/iflpanel/tahta/assets/scss/dev.scss
@@ -0,0 +1,22 @@
+/* 2023 Aliberk Sandıkçı*/
+
+#ders-programi {
+ display: none;
+ flex-direction: column;
+ padding: 0px 100px;
+ padding-top: 10px;
+
+ img {
+ max-width: 1309px;
+ max-height: 601px;
+ aspect-ratio: 1309/601;
+ }
+}
+
+.min,
+.sec,
+.msec {
+ display:flex;
+ width: 7vw;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/assets/scss/main.scss b/iflpanel/tahta/assets/scss/main.scss
new file mode 100644
index 0000000..752a40f
--- /dev/null
+++ b/iflpanel/tahta/assets/scss/main.scss
@@ -0,0 +1,236 @@
+/* 2023 Aliberk Sandıkçı*/
+@use "button" as b;
+@use "animation" as a;
+
+* {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+}
+
+body,
+html {
+ display: flex;
+ flex-direction: column;
+
+ margin: 0px;
+ height: 100%;
+ width: 100%;
+
+ background-color: black;
+ color: aliceblue;
+ font-family: "Montserrat", Arial, Helvetica, sans-serif;
+}
+
+section {
+
+ // SECTION TOP
+ top {
+ display: flex;
+ justify-content: space-around;
+ user-select: none;
+
+ width: 100%;
+ height: 100px;
+
+ .class {
+ margin: 5px;
+ min-width: 20vw;
+ margin-right: auto;
+ font-weight: 800;
+ font-style: oblique;
+ }
+
+ .clock {
+ display: flex;
+
+ #time {
+ display: flex;
+
+ //UNNECESSARY LINES?
+ align-items: center;
+ align-self: center;
+ align-content: center;
+ justify-items: center;
+ justify-self: center;
+ justify-content: center;
+ font-size: 80px;
+ }
+ }
+
+ .settings-box {
+ min-width: 20vw;
+ margin-left: auto;
+ text-align: right;
+
+ button {
+ height: 30px;
+ width: 30px;
+ line-height: 20px;
+ }
+
+ #settings {
+ display: none;
+ flex-direction: column;
+ align-items: end;
+ font-size: small;
+ margin-top: 5px;
+
+
+ form {
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ background-color: grey;
+
+ .cell {
+ float: left;
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 1vh;
+
+ input[type="checkbox"] {
+ //UNNECESSARY LINES?
+ appearance: none;
+ background-color: #fff;
+ margin: 0;
+ width: 1.15em;
+ height: 1.15em;
+ border: 0.15em solid darkslateblue;
+ border-radius: 0.15em;
+ transform: translateY(-0.075em);
+ display: grid;
+ place-content: center;
+ outline: 0px solid white;
+ outline-offset: 0px;
+
+ &::before {
+ //UNNECESSARY LINES?
+ content: "";
+ width: 0.65em;
+ height: 0.65em;
+ transform: scale(0);
+ transition: 120ms transform ease-in-out;
+ box-shadow: inset 1em 1em green;
+ transform-origin: bottom left;
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
+ }
+
+ &:checked::before {
+ transform: scale(1);
+ }
+
+ &:focus {
+ outline: max(2px, 0.15em) solid white;
+ outline-offset: max(2px, 0.15em);
+ }
+ }
+
+ label {
+ padding-left: 5px;
+ display: block;
+ text-align: left;
+ align-self: center;
+ }
+ }
+ }
+
+
+ }
+ }
+ }
+
+ // SECTION MID
+ mid {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ user-select: none;
+
+ #timers {
+ display: none;
+ flex-direction: column;
+
+ #timers-menu {
+ ul {
+ display: flex;
+ justify-content: center;
+ padding: 0;
+
+ li {
+ // padding: 1px;
+ list-style-type: none;
+ box-sizing: border-box;
+
+ @include b.button-effect;
+
+ .front {
+ font-size: medium;
+ font-weight: 500;
+ }
+ }
+ }
+
+ }
+
+ #stopwatch {
+ display: none;
+ flex-direction: column;
+
+ .timer {
+ font-size: 100px;
+ display: flex;
+ align-self: center;
+
+ .min,
+ .sec,
+ .msec {
+ width: 10vw;
+ }
+ }
+ }
+
+ #timer {
+ display: none;
+ flex-direction: column;
+
+ .timer {
+ font-size: xx-large;
+ }
+ }
+
+ }
+
+ #yemek-listesi {
+ display: none;
+ flex-direction: column;
+ }
+
+ #animations {
+ display: none;
+ flex-direction: column;
+ }
+
+ }
+
+ // SECTION BOTTOM
+ bottom {
+ margin-top: auto;
+
+ #rainbow {
+ width: 100%;
+ height: 20px;
+ animation: rain 4.72s ease infinite;
+ }
+ }
+}
+
+.kronometre {
+ text-align: center;
+ margin: auto;
+ font-size: 50px;
+}
\ No newline at end of file
diff --git a/iflpanel/tahta/dev.html b/iflpanel/tahta/dev.html
new file mode 100644
index 0000000..21dac80
--- /dev/null
+++ b/iflpanel/tahta/dev.html
@@ -0,0 +1,192 @@
+
+
+
+
yapım aşamasında: geriye doğru sayma özelliği
+yapım aşamasında: geriye doğru sayma özelliği
+