<!--
silly isnt it?
needs an open bowseer window to run in, to be active
well doesnt all code needs something active to run in
screenshot video short
https://www.youtube.com/shorts/-JTDc3kmIOg
// please free my flagged github acount?
// Free Electra?
// timed MDNS local url ESP8266 ESP32 light switch
// http://kitchen.local/LED=ON
// http://kitchen.local/LED=OFF
//
// http://living.local/LED=ON
// http://living.local/LED=OFF
//
// call the url by javascript in iframe timed
// Free Electra?
//https://stackoverflow.com/questions/35178135/how-to-fix-insecure-content-was-loaded-over-https-but-requested-an-insecure-re
// does not work from htpps
// save to disk and open in browser from http
//jsfidle does http
//http://jsfiddle.net/luberth/e2xmsgnL
// time picker android style
// i ike it, is the same on all devices
// input type time i do not like
// https://shanegh.github.io/analogue-time-picker/demo/
// https://github.com/ShaneGH/analogue-time-picker
-->
<html>
<head>
<meta http-equiv="Content-Security-Policy-Report-Only" content="Content-Security-Policy-Report-Only">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.teal-cyan.min.css" />
<!--
<script src="https://shanegh.github.io/analogue-time-picker/demo/analogue-time-picker.js"></script>
-->
<script src="timepicker.js"></script>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}
.content {
padding-bottom: 0px;
}
.section {
display: flex;
flex-wrap: wrap
}
.display {
width:100%;
max-width: 100%;
padding-bottom: 20px;
}
.code {
max-width: 100%;
overflow-x: hidden;
}
.display::before,
.code::before {
font-size: 18px;
display: block;
}
.display::before {
content: "Display";
padding-bottom: 2em;
}
.code::before {
content: "Code";
}
input.time {
text-align: right;
width: 100px;
font-size: 28px;
color: green;
}
.rop-display {
display: flex;
}
.ex-button {
text-transform: none;
margin-bottom: 10px;
display: block
}
.ex-button:first-child {
margin-top: 10px;
}
.container {
padding: 20px;
}
@media only screen and (max-width: 1200px) {
.container {
padding: 10px;
}
}
.datetime {
font-size: 28px;
color: red;
}
</style>
</head>
<body>
per day = on time x 6 watt led light / 1000 x 0,25 eurocent per kw<br>
<center>
<h1>Http://Living.local</h1>
<!--
<button onclick="reloadFrame()">Refresh</button>
<input type="text"
id="urlinput" value="http://kitchen.local" oninput="reloadFrame()">
-->
<a href="https://plnkr.co/plunk/vQj5gFfndyrfyjvR">Electra timed switching multi range sliders https://plnkr.co/plunk/vQj5gFfndyrfyjvR</a><br>
<p id="datetime" class="datetime"></p>
0 to 1439 minutes in a day, use that count for switching
<script>
function time() {
var today = new Date();
var date = today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear();
var maybeasecondzero='';
var maybeaminutezero='';
if(today.getSeconds()<=9)maybeasecondzero='0';
if(today.getMinutes()<=9)maybeaminutezero='0';
var time = today.getHours() + ":" + maybeaminutezero+today.getMinutes() + ":" + maybeasecondzero+today.getSeconds();
time += "<br><br> Time in minutes "+(parseInt(today.getHours())*60 + parseInt(today.getMinutes())) + ":" +maybeasecondzero+ today.getSeconds()
var dateTime = date+'<br>'+time;
//console.log(dateTime)
document.getElementById("datetime").innerHTML = dateTime;
}
setInterval(time, 250);
</script>
<p id="demo"></p>
<script>
let protocol = location.protocol;
if(protocol=="https:"){
document.getElementById("demo").innerHTML = "use file:// or http:// http:// iframe src does not work on "+ protocol;
}else{
document.getElementById("demo").innerHTML = protocol;
}
</script>
ESP8266 ESP32 WiFi relais switchtimes <br>
<p style="color:red">click on next time to get an android like timepicker<br>
times must be in following order?, Ascending order? </p>
<div style="width: 100%;">
<hr>
<div>
Switch ON Time 1<input type="text" class="time mdl-textfield__input" oninput="calc()" id="ontime" value="05:30"/>
Switch OFF Time 1<input type="text" class="time mdl-textfield__input" oninput="calc()" id="offtime" value="06:30"/>
</div>
<hr>
<div>
Switch ON Time 2<input type="text" class="time mdl-textfield__input" oninput="calc()" id="ontime2" value="16:30"/>
Switch OFF Time 2<input type="text" class="time mdl-textfield__input" oninput="calc()" id="offtime2" value="22:00"/>
</div>
<hr>
</div>
<p id="log"></p>
<p id="log2"></p>
<p id="result1"></p>
<p id="result2"></p>
<img id="showit"><br>
<input type="button" value="clear mylog textarea" onclick="document.getElementById('myTextarea').value='Erased';">
<textarea id="myTextarea" rows="10" cols="200" style="background-color: black;color:limegreen;"></textarea>
<div id="log"></div>
<br><hr><br>
<div class="iframe">
<center>
<iframe id="myIfr1" src="http://living.local" frameborder="1" width="20%" height="30%" ></iframe>
<iframe id="myIfr2" src="http://kitchen.local" frameborder="1" width="20%" height="30%"></iframe>
<!--
<object data="http://living.local" type="text/html" width="20%" height="60%"> run from http not https</object>
-->
</center>
</div>
<script>
var swichtime=[0,0,990,1320];
function mmyFunction() {
console.log('xonokonoknoknkonkoxxxxxxxxxxxxxxxxx');
}
window.onclock = timePickerInput({
inputElement: document.getElementById("ontime"),
mode: 24
});
window.offclock = timePickerInput({
inputElement: document.getElementById("offtime"),
mode: 24
});
window.onclock2 = timePickerInput({
inputElement: document.getElementById("ontime2"),
mode: 24 ,
});
window.offclock2 = timePickerInput({
inputElement: document.getElementById("offtime2"),
mode: 24
});
// i do not now how to get the changed value from timefield input picker
//window.onclock.addEventListener("onOk", function(){ calc(); });
//window.onclock.onOk(calc());
console.log('xxxxxxxxxxxxxxxxxx');
console.log('onclock ',window.onclock.getTime());
console.log('ofclock ',window.offclock.getTime());
console.log('xxxxxxxxxxxxxxxxxx');
// idontknow
//window.offclock.onTimeChanged((h, m) => console.log("hi",h,m));
//window.offclock(onTimeChanged((h, m) => console.log("hi",h,m)));
//onOk
/*
<pre>
██╗ ██╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ██╗ ██████╗ ███████╗████████╗
██║ ██║██╔═══██╗██║ ██║ ██╔══██╗██╔═══██╗ ██║ ██╔════╝ ██╔════╝╚══██╔══╝
███████║██║ ██║██║ █╗ ██║ ██║ ██║██║ ██║ ██║ ██║ ███╗█████╗ ██║
██╔══██║██║ ██║██║███╗██║ ██║ ██║██║ ██║ ██║ ██║ ██║██╔══╝ ██║
██║ ██║╚██████╔╝╚███╔███╔╝ ██████╔╝╚██████╔╝ ██║ ╚██████╔╝███████╗ ██║
╚═╝ ╚═╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝
Figlet font ANSI Shadow https://run.plnkr.co/plunks/ZEkhoGgs4ntDZzT0/
</pre>
*/
// i do not know, why not work
//document.getElementById('ontime').addEventListener("onchange", calc());
//window.onclock.addEventListener("onOk", calc());
// would ike an eventlistener when input changed
// next works but sily?
setInterval(calc, 1000);
function calc() {
// get the time value from input field
// console.log('now in calc');
var timetext;
var myArray;
timetext = document.getElementById("ontime").value;
myArray = timetext.split(":");
swichtime[0] = parseInt(myArray[0])*60+ parseInt(myArray[1]);
timetext = document.getElementById("offtime").value;
myArray = timetext.split(":");
swichtime[1] = parseInt(myArray[0])*60+ parseInt(myArray[1]);
timetext = document.getElementById("ontime2").value;
myArray = timetext.split(":");
swichtime[2] = parseInt(myArray[0])*60+ parseInt(myArray[1]);
timetext = document.getElementById("offtime2").value;
myArray = timetext.split(":");
swichtime[3] = parseInt(myArray[0])*60+ parseInt(myArray[1]);
}
calc();
function reloadFrame () {
//document.getElementById('myIfr1').src = document.getElementById('urlinput').value;
//console.log('reload iframe');
var now = new Date(); // actual time in now
var hour = now.getHours();
var minutes = now.getMinutes();
// var seconds= now.getSeconds();
var timeinminutes=(hour*60)+minutes;
var switchurl; // could be on or off url
var image_src_url;
var switchontimeinminutes = swichtime[0];//(17*60)+00; // 17:30 for baby's thats 5:30pm
////var switchofftimeinminutes = swichtime[1];(21*60)+30; // 21:30 for baby's thats 9:30pm
// on=swichtime[0] off=swichtime[1]
if (timeinminutes >= swichtime[0] && timeinminutes < swichtime[1]){
switchurl = 'http://living.local/LED=ON';
image_src_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT5YK65lgAFnhAlkT7J42OgWXgsHcXNcC_kkA&usqp=CAU";
}else{
switchurl = 'http://living.local/LED=OFF';
image_src_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSYFG_bXMk5ksJvP5sxwNk4dqklJFMT9DqqWw&usqp=CAU";
// on=swichtime[2] off=swichtime[3]
if (timeinminutes >= swichtime[2] && timeinminutes < swichtime[3]){
switchurl = 'http://living.local/LED=ON';
image_src_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT5YK65lgAFnhAlkT7J42OgWXgsHcXNcC_kkA&usqp=CAU";
}else{
switchurl = 'http://living.local/LED=OFF';
image_src_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSYFG_bXMk5ksJvP5sxwNk4dqklJFMT9DqqWw&usqp=CAU";
}
}
if (timeinminutes >= 1439){
document.getElementById('myTextarea').value='Erased by time'; // erase textare around midnight
}
mylog(switchurl);
console.log('now ',timeinminutes,' on ',swichtime[0],' off ',swichtime[1]);
console.log('now ',timeinminutes,' on ',swichtime[2],' off ',swichtime[3]);
//document.getElementById("log").innerHTML = 'Actual time in minutes now '+timeinminutes+' on1 '+swichtime[0]+' off1 '+swichtime[1];
//document.getElementById("log2").innerHTML = 'Actual time in minutes now '+timeinminutes+' on2 '+swichtime[2]+' off2 '+swichtime[3];
var onoff1 = 'Actual time in minutes now '+timeinminutes+' on1 '+swichtime[0]+' off1 '+swichtime[1];
var onoff2 = ' '+timeinminutes+' on2 '+swichtime[2]+' off2 '+swichtime[3];
document.getElementById('myIfr1').src = switchurl;
console.log('reload iframe \n',now,'\n',switchurl);
document.getElementById('showit').src = image_src_url; // set image on or of
//var text=document.getElementById('myTextarea').value;
//document.getElementById('myTextarea').value = onoff1+'\n'+onoff2+'\n\n'+text;
mylog(onoff1+'\n'+onoff2);
}
reloadFrame();
setInterval(reloadFrame, 10000);
function mylog(texttoadd) {
// add text to textarea
var text2=document.getElementById('myTextarea').value;
document.getElementById('myTextarea').value = texttoadd+'\n'+text2;
// matbe count nr of lines and skip lines if it gets to big
}
</script>
timed switching by calliing an on or of mdns url on an esp8266 or esp32 wifi switch<br>
<img src="https://www.elektramat.nl/media/catalog/product/cache/7254b39789edebd7b7c366a3fbcd6106/0/2/0260030_theben-timer-2026-20Tag-jpg_2.jpg">
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./src/utils/utils.ts
/** Add an event listener to an element and return a function which will dispose of the listener */
function registerEvent(element, event, fun) {
function f() { return fun.apply(this, arguments); }
element.addEventListener(event, f);
var removed = false;
return function () {
if (removed)
return;
removed = true;
element.removeEventListener(event, f);
};
}
/** Add an event listener to an element and return a function which will dispose of the listener */
function registerMouseEvent(element, event, fun) {
return registerEvent(element, event, fun);
}
/** Add an event listener to an element and return a function which will dispose of the listener */
function registerKeyEvent(element, event, fun) {
return registerEvent(element, event, fun);
}
/** Add an event listener to an element and return a function which will dispose of the listener */
function registerTouchEvent(element, event, fun) {
return registerEvent(element, event, fun);
}
// CONCATENATED MODULE: ./src/components/gestureTracker.ts
/** Track the mouse position over the entire screen and report back */
var gestureTracker_GestureTracker = /** @class */ (function () {
function GestureTracker(moveEvents, finishEvents) {
var _this = this;
this._disposables = [];
this._onFinished = [];
this._onMove = [];
var me = moveEvents
.map(function (x) { return registerEvent(document, x, function (e) { return _this.move(e); }); });
var fe = finishEvents
.map(function (x) { return registerEvent(document, x, function (e) { return _this.finish(); }); });
this._disposables = me.concat(fe);
}
GestureTracker.prototype.onFinished = function (callback) {
this._onFinished.push(callback);
};
GestureTracker.prototype.onMove = function (callback) {
this._onMove.push(callback);
};
GestureTracker.prototype.move = function (e) {
this._onMove
.slice(0)
.forEach(function (f) { return f(e); });
};
GestureTracker.prototype.finish = function () {
this._onFinished
.slice(0)
.forEach(function (f) { return f(); });
};
GestureTracker.prototype.dispose = function () {
this._onFinished.length = 0;
this._onMove.length = 0;
this._disposables
.splice(0, Number.MAX_VALUE)
.forEach(function (f) { return f(); });
};
return GestureTracker;
}());
// CONCATENATED MODULE: ./src/components/timePicker.ts
var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
/**The time picker component which contains all other components */
var timePicker_TimePicker = /** @class */ (function () {
function TimePicker(elements, hours, minutes, hand, mode, focusInput) {
var _this = this;
this.hours = hours;
this.minutes = minutes;
this.hand = hand;
this._timeChangeCallbacks = [];
this._okCallbacks = [];
this._cancelCallbacks = [];
this.mouseTracker = null;
this.touchTracker = null;
this.ok = elements.okButton;
this.cancel = elements.cancelButton;
this.clock = elements.clock;
// register events for when something happens with the "hours"
this.hours.onNext(function () { return _this.showMinutes(); });
this.hours.onRenderValuesChanged(function () { return _this.hourChangeOccurred(); });
this.hours.onInputFocus(function () { return _this.showHours(true); });
// register events for when something happens with the "minutes"
this.minutes.onNext(function () { return _this.ok.focus(); });
this.minutes.onPrevious(function () { return _this.showHours(true); });
this.minutes.onRenderValuesChanged(function () { return _this.minuteChangeOccurred(); });
this.minutes.onInputFocus(function () { return _this.showMinutes(); });
// show hours by default
this.showHours(focusInput);
// register dom events on clock face, ok and cancel buttons
this._createMouseTracker = registerMouseEvent(this.clock, "mousedown", function (e) { return _this.createMouseTracker(e); });
this._createTouchTracker = registerTouchEvent(this.clock, "touchstart", function (e) { return _this.createTouchTracker(e); });
this._okPropagation = registerMouseEvent(this.ok, "mousedown", function (e) { return e.stopPropagation(); });
this._cancelPropagation = registerMouseEvent(this.cancel, "mousedown", function (e) { return e.stopPropagation(); });
this._ok = registerMouseEvent(this.ok, "click", function () { return _this.okClick(); });
this._cancel = registerMouseEvent(this.cancel, "click", function () { return _this.cancelClick(); });
this.setMode(mode);
}
/**Add a callback to be fired when the time changes */
TimePicker.prototype.onTimeChanged = function (callback) {
this._timeChangeCallbacks.push(callback);
};
/**Add a callback to be fired when the user is finished */
TimePicker.prototype.onOk = function (callback) {
this._okCallbacks.push(callback);
};
/**Add a callback to be fired when the cancels */
TimePicker.prototype.onCancel = function (callback) {
this._cancelCallbacks.push(callback);
};
/**Set the format to 12h or 24h for the user */
TimePicker.prototype.setMode = function (mode) {
switch (mode) {
case 12:
this.hours.setTo12Hr();
break;
case 24:
this.hours.setTo24Hr();
break;
}
};
/** Show the hour hand */
TimePicker.prototype.showHours = function (focusInput) {
this.hours.focus(focusInput);
this.minutes.blur();
this.hand.setPositon(this.hours.value.angle, this.hours.value.position);
};
/**Show the minute hand */
TimePicker.prototype.showMinutes = function () {
this.minutes.normalizeAngle(this.hours.value.angle);
this.minutes.focus();
this.hours.blur();
this.hand.setPositon(this.minutes.value.angle, this.minutes.value.position);
};
/** Return the current time */
TimePicker.prototype.getTime = function () {
return {
hour: this.hours.value.value,
minute: this.minutes.value.value
};
};
/** Set the current time */
TimePicker.prototype.setTime = function (hours, minutes) {
var timeHasChanged = this._suppressTimeChangeEvents();
try {
this.hours.set(hours);
this.minutes.set(minutes);
}
finally {
timeHasChanged.complete();
}
};
TimePicker.prototype.hourChangeOccurred = function () {
if (this.hours.getFocused())
this.hand.setPositon(this.hours.value.angle, this.hours.value.position);
this.timeChangeOccurred();
};
TimePicker.prototype.minuteChangeOccurred = function () {
if (this.minutes.getFocused())
this.hand.setPositon(this.minutes.value.angle, this.minutes.value.position);
this.timeChangeOccurred();
};
TimePicker.prototype.timeChangeOccurred = function () {
var _this = this;
if (this._timeChangeSuppressed)
return;
this._timeChangeCallbacks
.slice(0)
.forEach(function (f) { return f(_this.hours.value.value, _this.minutes.value.value); });
};
/**Signify that the user is finished */
TimePicker.prototype.okClick = function () {
var _this = this;
this._okCallbacks
.slice(0)
.forEach(function (f) { return f(_this.hours.value.value, _this.minutes.value.value); });
};
/**Signify that the user has cancelled */
TimePicker.prototype.cancelClick = function () {
this._cancelCallbacks
.slice(0)
.forEach(function (f) { return f(); });
};
/** Specify that the time may change, and to supress change events if it does.
* When the returned "compltete" function is called, events are re-enabled, and one may be
* fired immediately if the time has changed while evets were disabled*/
TimePicker.prototype._suppressTimeChangeEvents = function () {
var _this = this;
// if events already suppressed, signify that
// one more "supressor" is active
if (this._timeChangeSuppressed) {
this._timeChangeSuppressed.instance++;
}
else {
this._timeChangeSuppressed = __assign({ instance: 1 }, this.getTime() // TODO: do we need to watch hand angle/position here too?
);
}
;
var c = false;
return {
complete: function () {
if (c)
return;
c = true;
if (!_this._timeChangeSuppressed)
return;
else if (_this._timeChangeSuppressed.instance > 1)
_this._timeChangeSuppressed.instance--;
else {
// if time has changed, fire event if necessary
var t1 = _this._timeChangeSuppressed;
_this._timeChangeSuppressed = null;
var t2 = _this.getTime();
if (t1.hour != t2.hour || t1.minute != t2.minute) {
_this.timeChangeOccurred();
}
}
}
};
};
/** Create an object to track the mousemove on the entire screen */
TimePicker.prototype.createMouseTracker = function (e) {
var _this = this;
// touch takes precedence over mouse
if (this.touchTracker)
return;
// use this as an opportunity to see if the clock html element has moved
this.hours.refreshOffsets();
this.minutes.refreshOffsets();
// Set the current hours or minutes
this.setTimeFromPosition(e.clientX, e.clientY);
// create a new tracker
if (this.mouseTracker)
return;
var mouseTracker = this.mouseTracker = new gestureTracker_GestureTracker(["mousemove"], ["mouseup"]);
// dispose when mouse released
mouseTracker.onFinished(function () {
mouseTracker.dispose();
if (mouseTracker === _this.mouseTracker)
_this.mouseTracker = null;
_this.hours.getFocused() ?
_this.hours.goNext() :
_this.minutes.goNext();
});
mouseTracker.onMove(function (e) { return _this.setTimeFromPosition(e.clientX, e.clientY); });
};
/** Create an object to track the touchmove over the entire screen */
TimePicker.prototype.createTouchTracker = function (e) {
var _this = this;
// touch takes precedence over mouse
if (this.mouseTracker) {
this.mouseTracker.dispose();
this.mouseTracker = null;
}
// prevent scrolling
e.preventDefault();
// use this as an opportunity to see if the clock html element has moved
this.hours.refreshOffsets();
this.minutes.refreshOffsets();
// Set the current hours or minutes
if (e.touches.length) {
this.setTimeFromPosition(e.touches[0].clientX, e.touches[0].clientY);
}
// create a new tracker
if (this.touchTracker)
return;
var touchTracker = this.touchTracker = new gestureTracker_GestureTracker(["touchmove"], ["touchend", "touchcancel"]);
// dispose when touch released
touchTracker.onFinished(function () {
touchTracker.dispose();
if (touchTracker === _this.touchTracker)
_this.touchTracker = null;
_this.hours.getFocused() ?
_this.hours.goNext() :
_this.minutes.goNext();
});
touchTracker.onMove(function (e) {
// prevent scrolling
e.preventDefault();
if (e.touches.length) {
_this.setTimeFromPosition(e.touches[0].clientX, e.touches[0].clientY);
}
});
};
TimePicker.prototype.setTimeFromPosition = function (clientX, clientY) {
this.hours.getFocused() ?
this.hours.setFromPosition(clientX, clientY) :
this.minutes.setFromPosition(clientX, clientY);
};
TimePicker.prototype.dispose = function () {
if (this.mouseTracker) {
this.mouseTracker.dispose();
this.mouseTracker = null;
}
this._timeChangeCallbacks.length = 0;
this._okCallbacks.length = 0;
this._cancelCallbacks.length = 0;
this._createMouseTracker();
this._createTouchTracker();
this._okPropagation();
this._cancelPropagation();
this._ok();
this._cancel();
};
return TimePicker;
}());
// CONCATENATED MODULE: ./src/utils/angle.ts
var _90 = Math.PI / 2;
var _360 = Math.PI * 2;
/** Get the angle of the left/top co-ordinate from the center of the width.height box */
function getAngle(left, top, width, height) {
var x = (width / 2) - left;
var y = (height / 2) - top;
// tan O = y / x
var angle = x ?
Math.atan(y / x) :
y < 0 ? -_90 : _90;
if (x < 0) {
// reflect along vertical axis
angle = -angle + (2 * (_90 + angle));
}
return angle;
}
/** Calculate the smallest difference between 2 angles. e.g. 90° is smaller than 450° */
function getAngleDelta(a1, a2) {
var diff = a2 - a1;
while (diff > Math.PI) {
diff -= _360;
}
while (diff < -Math.PI) {
diff += _360;
}
return diff;
}
// CONCATENATED MODULE: ./src/utils/html.ts
/** Get the offset to the window of an element */
function offset(el, prop) {
var offset = 0;
while (el instanceof HTMLElement) {
offset += el[prop];
if (window.getComputedStyle(el).getPropertyValue("position") === "fixed")
return offset;
el = el.offsetParent;
}
offset -= (prop === "offsetTop" ? window.pageYOffset : window.pageXOffset);
return offset;
}
/** Remove the child of an element if the element contains this child */
function removeChildSafe(parent, child) {
if (child.parentElement === parent)
parent.removeChild(child);
}
/** Track the number of modals on screen, and the initial overflow of the body element */
var modalInstance = null;
/** Render the given element as a modal, and return a function to close the modal */
function createModal(content) {
var modal = document.createElement("div");
modal.className = "atp-modal";
modal.appendChild(content);
document.body.appendChild(modal);
// cache the body overflow
if (!modalInstance) {
modalInstance = {
overflowX: document.body.style.overflowX,
overflowY: document.body.style.overflowY,
instance: 1
};
document.body.style.overflowX = "hidden";
document.body.style.overflowY = "hidden";
}
else {
modalInstance.instance++;
}
// register close events
var onClickOrEsc = [];
// using mouse down as click might fire on mouse up, if mouse down was not on this element
var disposeOnMouseDown = registerEvent(modal, "mousedown", function (e) {
if (e.target !== modal)
return;
onClickOrEsc.slice(0).forEach(function (f) { return f(); });
});
var disposeOnEsc = registerKeyEvent(document, "keydown", function (e) {
if (e.key !== "Escape")
return;
onClickOrEsc.slice(0).forEach(function (f) { return f(); });
});
var done = false;
return {
/** Add an event lisener to the mask being clicked or the escape key being pressed */
onClickOrEsc: function (f) { return onClickOrEsc.push(f); },
/** Remove the modal from the screen */
dispose: function () {
if (done)
return;
done = true;
disposeOnMouseDown();
disposeOnEsc();
onClickOrEsc.length = 0;
removeChildSafe(modal, content);
removeChildSafe(document.body, modal);
// reset the body overflow if this is the last modal
if (modalInstance) {
if (modalInstance.instance > 1) {
modalInstance.instance--;
}
else {
document.body.style.overflowX = modalInstance.overflowX;
document.body.style.overflowY = modalInstance.overflowY;
modalInstance = null;
}
}
}
};
}
// CONCATENATED MODULE: ./src/components/numbers.ts
var numbers_assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var numbers_360 = Math.PI * 2;
var Position;
(function (Position) {
Position["near"] = "near";
Position["far"] = "far";
})(Position || (Position = {}));
function round(x, decimals) {
return parseFloat(x.toFixed(decimals));
}
function sign(x) {
if (!x)
return 0;
if (x > 0)
return 1;
return -1;
}
function compareAngles(x, y) {
while (x < 0)
x += numbers_360;
while (x >= 0)
x -= numbers_360;
while (y < 0)
y += numbers_360;
while (y >= 0)
y -= numbers_360;
return sign(round(x, 5) - round(y, 5));
}
/** Base class for a number value (e.g. hours, minutes) */
var numbers_Numbers = /** @class */ (function () {
function Numbers(numberInput, elements, value) {
var _this = this;
this.numberInput = numberInput;
this._onInputFocus = [];
this._onRenderValuesChanged = [];
this._onValueChanged = [];
this._onNextCallbacks = [];
this._onPreviousCallbacks = [];
this._triggerValue = null;
this.ignoreCount = 0;
this.elements = numbers_assign({}, elements, { selectedNumber: null });
this.refreshOffsets();
this.set(value);
this.numberInput.onTimeChanged(function (v) { return _this.numberInputTimeChanged(v); });
this.numberInput.onNext(function () { return _this.goNext(); });
this.numberInput.onPrevious(function () { return _this.goPrevious(); });
this.highlightNumber();
this.numberInput.onFocus(function () { return _this.focusOnInput(); });
this.onRenderValuesChanged(function (rv) { return _this.triggerValueChanged(rv.value); });
// hidden by default. A parent component will need to call focus(...)
this.blur();
this.setLabel();
}
Numbers.prototype.onInputFocus = function (f) {
this._onInputFocus.push(f);
};
/** Triggers if value, angle or position changes */
Numbers.prototype.onRenderValuesChanged = function (f) {
this._onRenderValuesChanged.push(f);
};
/** Triggers only if value (e.g hour) changes */
Numbers.prototype.onValueChanged = function (f) {
this._onValueChanged.push(f);
};
/** Triggers when the component decides it should move on (like tab) */
Numbers.prototype.onNext = function (f) {
this._onNextCallbacks.push(f);
};
/** Triggers when the component decides it should move back (like shift tab) */
Numbers.prototype.onPrevious = function (f) {
this._onPreviousCallbacks.push(f);
};
/** Set the label. This is for accessability purposes only */
Numbers.prototype.setLabel = function () {
this.elements.label.innerHTML = this.getLabel();
};
Numbers.prototype.focusOnInput = function () {
this._onInputFocus
.slice(0)
.forEach(function (f) { return f(); });
};
Numbers.prototype.triggerValueChanged = function (value) {
if (this._triggerValue === value)
return;
this._triggerValue = value;
this._onValueChanged
.slice(0)
.forEach(function (f) { return f(value); });
};
/** Specify that this component is finished with input (like tab) */
Numbers.prototype.goNext = function () {
this._onNextCallbacks
.slice(0)
.forEach(function (cb) { return cb(); });
};
/** Specify that this component is finished with input (like shift tab) */
Numbers.prototype.goPrevious = function () {
this._onPreviousCallbacks
.slice(0)
.forEach(function (cb) { return cb(); });
};
/** re-calculate the width, height and position of the elements */
Numbers.prototype.refreshOffsets = function () {
this.offsetLeft = offset(this.elements.containerElement, "offsetLeft");
this.offsetTop = offset(this.elements.containerElement, "offsetTop");
this.width = this.elements.containerElement.offsetWidth;
this.height = this.elements.containerElement.offsetHeight;
var fontSize = parseFloat(window.getComputedStyle(this.elements.containerElement).fontSize || "x");
if (isNaN(fontSize))
fontSize = parseFloat(window.getComputedStyle(document.body).fontSize || "x");
this.fontSize = isNaN(fontSize) ? null : fontSize;
};
Numbers.prototype.getFocused = function () { return this.focused; };
/** Set the value based on the mouse position */
Numbers.prototype.setFromPosition = function (mouseX, mouseY) {
var v = this.getValuesFromPosition(mouseX - this.offsetLeft, mouseY - this.offsetTop);
this._set(v);
};
/** Set the value */
Numbers.prototype.set = function (value) {
var v = this.getValuesFromValue(value);
this._set(v);
};
Numbers.prototype._set = function (value) {
if (this.value &&
this.value.value === value.value &&
!compareAngles(this.value.angle, value.angle) &&
this.value.position === value.position)
return;
this.value = value;
this.numberInput.set(value.value);
this.highlightNumber();
this._onRenderValuesChanged
.slice(0)
.forEach(function (f) { return f(value); });
};
/** Highlight a number in the clock */
Numbers.prototype.highlightNumber = function () {
if (this.elements.selectedNumber) {
this.elements.selectedNumber.classList.remove("atp-number-selected");
}
this.elements.selectedNumber = this.getSelectedNumberElement();
if (this.elements.selectedNumber)
this.elements.selectedNumber.classList.add("atp-number-selected");
};
Numbers.prototype.getSelectedNumberElement = function () {
return this.elements.numbers[this.value.value] || null;
};
Numbers.prototype.numberInputTimeChanged = function (v) {
if (!this.ignoreCount)
this.set(v);
};
/** Ignore change events coming from the numberInput property */
Numbers.prototype.ignoreNumberInputChangeEvent = function () {
var _this = this;
this.ignoreCount++;
var done = false;
return function () {
if (done)
return;
done = true;
_this.ignoreCount--;
};
};
/** Focus this component
* @param {boolean} [focusInput=true] If true, will focus the cursor on the input also
*/
Numbers.prototype.focus = function (focusInput) {
if (focusInput === void 0) { focusInput = true; }
this.elements.containerElement.style.transform = "scale(1)";
this.elements.containerElement.style.opacity = "1";
this.focused = true;
this.numberInput.focus(focusInput);
};
/** Blur this component */
Numbers.prototype.blur = function () {
this.elements.containerElement.style.transform = "scale(0)";
this.elements.containerElement.style.opacity = "0";
this.focused = false;
this.numberInput.blur();
};
/** alter angle so that it is closest to the given angle, e.g. 500deg -> 140deg */
Numbers.prototype.normalizeAngle = function (angle) {
var angle1 = angle % numbers_360;
var angle2 = this.value.angle % numbers_360;
this.value.angle = angle + angle2 - angle1;
};
Numbers.prototype.dispose = function () {
this._onValueChanged.length = 0;
this._onPreviousCallbacks.length = 0;
this._onNextCallbacks.length = 0;
this._onInputFocus.length = 0;
this._onRenderValuesChanged.length = 0;
};
return Numbers;
}());
// CONCATENATED MODULE: ./src/components/hand.ts
var hand_90 = Math.PI / 2;
/**The hand of the clock which rotates to show the minute/hour */
var hand_Hand = /** @class */ (function () {
function Hand(elements) {
this.elements = elements;
this.angle = hand_90;
this.setPositon(this.angle, Position.far);
}
Hand.prototype.setPositon = function (angle, position) {
var _this = this;
var delta = getAngleDelta(this.angle, angle);
this.angle = this.angle + delta;
this.elements.hands.forEach(function (h) { return h.style.transform = "rotate(" + _this.angle + "rad)"; });
position === Position.near ?
this.elements.ballPostion.forEach(function (b) { return b.classList.add("atp-b-pos-pm"); }) :
this.elements.ballPostion.forEach(function (b) { return b.classList.remove("atp-b-pos-pm"); });
};
return Hand;
}());
// CONCATENATED MODULE: ./src/utils/distance.ts
var AmPm;
(function (AmPm) {
AmPm["am"] = "am";
AmPm["pm"] = "pm";
})(AmPm || (AmPm = {}));
function emToPx(em, fontSize) {
return (fontSize ||
parseFloat(window.getComputedStyle(document.body).fontSize ||
"12")) * em;
}
/** With a 24 hour clock box (width/height) and a mouse position (left/top),
* determine whether the use is pointing at an AM hour or a PM hour */
function getAMPM(left, top, width, height, fontSize) {
var w = width / 2;
var x = w - left;
var y = (height / 2) - top;
var distance = Math.sqrt((x * x) + (y * y));
var maxPm = w - emToPx(2.45, fontSize);
return distance > maxPm ? AmPm.am : AmPm.pm;
}
;
// CONCATENATED MODULE: ./src/utils/time.ts
var _30 = Math.PI / 6;
var _12 = Math.PI / 30;
var time_360 = Math.PI * 2;
var time_90 = Math.PI / 2;
/** Snap an angle to a given step. E.g. if angle = 22° and step = 10°, round down to 20° */
function snap(angle, step) {
var a = angle;
while (a < 0)
a += time_360;
var diff = a % step;
if (diff <= step / 2) {
return angle - diff;
}
return angle - diff + step;
}
/** Calculate the hour from the hand angle */
function getHours(handAngle, amPm) {
handAngle = snap(handAngle, _30);
var hour = parseInt((((handAngle - time_90) % time_360) / _30).toFixed());
if (hour < 0)
hour += 12;
if (hour >= 12)
hour -= 12;
if (!hour) {
if (amPm === AmPm.am)
hour = 12;
}
else {
if (amPm !== AmPm.am)
hour += 12;
}
return {
hour: hour,
handAngle: handAngle
};
}
var validate = /^\s*\d{1,2}\s*:\s*\d{1,2}\s*((am)|(pm))?\s*$/i;
function parseTime(time) {
if (!time || !validate.test(time))
return null;
var split = time.split(":");
var output = {
hour: parseInt(split[0]),
minute: parseInt(split[1])
};
if (output.minute < 0 || output.minute > 59)
return null;
if (/am/i.test(split[1])) {
if (output.hour < 1 || output.hour > 12)
return null;
}
else if (/pm/i.test(split[1])) {
if (output.hour < 1 || output.hour > 12)
return null;
if (output.hour === 12)
output.hour = 0;
else
output.hour += 12;
}
else {
if (output.hour < 0 || output.hour > 23)
return null;
}
return output;
}
/** Convert a 24 hour time into a string of the specified format */
function timeToString(h, m, mode) {
if (mode === 24) {
return ("0" + h).slice(-2) + ":" + ("0" + m).slice(-2);
}
else {
var ampm = !h || h > 12 ? " PM" : " AM";
if (!h)
h = 12;
else if (h > 12)
h -= 12;
return h + ":" + ("0" + m).slice(-2) + ampm;
}
}
/** Calculate the minute from the hand angle */
function getMinutes(handAngle) {
handAngle = snap(handAngle, _12);
var minute = parseInt((((handAngle - time_90) % time_360) / _12).toFixed());
while (minute < 0)
minute += 60;
while (minute >= 60)
minute -= 60;
return {
minute: minute,
handAngle: handAngle
};
}
function convert24hTo12h(value) {
if (!value)
return 12;
else if (value > 12)
return value - 12;
else
return value;
}
function convert12hTo24h(value, amPm) {
if (amPm === AmPm.am)
return value;
else if (amPm === AmPm.pm) {
if (value === 12)
return 0;
return value + 12;
}
else {
throw new Error("Expected \"am\" or \"pm\": \"" + amPm + "\"");
}
}
/** The default time format (12h/24h) based on the value of Date.prototype.toLocaleTimeString */
var defaultMode = (function () {
var locale = new Date("January 01, 2000 13:00:00 GMT+00:00").toLocaleTimeString();
return /(AM)|(PM)/i.test(locale) ? 12 : 24;
}());
// CONCATENATED MODULE: ./src/components/hours.ts
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var hours_90 = Math.PI / 2;
var hours_30 = Math.PI / 6;
/**A component to manage the hours */
var hours_Hours = /** @class */ (function (_super) {
__extends(Hours, _super);
function Hours(hourInput, elements, value) {
var _this = _super.call(this, hourInput, elements, value) || this;
_this.hourInput = hourInput;
_this.mode = 24;
_this.am = elements.am;
_this._toAm = registerMouseEvent(_this.am, "click", function () { return _this.setTo12Hr(AmPm.am); });
_this.pm = elements.pm;
_this._toPm = registerMouseEvent(_this.pm, "click", function () { return _this.setTo12Hr(AmPm.pm); });
_this.amPmButtons = elements.amPmButtons;
_this.showHideAmPm();
_this.onValueChanged(function () { return _this.highlightAmPm(); });
_this.highlightAmPm();
return _this;
}
/** Returns a label. The label is for accessability/screen reading purposes */
Hours.prototype.getLabel = function () { return "Hours " + this.mode + "h format"; };
/** Show/hide the AM/PM buttons based on the current "mode" */
Hours.prototype.showHideAmPm = function () {
if (this.mode === 12) {
this.amPmButtons.style.display = "";
this.amPmButtons.removeAttribute("aria-hidden");
}
else {
this.amPmButtons.style.display = "none";
this.amPmButtons.setAttribute("aria-hidden", "true");
}
};
/** Highlight the correct AM/PM button based on the current hour */
Hours.prototype.highlightAmPm = function () {
if (!this.value.value || this.value.value > 12) {
this.am.removeAttribute("aria-pressed");
this.pm.setAttribute("aria-pressed", "");
}
else {
this.pm.removeAttribute("aria-pressed");
this.am.setAttribute("aria-pressed", "");
}
};
/** Set the mode to 12h. Optionally , specify whether the time is AM or PM */
Hours.prototype.setTo12Hr = function (amPm) {
var value = this.value.value;
if (amPm) {
value = convert12hTo24h(convert24hTo12h(value), amPm);
}
this.mode = 12;
this.showHideAmPm();
this.hidePMHours();
var ig = this.ignoreNumberInputChangeEvent();
try {
this.hourInput.setTo12Hr(amPm);
}
finally {
ig();
}
// accessability label changes based on mode
this.setLabel();
this.set(value);
};
/** Set the mode to 24h. */
Hours.prototype.setTo24Hr = function () {
this.mode = 24;
this.showHideAmPm();
this.showPMHours();
var ig = this.ignoreNumberInputChangeEvent();
try {
this.hourInput.setTo24Hr();
}
finally {
ig();
}
// accessability label changes based on mode
this.setLabel();
this.set(this.value.value);
};
/** Hide hours 00 and 13 - 23 for 12h format */
Hours.prototype.hidePMHours = function () {
this.elements.numbers
.slice(0, 1)
.concat(this.elements.numbers.slice(13))
.forEach(function (x) { return x.style.display = "none"; });
};
/** Show hours 00 and 13 - 23 for 24h format */
Hours.prototype.showPMHours = function () {
this.elements.numbers
.slice(0, 1)
.concat(this.elements.numbers.slice(13))
.forEach(function (x) { return x.style.display = ""; });
};
/** Get the html element of the number currently selected */
Hours.prototype.getSelectedNumberElement = function () {
if (this.mode === 12) {
return this.elements.numbers[convert24hTo12h(this.value.value)];
}
return _super.prototype.getSelectedNumberElement.call(this);
};
/** Get the hour, angle, etc... based on the mouse position */
Hours.prototype.getValuesFromPosition = function (x, y) {
var angle = getAngle(x, y, this.elements.containerElement.offsetWidth, this.elements.containerElement.offsetHeight);
var amPm = this.mode === 24 ?
getAMPM(x, y, this.elements.containerElement.offsetWidth, this.elements.containerElement.offsetHeight, this.fontSize) :
this.value.value && this.value.value <= 12 ? AmPm.am : AmPm.pm;
var value = getHours(angle, amPm);
return {
angle: value.handAngle,
value: value.hour,
position: this.mode === 12 || amPm === AmPm.am ? Position.far : Position.near
};
};
/** Get the hour, angle, etc... based on the hour */
Hours.prototype.getValuesFromValue = function (value) {
value = parseInt(value.toFixed()) % 24;
var angle = (value * hours_30) + hours_90;
return {
angle: angle,
value: value,
position: this.mode === 12 || (value && value <= 12) ? Position.far : Position.near
};
};
Hours.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this._toAm();
this._toPm();
};
return Hours;
}(numbers_Numbers));
// CONCATENATED MODULE: ./src/assets/template.ts
// THIS IS AN AUTOGENERATED FILE, BUILD USING ./tools/buildHtmlTemplate.js
function create(model) {
var el = document.createElement('div');
el.innerHTML = "<div class=\"atp atp-background-color\" role=\"form\" aria-describedby=\"" + model.title + "\"><label style=\"display: none\" id=\"" + model.title + "\">Enter time</label><div class=\"atp-time atp-color--primary mdl-color--primary\"><label style=\"display: none\" for=\"" + model.hour + "\" class=\"atp-hour-label\">Hours</label><input type=\"text\" class=\"atp-hour\" id=\"" + model.hour + "\" />:<label style=\"display: none\" for=\"" + model.minute + "\" class=\"atp-minute-label\">Minutes</label><input type=\"text\" class=\"atp-minute\" id=\"" + model.minute + "\" /><div class=\"atp-ampm\"><label style=\"display: none\" for=\"" + model.am + "\">Change to AM</label><button class=\"atp-am\" id=\"" + model.am + "\">am</button><label style=\"display: none\" for=\"" + model.pm + "\">Change to PM</label><button class=\"atp-pm\" id=\"" + model.pm + "\">pm</button></div></div><div class=\"atp-clock-cnt\"><div class=\"atp-clock\" aria-hidden=\"true\"><div class=\"atp-face atp-face-color\"></div><div class=\"atp-h-cnt-cnt\"><div class=\"atp-h-cnt\"><div class=\"atp-b-pos\"></div><div class=\"atp-b atp-color--primary mdl-color--primary\"></div></div></div><div class=\"atp-ns atp-hours atp-number-color\"><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-0\"><div class=\"atp-n atp-n-0\">12</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-0\">00</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-1\"><div class=\"atp-n atp-n-1\">01</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-1\">13</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-2\"><div class=\"atp-n atp-n-2\">02</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-2\">14</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-3\"><div class=\"atp-n atp-n-3\">03</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-3\">15</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-4\"><div class=\"atp-n atp-n-4\">04</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-4\">16</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-5\"><div class=\"atp-n atp-n-5\">05</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-5\">17</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-6\"><div class=\"atp-n atp-n-6\">06</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-6\">18</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-7\"><div class=\"atp-n atp-n-7\">07</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-7\">19</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-8\"><div class=\"atp-n atp-n-8\">08</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-8\">20</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-9\"><div class=\"atp-n atp-n-9\">09</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-9\">21</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-10\"><div class=\"atp-n atp-n-10\">10</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-10\">22</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-11\"><div class=\"atp-n atp-n-11\">11</div><div class=\"atp-n-pad\"></div><div class=\"atp-n atp-n-11\">23</div></div></div></div><div class=\"atp-ns atp-minutes atp-number-color\"><div class=\"atp-n-cnt atp-n-cnt-0\"><div class=\"atp-n atp-n-0\">00</div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-1\"><div class=\"atp-n atp-n-1\">05</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-2\"><div class=\"atp-n atp-n-2\">10</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-3\"><div class=\"atp-n atp-n-3\">15</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-4\"><div class=\"atp-n atp-n-4\">20</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-5\"><div class=\"atp-n atp-n-5\">25</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-6\"><div class=\"atp-n atp-n-6\">30</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-7\"><div class=\"atp-n atp-n-7\">35</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-8\"><div class=\"atp-n atp-n-8\">40</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-9\"><div class=\"atp-n atp-n-9\">45</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-10\"><div class=\"atp-n atp-n-10\">50</div></div></div><div class=\"atp-n-box\"><div class=\"atp-n-cnt atp-n-cnt-11\"><div class=\"atp-n atp-n-11\">55</div></div></div></div><div class=\"atp-h-cnt-cnt\"><div class=\"atp-h-cnt\"><div class=\"atp-b-pos\"></div><div class=\"atp-b-spacer\"></div><div class=\"atp-h atp-color--primary mdl-color--primary\"></div></div></div><div class=\"atp-h-cnt-cnt atp-h-cnt-cnt-dot\"><div class=\"atp-h-dot atp-color--primary mdl-color--primary\"></div></div></div><div class=\"atp-clock-btn\"><button class=\"atp-ok atp-button mdl-button atp-button atp-button--primary mdl-button--primary atp-enforce-font-size\">ok</button><button class=\"atp-cancel atp-button mdl-button atp-button atp-button--primary mdl-button--primary atp-enforce-font-size\">cancel</button></div></div></div>";
var child = el.firstChild;
el.removeChild(child);
return child;
}
// CONCATENATED MODULE: ./src/components/htmlTree.ts
var getId = (function () {
var i = Math.floor(Math.random() * 100000);
return function () { return "atp-" + ++i; };
}());
function buildHtmlModel() {
var id = getId();
return {
hour: id + "-hour",
minute: id + "-minute",
am: id + "-am",
pm: id + "-pm",
title: id + "-title"
};
}
function getPxValue(width) {
// if value has no units, interpret as px
if (/^\s*\d+(\.\d*)?\s*$/.test(width))
width += "px";
if (/px\s*$/.test(width))
return parseFloat(width);
var test = document.createElement("div");
test.style.width = width;
document.body.appendChild(test);
var w = test.offsetWidth;
removeChildSafe(document.body, test);
return w;
}
// const fontMultiplier = 6 / 75;
var fontMultiplier = 4 / 75;
function getFontSize(width) {
// don't set font size for em or %
if (/(em|%)\s*$/.test(width))
return null;
var widthPx = getPxValue(width);
if (isNaN(widthPx))
throw new Error("Invalid width value: " + width);
if (widthPx <= 0)
console.warn("Width value \"" + width + "\" came to " + widthPx + "px");
return widthPx * fontMultiplier;
}
/** Creates or uses existing element and populates it with the html template */
var htmlTree_HtmlTree = /** @class */ (function () {
function HtmlTree(width, rootHtmlElement) {
this.element = create(buildHtmlModel());
if (rootHtmlElement) {
rootHtmlElement.innerHTML = "";
rootHtmlElement.appendChild(this.element);
}
this.setWidth(width);
}
HtmlTree.prototype.setWidth = function (widthValue) {
this.element.style.width = widthValue;
var fs = getFontSize(widthValue);
this.element.style.fontSize = fs != null ? fs + "px" : null;
};
HtmlTree.prototype.dispose = function () {
if (this.element.parentElement) {
this.element.parentElement.removeChild(this.element);
}
};
return HtmlTree;
}());
// CONCATENATED MODULE: ./src/components/minutes.ts
var minutes_extends = (undefined && undefined.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var minutes_90 = Math.PI / 2;
var _6 = Math.PI / 30;
var minutes_Minutes = /** @class */ (function (_super) {
minutes_extends(Minutes, _super);
function Minutes() {
return _super !== null && _super.apply(this, arguments) || this;
}
/** Get the minute, angle, etc... based on the mouse position */
Minutes.prototype.getValuesFromPosition = function (x, y) {
var angle = getAngle(x, y, this.elements.containerElement.offsetWidth, this.elements.containerElement.offsetHeight);
var value = getMinutes(angle);
return {
angle: value.handAngle,
value: value.minute,
position: Position.far
};
};
/** Returns a label. The label is for accessability/screen reading purposes */
Minutes.prototype.getLabel = function () { return "Minutes"; };
/** Get the minute, angle, etc... based on the minute */
Minutes.prototype.getValuesFromValue = function (value) {
value = parseInt(value.toFixed()) % 60;
var angle = (value * _6) + minutes_90;
return {
angle: angle,
value: value,
position: Position.far
};
};
return Minutes;
}(numbers_Numbers));
// CONCATENATED MODULE: ./src/utils/numberKeyPressInterpreters.ts
var numberKeyPressInterpreters_assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
/** Increase a numer with loop back over the max value */
function increase(val, max) {
var v = parseInt(val) + 1;
return v > max ? 0 : v;
}
/** Decrease a numer with loop back over the min value */
function decrease(val, max) {
var v = parseInt(val) - 1;
return v < 0 ? max : v;
}
/** Get the value and mouse position after a number key is pressed */
function getNewElementValues(element, key, max) {
var actualStart = element.selectionStart || 0;
var start = actualStart > 1 ?
1 :
actualStart;
var val1 = (element.value || "").substr(0, start);
var val2 = (element.value || "").substr(start + 1);
var value = parseInt("" + val1 + key + val2);
if (isNaN(value) || value < 0)
return null;
if (value <= max) {
var skip = 0;
if (!val1 && !val2 && value * 10 > max) {
// special case for when only 1 digit fits in the text box
skip++;
}
return {
value: value,
nextPosition: actualStart + 1 + skip
};
}
if (!actualStart) {
// set last digit to 0 and try again
value -= value % 10;
if (value <= max)
return {
value: value,
nextPosition: actualStart + 1
};
// just use the key as is
value = parseInt(key);
if (!isNaN(value) && value <= max)
return {
value: value,
// skipped an extra digit by using first key
nextPosition: actualStart + 2
};
}
return null;
}
var numberKey = /^\d$/;
var fKey = /^F\d+$/;
/** Get values which can inform a decision on what to do when a key is pressed */
function keyPressDetails(element, e, max) {
var handled = true;
switch (e.key) {
case "ArrowUp":
case "Up":
return {
handled: true,
value: increase(element.value, max)
};
case "ArrowDown":
case "Down":
return {
handled: true,
value: decrease(element.value, max)
};
case "ArrowRight":
case "Right":
var nextPosition = (element.selectionStart || 0) + 1;
return {
handled: nextPosition > 2,
nextPosition: nextPosition > 2 ? nextPosition : undefined
};
case "ArrowLeft":
case "Left":
var nextPosition = (element.selectionStart || 0) - 1;
return {
handled: nextPosition < 0,
nextPosition: nextPosition < 0 ? nextPosition : undefined
};
case "Tab":
return {
handled: false
};
default:
if (numberKey.test(e.key)) {
return numberKeyPressInterpreters_assign({ handled: true }, getNewElementValues(element, e.key, max));
}
else if (fKey.test(e.key)) {
return {
handled: false
};
}
}
return { handled: true };
}
// CONCATENATED MODULE: ./src/components/numberInput.ts
/** Component to manage the number number textbox (e.g. the hour/minute) */
var numberInput_NumberInput = /** @class */ (function () {
function NumberInput(input) {
var _this = this;
this.input = input;
this.value = 0;
this._onFocus = [];
this._onNextCallbacks = [];
this._onPreviousCallbacks = [];
this._timeChangedCallbacks = [];
this._keyPressHandler = registerKeyEvent(input, "keydown", function (e) { return _this.keyDown(e); });
this._focusHandler = registerKeyEvent(input, "focus", function (e) { return _this.focusOnInput(); });
}
/**Callback for when element receives focus */
NumberInput.prototype.onFocus = function (f) {
this._onFocus.push(f);
};
/**Callback for when element is complete (like tab) */
NumberInput.prototype.onNext = function (f) {
this._onNextCallbacks.push(f);
};
/**Callback for when element is complete (like shift tab) */
NumberInput.prototype.onPrevious = function (f) {
this._onPreviousCallbacks.push(f);
};
/**Callback for when value in the textbox has changed */
NumberInput.prototype.onTimeChanged = function (callback) {
this._timeChangedCallbacks.push(callback);
};
NumberInput.prototype.keyDown = function (e) {
var details = keyPressDetails(this.input, e, this.getMaxValue());
if (details.handled)
e.preventDefault();
if (details.value != null) {
this._set(details.value);
}
if (details.nextPosition != null) {
if (details.nextPosition < 0) {
this._onPreviousCallbacks.forEach(function (f) { return f(); });
}
else {
this.input.selectionEnd = details.nextPosition;
this.input.selectionStart = details.nextPosition;
if (details.nextPosition > 1) {
this._onNextCallbacks.forEach(function (f) { return f(); });
}
}
}
};
NumberInput.prototype.focusOnInput = function () {
this._onFocus
.slice(0)
.forEach(function (f) { return f(); });
};
/** Set a value in the textbox */
NumberInput.prototype.set = function (value) {
if (value < 0 || value > this.getMaxValue())
throw new Error("Invalid value \"" + value + "\"");
this._set(parseInt(value.toFixed()));
};
NumberInput.prototype._set = function (value) {
var changed = this.value !== value;
this.value = value;
this.input.value = this.transformInputValue(value);
if (changed) {
this._timeChangedCallbacks
.slice(0)
.forEach(function (f) { return f(value); });
}
};
/**
* @param {boolean} [focusInput=true] If true, will focus the cursor on the input also
*/
NumberInput.prototype.focus = function (focusInput) {
if (focusInput === void 0) { focusInput = true; }
this.input.classList.add("atp-focus");
if (focusInput) {
this.input.focus();
this.input.selectionStart = 0;
this.input.selectionEnd = 0;
}
};
NumberInput.prototype.blur = function () {
this.input.classList.remove("atp-focus");
};
NumberInput.prototype.dispose = function () {
this._focusHandler();
this._keyPressHandler();
this._onFocus.length = 0;
this._onPreviousCallbacks.length = 0;
this._onNextCallbacks.length = 0;
this._timeChangedCallbacks.length = 0;
};
return NumberInput;
}());
// CONCATENATED MODULE: ./src/components/hourInput.ts
var hourInput_extends = (undefined && undefined.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/** An input to manage hours */
var hourInput_HourInput = /** @class */ (function (_super) {
hourInput_extends(HourInput, _super);
function HourInput() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.mode = 24;
return _this;
}
HourInput.prototype.getMaxValue = function () { return 23; };
/**Set to 12h mode and set am/pm if necessary */
HourInput.prototype.setTo12Hr = function (amPm) {
var value = this.value;
if (amPm) {
value = convert12hTo24h(convert24hTo12h(value), amPm);
}
this.mode = 12;
this.set(value);
};
HourInput.prototype.setTo24Hr = function () {
this.mode = 24;
this.set(this.value);
};
/**Convert a 24 hour value into a 12 hour value if necessary */
HourInput.prototype.transformInputValue = function (value) {
if (this.mode === 12) {
if (!value)
value = 12;
else if (value > 12)
value -= 12;
return value.toString();
}
return ("0" + value).slice(-2);
};
return HourInput;
}(numberInput_NumberInput));
// CONCATENATED MODULE: ./src/components/minuteInput.ts
var minuteInput_extends = (undefined && undefined.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/** A numner input for mintes */
var MinuteInput = /** @class */ (function (_super) {
minuteInput_extends(MinuteInput, _super);
function MinuteInput() {
return _super !== null && _super.apply(this, arguments) || this;
}
MinuteInput.prototype.getMaxValue = function () { return 59; };
MinuteInput.prototype.transformInputValue = function (value) {
return ("0" + value).slice(-2);
};
return MinuteInput;
}(numberInput_NumberInput));
// CONCATENATED MODULE: ./src/di.ts
function toArray(xs) {
return Array.prototype.slice.call(xs);
}
/** A DI container which creates components and manages their lifecycles */
var di_DiContext = /** @class */ (function () {
function DiContext(config, rootHtmlElement) {
this.config = config;
this.disposables = [];
this.htmlTree = new htmlTree_HtmlTree(config.width, rootHtmlElement);
this.disposables.push(this.htmlTree);
}
DiContext.prototype.getRootElement = function () {
return this.htmlTree.element;
};
DiContext.prototype.getInnerElement = function (selector) {
var el = this.getRootElement().querySelectorAll(selector);
if (el.length !== 1) {
var message = el.length ? "Too many elements" : "Cannot find element";
throw new Error(message + " \"" + selector + "\".");
}
return el[0];
};
DiContext.prototype.buildHoursElementList = function (index) {
var list = [];
for (var i = 0; i < 12; i++) {
list[i] = this.getRootElement().querySelectorAll(".atp-hours .atp-n-" + i)[index];
}
return list.map(function (el, i) {
if (!el)
throw new Error("Invalid hours element " + i + ".");
return el;
});
};
DiContext.prototype.buildHoursElements = function () {
var hours = this
.buildHoursElementList(0)
.concat(this.buildHoursElementList(1));
// re-arrange numbers to put the 12 and 00 at the correct indexes
hours.splice(11, 0, hours.splice(0, 1)[0]);
hours.splice(0, 0, hours.splice(12, 1)[0]);
return {
numbers: hours,
containerElement: this.getInnerElement(".atp-hours"),
amPmButtons: this.getInnerElement(".atp-ampm"),
am: this.getInnerElement(".atp-am"),
pm: this.getInnerElement(".atp-pm"),
label: this.getInnerElement(".atp-hour-label")
};
};
DiContext.prototype.buildHoursInput = function () {
if (!this.hourInput) {
var el = this.getInnerElement(".atp-hour");
this.hourInput = new hourInput_HourInput(el);
this.disposables.push(this.hourInput);
}
return this.hourInput;
};
DiContext.prototype.buildHours = function () {
if (!this.hours) {
this.hours = new hours_Hours(this.buildHoursInput(), this.buildHoursElements(), this.config.time.hour);
this.disposables.push(this.hours);
}
return this.hours;
};
DiContext.prototype.buildMinutesElementList = function () {
var list = [];
for (var i = 0; i < 12; i++) {
list[(i * 5) % 60] = this.getRootElement().querySelectorAll(".atp-minutes .atp-n-" + i)[0];
}
return list.map(function (el, i) {
if (!el)
throw new Error("Invalid hours element " + i + ".");
return el;
});
};
DiContext.prototype.buildMinutesElements = function () {
return {
containerElement: this.getInnerElement(".atp-minutes"),
numbers: this.buildMinutesElementList(),
label: this.getInnerElement(".atp-minute-label")
};
};
DiContext.prototype.buildMinutesInput = function () {
if (!this.minuteInput) {
var el = this.getInnerElement(".atp-minute");
this.minuteInput = new MinuteInput(el);
this.disposables.push(this.minuteInput);
}
return this.minuteInput;
};
DiContext.prototype.buildMinutes = function () {
if (!this.minutes) {
this.minutes = new minutes_Minutes(this.buildMinutesInput(), this.buildMinutesElements(), this.config.time.minute);
this.disposables.push(this.minutes);
}
return this.minutes;
};
DiContext.prototype.buildHandElements = function () {
return {
ballPostion: toArray(this.getRootElement().querySelectorAll(".atp-b-pos")),
hands: toArray(this.getRootElement().querySelectorAll(".atp-h-cnt"))
};
};
DiContext.prototype.buildHand = function () {
return this.hand || (this.hand = new hand_Hand(this.buildHandElements()));
};
DiContext.prototype.buildTimePickerElements = function () {
return {
okButton: this.getInnerElement(".atp-ok"),
cancelButton: this.getInnerElement(".atp-cancel"),
clock: this.getInnerElement(".atp-clock")
};
};
DiContext.prototype.buildTimePicker = function () {
if (!this.timePicker) {
this.timePicker = new timePicker_TimePicker(this.buildTimePickerElements(), this.buildHours(), this.buildMinutes(), this.buildHand(), this.config.mode, this.config.focusOnInput);
this.disposables.push(this.timePicker);
}
return this.timePicker;
};
DiContext.prototype.dispose = function () {
this.disposables
.splice(0, Number.MAX_VALUE)
.forEach(function (x) { return x.dispose(); });
};
return DiContext;
}());
// CONCATENATED MODULE: ./src/init/parseInputs.ts
function parseTimeValues(hour, minute) {
var h = 0;
if (hour != null) {
h = parseInt(hour);
if (isNaN(h) || h < 0 || h > 23) {
throw new Error("The hr (" + hour + ") argument must be between 0 and 23.");
}
}
var m = 0;
if (minute != null) {
m = parseInt(minute);
if (isNaN(m) || m < 0 || m > 59) {
throw new Error("The mn (" + minute + ") argument must be between 0 and 59.");
}
}
return {
hour: h,
minute: m
};
}
function parseTimeInput(time) {
if (!time)
return { hour: 0, minute: 0 };
if (time instanceof Date) {
return {
hour: time.getHours(),
minute: time.getMinutes()
};
}
else {
return parseTimeValues(time.hour, time.minute);
}
}
function parseHtmlElement(el) {
if (el == null)
return undefined;
if (el instanceof HTMLElement)
return el;
throw new Error("The element must be a HTMLElement");
}
function parseMode(mode) {
if (mode == null)
return 24;
var m = parseInt(mode);
if (m === 12)
return 12;
else if (m === 24)
return 24;
else
throw new Error("The mode argument must be null, undefined, 12 or 24.");
}
function parseWidth(width) {
if (width == null)
return "300px";
if (typeof width === "number") {
if (width < 0)
throw new Error("The width (" + width + ") argument must be >= 0.");
return width + "px";
}
else if (typeof width === "string") {
return width;
}
else {
throw new Error("The width (" + width + ") argument must be a number or string.");
}
}
// CONCATENATED MODULE: ./src/init/publicTimePicker.ts
/**Wrap a DI context in a new public TimePicker object.
* The pulic TimePicker is more fault tolerant and is made
* to interact with js rather than ts
* It also has dispose logic and an onDispose event */
function publicTimePicker(context) {
var timePicker = context.buildTimePicker();
var element = context.getRootElement();
var onDispose = [];
function dispose() {
context.dispose();
onDispose
.splice(0, Number.MAX_VALUE)
.forEach(function (f) { return f(); });
}
timePicker.onOk(dispose);
timePicker.onCancel(dispose);
return {
element: element,
setWidth: function (width) {
context.htmlTree.setWidth(width == null || width === "" ?
"100%" :
typeof width === "number" ? width + "px" : width.toString());
},
getTime: function () { return timePicker.getTime(); },
setTime: function (hours, minutes) {
var h = parseInt(hours);
if (isNaN(h))
throw new Error("The hours value \"" + hours + "\" must be a number");
var m = parseInt(minutes);
if (isNaN(m))
throw new Error("The minutes value \"" + minutes + "\" must be a number");
if (h < 0 || h > 23)
throw new Error("The hours value \"" + h + "\" must be between 0 and 23");
if (m < 0 || m > 59)
throw new Error("The minutes value \"" + m + "\" must be between 0 and 59");
timePicker.setTime(h, m);
},
set12h: function () { return timePicker.setMode(12); },
set24h: function () { return timePicker.setMode(24); },
showHours: function () { return timePicker.showHours(true); },
showMinutes: function () { return timePicker.showMinutes(); },
ok: function () { return timePicker.okClick(); },
cancel: function () { return timePicker.cancelClick(); },
onTimeChanged: function (callback) {
if (typeof callback !== "function") {
throw new Error("onOk callback must be a function");
}
timePicker.onTimeChanged(callback);
},
onOk: function (callback) {
if (typeof callback !== "function") {
throw new Error("onOk callback must be a function");
}
timePicker.onOk(callback);
},
onCancel: function (callback) {
if (typeof callback !== "function") {
throw new Error("onCancel callback must be a function");
}
timePicker.onCancel(callback);
},
onDispose: function (callback) {
if (typeof callback !== "function") {
throw new Error("onCancel callback must be a function");
}
onDispose.push(callback);
},
dispose: dispose
};
}
// CONCATENATED MODULE: ./src/init/timePicker.ts
function parseTimePickerData(input) {
if (!input)
input = {};
return {
config: {
time: parseTimeInput(input.time),
mode: parseMode(input.mode),
width: parseWidth(input.width),
focusOnInput: !!input.focus
},
element: parseHtmlElement(input.element)
};
}
/** Create a new time picker. The timepicker lives in the "element" return value which can then be appended to the DOM */
function timePicker_create(input) {
var _input = parseTimePickerData(input);
var context = new di_DiContext(_input.config, _input.element);
return publicTimePicker(context);
}
// CONCATENATED MODULE: ./src/init/timePickerModal.ts
function parseInputs(input) {
if (!input)
input = {};
return {
config: {
time: parseTimeInput(input.time),
mode: parseMode(input.mode),
width: parseWidth(input.width),
focusOnInput: true
}
};
}
/** Create a new time picker and render in a modal */
function timePickerModal_create(input) {
var _input = parseInputs(input);
var context = new di_DiContext(_input.config);
var timePicker = publicTimePicker(context);
var modal = createModal(timePicker.element);
modal.onClickOrEsc(function () { return timePicker.cancel(); });
timePicker.onDispose(modal.dispose);
// focus on the first textbox in the time picker
context.getInnerElement(".atp-hour").focus();
return timePicker;
}
// CONCATENATED MODULE: ./src/init/timePickerInput.ts
/** Create a new time picker and render in a modal each time an input is focused */
function timePickerInput_create(input) {
if (!input || !(input.inputElement instanceof HTMLInputElement)) {
throw new Error("The inputElement must be a html input element");
}
var modal = null;
var el = input.inputElement;
var displayModal = function () {
modal = timePickerModal_create({
mode: input.mode,
width: input.width,
time: parseTime(el.value)
});
modal.onOk(function (h, m) {
// assuming that the timePickerModal call will have validated the mode
el.value = timeToString(h, m, input.mode || 24);
});
modal.onDispose(function () { return modal = null; });
};
var dispose = [
registerEvent(el, "focus", displayModal),
// prevent use input on input
registerEvent(el, "keyup", function (e) { return e.preventDefault(); }),
registerEvent(el, "keydown", function (e) { return e.preventDefault(); }),
registerEvent(el, "keypress", function (e) { return e.preventDefault(); })
];
var mode = parseMode(input.mode);
if (input.time) {
var t = parseTimeInput(input.time);
el.value = timeToString(t.hour, t.minute, mode);
}
if (document.activeElement === el)
displayModal();
return {
getTime: function () {
if (modal)
return modal.getTime();
return parseTime(el.value || "");
},
setTime: function (hour, minute, force) {
if (force === void 0) { force = false; }
if (modal) {
modal.setTime(hour, minute);
}
if (!modal || force) {
var time = parseTimeValues(hour, minute);
el.value = timeToString(time.hour, time.minute, mode);
}
},
dispose: function () {
if (modal)
modal.dispose();
dispose
.splice(0, Number.MAX_VALUE)
.forEach(function (f) { return f(); });
}
};
}
// CONCATENATED MODULE: ./src/assets/style.ts
// THIS IS AN AUTOGENERATED FILE, BUILD USING ./tools/buildCss.js
var css = ".atp-number-color{color:black;}.atp-number-selected{color:white;}.atp-background-color{background-color:white;}.atp-face-color{background-color:rgb(238, 238, 238);}.atp{width:100%;cursor:default;box-shadow:rgba(0, 0, 0, 0.25) 0px 14px 45px, rgba(0, 0, 0, 0.22) 0px 10px 18px;font-family:\"Helvetica\", \"Arial\", sans-serif;}.atp-clock-cnt{padding:2em 1em 1em 1em;}.atp-clock{width:100%;position:relative;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-o-user-select:none;user-select:none;}.atp-clock::before{content:\"\";display:block;padding-top:100%; }.atp-clock>*{width:100%;height:100%;position:absolute;top:0;left:0;}.atp-face{border-radius:100%;}.atp-ns{transform:scale(1);transition:transform 0.3s, opacity 0.05s;display:flex;}.atp-h-cnt-cnt{display:flex;align-items:center;}.atp-h-cnt-cnt-dot{justify-content:center;}.atp-h-cnt{height:1.65em;display:flex;transition:transform 0.1s;transform-origin:100% 50%;width:50%;align-items:center;transform:rotate(1.5708rad);}.atp-h-dot{height:0.3em;width:0.3em;border-radius:50%;}.atp-h{height:0.1em;flex:1;}.atp-n-box{width:100%;height:100%;top:0;left:0;position:absolute;display:flex;align-items:center;}.atp-n-cnt{width:100%;display:flex;align-items:center;padding-left:0.5em;}.atp-n-cnt>*{float:left;}.atp-n{width:1.3em;text-align:center;line-height:1.3em;height:1.3em;transition:color 0.1s;}.atp-clock *::selection{background:transparent;}.atp-n-pad{width:0.8em;height:1px;}.atp-n-cnt-1{transform:rotate(120deg);}.atp-n-1{transform:rotate(-120deg);}.atp-n-cnt-2{transform:rotate(150deg);}.atp-n-2{transform:rotate(-150deg);}.atp-n-cnt-3{transform:rotate(180deg);}.atp-n-3{transform:rotate(-180deg);}.atp-n-cnt-4{transform:rotate(210deg);}.atp-n-4{transform:rotate(-210deg);}.atp-n-cnt-5{transform:rotate(240deg);}.atp-n-5{transform:rotate(-240deg);}.atp-n-cnt-6{transform:rotate(270deg);}.atp-n-6{transform:rotate(-270deg);}.atp-n-cnt-7{transform:rotate(300deg);}.atp-n-7{transform:rotate(-300deg);}.atp-n-cnt-8{transform:rotate(330deg);}.atp-n-8{transform:rotate(-330deg);}.atp-n-cnt-10{transform:rotate(30deg);}.atp-n-10{transform:rotate(-30deg);}.atp-n-cnt-11{transform:rotate(60deg);}.atp-n-11{transform:rotate(-60deg);}.atp-n-cnt-0{transform:rotate(90deg);}.atp-n-0{transform:rotate(-90deg);}.atp-b,.atp-b-spacer{width:1.65em;}.atp-b-spacer{height:1px;}.atp-b{height:1.65em;border-radius:1.65em;}.atp-b-pos{width:0.32em;transition:width 0.1s;height:1px;display:inline-block;}.atp-b-pos-pm{width:2.42em}.atp-clock-btn{padding-top:2em;display:flex;flex-direction:row-reverse;}.atp-time{color:white;font-size:350%;padding:0.3em;text-align:right;}.atp-time .atp-hour,.atp-time .atp-minute{font-size:100%;width:1.3em;background:transparent;border:0;color:white;outline-width:0;opacity:0.7;}.atp-hour.atp-focus,.atp-minute.atp-focus,.atp-am[aria-pressed],.atp-pm[aria-pressed]{opacity:1;}.atp-time .atp-hour{text-align:right;}.atp-ampm{display:inline-block;}.atp-am,.atp-pm{background:transparent;border:0;display:block;text-transform:uppercase;color:white;outline-width:0;font-size:28%;cursor:pointer;opacity:0.7;}button.atp-enforce-font-size{font-size:100%;min-width:0;}.atp-color--primary{background-color:rgb(0,150,136);}.atp-button{background:0 0;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:\"Roboto\",\"Helvetica\",\"Arial\",sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:rgba(255,255,255,0);}.atp-button--primary{color:rgb(0,150,136);}.atp-modal{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0, 0, 0, 0.54);display:flex;justify-content:center;align-items:center;}";
var enabled = false;
function enable() {
if (enabled)
return;
enabled = true;
var el = document.createElement('style');
el.innerHTML = css;
var parent = document.head || document.body;
parent.firstChild ?
parent.insertBefore(el, parent.firstChild) :
parent.appendChild(el);
}
// CONCATENATED MODULE: ./index.ts
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timePicker", function() { return index_timePicker; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timePickerModal", function() { return timePickerModal; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timePickerInput", function() { return timePickerInput; });
var index_timePicker = timePicker_create;
var timePickerModal = timePickerModal_create;
var timePickerInput = timePickerInput_create;
// add css to page
enable();
/***/ })
/******/ ]);
});