Merge branch 'main' into 'master'

Main 2 master

See merge request hyper-drive/blockcatcher-app!1
This commit is contained in:
Eric Lewellen
2026-01-13 23:38:53 +00:00
36 changed files with 4601 additions and 93 deletions

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.idea/
node_modules/
.vscode/
*.map
.DS_Store
.sourcemaps
dist/

View File

@@ -1,93 +0,0 @@
# Blockcatcher App
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
* [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
* [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.redmaus.io/hyper-drive/blockcatcher-app.git
git branch -M master
git push -uf origin master
```
## Integrate with your tools
* [Set up project integrations](https://gitlab.redmaus.io/hyper-drive/blockcatcher-app/-/settings/integrations)
## Collaborate with your team
* [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
* [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
* [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
* [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
* [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy
Use the built-in continuous integration in GitLab.
* [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
* [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

10
capacitor.config.json Normal file
View File

@@ -0,0 +1,10 @@
{
"appId": "so.blockcatcher.app",
"appName": "Blockcatcher",
"webDir": "dist",
"plugins": {
"SplashScreen": {
"launchAutoHide": false
}
}
}

13
ios/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
App/build
App/Pods
App/output
App/App/public
DerivedData
xcuserdata
# Cordova plugins for Capacitor
capacitor-cordova-ios-plugins
# Generated Config files
App/App/capacitor.config.json
App/App/config.xml

View File

@@ -0,0 +1,424 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
504EC3011FED79650016851F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
isa = PBXGroup;
children = (
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
504EC2FB1FED79650016851F = {
isa = PBXGroup;
children = (
504EC3061FED79650016851F /* App */,
504EC3051FED79650016851F /* Products */,
7F8756D8B27F46E3366F6CEA /* Pods */,
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
);
sourceTree = "<group>";
};
504EC3051FED79650016851F /* Products */ = {
isa = PBXGroup;
children = (
504EC3041FED79650016851F /* App.app */,
);
name = Products;
sourceTree = "<group>";
};
504EC3061FED79650016851F /* App */ = {
isa = PBXGroup;
children = (
50379B222058CBB4000EE86E /* capacitor.config.json */,
504EC3071FED79650016851F /* AppDelegate.swift */,
504EC30B1FED79650016851F /* Main.storyboard */,
504EC30E1FED79650016851F /* Assets.xcassets */,
504EC3101FED79650016851F /* LaunchScreen.storyboard */,
504EC3131FED79650016851F /* Info.plist */,
2FAD9762203C412B000D30F8 /* config.xml */,
50B271D01FEDC1A000F3C39B /* public */,
);
path = App;
sourceTree = "<group>";
};
7F8756D8B27F46E3366F6CEA /* Pods */ = {
isa = PBXGroup;
children = (
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
504EC3031FED79650016851F /* App */ = {
isa = PBXNativeTarget;
buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */;
buildPhases = (
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
504EC3001FED79650016851F /* Sources */,
504EC3011FED79650016851F /* Frameworks */,
504EC3021FED79650016851F /* Resources */,
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
E3424294FACA667401D6F46C /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = App;
productName = App;
productReference = 504EC3041FED79650016851F /* App.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
504EC2FC1FED79650016851F /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0920;
TargetAttributes = {
504EC3031FED79650016851F = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 504EC2FB1FED79650016851F;
productRefGroup = 504EC3051FED79650016851F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
504EC3031FED79650016851F /* App */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
504EC3021FED79650016851F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
50B271D11FEDC1A000F3C39B /* public in Resources */,
504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
504EC30D1FED79650016851F /* Main.storyboard in Resources */,
2FAD9763203C412B000D30F8 /* config.xml in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E3424294FACA667401D6F46C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
504EC3001FED79650016851F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
504EC30B1FED79650016851F /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
504EC30C1FED79650016851F /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
504EC3111FED79650016851F /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
504EC3141FED79650016851F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
504EC3151FED79650016851F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
504EC3171FED79650016851F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 53DK57C7ZF;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
504EC3181FED79650016851F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 53DK57C7ZF;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
isa = XCConfigurationList;
buildConfigurations = (
504EC3141FED79650016851F /* Debug */,
504EC3151FED79650016851F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = {
isa = XCConfigurationList;
buildConfigurations = (
504EC3171FED79650016851F /* Debug */,
504EC3181FED79650016851F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 504EC2FC1FED79650016851F /* Project object */;
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:App.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,49 @@
import UIKit
import Capacitor
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
// Called when the app was launched with a url. Feel free to add additional processing here,
// but if you want the App API to support tracking app url opens, make sure to keep this call
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Called when the app was launched with an activity, including Universal Links.
// Feel free to add additional processing here, but if you want the App API to support
// tracking app url opens, make sure to keep this call
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "AppIcon-512@2x.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "splash-2732x2732-2.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "splash-2732x2732-1.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "splash-2732x2732.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17132" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17105"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<imageView key="view" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" id="snD-IY-ifK">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</imageView>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="Splash" width="1366" height="1366"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14111" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
</dependencies>
<scenes>
<!--Bridge View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

49
ios/App/App/Info.plist Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>Hyperia</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
</dict>
</plist>

27
ios/App/Podfile Normal file
View File

@@ -0,0 +1,27 @@
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
platform :ios, '14.0'
use_frameworks!
# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera'
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
pod 'CapacitorGoogleMaps', :path => '../../node_modules/@capacitor/google-maps'
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
end
target 'App' do
capacitor_pods
# Add your Pods here
end
post_install do |installer|
assertDeploymentTarget(installer)
end

66
ios/App/Podfile.lock Normal file
View File

@@ -0,0 +1,66 @@
PODS:
- Capacitor (7.4.4):
- CapacitorCordova
- CapacitorCamera (7.0.2):
- Capacitor
- CapacitorCordova (7.4.4)
- CapacitorGeolocation (7.1.5):
- Capacitor
- IONGeolocationLib (= 1.0.1)
- CapacitorGoogleMaps (7.2.0):
- Capacitor
- Google-Maps-iOS-Utils (~> 5.0)
- GoogleMaps (~> 8.4)
- CapacitorSplashScreen (7.0.3):
- Capacitor
- Google-Maps-iOS-Utils (5.0.0):
- GoogleMaps (~> 8.0)
- GoogleMaps (8.4.0):
- GoogleMaps/Maps (= 8.4.0)
- GoogleMaps/Base (8.4.0)
- GoogleMaps/Maps (8.4.0):
- GoogleMaps/Base
- IONGeolocationLib (1.0.1)
DEPENDENCIES:
- "Capacitor (from `../../node_modules/@capacitor/ios`)"
- "CapacitorCamera (from `../../node_modules/@capacitor/camera`)"
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
- "CapacitorGeolocation (from `../../node_modules/@capacitor/geolocation`)"
- "CapacitorGoogleMaps (from `../../node_modules/@capacitor/google-maps`)"
- "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)"
SPEC REPOS:
trunk:
- Google-Maps-iOS-Utils
- GoogleMaps
- IONGeolocationLib
EXTERNAL SOURCES:
Capacitor:
:path: "../../node_modules/@capacitor/ios"
CapacitorCamera:
:path: "../../node_modules/@capacitor/camera"
CapacitorCordova:
:path: "../../node_modules/@capacitor/ios"
CapacitorGeolocation:
:path: "../../node_modules/@capacitor/geolocation"
CapacitorGoogleMaps:
:path: "../../node_modules/@capacitor/google-maps"
CapacitorSplashScreen:
:path: "../../node_modules/@capacitor/splash-screen"
SPEC CHECKSUMS:
Capacitor: 09d9ff8e9618e8c4b3cab2bbee34a17215dd2fef
CapacitorCamera: 6e18d54c8ab30d7dc7b8cd93d96f9b4f57e9202a
CapacitorCordova: bf648a636f3c153f652d312ae145fb508b6ffced
CapacitorGeolocation: b96474c3259dd4a294227ea8ec19140b1837cceb
CapacitorGoogleMaps: 20b5445a532f80dbb120fa99941fd094bcc88af6
CapacitorSplashScreen: d06ae8804808e9f649a08e7bb7f283c77b688084
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
IONGeolocationLib: 20f9d0248a0b5264511fb57a37e25dd2badf797a
PODFILE CHECKSUM: 1f8c41a3cb5e4540693adb6a47064e328eec261d
COCOAPODS: 1.15.2

2275
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

29
package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "capacitor-app",
"version": "1.0.0",
"description": "An Amazing Capacitor App",
"type": "module",
"keywords": [
"capacitor",
"mobile"
],
"scripts": {
"start": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@capacitor/camera": "latest",
"@capacitor/core": "latest",
"@capacitor/geolocation": "^7.1.5",
"@capacitor/google-maps": "^7.2.0",
"@capacitor/ios": "^7.4.4",
"@capacitor/splash-screen": "latest"
},
"devDependencies": {
"@capacitor/cli": "latest",
"vite": "^5.4.2"
},
"author": "",
"license": "ISC"
}

1186
src/_/code/quill.js Normal file

File diff suppressed because one or more lines are too long

12
src/_/code/styles.css Normal file
View File

@@ -0,0 +1,12 @@
:root {
--main: #AEBDFF;
--accent: #60320c;
--text: #340000;
--yellow: #f1f3c3;
}
@media (prefers-color-scheme: dark) {
:root {
}
}

BIN
src/_/icons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100px" height="100px"><path d="M 17 21 A 1.0001 1.0001 0 0 0 16 22 L 16 32 A 1.0001 1.0001 0 0 0 17 33 L 83 33 A 1.0001 1.0001 0 0 0 84 32 L 84 22 A 1.0001 1.0001 0 0 0 83 21 L 17 21 z M 18 23 L 82 23 L 82 31 L 18 31 L 18 29 L 73.5 29 A 0.50005 0.50005 0 1 0 73.5 28 L 18 28 L 18 23 z M 76.5 28 A 0.50005 0.50005 0 1 0 76.5 29 L 78.5 29 A 0.50005 0.50005 0 1 0 78.5 28 L 76.5 28 z M 17 44 A 1.0001 1.0001 0 0 0 16 45 L 16 55 A 1.0001 1.0001 0 0 0 17 56 L 83 56 A 1.0001 1.0001 0 0 0 84 55 L 84 45 A 1.0001 1.0001 0 0 0 83 44 L 17 44 z M 18 46 L 82 46 L 82 54 L 18 54 L 18 46 z M 22.5 51 A 0.50005 0.50005 0 1 0 22.5 52 L 67.5 52 A 0.50005 0.50005 0 1 0 67.5 51 L 22.5 51 z M 70.5 51 A 0.50005 0.50005 0 1 0 70.5 52 L 73.5 52 A 0.50005 0.50005 0 1 0 73.5 51 L 70.5 51 z M 76.5 51 A 0.50005 0.50005 0 1 0 76.5 52 L 78.5 52 A 0.50005 0.50005 0 1 0 78.5 51 L 76.5 51 z M 17 67 A 1.0001 1.0001 0 0 0 16 68 L 16 78 A 1.0001 1.0001 0 0 0 17 79 L 83 79 A 1.0001 1.0001 0 0 0 84 78 L 84 68 A 1.0001 1.0001 0 0 0 83 67 L 17 67 z M 18 69 L 82 69 L 82 74 L 26.5 74 A 0.50005 0.50005 0 1 0 26.5 75 L 82 75 L 82 77 L 18 77 L 18 69 z M 21.5 74 A 0.50005 0.50005 0 1 0 21.5 75 L 23.5 75 A 0.50005 0.50005 0 1 0 23.5 74 L 21.5 74 z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

0
src/_/icons/play.svg Normal file
View File

71
src/_/icons/runner.svg Normal file
View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 511.697 511.697" xml:space="preserve">
<g transform="translate(0 1)">
<g>
<path style="fill:#FFE100;" d="M505.189,119.472L505.189,119.472c-7.81-7.81-13.885-9.546-21.695-1.736l-45.125,45.993
c-6.075,6.075-14.753,6.075-20.827,0.868l-63.349-59.01c-4.339-4.339-10.414-6.942-16.488-6.942h-94.59l-79.837,75.498
c-7.81,7.81-9.546,21.695-1.736,30.373c8.678,9.546,22.563,8.678,31.241,0l59.01-62.481h43.39L147.656,306.916H62.612
c-13.885,0-26.902,10.414-27.769,24.298c-0.868,15.62,11.281,27.77,26.034,27.77H165.88c10.414,0,19.959-4.339,27.77-12.149
l57.275-61.614l61.614,65.085L296.05,456.177c-2.603,12.149,2.603,25.166,13.885,30.373c15.62,6.942,32.108-1.736,36.447-17.356
l25.166-135.376c0.868-6.075-0.868-11.281-5.207-15.62l-71.159-72.027l69.424-69.424l45.993,45.993
c7.81,7.81,21.695,7.81,29.505,0l19.959-19.959l45.125-52.068C513.867,142.035,513.867,128.15,505.189,119.472"/>
<path style="fill:#FFE100;" d="M462.667,118.605l-0.868-0.868c-7.81-7.81-1.736-7.81-10.414,0l-34.712,45.993
c-6.075,6.075-14.753,6.075-20.827,0.868l-73.763-59.01c-4.339-4.339-4.339-6.942-10.414-6.942h-68.556l-79.837,75.498
c-7.81,7.81-9.546,21.695-1.736,30.373c8.678,9.546,4.339,8.678,12.149,0l60.746-62.481h34.712L121.623,306.916h-59.01
c-13.885,0-26.902,10.414-27.769,24.298c-0.868,15.62,11.281,27.77,26.034,27.77h95.458l69.424-72.895l60.746,64.217
l-16.488,105.871c-2.603,12.149,2.603,25.166,13.885,30.373c15.62,6.942,16.488-1.736,19.959-17.356l20.827-144.922
l-55.539-78.102l63.349-69.424l40.786,45.993c7.81,7.81,18.224-3.471,26.034-11.281l8.678-8.678l54.671-54.671
C470.477,140.299,470.477,126.415,462.667,118.605"/>
</g>
<g>
<path style="fill:#FFA800;" d="M323.819,324.272l-20.827,144.922c-2.603,11.281-3.471,19.092-10.414,19.959
c12.149,0.868,23.431-7.81,26.034-19.959l27.77-144.922l-77.234-77.234L323.819,324.272z"/>
<path style="fill:#FFA800;" d="M487.833,118.605l-0.868-0.868c-7.81-7.81-19.092-7.81-27.77-1.736
c0.868,0.868,0.868,0.868,1.736,1.736l0.868,0.868c7.81,7.81,7.81,20.827,0,29.505l-54.671,54.671l-8.678,8.678
c-4.339,4.339-8.678,9.546-13.885,12.149c7.81,6.942,20.827,6.942,28.637-0.868l19.959-19.959l54.671-54.671
C495.643,140.299,495.643,127.282,487.833,118.605"/>
</g>
<g>
<path style="fill:#FFFFFF;" d="M163.277,207.12c-0.868-0.868-1.736-1.736-2.603-2.603c-7.81-8.678-6.942-21.695,1.736-30.373
l80.705-75.498H217.08l-79.837,75.498c-7.81,7.81-9.546,21.695-1.736,30.373S155.467,213.194,163.277,207.12"/>
<path style="fill:#FFFFFF;" d="M34.843,331.215c0.868-13.885,13.017-24.298,26.902-24.298H35.711
c-13.885,0-26.902,10.414-27.769,24.298c0,15.62,12.149,27.77,26.902,27.77h26.034C46.124,358.984,33.975,346.835,34.843,331.215"
/>
</g>
<path style="fill:#FFE100;" d="M425.351,63.933c0-24.298-19.092-43.39-43.39-43.39c-0.868,0-26.034,19.092-26.034,43.39
c0,0.868,1.736,43.39,26.034,43.39C406.26,107.323,425.351,88.232,425.351,63.933"/>
<g>
<path style="fill:#FFA800;" d="M399.318,20.543c-2.603,0-6.075,0-8.678,0.868c19.959,4.339,34.712,21.695,34.712,42.522
s-14.753,38.183-34.712,42.522c2.603,0.868,6.075,0.868,8.678,0.868c24.298,0,43.39-19.092,43.39-43.39
S423.616,20.543,399.318,20.543"/>
<path style="fill:#FFA800;" d="M356.795,71.743c0,0.868,0,0.868,0,1.736C356.795,72.611,356.795,71.743,356.795,71.743"/>
</g>
<path d="M295.182,497.832c-5.207,0-9.546-0.868-14.753-3.471c-14.753-6.942-23.431-23.431-19.092-40.786l15.62-100.664
l-52.068-54.671l-62.481,66.82c-1.736,1.736-3.471,2.603-6.075,2.603H34.843c-9.546,0-18.224-4.339-25.166-10.414
c-6.942-6.942-10.414-16.488-9.546-26.034c0.868-18.224,16.488-32.976,36.447-32.976h81.573l32.108-35.58
c3.471-3.471,8.678-3.471,12.149-0.868c3.471,3.471,3.471,8.678,0.868,12.149l-34.712,39.051c-2.603,1.736-4.339,2.603-6.942,2.603
H36.579c-10.414,0-19.092,6.942-19.092,16.488c0,5.207,1.736,9.546,4.339,13.017c3.471,3.471,7.81,5.207,13.017,5.207h118.02
l65.953-70.292c1.736-1.736,4.339-2.603,6.075-2.603c2.603,0,4.339,0.868,6.075,2.603l61.614,64.217
c1.736,1.736,2.603,4.339,2.603,6.942l-16.488,105.871c-1.736,9.546,1.736,18.224,9.546,21.695c5.207,2.603,10.414,1.736,14.753,0
c4.339-2.603,7.81-6.942,9.546-11.281l26.034-139.715l-74.63-74.631c-2.603-2.603-3.471-4.339-3.471-6.942
c0-2.603,0.868-4.339,2.603-6.075l69.424-69.424c3.471-3.471,8.678-3.471,12.149,0l45.993,45.993
c4.339,4.339,12.149,4.339,17.356,0l74.63-74.631c4.339-4.339,4.339-12.149,0-16.488l-0.868-0.868
c-5.207-5.207-13.017-5.207-17.356,0l-45.125,45.993c-8.678,8.678-23.431,9.546-32.976,0.868l-63.349-59.01
c-2.603-2.603-6.942-4.339-10.414-4.339h-91.986l-77.234,73.763c-5.207,5.207-5.207,13.017-0.868,18.224
c2.603,2.603,6.075,4.339,9.546,4.339l0,0c3.471,0,6.942-1.736,8.678-4.339l59.01-62.481c1.736-1.736,4.339-2.603,6.075-2.603
h43.39c3.471,0,6.942,1.736,7.81,5.207s0.868,6.942-1.736,9.546l-69.424,78.102c-3.471,3.471-8.678,4.339-12.149,0.868
c-3.471-3.471-3.471-8.678-0.868-12.149l56.407-63.349h-19.959l-56.407,59.878c-5.207,6.075-13.017,9.546-21.695,9.546l0,0
c-8.678,0-16.488-3.471-21.695-9.546c-10.414-11.281-9.546-30.373,1.736-42.522l79.837-76.366c1.736-3.471,3.471-4.339,6.075-4.339
h94.59c8.678,0,16.488,3.471,22.563,8.678l63.349,59.01c2.603,2.603,6.075,2.603,8.678,0l45.125-45.993
c11.281-11.281,30.373-11.281,42.522,0l0.868,0.868c11.281,11.281,11.281,30.373,0,41.654l-74.63,74.631
c-11.281,11.281-30.373,11.281-41.654,0l-39.919-39.919l-57.275,57.275l72.027,72.027c1.736,1.736,2.603,5.207,2.603,7.81
L329.026,470.93c-2.603,10.414-9.546,19.092-18.224,23.431C305.595,496.964,300.389,497.832,295.182,497.832z"/>
<path d="M187.575,241.832c0-5.207-3.471-8.678-8.678-8.678s-8.678,3.471-8.678,8.678s3.471,8.678,8.678,8.678
S187.575,247.038,187.575,241.832"/>
<path d="M399.318,116.001c-28.637,0-52.068-23.431-52.068-52.068s23.431-52.068,52.068-52.068
c28.637,0,52.068,23.431,52.068,52.068S427.955,116.001,399.318,116.001z M399.318,29.221c-19.092,0-34.712,15.62-34.712,34.712
s15.62,34.712,34.712,34.712c19.092,0,34.712-15.62,34.712-34.712S418.409,29.221,399.318,29.221z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

0
src/_/icons/stop.svg Normal file
View File

BIN
src/_/imgs/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

12
src/css/style.css Normal file
View File

@@ -0,0 +1,12 @@
html,
body {
padding: 0;
margin: 0;
}
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}

31
src/index.html Normal file
View File

@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Blockcatcher</title>
<meta
name="viewport"
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<script
type="module"
src="https://unpkg.com/@ionic/pwa-elements@latest/dist/ionicpwaelements/ionicpwaelements.esm.js"
></script>
<script
nomodule
src="https://unpkg.com/@ionic/pwa-elements@latest/dist/ionicpwaelements/ionicpwaelements.js"
></script>
<link rel="icon" type="image/x-icon" href="./_/icons/runner.svg" />
<link rel="manifest" href="./manifest.json" />
<link rel="stylesheet" href="./_/code/styles.css" />
<script src="./_/code/quill.js"></script>
<script type="module" src="./index.js"></script>
<meta name="theme-color" content="#31d53d" />
</head>
<body>
</body>
</html>

3
src/index.js Normal file
View File

@@ -0,0 +1,3 @@
import "./js/Home.js"
Home()
document.body.style.backgroundColor = "var(--main)"

197
src/js/Home.js Normal file
View File

@@ -0,0 +1,197 @@
class Home extends Shadow {
tracking = false
logs = []
timer = null
async startTracking() {
if (!navigator.geolocation) {
alert("Geolocation is not supported by your browser.");
return;
}
this.tracking = true
navigator.geolocation.requestPermission?.() || Promise.resolve('granted');
const permission = await new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(
() => resolve('granted'),
() => resolve('denied')
);
});
if (permission === 'denied') {
alert("Location permission required");
this.tracking = false
return;
}
const timer = setInterval(async () => {
navigator.geolocation.getCurrentPosition(
async (pos) => {
const { latitude, longitude } = pos.coords;
const now = new Date();
const log = `${now.toISOString()} — (${latitude}, ${longitude})`;
const timestamp = this.formatCentralTime(now);
this.logs = [log, ...this.logs]
this.updateLogs()
await this.sendLocation(latitude, longitude, timestamp);
},
(err) => console.error("Location error:", err),
{ enableHighAccuracy: true }
);
}, 1000);
this.timer = timer
}
stopTracking() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
this.tracking = false;
}
}
render() {
ZStack(() => {
// Title bar
HStack(() => {
img("./_/icons/runner.svg", "2em", "2em")
p("San Marcos, TX")
.fontSize(1.2, em)
img("./_/icons/hamburger.svg", "2em", "2em")
})
.gap(15, vw)
.position("fixed")
.top(0)
.left(0)
.width(100, vw)
.paddingTop(2, em)
.paddingBottom(2, em)
.borderBottom("0.1rem solid var(--text)")
.backgroundColor("var(--yellow)")
.fontWeight("bold")
.display("flex")
.alignItems("center")
.justifyContent("center")
.zIndex(10)
VStack(() => {
button(() => {
if(this.tracking) {
Rectangle("48%", "48%")
.fill("#264B61")
.stroke("0.2em", "black")
} else {
Triangle("58%", "58%")
.fill("#9F292B")
.stroke("0.2em", "black")
}
})
.attr({"id": "playButton"})
.width(120, px)
.height(120, px)
.x(50, vw).y(50, vh)
.center()
.borderRadius(50, "%")
.backgroundColor(this.tracking ? "#CD593E" : "#A6EABD")
.border("0.2em solid black")
.cursor("pointer")
.display("flex")
.alignItems("center")
.justifyContent("center")
.onTap(() => {
console.log("tapped")
if (this.tracking) {
this.stopTracking();
this.rerender()
} else {
this.startTracking();
this.rerender()
}
})
VStack(() => {
this.logs.map(log =>
div(log)
.paddingHorizontal("8px")
.paddingVertical("12px")
.backgroundColor("rgba(255,255,255,0.9)")
.borderRadius(6, px)
.marginBottom(6, px)
.fontSize(0.9, rem)
.color("#222")
.fontFamily("monospace")
)
})
.attr({"id": "logList"})
.flex(1)
.overflowY("auto")
.paddingHorizontal(16, px)
})
.marginTop(7, em)
})
.overflowX("hidden")
.width(100, vw)
.height(100, vh)
.display("block")
.margin(0)
.color("var(--text)")
.fontFamily("Arial")
}
showTracking() {
this.$("#playButton").rerender()
this.$("#playButton").style.backgroundColor = this.tracking ? "#CD593E" : "#A6EABD"
}
updateLogs() {
let list = this.$("#logList")
list.rerender()
list.attr({"id": "logList"})
}
formatCentralTime(date) {
return new Intl.DateTimeFormat('en-US', {
timeZone: 'America/Chicago',
month: '2-digit',
day: '2-digit',
year: '2-digit',
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: true
})
.format(date)
.replace(/,/, '') // "04/05/25, 2:30:00 PM" → "04/05/25 2:30:00 PM"
.replace(/\//g, '.') // → "04.05.25 2:30:00 PM"
.toLowerCase()
.replace(' pm', 'pm')
.replace(' am', 'am');
}
async sendLocation(lat, lon, timestamp) {
try {
const resp = await fetch('http://localhost:3008/api/location', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: "Freddy Krueger",
latitude: lat,
longitude: lon,
timestamp
})
});
if (!resp.ok) throw new Error(resp.status);
console.log('Location sent');
} catch (e) {
console.error('Failed to send location:', e);
}
}
}
register(Home)

13
src/manifest.json Normal file
View File

@@ -0,0 +1,13 @@
{
"name": "App",
"short_name": "App",
"start_url": "index.html",
"display": "standalone",
"icons": [{
"src": "_/imgs/logo.png",
"sizes": "512x512",
"type": "image/png"
}],
"background_color": "#31d53d",
"theme_color": "#31d53d"
}

14
vite.config.ts Normal file
View File

@@ -0,0 +1,14 @@
import { defineConfig } from 'vite';
export default defineConfig({
root: './src',
build: {
outDir: '../dist',
minify: false,
emptyOutDir: true,
},
server: {
host: true,
allowedHosts: ['sam.local'],
}
});