diff --git a/package.json b/package.json index eb64199..0fab7db 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "homepage": "https://jmaio.github.io/mandelbrot-maps/", "dependencies": { "@material-ui/core": "^4.4.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.44", "@mdi/js": "^4.4.95", "complex.js": "^2.0.11", "gl-matrix": "^3.1.0", @@ -49,4 +51,4 @@ "jest-canvas-mock": "^2.2.0", "jest-webgl-canvas-mock": "^0.2.3" } -} \ No newline at end of file +} diff --git a/public/clientDetect.js b/public/clientDetect.js new file mode 100644 index 0000000..8e079f0 --- /dev/null +++ b/public/clientDetect.js @@ -0,0 +1,216 @@ +/** + * JavaScript Client Detection + * (C) viazenetti GmbH (Christian Ludwig) + */ +(function (window) { + var unknown = '-'; + + // screen + var screenSize = ''; + if (screen.width) { + width = (screen.width) ? screen.width : ''; + height = (screen.height) ? screen.height : ''; + screenSize += '' + width + " x " + height; + } + + // browser + var nVer = navigator.appVersion; + var nAgt = navigator.userAgent; + var browser = navigator.appName; + var version = '' + parseFloat(navigator.appVersion); + var majorVersion = parseInt(navigator.appVersion, 10); + var nameOffset, verOffset, ix; + + // Opera + if ((verOffset = nAgt.indexOf('Opera')) != -1) { + browser = 'Opera'; + version = nAgt.substring(verOffset + 6); + if ((verOffset = nAgt.indexOf('Version')) != -1) { + version = nAgt.substring(verOffset + 8); + } + } + // Opera Next + if ((verOffset = nAgt.indexOf('OPR')) != -1) { + browser = 'Opera'; + version = nAgt.substring(verOffset + 4); + } + // Edge + else if ((verOffset = nAgt.indexOf('Edge')) != -1) { + browser = 'Microsoft Edge'; + version = nAgt.substring(verOffset + 5); + } + // MSIE + else if ((verOffset = nAgt.indexOf('MSIE')) != -1) { + browser = 'Microsoft Internet Explorer'; + version = nAgt.substring(verOffset + 5); + } + // Chrome + else if ((verOffset = nAgt.indexOf('Chrome')) != -1) { + browser = 'Chrome'; + version = nAgt.substring(verOffset + 7); + } + // Safari + else if ((verOffset = nAgt.indexOf('Safari')) != -1) { + browser = 'Safari'; + version = nAgt.substring(verOffset + 7); + if ((verOffset = nAgt.indexOf('Version')) != -1) { + version = nAgt.substring(verOffset + 8); + } + } + // Firefox + else if ((verOffset = nAgt.indexOf('Firefox')) != -1) { + browser = 'Firefox'; + version = nAgt.substring(verOffset + 8); + } + // MSIE 11+ + else if (nAgt.indexOf('Trident/') != -1) { + browser = 'Microsoft Internet Explorer'; + version = nAgt.substring(nAgt.indexOf('rv:') + 3); + } + // Other browsers + else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { + browser = nAgt.substring(nameOffset, verOffset); + version = nAgt.substring(verOffset + 1); + if (browser.toLowerCase() == browser.toUpperCase()) { + browser = navigator.appName; + } + } + // trim the version string + if ((ix = version.indexOf(';')) != -1) version = version.substring(0, ix); + if ((ix = version.indexOf(' ')) != -1) version = version.substring(0, ix); + if ((ix = version.indexOf(')')) != -1) version = version.substring(0, ix); + + majorVersion = parseInt('' + version, 10); + if (isNaN(majorVersion)) { + version = '' + parseFloat(navigator.appVersion); + majorVersion = parseInt(navigator.appVersion, 10); + } + + // mobile version + var mobile = /Mobile|mini|Fennec|Android|iP(ad|od|hone)/.test(nVer); + + // cookie + var cookieEnabled = (navigator.cookieEnabled) ? true : false; + + if (typeof navigator.cookieEnabled == 'undefined' && !cookieEnabled) { + document.cookie = 'testcookie'; + cookieEnabled = (document.cookie.indexOf('testcookie') != -1) ? true : false; + } + + // system + var os = unknown; + var clientStrings = [ + {s:'Windows 10', r:/(Windows 10.0|Windows NT 10.0)/}, + {s:'Windows 8.1', r:/(Windows 8.1|Windows NT 6.3)/}, + {s:'Windows 8', r:/(Windows 8|Windows NT 6.2)/}, + {s:'Windows 7', r:/(Windows 7|Windows NT 6.1)/}, + {s:'Windows Vista', r:/Windows NT 6.0/}, + {s:'Windows Server 2003', r:/Windows NT 5.2/}, + {s:'Windows XP', r:/(Windows NT 5.1|Windows XP)/}, + {s:'Windows 2000', r:/(Windows NT 5.0|Windows 2000)/}, + {s:'Windows ME', r:/(Win 9x 4.90|Windows ME)/}, + {s:'Windows 98', r:/(Windows 98|Win98)/}, + {s:'Windows 95', r:/(Windows 95|Win95|Windows_95)/}, + {s:'Windows NT 4.0', r:/(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/}, + {s:'Windows CE', r:/Windows CE/}, + {s:'Windows 3.11', r:/Win16/}, + {s:'Android', r:/Android/}, + {s:'Open BSD', r:/OpenBSD/}, + {s:'Sun OS', r:/SunOS/}, + {s:'Chrome OS', r:/CrOS/}, + {s:'Linux', r:/(Linux|X11(?!.*CrOS))/}, + {s:'iOS', r:/(iPhone|iPad|iPod)/}, + {s:'Mac OS X', r:/Mac OS X/}, + {s:'Mac OS', r:/(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/}, + {s:'QNX', r:/QNX/}, + {s:'UNIX', r:/UNIX/}, + {s:'BeOS', r:/BeOS/}, + {s:'OS/2', r:/OS\/2/}, + {s:'Search Bot', r:/(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/} + ]; + for (var id in clientStrings) { + var cs = clientStrings[id]; + if (cs.r.test(nAgt)) { + os = cs.s; + break; + } + } + + var osVersion = unknown; + + if (/Windows/.test(os)) { + osVersion = /Windows (.*)/.exec(os)[1]; + os = 'Windows'; + } + + switch (os) { + case 'Mac OS X': + osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1]; + break; + + case 'Android': + osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1]; + break; + + case 'iOS': + osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer); + osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0); + break; + + default: + break; + } + + // user agent string manipulation to obtain device model + var system = nAgt.substring(nAgt.indexOf('(') + 1, nAgt.indexOf(')')); + var device = system.substring(system.lastIndexOf(';') + 1); + + // use JavaScript to detect GPU used from within your browser - by cvan + // https://gist.github.com/cvan/042b2448fcecefafbb6a91469484cdf8 + var canvas = document.createElement('canvas'); + var gl; + var debugInfo; + var gpuVendor; + var renderer; + + try { + gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); + } catch (e) {} + + if (gl) { + debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); + gpuVendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL); + renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); + } + // ---------------------------------------------------------------- + + window.jscd = { + browser: browser, + browserVersion: majorVersion, + browserRelease: version, + // vendor: navigator.vendor, + device: device, + os: os, + osVersion: osVersion, + mobile: mobile, + platform: navigator.platform, + screen: screenSize, + dpr: +window.devicePixelRatio.toFixed(3), + gpu: renderer, + gpuVendor: gpuVendor, + userAgent: navigator.userAgent, + // cookies: cookieEnabled, + // flashVersion: flashVersion + }; +}(this)); + +// alert( +// 'OS: ' + jscd.os +' '+ jscd.osVersion + '\n' + +// 'Browser: ' + jscd.browser +' '+ jscd.browserMajorVersion + +// ' (' + jscd.browserVersion + ')\n' + +// 'Mobile: ' + jscd.mobile + '\n' + +// 'Flash: ' + jscd.flashVersion + '\n' + +// 'Cookies: ' + jscd.cookies + '\n' + +// 'Screen Size: ' + jscd.screen + '\n\n' + +// 'Full User Agent: ' + navigator.userAgent +// ); diff --git a/public/favicon-192.png b/public/favicon-192.png new file mode 100644 index 0000000..99cca91 Binary files /dev/null and b/public/favicon-192.png differ diff --git a/public/favicon-256.png b/public/favicon-256.png new file mode 100644 index 0000000..93fa277 Binary files /dev/null and b/public/favicon-256.png differ diff --git a/public/favicon-512.png b/public/favicon-512.png new file mode 100644 index 0000000..4379449 Binary files /dev/null and b/public/favicon-512.png differ diff --git a/public/index.html b/public/index.html index 4c825ec..9f0ec4f 100644 --- a/public/index.html +++ b/public/index.html @@ -11,15 +11,22 @@ gtag('config', 'UA-25811690-6'); + - + + - + + + + + + + -