Things almost done

This commit is contained in:
Astatin3
2024-01-05 08:59:40 -07:00
parent 2928814d88
commit ad431dd4da
25 changed files with 2438 additions and 2 deletions
BIN
View File
Binary file not shown.
+55
View File
@@ -0,0 +1,55 @@
import * as utils from '/src/utils.js'
import * as jsonpack from '/src/jsonpack.js'
let c = null
export function authClient(rawClient) {
c = this
this.rawClient = rawClient
this.login = (username, password)=>{
const salt = utils.getUnixTime()
const key = (utils.sha256(
username +
utils.sha256(password) +
salt
))
//console.log(c.rawClient.send)
c.rawClient.send('login', {
data: key,
salt: salt
})
}
this.send = (data)=>{
}
this.clidata = (data)=>{
// const session = utils.getCookie('session')
// if(session != ''){
// this.rawClient.send('reauth', {
// session: session
// })
// }
}
this.loginSuccess = (data)=>{
utils.popupSuccess('Connection', 'Successfully logged in!')
utils.iconauth()
console.log(data.data.session)
if(data.data.session != null){
utils.setCookie('session', data.data.session)
}
window.location = data.data.redir
}
this.reauth = (data)=>{
utils.popupSuccess('Connection', 'Successfully logged in!')
utils.iconauth()
}
this.rawClient.addRawTypeListener('clidata', this.clidata)
this.rawClient.addRawTypeListener('loginSuccess', this.loginSuccess)
this.rawClient.addRawTypeListener('reauth', this.reauth)
}
+559
View File
@@ -0,0 +1,559 @@
/*
Copyright (c) 2013, Rodrigo González, Sapienlab All Rights Reserved.
Available via MIT LICENSE. See https://github.com/roro89/jsonpack/blob/master/LICENSE.md for details.
*/
var TOKEN_TRUE = -1;
var TOKEN_FALSE = -2;
var TOKEN_NULL = -3;
var TOKEN_EMPTY_STRING = -4;
var TOKEN_UNDEFINED = -5;
export function pack(json, options) {
// Canonizes the options
options = options || {};
// A shorthand for debugging
var verbose = options.verbose || false;
verbose && console.log('Normalize the JSON Object');
// JSON as Javascript Object (Not string representation)
json = typeof json === 'string' ? this.JSON.parse(json) : json;
verbose && console.log('Creating a empty dictionary');
// The dictionary
var dictionary = {
strings : [],
integers : [],
floats : []
};
verbose && console.log('Creating the AST');
// The AST
var ast = (function recursiveAstBuilder(item) {
verbose && console.log('Calling recursiveAstBuilder with ' + this.JSON.stringify(item));
// The type of the item
var type = typeof item;
// Case 7: The item is null
if (item === null) {
return {
type : 'null',
index : TOKEN_NULL
};
}
//add undefined
if (typeof item === 'undefined') {
return {
type : 'undefined',
index : TOKEN_UNDEFINED
};
}
// Case 1: The item is Array Object
if ( item instanceof Array) {
// Create a new sub-AST of type Array (@)
var ast = ['@'];
// Add each items
for (var i in item) {
if (!item.hasOwnProperty(i)) continue;
ast.push(recursiveAstBuilder(item[i]));
}
// And return
return ast;
}
// Case 2: The item is Object
if (type === 'object') {
// Create a new sub-AST of type Object ($)
var ast = ['$'];
// Add each items
for (var key in item) {
if (!item.hasOwnProperty(key))
continue;
ast.push(recursiveAstBuilder(key));
ast.push(recursiveAstBuilder(item[key]));
}
// And return
return ast;
}
// Case 3: The item empty string
if (item === '') {
return {
type : 'empty',
index : TOKEN_EMPTY_STRING
};
}
// Case 4: The item is String
if (type === 'string') {
// The index of that word in the dictionary
var index = _indexOf.call(dictionary.strings, item);
// If not, add to the dictionary and actualize the index
if (index == -1) {
dictionary.strings.push(_encode(item));
index = dictionary.strings.length - 1;
}
// Return the token
return {
type : 'strings',
index : index
};
}
// Case 5: The item is integer
if (type === 'number' && item % 1 === 0) {
// The index of that number in the dictionary
var index = _indexOf.call(dictionary.integers, item);
// If not, add to the dictionary and actualize the index
if (index == -1) {
dictionary.integers.push(_base10To36(item));
index = dictionary.integers.length - 1;
}
// Return the token
return {
type : 'integers',
index : index
};
}
// Case 6: The item is float
if (type === 'number') {
// The index of that number in the dictionary
var index = _indexOf.call(dictionary.floats, item);
// If not, add to the dictionary and actualize the index
if (index == -1) {
// Float not use base 36
dictionary.floats.push(item);
index = dictionary.floats.length - 1;
}
// Return the token
return {
type : 'floats',
index : index
};
}
// Case 7: The item is boolean
if (type === 'boolean') {
return {
type : 'boolean',
index : item ? TOKEN_TRUE : TOKEN_FALSE
};
}
// Default
throw new Error('Unexpected argument of type ' + typeof (item));
})(json);
// A set of shorthands proxies for the length of the dictionaries
var stringLength = dictionary.strings.length;
var integerLength = dictionary.integers.length;
var floatLength = dictionary.floats.length;
verbose && console.log('Parsing the dictionary');
// Create a raw dictionary
var packed = dictionary.strings.join('|');
packed += '^' + dictionary.integers.join('|');
packed += '^' + dictionary.floats.join('|');
verbose && console.log('Parsing the structure');
// And add the structure
packed += '^' + (function recursiveParser(item) {
verbose && console.log('Calling a recursiveParser with ' + this.JSON.stringify(item));
// If the item is Array, then is a object of
// type [object Object] or [object Array]
if ( item instanceof Array) {
// The packed resulting
var packed = item.shift();
for (var i in item) {
if (!item.hasOwnProperty(i))
continue;
packed += recursiveParser(item[i]) + '|';
}
return (packed[packed.length - 1] === '|' ? packed.slice(0, -1) : packed) + ']';
}
// A shorthand proxies
var type = item.type, index = item.index;
if (type === 'strings') {
// Just return the base 36 of index
return _base10To36(index);
}
if (type === 'integers') {
// Return a base 36 of index plus stringLength offset
return _base10To36(stringLength + index);
}
if (type === 'floats') {
// Return a base 36 of index plus stringLength and integerLength offset
return _base10To36(stringLength + integerLength + index);
}
if (type === 'boolean') {
return item.index;
}
if (type === 'null') {
return TOKEN_NULL;
}
if (type === 'undefined') {
return TOKEN_UNDEFINED;
}
if (type === 'empty') {
return TOKEN_EMPTY_STRING;
}
throw new TypeError('The item is alien!');
})(ast);
verbose && console.log('Ending parser');
// If debug, return a internal representation of dictionary and stuff
if (options.debug)
return {
dictionary : dictionary,
ast : ast,
packed : packed
};
return packed;
};
export function unpack(packed, options) {
// Canonizes the options
options = options || {};
// A raw buffer
var rawBuffers = packed.split('^');
// Create a dictionary
options.verbose && console.log('Building dictionary');
var dictionary = [];
// Add the strings values
var buffer = rawBuffers[0];
if (buffer !== '') {
buffer = buffer.split('|');
options.verbose && console.log('Parse the strings dictionary');
for (var i=0, n=buffer.length; i<n; i++){
dictionary.push(_decode(buffer[i]));
}
}
// Add the integers values
buffer = rawBuffers[1];
if (buffer !== '') {
buffer = buffer.split('|');
options.verbose && console.log('Parse the integers dictionary');
for (var i=0, n=buffer.length; i<n; i++){
dictionary.push(_base36To10(buffer[i]));
}
}
// Add the floats values
buffer = rawBuffers[2];
if (buffer !== '') {
buffer = buffer.split('|')
options.verbose && console.log('Parse the floats dictionary');
for (var i=0, n=buffer.length; i<n; i++){
dictionary.push(parseFloat(buffer[i]));
}
}
// Free memory
buffer = null;
options.verbose && console.log('Tokenizing the structure');
// Tokenizer the structure
var number36 = '';
var tokens = [];
var len=rawBuffers[3].length;
for (var i = 0; i < len; i++) {
var symbol = rawBuffers[3].charAt(i);
if (symbol === '|' || symbol === '$' || symbol === '@' || symbol === ']') {
if (number36) {
tokens.push(_base36To10(number36));
number36 = '';
}
symbol !== '|' && tokens.push(symbol);
} else {
number36 += symbol;
}
}
// A shorthand proxy for tokens.length
var tokensLength = tokens.length;
// The index of the next token to read
var tokensIndex = 0;
options.verbose && console.log('Starting recursive parser');
return (function recursiveUnpackerParser() {
// Maybe '$' (object) or '@' (array)
var type = tokens[tokensIndex++];
options.verbose && console.log('Reading collection type ' + (type === '$' ? 'object' : 'Array'));
// Parse an array
if (type === '@') {
var node = [];
for (; tokensIndex < tokensLength; tokensIndex++) {
var value = tokens[tokensIndex];
options.verbose && console.log('Read ' + value + ' symbol');
if (value === ']')
return node;
if (value === '@' || value === '$') {
node.push(recursiveUnpackerParser());
} else {
switch(value) {
case TOKEN_TRUE:
node.push(true);
break;
case TOKEN_FALSE:
node.push(false);
break;
case TOKEN_NULL:
node.push(null);
break;
case TOKEN_UNDEFINED:
node.push(undefined);
break;
case TOKEN_EMPTY_STRING:
node.push('');
break;
default:
node.push(dictionary[value]);
}
}
}
options.verbose && console.log('Parsed ' + this.JSON.stringify(node));
return node;
}
// Parse a object
if (type === '$') {
var node = {};
for (; tokensIndex < tokensLength; tokensIndex++) {
var key = tokens[tokensIndex];
if (key === ']')
return node;
if (key === TOKEN_EMPTY_STRING)
key = '';
else
key = dictionary[key];
var value = tokens[++tokensIndex];
if (value === '@' || value === '$') {
node[key] = recursiveUnpackerParser();
} else {
switch(value) {
case TOKEN_TRUE:
node[key] = true;
break;
case TOKEN_FALSE:
node[key] = false;
break;
case TOKEN_NULL:
node[key] = null;
break;
case TOKEN_UNDEFINED:
node[key] = undefined;
break;
case TOKEN_EMPTY_STRING:
node[key] = '';
break;
default:
node[key] = dictionary[value];
}
}
}
options.verbose && console.log('Parsed ' + this.JSON.stringify(node));
return node;
}
throw new TypeError('Bad token ' + type + ' isn\'t a type');
})();
}
/**
* Get the index value of the dictionary
* @param {Object} dictionary a object that have two array attributes: 'string' and 'number'
* @param {Object} data
*/
var _indexOfDictionary = function(dictionary, value) {
// The type of the value
var type = typeof value;
// If is boolean, return a boolean token
if (type === 'boolean')
return value ? TOKEN_TRUE : TOKEN_FALSE;
// If is null, return a... yes! the null token
if (value === null)
return TOKEN_NULL;
//add undefined
if (typeof value === 'undefined')
return TOKEN_UNDEFINED;
if (value === '') {
return TOKEN_EMPTY_STRING;
}
if (type === 'string') {
value = _encode(value);
var index = _indexOf.call(dictionary.strings, value);
if (index === -1) {
dictionary.strings.push(value);
index = dictionary.strings.length - 1;
}
}
// If has an invalid JSON type (example a function)
if (type !== 'string' && type !== 'number') {
throw new Error('The type is not a JSON type');
};
if (type === 'string') {// string
value = _encode(value);
} else if (value % 1 === 0) {// integer
value = _base10To36(value);
} else {// float
}
// If is number, "serialize" the value
value = type === 'number' ? _base10To36(value) : _encode(value);
// Retrieve the index of that value in the dictionary
var index = _indexOf.call(dictionary[type], value);
// If that value is not in the dictionary
if (index === -1) {
// Push the value
dictionary[type].push(value);
// And return their index
index = dictionary[type].length - 1;
}
// If the type is a number, then add the '+' prefix character
// to differentiate that they is a number index. If not, then
// just return a 36-based representation of the index
return type === 'number' ? '+' + index : index;
};
var _encode = function(str) {
if ( typeof str !== 'string')
return str;
return str.replace(/[\+ \|\^\%]/g, function(a) {
return ({
' ' : '+',
'+' : '%2B',
'|' : '%7C',
'^' : '%5E',
'%' : '%25'
})[a]
});
};
var _decode = function(str) {
if ( typeof str !== 'string')
return str;
return str.replace(/\+|%2B|%7C|%5E|%25/g, function(a) {
return ({
'+' : ' ',
'%2B' : '+',
'%7C' : '|',
'%5E' : '^',
'%25' : '%'
})[a]
})
};
var _base10To36 = function(number) {
return Number.prototype.toString.call(number, 36).toUpperCase();
};
var _base36To10 = function(number) {
return parseInt(number, 36);
};
var _indexOf = Array.prototype.indexOf ||
function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++) {
if (this[i] === obj) {
return i;
}
}
return -1;
};
+24
View File
@@ -0,0 +1,24 @@
import * as utils from "/src/utils.js"
import * as packets from "/src/packets.js"
import * as auth from "/src/auth.js"
import * as jsonpack from "/src/jsonpack.js"
const hostname = window.location.href.split('/')[2]
//import * as crypto from "/src/crypto-js.min.js"
let rawClient = new packets.rawClient('/listen')
let client = new auth.authClient(rawClient)
window.utils = utils
window.packets = packets
window.auth = auth
window.jsonpack = jsonpack
window.rawClient = rawClient
window.authClient = client
window.authLogin = client.login
window.sendAuth = client.send
window.sendRaw = rawClient.send
window.addRawTypeListener = rawClient.addRawTypeListener
+102
View File
@@ -0,0 +1,102 @@
import * as jsonpack from '/src/jsonpack.js'
import * as utils from "/src/utils.js"
let cID = null
let evListeners = []
let c = null
function getErrorDesc(error){
switch(error){
case 'invalidLogin':
return 'Invalid username or password'
case 'invalidLoginRequest':
return 'Some part of the login request is invalid, please try again'
case 'prelogin':
return 'You are already logged in'
}
return error
}
function processData(data){
data = jsonpack.unpack(data)
switch(data.type){
case 'clidata':
c.cID = data.data.cid
if(window.location.pathname == "/login") {
utils.popupWarning('Connection', 'Connected to server!')
utils.iconunauth()
}else{
utils.popupInfo('Connection', 'Connected to server!')
utils.iconauth()
}
break
case 'data':
console.log(data.data)
break
case 'error':
utils.popupError(`Error: ${data.data}`, getErrorDesc(data.data))
}
for(let i=0;i<evListeners.length;i++){
const ev = evListeners[i]
if(ev.type == data.type){
ev.func(data)
}
}
}
export function rawClient(loc) {
c = this
this.connected = false
this.location = loc
this.evtSource = new EventSource(loc);
this.onopen = ()=>{}
this.onclose = ()=>{}
this.cID = null
this.evtSource.onmessage = (event) => {
console.log(`Data: ${event.data}`)
processData(event.data)
}
this.evtSource.onerror = (event) => {
console.log('Error!')
this.connected = false
utils.icondisconnect()
utils.popupError('Connection', 'Disconnected from server')
this.onclose()
}
this.evtSource.onopen = (event) => {
console.log('Connected!')
this.connected = true
utils.iconunauth()
this.onopen()
}
this.send = (type, data)=>{
//console.log({type, data})
fetch(this.location, {
method: "post",
headers: {
'Accept': '*',
'Content-Type': 'text/plain'
},
body: jsonpack.pack({
type: type,
data: data,
cid: this.cID
})
})
}
this.addRawTypeListener = (type, func)=>{
evListeners.push({
type: type,
func: func
})
}
}
+5
View File
File diff suppressed because one or more lines are too long
+270
View File
@@ -0,0 +1,270 @@
@font-face {
font-family: "UbuntuMono";
src: url(/src/UbuntuMono-R.ttf) format("truetype");
}
:root {
--topnavheight: 45px;
--sidenavwidth: 150px;
--popupBoxWidth: 300px;
--background-0: #212529;
--background-1: #404040;
--text-0: #242424;
--text-1: #d3d3d3;
--text-black: #242424;
--text-white: #d3d3d3;
--success-1:#059100;
--warning-1:#ffdc3e;
--error-1: #b60f0f;
--font: "UbuntuMono";
}
* {
font-family: var(--font);
}
body {
position:fixed;
right: 0;
height: 0;
overflow: scroll;
width: calc( 100vw - var(--sidenavwidth) + 32px );
height: calc( 100vh - var(--topnavheight) + 32px );
}
.maindiv {
position: fixed;
top: var(--topnavheight);
left: var(--sidenavwidth);
width: calc(100% - var(--sidenavwidth));
height: calc(100% - var(--topnavheight));
padding: 5px;
}
.text-white {
color: var(--text-white) !important;
font-family: var(--font);
}
.text-black {
color: var(--text-black) !important;
font-family: var(--font);
}
.navbar {
position: fixed;
top:0;
left:0;
right:0;
height:var(--topnavheight);
padding:5px;
padding-left: calc(var(--sidenavwidth) + 10px);
z-index: 10;
background-color: var(--background-0);
}
.navbar ul {
position: fixed;
top: calc(var(--topnavheight) * 0.1);
padding: 0px;
/* height: var(--topnavheight); */
height: calc(var(--topnavheight) * 0.8);
padding-right: calc(var(--topnavheight) * 2.8);
left: var(--sidenavwidth);
width: calc(100% - var(--sidenavwidth));
overflow-x: scroll;
overflow-y: hidden;
}
.navpanel {
display: flex;
flex-direction: column;
flex-shrink: 0;
font-size: 16px;
font-weight: 400;
line-height: 24px;
overflow: hidden;
padding-left: 14px;
position:fixed;
top: var(--topnavheight);
bottom:0;
left:0;
width: var(--sidenavwidth);
height:100%;
resize: left;
z-index: 20;
background-color: var(--background-0);
}
.navpanel details {
padding-bottom: 0px;
padding-left: 5px;
margin-bottom: 0px;
}
.navpanel summary {
font-size: 15px;
padding-top: 10px;
padding-bottom: 10px;
margin-bottom: 0px !important;
}
.navpanel summary:hover {
color: var(--primary);
background-color: rgba(0,0,0,0.1);
}
.navpanel ul {
margin-top: 10px;
margin-bottom: 10px;
padding-left: 5px;
}
.navpanel li {
font-size: 14px;
margin-left: -5px;
margin-bottom: 0;
cursor: pointer;
}
.navpanel li:hover {
color: var(--primary);
background-color: rgba(0,0,0,0.1);
}
li::marker {
content: "- ";
padding-left: -20px;
padding-right: 5px;
}
.navconntext {
position: fixed;
font-size: calc(var(--topnavheight) * 0.3);
margin: calc((var(--topnavheight) * 0.25 * 0.75) - 5px);
background-color: rgba(255, 0, 0, 0.2);
border-style: solid;
border-width: 1px !important;
border-color: #ff0000;
padding: 8px;
right:0;
top:0;
}
.sidenav-button {
width:100%;
margin-bottom: 10px;
}
.topnav-button {
margin-left: 13px !important;
height: 100% !important;
font-size: calc( var(--topnavheight) * ( 3 / 9 ) );
line-height: calc( var(--topnavheight) * ( 3 / 9 ) );
}
.navTitle {
position: fixed;
margin-bottom: 1px;
top: 0;
left: 0;
width: var(--sidenavwidth);
height: var(--topnavheight);
text-align:center;
line-height: var(--topnavheight);
text-decoration:none;
}
.navTitle:hover {
background-color: rgba(0,0,0,0.1);
}
.popupBox {
position: fixed;
/* display: flex;
box-sizing: content-box;
justify-content: flex-end;
flex-direction: column; */
width: var(--popupBoxWidth);
height: calc(100% - var(--topnavheight) - 10px);
bottom: 0;
right: 20px;
overflow: auto;
}
.popupBox dialog {
display: flex;
z-index: inherit;
position: relative;
top: inherit;
right: inherit;
bottom: inherit;
left: inherit;
align-items: inherit;
justify-content: inherit;
width: inherit;
min-width: inherit;
height: auto;
min-height: inherit;
padding: 0;
background-color: inherit;
left: 0;
margin: 0;
margin-bottom: 20px;
justify-content:right;
flex-direction: column;
}
.popupBox article {
margin: 0;
opacity: 0.5;
padding-bottom: 10px;
}
.popupBox header {
border: 0;
padding-left: 15px;
padding-right: 15px;
padding-top: 10px;
padding-bottom: 10px;
margin-bottom: 10px;
}
.popupBox article:hover {
opacity: 1;
}
.popupBox article a {
cursor: pointer;
}
.popupBox article p {
font-size: 15px;
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
}
+242
View File
@@ -0,0 +1,242 @@
export const setCookie = (name, value, hours = 1, path = '/') => {
const expires = new Date(Date.now() + hours * 6e4).toUTCString()
document.cookie = `${name}=${encodeURIComponent(value)}; path=${path}; SameSite=None; secure=True; session=True`
}
export const getCookie = (name) => {
return document.cookie.split('; ').reduce((r, v) => {
const parts = v.split('=')
return parts[0] === name ? decodeURIComponent(parts[1]) : r
}, '')
}
export function genID(length = 8){
// Declare all characters
let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
// Pick characers randomly
let str = '';
for (let i = 0; i < length; i++) {
str += chars.charAt(Math.floor(Math.random() * chars.length));
}
return str;
}
export function icondisconnect() {
let icon = document.getElementById('connecticon')
icon.style.backgroundColor = "rgba(255, 0, 0, 0.2)"
icon.style.borderColor = "#ff0000"
icon.innerText = "Disconnected"
}
export function iconunauth() {
let icon = document.getElementById('connecticon')
icon.style.backgroundColor = "rgba(255, 255, 0, 0.2)"
icon.style.borderColor = "#ffff00"
icon.innerText = "Unauthenticated"
}
export function iconauth() {
let icon = document.getElementById('connecticon')
icon.style.backgroundColor = "rgba(0, 255, 0, 0.2)"
icon.style.borderColor = "#00ff00"
icon.innerText = "Authenticated"
}
// function addPopup(bgcolor, fgcolor, innerHTML) {
// const elem = document.getElementById('popupBox')
// const id = 'popup-'+genID(16)
// elem.innerHTML = `<div class="popup"
// class="popup"
// style="background-color: ${bgcolor};
// color: ${fgcolor}"
// id='${id}'
// onclick="elem=document.getElementById('${id}');elem.parentNode.removeChild(elem)">
// ${innerHTML}
// </div>` +
// elem.innerHTML
// setTimeout(()=>{
// elem.parentNode.removeChild(elem)
// }, 30000)
// }
function addPopup(bgcolor, isDark, title, content) {
const elem = document.getElementById('popupBox')
let header
let textColor
if(isDark){
header = 'rgba(255,255,255,0.05)'
textColor = 'text-white'
}else{
header = 'rgba(0,0,0,0.2)'
textColor = 'text-black'
}
elem.innerHTML += `
<dialog class="example ${textColor}" open>
<article style="background-color:${bgcolor};">
<header style="background-color:${header};">
<p class='noselect' style='font-size:10px;opacity:0.75'>${formatTime(getUnixTime())}</p>
<a class="close ${textColor}" onclick="elem=document.getElementById('popupBox');elem.removeChild(this.parentElement.parentElement.parentElement)"></a>
${title}
</header>
<p class='${textColor}'>${content}</p>
</article>
</dialog>
`
}
export function popupInfo(title, text){
addPopup('var(--card-sectionning-background-color)', true, title, text)
}
export function popupSuccess(title, text){
addPopup('#005000', true, title, text)
}
export function popupWarning(title, text){
addPopup('#393900', true, title, text)
}
export function popupError(title, text){
addPopup('#500000', true, title, text)
}
export function getUnixTime() {
return (+ new Date())
}
function formatTime(Millis){
const date = new Date(Millis)
if(date.getDate() != (new Date()).getDate()){
return date.getMonth()+1 + "/" + date.getDate() + "/" + date.getFullYear()
}else{
var Hour = ""
var Minute = ""
var AmPm = ""
if(date.getHours() == 0){
Hour = "12"
AmPm = "AM"
}else if(date.getHours() < 12){
Hour = date.getHours()
AmPm = "AM"
}else if(date.getHours() == 12){
Hour = "12"
AmPm = "PM"
}else{
Hour = date.getHours() - 12
AmPm = "PM"
}
if(date.getMinutes() < 10){
Minute = "0" + date.getMinutes()
}else{
Minute = date.getMinutes()
}
return Hour + ":" + Minute + " " + AmPm
}
}
export function sha256(ascii) {
function rightRotate(value, amount) {
return (value>>>amount) | (value<<(32 - amount));
};
var mathPow = Math.pow;
var maxWord = mathPow(2, 32);
var lengthProperty = 'length'
var i, j; // Used as a counter across the whole file
var result = ''
var words = [];
var asciiBitLength = ascii[lengthProperty]*8;
//* caching results is optional - remove/add slash from front of this line to toggle
// Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes
// (we actually calculate the first 64, but extra values are just ignored)
var hash = sha256.h = sha256.h || [];
// Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes
var k = sha256.k = sha256.k || [];
var primeCounter = k[lengthProperty];
/*/
var hash = [], k = [];
var primeCounter = 0;
//*/
var isComposite = {};
for (var candidate = 2; primeCounter < 64; candidate++) {
if (!isComposite[candidate]) {
for (i = 0; i < 313; i += candidate) {
isComposite[i] = candidate;
}
hash[primeCounter] = (mathPow(candidate, .5)*maxWord)|0;
k[primeCounter++] = (mathPow(candidate, 1/3)*maxWord)|0;
}
}
ascii += '\x80' // Append Ƈ' bit (plus zero padding)
while (ascii[lengthProperty]%64 - 56) ascii += '\x00' // More zero padding
for (i = 0; i < ascii[lengthProperty]; i++) {
j = ascii.charCodeAt(i);
if (j>>8) return; // ASCII check: only accept characters in range 0-255
words[i>>2] |= j << ((3 - i)%4)*8;
}
words[words[lengthProperty]] = ((asciiBitLength/maxWord)|0);
words[words[lengthProperty]] = (asciiBitLength)
// process each chunk
for (j = 0; j < words[lengthProperty];) {
var w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration
var oldHash = hash;
// This is now the undefinedworking hash", often labelled as variables a...g
// (we have to truncate as well, otherwise extra entries at the end accumulate
hash = hash.slice(0, 8);
for (i = 0; i < 64; i++) {
var i2 = i + j;
// Expand the message into 64 words
// Used below if
var w15 = w[i - 15], w2 = w[i - 2];
// Iterate
var a = hash[0], e = hash[4];
var temp1 = hash[7]
+ (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
+ ((e&hash[5])^((~e)&hash[6])) // ch
+ k[i]
// Expand the message schedule if needed
+ (w[i] = (i < 16) ? w[i] : (
w[i - 16]
+ (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15>>>3)) // s0
+ w[i - 7]
+ (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2>>>10)) // s1
)|0
);
// This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble
var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
+ ((a&hash[1])^(a&hash[2])^(hash[1]&hash[2])); // maj
hash = [(temp1 + temp2)|0].concat(hash); // We don't bother trimming off the extra ones, they're harmless as long as we're truncating when we do the slice()
hash[4] = (hash[4] + temp1)|0;
}
for (i = 0; i < 8; i++) {
hash[i] = (hash[i] + oldHash[i])|0;
}
}
for (i = 0; i < 8; i++) {
for (j = 3; j + 1; j--) {
var b = (hash[i]>>(j*8))&255;
result += ((b < 16) ? 0 : '') + b.toString(16);
}
}
return result.toUpperCase();
};