XTRAJW55GQBNSQ2I5JYTPOYCYZ745XQ5EEB6ETAV7HFUAFFYJM3QC /* http://meyerweb.com/eric/tools/css/reset/v2.0 | 20110126License: none (public domain)*/html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed,figure, figcaption, footer, header, hgroup,menu, nav, output, ruby, section, summary,time, mark, audio, video {margin: 0;padding: 0;border: 0;font-size: 100%;font: inherit;vertical-align: baseline;}/* HTML5 display-role reset for older browsers */article, aside, details, figcaption, figure,footer, header, hgroup, menu, nav, section {display: block;}body {line-height: 1;}ol, ul {list-style: none;}blockquote, q {quotes: none;}blockquote:before, blockquote:after,q:before, q:after {content: '';content: none;}table {border-collapse: collapse;border-spacing: 0;}
#ett-header {background-color: rgb(220, 223, 238);border-radius: 4px;padding: .3em;font-family: sans-serif, monospace;font-weight: bolder;}#ett-title,#ett-date-container {font-size: 2em;line-height: 1.3em;border-radius: 4px;}#ett-title {color: steelblue;}#ett-date-container {background-color: white;color: #607072;text-align: center;}#ett-date {font-family: sans-serif, monospace;font-size: 1em;line-height: 1.3em;text-align: center;}.ett-task-name,.ett-task-time,.ett-task-total{height: 3em;padding: 0px;}.ett-task-index {border: solid 2px;border-radius: 4px;width: 17px;height: 17px;margin: 0px;text-align: center;margin-right: 4px;font-family: sans-serif, monospace;line-height: 17px;background-color: white;border-color: steelblue;color: steelblue;}.ett-major-task .ett-task-index {font-weight: bold;background-color: darkorange;border-color: darkorange;color: white;}.task-header {margin-top: 2em;}.task-header .ett-task-time {color: darkorange;font-family: sans-serif, monospace;font-weight: bold;user-select:none;-o-user-select:none;-ms-user-select:none;-moz-user-select: none;-webkit-user-select: none;}.task-header .ett-task-name input {color: steelblue;font-family: sans-serif, monospace;font-weight: bolder;font-size: 1em;word-wrap: wrap;}.ett-task-name input {height: 21px;text-indent: .2em;border: none;border-bottom: solid 2px steelblue;border-bottom-left-radius: 8px;border-top: 0px;border-top-left-radius: 0px;}.ett-task-name input:focus {outline: none;}@media only screen and (max-width: 1190px) {.ett-task-name input {border-bottom: 0px;border-bottom-left-radius: 0px;border-top: solid 2px steelblue;border-top-left-radius: 8px;}}.ett-task-total {min-width: 3em;max-width: 4em;border: none;font-family: sans-serif, monospace;text-align: right;font-size: .8em;}.task-header .ett-task-total {font-weight: bold;}.task-header .ett-task-time {position: relative;overflow: visible;}.task-header .ett-task-time .bubble-hour-break:nth-child(1)::before {content: "start";font-family: sans-serif, monospace;font-size: .75em;position: absolute;top: .3em;left: -2.5em;}.bubble-hour-break {border-left: solid 1px darkorange;}.bubble-15m {border-color: steelblue;background-color: #FFF;}.bubble-15m.bubble3 > .bubble-5m {border-color: rgba(70,130,180,.5);background-color: #FFF;}.bubble-hour[data-hour="6"] .bubble-15m,.bubble-hour[data-hour="12"] .bubble-15m,.bubble-hour[data-hour="18"] .bubble-15m {border-color: darkorange;}.bubble-hour[data-hour="6"] .bubble-15m.bubble3 > .bubble-5m:nth-child(2),.bubble-hour[data-hour="12"] .bubble-15m.bubble3 > .bubble-5m:nth-child(2),.bubble-hour[data-hour="18"] .bubble-15m.bubble3 > .bubble-5m:nth-child(2) {border-color: rgba(255,165,0,.5);}.bubble-15m.fill,.bubble-15m.bubble3 > .bubble-5m.fill {background-color: #607072;}.task-header .ett-task-name input,.task-header .ett-task-total {border-color: transparent;}#task-subheader.task-header .ett-task-total {visibility: hidden;}#ett-date-container .datepicker {font-size: 50%;filter: drop-shadow(0rem .5rem .5rem rgb(54, 40, 22));}#ett-date-container .datepicker-cell.prev:not(.disabled),#ett-date-container .datepicker-cell.next:not(.disabled) {font-size: 80%;color: #9a9a9a;}#ett-date-container .datepicker-controls .button:hover,#ett-date-container .datepicker-cell:not(.disabled):not(.selected):hover {background-color: #cddbf3;}
#ett-header {display: flex;flex-direction: row;flex-wrap: wrap;margin: 0px;border: solid 0px red;}#ett-title {flex-grow: 3;}#ett-date-container {flex-grow: 1;display: flex;border: solid 0px orange;position: relative;}#ett-date {border: 0px;margin: 0px;padding: 0px;background-color: transparent;width: 100%;height: 100%;border: solid 0px red;}.ett-task {display: flex;flex-direction: row;flex-wrap: wrap;margin: 0px;border: solid 0px red;}.ett-task-index {margin: 0px;padding: 0px;}.ett-task-name {margin: 0px;padding: 0px;flex-grow: 1;flex-shrink: 1;min-width: 313px;}.ett-task-name input {margin: 0px;padding: 0px;border: 0px;width: 100%;min-width: 313px;border: solid 1px black;}.task-header .ett-task-index {visibility: hidden;}.task-header .ett-task-name input {position: relative;left: -1.5em;}.ett-task-total {flex-grow: 1;width: 4em;}.ett-task-time {flex-grow: 2;display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: space-evenly;margin: 0px;padding: 0px;max-width: 850px;min-width: 785px;}.bubble-hour {border: 0px;margin: 0px;padding: 0px;overflow: hidden;text-overflow: hidden;width: 3em;display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: space-evenly;}.bubble-hour-break {border: 0px;margin: 0px;padding: 0px;overflow: hidden;text-overflow: hidden;width: 0px;}.bubble-15m {border: solid 2px;border-radius: 4px;width: 6px;height: 17px;margin: 0px;display: flex;flex-direction: column;flex-wrap: wrap;justify-content: start;}.bubble-15m > .bubble-5m {visibility: hidden;}.bubble-15m.bubble3 > .bubble-5m {flex: 1;visibility: visible;overflow: hidden;margin: 0px;padding: 0px;border: 0px;width: 6px;height: 5px;}.bubble-15m.bubble3 > .bubble-5m:nth-child(1) {border-top-left-radius: 2px;border-top-right-radius: 2px;}.bubble-15m.bubble3 > .bubble-5m:nth-child(2) {border-top: dotted 1px;border-bottom: dotted 1px;}.bubble-15m.bubble3 > .bubble-5m:nth-child(3) {border-bottom-left-radius: 2px;border-bottom-right-radius: 2px;}
import { EttTask, BubbleHour, Bubble, Bubble3 } from './bubbles.js';document.addEventListener('DOMContentLoaded', function() {/// this should be dynamically loaded from local storageconst ettConfig = {date: new Date().toLocaleDateString('en-CA'),startHour: 7,numHours: 12,numTasks: 7,numMajor: 3,tasks: {1: {name: 'first task',hours: {7: { 15:15, 60:15 }}}}}/// pull ETT elements out of the DOMconst ettTemplate = document.getElementById('ett-task-template')const ettDate = document.getElementById('ett-date')const ettTaskContainer = document.getElementById('ett-tasks')const taskTemplate = ettTemplate.content.firstElementChild.cloneNode(true)const hourBreakTemplate = taskTemplate.querySelector('.bubble-hour-break').cloneNode(true)const hourTemplate = taskTemplate.querySelector('.bubble-hour').cloneNode(true)const bubbleTemplate = taskTemplate.querySelector('.bubble-15m').cloneNode(true)const header = taskTemplate.cloneNode(true)header.setAttribute('role','ett-header')const ettTotal = header.querySelector('.ett-task-total')const subHeader = taskTemplate.cloneNode(true)subHeader.setAttribute('role','ett-subheader')ettDate.value = ettConfig.date// add tasksfor ( let t=1; t<=ettConfig.numTasks; t++ ) {// new headerif ( t == 1 ) {// add top header - just a specially formatted taskheader.classList.add('task-header')// header titlelet headerInput = header.querySelector('.ett-task-name input')headerInput.value = 'THE MAJOR TASKS FOR TODAY'headerInput.setAttribute('readonly','readonly')// header hourslet hoursContainer = header.querySelector('.ett-task-time')hoursContainer.innerHTML = ''for ( let h=0; h<ettConfig.numHours; h++ ) {let newHour = hourTemplate.cloneNode(true)let hour = ettConfig.startHour+h;if ( hour > 12 ) { hour = hour - 12; hour += "PM" }else if ( hour == 12 ) { hour += "PM" }else if ( hour == 24 ) { hour += "AM" }else { hour += "AM" }newHour.innerHTML = hourlet newBreak = hourBreakTemplate.cloneNode(true)hoursContainer.appendChild(newBreak)hoursContainer.appendChild(newHour)}let newBreak = hourBreakTemplate.cloneNode(true)hoursContainer.appendChild(newBreak)header.setAttribute('id','task-header')header.setAttribute('data-date',ettConfig.date)ettTaskContainer.appendChild(header)// new sub-header} else if ( t == (ettConfig.numMajor+1) ) {// add sub header - just a specially formatted tasksubHeader.classList.add('task-header')// header titlelet headerInput = subHeader.querySelector('.ett-task-name input')headerInput.value = 'STUFF THAT "JUST HAPPENED"'headerInput.setAttribute('readonly','readonly')// header hourslet hoursContainer = subHeader.querySelector('.ett-task-time')hoursContainer.innerHTML = ''for ( let h=0; h<ettConfig.numHours; h++ ) {let newHour = hourTemplate.cloneNode(true)let hour = ettConfig.startHour+h;if ( hour > 12 ) { hour = hour - 12; hour += "PM" }else if ( hour == 12 ) { hour += "PM" }else if ( hour == 24 ) { hour += "AM" }else { hour += "AM" }newHour.innerHTML = hourlet newBreak = hourBreakTemplate.cloneNode(true)hoursContainer.appendChild(newBreak)hoursContainer.appendChild(newHour)}let newBreak = hourBreakTemplate.cloneNode(true)hoursContainer.appendChild(newBreak)subHeader.setAttribute('id','task-subheader')subHeader.setAttribute('data-date',ettConfig.date)ettTaskContainer.appendChild(subHeader)}// new emergent tasklet newTask = taskTemplate.cloneNode(true)let hourContainer = newTask.querySelector('.ett-task-time')if ( t in ettConfig.tasks && ettConfig.tasks[t].name ){let taskName = newTask.querySelector('.ett-task-name input')if ( taskName ) {taskName.value = ettConfig.tasks[t].name}}hourContainer.innerHTML = ''for ( let hh=0; hh<ettConfig.numHours; hh++ ) {let newHour = hourTemplate.cloneNode(true)let h = ettConfig.startHour+hh;let hourId = 'task-'+t+'-hour-'+hnewHour.setAttribute('id',hourId)newHour.setAttribute('data-hour',h)newHour.innerHTML = '';for ( let b=0; b<4; b++ ) {let m = (b+1)*15;let newBubble = bubbleTemplate.cloneNode(true)newBubble.setAttribute('id',hourId+'-minute-'+m)newBubble.setAttribute('data-hour-index',b)newBubble.setAttribute('data-task-index',(4*hh)+b)if ( t in ettConfig.tasks &&h in ettConfig.tasks[t].hours &&m in ettConfig.tasks[t].hours[h] &&ettConfig.tasks[t].hours[h][m] > 0 ){newBubble.setAttribute('data-time',ettConfig.tasks[t].hours[h][m])}newHour.appendChild(newBubble)}let newBreak = hourBreakTemplate.cloneNode(true)hourContainer.appendChild(newBreak)hourContainer.appendChild(newHour)}let newBreak = hourBreakTemplate.cloneNode(true)hourContainer.appendChild(newBreak)newTask.setAttribute('id','task-'+t)let indexElement = newTask.querySelector('.ett-task-index')if ( t < 10 ) {indexElement.innerHTML = '0'+t} else {indexElement.innerHTML = t}newTask.setAttribute('data-date',ettConfig.date);if ( t <= ettConfig.numMajor ) {newTask.classList.add('ett-major-task')}ettTaskContainer.appendChild(newTask);}const sumTime = ev => {let total = 0;let ettTasks = ettTaskContainer.querySelectorAll('[role=ett-task]')ettTasks.forEach(ettTask => {total += parseInt(ettTask.getAttribute('data-time'))});let hours = (total/60)ettTotal.innerHTML = hours.toFixed(2)+' H';};let ettTasks = ettTaskContainer.querySelectorAll('[role=ett-task]')ettTasks.forEach(ettTaskElement => {let ettTask = new EttTask(ettTaskElement,sumTime)});/// DATE PICKERconst calPopup = document.querySelector('#ett-date');const datepicker = new Datepicker(calPopup, {format: 'yyyy-mm-dd'});calPopup.addEventListener('focus',ev => {let dp = ev.target.parentNode.querySelector('.datepicker')dp.style.marginLeft = '-128px';dp.style.left = '50%';})/// PERSISTENCEdocument.addEventListener('persist',ev => {console.log('SAVE')})})
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Emergent Task Timer</title><!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]--><link rel="stylesheet" href="ett.layout.css"><link rel="stylesheet" href="ett.styles.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.2.0/dist/css/datepicker.min.css"></head><!-- https://developer.okta.com/blog/2019/12/18/vanilla-javascript-components --><body id="ett"><header id="ett-header"><div id="ett-title">Emergent Task Timer</div><div id="ett-date-container"><input id="ett-date" value="YYYY-MM-DD" /></div></header><main id="ett-tasks"></main><template id="ett-task-template"><div class="ett-task" role="ett-task" data-date="" data-time="0" data-name=""><div class="ett-task-index"><br /></div><div class="ett-task-name"><input name="ett-task-name" /></div><div class="ett-task-time"unselectable="on"onselectstart="return false;"onmousedown="return false;"><div class="bubble-hour-break"><br /></div><div class="bubble-hour" role="bubble-hour" data-time="0"><div class="bubble-15m" role="bubble-15m" data-time="0"><div class="bubble-5m" data-value="15"><br /></div><div class="bubble-5m" data-value="10"><br /></div><div class="bubble-5m" data-value="5"><br /></div></div></div><div class="bubble-hour-break"><br /></div></div><div class="ett-task-total">0</div></div></template><script type="module" src="ett.js"></script><script src="https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.2.0/dist/js/datepicker.min.js"></script></body></html>
<?xml version="1.0" encoding="utf-8"?><!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon --><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve"><metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata><g><g transform="translate(0.000000,511.000000) scale(0.100000,-0.100000)"><path d="M2904.7,4993.8c-142.2-44.2-244.1-132.6-305.6-271c-38.4-82.6-40.4-123-40.4-918.6c0-703.4,3.9-841.7,28.8-901.3c78.8-190.2,244.1-299.8,442-299.8c194.1,0,349.8,98,436.2,271c44.2,90.3,44.2,92.3,44.2,916.7c0,914.8,0,916.7-123,1053.1C3264,4980.4,3064.2,5041.9,2904.7,4993.8z"/><path d="M6809.7,4988c-99.9-34.6-246-176.8-286.4-280.6c-30.7-82.6-34.6-163.4-34.6-916.7v-826.4l44.2-90.3c90.3-182.6,305.6-301.7,493.9-274.8c128.8,21.1,276.7,117.2,345.9,228.7l57.7,94.2l5.8,847.5c3.8,751.4,1.9,857.1-26.9,932.1c-40.4,107.6-126.9,205.6-226.8,255.6C7092.2,5003.4,6902,5018.8,6809.7,4988z"/><path d="M1017.5,3756.2c-228.7-78.8-417-240.2-522.7-449.7c-90.3-178.7-88.4-76.9-88.4-3784c0-2409.9,5.8-3514.9,21.1-3593.7c44.2-244.1,221-492,434.3-607.3c215.2-119.2-38.4-111.5,4137.6-111.5c4174.1,0,3922.3-5.8,4135.6,109.5c213.3,115.3,392,367.1,436.3,609.2c30.7,163.3,28.8,7022.1,0,7164.3c-69.2,326.7-320.9,595.8-640,680.3c-71.1,19.2-242.1,26.9-640,26.9h-543.8V3393c0-284.4-7.7-440.1-26.9-507.3c-61.5-228.7-213.3-415.1-430.5-520.8c-99.9-50-128.8-53.8-320.9-53.8c-199.9,0-219.1,3.8-340.2,63.4c-161.4,78.8-320.9,246-382.4,401.7c-42.3,103.8-46.1,144.1-51.9,568.8l-5.8,455.5H4997.5H3807.9v-418.9c0-326.7-7.7-442-30.7-524.7c-61.5-209.5-226.8-399.7-426.6-493.9c-98-46.1-132.6-51.9-320.9-51.9c-192.2,0-221,3.8-320.9,53.8c-222.9,109.5-388.2,315.2-436.2,547.7c-11.5,55.7-21.1,278.7-21.1,493.9v394h-551.5C1173.2,3798.5,1140.5,3796.5,1017.5,3756.2z M8992.8-1401.8c-5.8-2594.4-5.8-2629-44.2-2680.9c-21.1-26.9-63.4-67.3-96.1-86.5c-55.7-32.7-205.6-34.6-3853.1-34.6H1203.9l-69.2,44.2c-142.2,88.4-132.6-123-132.6,2778.9v2605.9h3997.3h3997.3L8992.8-1401.8z"/><path d="M2307,527.6c-142.2-75-171-148-171-443.9c0-219.1,3.9-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,518.9-42.3s455.5,1.9,518.9,42.3c38.4,23,88.4,76.9,111.5,117.2c36.5,67.3,42.3,103.8,42.3,320.9c0,228.7-3.8,251.8-48,328.6c-30.8,53.8-74.9,94.2-130.7,121.1c-76.9,36.5-115.3,40.4-497.7,40.4C2408.9,571.8,2387.7,569.9,2307,527.6z"/><path d="M4497.8,527.6c-142.2-75-171-148-171-443.9c0-219.1,3.8-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,518.9-42.3c432.4,0,455.5,1.9,518.9,42.3c38.4,23,88.4,76.9,111.5,117.2c38.4,67.3,42.3,103.8,42.3,322.9c0,296-28.8,369-171,443.9c-80.7,42.3-101.9,44.2-501.6,44.2C4599.7,571.8,4578.5,569.9,4497.8,527.6z"/><path d="M6688.6,527.6c-142.2-75-171-148-171-443.9c0-219.1,3.8-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,518.9-42.3c432.4,0,455.4,1.9,518.9,42.3c38.4,23,88.4,76.9,111.5,117.2c38.4,67.3,42.3,103.8,42.3,322.9c0,296-28.8,369-171.1,443.9c-80.7,42.3-101.8,44.2-501.6,44.2S6769.3,569.9,6688.6,527.6z"/><path d="M2308.9-1046.3c-142.2-73-173-148-173-445.8c0-219.1,3.9-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,520.8-42.3c449.7,0,453.5,0,522.7,48c124.9,86.5,148,153.7,148,434.3c0,296-28.8,369-171,443.9c-80.7,42.3-101.9,44.2-499.7,44.2C2416.5-1004,2389.6-1006,2308.9-1046.3z"/><path d="M4497.8-1048.2c-142.2-75-171-148-171-443.9c0-219.1,3.8-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,520.8-42.3c449.7,0,453.5,0,522.7,48c124.9,86.5,148,153.7,148,434.3c0,296-28.8,369-171,443.9c-80.7,42.3-101.9,44.2-501.6,44.2C4599.7-1004,4578.5-1006,4497.8-1048.2z"/><path d="M6688.6-1048.2c-142.2-75-171-148-171-443.9c0-219.1,3.8-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,518.9-42.3c432.4,0,455.4,1.9,518.9,42.3c38.4,23,88.4,76.9,111.5,117.2c38.4,67.3,42.3,103.8,42.3,322.9c0,296-28.8,369-171.1,443.9c-80.7,42.3-101.8,44.2-501.6,44.2S6769.3-1006,6688.6-1048.2z"/><path d="M2308.9-2622.2c-142.2-73-173-148-173-445.8c0-219.1,3.9-255.6,42.3-322.9c82.6-146,126.8-159.5,563.1-165.3c468.9-7.7,528.5,0,618.8,78.8c103.8,90.3,121.1,151.8,121.1,420.9c0,282.5-30.7,357.4-171,432.4c-80.7,42.3-101.9,44.2-499.7,44.2C2416.5-2579.9,2389.6-2581.8,2308.9-2622.2z"/><path d="M4499.7-2622.2c-142.2-73-173-148-173-445.8c0-219.1,3.8-255.6,42.3-322.9c23.1-40.4,73-94.2,111.5-117.2c63.4-40.4,86.5-42.3,520.8-42.3c449.7,0,453.5,0,522.7,48c124.9,86.5,148,153.7,148,434.3c0,296-28.8,369-171,443.9c-80.7,42.3-101.9,44.2-499.7,44.2C4607.4-2579.9,4580.5-2581.8,4499.7-2622.2z"/></g></g></svg>
class EttTask {constructor(taskElement, onUpdate) {let self = this/* data */const bubbleHourElements = taskElement.querySelectorAll('[role=bubble-hour]')const taskTotal = taskElement.querySelector('.ett-task-total')// var lineStart = {x:0,y:0}var multiSelectFill = falsethis.element = taskElementthis.bubbleHours = []this.bubbles = []this.bubbleStartIndex = null/* actions */const sumTime = ev => {let total = 0bubbleHourElements.forEach(bubbleHour => {total += parseInt(bubbleHour.getAttribute('data-time'))})taskElement.setAttribute('data-time', total)let hours = (total / 60)taskTotal.innerHTML = hours.toFixed(2) + ' H'onUpdate()}/* init */bubbleHourElements.forEach(bubbleHourElement => {let bubbleHour = new BubbleHour(bubbleHourElement, sumTime, self)self.bubbleHours.push(bubbleHour)})taskElement.ett = thissumTime()return this}}class BubbleHour {constructor(hourElement, onUpdate, task) {let self = this/* data */this.element = hourElementthis.bubbleElements = hourElement.querySelectorAll('[role=bubble-15m]')this.bubbles = []/* actions */const sumTime = ev => {let total = 0// let bubbles = ev.currentTarget.querySelectorAll('> [role=bubble-15m]')self.bubbleElements.forEach(bubbleElement => {total += parseInt(bubbleElement.getAttribute('data-time'))})hourElement.setAttribute('data-time', total)onUpdate()}/* init */this.bubbleElements.forEach(bubbleElement => {let bubble = new Bubble(bubbleElement, sumTime, task, self)self.bubbles.push(bubble)task.bubbles.push(bubble)})hourElement.ett = thissumTime()return this}}class Bubble3 {constructor(bubbleElement, onUpdate, task) {let self = this/* data */this.element = bubbleElementthis.bubbles5m = bubbleElement.querySelectorAll('.bubble-5m')/* actions */const fillBubble = (time) => {bubbles5m.forEach(bubble => {time = parseInt(time)let minTrigger = parseInt(bubble.getAttribute('data-value')) - 4if (time > 0 && time >= minTrigger) {bubble.classList.add('fill')} else {bubble.classList.remove('fill')}})}const sumTime = ev => {const currentTime = bubbleElement.getAttribute('data-time')fillBubble(currentTime)}const cycleTime = ev => {let currentTime = parseInt(bubbleElement.getAttribute('data-time'))if (currentTime >= 15) {currentTime = 0} else {currentTime += 5}bubbleElement.setAttribute('data-time', currentTime)fillBubble(currentTime)onUpdate()}/* init */bubbleElement.addEventListener('click', cycleTime)bubbleElement.classList.add('bubble3')bubbleElement.ett = thissumTime()return this}}class Bubble {constructor(bubbleElement, onUpdate, task, hour) {let self = this/* data */this.element = bubbleElement/* actions */this.fillBubble = (time) => {bubbleElement.setAttribute('data-time', parseInt(time))if (parseInt(time) > 0) {bubbleElement.classList.add('fill')} else {bubbleElement.classList.remove('fill')}onUpdate()}const sumTime = ev => {const currentTime = bubbleElement.getAttribute('data-time')self.fillBubble(currentTime)}const cycleTime = ev => {var currentTime = parseInt(bubbleElement.getAttribute('data-time'))if (currentTime > 0) {currentTime = 0} else {currentTime = 15}self.fillBubble(currentTime)document.dispatchEvent(new Event('persist'))}/* init */const preMultiFill = ev => {bubbleElement.addEventListener('mouseup', cycleTime)bubbleElement.addEventListener('mouseout', multiSelectActivate)document.addEventListener('mouseup', multiSelectCancel)task.bubbleStartIndex = parseInt(bubbleElement.getAttribute('data-task-index'))}const multiSelectActivate = ev => {bubbleElement.removeEventListener('mouseup', cycleTime)bubbleElement.removeEventListener('mouseout', multiSelectActivate)task.multiSelectActive = trueconst currentTime = parseInt(bubbleElement.getAttribute('data-time'))if (currentTime > 0) {task.multiSelectFill = falseself.fillBubble(0)document.body.style.cursor = 'not-allowed'} else {task.multiSelectFill = trueself.fillBubble(15)document.body.style.cursor = 'copy'}}const multiSelectCancel = ev => {task.multiSelectActive = falsebubbleElement.removeEventListener('mouseout', multiSelectActivate)document.removeEventListener('mouseup', multiSelectCancel)task.bubbleStartIndex = nulldocument.body.style.cursor = 'default'document.dispatchEvent(new Event('persist'))}const multiFill = ev => {if (task.multiSelectActive) {if (task.multiSelectFill) {self.fillBubble(15)} else {self.fillBubble(0)}let bubbleIndex = parseInt(bubbleElement.getAttribute('data-task-index'))let bubbleStartIndex = parseInt(task.bubbleStartIndex)if (bubbleStartIndex !== null && bubbleStartIndex !== bubbleIndex) {let startIndex = Math.min(bubbleIndex,task.bubbleStartIndex);let endIndex = Math.max(bubbleIndex,task.bubbleStartIndex);for (let i = startIndex; i <= endIndex; i++) {let betweenBubble = task.element.querySelector('[data-task-index="' + i + '"]')if ( betweenBubble ) {if (task.multiSelectFill) {betweenBubble.ett.fillBubble(15)} else {betweenBubble.ett.fillBubble(0)}}}}}}bubbleElement.addEventListener('mousedown', preMultiFill)bubbleElement.addEventListener('mouseenter', multiFill)bubbleElement.ett = thissumTime()return this}}export { EttTask, BubbleHour, Bubble, Bubble3 }
.git.DS_Store