Initial commit

This commit is contained in:
Rene Vergara 2024-08-27 07:27:37 -05:00
commit 41165f9c2c
Signed by: pitmutt
GPG key ID: 65122AD495A7F5B2
64 changed files with 63602 additions and 0 deletions

10
.gitignore vendored Normal file
View file

@ -0,0 +1,10 @@
/bower_components/
/node_modules/
/.pulp-cache/
/output/
/generated-docs/
/.psc-package/
/.psc*
/.purs*
/.psa*
/.spago

15
CHANGELOG.md Normal file
View file

@ -0,0 +1,15 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.1.0.0]
### Added
- CHANGELOG.md
- README.md
- Basic UI

22
LICENSE Normal file
View file

@ -0,0 +1,22 @@
MIT License
Copyright (c) 2022-2024 Vergara Technologies LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

6
README.md Normal file
View file

@ -0,0 +1,6 @@
# exblo-app
[![Please don't upload to GitHub](https://nogithub.codeberg.page/badge.svg)](https://nogithub.codeberg.page) ![](https://img.shields.io/badge/License-MIT-green
)
The UI for the [exblo](https://testnet.exblo.app) block explorer.

9000
dev/app.js Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dev/fonts/F25_Executive.otf Normal file

Binary file not shown.

BIN
dev/fonts/remixicon.eot Normal file

Binary file not shown.

8572
dev/fonts/remixicon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
dev/fonts/remixicon.ttf Normal file

Binary file not shown.

BIN
dev/fonts/remixicon.woff Normal file

Binary file not shown.

BIN
dev/fonts/remixicon.woff2 Normal file

Binary file not shown.

12
dev/index.html Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>exblo - Zcash Explorer</title>
<link rel="stylesheet" href="main.css" />
<link rel="stylesheet" href="remixicon.css" />
</head>
<body>
<script src="app.js" charset="utf-8"></script>
</body>
</html>

145
dev/main.css Normal file
View file

@ -0,0 +1,145 @@
:root {
--input-border: #8b8a8b;
--input-focus-h: 245;
--input-focus-s: 100%;
--input-focus-l: 42%;
}
@font-face {
font-family: 'AtkinsonHyperlegible';
src: url('./fonts/Atkinson-Hyperlegible-Regular-102.eot');
src: url('./fonts/Atkinson-Hyperlegible-Regular-102.eot?#iefix') format('embedded-opentype'),
url('./fonts/Atkinson-Hyperlegible-Regular-102a.woff2') format('woff2'),
url('./fonts/Atkinson-Hyperlegible-Regular-102.woff') format('woff'),
url('./fonts/Atkinson-Hyperlegible-Regular-102.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'F25Executive';
src: url('./fonts/F25_Executive.otf') format('opentype');
font-display: swap;
}
* {
box-sizing: border-box;
}
html {
font-family: 'AtkinsonHyperlegible', sans-serif;
}
button.btn-primary {
border: none;
font-family: inherit;
padding: 0;
cursor: pointer;
@media screen and (-ms-high-contrast: active) {
border: 2px solid currentcolor;
}
}
button.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
background-color: green;
cursor: pointer;
font-family: inherit;
border-radius: 8px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18);
padding: 0.25em 0.75em;
min-width: 10ch;
min-height: 44px;
text-align: center;
line-height: 1.1;
}
button:disabled {
background-color: gray;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
margin: auto;
width: 50%;
text-align: center;
}
.card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.bigcard {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
margin: auto;
width: 90%;
text-align: center;
}
.bigcard:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.infocard {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
margin: auto;
width: 75%;
text-align: center;
}
.infocard:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.input {
font-size: 14px;
font-size: max(14px, 1em);
font-family: inherit;
padding: 0.25em 0.5em;
background-color: #fff;
border: 2px solid var(--input-border);
border-radius: 4px;
}
th {
font-family: 'F25Executive', serif;
font-size: 15px;
border-bottom: 1px dashed #aaa;
}
td {
word-wrap: anywhere;
text-align: left;
border-bottom: 1px dashed #aaa;
}
tr {
}
h1 {
font-family: 'F25Executive', serif;
}
h2 {
font-family: 'F25Executive', serif;
}
h3 {
font-family: 'F25Executive', serif;
}
h4 {
font-family: 'F25Executive', serif;
}
h5 {
font-family: 'F25Executive', serif;
}

2896
dev/remixicon.css Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

12
dist/.parcel-cache/47d481ff6257efcc.txt vendored Normal file
View file

@ -0,0 +1,12 @@
11
61/home/rav/Documents/scripts/kusari-app/dist/index.0de476db.js1724092378475126476 0
66/home/rav/Documents/scripts/kusari-app/dist/dist/index.6d460313.js1724092618631422153 0
65/home/rav/Documents/scripts/kusari-app/dist/dist/dist.3464ddca.js1724092618495424224 0
65/home/rav/Documents/scripts/kusari-app/dist/index.0de476db.js.map1724092378483126352 0
69/home/rav/Documents/scripts/kusari-app/dist/dist/dist.3464ddca.js.map1724092618499424163 0
70/home/rav/Documents/scripts/kusari-app/dist/dist/index.6d460313.js.map1724092618643421970 0
59/home/rav/Documents/scripts/kusari-app/dist/dist/index.html1724092618487424346 0
48/home/rav/Documents/scripts/kusari-app/dist/dist1724092618643421970 1
54/home/rav/Documents/scripts/kusari-app/dist/index.html1724092378471126540 0
50/home/rav/Documents/scripts/kusari-app/dist/app.js1724089819059844631 0
43/home/rav/Documents/scripts/kusari-app/dist1724092618467424651 1

Binary file not shown.

Binary file not shown.

12
dist/.parcel-cache/9e063c879a3e4ec8.txt vendored Normal file
View file

@ -0,0 +1,12 @@
11
61/home/rav/Documents/scripts/kusari-app/dist/index.0de476db.js1724092378475126476 0
66/home/rav/Documents/scripts/kusari-app/dist/dist/index.6d460313.js1724092618631422153 0
65/home/rav/Documents/scripts/kusari-app/dist/dist/dist.3464ddca.js1724092618495424224 0
65/home/rav/Documents/scripts/kusari-app/dist/index.0de476db.js.map1724092378483126352 0
69/home/rav/Documents/scripts/kusari-app/dist/dist/dist.3464ddca.js.map1724092618499424163 0
70/home/rav/Documents/scripts/kusari-app/dist/dist/index.6d460313.js.map1724092618643421970 0
59/home/rav/Documents/scripts/kusari-app/dist/dist/index.html1724092618487424346 0
48/home/rav/Documents/scripts/kusari-app/dist/dist1724092618643421970 1
54/home/rav/Documents/scripts/kusari-app/dist/index.html1724092378471126540 0
50/home/rav/Documents/scripts/kusari-app/dist/app.js1724089819059844631 0
43/home/rav/Documents/scripts/kusari-app/dist1724092618467424651 1

Binary file not shown.

BIN
dist/.parcel-cache/data.mdb vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/.parcel-cache/lock.mdb vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/F25_Executive.aabe3e61.otf vendored Normal file

Binary file not shown.

8099
dist/app.js vendored Normal file

File diff suppressed because it is too large Load diff

590
dist/dev.ff48a766.js vendored Normal file
View file

@ -0,0 +1,590 @@
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
/* eslint-disable no-undef */
var globalObject =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
/* eslint-enable no-undef */
// Save the require from previous bundle to this closure if any
var previousRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
var cache = previousRequire.cache || {};
// Do not use `require` to prevent Webpack from trying to bundle this call
var nodeRequire =
typeof module !== 'undefined' &&
typeof module.require === 'function' &&
module.require.bind(module);
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}
var err = new Error("Cannot find module '" + name + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
localRequire.resolve = resolve;
localRequire.cache = {};
var module = (cache[name] = new newRequire.Module(name));
modules[name][0].call(
module.exports,
localRequire,
module,
module.exports,
this
);
}
return cache[name].exports;
function localRequire(x) {
var res = localRequire.resolve(x);
return res === false ? {} : newRequire(res);
}
function resolve(x) {
var id = modules[name][1][x];
return id != null ? id : x;
}
}
function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}
newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [
function (require, module) {
module.exports = exports;
},
{},
];
};
Object.defineProperty(newRequire, 'root', {
get: function () {
return globalObject[parcelRequireName];
},
});
globalObject[parcelRequireName] = newRequire;
for (var i = 0; i < entry.length; i++) {
newRequire(entry[i]);
}
if (mainEntry) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(mainEntry);
// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = mainExports;
// RequireJS
} else if (typeof define === 'function' && define.amd) {
define(function () {
return mainExports;
});
// <script>
} else if (globalName) {
this[globalName] = mainExports;
}
}
})({"1V81K":[function(require,module,exports) {
var global = arguments[3];
var HMR_HOST = null;
var HMR_PORT = null;
var HMR_SECURE = false;
var HMR_ENV_HASH = "d6ea1d42532a7575";
var HMR_USE_SSE = false;
module.bundle.HMR_BUNDLE_ID = "592db56dff48a766";
"use strict";
/* global HMR_HOST, HMR_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */ /*::
import type {
HMRAsset,
HMRMessage,
} from '@parcel/reporter-dev-server/src/HMRServer.js';
interface ParcelRequire {
(string): mixed;
cache: {|[string]: ParcelModule|};
hotData: {|[string]: mixed|};
Module: any;
parent: ?ParcelRequire;
isParcelRequire: true;
modules: {|[string]: [Function, {|[string]: string|}]|};
HMR_BUNDLE_ID: string;
root: ParcelRequire;
}
interface ParcelModule {
hot: {|
data: mixed,
accept(cb: (Function) => void): void,
dispose(cb: (mixed) => void): void,
// accept(deps: Array<string> | string, cb: (Function) => void): void,
// decline(): void,
_acceptCallbacks: Array<(Function) => void>,
_disposeCallbacks: Array<(mixed) => void>,
|};
}
interface ExtensionContext {
runtime: {|
reload(): void,
getURL(url: string): string;
getManifest(): {manifest_version: number, ...};
|};
}
declare var module: {bundle: ParcelRequire, ...};
declare var HMR_HOST: string;
declare var HMR_PORT: string;
declare var HMR_ENV_HASH: string;
declare var HMR_SECURE: boolean;
declare var HMR_USE_SSE: boolean;
declare var chrome: ExtensionContext;
declare var browser: ExtensionContext;
declare var __parcel__import__: (string) => Promise<void>;
declare var __parcel__importScripts__: (string) => Promise<void>;
declare var globalThis: typeof self;
declare var ServiceWorkerGlobalScope: Object;
*/ var OVERLAY_ID = "__parcel__error__overlay__";
var OldModule = module.bundle.Module;
function Module(moduleName) {
OldModule.call(this, moduleName);
this.hot = {
data: module.bundle.hotData[moduleName],
_acceptCallbacks: [],
_disposeCallbacks: [],
accept: function(fn) {
this._acceptCallbacks.push(fn || function() {});
},
dispose: function(fn) {
this._disposeCallbacks.push(fn);
}
};
module.bundle.hotData[moduleName] = undefined;
}
module.bundle.Module = Module;
module.bundle.hotData = {};
var checkedAssets /*: {|[string]: boolean|} */ , assetsToDispose /*: Array<[ParcelRequire, string]> */ , assetsToAccept /*: Array<[ParcelRequire, string]> */ ;
function getHostname() {
return HMR_HOST || (location.protocol.indexOf("http") === 0 ? location.hostname : "localhost");
}
function getPort() {
return HMR_PORT || location.port;
}
// eslint-disable-next-line no-redeclare
var parent = module.bundle.parent;
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== "undefined") {
var hostname = getHostname();
var port = getPort();
var protocol = HMR_SECURE || location.protocol == "https:" && ![
"localhost",
"127.0.0.1",
"0.0.0.0"
].includes(hostname) ? "wss" : "ws";
var ws;
if (HMR_USE_SSE) ws = new EventSource("/__parcel_hmr");
else try {
ws = new WebSocket(protocol + "://" + hostname + (port ? ":" + port : "") + "/");
} catch (err) {
if (err.message) console.error(err.message);
ws = {};
}
// Web extension context
var extCtx = typeof browser === "undefined" ? typeof chrome === "undefined" ? null : chrome : browser;
// Safari doesn't support sourceURL in error stacks.
// eval may also be disabled via CSP, so do a quick check.
var supportsSourceURL = false;
try {
(0, eval)('throw new Error("test"); //# sourceURL=test.js');
} catch (err) {
supportsSourceURL = err.stack.includes("test.js");
}
// $FlowFixMe
ws.onmessage = async function(event /*: {data: string, ...} */ ) {
checkedAssets = {} /*: {|[string]: boolean|} */ ;
assetsToAccept = [];
assetsToDispose = [];
var data /*: HMRMessage */ = JSON.parse(event.data);
if (data.type === "update") {
// Remove error overlay if there is one
if (typeof document !== "undefined") removeErrorOverlay();
let assets = data.assets.filter((asset)=>asset.envHash === HMR_ENV_HASH);
// Handle HMR Update
let handled = assets.every((asset)=>{
return asset.type === "css" || asset.type === "js" && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);
});
if (handled) {
console.clear();
// Dispatch custom event so other runtimes (e.g React Refresh) are aware.
if (typeof window !== "undefined" && typeof CustomEvent !== "undefined") window.dispatchEvent(new CustomEvent("parcelhmraccept"));
await hmrApplyUpdates(assets);
// Dispose all old assets.
let processedAssets = {} /*: {|[string]: boolean|} */ ;
for(let i = 0; i < assetsToDispose.length; i++){
let id = assetsToDispose[i][1];
if (!processedAssets[id]) {
hmrDispose(assetsToDispose[i][0], id);
processedAssets[id] = true;
}
}
// Run accept callbacks. This will also re-execute other disposed assets in topological order.
processedAssets = {};
for(let i = 0; i < assetsToAccept.length; i++){
let id = assetsToAccept[i][1];
if (!processedAssets[id]) {
hmrAccept(assetsToAccept[i][0], id);
processedAssets[id] = true;
}
}
} else fullReload();
}
if (data.type === "error") {
// Log parcel errors to console
for (let ansiDiagnostic of data.diagnostics.ansi){
let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;
console.error("\uD83D\uDEA8 [parcel]: " + ansiDiagnostic.message + "\n" + stack + "\n\n" + ansiDiagnostic.hints.join("\n"));
}
if (typeof document !== "undefined") {
// Render the fancy html overlay
removeErrorOverlay();
var overlay = createErrorOverlay(data.diagnostics.html);
// $FlowFixMe
document.body.appendChild(overlay);
}
}
};
if (ws instanceof WebSocket) {
ws.onerror = function(e) {
if (e.message) console.error(e.message);
};
ws.onclose = function() {
console.warn("[parcel] \uD83D\uDEA8 Connection to the HMR server was lost");
};
}
}
function removeErrorOverlay() {
var overlay = document.getElementById(OVERLAY_ID);
if (overlay) {
overlay.remove();
console.log("[parcel] \u2728 Error resolved");
}
}
function createErrorOverlay(diagnostics) {
var overlay = document.createElement("div");
overlay.id = OVERLAY_ID;
let errorHTML = '<div style="background: black; opacity: 0.85; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; font-family: Menlo, Consolas, monospace; z-index: 9999;">';
for (let diagnostic of diagnostics){
let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame)=>{
return `${p}
<a href="/__parcel_launch_editor?file=${encodeURIComponent(frame.location)}" style="text-decoration: underline; color: #888" onclick="fetch(this.href); return false">${frame.location}</a>
${frame.code}`;
}, "") : diagnostic.stack;
errorHTML += `
<div>
<div style="font-size: 18px; font-weight: bold; margin-top: 20px;">
\u{1F6A8} ${diagnostic.message}
</div>
<pre>${stack}</pre>
<div>
${diagnostic.hints.map((hint)=>"<div>\uD83D\uDCA1 " + hint + "</div>").join("")}
</div>
${diagnostic.documentation ? `<div>\u{1F4DD} <a style="color: violet" href="${diagnostic.documentation}" target="_blank">Learn more</a></div>` : ""}
</div>
`;
}
errorHTML += "</div>";
overlay.innerHTML = errorHTML;
return overlay;
}
function fullReload() {
if ("reload" in location) location.reload();
else if (extCtx && extCtx.runtime && extCtx.runtime.reload) extCtx.runtime.reload();
}
function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ {
var modules = bundle.modules;
if (!modules) return [];
var parents = [];
var k, d, dep;
for(k in modules)for(d in modules[k][1]){
dep = modules[k][1][d];
if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([
bundle,
k
]);
}
if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id));
return parents;
}
function updateLink(link) {
var href = link.getAttribute("href");
if (!href) return;
var newLink = link.cloneNode();
newLink.onload = function() {
if (link.parentNode !== null) // $FlowFixMe
link.parentNode.removeChild(link);
};
newLink.setAttribute("href", // $FlowFixMe
href.split("?")[0] + "?" + Date.now());
// $FlowFixMe
link.parentNode.insertBefore(newLink, link.nextSibling);
}
var cssTimeout = null;
function reloadCSS() {
if (cssTimeout) return;
cssTimeout = setTimeout(function() {
var links = document.querySelectorAll('link[rel="stylesheet"]');
for(var i = 0; i < links.length; i++){
// $FlowFixMe[incompatible-type]
var href /*: string */ = links[i].getAttribute("href");
var hostname = getHostname();
var servedFromHMRServer = hostname === "localhost" ? new RegExp("^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):" + getPort()).test(href) : href.indexOf(hostname + ":" + getPort());
var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;
if (!absolute) updateLink(links[i]);
}
cssTimeout = null;
}, 50);
}
function hmrDownload(asset) {
if (asset.type === "js") {
if (typeof document !== "undefined") {
let script = document.createElement("script");
script.src = asset.url + "?t=" + Date.now();
if (asset.outputFormat === "esmodule") script.type = "module";
return new Promise((resolve, reject)=>{
var _document$head;
script.onload = ()=>resolve(script);
script.onerror = reject;
(_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);
});
} else if (typeof importScripts === "function") {
// Worker scripts
if (asset.outputFormat === "esmodule") return import(asset.url + "?t=" + Date.now());
else return new Promise((resolve, reject)=>{
try {
importScripts(asset.url + "?t=" + Date.now());
resolve();
} catch (err) {
reject(err);
}
});
}
}
}
async function hmrApplyUpdates(assets) {
global.parcelHotUpdate = Object.create(null);
let scriptsToRemove;
try {
// If sourceURL comments aren't supported in eval, we need to load
// the update from the dev server over HTTP so that stack traces
// are correct in errors/logs. This is much slower than eval, so
// we only do it if needed (currently just Safari).
// https://bugs.webkit.org/show_bug.cgi?id=137297
// This path is also taken if a CSP disallows eval.
if (!supportsSourceURL) {
let promises = assets.map((asset)=>{
var _hmrDownload;
return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch((err)=>{
// Web extension fix
if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != "undefined" && global instanceof ServiceWorkerGlobalScope) {
extCtx.runtime.reload();
return;
}
throw err;
});
});
scriptsToRemove = await Promise.all(promises);
}
assets.forEach(function(asset) {
hmrApply(module.bundle.root, asset);
});
} finally{
delete global.parcelHotUpdate;
if (scriptsToRemove) scriptsToRemove.forEach((script)=>{
if (script) {
var _document$head2;
(_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);
}
});
}
}
function hmrApply(bundle /*: ParcelRequire */ , asset /*: HMRAsset */ ) {
var modules = bundle.modules;
if (!modules) return;
if (asset.type === "css") reloadCSS();
else if (asset.type === "js") {
let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];
if (deps) {
if (modules[asset.id]) {
// Remove dependencies that are removed and will become orphaned.
// This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.
let oldDeps = modules[asset.id][1];
for(let dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) {
let id = oldDeps[dep];
let parents = getParents(module.bundle.root, id);
if (parents.length === 1) hmrDelete(module.bundle.root, id);
}
}
if (supportsSourceURL) // Global eval. We would use `new Function` here but browser
// support for source maps is better with eval.
(0, eval)(asset.output);
// $FlowFixMe
let fn = global.parcelHotUpdate[asset.id];
modules[asset.id] = [
fn,
deps
];
} else if (bundle.parent) hmrApply(bundle.parent, asset);
}
}
function hmrDelete(bundle, id) {
let modules = bundle.modules;
if (!modules) return;
if (modules[id]) {
// Collect dependencies that will become orphaned when this module is deleted.
let deps = modules[id][1];
let orphans = [];
for(let dep in deps){
let parents = getParents(module.bundle.root, deps[dep]);
if (parents.length === 1) orphans.push(deps[dep]);
}
// Delete the module. This must be done before deleting dependencies in case of circular dependencies.
delete modules[id];
delete bundle.cache[id];
// Now delete the orphans.
orphans.forEach((id)=>{
hmrDelete(module.bundle.root, id);
});
} else if (bundle.parent) hmrDelete(bundle.parent, id);
}
function hmrAcceptCheck(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) {
if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true;
// Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.
let parents = getParents(module.bundle.root, id);
let accepted = false;
while(parents.length > 0){
let v = parents.shift();
let a = hmrAcceptCheckOne(v[0], v[1], null);
if (a) // If this parent accepts, stop traversing upward, but still consider siblings.
accepted = true;
else {
// Otherwise, queue the parents in the next level upward.
let p = getParents(module.bundle.root, v[1]);
if (p.length === 0) {
// If there are no parents, then we've reached an entry without accepting. Reload.
accepted = false;
break;
}
parents.push(...p);
}
}
return accepted;
}
function hmrAcceptCheckOne(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) {
var modules = bundle.modules;
if (!modules) return;
if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {
// If we reached the root bundle without finding where the asset should go,
// there's nothing to do. Mark as "accepted" so we don't reload the page.
if (!bundle.parent) return true;
return hmrAcceptCheck(bundle.parent, id, depsByBundle);
}
if (checkedAssets[id]) return true;
checkedAssets[id] = true;
var cached = bundle.cache[id];
assetsToDispose.push([
bundle,
id
]);
if (!cached || cached.hot && cached.hot._acceptCallbacks.length) {
assetsToAccept.push([
bundle,
id
]);
return true;
}
}
function hmrDispose(bundle /*: ParcelRequire */ , id /*: string */ ) {
var cached = bundle.cache[id];
bundle.hotData[id] = {};
if (cached && cached.hot) cached.hot.data = bundle.hotData[id];
if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) {
cb(bundle.hotData[id]);
});
delete bundle.cache[id];
}
function hmrAccept(bundle /*: ParcelRequire */ , id /*: string */ ) {
// Execute the module.
bundle(id);
// Run the accept callbacks in the new version of the module.
var cached = bundle.cache[id];
if (cached && cached.hot && cached.hot._acceptCallbacks.length) cached.hot._acceptCallbacks.forEach(function(cb) {
var assetsToAlsoAccept = cb(function() {
return getParents(module.bundle.root, id);
});
if (assetsToAlsoAccept && assetsToAccept.length) {
assetsToAlsoAccept.forEach(function(a) {
hmrDispose(a[0], a[1]);
});
// $FlowFixMe[method-unbinding]
assetsToAccept.push.apply(assetsToAccept, assetsToAlsoAccept);
}
});
}
},{}],"lgMMc":[function(require,module,exports) {
},{}]},["1V81K","lgMMc"], "lgMMc", "parcelRequire94c2")
//# sourceMappingURL=dev.ff48a766.js.map

1
dist/dev.ff48a766.js.map vendored Normal file

File diff suppressed because one or more lines are too long

585
dist/dist/dist.3464ddca.js vendored Normal file
View file

@ -0,0 +1,585 @@
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
/* eslint-disable no-undef */
var globalObject =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
/* eslint-enable no-undef */
// Save the require from previous bundle to this closure if any
var previousRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
var cache = previousRequire.cache || {};
// Do not use `require` to prevent Webpack from trying to bundle this call
var nodeRequire =
typeof module !== 'undefined' &&
typeof module.require === 'function' &&
module.require.bind(module);
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}
var err = new Error("Cannot find module '" + name + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
localRequire.resolve = resolve;
localRequire.cache = {};
var module = (cache[name] = new newRequire.Module(name));
modules[name][0].call(
module.exports,
localRequire,
module,
module.exports,
this
);
}
return cache[name].exports;
function localRequire(x) {
var res = localRequire.resolve(x);
return res === false ? {} : newRequire(res);
}
function resolve(x) {
var id = modules[name][1][x];
return id != null ? id : x;
}
}
function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}
newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [
function (require, module) {
module.exports = exports;
},
{},
];
};
Object.defineProperty(newRequire, 'root', {
get: function () {
return globalObject[parcelRequireName];
},
});
globalObject[parcelRequireName] = newRequire;
for (var i = 0; i < entry.length; i++) {
newRequire(entry[i]);
}
if (mainEntry) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(mainEntry);
// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = mainExports;
// RequireJS
} else if (typeof define === 'function' && define.amd) {
define(function () {
return mainExports;
});
// <script>
} else if (globalName) {
this[globalName] = mainExports;
}
}
})({"65hmi":[function(require,module,exports) {
var global = arguments[3];
var HMR_HOST = null;
var HMR_PORT = null;
var HMR_SECURE = false;
var HMR_ENV_HASH = "d6ea1d42532a7575";
module.bundle.HMR_BUNDLE_ID = "0907ca6d3464ddca";
"use strict";
/* global HMR_HOST, HMR_PORT, HMR_ENV_HASH, HMR_SECURE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */ /*::
import type {
HMRAsset,
HMRMessage,
} from '@parcel/reporter-dev-server/src/HMRServer.js';
interface ParcelRequire {
(string): mixed;
cache: {|[string]: ParcelModule|};
hotData: {|[string]: mixed|};
Module: any;
parent: ?ParcelRequire;
isParcelRequire: true;
modules: {|[string]: [Function, {|[string]: string|}]|};
HMR_BUNDLE_ID: string;
root: ParcelRequire;
}
interface ParcelModule {
hot: {|
data: mixed,
accept(cb: (Function) => void): void,
dispose(cb: (mixed) => void): void,
// accept(deps: Array<string> | string, cb: (Function) => void): void,
// decline(): void,
_acceptCallbacks: Array<(Function) => void>,
_disposeCallbacks: Array<(mixed) => void>,
|};
}
interface ExtensionContext {
runtime: {|
reload(): void,
getURL(url: string): string;
getManifest(): {manifest_version: number, ...};
|};
}
declare var module: {bundle: ParcelRequire, ...};
declare var HMR_HOST: string;
declare var HMR_PORT: string;
declare var HMR_ENV_HASH: string;
declare var HMR_SECURE: boolean;
declare var chrome: ExtensionContext;
declare var browser: ExtensionContext;
declare var __parcel__import__: (string) => Promise<void>;
declare var __parcel__importScripts__: (string) => Promise<void>;
declare var globalThis: typeof self;
declare var ServiceWorkerGlobalScope: Object;
*/ var OVERLAY_ID = "__parcel__error__overlay__";
var OldModule = module.bundle.Module;
function Module(moduleName) {
OldModule.call(this, moduleName);
this.hot = {
data: module.bundle.hotData[moduleName],
_acceptCallbacks: [],
_disposeCallbacks: [],
accept: function(fn) {
this._acceptCallbacks.push(fn || function() {});
},
dispose: function(fn) {
this._disposeCallbacks.push(fn);
}
};
module.bundle.hotData[moduleName] = undefined;
}
module.bundle.Module = Module;
module.bundle.hotData = {};
var checkedAssets /*: {|[string]: boolean|} */ , assetsToDispose /*: Array<[ParcelRequire, string]> */ , assetsToAccept /*: Array<[ParcelRequire, string]> */ ;
function getHostname() {
return HMR_HOST || (location.protocol.indexOf("http") === 0 ? location.hostname : "localhost");
}
function getPort() {
return HMR_PORT || location.port;
}
// eslint-disable-next-line no-redeclare
var parent = module.bundle.parent;
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== "undefined") {
var hostname = getHostname();
var port = getPort();
var protocol = HMR_SECURE || location.protocol == "https:" && ![
"localhost",
"127.0.0.1",
"0.0.0.0"
].includes(hostname) ? "wss" : "ws";
var ws;
try {
ws = new WebSocket(protocol + "://" + hostname + (port ? ":" + port : "") + "/");
} catch (err) {
if (err.message) console.error(err.message);
ws = {};
}
// Web extension context
var extCtx = typeof browser === "undefined" ? typeof chrome === "undefined" ? null : chrome : browser;
// Safari doesn't support sourceURL in error stacks.
// eval may also be disabled via CSP, so do a quick check.
var supportsSourceURL = false;
try {
(0, eval)('throw new Error("test"); //# sourceURL=test.js');
} catch (err) {
supportsSourceURL = err.stack.includes("test.js");
}
// $FlowFixMe
ws.onmessage = async function(event /*: {data: string, ...} */ ) {
checkedAssets = {} /*: {|[string]: boolean|} */ ;
assetsToAccept = [];
assetsToDispose = [];
var data /*: HMRMessage */ = JSON.parse(event.data);
if (data.type === "update") {
// Remove error overlay if there is one
if (typeof document !== "undefined") removeErrorOverlay();
let assets = data.assets.filter((asset)=>asset.envHash === HMR_ENV_HASH);
// Handle HMR Update
let handled = assets.every((asset)=>{
return asset.type === "css" || asset.type === "js" && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);
});
if (handled) {
console.clear();
// Dispatch custom event so other runtimes (e.g React Refresh) are aware.
if (typeof window !== "undefined" && typeof CustomEvent !== "undefined") window.dispatchEvent(new CustomEvent("parcelhmraccept"));
await hmrApplyUpdates(assets);
// Dispose all old assets.
let processedAssets = {} /*: {|[string]: boolean|} */ ;
for(let i = 0; i < assetsToDispose.length; i++){
let id = assetsToDispose[i][1];
if (!processedAssets[id]) {
hmrDispose(assetsToDispose[i][0], id);
processedAssets[id] = true;
}
}
// Run accept callbacks. This will also re-execute other disposed assets in topological order.
processedAssets = {};
for(let i = 0; i < assetsToAccept.length; i++){
let id = assetsToAccept[i][1];
if (!processedAssets[id]) {
hmrAccept(assetsToAccept[i][0], id);
processedAssets[id] = true;
}
}
} else fullReload();
}
if (data.type === "error") {
// Log parcel errors to console
for (let ansiDiagnostic of data.diagnostics.ansi){
let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;
console.error("\uD83D\uDEA8 [parcel]: " + ansiDiagnostic.message + "\n" + stack + "\n\n" + ansiDiagnostic.hints.join("\n"));
}
if (typeof document !== "undefined") {
// Render the fancy html overlay
removeErrorOverlay();
var overlay = createErrorOverlay(data.diagnostics.html);
// $FlowFixMe
document.body.appendChild(overlay);
}
}
};
ws.onerror = function(e) {
if (e.message) console.error(e.message);
};
ws.onclose = function() {
console.warn("[parcel] \uD83D\uDEA8 Connection to the HMR server was lost");
};
}
function removeErrorOverlay() {
var overlay = document.getElementById(OVERLAY_ID);
if (overlay) {
overlay.remove();
console.log("[parcel] \u2728 Error resolved");
}
}
function createErrorOverlay(diagnostics) {
var overlay = document.createElement("div");
overlay.id = OVERLAY_ID;
let errorHTML = '<div style="background: black; opacity: 0.85; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; font-family: Menlo, Consolas, monospace; z-index: 9999;">';
for (let diagnostic of diagnostics){
let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame)=>{
return `${p}
<a href="/__parcel_launch_editor?file=${encodeURIComponent(frame.location)}" style="text-decoration: underline; color: #888" onclick="fetch(this.href); return false">${frame.location}</a>
${frame.code}`;
}, "") : diagnostic.stack;
errorHTML += `
<div>
<div style="font-size: 18px; font-weight: bold; margin-top: 20px;">
\u{1F6A8} ${diagnostic.message}
</div>
<pre>${stack}</pre>
<div>
${diagnostic.hints.map((hint)=>"<div>\uD83D\uDCA1 " + hint + "</div>").join("")}
</div>
${diagnostic.documentation ? `<div>\u{1F4DD} <a style="color: violet" href="${diagnostic.documentation}" target="_blank">Learn more</a></div>` : ""}
</div>
`;
}
errorHTML += "</div>";
overlay.innerHTML = errorHTML;
return overlay;
}
function fullReload() {
if ("reload" in location) location.reload();
else if (extCtx && extCtx.runtime && extCtx.runtime.reload) extCtx.runtime.reload();
}
function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ {
var modules = bundle.modules;
if (!modules) return [];
var parents = [];
var k, d, dep;
for(k in modules)for(d in modules[k][1]){
dep = modules[k][1][d];
if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([
bundle,
k
]);
}
if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id));
return parents;
}
function updateLink(link) {
var href = link.getAttribute("href");
if (!href) return;
var newLink = link.cloneNode();
newLink.onload = function() {
if (link.parentNode !== null) // $FlowFixMe
link.parentNode.removeChild(link);
};
newLink.setAttribute("href", // $FlowFixMe
href.split("?")[0] + "?" + Date.now());
// $FlowFixMe
link.parentNode.insertBefore(newLink, link.nextSibling);
}
var cssTimeout = null;
function reloadCSS() {
if (cssTimeout) return;
cssTimeout = setTimeout(function() {
var links = document.querySelectorAll('link[rel="stylesheet"]');
for(var i = 0; i < links.length; i++){
// $FlowFixMe[incompatible-type]
var href /*: string */ = links[i].getAttribute("href");
var hostname = getHostname();
var servedFromHMRServer = hostname === "localhost" ? new RegExp("^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):" + getPort()).test(href) : href.indexOf(hostname + ":" + getPort());
var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;
if (!absolute) updateLink(links[i]);
}
cssTimeout = null;
}, 50);
}
function hmrDownload(asset) {
if (asset.type === "js") {
if (typeof document !== "undefined") {
let script = document.createElement("script");
script.src = asset.url + "?t=" + Date.now();
if (asset.outputFormat === "esmodule") script.type = "module";
return new Promise((resolve, reject)=>{
var _document$head;
script.onload = ()=>resolve(script);
script.onerror = reject;
(_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);
});
} else if (typeof importScripts === "function") {
// Worker scripts
if (asset.outputFormat === "esmodule") return import(asset.url + "?t=" + Date.now());
else return new Promise((resolve, reject)=>{
try {
importScripts(asset.url + "?t=" + Date.now());
resolve();
} catch (err) {
reject(err);
}
});
}
}
}
async function hmrApplyUpdates(assets) {
global.parcelHotUpdate = Object.create(null);
let scriptsToRemove;
try {
// If sourceURL comments aren't supported in eval, we need to load
// the update from the dev server over HTTP so that stack traces
// are correct in errors/logs. This is much slower than eval, so
// we only do it if needed (currently just Safari).
// https://bugs.webkit.org/show_bug.cgi?id=137297
// This path is also taken if a CSP disallows eval.
if (!supportsSourceURL) {
let promises = assets.map((asset)=>{
var _hmrDownload;
return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch((err)=>{
// Web extension fix
if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != "undefined" && global instanceof ServiceWorkerGlobalScope) {
extCtx.runtime.reload();
return;
}
throw err;
});
});
scriptsToRemove = await Promise.all(promises);
}
assets.forEach(function(asset) {
hmrApply(module.bundle.root, asset);
});
} finally{
delete global.parcelHotUpdate;
if (scriptsToRemove) scriptsToRemove.forEach((script)=>{
if (script) {
var _document$head2;
(_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);
}
});
}
}
function hmrApply(bundle /*: ParcelRequire */ , asset /*: HMRAsset */ ) {
var modules = bundle.modules;
if (!modules) return;
if (asset.type === "css") reloadCSS();
else if (asset.type === "js") {
let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];
if (deps) {
if (modules[asset.id]) {
// Remove dependencies that are removed and will become orphaned.
// This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.
let oldDeps = modules[asset.id][1];
for(let dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) {
let id = oldDeps[dep];
let parents = getParents(module.bundle.root, id);
if (parents.length === 1) hmrDelete(module.bundle.root, id);
}
}
if (supportsSourceURL) // Global eval. We would use `new Function` here but browser
// support for source maps is better with eval.
(0, eval)(asset.output);
// $FlowFixMe
let fn = global.parcelHotUpdate[asset.id];
modules[asset.id] = [
fn,
deps
];
} else if (bundle.parent) hmrApply(bundle.parent, asset);
}
}
function hmrDelete(bundle, id) {
let modules = bundle.modules;
if (!modules) return;
if (modules[id]) {
// Collect dependencies that will become orphaned when this module is deleted.
let deps = modules[id][1];
let orphans = [];
for(let dep in deps){
let parents = getParents(module.bundle.root, deps[dep]);
if (parents.length === 1) orphans.push(deps[dep]);
}
// Delete the module. This must be done before deleting dependencies in case of circular dependencies.
delete modules[id];
delete bundle.cache[id];
// Now delete the orphans.
orphans.forEach((id)=>{
hmrDelete(module.bundle.root, id);
});
} else if (bundle.parent) hmrDelete(bundle.parent, id);
}
function hmrAcceptCheck(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) {
if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true;
// Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.
let parents = getParents(module.bundle.root, id);
let accepted = false;
while(parents.length > 0){
let v = parents.shift();
let a = hmrAcceptCheckOne(v[0], v[1], null);
if (a) // If this parent accepts, stop traversing upward, but still consider siblings.
accepted = true;
else {
// Otherwise, queue the parents in the next level upward.
let p = getParents(module.bundle.root, v[1]);
if (p.length === 0) {
// If there are no parents, then we've reached an entry without accepting. Reload.
accepted = false;
break;
}
parents.push(...p);
}
}
return accepted;
}
function hmrAcceptCheckOne(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) {
var modules = bundle.modules;
if (!modules) return;
if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {
// If we reached the root bundle without finding where the asset should go,
// there's nothing to do. Mark as "accepted" so we don't reload the page.
if (!bundle.parent) return true;
return hmrAcceptCheck(bundle.parent, id, depsByBundle);
}
if (checkedAssets[id]) return true;
checkedAssets[id] = true;
var cached = bundle.cache[id];
assetsToDispose.push([
bundle,
id
]);
if (!cached || cached.hot && cached.hot._acceptCallbacks.length) {
assetsToAccept.push([
bundle,
id
]);
return true;
}
}
function hmrDispose(bundle /*: ParcelRequire */ , id /*: string */ ) {
var cached = bundle.cache[id];
bundle.hotData[id] = {};
if (cached && cached.hot) cached.hot.data = bundle.hotData[id];
if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) {
cb(bundle.hotData[id]);
});
delete bundle.cache[id];
}
function hmrAccept(bundle /*: ParcelRequire */ , id /*: string */ ) {
// Execute the module.
bundle(id);
// Run the accept callbacks in the new version of the module.
var cached = bundle.cache[id];
if (cached && cached.hot && cached.hot._acceptCallbacks.length) cached.hot._acceptCallbacks.forEach(function(cb) {
var assetsToAlsoAccept = cb(function() {
return getParents(module.bundle.root, id);
});
if (assetsToAlsoAccept && assetsToAccept.length) {
assetsToAlsoAccept.forEach(function(a) {
hmrDispose(a[0], a[1]);
});
// $FlowFixMe[method-unbinding]
assetsToAccept.push.apply(assetsToAccept, assetsToAlsoAccept);
}
});
}
},{}],"j4kuM":[function(require,module,exports) {
},{}]},["65hmi","j4kuM"], "j4kuM", "parcelRequire94c2")
//# sourceMappingURL=dist.3464ddca.js.map

1
dist/dist/dist.3464ddca.js.map vendored Normal file

File diff suppressed because one or more lines are too long

4445
dist/dist/index.6d460313.js vendored Normal file

File diff suppressed because it is too large Load diff

1
dist/dist/index.6d460313.js.map vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/dist/index.html vendored Normal file
View file

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en" dir="ltr"><head><meta charset="utf-8"><title>Kusari - Zcash Explorer</title></head><body> <script src="/index.6d460313.js" charset="utf-8"></script> <script src="/dist.3464ddca.js"></script></body></html>

125
dist/index.0958ba2c.css vendored Normal file
View file

@ -0,0 +1,125 @@
:root {
--input-border: #8b8a8b;
--input-focus-h: 245;
--input-focus-s: 100%;
--input-focus-l: 42%;
}
@font-face {
font-family: AtkinsonHyperlegible;
src: url("Atkinson-Hyperlegible-Regular-102.700850d5.eot");
src: url("Atkinson-Hyperlegible-Regular-102.700850d5.eot#iefix") format("embedded-opentype"), url("Atkinson-Hyperlegible-Regular-102a.a57ca607.woff2") format("woff2"), url("Atkinson-Hyperlegible-Regular-102.a0105b4e.woff") format("woff"), url("Atkinson-Hyperlegible-Regular-102.3f5473b4.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: F25Executive;
src: url("F25_Executive.aabe3e61.otf") format("opentype");
font-display: swap;
}
* {
box-sizing: border-box;
}
html {
font-family: AtkinsonHyperlegible, sans-serif;
}
button.btn-primary {
cursor: pointer;
border: none;
padding: 0;
font-family: inherit;
@media screen and (-ms-high-contrast: active) {
& {
border: 2px solid;
}
}
}
button.btn-primary {
color: #fff;
cursor: pointer;
text-align: center;
background-color: green;
border-radius: 8px;
justify-content: center;
align-items: center;
min-width: 10ch;
min-height: 44px;
padding: .25em .75em;
font-family: inherit;
line-height: 1.1;
display: inline-flex;
box-shadow: 0 3px 5px #0000002e;
}
button:disabled {
background-color: gray;
}
.card {
text-align: center;
width: 50%;
margin: auto;
transition: all .3s;
box-shadow: 0 4px 8px #0003;
}
.card:hover {
box-shadow: 0 8px 16px #0003;
}
.bigcard {
text-align: center;
width: 90%;
margin: auto;
transition: all .3s;
box-shadow: 0 4px 8px #0003;
}
.bigcard:hover {
box-shadow: 0 8px 16px #0003;
}
.infocard {
text-align: center;
width: 75%;
margin: auto;
transition: all .3s;
box-shadow: 0 4px 8px #0003;
}
.infocard:hover {
box-shadow: 0 8px 16px #0003;
}
.input {
border: 2px solid var(--input-border);
background-color: #fff;
border-radius: 4px;
padding: .25em .5em;
font-family: inherit;
font-size: max(14px, 1em);
}
th {
border-bottom: 1px dashed #aaa;
font-family: F25Executive, serif;
font-size: 15px;
}
td {
word-wrap: anywhere;
text-align: left;
border-bottom: 1px dashed #aaa;
}
h1, h2, h3, h4, h5 {
font-family: F25Executive, serif;
}
/*# sourceMappingURL=index.0958ba2c.css.map */

1
dist/index.0958ba2c.css.map vendored Normal file
View file

@ -0,0 +1 @@
{"mappings":"AAAA;;;;;;;AAOA;;;;;;;;;AAYA;;;;;;AAMA;;;;AAIA;;;;AAIA;;;;;;EAME;IAA+C;;;;;;AAKjD;;;;;;;;;;;;;;;;;AAiBA;;;;AAIA;;;;;;;;AAQA;;;;AAIA;;;;;;;;AAQA;;;;AAIA;;;;;;;;AAQA;;;;AAIA;;;;;;;;;AAUA;;;;;;AAMA;;;;;;AASA","sources":["dev/main.css"],"sourcesContent":[":root {\n\t--input-border: #8b8a8b;\n\t--input-focus-h: 245;\n\t--input-focus-s: 100%;\n\t--input-focus-l: 42%;\n}\n\n@font-face {\n font-family: 'AtkinsonHyperlegible';\n src: url('./fonts/Atkinson-Hyperlegible-Regular-102.eot');\n src: url('./fonts/Atkinson-Hyperlegible-Regular-102.eot?#iefix') format('embedded-opentype'),\n url('./fonts/Atkinson-Hyperlegible-Regular-102a.woff2') format('woff2'),\n url('./fonts/Atkinson-Hyperlegible-Regular-102.woff') format('woff'),\n url('./fonts/Atkinson-Hyperlegible-Regular-102.ttf') format('truetype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n}\n\n@font-face {\n font-family: 'F25Executive';\n src: url('./fonts/F25_Executive.otf') format('opentype');\n font-display: swap;\n}\n\n* {\n\tbox-sizing: border-box;\n}\n\nhtml {\n\tfont-family: 'AtkinsonHyperlegible', sans-serif;\n}\n\nbutton.btn-primary {\n\tborder: none;\n font-family: inherit;\n padding: 0;\n cursor: pointer;\n\n @media screen and (-ms-high-contrast: active) {\n border: 2px solid currentcolor;\n }\n}\n\nbutton.btn-primary {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tcolor: white;\n\tbackground-color: green;\n\tcursor: pointer;\n\tfont-family: inherit;\n\tborder-radius: 8px;\n box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18);\n\tpadding: 0.25em 0.75em;\n min-width: 10ch;\n min-height: 44px;\n\ttext-align: center;\n\tline-height: 1.1;\n}\n\nbutton:disabled {\n\tbackground-color: gray;\n}\n\n.card {\n\tbox-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\n\ttransition: 0.3s;\n\tmargin: auto;\n\twidth: 50%;\n\ttext-align: center;\n}\n\n.card:hover {\n\tbox-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);\n}\n\n.bigcard {\n\tbox-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\n\ttransition: 0.3s;\n\tmargin: auto;\n\twidth: 90%;\n\ttext-align: center;\n}\n\n.bigcard:hover {\n\tbox-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);\n}\n\n.infocard {\n\tbox-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\n\ttransition: 0.3s;\n\tmargin: auto;\n\twidth: 75%;\n\ttext-align: center;\n}\n\n.infocard:hover {\n\tbox-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);\n}\n\n.input {\n\tfont-size: 14px;\n\tfont-size: max(14px, 1em);\n\tfont-family: inherit;\n\tpadding: 0.25em 0.5em;\n\tbackground-color: #fff;\n\tborder: 2px solid var(--input-border);\n\tborder-radius: 4px;\n}\n\nth {\n\tfont-family: 'F25Executive', serif;\n\tfont-size: 15px;\n\tborder-bottom: 1px dashed #aaa;\n}\n\ntd {\n\tword-wrap: anywhere;\n\ttext-align: left;\n\tborder-bottom: 1px dashed #aaa;\n}\n\ntr {\n}\n\nh1 {\n\tfont-family: 'F25Executive', serif;\n}\n\nh2 {\n\tfont-family: 'F25Executive', serif;\n}\n\nh3 {\n\tfont-family: 'F25Executive', serif;\n}\n\nh4 {\n\tfont-family: 'F25Executive', serif;\n}\n\nh5 {\n\tfont-family: 'F25Executive', serif;\n}\n"],"names":[],"version":3,"file":"index.0958ba2c.css.map","sourceRoot":"/__parcel_source_root/"}

2
dist/index.0de476db.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/index.0de476db.js.map vendored Normal file

File diff suppressed because one or more lines are too long

7902
dist/index.34d20e85.js vendored Normal file

File diff suppressed because it is too large Load diff

1
dist/index.34d20e85.js.map vendored Normal file

File diff suppressed because one or more lines are too long

2
dist/index.a9636e70.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/index.a9636e70.js.map vendored Normal file

File diff suppressed because one or more lines are too long

11483
dist/index.c092d7f2.css vendored Normal file

File diff suppressed because it is too large Load diff

1
dist/index.c092d7f2.css.map vendored Normal file

File diff suppressed because one or more lines are too long

12
dist/index.html vendored Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>exblo - Zcash Explorer</title>
<link rel="stylesheet" href="/index.0958ba2c.css">
<link rel="stylesheet" href="/index.c092d7f2.css">
</head>
<body>
<script src="/index.34d20e85.js" charset="utf-8"></script>
<script src="/dev.ff48a766.js"></script></body>
</html>

2870
dist/remixicon.4832fb0b.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
dist/remixicon.6a8d4c81.eot vendored Normal file

Binary file not shown.

BIN
dist/remixicon.71130c6d.ttf vendored Normal file

Binary file not shown.

BIN
dist/remixicon.ca1aa115.woff2 vendored Normal file

Binary file not shown.

BIN
dist/remixicon.f416f0f4.woff vendored Normal file

Binary file not shown.

6286
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

16
package.json Normal file
View file

@ -0,0 +1,16 @@
{
"private": true,
"devDependencies": {
"parcel": "^2.12.0",
"purescript": "^0.15.15",
"purs-backend-es": "^1.4.2",
"spago": "^0.21.0"
},
"scripts": {
"build": "spago build",
"bundle": "spago bundle-app --to dev/app.js",
"test": "spago test",
"serve": "spago build && parcel serve --open --no-cache --dist-dir dist/ dev/index.html",
"build-prod": "rm -rf dist && mkdir -p dist && cp dev/index.html dist/ && spago bundle-app --to dist/app.js && parcel build prod/index.html"
}
}

105
packages.dhall Normal file
View file

@ -0,0 +1,105 @@
{-
Welcome to your new Dhall package-set!
Below are instructions for how to edit this file for most use
cases, so that you don't need to know Dhall to use it.
## Use Cases
Most will want to do one or both of these options:
1. Override/Patch a package's dependency
2. Add a package not already in the default package set
This file will continue to work whether you use one or both options.
Instructions for each option are explained below.
### Overriding/Patching a package
Purpose:
- Change a package's dependency to a newer/older release than the
default package set's release
- Use your own modified version of some dependency that may
include new API, changed API, removed API by
using your custom git repo of the library rather than
the package set's repo
Syntax:
where `entityName` is one of the following:
- dependencies
- repo
- version
-------------------------------
let upstream = --
in upstream
with packageName.entityName = "new value"
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with halogen.version = "master"
with halogen.repo = "https://example.com/path/to/git/repo.git"
with halogen-vdom.version = "v4.0.0"
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
-------------------------------
### Additions
Purpose:
- Add packages that aren't already included in the default package set
Syntax:
where `<version>` is:
- a tag (i.e. "v4.0.0")
- a branch (i.e. "master")
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
-------------------------------
let upstream = --
in upstream
with new-package-name =
{ dependencies =
[ "dependency1"
, "dependency2"
]
, repo =
"https://example.com/path/to/git/repo.git"
, version =
"<version>"
}
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with benchotron =
{ dependencies =
[ "arrays"
, "exists"
, "profunctor"
, "strings"
, "quickcheck"
, "lcg"
, "transformers"
, "foldable-traversable"
, "exceptions"
, "node-fs"
, "node-buffer"
, "node-readline"
, "datetime"
, "now"
]
, repo =
"https://github.com/hdgarrood/purescript-benchotron.git"
, version =
"v7.0.0"
}
-------------------------------
-}
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.14-20240227/packages.dhall
sha256:c9633eb78193aac138d7debbc907bfedb8f2e3025ef5a874b8dbc1f35b75eef4
in upstream

36
spago.dhall Normal file
View file

@ -0,0 +1,36 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
Need help? See the following resources:
- Spago documentation: https://github.com/purescript/spago
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
When creating a new Spago project, you can use
`spago init --no-comments` or `spago init -C`
to generate this file without the comments in this block.
-}
{ name = "exblo-app"
, dependencies =
[ "aff"
, "affjax"
, "simple-json"
, "affjax-web"
, "console"
, "tailrec"
, "nullable"
, "integers"
, "datetime"
, "formatters"
, "arrays"
, "effect"
, "either"
, "halogen"
, "halogen-subscriptions"
, "maybe"
, "prelude"
, "web-events"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
}

309
src/Exblo/UI.purs Normal file
View file

@ -0,0 +1,309 @@
module Exblo.UI where
import Prelude
import Control.Monad.Rec.Class (forever)
import Simple.JSON (readJSON)
import Affjax.Web as AX
import Affjax.ResponseFormat as AXRF
import Data.Maybe (Maybe(..))
import Data.Either (Either(..))
import Data.Int (toNumber)
import Data.Nullable (Nullable, toMaybe)
import Data.Array (length, foldl)
import Data.Formatter.DateTime as FDT
import Data.DateTime.Instant (toDateTime, instant)
import Effect.Aff (Milliseconds(..))
import Effect.Aff as Aff
import Effect.Aff.Class (class MonadAff)
import Effect.Class.Console (log)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Halogen.Subscription as HS
import Web.Event.Event (Event)
import Web.Event.Event as Event
type Transaction =
{ txid :: String
, height :: Int
, confirmations :: Int
, expiry :: Int
, transparent :: Nullable TBundle
, sapling :: Nullable SBundle
, orchard :: Nullable OBundle
}
type TBundle =
{ vin :: Array TxIn
, vout :: Array TxOut
, coinbase :: Boolean
}
type TxIn =
{ prevoutput :: OutPoint
, inputscript :: String
, sequence :: Number
}
type OutPoint =
{ txid :: String
, index :: Number
}
type TxOut =
{ value :: Int
, outputscript :: String
}
type SBundle =
{ spends :: Array ShieldedSpend
, outputs :: Array ShieldedOutput
, value :: Int
, sig :: String
}
type ShieldedSpend =
{ cv :: String
, anchor :: String
, nullifier :: String
, rk :: String
, proof :: String
, spendAuthSig :: String
}
type ShieldedOutput =
{ cv :: String
, cmu :: String
, ephemeralKey :: String
, encCiphertext :: String
, outCiphertext :: String
, proof :: String
}
type OBundle =
{ actions :: Array OrchardAction
, flags :: Array Boolean
, value :: Int
, anchor :: String
, proof :: String
, sig :: String
}
type OrchardAction =
{ nullifier :: String
, rk :: String
, cmx :: String
, ephemeralKey :: String
, encCiphertext :: String
, outCiphertext :: String
, cv :: String
, spendAuthSig :: String
}
type State =
{ block :: Maybe Int
, loading :: Boolean
, term :: String
, tx :: Maybe Transaction
}
data Action
= Initialize
| Refresh
| Search Event
| SetTerm String
component :: forall q i o m. MonadAff m => H.Component q i o m
component =
H.mkComponent
{ initialState: \_ -> { block: Nothing, loading: false, term: "", tx: Nothing }
, render
, eval: H.mkEval H.defaultEval { handleAction = handleAction, initialize = Just Initialize }
}
render :: forall cs m. State -> H.ComponentHTML Action cs m
render state =
HH.div
[ css "bigcard"
]
[ HH.h1_ [ HH.text "exblo" ]
, HH.div
[ css "card"
]
[ HH.h3_ [ HH.text "latest block" ]
, HH.p_
[ HH.text $
if state.loading then "Loading..."
else case state.block of
Nothing -> "N/A"
Just b -> show b
]
]
, HH.form
[ HE.onSubmit \ev -> Search ev ]
[ HH.p_
[ HH.input
[ css "input"
, HP.value state.term
, HP.placeholder "Search TX ID..."
, HE.onValueInput \str -> SetTerm str
]
, HH.button
[ css "btn-primary raised"
, HP.type_ HP.ButtonSubmit
]
[ HH.i [ css "ri-search-line ri-xl" ] [] ]
]
]
, case state.tx of
Nothing -> HH.p_ [ HH.text "Explore the Zcash blockchain" ]
Just t ->
HH.div
[ css "card" ]
[ HH.table_
[ HH.tr_ [ HH.th_ [ HH.text "tx id" ], HH.td_ [ HH.text t.txid ] ]
, HH.tr_ [ HH.th_ [ HH.text "block" ], HH.td_ [ HH.text (show t.height) ] ]
, HH.tr_ [ HH.th_ [ HH.text "confirmations" ], HH.td_ [ HH.text (show t.confirmations) ] ]
, HH.tr_ [ HH.th_ [ HH.text "expiry" ], HH.td_ [ HH.text (show t.expiry) ] ]
, HH.tr_ [ HH.th_ [ HH.text "fee" ], HH.td_ [ HH.text (show $ sumBundles t.transparent t.sapling t.orchard) ] ]
, case toMaybe t.orchard of
Nothing -> HH.p_ []
Just orc ->
HH.tr_
[ HH.th_ [ HH.text "orchard" ]
, HH.table_
[ HH.tr_
[ HH.th_ [ HH.text "actions" ]
, HH.td_ [ HH.text (show $ length orc.actions) ]
]
, HH.tr_
[ HH.th_ [ HH.text "value" ]
, HH.td_ [ HH.text (show orc.value) ]
]
]
]
, case toMaybe t.sapling of
Nothing -> HH.p_ []
Just sap ->
HH.tr_
[ HH.th_ [ HH.text "sapling" ]
, HH.table_
[ HH.tr_
[ HH.th_ [ HH.text "spends" ]
, HH.td_ [ HH.text (show $ length sap.spends) ]
]
, HH.tr_
[ HH.th_ [ HH.text "outputs" ]
, HH.td_ [ HH.text (show $ length sap.outputs) ]
]
, HH.tr_
[ HH.th_ [ HH.text "value" ]
, HH.td_ [ HH.text (show $ sap.value) ]
]
]
]
, case toMaybe t.transparent of
Nothing -> HH.p_ []
Just transp ->
HH.tr_
[ HH.th_
[ HH.text "transparent"
, if transp.coinbase then HH.i [ css "ri-money-dollar-circle-line ri-xl" ] []
else HH.p_ []
]
, HH.table_
[ HH.tr_
[ HH.th_ [ HH.text "inputs" ]
, HH.td_ [ HH.text (show $ length transp.vin) ]
]
, HH.tr_
[ HH.th_ [ HH.text "outputs" ]
, HH.td_ [ HH.text (show $ length transp.vout) ]
]
, HH.tr_
[ HH.th_ [ HH.text "value" ]
, HH.td_ [ HH.text (show $ foldl (\a b -> a + b.value) 0 transp.vout) ]
]
]
]
]
]
, HH.p_
[ HH.i [ css "ri-copyright-line" ] []
, HH.text "2024 Vergara Technologies LLC"
]
]
handleAction :: forall cs o m. MonadAff m => Action -> H.HalogenM State Action cs o m Unit
handleAction = case _ of
Initialize -> do
_ <- H.subscribe =<< timer Refresh
handleAction Refresh
Refresh -> do
H.modify_ _ { loading = true }
res <- H.liftAff $ AX.get AXRF.string ("https://api.exblo.app/getblock")
case res of
Left err -> do
log $ "/block response failed to decode: " <> AX.printError err
Right response -> do
case readJSON response.body of
Right (i :: Int) ->
H.modify_ _
{ loading = false
, block = Just i
}
Left e -> do
log $ "Can't parse JSON. " <> show e
SetTerm s -> do
H.modify_ _ { term = s }
Search event -> do
H.liftEffect $ Event.preventDefault event
term <- H.gets _.term
H.modify_ _ { loading = true }
res <- H.liftAff $ AX.get AXRF.string ("https://api.exblo.app/gettransaction/" <> term)
case res of
Left err -> do
log $ "/gettransaction response failed to decode: " <> AX.printError err
Right response -> do
case readJSON response.body of
Right (t :: Transaction) ->
H.modify_ _
{ loading = false
, tx = Just t
}
Left e -> do
log $ "Can't parse JSON. " <> show e
convertToDate :: Int -> String
convertToDate secs =
case instant (Milliseconds (toNumber (1000 * secs))) of
Nothing -> "N/A"
Just i ->
case (FDT.formatDateTime "YYYY-DD-MM HH:mm:ss:SSS" <<< toDateTime) i of
Left _e -> "N/A"
Right d -> d
sumBundles :: Nullable TBundle -> Nullable SBundle -> Nullable OBundle -> Int
sumBundles t s o =
( case toMaybe o of
Nothing -> 0
Just orc -> orc.value
)
+
( case toMaybe s of
Nothing -> 0
Just sap -> sap.value
)
timer :: forall m a. MonadAff m => a -> m (HS.Emitter a)
timer val = do
{ emitter, listener } <- H.liftEffect HS.create
_ <- H.liftAff $ Aff.forkAff $ forever do
Aff.delay $ Milliseconds 60000.0
H.liftEffect $ HS.notify listener val
pure emitter
css :: forall r i. String -> HH.IProp (class :: String | r) i
css = HP.class_ <<< HH.ClassName

13
src/Main.purs Normal file
View file

@ -0,0 +1,13 @@
module Main where
import Prelude
import Effect (Effect)
import Halogen.Aff as HA
import Halogen.VDom.Driver (runUI)
import Exblo.UI as UI
main :: Effect Unit
main = HA.runHalogenAff do
body <- HA.awaitBody
runUI UI.component unit body

11
test/Main.purs Normal file
View file

@ -0,0 +1,11 @@
module Test.Main where
import Prelude
import Effect (Effect)
import Effect.Class.Console (log)
main :: Effect Unit
main = do
log "🍝"
log "You should add some tests."