- Move setAttributesAccordingToPosition to HippieTaskbar - Use TimeDisplay inside HippieTaskbar - Add readJsonFile and loadJson to app - Initialize taskbar with config from data/windows.json - Update jshint globals
756 lines
17 KiB
JavaScript
756 lines
17 KiB
JavaScript
/* jshint strict: false */
|
|
|
|
// TODO: Inhalte angleichen nach Zusammenfassung von app.js und function.js.
|
|
// Benennung und Beschreibungen verbessern.
|
|
|
|
// This is called everytime
|
|
function setup() {
|
|
'use strict';
|
|
|
|
console.group('Document information');
|
|
console.info('\n', HIPPIE.brand, '\n\n');
|
|
console.info('HTML:', hippie.screen, '\nBODY:', hippie.body);
|
|
console.groupEnd();
|
|
if (debugOn) {
|
|
console.group('Debug information');
|
|
console.dir(hippie);
|
|
console.groupEnd();
|
|
}
|
|
}
|
|
|
|
// MODULE Scroll navigation
|
|
// Using constructor function
|
|
function HippieScroll($tp, $dn) {
|
|
'use strict';
|
|
|
|
// this.$tp = $tp;
|
|
// Define initial situation
|
|
let initLeft = false;
|
|
const initY = hippie.screen.vh;
|
|
|
|
$tp.addClass('di_none');
|
|
|
|
// Check scroll position and toggle element
|
|
this.check = function () {
|
|
hippie.screen.y = Math.min($(document).scrollTop(), document.documentElement.scrollTop);
|
|
if (hippie.screen.y > initY) {
|
|
if (!initLeft) {
|
|
$tp.removeClass('di_none');
|
|
console.info('Initial viewport left');
|
|
}
|
|
initLeft = true;
|
|
} else {
|
|
if (initLeft) {
|
|
$tp.addClass('di_none');
|
|
console.info('Initial viewport entered');
|
|
}
|
|
initLeft = false;
|
|
}
|
|
};
|
|
|
|
// Add events to navigation elements
|
|
$tp.click(function (event) {
|
|
event.preventDefault();
|
|
$('html, body').stop().animate({
|
|
scrollTop: 0
|
|
}, basicEase);
|
|
// console.log('Scrolled to top');
|
|
});
|
|
$dn.click(function (event) {
|
|
event.preventDefault();
|
|
const pos = Math.max(hippie.screen.dh, hippie.body.h) - hippie.screen.vh;
|
|
$('html').scrollTop(pos);
|
|
// document.documentElement.scrollTop = pos;
|
|
console.info('Scrolled down to', pos);
|
|
});
|
|
}
|
|
|
|
function HippieFade(toggleElement, initState) {
|
|
'use strict';
|
|
|
|
const fragment = document.createDocumentFragment();
|
|
const overlay = document.createElement('div');
|
|
|
|
overlay.id = 'mouse_overlay';
|
|
|
|
if (initState) {
|
|
overlay.classList.add('active');
|
|
}
|
|
|
|
toggleElement.addEventListener('click', function () {
|
|
overlay.classList.toggle('active');
|
|
});
|
|
|
|
fragment.appendChild(overlay);
|
|
document.body.style.position = 'relative';
|
|
document.body.prepend(fragment);
|
|
}
|
|
|
|
// MODULE Meta elements
|
|
function HippieMeta($ma, $pp) {
|
|
'use strict';
|
|
|
|
let metaOn = false;
|
|
|
|
$ma.click(function () {
|
|
let $wrap, $pop;
|
|
|
|
// if (metaOn !== true) {
|
|
if (!metaOn) {
|
|
metaOn = true;
|
|
|
|
$pp.each(function () {
|
|
// if ($(this).css('position') === 'static') {
|
|
// $(this).addClass('js_changed_pos');
|
|
// $(this).css('position', 'relative');
|
|
// }
|
|
// $pop = $(this).next('.exp_pop').detach();
|
|
// $wrap = $(this).wrap('<span class="exp_wrap"></span>').parent().prepend('<span class="exp_overlay"></span>').prepend('<span class="exp_marker_pop"></span>');
|
|
// $wrap.after($pop);
|
|
|
|
$('<div></div>').addClass('exp_overlay').css({
|
|
position: 'absolute',
|
|
width: '100%',
|
|
height: '100%',
|
|
top: 0,
|
|
left: 0
|
|
}).appendTo($(this).addClass('exp_wrap'));
|
|
|
|
// Displays explanation popup following the mouse
|
|
$(this).on({
|
|
mouseenter: function () {
|
|
// if ($(this).attr('emmet')) {
|
|
//
|
|
// }
|
|
$(this).next('.exp_pop').show();
|
|
},
|
|
mouseleave: function () {
|
|
$(this).next('.exp_pop').hide();
|
|
},
|
|
mousemove: function (event) {
|
|
$(this).next('.exp_pop').css({
|
|
'top': event.pageY - $(this).next('.exp_pop').outerHeight() - 4,
|
|
'left': event.pageX + 8
|
|
// 'left': event.pageX - $(this).offset().left + 8
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
} else {
|
|
$pp.each(function () {
|
|
$(this).off('mouseenter mouseleave mousemove');
|
|
|
|
$(this).removeClass('exp_wrap').find('.exp_overlay').remove();
|
|
// $wrap = $(this).parent('.exp_wrap');
|
|
// $pop = $wrap.next('.exp_pop').detach();
|
|
// $wrap.find('.exp_marker_pop').remove();
|
|
// $(this).unwrap('.exp_wrap');
|
|
// $(this).after($pop);
|
|
// if ($(this).hasClass('js_changed_pos')) {
|
|
// $(this).css('position', '');
|
|
// if ($(this).attr('style') === '') {
|
|
// $(this).removeAttr('style');
|
|
// }
|
|
// $(this).removeClass('js_changed_pos');
|
|
// }
|
|
});
|
|
|
|
metaOn = false;
|
|
}
|
|
console.log('Explanation mode', metaOn);
|
|
});
|
|
}
|
|
|
|
// Sets the href attribute to mailto: with given information
|
|
function composeMail(tag, name, prov, suffix, text, topic) {
|
|
'use strict';
|
|
|
|
let trigger = tag.indexOf('.');
|
|
let mailString = name + '@' + prov + '.' + suffix;
|
|
let textString = mailString.replace(/@/g, '(at)');
|
|
let descString = 'Nachricht an ' + mailString;
|
|
|
|
if (!text) {
|
|
text = mailString;
|
|
} else if (text === 'at') {
|
|
text = textString;
|
|
} else if (text === 'to') {
|
|
text = descString;
|
|
}
|
|
|
|
if (topic) {
|
|
topic = '?subject=' + topic;
|
|
} else {
|
|
topic = '';
|
|
}
|
|
|
|
if (trigger === -1) {
|
|
const el = document.getElementById(tag);
|
|
const elContent = el.innerHTML;
|
|
|
|
el.innerHTML = elContent + text;
|
|
el.setAttribute('href', 'mailto:' + mailString + topic);
|
|
} else {
|
|
const elements = document.getElementsByClassName(tag.slice(1));
|
|
|
|
for (const element of elements) {
|
|
const content = element.innerHTML;
|
|
|
|
element.innerHTML = content + text;
|
|
element.setAttribute('href', 'mailto:' + mailString + topic);
|
|
}
|
|
}
|
|
}
|
|
|
|
// get document coordinates of the element
|
|
// function getCoords (elem) {
|
|
// let box = elem.getBoundingClientRect();
|
|
//
|
|
// return {
|
|
// top: box.top + pageYOffset,
|
|
// left: box.left + pageXOffset
|
|
// };
|
|
// }
|
|
|
|
// https://stackoverflow.com/a/488073/1444149
|
|
// function Utils () {}
|
|
//
|
|
// Utils.prototype = {
|
|
// constructor: Utils,
|
|
// isElementInView: function (element, fullyInView) {
|
|
// var pageTop = $(window).scrollTop();
|
|
// var pageBottom = pageTop + $(window).height();
|
|
// var elementTop = $(element).offset().top;
|
|
// var elementBottom = elementTop + $(element).height();
|
|
//
|
|
// if (fullyInView === true) {
|
|
// return ((pageTop < elementTop) && (pageBottom > elementBottom));
|
|
// } else {
|
|
// return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
|
|
// }
|
|
// }
|
|
// };
|
|
//
|
|
// var Utils = new Utils();
|
|
|
|
class TimeDisplay {
|
|
constructor(element, options, interval) {
|
|
this.element = element;
|
|
this.options = options || {hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false};
|
|
this.interval = interval || 1000;
|
|
this.isPaused = false;
|
|
this.locale = navigator.language || 'en-US';
|
|
|
|
this.updateTime();
|
|
|
|
console.group('Time information');
|
|
console.info('\nOptions:', this.options, '\n\n');
|
|
console.info('Interval:', this.interval);
|
|
console.groupEnd();
|
|
}
|
|
|
|
formatTime(time) {
|
|
return time.toLocaleTimeString(this.locale, this.options);
|
|
}
|
|
|
|
// TODO: Zeit nur im Sekundentakt aktualisieren wenn Sekunden angezeigt werden
|
|
async updateTime() {
|
|
while (true) {
|
|
if (!this.isPaused) {
|
|
const now = new Date();
|
|
this.element.textContent = this.formatTime(now);
|
|
}
|
|
await new Promise(resolve => setTimeout(resolve, this.interval));
|
|
}
|
|
}
|
|
|
|
pause() {
|
|
this.isPaused = true;
|
|
}
|
|
|
|
resume() {
|
|
this.isPaused = false;
|
|
}
|
|
}
|
|
|
|
class DateDisplay {
|
|
constructor(element, options, direction) {
|
|
this.element = element;
|
|
this.options = options || {year: 'numeric', month: 'long', day: 'numeric'};
|
|
this.direction = direction || 0;
|
|
|
|
this.updateDate();
|
|
this.checkForDateChange();
|
|
|
|
console.group('Date information');
|
|
console.info('\nOptions:', this.options, '\n\n');
|
|
console.info('Remaining minutes:', Math.floor(this.getTimeUntilNextMidnight() / 3600));
|
|
console.groupEnd();
|
|
}
|
|
|
|
formatDate(date) {
|
|
const formatter = new Intl.DateTimeFormat(navigator.language, this.options);
|
|
|
|
switch (this.direction) {
|
|
case 1:
|
|
const dateString = formatter
|
|
.formatToParts(date)
|
|
.map(({type, value}) => {
|
|
// if (type === 'day' || type === 'month') {
|
|
if (type === 'literal') {
|
|
return `${value}<br>`;
|
|
} else {
|
|
return value;
|
|
}
|
|
})
|
|
.join('');
|
|
|
|
return dateString;
|
|
case 0:
|
|
default:
|
|
return formatter.format(date);
|
|
}
|
|
}
|
|
|
|
updateDate() {
|
|
const now = new Date();
|
|
|
|
this.element.innerHTML = this.formatDate(now);
|
|
}
|
|
|
|
changeFormat(format, direction) {
|
|
this.options = format;
|
|
this.direction = direction;
|
|
|
|
this.updateDate();
|
|
}
|
|
|
|
getTimeUntilNextMidnight() {
|
|
const now = new Date();
|
|
const nextMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
|
|
|
|
return nextMidnight - now;
|
|
}
|
|
|
|
checkForDateChange() {
|
|
const timeUntilNextMidnight = this.getTimeUntilNextMidnight();
|
|
|
|
setTimeout(() => {
|
|
this.updateDate();
|
|
this.checkForDateChange();
|
|
}, timeUntilNextMidnight);
|
|
}
|
|
}
|
|
|
|
// TODO: Kompatibilität für Zeiger
|
|
function checkButtonAndTarget(event, element, button = 0) {
|
|
return (
|
|
event.button === button &&
|
|
event.target === element
|
|
);
|
|
}
|
|
|
|
function getClosestEdgeToElement(element) {
|
|
'use strict';
|
|
|
|
const bounding = element.getBoundingClientRect();
|
|
const distances = {
|
|
top: bounding.top,
|
|
right: window.innerWidth - bounding.right,
|
|
bottom: window.innerHeight - bounding.bottom,
|
|
left: bounding.left
|
|
};
|
|
|
|
return Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b);
|
|
}
|
|
|
|
function getClosestEdgeToMouse(event) {
|
|
'use strict';
|
|
|
|
const mouseX = event.clientX;
|
|
const mouseY = event.clientY;
|
|
const distances = {
|
|
left: mouseX,
|
|
right: window.innerWidth - mouseX,
|
|
top: mouseY,
|
|
bottom: window.innerHeight - mouseY
|
|
};
|
|
|
|
return Object.keys(distances).reduce((a, b) =>
|
|
distances[a] < distances[b] ? a : b
|
|
);
|
|
}
|
|
|
|
function centerElementUnderCursor(event, element) {
|
|
'use strict';
|
|
|
|
const offsetX = element.getBoundingClientRect().width / 2;
|
|
const offsetY = element.getBoundingClientRect().height / 2;
|
|
const x = event.clientX - offsetX;
|
|
const y = event.clientY - offsetY;
|
|
|
|
element.style.left = `${x}px`;
|
|
element.style.top = `${y}px`;
|
|
}
|
|
|
|
/**
|
|
* Gibt eine Zahl zwischen <min> und <max> aus.
|
|
* Die Werte <min> und <max> sind dabei mit eingeschlossen.
|
|
* Mit <pos> kann der Exponent für eine 10er-Teilung angegeben werden.
|
|
*
|
|
* @param {number} min
|
|
* @param {number} max
|
|
* @param {number} pos
|
|
* @returns {number}
|
|
*/
|
|
function randomIntFrom(min, max, pos = 0) {
|
|
pos = Math.pow(10, pos);
|
|
min = Math.ceil(min);
|
|
max = Math.floor(max);
|
|
|
|
return Math.floor((Math.random() * (max - min + 1) + min) / pos) * pos;
|
|
}
|
|
|
|
function randomFloatFrom(min, max, dec = 1) {
|
|
dec = Math.pow(10, dec);
|
|
|
|
return Math.round((Math.random() * (max - min) + min) * dec) / dec;
|
|
}
|
|
|
|
/**
|
|
* Ersetzt \n durch <br>.
|
|
*
|
|
* @param {string} text
|
|
* @returns {string}
|
|
*/
|
|
function replaceLineBreaks(text) {
|
|
if (text === '' || !text.includes('\n')) {
|
|
return text;
|
|
}
|
|
|
|
return text.split('\n').join('<br>');
|
|
}
|
|
|
|
/**
|
|
* Gibt eine zufällige Farbe als HEX-Wert aus.
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
function getRandomColor() {
|
|
const letters = '0123456789ABCDEF';
|
|
let color = '#';
|
|
|
|
for (let i = 0; i < 6; i++) {
|
|
color += letters[Math.floor(Math.random() * 16)];
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
function getRandomFormattedString(chars = 2, digits = 6, separator = '-') {
|
|
const getRandomUppercase = () => String.fromCharCode(Math.floor(Math.random() * 26) + 65);
|
|
const getRandomDigit = () => Math.floor(Math.random() * 10);
|
|
let string = '';
|
|
|
|
for (let i = 0; i < chars; i++) {
|
|
string += getRandomUppercase();
|
|
}
|
|
|
|
string += separator;
|
|
|
|
for (let i = 0; i < digits; i++) {
|
|
string += getRandomDigit();
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
function toggleColumn(table, index) {
|
|
const rows = table.rows;
|
|
const isHidden = rows[0].cells[index].classList.contains('di_none');
|
|
|
|
for (let i = 0; i < rows.length; i++) {
|
|
const cell = rows[i].cells[index];
|
|
|
|
if (isHidden) {
|
|
cell.classList.remove('di_none');
|
|
} else {
|
|
cell.classList.add('di_none');
|
|
}
|
|
}
|
|
}
|
|
|
|
function convertToRomanNumeral(num) {
|
|
const romanNumeralMap = [
|
|
{value: 1000, numeral: 'M'},
|
|
{value: 900, numeral: 'CM'},
|
|
{value: 500, numeral: 'D'},
|
|
{value: 400, numeral: 'CD'},
|
|
{value: 100, numeral: 'C'},
|
|
{value: 90, numeral: 'XC'},
|
|
{value: 50, numeral: 'L'},
|
|
{value: 40, numeral: 'XL'},
|
|
{value: 10, numeral: 'X'},
|
|
{value: 9, numeral: 'IX'},
|
|
{value: 5, numeral: 'V'},
|
|
{value: 4, numeral: 'IV'},
|
|
{value: 1, numeral: 'I'}
|
|
];
|
|
|
|
let result = '';
|
|
for (let i = 0; i < romanNumeralMap.length; i++) {
|
|
while (num >= romanNumeralMap[i].value) {
|
|
result += romanNumeralMap[i].numeral;
|
|
num -= romanNumeralMap[i].value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function capitalizeFirstLetter(text) {
|
|
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
}
|
|
|
|
function mapRange(value, inMin, inMax, outMin, outMax, reverse = false, clamp = false) {
|
|
let min = outMin;
|
|
let max = outMax;
|
|
|
|
if (reverse) {
|
|
[min, max] = [max, min];
|
|
}
|
|
|
|
const mapped = (value - inMin) * (max - min) / (inMax - inMin) + min;
|
|
|
|
if (clamp) {
|
|
return Math.max(Math.min(min, max), Math.min(Math.max(min, max), mapped));
|
|
}
|
|
return mapped;
|
|
}
|
|
|
|
function zeroFill(number, width) {
|
|
width -= number.toString().length;
|
|
|
|
if (width > 0) {
|
|
return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number;
|
|
}
|
|
return number + ''; // always return a string
|
|
}
|
|
|
|
// Source - https://stackoverflow.com/a/47480429
|
|
// Posted by Etienne Martin, modified by community. See post 'Timeline' for change history
|
|
// Retrieved 2026-03-08, License - CC BY-SA 4.0
|
|
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
|
|
async function readJsonFile(file) {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
|
|
reader.readAsText(file);
|
|
reader.onload = function () {
|
|
try {
|
|
resolve(JSON.parse(reader.result));
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
};
|
|
reader.onerror = function () {
|
|
reject(reader.error);
|
|
};
|
|
});
|
|
}
|
|
|
|
async function loadJson(filePath) {
|
|
try {
|
|
const response = await fetch(filePath);
|
|
|
|
if (!response.ok) throw new Error(`Failed to load file: ${response.status}`);
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Error loading file:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
class RandomPixelPlaceholder {
|
|
constructor(parent, options = {}) {
|
|
this.container = parent;
|
|
this.width = options.width || 400;
|
|
this.height = options.height || 300;
|
|
this.colors = options.colors || ['#000000', '#ffffff'];
|
|
this.filter = options.filter || '';
|
|
this.type = options.type || 'canvas'; // 'canvas' or 'img'
|
|
this.element = this.createElement();
|
|
|
|
this.addContextToElement();
|
|
}
|
|
|
|
createElement() {
|
|
if (this.type === 'img') {
|
|
const img = document.createElement('img');
|
|
img.style.filter = this.filter;
|
|
|
|
this.container.appendChild(img);
|
|
|
|
return img;
|
|
} else {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
canvas.style.filter = this.filter;
|
|
|
|
this.container.appendChild(canvas);
|
|
|
|
return canvas;
|
|
}
|
|
}
|
|
|
|
addContextToElement() {
|
|
if (this.type === 'img') {
|
|
// Create intermediate canvas
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
|
|
this.fillWithRandomPixels(canvas);
|
|
|
|
// Convert canvas to image data URL and set as img src
|
|
this.element.src = canvas.toDataURL();
|
|
this.element.width = this.width;
|
|
this.element.height = this.height;
|
|
} else {
|
|
this.fillWithRandomPixels(this.element);
|
|
}
|
|
}
|
|
|
|
fillWithRandomPixels(canvas) {
|
|
const ctx = canvas.getContext('2d');
|
|
const imageData = ctx.createImageData(this.width, this.height);
|
|
const data = imageData.data;
|
|
|
|
for (let i = 0; i < data.length; i += 4) {
|
|
const color = this.getRandomColor();
|
|
const rgb = this.hexToRgb(color);
|
|
|
|
data[i] = rgb.r; // Red
|
|
data[i + 1] = rgb.g; // Green
|
|
data[i + 2] = rgb.b; // Blue
|
|
data[i + 3] = 255; // Alpha
|
|
}
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
}
|
|
|
|
getRandomColor() {
|
|
return this.colors[Math.floor(Math.random() * this.colors.length)];
|
|
}
|
|
|
|
hexToRgb(hex) {
|
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
|
|
return result ? {
|
|
r: parseInt(result[1], 16),
|
|
g: parseInt(result[2], 16),
|
|
b: parseInt(result[3], 16)
|
|
} : {r: 0, g: 0, b: 0};
|
|
}
|
|
}
|
|
|
|
// CONCEPTS
|
|
|
|
// NOTE: Benutzt private Zuweisungen
|
|
class elementBinder {
|
|
#element;
|
|
|
|
constructor(element) {
|
|
this.#setElement(element);
|
|
}
|
|
|
|
#setElement(value) {
|
|
if (!value) {
|
|
throw new Error('No element found');
|
|
}
|
|
this.#element = value;
|
|
this.#element.style.background = "hotpink";
|
|
}
|
|
|
|
get element() {
|
|
return this.#element;
|
|
}
|
|
|
|
set element(value) {
|
|
this.#setElement(value);
|
|
}
|
|
}
|
|
|
|
//OLD
|
|
|
|
function Clock(id) {
|
|
'use strict';
|
|
|
|
this.id = id;
|
|
const that = this;
|
|
|
|
setInterval(function () {
|
|
that.updateClock();
|
|
}, 1000);
|
|
this.updateClock();
|
|
}
|
|
|
|
Clock.prototype.updateClock = function () {
|
|
'use strict';
|
|
|
|
const date = new Date();
|
|
const clock = document.getElementById(this.id);
|
|
//console.log(this);
|
|
clock.innerHTML = this.formatDigits(date.getHours()) + ':' + this.formatDigits(date.getMinutes()) + ":" + this.formatDigits(date.getSeconds());
|
|
};
|
|
|
|
Clock.prototype.formatDigits = function (val) {
|
|
'use strict';
|
|
|
|
if (val < 10) val = '0' + val;
|
|
|
|
return val;
|
|
};
|
|
|
|
//Länge der Balken im Diagram berechnen
|
|
function barwidth(size, G, W) {
|
|
var s = size;
|
|
var g = G;
|
|
var w = W;
|
|
var p = (w / g) * 100;
|
|
var newW = s * (p / 100);
|
|
|
|
return newW;
|
|
}
|
|
|
|
//String Element erweitern
|
|
String.prototype.transform = function () {
|
|
return parseFloat(this.replace(',', '.'));
|
|
}
|
|
//Array Element erweitern
|
|
Array.prototype.arrayAdd = function () {
|
|
return eval(this.join('+'));
|
|
}
|
|
|
|
//Speicherplatz in Prozent berechnen
|
|
function percentage(total, gigs, round) {
|
|
var totalSpace = total;
|
|
var singleSpace = gigs;
|
|
var z = round;
|
|
var p = singleSpace / (totalSpace / 100);
|
|
|
|
return p;
|
|
}
|
|
|
|
//Speicherplatz in GB berechnen
|
|
function gigabytes(percent, total, round) {
|
|
var occupiedPercent = percent;
|
|
var singleSpace = total;
|
|
var z = round;
|
|
var g = (singleSpace / 100) * occupiedPercent;
|
|
|
|
return g;
|
|
}
|