Compare commits

...

33 Commits

Author SHA1 Message Date
Skylar Ittner b631561620 Remove URL handler 4 months ago
Skylar Ittner 8dea193917 Don't throw errors in console if Matomo isn't loaded 4 months ago
Skylar Ittner 4c68c14293 Remove money stuff (bloat--) 4 months ago
Skylar Ittner 25c27cb405 Bump app version to 2.1.0 4 months ago
Skylar Ittner 2031639623 Add locations map, add kiosks, remove crypto/money orders, text tweaks 4 months ago
Skylar Ittner ee42e8aeb3 Bump version to 2.0.5 and fix iOS App Store nonsense 9 months ago
Skylar Ittner 06c691aef2 Adjustments 10 months ago
Skylar Ittner 3e87c8f9b5 Don't require camera autofocus or flash or gps 10 months ago
Skylar Ittner e7512b73e4 Don't require camera autofocus or flash or gps 10 months ago
Skylar Ittner ef73d0b0c2 Don't require camera autofocus or flash or gps 10 months ago
Skylar Ittner 7238a86898 Don't require camera autofocus or flash 10 months ago
Skylar Ittner f23fc2417d Change Drop and Send time warning to 3PM since Helena PO critical entry moved an hour earlier 10 months ago
Skylar Ittner e0a2e91b85 Remove labelmaker.js reference 10 months ago
Skylar Ittner 2f54dbe032 Hide PostalPoint from menu 10 months ago
Skylar Ittner 0244e9e333 Fix two Quick Send bugs 11 months ago
Skylar Ittner e9950a222d Add PostalPoint page 11 months ago
Skylar Ittner c5923625c3 Organize and update link handler code 11 months ago
Skylar Ittner f2463d021d Handle Helena Express deep links with the home page barcode scanner 11 months ago
Skylar Ittner ed1f4dddcf Handle opening tracking URLs in receipts 11 months ago
Skylar Ittner 8e64fdfe62 Text and URL adjustments, handle more website URLs 11 months ago
Skylar Ittner 89df54c1fe Add account number to quick send 11 months ago
Skylar Ittner 35fbcca41b New more better quick send 11 months ago
Skylar Ittner f25a2a07db Cache dynamic content for eight hours, not one 11 months ago
Skylar Ittner 78f4c4992f Remove loyalty info since nobody's ever cashed it in anyways 11 months ago
Skylar Ittner f5d9bef01a Add note that prepaid pickups may cost extra 11 months ago
Skylar Ittner 8034957b31 Update API endpoints to use apis.helena.express 1 year ago
Skylar Ittner 9b77b8e8a0 Remove regional rate options 1 year ago
Skylar Ittner 7c2ca1d16c Bump version to 2.0.4 1 year ago
Skylar Ittner d5e270ecfa Set country zoom level to 3 1 year ago
Skylar Ittner db909f5a27 Update copyright year 1 year ago
Skylar Ittner 5285f6445f Support country-level map zoom on tracking page 1 year ago
Skylar Ittner 148f38d9d9 Add "quick send" for customers to present address info at trailer 1 year ago
Skylar Ittner b56c8dbe3f Fetch dynamically-updating text from server, add FAQ to money order page 1 year ago

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.netsyms.helenaexpress.app" version="2.0.3" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<widget id="com.netsyms.helenaexpress.app" version="2.1.0" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name short="Helena Express">Helena Express</name>
<description>
</description>
@ -51,6 +51,12 @@
<icon background="res/android/drawable/ic_launcher_background.xml" density="xxxhdpi" foreground="res/android/drawable/ic_launcher_foreground.xml" src="res/android/mipmap-xxxhdpi/ic_launcher.png" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="AndroidXEnabled" value="true" />
<!-- Don't exclude devices with very cheap cameras like Kindle Fire tablets -->
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
</config-file>
</platform>
<platform name="ios">
<preference name="StatusBarOverlaysWebView" value="false" />
@ -66,6 +72,9 @@
<edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
<string>Your location is used to show your position on maps. It does not leave your device.</string>
</edit-config>
<edit-config file="*-Info.plist" mode="merge" target="NSLocationAlwaysAndWhenInUseUsageDescription">
<string>Your location is used to show your position on maps. It does not leave your device.</string>
</edit-config>
<config-file target="*-Info.plist" parent="ITSAppUsesNonExemptEncryption" mode="add">
<false/>
</config-file>

@ -1,269 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
Generated file; DO NOT EDIT.
-->
<project name="PackageNotice" basedir="..">
<property file="nbproject/configs/${config}.properties" />
<scriptdef name="checkVersion" language="javascript">
<attribute name="first" />
<attribute name="property" />
<![CDATA[
var first = attributes.get("first");
if (first >= "3.0.0") {
project.setProperty(attributes.get("property"), true);
}
]]>
</scriptdef>
<scriptdef name="forDevice" language="javascript">
<![CDATA[
var dev = project.getProperty("device");
if (dev == "device") {
project.setProperty("build.for.device", true);
}
]]>
</scriptdef>
<target name="check-cordova-project">
<condition property="cordova.project">
<or>
<available file=".cordova"/>
<available file="hooks"/>
</or>
</condition>
</target>
<target name="upgrade-to-cordova-project" depends="check-cordova-project,check-cordova-version" unless="cordova.project">
<echo level="info" message="${cordova.command} -d create ${java.io.tmpdir}/nb_temp_project com.coolappz.${project.name} ${project.name}" />
<delete dir="${java.io.tmpdir}/nb_temp_project"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true" >
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="create"/>
<arg value="${java.io.tmpdir}/nb_temp_project"/>
<arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" />
</exec>
<copy todir="." overwrite="true" failonerror="false">
<fileset dir="${java.io.tmpdir}/nb_temp_project"/>
</copy>
<delete dir="${java.io.tmpdir}/nb_temp_project"/>
<delete dir="www"/>
<copy todir="www" failonerror="false" quiet="true" >
<fileset dir="${site.root}"/>
</copy>
</target>
<target name="create-hello-world" depends="check-cordova-version">
<echo level="info" message="${cordova.command} -d create www_nb_temp com.coolappz.${project.name} ${project.name}" />
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="create"/>
<arg value="www_nb_temp"/>
<arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" />
</exec>
<delete dir="www"/>
<mkdir dir="www"/>
<move file="www_nb_temp/www" tofile="www"/>
<delete dir="www_nb_temp"/>
<delete file="www/config.xml"/>
</target>
<taskdef
classname="org.netbeans.modules.cordova.updatetask.ReadConfigTask"
classpath="${update.task.jar}"
name="readconfig"/>
<taskdef
classname="org.netbeans.modules.cordova.updatetask.PluginTask"
classpath="${update.task.jar}"
name="plugintask"/>
<target name="check-cordova-version">
<property environment="env"/>
<checkVersion first="${cordova.version}" property="cordova.ver.3"/>
<fail message="Cordova version 3 or greater required." unless="cordova.ver.3"/>
<readconfig/>
<forDevice/>
</target>
<target name="check-android-template">
<available file="platforms/android" property="android.generated.exists"/>
</target>
<target name="check-ios-template">
<available file="platforms/ios" property="ios.generated.exists"/>
</target>
<target name="create-android" depends="check-android-template,check-cordova-version,upgrade-to-cordova-project" unless="android.generated.exists">
<echo level="info" message="${cordova.command} -d platform add android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="android"/>
</exec>
</target>
<target name="create-ios" depends="check-ios-template,check-cordova-version,upgrade-to-cordova-project" unless="ios.generated.exists">
<echo level="info" message="${cordova.command} -d platform add ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" dir="." failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="ios"/>
</exec>
</target>
<target name="rebuild-ios" depends="clean-ios,build-ios"/>
<target name="build-ios" depends="create-ios,update-plugins,update-ios,build-ios-xcodebuild,build-ios-ipa"/>
<target name="build-ios-xcodebuild">
<property name="path" location="platforms/ios/build"/>
<exec executable="xcodebuild" dir="platforms/ios" failonerror="true">
<arg value="-project"/>
<arg value="${project.name}.xcodeproj"/>
<arg value="ARCHS=${ios.build.arch}"/>
<arg value="-target"/>
<arg value="${project.name}"/>
<arg value="-configuration"/>
<arg value="Release"/>
<arg value="-sdk"/>
<arg value="${ios.build.sdk}" />
<arg value="build"/>
<arg value="CONFIGURATION_BUILD_DIR=${path}"/>
</exec>
</target>
<target name="build-ios-ipa" if="build.for.device">
<exec executable="xcrun" dir="platforms/ios/build" failonerror="true">
<env key="CODESIGN_ALLOCATE" value="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate" />
<arg value="-sdk"/>
<arg value="${ios.build.sdk}" />
<arg value="PackageApplication"/>
<arg value="-v"/>
<arg value="${project.name}.app"/>
<arg value="-o"/>
<arg value="${basedir}/platforms/ios/build/${project.name}.ipa"/>
<arg value="--sign"/>
<arg value="${ios.certificate.name}"/>
<arg value="--embed"/>
<arg value="${ios.provisioning.profile}"/>
</exec>
<available file="${basedir}/platforms/ios/build/${project.name}.ipa" property="ipa.found"/>
<fail unless="ipa.found" message="PackageApplication failed."/>
</target>
<target name="sim-ios" depends="build-ios,ios-run-device,ios-run-simulator">
</target>
<target name="ios-run-device" if="build.for.device">
<echo>
Install "${basedir}/platforms/ios/build/${project.name}.ipa" through iTunes and run it.
</echo>
<exec executable="open" failonerror="true">
<arg value="${basedir}/platforms/ios/build/${project.name}.ipa"/>
</exec>
</target>
<target name="ios-run-simulator" unless="build.for.device">
<exec executable="killall" dir="platforms/ios/build">
<arg value="launchd_sim"/>
</exec>
<exec executable="${ios.sim.exec}" dir="platforms/ios/build">
<arg line="launch ${project.name}.app ${ios.device.args} --exit"/>
</exec>
</target>
<target name="update-plugins">
<plugintask/>
</target>
<target name="update-android">
<echo level="info" message="${cordova.command} prepare android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="prepare"/>
<arg value="android"/>
</exec>
</target>
<target name="update-ios">
<echo level="info" message="${cordova.command} prepare ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="prepare"/>
<arg value="ios"/>
</exec>
</target>
<target name="rebuild-android" depends="clean-android,build-android"/>
<target name="build-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d build android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="build"/>
<arg value="android"/>
</exec>
</target>
<target name="sim-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d ${android.target.device.arg} android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="${android.target.device.arg}"/>
<arg value="android"/>
</exec>
</target>
<target name="clean-android" depends="check-android-template" if="android.generated.exists">
<exec executable="./gradlew" dir="platforms/android">
<arg value="clean" />
</exec>
</target>
<target name="clean-ios" depends="check-ios-template" if="ios.generated.exists">
<exec executable="platforms/ios/cordova/clean" />
</target>
</project>

@ -1,3 +0,0 @@
device=emulator
display.name=Android Emulator
type=android

@ -1,3 +0,0 @@
device=device
display.name=Android Device
type=android

@ -1,5 +0,0 @@
device=emulator
display.name=iPhone Simulator
ios.build.arch=i386
ios.build.sdk=
type=ios

@ -1,5 +0,0 @@
device=device
display.name=iPhone Device
ios.build.arch=armv7 armv7s
ios.build.sdk=
type=ios

@ -1,9 +0,0 @@
<#if licenseFirst??>
${licenseFirst}
</#if>
${licensePrefix}This Source Code Form is subject to the terms of the Mozilla Public
${licensePrefix}License, v. 2.0. If a copy of the MPL was not distributed with this
${licensePrefix}file, You can obtain one at http://mozilla.org/MPL/2.0/.
<#if licenseLast??>
${licenseLast}
</#if>

@ -1,48 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# This is a list of plugins installed in your project
# You can delete or add new plugins
#
# Format is following:
# id.of.plugin=url_of_repository
#
# Corresponding "id.of.plugin" can be found in the plugin's plugin.xml file:
# <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="foo.bar.plugin" version="0.0.1">
#
# This list contains all core cordova plugins.
#
# For more information about plugins see http://cordova.apache.org/blog/releases/2013/07/23/cordova-3.html
#
cordova-plugin-device=https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git
cordova-plugin-network-information=https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git
cordova-plugin-battery-status=https://git-wip-us.apache.org/repos/asf/cordova-plugin-battery-status.git
cordova-plugin-device-motion=https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git
cordova-plugin-device-orientation=https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-orientation.git
cordova-plugin-geolocation=https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git
cordova-plugin-camera=https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git
cordova-plugin-media-capture=https://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture.git
cordova-plugin-media=https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git
cordova-plugin-file=https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git
cordova-plugin-file-transfer=https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git
cordova-plugin-dialogs=https://git-wip-us.apache.org/repos/asf/cordova-plugin-dialogs.git
cordova-plugin-vibration=https://git-wip-us.apache.org/repos/asf/cordova-plugin-vibration.git
cordova-plugin-contacts=https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git
cordova-plugin-globalization=https://git-wip-us.apache.org/repos/asf/cordova-plugin-globalization.git
cordova-plugin-splashscreen=https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git
cordova-plugin-console=https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git

@ -1,9 +1,4 @@
auxiliary.org-netbeans-modules-cordova.cordova_5f_build_5f_script_5f_version=52
auxiliary.org-netbeans-modules-cordova.phonegap=true
auxiliary.org-netbeans-modules-javascript-nodejs.run_2e_enabled=false
browser.run=true
file.reference.HelenaExpress-www=www
files.encoding=UTF-8
project.licensePath=./nbproject/license-mpl.txt
site.root.folder=${file.reference.HelenaExpress-www}
start.file=index.html
source.folder=

@ -3,7 +3,7 @@
<type>org.netbeans.modules.web.clientproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
<name>Helena Express App</name>
<name>com.netsyms.helenaexpress.app</name>
</data>
</configuration>
</project>

2
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "com.netsyms.helenaexpress.app",
"version": "2.0.3",
"version": "2.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {

@ -1,7 +1,7 @@
{
"name": "com.netsyms.helenaexpress.app",
"displayName": "Helena Express",
"version": "2.0.3",
"version": "2.1.0",
"description": "App to request and track shipping services",
"product_string": "Helena Express",
"main": "www/index.html",

@ -63,6 +63,18 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
background-color: rgba(0,0,0,0.95);
}
.hidden-light {
display: none;
}
.dark .hidden-dark {
display: none;
}
.dark .hidden-light {
display: initial;
}
.navbar, .navbar-bg, .subnavbar, .subnavbar *, .subnavbar .searchbar-inner .searchbar-input-wrap * {
background-color: var(--solid-translucent-color);
}
@ -199,4 +211,18 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
max-height: 40vh;
max-width: 90%;
height: 50rem;
}
dl {
margin-left: 1rem;
margin-right: 1rem;
}
dt {
font-weight: 700;
}
dd {
margin-left: 1rem;
margin-bottom: .5rem;
}

@ -57,6 +57,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
:root {
--location-map-height: calc(100vh - calc(var(--f7-navbar-height) + var(--f7-toolbar-height)));
}
.md, .aurora {
--service-area-map-height: calc(100vh - calc(var(--f7-navbar-height) + var(--f7-toolbar-height)));
}
@ -70,6 +74,22 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
height: var(--service-area-map-height);
}
#mapbox-locations {
width: 100%;
height: var(--location-map-height);
}
#locationInfoModal .sheet-modal-inner {
overflow-y: auto;
}
#locationInfoModalContainer {
margin-top: 1em;
}
#mapbox-locations.sheet-open {
height: calc(var(--location-map-height) - var(--f7-sheet-height));
}
/*

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81.953mm" height="17.496mm" version="1.1" viewBox="0 0 81.953 17.496" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<defs>
<clipPath id="clipPath965">
<rect x="73.099" y="121.75" width="66.791" height=".70158" fill="#2196f3" style="paint-order:normal"/>
</clipPath>
</defs>
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-49.738 -106.82)">
<g transform="translate(-7.3027 -5.9991)">
<g stroke-width=".26458px">
<g aria-label="PostalPoint">
<path d="m78.763 117.96q0.71118 0 1.2756 0.15804 0.57572 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989 0.21448 0.41768 0.21448 0.93696 0 0.84664-0.32737 1.4336-0.32737 0.58701-0.90309 0.94824-0.57572 0.36124-1.3546 0.51928t-1.6933 0.15804h-0.44026l-0.63216 2.619h-1.7497l1.84-7.7101q0.60958-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.19191 0-0.32737 0.0113-0.13546 0.0113-0.27093 0.0226l-0.54185 2.3029h0.44026q0.47412 0 0.85794-0.0677 0.3951-0.079 0.66603-0.24835 0.28222-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37252-0.72247-0.36124-0.21448-1.0386-0.21448z"/>
<path d="m84.728 126.03q-0.5983 0-1.0386-0.18062-0.44026-0.18062-0.73376-0.50799-0.28222-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22577-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62087-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45154 0.18061 0.73376 0.50798 0.2935 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21448 0.67732-0.63216 1.2192-0.41768 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37252 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.2935 0.72247-0.09031 0.38381-0.09031 0.73376 0 0.57572 0.18062 0.8918 0.18062 0.30479 0.65474 0.30479 0.37252 0 0.65474-0.21448t0.47412-0.54185q0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m90.718 124.67q0.57572 0 0.7902-0.15804 0.21448-0.16933 0.21448-0.36123 0-0.12418-0.04515-0.21449-0.03387-0.0903-0.12417-0.16932-0.09031-0.079-0.24835-0.15805-0.15804-0.0903-0.40639-0.20319-0.28222-0.12417-0.53056-0.25964-0.24835-0.14675-0.44026-0.33866-0.18062-0.20319-0.2935-0.45154-0.1016-0.25964-0.1016-0.60959 0-0.91437 0.66603-1.4449 0.67732-0.53056 1.9642-0.53056 0.60958 0 1.0837 0.13546 0.47412 0.13546 0.76762 0.29351l-0.57572 1.253q-0.23706-0.12417-0.60958-0.23706t-0.73376-0.11289q-0.15804 0-0.31608 0.0226-0.14675 0.0113-0.28222 0.0677-0.12418 0.0564-0.2032 0.15804-0.07902 0.1016-0.07902 0.27093 0 0.22577 0.16933 0.33866 0.18062 0.11288 0.4967 0.27092 0.44026 0.21449 0.73376 0.39511 0.2935 0.18061 0.46283 0.38381 0.18062 0.20319 0.25964 0.46283 0.07902 0.25964 0.07902 0.60959 0 0.36123-0.15804 0.71118-0.14675 0.34995-0.47412 0.62087-0.32737 0.27093-0.83536 0.44026-0.50799 0.16933-1.2192 0.16933-0.44026 0-0.80149-0.0564-0.34995-0.0564-0.62087-0.13546-0.27093-0.0903-0.46283-0.18062-0.18062-0.0903-0.28222-0.14675l0.57572-1.2869q0.19191 0.11289 0.5983 0.28221 0.40639 0.16933 0.98211 0.16933z"/>
<path d="m96.112 118.45 1.7497-0.27093-0.42897 1.7497h1.8739l-0.33866 1.3772h-1.8626l-0.4967 2.0771q-0.06773 0.25964-0.09031 0.48541-0.01129 0.22577 0.05644 0.3951 0.07902 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27093 0 0.51928-0.0451 0.25964-0.0564 0.51928-0.14675l0.12418 1.2869q-0.33866 0.12417-0.73376 0.21448-0.3951 0.0903-0.93696 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60958-0.63216-0.18062-0.40639-0.15804-0.92567 0.02258-0.51928 0.15804-1.095z"/>
<path d="m104.8 123.31q-0.15804 0.64345-0.0903 1.2982 0.0677 0.64345 0.25963 1.1514l-1.5014 0.21448q-0.0677-0.13546-0.12418-0.25963-0.0564-0.12418-0.11288-0.28222-0.31608 0.25964-0.6999 0.42897-0.38381 0.16933-0.85793 0.16933-0.56443 0-0.97082-0.19191-0.3951-0.20319-0.65474-0.53056-0.24835-0.33866-0.36124-0.77892-0.11289-0.45154-0.11289-0.95953 0-0.77891 0.27093-1.4675 0.28222-0.6886 0.76762-1.1966 0.4967-0.51928 1.1627-0.81278t1.4449-0.2935q0.1016 0 0.34995 0.0113 0.25963 0.0113 0.587 0.0564 0.32737 0.0339 0.68861 0.12417 0.36123 0.0903 0.6886 0.24835zm-1.174-2.0771q-0.14675-0.0226-0.27093-0.0339-0.11288-0.0113-0.28221-0.0113-0.38382 0-0.72247 0.19191-0.32737 0.19191-0.57572 0.50799-0.24835 0.30479-0.3951 0.71118-0.13547 0.40639-0.13547 0.84665 0 0.54185 0.18062 0.85793t0.66603 0.31608q0.25964 0 0.46283-0.1016 0.21448-0.10159 0.45155-0.33865 0.0226-0.28222 0.0677-0.58701 0.0564-0.31608 0.11288-0.57572z"/>
<path d="m108.6 125.98q-0.80149 0-1.2643-0.20319-0.45155-0.21449-0.65474-0.57572-0.19191-0.36124-0.19191-0.82407 0.0113-0.47412 0.13546-1.0047l1.4337-5.9942 1.7497-0.27092-1.5691 6.5022q-0.0451 0.2032-0.0564 0.37253 0 0.16933 0.0677 0.30479 0.0677 0.12418 0.22578 0.2032 0.16932 0.079 0.46283 0.10159z"/>
<path d="m114.04 117.96q0.71119 0 1.2756 0.15804 0.57571 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989t0.21448 0.93696q0 0.84664-0.32737 1.4336-0.32736 0.58701-0.90308 0.94824-0.57572 0.36124-1.3546 0.51928-0.77891 0.15804-1.6933 0.15804h-0.44025l-0.63217 2.619h-1.7497l1.84-7.7101q0.60959-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.1919 0-0.32737 0.0113-0.13546 0.0113-0.27092 0.0226l-0.54186 2.3029h0.44026q0.47412 0 0.85793-0.0677 0.3951-0.079 0.66603-0.24835 0.28221-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37253-0.72247-0.36123-0.21448-1.0386-0.21448z"/>
<path d="m120 126.03q-0.59829 0-1.0386-0.18062t-0.73376-0.50799q-0.28221-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22578-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62088-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45155 0.18061 0.73376 0.50798 0.29351 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21449 0.67732-0.63217 1.2192-0.41767 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37253 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.29351 0.72247-0.0903 0.38381-0.0903 0.73376 0 0.57572 0.18061 0.8918 0.18062 0.30479 0.65474 0.30479 0.37253 0 0.65474-0.21448 0.28222-0.21448 0.47412-0.54185 0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m125.74 125.87h-1.6707l1.4111-5.9378h1.682zm0.81278-6.6603q-0.34995 0-0.63216-0.2032-0.28222-0.21448-0.28222-0.64345 0-0.23706 0.0903-0.44025 0.1016-0.21449 0.25964-0.36124 0.15804-0.15804 0.36124-0.24835 0.21448-0.0903 0.45154-0.0903 0.34995 0 0.63216 0.21449 0.28222 0.20319 0.28222 0.63216 0 0.23706-0.1016 0.45154-0.0903 0.2032-0.24835 0.36124-0.15804 0.14675-0.37252 0.23706-0.2032 0.0903-0.44026 0.0903z"/>
<path d="m128.89 120.2q0.1919-0.0564 0.41767-0.12418 0.23707-0.079 0.51928-0.13546 0.2935-0.0677 0.64345-0.1016 0.36124-0.0451 0.81278-0.0451 1.3321 0 1.8288 0.76762 0.49669 0.76763 0.16932 2.0997l-0.76762 3.206h-1.682l0.74505-3.1382q0.0677-0.2935 0.10159-0.56443 0.0452-0.28221 0-0.48541-0.0451-0.21448-0.21448-0.33866-0.15804-0.13546-0.4967-0.13546-0.32737 0-0.66603 0.0677l-1.095 4.5945h-1.682z"/>
<path d="m135.8 118.45 1.7497-0.27093-0.42896 1.7497h1.8739l-0.33865 1.3772h-1.8626l-0.4967 2.0771q-0.0677 0.25964-0.0903 0.48541-0.0113 0.22577 0.0564 0.3951 0.079 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27092 0 0.51927-0.0451 0.25964-0.0564 0.51928-0.14675l0.12417 1.2869q-0.33865 0.12417-0.73376 0.21448-0.3951 0.0903-0.93695 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60959-0.63216-0.18061-0.40639-0.15804-0.92567 0.0226-0.51928 0.15804-1.095z"/>
</g>
<g clip-path="url(#clipPath965)" fill="#fff" aria-label="PostalPoint">
<path d="m78.763 117.96q0.71118 0 1.2756 0.15804 0.57572 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989 0.21448 0.41768 0.21448 0.93696 0 0.84664-0.32737 1.4336-0.32737 0.58701-0.90309 0.94824-0.57572 0.36124-1.3546 0.51928t-1.6933 0.15804h-0.44026l-0.63216 2.619h-1.7497l1.84-7.7101q0.60958-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.19191 0-0.32737 0.0113-0.13546 0.0113-0.27093 0.0226l-0.54185 2.3029h0.44026q0.47412 0 0.85794-0.0677 0.3951-0.079 0.66603-0.24835 0.28222-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37252-0.72247-0.36124-0.21448-1.0386-0.21448z"/>
<path d="m84.728 126.03q-0.5983 0-1.0386-0.18062-0.44026-0.18062-0.73376-0.50799-0.28222-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22577-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62087-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45154 0.18061 0.73376 0.50798 0.2935 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21448 0.67732-0.63216 1.2192-0.41768 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37252 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.2935 0.72247-0.09031 0.38381-0.09031 0.73376 0 0.57572 0.18062 0.8918 0.18062 0.30479 0.65474 0.30479 0.37252 0 0.65474-0.21448t0.47412-0.54185q0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m90.718 124.67q0.57572 0 0.7902-0.15804 0.21448-0.16933 0.21448-0.36123 0-0.12418-0.04515-0.21449-0.03387-0.0903-0.12417-0.16932-0.09031-0.079-0.24835-0.15805-0.15804-0.0903-0.40639-0.20319-0.28222-0.12417-0.53056-0.25964-0.24835-0.14675-0.44026-0.33866-0.18062-0.20319-0.2935-0.45154-0.1016-0.25964-0.1016-0.60959 0-0.91437 0.66603-1.4449 0.67732-0.53056 1.9642-0.53056 0.60958 0 1.0837 0.13546 0.47412 0.13546 0.76762 0.29351l-0.57572 1.253q-0.23706-0.12417-0.60958-0.23706t-0.73376-0.11289q-0.15804 0-0.31608 0.0226-0.14675 0.0113-0.28222 0.0677-0.12418 0.0564-0.2032 0.15804-0.07902 0.1016-0.07902 0.27093 0 0.22577 0.16933 0.33866 0.18062 0.11288 0.4967 0.27092 0.44026 0.21449 0.73376 0.39511 0.2935 0.18061 0.46283 0.38381 0.18062 0.20319 0.25964 0.46283 0.07902 0.25964 0.07902 0.60959 0 0.36123-0.15804 0.71118-0.14675 0.34995-0.47412 0.62087-0.32737 0.27093-0.83536 0.44026-0.50799 0.16933-1.2192 0.16933-0.44026 0-0.80149-0.0564-0.34995-0.0564-0.62087-0.13546-0.27093-0.0903-0.46283-0.18062-0.18062-0.0903-0.28222-0.14675l0.57572-1.2869q0.19191 0.11289 0.5983 0.28221 0.40639 0.16933 0.98211 0.16933z"/>
<path d="m96.112 118.45 1.7497-0.27093-0.42897 1.7497h1.8739l-0.33866 1.3772h-1.8626l-0.4967 2.0771q-0.06773 0.25964-0.09031 0.48541-0.01129 0.22577 0.05644 0.3951 0.07902 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27093 0 0.51928-0.0451 0.25964-0.0564 0.51928-0.14675l0.12418 1.2869q-0.33866 0.12417-0.73376 0.21448-0.3951 0.0903-0.93696 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60958-0.63216-0.18062-0.40639-0.15804-0.92567 0.02258-0.51928 0.15804-1.095z"/>
<path d="m104.8 123.31q-0.15804 0.64345-0.0903 1.2982 0.0677 0.64345 0.25963 1.1514l-1.5014 0.21448q-0.0677-0.13546-0.12418-0.25963-0.0564-0.12418-0.11288-0.28222-0.31608 0.25964-0.6999 0.42897-0.38381 0.16933-0.85793 0.16933-0.56443 0-0.97082-0.19191-0.3951-0.20319-0.65474-0.53056-0.24835-0.33866-0.36124-0.77892-0.11288-0.45154-0.11288-0.95953 0-0.77891 0.27092-1.4675 0.28222-0.6886 0.76763-1.1966 0.4967-0.51928 1.1627-0.81278t1.4449-0.2935q0.1016 0 0.34995 0.0113 0.25963 0.0113 0.587 0.0564 0.32737 0.0339 0.68861 0.12417 0.36123 0.0903 0.6886 0.24835zm-1.174-2.0771q-0.14675-0.0226-0.27093-0.0339-0.11288-0.0113-0.28221-0.0113-0.38382 0-0.72247 0.19191-0.32737 0.19191-0.57572 0.50799-0.24835 0.30479-0.3951 0.71118-0.13547 0.40639-0.13547 0.84665 0 0.54185 0.18062 0.85793t0.66603 0.31608q0.25964 0 0.46283-0.1016 0.21448-0.10159 0.45155-0.33865 0.0226-0.28222 0.0677-0.58701 0.0564-0.31608 0.11288-0.57572z"/>
<path d="m108.6 125.98q-0.80149 0-1.2643-0.20319-0.45155-0.21449-0.65474-0.57572-0.19191-0.36124-0.19191-0.82407 0.0113-0.47412 0.13546-1.0047l1.4337-5.9942 1.7497-0.27092-1.5691 6.5022q-0.0451 0.2032-0.0564 0.37253 0 0.16933 0.0677 0.30479 0.0677 0.12418 0.22578 0.2032 0.16932 0.079 0.46283 0.10159z"/>
<path d="m114.04 117.96q0.71119 0 1.2756 0.15804 0.57571 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989t0.21448 0.93696q0 0.84664-0.32737 1.4336-0.32736 0.58701-0.90308 0.94824-0.57572 0.36124-1.3546 0.51928-0.77891 0.15804-1.6933 0.15804h-0.44025l-0.63217 2.619h-1.7497l1.84-7.7101q0.60959-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.1919 0-0.32737 0.0113-0.13546 0.0113-0.27092 0.0226l-0.54186 2.3029h0.44026q0.47412 0 0.85793-0.0677 0.3951-0.079 0.66603-0.24835 0.28221-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37253-0.72247-0.36123-0.21448-1.0386-0.21448z"/>
<path d="m120 126.03q-0.59829 0-1.0386-0.18062t-0.73376-0.50799q-0.28221-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22578-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62088-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45155 0.18061 0.73376 0.50798 0.29351 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21449 0.67732-0.63217 1.2192-0.41767 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37253 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.29351 0.72247-0.0903 0.38381-0.0903 0.73376 0 0.57572 0.18061 0.8918 0.18062 0.30479 0.65474 0.30479 0.37253 0 0.65474-0.21448 0.28222-0.21448 0.47412-0.54185 0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m125.74 125.87h-1.6707l1.4111-5.9378h1.682zm0.81278-6.6603q-0.34995 0-0.63216-0.2032-0.28222-0.21448-0.28222-0.64345 0-0.23706 0.0903-0.44025 0.1016-0.21449 0.25964-0.36124 0.15804-0.15804 0.36124-0.24835 0.21448-0.0903 0.45154-0.0903 0.34995 0 0.63216 0.21449 0.28222 0.20319 0.28222 0.63216 0 0.23706-0.1016 0.45154-0.0903 0.2032-0.24835 0.36124-0.15804 0.14675-0.37252 0.23706-0.2032 0.0903-0.44026 0.0903z"/>
<path d="m128.89 120.2q0.1919-0.0564 0.41767-0.12418 0.23707-0.079 0.51928-0.13546 0.2935-0.0677 0.64345-0.1016 0.36124-0.0451 0.81278-0.0451 1.3321 0 1.8288 0.76762 0.49669 0.76763 0.16932 2.0997l-0.76762 3.206h-1.682l0.74505-3.1382q0.0677-0.2935 0.10159-0.56443 0.0452-0.28221 0-0.48541-0.0451-0.21448-0.21448-0.33866-0.15804-0.13546-0.4967-0.13546-0.32737 0-0.66603 0.0677l-1.095 4.5945h-1.682z"/>
<path d="m135.8 118.45 1.7497-0.27093-0.42896 1.7497h1.8739l-0.33865 1.3772h-1.8626l-0.4967 2.0771q-0.0677 0.25964-0.0903 0.48541-0.0113 0.22577 0.0564 0.3951 0.079 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27092 0 0.51927-0.0451 0.25964-0.0564 0.51928-0.14675l0.12417 1.2869q-0.33865 0.12417-0.73376 0.21448-0.3951 0.0903-0.93695 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60959-0.63216-0.18061-0.40639-0.15804-0.92567 0.0226-0.51928 0.15804-1.095z"/>
</g>
</g>
<g transform="translate(1.3993 2.6002)">
<path d="m61.891 114.86 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m64.391 114.86-1.25 0.53541v1.5177l1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m64.391 114.86-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m63.141 116.92 1.25 0.53541v1.5177l-1.25-0.53542z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m65.641 116.92-1.25 0.53541v1.5177l1.25-0.53542z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m65.641 116.92-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#006e9f" style="paint-order:normal"/>
<path d="m60.641 116.92 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m63.141 116.92-1.25 0.53541v1.5177l1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m63.141 116.92-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#006e9f" style="paint-order:normal"/>
<path d="m60.641 115.4 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m63.141 115.4-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m63.141 115.4-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m63.141 115.4 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m65.641 115.4-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m65.641 115.4-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m60.641 123.61 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m65.641 123.61-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m65.641 123.61-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m58.141 111.29 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m63.141 111.29-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m63.141 111.29-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m63.141 119.51 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m68.141 119.51-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m68.141 119.51-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m58.141 119.51 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m63.141 119.51-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m63.141 119.51-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m65.641 115.4 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m70.641 115.4-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m70.641 115.4-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m55.641 115.4 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m60.641 115.4-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m60.641 115.4-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m63.141 111.29 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m68.141 111.29-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m68.141 111.29-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m61.891 117.45 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m64.391 117.45-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m64.391 117.45-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="82.453mm" height="18.496mm" version="1.1" viewBox="0 0 82.453 18.496" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<defs>
<clipPath id="clipPath907">
<rect x="73.099" y="121.75" width="66.791" height=".70158" display="none" fill="#2196f3" style="paint-order:normal"/>
<path class="powerclip" d="m69.733 112.11h74.26v18.918h-74.26zm3.3652 9.6352v0.70159h66.791v-0.70159z" fill="#2196f3" style="paint-order:normal"/>
</clipPath>
</defs>
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-49.238 -106.32)">
<g transform="translate(-27.882 -9.2062)" style="paint-order:normal">
<path d="m82.619 116.03-2.5001 1.0707v3.0355l-2.4996 1.0707v3.0355l2.4996 1.0713v3.035l2.5001 1.0713v3.035l2.5001 1.0713 2.5001-1.0713v-3.035l2.5001-1.0713v-3.035l2.4996-1.0713v-3.0355l-2.4996-1.0707v-3.0355l-2.5001-1.0707-2.5001 1.0707z" fill="#00b0ff" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" style="paint-order:normal"/>
</g>
<g transform="translate(-7.3027 -5.9991)">
<g transform="translate(1.3993 2.6002)">
<path d="m61.891 114.86 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m64.391 114.86-1.25 0.53541v1.5177l1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m64.391 114.86-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m63.141 116.92 1.25 0.53541v1.5177l-1.25-0.53542z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m65.641 116.92-1.25 0.53541v1.5177l1.25-0.53542z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m65.641 116.92-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#006e9f" style="paint-order:normal"/>
<path d="m60.641 116.92 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m63.141 116.92-1.25 0.53541v1.5177l1.25-0.53541z" fill="#00b0ff" style="paint-order:normal"/>
<path d="m63.141 116.92-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#006e9f" style="paint-order:normal"/>
<path d="m60.641 115.4 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m63.141 115.4-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m63.141 115.4-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m63.141 115.4 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m65.641 115.4-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m65.641 115.4-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
<path d="m60.641 123.61 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m65.641 123.61-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m65.641 123.61-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m58.141 111.29 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m63.141 111.29-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m63.141 111.29-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m63.141 119.51 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m68.141 119.51-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m68.141 119.51-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m58.141 119.51 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m63.141 119.51-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m63.141 119.51-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m65.641 115.4 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m70.641 115.4-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m70.641 115.4-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m55.641 115.4 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m60.641 115.4-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m60.641 115.4-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m63.141 111.29 2.5 1.0708v3.0354l-2.5-1.0708z" fill="#40c4ff" style="paint-order:normal"/>
<path d="m68.141 111.29-2.5 1.0708v3.0354l2.5-1.0708z" fill="#0091ea" style="paint-order:normal"/>
<path d="m68.141 111.29-2.5 1.0708-2.5-1.0708 2.5-1.0708z" fill="#03a9f4" style="paint-order:normal"/>
<path d="m61.891 117.45 1.25 0.53541v1.5177l-1.25-0.53541z" fill="#eee" style="paint-order:normal"/>
<path d="m64.391 117.45-1.25 0.53541v1.5177l1.25-0.53541z" fill="#bdbdbd" style="paint-order:normal"/>
<path d="m64.391 117.45-1.25 0.53541-1.25-0.53541 1.25-0.53541z" fill="#fff" style="paint-order:normal"/>
</g>
<g clip-path="url(#clipPath907)" fill="#fff" stroke-width=".26458px" aria-label="PostalPoint">
<path d="m78.763 117.96q0.71118 0 1.2756 0.15804 0.57572 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989 0.21448 0.41768 0.21448 0.93696 0 0.84664-0.32737 1.4336-0.32737 0.58701-0.90309 0.94824-0.57572 0.36124-1.3546 0.51928t-1.6933 0.15804h-0.44026l-0.63216 2.619h-1.7497l1.84-7.7101q0.60958-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.19191 0-0.32737 0.0113-0.13546 0.0113-0.27093 0.0226l-0.54185 2.3029h0.44026q0.47412 0 0.85794-0.0677 0.3951-0.079 0.66603-0.24835 0.28222-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37252-0.72247-0.36124-0.21448-1.0386-0.21448z"/>
<path d="m84.728 126.03q-0.5983 0-1.0386-0.18062-0.44026-0.18062-0.73376-0.50799-0.28222-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22577-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62087-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45154 0.18061 0.73376 0.50798 0.2935 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21448 0.67732-0.63216 1.2192-0.41768 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37252 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.2935 0.72247-0.09031 0.38381-0.09031 0.73376 0 0.57572 0.18062 0.8918 0.18062 0.30479 0.65474 0.30479 0.37252 0 0.65474-0.21448t0.47412-0.54185q0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m90.718 124.67q0.57572 0 0.7902-0.15804 0.21448-0.16933 0.21448-0.36123 0-0.12418-0.04515-0.21449-0.03387-0.0903-0.12417-0.16932-0.09031-0.079-0.24835-0.15805-0.15804-0.0903-0.40639-0.20319-0.28222-0.12417-0.53056-0.25964-0.24835-0.14675-0.44026-0.33866-0.18062-0.20319-0.2935-0.45154-0.1016-0.25964-0.1016-0.60959 0-0.91437 0.66603-1.4449 0.67732-0.53056 1.9642-0.53056 0.60958 0 1.0837 0.13546 0.47412 0.13546 0.76762 0.29351l-0.57572 1.253q-0.23706-0.12417-0.60958-0.23706t-0.73376-0.11289q-0.15804 0-0.31608 0.0226-0.14675 0.0113-0.28222 0.0677-0.12418 0.0564-0.2032 0.15804-0.07902 0.1016-0.07902 0.27093 0 0.22577 0.16933 0.33866 0.18062 0.11288 0.4967 0.27092 0.44026 0.21449 0.73376 0.39511 0.2935 0.18061 0.46283 0.38381 0.18062 0.20319 0.25964 0.46283 0.07902 0.25964 0.07902 0.60959 0 0.36123-0.15804 0.71118-0.14675 0.34995-0.47412 0.62087-0.32737 0.27093-0.83536 0.44026-0.50799 0.16933-1.2192 0.16933-0.44026 0-0.80149-0.0564-0.34995-0.0564-0.62087-0.13546-0.27093-0.0903-0.46283-0.18062-0.18062-0.0903-0.28222-0.14675l0.57572-1.2869q0.19191 0.11289 0.5983 0.28221 0.40639 0.16933 0.98211 0.16933z"/>
<path d="m96.112 118.45 1.7497-0.27093-0.42897 1.7497h1.8739l-0.33866 1.3772h-1.8626l-0.4967 2.0771q-0.06773 0.25964-0.09031 0.48541-0.01129 0.22577 0.05644 0.3951 0.07902 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27093 0 0.51928-0.0451 0.25964-0.0564 0.51928-0.14675l0.12418 1.2869q-0.33866 0.12417-0.73376 0.21448-0.3951 0.0903-0.93696 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60958-0.63216-0.18062-0.40639-0.15804-0.92567 0.02258-0.51928 0.15804-1.095z"/>
<path d="m104.8 123.31q-0.15804 0.64345-0.0903 1.2982 0.0677 0.64345 0.25963 1.1514l-1.5014 0.21448q-0.0677-0.13546-0.12418-0.25963-0.0564-0.12418-0.11288-0.28222-0.31608 0.25964-0.6999 0.42897-0.38381 0.16933-0.85793 0.16933-0.56443 0-0.97082-0.19191-0.3951-0.20319-0.65474-0.53056-0.24835-0.33866-0.36124-0.77892-0.11288-0.45154-0.11288-0.95953 0-0.77891 0.27092-1.4675 0.28222-0.6886 0.76763-1.1966 0.4967-0.51928 1.1627-0.81278t1.4449-0.2935q0.1016 0 0.34995 0.0113 0.25963 0.0113 0.587 0.0564 0.32737 0.0339 0.68861 0.12417 0.36123 0.0903 0.6886 0.24835zm-1.174-2.0771q-0.14675-0.0226-0.27093-0.0339-0.11288-0.0113-0.28221-0.0113-0.38382 0-0.72247 0.19191-0.32737 0.19191-0.57572 0.50799-0.24835 0.30479-0.3951 0.71118-0.13547 0.40639-0.13547 0.84665 0 0.54185 0.18062 0.85793t0.66603 0.31608q0.25964 0 0.46283-0.1016 0.21448-0.10159 0.45155-0.33865 0.0226-0.28222 0.0677-0.58701 0.0564-0.31608 0.11288-0.57572z"/>
<path d="m108.6 125.98q-0.80149 0-1.2643-0.20319-0.45155-0.21449-0.65474-0.57572-0.19191-0.36124-0.19191-0.82407 0.0113-0.47412 0.13546-1.0047l1.4337-5.9942 1.7497-0.27092-1.5691 6.5022q-0.0451 0.2032-0.0564 0.37253 0 0.16933 0.0677 0.30479 0.0677 0.12418 0.22578 0.2032 0.16932 0.079 0.46283 0.10159z"/>
<path d="m114.04 117.96q0.71119 0 1.2756 0.15804 0.57571 0.14675 0.97082 0.44026 0.3951 0.28221 0.60958 0.69989t0.21448 0.93696q0 0.84664-0.32737 1.4336-0.32736 0.58701-0.90308 0.94824-0.57572 0.36124-1.3546 0.51928-0.77891 0.15804-1.6933 0.15804h-0.44025l-0.63217 2.619h-1.7497l1.84-7.7101q0.60959-0.11289 1.1514-0.15804 0.55314-0.0452 1.0386-0.0452zm-0.14675 1.4788q-0.1919 0-0.32737 0.0113-0.13546 0.0113-0.27092 0.0226l-0.54186 2.3029h0.44026q0.47412 0 0.85793-0.0677 0.3951-0.079 0.66603-0.24835 0.28221-0.16933 0.42897-0.42897 0.15804-0.27092 0.15804-0.65474 0-0.50798-0.37253-0.72247-0.36123-0.21448-1.0386-0.21448z"/>
<path d="m120 126.03q-0.59829 0-1.0386-0.18062t-0.73376-0.50799q-0.28221-0.32737-0.42897-0.76762-0.14675-0.45155-0.14675-0.9934 0-0.67732 0.21448-1.3546 0.22578-0.67732 0.65474-1.2192 0.42897-0.54186 1.0498-0.88052 0.62088-0.34994 1.4224-0.34994 0.58701 0 1.0273 0.18062 0.45155 0.18061 0.73376 0.50798 0.29351 0.32737 0.44026 0.77892 0.14675 0.44025 0.14675 0.98211 0 0.67731-0.21448 1.3546-0.21449 0.67732-0.63217 1.2192-0.41767 0.54185-1.0498 0.8918-0.62087 0.33866-1.4449 0.33866zm0.83536-4.8315q-0.37253 0-0.65474 0.21449-0.28222 0.21448-0.47412 0.54185-0.19191 0.32737-0.29351 0.72247-0.0903 0.38381-0.0903 0.73376 0 0.57572 0.18061 0.8918 0.18062 0.30479 0.65474 0.30479 0.37253 0 0.65474-0.21448 0.28222-0.21448 0.47412-0.54185 0.19191-0.32737 0.28222-0.71119 0.1016-0.3951 0.1016-0.74504 0-0.57572-0.18062-0.88052-0.18062-0.31608-0.65474-0.31608z"/>
<path d="m125.74 125.87h-1.6707l1.4111-5.9378h1.682zm0.81278-6.6603q-0.34995 0-0.63216-0.2032-0.28222-0.21448-0.28222-0.64345 0-0.23706 0.0903-0.44025 0.1016-0.21449 0.25964-0.36124 0.15804-0.15804 0.36124-0.24835 0.21448-0.0903 0.45154-0.0903 0.34995 0 0.63216 0.21449 0.28222 0.20319 0.28222 0.63216 0 0.23706-0.1016 0.45154-0.0903 0.2032-0.24835 0.36124-0.15804 0.14675-0.37252 0.23706-0.2032 0.0903-0.44026 0.0903z"/>
<path d="m128.89 120.2q0.1919-0.0564 0.41767-0.12418 0.23707-0.079 0.51928-0.13546 0.2935-0.0677 0.64345-0.1016 0.36124-0.0451 0.81278-0.0451 1.3321 0 1.8288 0.76762 0.49669 0.76763 0.16932 2.0997l-0.76762 3.206h-1.682l0.74505-3.1382q0.0677-0.2935 0.10159-0.56443 0.0452-0.28221 0-0.48541-0.0451-0.21448-0.21448-0.33866-0.15804-0.13546-0.4967-0.13546-0.32737 0-0.66603 0.0677l-1.095 4.5945h-1.682z"/>
<path d="m135.8 118.45 1.7497-0.27093-0.42896 1.7497h1.8739l-0.33865 1.3772h-1.8626l-0.4967 2.0771q-0.0677 0.25964-0.0903 0.48541-0.0113 0.22577 0.0564 0.3951 0.079 0.15804 0.25964 0.24835 0.18062 0.0903 0.4967 0.0903 0.27092 0 0.51927-0.0451 0.25964-0.0564 0.51928-0.14675l0.12417 1.2869q-0.33865 0.12417-0.73376 0.21448-0.3951 0.0903-0.93695 0.0903-0.77891 0-1.2079-0.22577-0.42897-0.23706-0.60959-0.63216-0.18061-0.40639-0.15804-0.92567 0.0226-0.51928 0.15804-1.095z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

@ -31,12 +31,20 @@ class MapControl {
* @param {number} latitude
* @param {number} longitude
* @param {boolean} accurate set true to zoom to street level (z13), false to zoom to general area (z10).
* @param {boolean} countrylevel set true to override accurate and set zoom level to 3
* @returns {undefined}
*/
clearMarkersAndCenterMapOnNewMarker(classname, latitude, longitude, accurate) {
clearMarkersAndCenterMapOnNewMarker(classname, latitude, longitude, accurate, countrylevel) {
this.mapObj.removeMarkers();
this.mapObj.addMarker(latitude, longitude, classname);
this.mapObj.animateMapIn(latitude, longitude, (accurate ? 13 : 10));
var zoomlevel = 10;
if (accurate) {
zoomlevel = 13;
}
if (countrylevel) {
zoomlevel = 3;
}
this.mapObj.animateMapIn(latitude, longitude, zoomlevel);
}
loadMarkersFromGeoJson(geojson, iconname, name) {

@ -101,11 +101,9 @@ function verifyCode(code) {
}
function displayAccountInfo() {
$("#loyaltyBalanceBox").addClass("display-none");
$("#loyaltyErrorMessage").html("");
if (inStorage("accountkey") && inStorage("accountnumber")) {
} else {
$("#loyaltyErrorMessage").text("Error: No account connected.");
$("#accountErrorMessage").text("Error: No account connected.");
return;
}
apirequest(SETTINGS.apis.getaccountinfo, {
@ -115,8 +113,6 @@ function displayAccountInfo() {
$("#hasaccountbox").css("display", "");
$("#loadingaccountbox").css("display", "none");
if (success.status == "OK") {
$("#loyaltyCreditBalanceHeading").text(success.credits + " points");
$("#loyaltyBalanceBox").removeClass("display-none")
$("#accountnumberspan").text(success.accountnumber);
if (success.payments_setup === false) {
@ -131,11 +127,10 @@ function displayAccountInfo() {
$("#accountupdateform input#streetaddress").val(success.streetaddress);
$("#accountupdateform input#zipcode").val(success.zipcode);
} else {
$("#loyaltyBalanceBox").addClass("display-none");
$("#loyaltyErrorMessage").text("Error: " + success.msg);
$("#accountErrorMessage").text("Error: " + success.msg);
}
}, function (xhr, status, error) {
$("#loyaltyErrorMessage").text("Error: Couldn't get your account info. Try again later.");
$("#accountErrorMessage").text("Error: Couldn't get your account info. Try again later.");
sendErrorReport("Account", "Couldn't display account info", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
}, "GET");
}
@ -329,4 +324,21 @@ function loadReceiptHTMLIntoPopup(receiptid) {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
sendErrorReport("Receipts", "Couldn't load receipt", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
}, "POST");
}
function receiptiframeloadevent() {
$("#receiptvieweriframe").contents().find("a").each(function () {
$(this).attr("data-href", $(this).attr("href"));
$(this).attr("href", "#");
$(this).on("click", function (evt) {
var href = evt.target.getAttribute("data-href");
window.parent.openReceiptIframeLink(href);
});
});
}
function openReceiptIframeLink(href) {
if (handleDeepLink(href)) {
app.popup.close();
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,523 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var walletPubKeyRegex = /^(bc1|[13]|D)[a-zA-HJ-NP-Z0-9]{25,}$/;
var paymentRequestRegex = /^(?:bitcoin|dogecoin):([a-zA-Z0-9]{20,40})(?:\?(.*))?$/;
var walletPrivateKeyRegex = /^[0-9A-Za-z]+$/;
/**
* Parse a crypto URI and extract the info in it.
* Copyright (c) 2019 Robin Linus, MIT license, https://github.com/coins/bitcoin-uri-js
* @param {type} uri
* @returns {parsePaymentURI.parsed}
*/
function parsePaymentURI(uri) {
const legalKeys = ['address', 'amount', 'value', 'message', 'send', 'tx'];
const match = paymentRequestRegex.exec(uri);
if (!match) {
return null;
}
const parsed = {uri: uri}
if (match[2]) {
const queries = match[2].split('&');
for (let i = 0; i < queries.length; i++) {
const query = queries[i].split('=');
const key = query[0];
if (query.length === 2 && legalKeys.includes(key)) {
parsed[key] = decodeURIComponent(query[1].replace(/\+/g, '%20'));
}
}
}
parsed.address = match[1];
return parsed;
}
function openWalletPage(walletaddress) {
var navuri = '/crypto/' + walletaddress;
if (typeof router.currentRoute.query.paymenturi != 'undefined') {
var parsed = parsePaymentURI(router.currentRoute.query.paymenturi);
if (parsed != null) {
navuri += '/' + parsed.address;
if (typeof parsed['amount'] != 'undefined') {
navuri += '/' + parsed.amount;
}
}
}
router.navigate(navuri);
}
function scanWalletQrCode(callback) {
scanBarcode(function (result) {
if (walletPubKeyRegex.test(result)) {
callback(result);
} else {
app.dialog.alert("That doesn't look like a valid wallet address.", "Error");
return;
}
}, function () {
app.dialog.alert("Something went wrong and we can't scan right now.", "Error");
});
}
function scanPrivateKeyQrCode(callback) {
scanBarcode(function (result) {
if (walletPrivateKeyRegex.test(result)) {
callback(result);
} else {
app.dialog.alert("That doesn't look like a valid wallet address.", "Error");
return;
}
}, function () {
app.dialog.alert("Something went wrong and we can't scan right now.", "Error");
});
}
/**
* Create and sign a crypto transaction.
*
* @param {type} bitcoreLib Bitcore, Litecore, Dogecore, etc.
* @param {type} privateKeyString Private key from wallet QR code
* @param {type} sourceAddress Sender's wallet address
* @param {type} destinationAddress Recipient's wallet address
* @param {Array} utxos Unspent transaction inputs, as array. See createUtxo()
* @param {type} outputSatoshis Amount to send to recipient's wallet
* @returns {string} Hex of serialized transaction, suitable for broadcast via Bitcoin Core or an API.
*/
function createSignedTransaction(bitcoreLib, privateKeyString, sourceAddress, destinationAddress, utxos, outputSatoshis, feePerByte) {
if (typeof feePerByte == "undefined") {
feePerByte = -1;
}
try {
var privateKey = new bitcoreLib.PrivateKey(privateKeyString);
var transaction = new bitcoreLib.Transaction()
.from(utxos)
.to(destinationAddress, outputSatoshis)
.change(sourceAddress);
var size = transaction._estimateSize();
var fee = size * feePerByte;
if (feePerByte > -1) {
// use our fee
transaction = transaction.fee(fee);
} else {
// use lib's fee
fee = transaction.getFee();
}
transaction = transaction.sign(privateKey);
var inputTotal = transaction._getInputAmount();
var outputTotal = fee + outputSatoshis;
} catch (ex) {
throw new Error("There was an internal error while creating the transaction. Details: " + ex.message);
}
console.log(inputTotal, outputTotal);
if (outputTotal > inputTotal) {
throw new Error("You have insufficient funds to cover the payment and transaction fees.");
}
try {
return {serialized: transaction.serialize(), fee: fee, sendamount: outputSatoshis, totalspent: outputTotal};
} catch (ex) {
throw new Error("Couldn't create the transaction. It's likely you typed something wrong. Check that you have enough funds.");
}
}
/**
* Create a UTXO.
*
* @param {type} sourceAddress Sender's wallet address
* @param {type} txHash From UTXO (unspent output)
* @param {type} txOutputIndex From UTXO (unspent output)
* @param {type} script From UTXO (unspent output)
* @param {type} inputSatoshis From UTXO (unspent output)
* @returns {createUtxo.utxo}
*/
function createUtxo(sourceAddress, txHash, txOutputIndex, script, inputSatoshis) {
var utxo = {
"txId": txHash,
"outputIndex": txOutputIndex,
"address": sourceAddress,
"script": script,
"satoshis": inputSatoshis
};
return utxo;
}
/**
* Get unspent outputs for a wallet address.
* @param {string} walletaddress
* @param {function} successCallback Passes object with {utxos: [{txHash,txOutputIndex,script,value}], currency: "DOGE", label: "Dogecoin"}
* @param {function} errorCallback Passes string error message suitable for display
* @returns {undefined}
*/
function getUTXOData(walletaddress, successCallback, errorCallback) {
apirequest(SETTINGS.apis.getutxo, {
walletaddress: walletaddress
}, function (resp) {
if (resp.status == "OK") {
successCallback({
utxos: resp.unspent_outputs,
currency: resp.currency,
label: resp.label
});
} else {
errorCallback(resp.msg);
}
}, function (errorData) {
try {
var error = $.parseJSON(errorData.responseText);
if (error && typeof error.msg != 'undefined') {
errorCallback(resp.msg);
sendErrorReport("Crypto", "Couldn't get UTXO data", error.msg);
} else {
errorCallback("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.");
sendErrorReport("Crypto", "Couldn't get UTXO data", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
} catch (ex) {
errorCallback("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.");
sendErrorReport("Crypto", "Couldn't get UTXO data", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
});
}
function sendCoins(privatekey, fromaddress, toaddress, amount) {
var progressdialog = app.dialog.progress("Querying blockchain...", 20);
getUTXOData(fromaddress, function (success) {
progressdialog.setProgress(40);
progressdialog.setText("Creating transaction...");
if (success.utxos.length == 0) {
app.dialog.close();
app.dialog.alert("Your wallet has no available funds (ZERO_LENGTH_UTXO).", "Error");
return;
}
var utxos = [];
for (var i = 0; i < success.utxos.length; i++) {
utxos.push(createUtxo(fromaddress, success.utxos[i].txHash, success.utxos[i].txOutputIndex, success.utxos[i].script, success.utxos[i].value));
}
var bitcore = null;
var satoshis = parseInt((amount * 100000000).toFixed(0)); // Make sure it's an int and not something like 10.0000000001 or 9.532999999999
switch (success.currency) {
case "DOGE":
bitcore = require("bitcore-lib-doge");
break;
case "BTC":
bitcore = require("bitcore-lib");
break;
default:
app.dialog.close();
app.dialog.alert("This app version doesn't support " + success.currency + ".", "Error");
return;
}
progressdialog.setProgress(60);
progressdialog.setText("Calculating fees...");
apirequest(SETTINGS.apis.cryptofees, {
currency: success.currency
}, function (resp) {
if (resp.status == "OK") {
try {
var txdata = createSignedTransaction(bitcore, privatekey, fromaddress, toaddress, utxos, satoshis, resp.feePerByte);
} catch (ex) {
console.error(ex);
app.dialog.close();
app.dialog.alert(ex.message, "Error");
return;
}
progressdialog.close();
app.dialog.confirm("Sending " + (txdata.sendamount / 100000000) + " " + success.currency
+ " with a fee of " + (txdata.fee / 100000000) + " " + success.currency
+ " for a total spend of " + (txdata.totalspent / 100000000) + " " + success.currency + ".",
"Confirm Transaction",
function (ok) {
progressdialog = app.dialog.progress("Sending payment...", 80);
apirequest(SETTINGS.apis.broadcasttransaction, {
transactiondata: txdata.serialized,
currency: success.currency
}, function (resp) {
if (resp.status == "OK") {
app.dialog.close();
app.dialog.alert("Sent " + amount + " " + success.currency + " to " + toaddress.substring(0, 5) + "..." + toaddress.substring(toaddress.length - 5, 999), "Success!");
$('#walletPrivateKey').val(""); // clear private key input box
app.popup.close();
return;
} else {
app.dialog.close();
app.dialog.alert(resp.msg, "Error");
}
}, function (errorData) {
app.dialog.close();
try {
var error = $.parseJSON(errorData.responseText);
if (error && typeof error.msg != 'undefined') {
app.dialog.alert(error.msg, "Error");
sendErrorReport("Crypto", "Couldn't broadcast transaction", error.msg);
} else {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't broadcast transaction", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
} catch (ex) {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't broadcast transaction", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
});
});
} else {
app.dialog.close();
app.dialog.alert(resp.msg, "Error");
}
}, function (errorData) {
app.dialog.close();
try {
var error = $.parseJSON(errorData.responseText);
if (error && typeof error.msg != 'undefined') {
app.dialog.alert(error.msg, "Error");
sendErrorReport("Crypto", "Couldn't get transaction fees", error.msg);
} else {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't get transaction fees", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
} catch (ex) {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't get transaction fees", "Server/network problem: " + errorData.status + ": " + errorData.statusText);
}
});
}, function (error) {
app.dialog.close();
app.dialog.alert(error, "Error");
});
}
function walletGUISendCoins() {
if (!walletPubKeyRegex.test($('#walletAddress').text())) {
app.dialog.alert("Your wallet address doesn't look right. Check it and try again.", "Error");
return;
}
if (isNaN($('#transactionAmount').val()) || $('#transactionAmount').val() < 0.00000001) {
app.dialog.alert("The amount to send doesn't look right. Check it and try again.", "Error");
return;
}
// Remove payment request URL stuff
if ($('#walletToAddress').val().startsWith("bitcoin:")) {
$('#walletToAddress').val($('#walletToAddress').val().replace("bitcoin:", ""));
}
if ($('#walletToAddress').val().startsWith("dogecoin:")) {
$('#walletToAddress').val($('#walletToAddress').val().replace("dogecoin:", ""));
}
if (!walletPubKeyRegex.test($('#walletToAddress').val())) {
app.dialog.alert("The recipient's wallet address doesn't look right. Check it and try again.", "Error");
return;
}
sendCoins($('#walletPrivateKey').val(), $('#walletAddress').text(), $('#walletToAddress').val(), parseFloat($('#transactionAmount').val()));
}
function openWalletBalancePage( {to, resolve, reject}) {
var address = to.params.walletaddress;
if (!walletPubKeyRegex.test(address)) {
app.dialog.alert("That doesn't look like a valid wallet address.", "Error");
reject();
return;
}
app.dialog.preloader("Loading...");
apirequest(SETTINGS.apis.walletbalance, {
walletaddress: address
}, function (resp) {
app.dialog.close();
if (resp.status == "OK") {
var context = {
balance: resp.balance,
currencyunit: resp.currency,
fiatvalue: resp.usdvalue,
currencyname: resp.label,
attribution: resp.attribution,
exchangerate: resp.exchangerates.usd,
logo: "./assets/images/crypto/" + resp.currency + ".svg",
walletaddress: to.params.walletaddress,
sendtoaddress: (typeof to.params.toaddress != "undefined" ? to.params.toaddress : ""),
sendtoamount: (typeof to.params.amount != "undefined" ? to.params.amount : "")
};
resolve({
content: compiledPages.crypto_wallet(context)
});
} else {
reject();
app.dialog.alert(resp.msg, "Error");
}
}, function (error) {
reject();
app.dialog.close();
try {
var error = $.parseJSON(error.responseText);
if (error && typeof error.msg != 'undefined') {
app.dialog.alert(error.msg, "Error");
sendErrorReport("Crypto", "Couldn't get wallet balance", error.msg);
} else {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't get wallet balance", "Server/network problem: " + error.status + ": " + error.statusText);
}
} catch (ex) {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later. Your funds are safe.", "Error");
sendErrorReport("Crypto", "Couldn't get wallet balance", "Server/network problem: " + error.status + ": " + error.statusText);
}
});
}
/**
* Setup an input for specifying amount to send in USD, with conversion to crypto.
* @param {string} walletAddress Detects cryptocurrency from wallet address
* @returns {undefined}
*/
function setupFiatConversion(walletAddress) {
apirequest(SETTINGS.apis.walletbalance, {
walletaddress: walletAddress
}, function (resp) {
if (resp.status != "OK") {
return;
}
if (resp.exchangerates.usd == -1) {
return;
}
$("#cryptoFiatInputItem").css("display", "");
$("#cryptoAmountSendCurrencyLabel").text(resp.currency);
$("#cryptoAmountSendFiatLabel").text("$");
$("#transactionAmountFiat").data("exchange-rate", resp.exchangerates.usd);
$("#transactionAmountFiat").data("cryptocurrency", resp.currency);
$("#transactionAmount").off("input change paste keyup");
$("#transactionAmountFiat").off("input change paste keyup");
$("#transactionAmount").on("input change paste keyup", function () {
if ($("#cryptoFiatInputItem").css("display") == "none") {
return;
}
var amount = parseFloat($("#transactionAmount").val());
var exchangerate = parseFloat($("#transactionAmountFiat").data("exchange-rate"));
$("#transactionAmountFiat").val((amount * exchangerate).toFixed(2));
//$("#transactionAmount").val(amount.toFixed(8));
});
$("#transactionAmountFiat").on("input change paste keyup", function () {
if ($("#cryptoFiatInputItem").css("display") == "none") {
return;
}
var fiatamount = parseFloat($("#transactionAmountFiat").val());
var exchangerate = parseFloat($("#transactionAmountFiat").data("exchange-rate"));
$("#transactionAmount").val((fiatamount / exchangerate).toFixed(8));
});
if ($("#transactionAmount").val() != "") {
// Update the fiat conversion calculation if there's an amount prefilled
$("#transactionAmount").trigger("input");
}
});
}
function setupReceiveFiatConversion() {
var exchangerate = $("#receiveAmountFiat").data("exchangerate");
var fiatlabel = $("#receiveAmountFiat").data("currencylabel");
if (exchangerate == -1) {
return;
}
$("#cryptoAmountReceiveFiatLI").css("display", "");
$("#cryptoAmountReceiveFiatLabel").text(fiatlabel);
$("#receiveAmount").off("input change paste keyup");
$("#receiveAmountFiat").off("input change paste keyup");
$("#receiveAmount").on("input change paste keyup", function () {
if ($("#cryptoAmountReceiveFiatLI").css("display") == "none") {
return;
}
var amount = parseFloat($("#receiveAmount").val());
var exchangerate = parseFloat($("#receiveAmountFiat").data("exchangerate"));
$("#receiveAmountFiat").val((amount * exchangerate).toFixed(2));
});
$("#receiveAmountFiat").on("input change paste keyup", function () {
var fiatamount = parseFloat($("#receiveAmountFiat").val());
var exchangerate = parseFloat($("#receiveAmountFiat").data("exchangerate"));
$("#receiveAmount").val((fiatamount / exchangerate).toFixed(8));
});
if ($("#receiveAmount").val() != "") {
// Update the fiat conversion calculation if there's an amount prefilled
$("#receiveAmount").trigger("input");
}
}
/**
* Hides the fiat conversion input box.
* @returns {undefined}
*/
function unsetupFiatConversion() {
$("#cryptoFiatInputItem").css("display", "none");
$("#cryptoAmountSendCurrencyLabel").text("");
$("#transactionAmountFiat").removeData("exchange-rate");
$("#transactionAmountFiat").removeData("cryptocurrency");
$("#transactionAmount").off("input change paste keyup");
$("#transactionAmountFiat").off("input change paste keyup");
}
function showPaymentRequestQRCode() {
var paymenturi = "";
switch ($("#receiveAmount").data("currency")) {
case "DOGE":
paymenturi = "dogecoin:";
break;
case "BTC":
paymenturi = "bitcoin:";
break;
}
paymenturi += $('#walletAddress').text();
if ($("#receiveAmount").val() > 0) {
paymenturi += "?amount=" + $("#receiveAmount").val();
}
$("#paymentRequestQRCodeContainer").html("");
new QRCode(document.getElementById("paymentRequestQRCodeContainer"), paymenturi);
}
$("#app").on("click", "#sendCryptoOpenPopupBtn", function () {
if (platform_type == "cordova") {
if (cordova.platformId == "ios") {
app.dialog.create({
title: "Switch to Web Version",
text: "Apple doesn't allow this feature on the App Store. Tap Continue to launch the web version of this app instead, which is allowed to send crypto. We're sorry for the inconvenience.",
verticalButtons: true,
buttons: [
{
text: "Continue",
bold: true,
keyCodes: [13],
onClick: function () {
openExternalBrowser("https://app.helena.express/?startpage=crypto");
}
},
{
text: "Cancel",
color: "red"
}
]
}).open();
return;
}
}
app.popup.open("#sendCryptoPopup");
if (walletPubKeyRegex.test($("#walletAddress").text())) {
setupFiatConversion($("#walletAddress").text());
} else {
unsetupFiatConversion();
}
});

@ -78,7 +78,7 @@ $("body").on("popup:open", "#dasLocationMapPopup", function () {
dropboxMap.reloadMap();
dropboxMap.mapObj.on('load', function () {
dropboxMap.mapObj.jumpTo({center: [-112.005, 46.589], zoom: 8});
dropboxMap.loadIcon("./assets/images/dropbox-icon.png", "dropbox", function () {
dropboxMap.loadIcon("./assets/images/DAS_marker.png", "dropbox", function () {
apirequest(SETTINGS.apis.dropandsendlocations, {}, function (data) {
dropboxMap.loadMarkersFromGeoJson(data, "dropbox", "dropbox");
dropboxMap.mapObj.on('click', 'marker-layer-dropbox', function (e) {

@ -33,6 +33,8 @@ function openGenericBarcodeScanner() {
} else if (trackingcoderegex.test(result)) {
code = result;
action = "track";
} else if (result.startsWith("https://helena.express/")) {
action = "hlnexurl";
}
switch (action) {
@ -49,6 +51,9 @@ function openGenericBarcodeScanner() {
router.navigate("/crypto?paymenturi=" + code);
//app.dialog.alert("Not implemented.");
break;
case "hlnexurl":
handleDeepLink(result);
break;
default:
app.dialog.alert("This app can't understand what's in that barcode.", "Error");
return;

@ -0,0 +1,128 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/**
* Open a location on the map.
* @param {type} e
* @returns {undefined}
*/
var openMapLocationInfo = function (e) {
var coordinates = e.geometry.coordinates.slice();
showLocationDetails(e);
locationMap.mapObj.resize();
locationMap.mapObj.easeTo({
center: [coordinates[0], coordinates[1]],
zoom: 15,
bearing: 0,
pitch: 0
});
};
var showLocationDetails = function (e) {
var coordinates = e.geometry.coordinates.slice();
var name = e.properties.name;
var info = e.properties.info;
var hours = e.properties.hours;
var geolink = "geo:" + (Math.round(coordinates[1] * 1000000) / 1000000) + "," + (Math.round(coordinates[0] * 1000000) / 1000000);
var typeinfo = "";
if (e.properties.branding == "DAS") {
typeinfo = "<b>Drop and Send&#8480; Drop Box</b><br />Use this app to send packages from this box, no postage necessary. Just put your package inside and scan the QR code with this app.";
} else if (e.properties.branding == "PP") {
typeinfo = "<b>PostalPoint&trade; Kiosk</b><br />Purchase postage, send USPS packages, and get free boxes here.";
}
$("#locationInfoName").text(name);
$("#locationInfoModalContainer").html(
"<div class='row'><div class='col-50'>"
+ "<a class=\"button button-small\" href=\"" + geolink + "\"><i class=\"fas fa-location-circle\"></i>&nbsp; Directions</a>"
+ "</div>"
+ "<div class='col-50'>"
+ (e.properties.branding == "DAS" ? "<a class=\"button button-small sheet-close\" href=\"\" onclick=\"router.navigate('/das');\"><i class=\"fas fa-info-circle\"></i>&nbsp; More Info</a>" : "")
+ (e.properties.branding == "PP" ? "<a class=\"button button-small sheet-close\" href=\"\" onclick=\"router.navigate('/kiosk');\"><i class=\"fas fa-info-circle\"></i>&nbsp; More info</a>" : "")
+ "</div></div>"
+ typeinfo + "<br />"
+ (hours == "" ? "" : "<b>Hours:</b> " + hours)
+ "<br /><b>Info:</b> " + info
);
app.sheet.open("#locationInfoModal");
};
function loadLocationMap() {
if (MapControl.supported()) {
if (locationMap == null) {
app.preloader.show();
var mapboxel = document.getElementById("mapbox-locations");
locationMap = new MapControl(mapboxel, true);
locationMap.reloadMap();
var locationMapLoaded = false;
locationMap.mapObj.on('load', function () {
locationMapLoaded = true;
});
apirequest(SETTINGS.apis.locations, {}, function (resp) {
var loadWhenMapReady = function () {
if (locationMapLoaded) {
setupLocationMap(resp);
} else {
setTimeout(function () {
loadWhenMapReady();
}, 100);
}
}
loadWhenMapReady();
}, function (xhr) {
app.preloader.hide();
try {
var error = $.parseJSON(xhr.responseText);
if (error && typeof error.msg != 'undefined') {
app.dialog.alert(error.msg, "Error");
sendErrorReport("Location Map", "Couldn't get locations GeoJSON", error.msg);
} else {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
sendErrorReport("Location Map", "Couldn't get locations GeoJSON", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
}
} catch (ex) {
app.dialog.alert("There's a server or network problem. Check your Internet connection or try again later.", "Error");
sendErrorReport("Location Map", "Couldn't get locations GeoJSON", "Server/network problem: " + xhr.status + ": " + xhr.statusText);
}
});
}
} else {
showWebGLErrorMessage();
app.preloader.hide();
}
}
function setupLocationMap(geojson) {
app.preloader.hide();
geojson.features.forEach((marker) => {
const el = document.createElement('div');
el.className = 'marker';
el.style.backgroundImage = "url(./assets/images/" + marker.properties.branding + "_marker.png)";
el.style.width = "32px";
el.style.height = "32px";
el.style.cursor = "pointer";
el.addEventListener('click', () => {
openMapLocationInfo(marker);
});
new maplibregl.Marker({element: el})
.setLngLat(marker.geometry.coordinates)
.addTo(locationMap.mapObj);
});
locationMap.mapObj.jumpTo({center: [-112.005, 46.589], zoom: 9});
}
$("body").on("sheet:open", "#locationInfoModal", function () {
$("#mapbox-locations").addClass("sheet-open");
locationMap.mapObj.resize();
});
$("body").on("sheet:close", "#locationInfoModal", function () {
$("#mapbox-locations").removeClass("sheet-open");
locationMap.mapObj.resize();
locationMap.mapObj.easeTo({center: [-112.005, 46.589], zoom: 9});
});

@ -23,6 +23,9 @@ var app = new Framework7({
popover: {
backdrop: true
},
sheet: {
backdrop: false
},
touch: {
tapHold: true
},
@ -226,6 +229,38 @@ function openStartpageURLArg() {
return false;
}
/**
* Get the cached dynamic page content if available, else return null (and try to fetch it for next time)
* @param {string} page the page ID
* @returns {string|null}
*/
function getDynamicPageContent(page) {
if (inStorage("dynamiccontent_" + page)) {
return getStorage("dynamiccontent_" + page);
}
apirequest(SETTINGS.apis.dynamicappcontent, {page: page}, function (resp) {
if (resp.status == "OK") {
setStorage("dynamiccontent_" + resp.page, resp.content);
}
});
return null;
}
// update dynamic page text cache
setTimeout(function () {
dynamicPages.forEach(function (pageid) {
// Only update if it's been over eight hours since last update
if (!inStorage("dynamiccontent-lastupdated_" + pageid) || getStorage("dynamiccontent-lastupdated_" + pageid) < time() - 60 * 60 * 8) {
apirequest(SETTINGS.apis.dynamicappcontent, {page: pageid}, function (resp) {
if (resp.status == "OK") {
setStorage("dynamiccontent_" + resp.page, resp.content);
setStorage("dynamiccontent-lastupdated_" + resp.page, time());
}
});
}
});
}, 500);
if (setup) {
router.navigate("/home");
} else {

@ -7,6 +7,7 @@
var dropboxMap = null;
var serviceAreaMap = null;
var locationMap = null;
function showWebGLErrorMessage() {
app.dialog.alert("Well, this is awkward. Your device doesn't support displaying the map. If your \n\

@ -1,36 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
$("#app").on("submit", "#moneyorderForm", function (e) {
e.preventDefault();
verifyMoneyOrder($('#moneyorderserial').val());
return false;
});
function verifyMoneyOrder(serial) {
if (typeof serial != "string" || serial == "" || /^[0-9]{3,8}$/.test(serial) == false) {
app.dialog.alert("Enter a valid Helena Express money order serial number.", "Whoops!");
return;
}
app.dialog.preloader("Working...");
apirequest(SETTINGS.apis.moneyorderverify, {
serial: serial
}, function (resp) {
app.dialog.close();
if (resp.status == "OK") {
app.dialog.alert("Amount: $" + resp.amount
+ "<br>Issued: " + resp.issued_date + " UTC"
+ (resp.mo_status == "" ? "" : "<br>Status: " + resp.mo_status),
"Money Order #" + resp.serial);
} else {
app.dialog.alert(resp.msg, "Error");
}
}, function (error) {
app.dialog.close();
app.dialog.alert("Connection or server error. Try again later.", "Whoops!");
sendErrorReport("Money Order", "Verification");
});
}

@ -141,6 +141,96 @@ function setupCordovaBarcodeScanner() {
};
}
/**
* Handle a deep link.
* @param {string} href the link
* @returns {boolean} true if handled, false if rejected.
*/
function handleDeepLink(href) {
var link = new URL(href);
if (link.host != "helena.express") {
return false;
}
if (link.hash) {
link.fragment = link.hash.substr(1);
}
switch (link.pathname) {
case "/":
break;
case "/app":
case "/app/get":
app.dialog.alert("You already have the Helena Express app. You're using it right now!", "Hi there!");
break;
case "/das":
router.navigate("/das");
break;
case "/das/map":
router.navigate("/das");
break;
case "/das/pickup":
if (link.fragment) {
sendPickupCode(link.fragment);
} else {
router.navigate("/das");
}
break;
case "/das/account":
router.navigate("/account");
break;
case "/fast":
router.navigate("/quicksend");
break;
case "/kiosk":
router.navigate("/kiosk");
break;
case "/manifest":
openExternalBrowser(link.href);
break;
case "/mobile":
case "/mobile/":
router.navigate("/mobile");
break;
case "/notary":
router.navigate("/notary");
break;
case "/pickup":
router.navigate("/pickup");
break;
case "/locations":
router.navigate("/locations");
break;
case "/rates":
router.navigate("/rates");
break;
case "/review":
openExternalBrowser("https://helena.express/review");
break;
case "/schedule":
router.navigate("/appointment");
break;
case "/send":
router.navigate("/send");
break;
case "/shop":
router.navigate("/shop");
break;
case "/telegram":
case "/telegram/":
router.navigate("/telegram");
break;
case "/track":
if (link.fragment) {
router.navigate("/track/" + link.fragment);
} else {
router.navigate("/track");
}
break;
default:
openBrowser(link.href);
}
return true;
}
function initCordova() {
platform_type = "cordova";
@ -221,57 +311,9 @@ function initCordova() {
}
IonicDeeplink.onDeepLink(function (link) {
if (link.host != "helena.express") {
return;
}
// Wait a bit so the home page has time to load first.
setTimeout(function () {
switch (link.path) {
case "/":
break;
case "/track":
if (link.fragment) {
router.navigate("/track/" + link.fragment);
} else {
router.navigate("/track");
}
break;
case "/rates":
router.navigate("/rates");
break;
case "/schedule":
router.navigate("/appointment");
break;
case "/shop":
router.navigate("/shop");
break;
case "/pickup":
router.navigate("/send");
break;
case "/telegram":
case "/telegram/":
router.navigate("/telegram");
break;
case "/das":
router.navigate("/dropandsend");
break;
case "/das/map":
router.navigate("/dropandsend");
break;
case "/das/pickup":
if (link.fragment) {
sendPickupCode(link.fragment);
} else {
router.navigate("/dropandsend");
}
break;
case "/das/account":
router.navigate("/account");
break;
default:
openBrowser(link.url);
break;
}
handleDeepLink(link.url);
}, 1000);
});
}, false);

@ -0,0 +1,52 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function showAddressQRCode() {
var content = "QSv1|tofrom"
+ "|" + (inStorage("accountnumber") ? getStorage("accountnumber") : "")
+ "|" + $("#addresscodeform #to_name").val()
+ "|" + $("#addresscodeform #to_company").val()
+ "|" + $("#addresscodeform #to_street1").val()
+ "|" + $("#addresscodeform #to_street2").val()
+ "|" + $("#addresscodeform #to_city").val()
+ "|" + $("#addresscodeform #to_state").val()
+ "|" + $("#addresscodeform #to_zip").val()
+ "|" + $("#addresscodeform #to_country").val()
+ "|" + $("#addresscodeform #to_phone").val()
+ "|" // email
+ "|" + $("#addresscodeform #from_name").val()
+ "|" + $("#addresscodeform #from_company").val()
+ "|" + $("#addresscodeform #from_street1").val()
+ "|" + $("#addresscodeform #from_street2").val()
+ "|" // city
+ "|" // state
+ "|" + $("#addresscodeform #from_zip").val()
+ "|" // country
+ "|" + $("#addresscodeform #from_phone").val()
+ "|"; // email
setStorage("quicksend_name", $("#addresscodeform #from_name").val());
setStorage("quicksend_company", $("#addresscodeform #from_company").val());
setStorage("quicksend_street1", $("#addresscodeform #from_street1").val());
setStorage("quicksend_street2", $("#addresscodeform #from_street2").val());
setStorage("quicksend_zip", $("#addresscodeform #from_zip").val());
setStorage("quicksend_phone", $("#addresscodeform #from_phone").val());
var canvas = document.createElement('canvas');
bwipjs.toCanvas(canvas, {
bcid: 'pdf417', // Barcode type
text: content, // Text to encode
scale: 5,
includetext: false, // Show human-readable text
textxalign: 'center', // Always good to set this
eclevel: 'M'
});
document.getElementById("addresscode-barcode").src = canvas.toDataURL('image/png');
app.popup.create({el: document.getElementById("qrCodePopup")}).open();
}

@ -6,7 +6,7 @@
function sendErrorReport(category, error, errordata) {
if (getStorage("analytics") !== "false") {
if (getStorage("analytics") !== "false" && typeof _paq !== "undefined") {
try {
if (typeof errordata == "undefined") {
_paq.push(['trackEvent', 'Error', category, error]);
@ -20,7 +20,7 @@ function sendErrorReport(category, error, errordata) {
}
function sendActionReport(category, action, data) {
if (getStorage("analytics") !== "false") {
if (getStorage("analytics") !== "false" && typeof _paq !== "undefined") {
try {
if (typeof data == "undefined") {
_paq.push(['trackEvent', 'User Action', category, action]);
@ -34,7 +34,7 @@ function sendActionReport(category, action, data) {
}
function trackPageView(url, title) {
if (getStorage("analytics") !== "false") {
if (getStorage("analytics") !== "false" && typeof _paq !== "undefined") {
try {
_paq.push(['setCustomUrl', "https://app.helena.express" + url]);
_paq.push(['setDocumentTitle', title]);

@ -12,7 +12,11 @@
* @returns {undefined}
*/
function setStorage(key, value) {
localStorage.setItem(key, value);
if (typeof value == "string") {
localStorage.setItem(key, value);
} else {
localStorage.setItem(key, "JSON|" + JSON.stringify(value));
}
}
/**
@ -21,7 +25,12 @@ function setStorage(key, value) {
* @returns {DOMString}
*/
function getStorage(key) {
return localStorage.getItem(key);
var val = localStorage.getItem(key);
if (typeof val == "string" && val.startsWith("JSON|")) {
return JSON.parse(val.substr(5));
} else {
return val;
}
}
function removeFromStorage(key) {

@ -193,7 +193,8 @@ function trackOpenAsync( {to, resolve, reject}) {
enabled: (typeof resp.info.latitude == "number" && typeof resp.info.longitude == "number" && MapControl.supported()),
latitude: resp.info.latitude,
longitude: resp.info.longitude,
accurate: resp.info.geoaccurate
accurate: resp.info.geoaccurate,
geoiscountrylevel: (typeof resp.info.geoiscountrylevel == "undefined" ? false : resp.info.geoiscountrylevel)
}
};
if (resp.info.statustext) {

@ -44,9 +44,8 @@
<script src="node_modules/template7/dist/template7.min.js"></script>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/maplibre-gl/dist/maplibre-gl.js"></script>
<script src="node_modules/bwip-js/dist/bwip-js-min.js"></script>
<script src="assets/js/qrcode.min.js"></script>
<script src="assets/js/bitcore-lib.min.js"></script>
<script src="assets/js/bitcore-lib-doge.min.js"></script>
<script src="settings.js"></script>
@ -67,9 +66,9 @@
<script src="assets/js/account.js"></script>
<script src="assets/js/shop.js"></script>
<script src="assets/js/home.js"></script>
<script src="assets/js/crypto.js"></script>
<script src="assets/js/serviceareamap.js"></script>
<script src="assets/js/moneyorder.js"></script>
<script src="assets/js/locationmap.js"></script>
<script src="assets/js/quicksend.js"></script>
<script src="routes.js"></script>
<script src="assets/js/main.js"></script>

@ -1,16 +1,17 @@
{
"name": "HelenaExpressApp",
"version": "2.0.3",
"version": "2.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "HelenaExpressApp",
"version": "2.0.3",
"version": "2.0.4",
"license": "MPL-2.0",
"dependencies": {
"@fortawesome/fontawesome-pro": "^6",
"@zxing/library": "^0.15.2",
"bwip-js": "^3.1.0",
"framework7": "^7.0.2",
"jquery": "^3.6.0",
"maplibre-gl": "^1.15.3",
@ -103,6 +104,14 @@
"text-encoding": "^0.7.0"
}
},
"node_modules/bwip-js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bwip-js/-/bwip-js-3.1.0.tgz",
"integrity": "sha512-H+4s1/25kC/ybwt+o0zhFkbTL4nGrzZV7KW44luWqT/ClmCzhXVqVgaNx8d9YoOUVKR461xDmLt3eGDRtGqRag==",
"bin": {
"bwip-js": "bin/bwip-js.js"
}
},
"node_modules/csscolorparser": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
@ -199,40 +208,6 @@
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
},
"node_modules/mapbox-gl": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.2.tgz",
"integrity": "sha512-CPjtWygL+f7naL+sGHoC2JQR0DG7u+9ik6WdkjjVmz2uy0kBC2l+aKfdi3ZzUR7VKSQJ6Mc/CeCN+6iVNah+ww==",
"peer": true,
"dependencies": {
"@mapbox/geojson-rewind": "^0.5.0",
"@mapbox/geojson-types": "^1.0.2",
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
"@mapbox/mapbox-gl-supported": "^1.5.0",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/tiny-sdf": "^1.1.1",
"@mapbox/unitbezier": "^0.0.0",
"@mapbox/vector-tile": "^1.3.1",
"@mapbox/whoots-js": "^3.1.0",
"csscolorparser": "~1.0.3",
"earcut": "^2.2.2",
"geojson-vt": "^3.2.1",
"gl-matrix": "^3.2.1",
"grid-index": "^1.1.0",
"minimist": "^1.2.5",
"murmurhash-js": "^1.0.0",
"pbf": "^3.2.1",
"potpack": "^1.0.1",
"quickselect": "^2.0.0",
"rw": "^1.3.3",
"supercluster": "^7.1.0",
"tinyqueue": "^2.0.3",
"vt-pbf": "^3.1.1"
},
"engines": {
"node": ">=6.4.0"
}
},
"node_modules/maplibre-gl": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-1.15.3.tgz",
@ -469,6 +444,11 @@
"ts-custom-error": "^3.0.0"
}
},
"bwip-js": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bwip-js/-/bwip-js-3.1.0.tgz",
"integrity": "sha512-H+4s1/25kC/ybwt+o0zhFkbTL4nGrzZV7KW44luWqT/ClmCzhXVqVgaNx8d9YoOUVKR461xDmLt3eGDRtGqRag=="
},
"csscolorparser": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
@ -540,37 +520,6 @@
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
},
"mapbox-gl": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.2.tgz",
"integrity": "sha512-CPjtWygL+f7naL+sGHoC2JQR0DG7u+9ik6WdkjjVmz2uy0kBC2l+aKfdi3ZzUR7VKSQJ6Mc/CeCN+6iVNah+ww==",
"peer": true,
"requires": {
"@mapbox/geojson-rewind": "^0.5.0",
"@mapbox/geojson-types": "^1.0.2",
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
"@mapbox/mapbox-gl-supported": "^1.5.0",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/tiny-sdf": "^1.1.1",
"@mapbox/unitbezier": "^0.0.0",
"@mapbox/vector-tile": "^1.3.1",
"@mapbox/whoots-js": "^3.1.0",
"csscolorparser": "~1.0.3",
"earcut": "^2.2.2",
"geojson-vt": "^3.2.1",
"gl-matrix": "^3.2.1",
"grid-index": "^1.1.0",
"minimist": "^1.2.5",
"murmurhash-js": "^1.0.0",
"pbf": "^3.2.1",
"potpack": "^1.0.1",
"quickselect": "^2.0.0",
"rw": "^1.3.3",
"supercluster": "^7.1.0",
"tinyqueue": "^2.0.3",
"vt-pbf": "^3.1.1"
}
},
"maplibre-gl": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-1.15.3.tgz",

@ -1,11 +1,12 @@
{
"name": "HelenaExpressApp",
"version": "2.0.3",
"version": "2.1.0",
"main": "index.html",
"license": "MPL-2.0",
"dependencies": {
"@fortawesome/fontawesome-pro": "^6",
"@zxing/library": "^0.15.2",
"bwip-js": "^3.1.0",
"framework7": "^7.0.2",
"jquery": "^3.6.0",
"maplibre-gl": "^1.15.3",

@ -40,11 +40,6 @@
Your Account Number:
<h2><span id="accountnumberspan">Loading...</span></h2>
</div>
<div id="loyaltyBalanceBox" class="card-content-padding">
<div>You have earned a total of</div>
<h2 id="loyaltyCreditBalanceHeading">...</h2>
<img id="loyaltyBarcodeImg" style="width: 90%; max-width: 300px; padding: 1.2em; background: white; display: none;" />
</div>
<div class="row">
<div class="col-100 medium-50">
<div class="block padding-half">
@ -57,12 +52,7 @@
</div>
</div>
</div>
<div id="loyaltyErrorMessage"></div>
<div class="block margin-top">
Loyalty points have no cash value. All points and associated discounts
are offered as a courtesy by and at the discretion of Helena Express
and may be revoked, canceled, or modified at any time for any reason.
</div>
<div id="accountErrorMessage"></div>
</div>

@ -1,67 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="crypto">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Crypto Wallet</div>
</div>
</div>
<div class="page-content">
<div class="row justify-content-center">
<div class="col-100 medium-60 large-70">
<div class="swiper margin-top" id="crypto-intro-swiper">
<div class="swiper-wrapper">
{{#each slideshow}}
<div class="swiper-slide display-flex justify-contenty-center align-items-center flex-direction-column">
<img src="{{image}}" style="max-height: 40vh; max-width: 90%; height: 50rem;"/>
<p class="text-align-center margin padding">{{text}}</p>
</div>
{{/each}}
</div>
<div id="crypto-intro-swiper-pagination" class="swiper-pagination"></div>
</div>
</div>
<div class="col-100 medium-40 large-30">
<div class="block text-align-center">
<div class="button hapticbtn button-fill" onclick="scanWalletQrCode(openWalletPage);"><i class="fa-solid fa-qrcode"></i> Scan Wallet</div>
</div>
<div class="block text-align-center">
<a href="#" onclick="$('#wallet-address-manual-entry').removeClass('display-none');$('a[name=wallet-address-manual-entry-anchor]').get(0).scrollIntoView();">Can't scan? <span class="taptext">Tap</span><span class="clicktext">Click</span> here.</a>
</div>
<div class="block">
<div class="list margin-bottom-half display-none" id="wallet-address-manual-entry">
<ul class="padding">
<li class="item-content">
Type your wallet's public address below, then press the open wallet button.
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" id="walletPubKeyManualEntry" placeholder="1X68a3n1..." />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content">
<div class="button button-outline hapticbtn" onclick="openWalletPage($('#walletPubKeyManualEntry').val());">Open Wallet</div>
</li>
</ul>
</div>
<a name="wallet-address-manual-entry-anchor" href="#wallet-address-manual-entry-anchor"></a>
</div>
</div>
</div>
</div>
</div>

@ -1,209 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="crypto_wallet">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Crypto Wallet</div>
</div>
</div>
<div class="page-content">
<div class="card-content-padding text-align-center">
<img id="walletBalanceLogo" style="max-height: 25vh; max-width: 25vw; height: 5em;" src="{{logo}}" />
<p>This <span id="walletCurrency">{{currencyname}}</span> wallet contains</p>
<h2><span id="walletBalanceAmount">{{balance}} {{currencyunit}}</span></h2>
<p>currently worth</p>
<h2><span id="walletFiatAmount">{{fiatvalue}}</span></h2>
</div>
<div class="row justify-content-center">
<div class="col-100 medium-50 large-30">
<div class="block">
<div class="button hapticbtn button-fill popup-open" id="sendCryptoOpenPopupBtn"><i class="fa-solid fa-inbox-out"></i> Send</div>
</div>
<div class="block">
<div class="button hapticbtn button-fill popup-open" data-popup="#receiveCryptoPopup" id="receiveCryptoOpenPopupBtn"><i class="fa-solid fa-inbox-in"></i> Receive</div>
</div>
</div>
</div>
<div class="card-content-padding text-color-gray text-align-center" id="walletAddress">{{walletaddress}}</div>
<div class="card-content-padding text-color-gray text-align-center" id="walletBalanceAttribution">
{{attribution}}
</div>
</div>
<div class="popup" id="sendCryptoPopup">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link popup-close" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Close</span>
</a>
</div>
<div class="title">Send Crypto</div>
</div>
</div>
<div class="list margin-bottom-half">
<ul>
<li class="item-divider">Step 1</li>
<li class="item-content">
<div class="item-inner">
Scan your private key. The private key unlocks your wallet and authorizes the transfer.
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" id="walletPrivateKey" placeholder="6JJRxyW..." />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content">
<div class="button hapticbtn button-fill" onclick="scanPrivateKeyQrCode(function (d) {
$('#walletPrivateKey').val(d);
});"><i class="fa-solid fa-key"></i> Scan Private Key
</div>
</li>
<li class="item-divider">Step 2</li>
<li class="item-content">
<div class="item-inner">
Scan or paste the recipient's wallet address.
The money will be sent here. Important: the recipient must be expecting the
same cryptocurrency your wallet uses. Otherwise the money will
be lost forever.
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" id="walletToAddress" placeholder="1X68a3n1..." value="{{sendtoaddress}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content">
<div class="button hapticbtn button-fill" onclick="scanWalletQrCode(function (d) {
var parsed = parsePaymentURI(d);
if (parsed == null) {
$('#walletToAddress').val(d);
} else {
$('#walletToAddress').val(parsed.address);
if (typeof parsed['amount'] != 'undefined') {
$('#transactionAmount').val(parsed.amount);
}
}
});"><i class="fa-solid fa-inbox-in"></i> Scan Recipient's Wallet
</div>
</li>
<li class="item-divider">Step 3</li>
<li class="item-content">
<div class="item-inner">
Enter the amount to send.
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label" id="cryptoAmountSendCurrencyLabel"></div>
<div class="item-input-wrap">
<input type="number" id="transactionAmount" step="0.00000001" min="0.00000001" max="999999.99999999" value="{{sendtoamount}}"/>
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input" id="cryptoFiatInputItem" style="display: none;">
<div class="item-inner">
<div class="item-title item-label" id="cryptoAmountSendFiatLabel"></div>
<div class="item-input-wrap">
<input type="number" id="transactionAmountFiat" step="0.01" min="0.01" max="9999.99"/>
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-divider">Step 4</li>
<li class="item-content">
<div class="item-inner">
<div><span class="taptext">Tap</span><span class="clicktext">Click</span> the button to send the transaction.</div>
</div>
</li>
<li class="item-content">
<div class="button hapticbtn button-fill" onclick="walletGUISendCoins()">
<i class="fa-solid fa-paper-plane"></i> Send Transaction
</div>
</li>
<li class="item-content">
<div class="button hapticbtn popup-close" onclick="$('#walletPrivateKey').val('');" >
<i class="fa-solid fa-xmark"></i> Cancel
</div>
</li>
</ul>
</div>
</div>
<div class="popup" id="receiveCryptoPopup">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link popup-close" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Close</span>
</a>
</div>
<div class="title">Request Crypto</div>
</div>
</div>
<div class="margin">
Enter the amount to request.
</div>
<div class="list margin-bottom-half margin-top-half">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label" id="cryptoAmountReceiveCurrencyLabel">{{currencyunit}}</div>
<div class="item-input-wrap">
<input type="number" id="receiveAmount" step="0.00000001" min="0.00000001" max="999999.99999999" data-currency="{{currencyunit}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input" id="cryptoAmountReceiveFiatLI" style="display: none;">
<div class="item-inner">
<div class="item-title item-label" id="cryptoAmountReceiveFiatLabel"></div>
<div class="item-input-wrap">
<input type="number" id="receiveAmountFiat" step="0.01" min="0.01" max="9999.99" data-exchangerate="{{exchangerate}}" data-currencylabel="$"/>
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content">
<div class="button hapticbtn button-fill" onclick="showPaymentRequestQRCode()">
<i class="fa-solid fa-qrcode"></i> Show Payment Request Code
</div>
</li>
</ul>
</div>
<div id="paymentRequestQRCodeContainer" class="block display-flex justify-content-center"></div>
</div>
</div>

@ -41,11 +41,11 @@
</li>
<li class="padding text-align-center" id="pickupLateInDayWarning" style="display: none;">
<i class="fa-duotone fa-clock fa-2x text-color-purple"></i><br>
Packages dropped off after 4PM might not be shipped until the following day.
Packages dropped off after 3PM might not be shipped until the following day.
</li>
<li class="padding text-align-center" id="pickupWeekendWarning" style="display: none;">
<i class="fa-duotone fa-calendar-exclamation fa-2x text-color-blue"></i><br>
Most packages won't leave Helena until Monday.
We pick up packages every day, but many won't ship out until Monday.
</li>
<li>
<div class="item-content item-link hapticbtn popup-open" data-popup="#dasHowItWorksPopup">
@ -160,7 +160,7 @@
<i class="fa-regular fa-qrcode"></i> Scan the Pickup Code to alert us there's a package to send.
</li>
<li>
<i class="fa-duotone fa-receipt"></i> Wait for an emailed receipt from us with the tracking code. Your credit card is automatically billed for the cost of shipping.
<i class="fa-duotone fa-receipt"></i> Wait for an emailed receipt from us with the tracking code. Your credit card is automatically billed for the cost of shipping plus a small pickup fee.
</li>
</ul>
</div>

@ -0,0 +1,68 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="trailer">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Shipping Kiosks</div>
</div>
</div>
<div class="page-content noselect">
<div class="row justify-content-center">
<div class="col-100 medium-50 padding-top">
<div class="card">
<div class="card-body padding">
<div class="text-align-center">
<img src="./assets/images/postalpoint-logo-horizontal-black.svg" class="hidden-dark margin" style="max-height: 20vh; max-width: 80%;" />
<img src="./assets/images/postalpoint-logo-horizontal-white.svg" class="hidden-light margin" style="max-height: 20vh; max-width: 80%;" />
</div>
<div class="block margin-bottom" id="kiosk-dyncontent">
Visit a PostalPoint™ shipping kiosk to send mail and packages.
We've designed the kiosks with a simple and easy to use touchscreen, free boxes and envelopes, and a secure package drop.
You pay USPS retail prices with no markup. Free tracking and insurance included.
</div>
</div>
</div>
</div>
<div class="col-100 medium-50">
<div class="block-title">Locations</div>
<div class="list">
<ul>
{{#each locations}}
<li>
<a href="geo:{{geo}}" class="item-content item-link">
<div class="item-inner item-cell">
<div class="item-row">
<div class="item-cell">
<span style="font-weight: 600;">{{name}}</span>
<br />Hours: {{hours}}
</div>
</div>
<div class="item-row">
<div class="item-cell">
{{info}}
</div>
</div>
</div>
</a>
</li>
{{/each}}
</ul>
</div>
</div>
</div>
<div class="block text-align-center margin-top">
Helena Express is a founding member of the PostalPoint shipping network. PostalPoint is a trademark of PostalPortal LLC.
</div>
</div>
</div>

@ -0,0 +1,42 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="locations">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back sheet-close" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Locations</div>
</div>
</div>
<div class="page-content noselect">
<div class="toolbar">
<div class="toolbar-inner justify-content-start">
<span class="margin-horizontal-half padding-half"><img src="./assets/images/DAS_marker.png" style="height: 24px; vertical-align: middle;" /> Drop Box</span>
<span class="margin-horizontal-half padding-half"><img src="./assets/images/PP_marker.png" style="height: 24px; vertical-align: middle;" /> Kiosk</span>
</div>
</div>
<div id="mapbox-locations"></div>
</div>
<div class="sheet-modal" id="locationInfoModal">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="title" id="locationInfoName">Hide On Scroll</div>
<div class="right"><a class="link sheet-close" href="#"><i class="far fa-times if-not-ios"></i> <span class="if-ios">Close</span></a></div>
</div>
</div>
<div class="sheet-modal-inner">
<div class="block" id="locationInfoModalContainer"></div>
</div>
</div>
</div>

@ -1,42 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="money">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back hapticbtn" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Money</div>
</div>
</div>
<div class="page-content noselect">
<div class="row justify-content-center margin-top">
<div class="col-100 medium-90 xlarge-75 margin-horizontal">
<div class="row justify-content-center">
{{#each pages}}
<div class="col-100 small-50 large-33 no-margin-vertical">
<div class="card hapticbtn pointercursor" onclick="router.navigate('{{href}}');">
<div class="card-content text-align-center padding">
<h1 class="no-margin"><i class="{{icon}}"></i></h1>
<br />
<span style="font-weight: 700;">{{title}}</span>
<br />
<span>{{text}}</span>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</div>

@ -1,48 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="moneyorder">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Verify Money Order</div>
</div>
</div>
<div class="page-content">
<div class="row justify-content-center">
<div class="col-100 medium-90 xlarge-75 margin-horizontal">
<div class="card margin">
<form class="card-content padding-vertical" id="moneyorderForm">
<div class="list media-list">
<ul>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Serial Number</div>
<div class="item-input-wrap">
<input type="text" id="moneyorderserial" placeholder="12345" inputmode="numeric" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="padding">
<div class="button hapticbtn button-fill" onclick="verifyMoneyOrder($('#moneyorderserial').val())"><i class="fa-solid fa-magnifying-glass-dollar"></i> Verify</div>
</li>
</ul>
</div>
</form>
</div>
</div>
</div>
</div>
</div>

@ -19,7 +19,7 @@
<div class="page-content noselect">
<div class="row justify-content-center">
<div class="col-100 medium-60 large-70">
<div class="col-100 medium-60 large-70" id="notary-dyncontent">
<div class="swiper margin-top" id="notary-info-swiper">
<div class="swiper-wrapper">
<div class="swiper-slide display-flex justify-contenty-center align-items-center flex-direction-column">
@ -61,6 +61,11 @@
licensed to practice law. We are not allowed to draft legal
records, give advice on legal matters, including immigration, or charge
a fee for those activities.
<br />
<br />
<br />
<br />
<br />
</div>
</div>
</div>

@ -109,7 +109,7 @@
<!-- Checkbox icon -->
<i class="icon icon-checkbox"></i>
<span class="item-inner no-line-after">
<span>Package has a prepaid return label</span>
<span>Package has a prepaid return label (extra fees may apply to prepaid pickups)</span>
</span>
</label>
</li>

@ -0,0 +1,73 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="postalpoint">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">PostalPoint Kiosk</div>
</div>
</div>
<div class="page-content noselect">
<div class="row justify-content-center">
<div class="col-100 medium-50 padding-top">
<div class="card">
<div class="card-body padding-top">
<!-- <div class="block text-align-center">
<img src="assets/images/mail-trailer.svg" class="margin" style="max-height: 20vh; max-width: 80%;" />
</div> -->
<div class="block margin-bottom" id="postalpoint-dyncontent">
Our network of PostalPoint kiosks are a quick and convenient way to
send mail and packages. Located in local businesses, our kiosks have an
easy to use touchscreen and a secure parcel drop. You pay the normal
USPS prices without markup or fees.
<br /><br />
Walk in, put your box on the scale, answer a few questions, tap your
card, and get a shipping label (with postage). Then just place your package
in the secure locker. The kiosk can print or email a receipt so you'll
have the tracking number.
</div>
<div class="block margin-bottom">
Don't like typing addresses on the kiosk? With Quick Send, you can type
right here instead! Tap the button below, then tap "Quick Send" on the kiosk.
</div>
<div class="block">
<div class="button" onclick='router.navigate("/quicksend");'>
Open Quick Send
</div>
</div>
</div>
</div>
</div>
<div class="col-100 medium-50">
<div class="block-title">Locations</div>
<div class="list media-list">
<ul>
{{#each locations}}
<li>
<a href="geo:{{geo}}" class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">{{name}}</div>
</div>
<div class="item-text">{{info}}</div>
<div class="item-text">{{hours}}</div>
</div>
</a>
</li>
{{/each}}
</ul>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,577 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<div class="page" data-name="address_qrcode">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link back hapticbtn" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Back</span>
</a>
</div>
<div class="title">Quick Send</div>
</div>
</div>
<div class="page-content">
<div class="row justify-content-center">
<div class="col-100 medium-90 margin-horizontal">
<div class="card margin">
<div class="card-content text-align-center padding">
For faster service, fill in this form and press Show Barcode, then scan the barcode that appears.
<br>
All fields are optional, but fill in as much as possible.
</div>
</div>
</div>
<div class="col-100 medium-90 margin-horizontal">
<div class="card margin">
<div class="card-content text-align-center" id="addresscodeform">
<div class="row">
<div class="col-100 medium-50 xlarge-33">
<div class="list">
<ul>
<li class="item-divider">Return Address:</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Name (or care of)</div>
<div class="item-input-wrap">
<input type="text" id="from_name" placeholder="" value="{{from_name}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Company (or name)</div>
<div class="item-input-wrap">
<input type="text" id="from_company" placeholder="" value="{{from_company}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Street Address</div>
<div class="item-input-wrap">
<input type="text" id="from_street1" placeholder="1234 Example Rd" value="{{from_street1}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Address Line 2</div>
<div class="item-input-wrap">
<input type="text" id="from_street2" placeholder="Apt 37" value="{{from_street2}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">ZIP Code</div>
<div class="item-input-wrap">
<input type="text" id="from_zip" inputmode="numeric" value="{{from_zip}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Phone Number</div>
<div class="item-input-wrap">
<input type="tel" id="from_phone" value="{{from_phone}}" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="col-100 medium-50 xlarge-33">
<div class="list">
<ul>
<li class="item-divider">To:</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Name (or care of)</div>
<div class="item-input-wrap">
<input type="text" id="to_name" placeholder="" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Company (or name)</div>
<div class="item-input-wrap">
<input type="text" id="to_company" placeholder="" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Street Address</div>
<div class="item-input-wrap">
<input type="text" id="to_street1" placeholder="987 Street Drive" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Address Line 2</div>
<div class="item-input-wrap">
<input type="text" id="to_street2" placeholder="Apt 37" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label" id="ziptext">ZIP Code</div>
<div class="item-input-wrap">
<input type="text" id="to_zip" inputmode="numeric" />
<span class="input-clear-button"></span>
</div>
<a href="#" class="popup-open" id="zipcodelookuplink" onclick="$('#ziplookup_address').val($('#to_street1').val());" data-popup="#zipLookupPopup">I don't know the ZIP Code</a>
</div>
</li>
<li class="item-content item-input item-input-outline citystateboxes" style="display: none;">
<div class="item-inner">
<div class="item-title item-floating-label">City</div>
<div class="item-input-wrap">
<input type="text" id="to_city" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline citystateboxes" style="display: none;">
<div class="item-inner">
<div class="item-title item-floating-label">State/Province</div>
<div class="item-input-wrap">
<input type="text" id="to_state" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Country</div>
<div class="item-input-wrap input-dropdown-wrap">
<select id="to_country" name="to_country">
<option value="US" selected>United States of America</option>
<option value="AF">Afghanistan</option>
<option value="AX">Åland Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
<option value="AO">Angola</option>
<option value="AI">Anguilla</option>
<option value="AQ">Antarctica</option>
<option value="AG">Antigua and Barbuda</option>
<option value="AR">Argentina</option>
<option value="AM">Armenia</option>
<option value="AW">Aruba</option>
<option value="AU">Australia</option>
<option value="AT">Austria</option>
<option value="AZ">Azerbaijan</option>
<option value="BS">Bahamas</option>
<option value="BH">Bahrain</option>
<option value="BD">Bangladesh</option>
<option value="BB">Barbados</option>
<option value="BY">Belarus</option>
<option value="BE">Belgium</option>
<option value="BZ">Belize</option>
<option value="BJ">Benin</option>
<option value="BM">Bermuda</option>
<option value="BT">Bhutan</option>
<option value="BO">Bolivia (Plurinational State of)</option>
<option value="BQ">Bonaire, Sint Eustatius and Saba</option>
<option value="BA">Bosnia and Herzegovina</option>
<option value="BW">Botswana</option>
<option value="BV">Bouvet Island</option>
<option value="BR">Brazil</option>
<option value="IO">British Indian Ocean Territory</option>
<option value="BN">Brunei Darussalam</option>
<option value="BG">Bulgaria</option>
<option value="BF">Burkina Faso</option>
<option value="BI">Burundi</option>
<option value="CV">Cabo Verde</option>
<option value="KH">Cambodia</option>
<option value="CM">Cameroon</option>
<option value="CA">Canada</option>
<option value="KY">Cayman Islands</option>
<option value="CF">Central African Republic</option>
<option value="TD">Chad</option>
<option value="CL">Chile</option>
<option value="CN">China</option>
<option value="CX">Christmas Island</option>
<option value="CC">Cocos (Keeling) Islands</option>
<option value="CO">Colombia</option>
<option value="KM">Comoros</option>
<option value="CG">Congo</option>
<option value="CD">Congo, Democratic Republic of the</option>
<option value="CK">Cook Islands</option>
<option value="CR">Costa Rica</option>
<option value="CI">Côte d'Ivoire</option>
<option value="HR">Croatia</option>
<option value="CU">Cuba</option>
<option value="CW">Curaçao</option>
<option value="CY">Cyprus</option>
<option value="CZ">Czechia</option>
<option value="DK">Denmark</option>
<option value="DJ">Djibouti</option>
<option value="DM">Dominica</option>
<option value="DO">Dominican Republic</option>
<option value="EC">Ecuador</option>
<option value="EG">Egypt</option>
<option value="SV">El Salvador</option>
<option value="GQ">Equatorial Guinea</option>
<option value="ER">Eritrea</option>
<option value="EE">Estonia</option>
<option value="SZ">Eswatini</option>
<option value="ET">Ethiopia</option>
<option value="FK">Falkland Islands (Malvinas)</option>
<option value="FO">Faroe Islands</option>
<option value="FJ">Fiji</option>
<option value="FI">Finland</option>
<option value="FR">France</option>
<option value="GF">French Guiana</option>
<option value="PF">French Polynesia</option>
<option value="TF">French Southern Territories</option>
<option value="GA">Gabon</option>
<option value="GM">Gambia</option>
<option value="GE">Georgia</option>
<option value="DE">Germany</option>
<option value="GH">Ghana</option>
<option value="GI">Gibraltar</option>
<option value="GR">Greece</option>
<option value="GL">Greenland</option>
<option value="GD">Grenada</option>
<option value="GP">Guadeloupe</option>
<option value="GU">Guam</option>
<option value="GT">Guatemala</option>
<option value="GG">Guernsey</option>
<option value="GN">Guinea</option>
<option value="GW">Guinea-Bissau</option>
<option value="GY">Guyana</option>
<option value="HT">Haiti</option>
<option value="HM">Heard Island and McDonald Islands</option>
<option value="VA">Holy See</option>
<option value="HN">Honduras</option>
<option value="HK">Hong Kong</option>
<option value="HU">Hungary</option>
<option value="IS">Iceland</option>
<option value="IN">India</option>
<option value="ID">Indonesia</option>
<option value="IR">Iran (Islamic Republic of)</option>
<option value="IQ">Iraq</option>
<option value="IE">Ireland</option>
<option value="IM">Isle of Man</option>
<option value="IL">Israel</option>
<option value="IT">Italy</option>
<option value="JM">Jamaica</option>
<option value="JP">Japan</option>
<option value="JE">Jersey</option>
<option value="JO">Jordan</option>
<option value="KZ">Kazakhstan</option>
<option value="KE">Kenya</option>
<option value="KI">Kiribati</option>
<option value="KP">Korea (Democratic People's Republic of)</option>
<option value="KR">Korea, Republic of</option>
<option value="KW">Kuwait</option>
<option value="KG">Kyrgyzstan</option>
<option value="LA">Lao People's Democratic Republic</option>
<option value="LV">Latvia</option>
<option value="LB">Lebanon</option>
<option value="LS">Lesotho</option>
<option value="LR">Liberia</option>
<option value="LY">Libya</option>
<option value="LI">Liechtenstein</option>
<option value="LT">Lithuania</option>
<option value="LU">Luxembourg</option>
<option value="MO">Macao</option>
<option value="MG">Madagascar</option>
<option value="MW">Malawi</option>
<option value="MY">Malaysia</option>
<option value="MV">Maldives</option>
<option value="ML">Mali</option>
<option value="MT">Malta</option>
<option value="MH">Marshall Islands</option>
<option value="MQ">Martinique</option>
<option value="MR">Mauritania</option>
<option value="MU">Mauritius</option>
<option value="YT">Mayotte</option>
<option value="MX">Mexico</option>
<option value="FM">Micronesia (Federated States of)</option>
<option value="MD">Moldova, Republic of</option>
<option value="MC">Monaco</option>
<option value="MN">Mongolia</option>
<option value="ME">Montenegro</option>
<option value="MS">Montserrat</option>
<option value="MA">Morocco</option>
<option value="MZ">Mozambique</option>
<option value="MM">Myanmar</option>
<option value="NA">Namibia</option>
<option value="NR">Nauru</option>
<option value="NP">Nepal</option>
<option value="NL">Netherlands</option>
<option value="NC">New Caledonia</option>
<option value="NZ">New Zealand</option>
<option value="NI">Nicaragua</option>
<option value="NE">Niger</option>
<option value="NG">Nigeria</option>
<option value="NU">Niue</option>
<option value="NF">Norfolk Island</option>
<option value="MK">North Macedonia</option>
<option value="MP">Northern Mariana Islands</option>
<option value="NO">Norway</option>
<option value="OM">Oman</option>
<option value="PK">Pakistan</option>
<option value="PW">Palau</option>
<option value="PS">Palestine, State of</option>
<option value="PA">Panama</option>
<option value="PG">Papua New Guinea</option>
<option value="PY">Paraguay</option>
<option value="PE">Peru</option>
<option value="PH">Philippines</option>
<option value="PN">Pitcairn</option>
<option value="PL">Poland</option>
<option value="PT">Portugal</option>
<option value="PR">Puerto Rico</option>
<option value="QA">Qatar</option>
<option value="RE">Réunion</option>
<option value="RO">Romania</option>
<option value="RU">Russian Federation</option>
<option value="RW">Rwanda</option>
<option value="BL">Saint Barthélemy</option>
<option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
<option value="KN">Saint Kitts and Nevis</option>
<option value="LC">Saint Lucia</option>
<option value="MF">Saint Martin (French part)</option>
<option value="PM">Saint Pierre and Miquelon</option>
<option value="VC">Saint Vincent and the Grenadines</option>
<option value="WS">Samoa</option>
<option value="SM">San Marino</option>
<option value="ST">Sao Tome and Principe</option>
<option value="SA">Saudi Arabia</option>
<option value="SN">Senegal</option>
<option value="RS">Serbia</option>
<option value="SC">Seychelles</option>
<option value="SL">Sierra Leone</option>
<option value="SG">Singapore</option>
<option value="SX">Sint Maarten (Dutch part)</option>
<option value="SK">Slovakia</option>
<option value="SI">Slovenia</option>
<option value="SB">Solomon Islands</option>
<option value="SO">Somalia</option>
<option value="ZA">South Africa</option>
<option value="GS">South Georgia and the South Sandwich Islands</option>
<option value="SS">South Sudan</option>
<option value="ES">Spain</option>
<option value="LK">Sri Lanka</option>
<option value="SD">Sudan</option>
<option value="SR">Suriname</option>
<option value="SJ">Svalbard and Jan Mayen</option>
<option value="SE">Sweden</option>
<option value="CH">Switzerland</option>
<option value="SY">Syrian Arab Republic</option>
<option value="TW">Taiwan, Province of China</option>
<option value="TJ">Tajikistan</option>
<option value="TZ">Tanzania, United Republic of</option>
<option value="TH">Thailand</option>
<option value="TL">Timor-Leste</option>
<option value="TG">Togo</option>
<option value="TK">Tokelau</option>
<option value="TO">Tonga</option>
<option value="TT">Trinidad and Tobago</option>
<option value="TN">Tunisia</option>
<option value="TR">Turkey</option>
<option value="TM">Turkmenistan</option>
<option value="TC">Turks and Caicos Islands</option>
<option value="TV">Tuvalu</option>
<option value="UG">Uganda</option>
<option value="UA">Ukraine</option>
<option value="AE">United Arab Emirates</option>
<option value="GB">United Kingdom of Great Britain and Northern Ireland</option>
<option value="US">United States of America</option>
<option value="UM">United States Minor Outlying Islands</option>
<option value="UY">Uruguay</option>
<option value="UZ">Uzbekistan</option>
<option value="VU">Vanuatu</option>
<option value="VE">Venezuela (Bolivarian Republic of)</option>
<option value="VN">Viet Nam</option>
<option value="VG">Virgin Islands (British)</option>
<option value="VI">Virgin Islands (U.S.)</option>
<option value="WF">Wallis and Futuna</option>
<option value="EH">Western Sahara</option>
<option value="YE">Yemen</option>
<option value="ZM">Zambia</option>
<option value="ZW">Zimbabwe</option>
</select>
</div>
</div>
</li>
<li class="item-content item-input item-input-outline">
<div class="item-inner">
<div class="item-title item-floating-label">Phone Number</div>
<div class="item-input-wrap">
<input type="tel" id="to_phone" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="card-content-padding">
<div class="button hapticbtn button-fill" onclick="showAddressQRCode()"><i class="fa-regular fa-qrcode"></i> Show Barcode</div>
</div>
</div>
</div>
</div>
</div>
<div class="popup" id="qrCodePopup">
<div class="block text-align-center">
<span style="padding: 20px; background-color: white; display: inline-block;">
<img id="addresscode-barcode" style="max-width: 90%;" />
</span>
<p><a class="button popup-close" href="#">Close</a></p>
</div>
</div>
<div class="popup" id="zipLookupPopup">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a class="link popup-close" href="#">
<i class="icon icon-back"></i>
<span class="if-not-md">Close</span>
</a>
</div>
<div class="title">ZIP Code Lookup</div>
</div>
</div>
<div class="list margin-bottom-half margin-top-half">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Address</div>
<div class="item-input-wrap">
<input type="text" id="ziplookup_address" placeholder="123 Example St"/>
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">City</div>
<div class="item-input-wrap">
<input type="text" id="ziplookup_city" placeholder="Helena"/>
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">State/Territory</div>
<div class="item-input-wrap">
<select id="ziplookup_state">
<option value=""></option>
<optgroup label="States">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DC">District of Columbia/Washington D.C.</option>
<option value="DE">Delaware</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</optgroup>
<optgroup label="Military">
<option value="AE">AE: Europe, Middle East, Canada</option>
<option value="AP">AP: Pacific</option>
<option value="AA">AA: Americas (except Canada)</option>
</optgroup>
<optgroup label="Territories">
<option value="AS">American Samoa</option>
<option value="GU">Guam</option>
<option value="MP">Northern Mariana Islands</option>
<option value="PR">Puerto Rico</option>
<option value="VI">U.S. Virgin Islands</option>
</optgroup>
<optgroup label="Freely Associated States">
<option value="FM">Federated States of Micronesia</option>
<option value="MH">Marshall Islands</option>
<option value="PW">Palau</option>
</optgroup>
</select>
</div>
</div>
</li>
<li class="item-content">
<div class="button hapticbtn button-fill" onclick="doZipCodeLookup($('#ziplookup_address').val(), $('#ziplookup_city').val(), $('#ziplookup_state').val());">
<i class="fa-solid fa-search"></i> Find ZIP Code
</div>
</li>
</ul>
</div>
</div>
</div>

@ -373,8 +373,6 @@
<option value="MediumFlatRateBox">USPS Medium Flat Rate Box</option>
<option value="LargeFlatRateBox">USPS Large Flat Rate Box</option>
<option value="LargeFlatRateBoxAPOFPO">USPS Large Flat Rate Box APO/FPO</option>
<option value="RegionalRateBoxA">USPS Regional Rate Box A</option>
<option value="RegionalRateBoxB">USPS Regional Rate Box B</option>
</optgroup>
<optgroup label="UPS">
<option value="UPSLetter">UPS Letter</option>

@ -62,7 +62,7 @@
<div class="title">Receipt</div>
</div>
</div>
<iframe id="receiptvieweriframe"></iframe>
<iframe id="receiptvieweriframe" onload="receiptiframeloadevent()"></iframe>
</div>
</div>

@ -23,7 +23,7 @@
<div class="row justify-content-center">
{{#each pages}}
<div class="col-100 small-50 large-33 no-margin-vertical">
<div class="card hapticbtn pointercursor" onclick="router.navigate('{{href}}');">
<div class="card hapticbtn pointercursor margin-half" onclick="router.navigate('{{href}}');">
<div class="card-content text-align-center padding">
<h1 class="no-margin"><i class="{{icon}}"></i></h1>
<br />

@ -28,7 +28,7 @@
<li>
<div class="block text-align-center">
<img src="assets/images/telegram.svg" class="margin" style="max-height: 20vh; max-width: 80%;" />
<p class="margin">
<p class="margin" id="telegram-dyncontent">
Send a telegram with Helena Express for $15.
We'll hand-deliver your message to anywhere in Helena, East Helena, Montana City, the Helena Valley, and the hills around Helena.
</p>

@ -30,7 +30,7 @@
{{#if map.enabled}}
<div class="col-100 large-50 xlarge-50">
<div class="no-margin-vertical-md tablet-inset elevation-tablet display-flex align-items-stretch" id="trackMapContainer">
<div class="mapbox" style="width: 100%; height: 100%;" id="mapbox-track" data-latitude="{{map.latitude}}" data-longitude="{{map.longitude}}" data-accurate="{{map.accurate}}"></div>
<div class="mapbox" style="width: 100%; height: 100%;" id="mapbox-track" data-latitude="{{map.latitude}}" data-longitude="{{map.longitude}}" data-accurate="{{map.accurate}}" data-geoiscountrylevel="{{map.geoiscountrylevel}}"></div>
</div>
</div>
{{/if}}

@ -23,23 +23,28 @@
<div class="card">
<div class="card-body padding-top">
<div class="block text-align-center">
<img src="assets/images/trailer-front-august2022-cleaned.jpg" style="max-width: 100%; max-height: 300px;"/>
<img src="assets/images/mail-trailer.svg" class="margin" style="max-height: 20vh; max-width: 80%;" />
</div>
<div class="block margin-bottom">
<div class="block margin-bottom" id="trailer-dyncontent">
Our Mobile Shipping Center is a specialized trailer equipped to offer mailing,
shipping, notarizing, copying, and faxing services. With no pickup or travel fees,
shipping, notarizing, copying, and faxing services. With no markup or extra fees,
it's a good way to save money and skip the line at the post office.
</div>
<div class="block margin-bottom">
Check the schedule and come visit us! Need directions?
Just <span class="taptext">tap</span><span class="clicktext">click</span>
a location to open a map.
</div>
<div class="block">
<div class="button" onclick='openExternalBrowser("https://helena.express/mobile");'>
Learn More &nbsp;<i class="fa-regular fa-arrow-up-right-from-square"></i>
</div>
</div>
<div class="block margin-bottom">
Use Quick Send for faster service! Just enter the address info for your package ahead of time then show us your phone screen.
</div>
<div class="block">
<div class="button" onclick='router.navigate("/quicksend");'>
Open Quick Send
</div>
</div>
</div>
</div>
</div>

@ -4,6 +4,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var dynamicPages = [
"notary",
"telegram",
"trailer"
];
var compiledPages = {};
var pagesToCompile = [
"home",
@ -17,15 +22,14 @@ var pagesToCompile = [
"shop",
"shoppingcart_fragment",
"rateresult",
"crypto",
"crypto_wallet",
"account",
"trackresult",
"settings",
"receipts",
"trailer",
"money",
"moneyorder"
"kiosk",
"locations",
"quicksend"
];
console.log("Compiling page templates...");
for (var i = 0; i < pagesToCompile.length; i++) {
@ -48,82 +52,6 @@ var routes = [
}
}
},
{
path: '/crypto',
name: 'crypto',
async: function ( {resolve, reject}) {
resolve({
content: compiledPages.crypto({
slideshow: [
{
image: "assets/images/crypto/slides/intro.svg",
text: "Bitcoin and cryptocurrency can be complicated. We've made it simple. Swipe left for more."
},
{
image: "assets/images/crypto/slides/vault.svg",
text: "With your Helena Express paper wallet, you can save..."
},
{
image: "assets/images/crypto/slides/spend.svg",
text: "...or spend, without worrying about hackers..."
},
{
image: "assets/images/crypto/slides/secure.svg",
text: "...because paper can't be hacked."
},
{
image: "assets/images/crypto/slides/scantostart.svg",
text: "Scan your paper wallet to get started, or order one in the shop."
}
]
})
}, {});
},
on: {
pageAfterIn: function () {
app.swiper.destroy("#crypto-intro-swiper");
app.swiper.create("#crypto-intro-swiper", {
pagination: {
el: "#crypto-intro-swiper-pagination",
type: "bullets",
clickable: true
}
});
}
}
},
{
path: '/crypto/:walletaddress/:toaddress',
async: openWalletBalancePage,
name: 'crypto_wallet',
on: {
pageAfterIn: function () {
$("#sendCryptoOpenPopupBtn").click();
setupReceiveFiatConversion();
}
}
},
{
path: '/crypto/:walletaddress/:toaddress/:amount',
async: openWalletBalancePage,
name: 'crypto_wallet',
on: {
pageAfterIn: function () {
$("#sendCryptoOpenPopupBtn").click();
setupReceiveFiatConversion();
}
}
},
{
path: '/crypto/:walletaddress',
async: openWalletBalancePage,
name: 'crypto_wallet',
on: {
pageAfterIn: function () {
setupReceiveFiatConversion();
}
}
},
{
path: '/home',
name: 'home',
@ -154,7 +82,7 @@ var routes = [
title: "Send a Package",
href: "/send",
icon: "fa-duotone fa-box-alt",
text: "Find a drop box or schedule a pickup."
text: "Find locations or request a pickup."
},
{
title: "Notarize a Document",
@ -163,10 +91,10 @@ var routes = [
text: "Book a mobile notary visit."
},
{
title: "Write a Telegram",
href: "/telegram",
icon: "fa-duotone fa-typewriter",
text: "Send a hand-delivered telegram anywhere in the Helena area."
title: "Locations",
href: "/locations",
icon: "fa-duotone fa-map-location-dot",
text: "Find a shipping kiosk or drop box near you."
},
{
title: "Shop for Supplies",
@ -175,17 +103,17 @@ var routes = [
text: "Get boxes, labels, and shipping supplies delivered to your door."
},
{
title: "Money Services",
href: "/money",
icon: "fa-duotone fa-money-bill-wave",
text: "Manage cryptocurrency and verify money orders."
title: "Write a Telegram",
href: "/telegram",
icon: "fa-duotone fa-typewriter",
text: "Send a hand-delivered telegram anywhere in the Helena area."
},
{
title: "My Account",
href: "/account",
icon: "fa-duotone fa-user-circle",
text: "Get account number, check rewards points, update payment method, and more."
},
text: "View receipts, get account number, update payment method, and more."
}
]
})
}, {});
@ -199,68 +127,51 @@ var routes = [
content: compiledPages.send({
pages: [
{
title: "Use a Drop Box",
href: "/dropandsend",
title: "Self-Serve Kiosk",
href: "/kiosk",
icon: "fa-duotone fa-display",
text: "Visit a friendly neighborhood PostalPoint™ shipping kiosk to send mail and packages with no lines or hassle."
},
{
title: "Drop Box",
href: "/das",
icon: "fa-duotone fa-box-alt",
text: "Bring your package to a Drop and Send location and we'll ship it for you. No postage or appointment needed."
text: "Just drop your package into a Drop and Send℠ drop box and scan the QR code. We'll charge the postage to your Helena Express account."
},
{
title: "Request a Pickup",
title: "Pickup",
href: "/pickup",
icon: "fa-duotone fa-home",
text: "Leave your package on your porch and we'll pick it up and ship it for you. No postage or appointment needed."
},
{
title: "Visit Us",
href: "/trailer",
icon: "fa-duotone fa-caravan",
text: "Our Mobile Shipping Center roams the Helena area like a food truck for mail. Find dates and places here."
},
{
title: "Book an Appointment",
title: "Appointment",
href: "/appointment/shipping",
icon: "fa-duotone fa-calendar-alt",
text: "A courier will come to you on your schedule. No account required."
}
]
})
}, {});
}
},
{
path: '/money',
name: 'money',
async: function ( { resolve, reject }) {
resolve({
content: compiledPages.money({
pages: [
{
title: "Verify Money Order",
href: "/moneyorder",
icon: "fa-duotone fa-money-check-dollar",
text: "Check and verify a Helena Express money order."
text: "We'll come to your home or business on your schedule. It's like a post office in your driveway!"
},
{
title: "Crypto Wallet",
href: "/crypto",
icon: "fa-duotone fa-wallet",
text: "Check your crypto wallet balance and pay people with cryptocurrency."
title: "Mobile Shipping Center",
href: "/mobile",
icon: "fa-duotone fa-caravan",
text: "Our Mobile Shipping Center is a specially-designed trailer for printing postage, shipping mail and packages, and more."
}
]
})
}, {});
}
},
{
path: '/moneyorder',
content: compiledPages.moneyorder(),
name: 'moneyorder'
},
{
path: '/notary',
content: compiledPages.notary(),
name: 'notary',
on: {
pageBeforeIn: function () {
dyncontent = getDynamicPageContent("notary");
if (dyncontent != null) {
$("#notary-dyncontent").html(dyncontent);
}
},
pageAfterIn: function () {
app.swiper.destroy("#notary-info-swiper");
app.swiper.create("#notary-info-swiper", {
@ -273,6 +184,19 @@ var routes = [
}
}
},
{
path: '/locations',
content: compiledPages.locations(),
name: 'locations',
on: {
pageAfterIn: function () {
loadLocationMap();
},
pageAfterOut: function () {
locationMap = null;
}
}
},
{
path: '/servicearea',
content: compiledPages.servicearea(),
@ -286,6 +210,22 @@ var routes = [
}
}
},
{
path: '/quicksend',
name: 'quicksend',
async: function ( {resolve}) {
resolve({
content: compiledPages.quicksend({
from_name: inStorage("quicksend_name") ? getStorage("quicksend_name") : "",
from_company: inStorage("quicksend_company") ? getStorage("quicksend_company") : "",
from_street1: inStorage("quicksend_street1") ? getStorage("quicksend_street1") : (inStorage("lastpickupaddress") ? getStorage("lastpickupaddress") : ""),
from_street2: inStorage("quicksend_street2") ? getStorage("quicksend_street2") : "",
from_zip: inStorage("quicksend_zip") ? getStorage("quicksend_zip") : (inStorage("lastpickupzipcode") ? getStorage("lastpickupzipcode") : ""),
from_phone: inStorage("quicksend_phone") ? getStorage("quicksend_phone") : ""
})
}, {});
},
},
{
path: '/appointment',
name: 'appointment',
@ -330,7 +270,7 @@ var routes = [
]
},
{
path: '/dropandsend',
path: '/das',
name: 'dropandsend',
content: compiledPages.dropandsend(),
on: {
@ -350,7 +290,7 @@ var routes = [
break;
}
var hourofday = formatTimestamp("H");
if (hourofday > 12 + 4) {
if (hourofday > 12 + 3) {
$("#pickupLateInDayWarning").css("display", "");
}
},
@ -359,6 +299,48 @@ var routes = [
}
}
},
{
path: '/postalpoint',
name: 'postalpoint',
async: function ( {resolve, reject}) {
app.dialog.preloader("Loading...");
apirequest(SETTINGS.apis.postalpoint_locations, [], function (resp) {
app.dialog.close();
var locations = [];
for (var i = 0; i < resp.features.length; i++) {
locations.push({
name: resp.features[i].properties.name,
info: resp.features[i].properties.info,
hours: resp.features[i].properties.hours,
geo: resp.features[i].geometry.coordinates[1] + "," + resp.features[i].geometry.coordinates[0]
});
}
resolve({
content: compiledPages.postalpoint({
locations: locations
})
}, {});
}, function (error) {
app.dialog.close();
app.dialog.alert("Couldn't download the list of PostalPoint locations. Try again later.", "Whoops!");
sendErrorReport("PostalPoint", "Loading locations");
resolve({
content: compiledPages.postalpoint({
locations: []
})
}, {});
}, "GET");
},
on: {
pageBeforeIn: function () {
dyncontent = getDynamicPageContent("postalpoint");
if (dyncontent != null) {
$("#postalpoint-dyncontent").html(dyncontent);
}
}
}
},
{
path: '/pickup',
name: 'pickup',
@ -411,7 +393,7 @@ var routes = [
}
},
{
path: '/trailer',
path: '/mobile',
name: 'trailer',
async: function ( {resolve, reject}) {
app.dialog.preloader("Checking the schedule...");
@ -433,6 +415,60 @@ var routes = [
})
}, {});
}, "GET");
},
on: {
pageBeforeIn: function () {
dyncontent = getDynamicPageContent("trailer");
if (dyncontent != null) {
$("#trailer-dyncontent").html(dyncontent);
}
}
}
},
{
path: '/kiosk',
name: 'kiosk',
async: function ( {resolve, reject}) {
app.dialog.preloader("Loading...");
apirequest(SETTINGS.apis.locations, [], function (resp) {
app.dialog.close();
var kioskLocations = [];
for (var i = 0; i < resp.features.length; i++) {
if (resp.features[i].properties.branding != "PP") {
continue;
}
kioskLocations.push({
name: resp.features[i].properties.name,
hours: resp.features[i].properties.hours,
info: resp.features[i].properties.info,
geo: "geo:" + (Math.round(resp.features[i].geometry.coordinates[1] * 1000000) / 1000000) + "," + (Math.round(resp.features[i].geometry.coordinates[0] * 1000000) / 1000000)
});
}
resolve({
content: compiledPages.kiosk({
locations: kioskLocations
})
}, {});
}, function (error) {
app.dialog.close();
app.dialog.alert("Couldn't get the kiosk locations. Try again later.", "Whoops!");
sendErrorReport("Kiosks", "Loading locations");
resolve({
content: compiledPages.kiosk({
locations: []
})
}, {});
}, "GET");
},
on: {
pageBeforeIn: function () {
dyncontent = getDynamicPageContent("kiosk");
if (dyncontent != null) {
$("#kiosk-dyncontent").html(dyncontent);
}
}
}
},
{
@ -448,6 +484,10 @@ var routes = [
}, function (error) {
$("#addPaymentMethodNag").css("display", "");
});
dyncontent = getDynamicPageContent("telegram");
if (dyncontent != null) {
$("#telegram-dyncontent").html(dyncontent);
}
}
}
},
@ -496,7 +536,8 @@ var routes = [
var latitude = $(mapboxel).data("latitude");
var longitude = $(mapboxel).data("longitude");
var accurate = $(mapboxel).data("accurate") == true;
trackingMap.clearMarkersAndCenterMapOnNewMarker("package-marker", latitude, longitude, accurate);
var geoiscountrylevel = $(mapboxel).data("geoiscountrylevel") == true;
trackingMap.clearMarkersAndCenterMapOnNewMarker("package-marker", latitude, longitude, accurate, geoiscountrylevel);
}
}
},
@ -564,7 +605,7 @@ var routes = [
{
setting: "versions",
title: "Helena Express app v" + app_version,
text: "Copyright &copy; 2019-2022 Helena Express and Netsyms Technologies.",
text: "Copyright &copy; 2019-2023 Helena Express and Netsyms Technologies.",
onclick: ""
},
{

@ -6,51 +6,48 @@
var SETTINGS = {
apis: {
// Dynamic text content updater
dynamicappcontent: "https://apis.helena.express/v1/dynamicappcontent/",
// Tracking
track: "http://localhost/helena.express/apis/track/",
trackmultiple: "http://localhost/helena.express/apis/trackmultiple/",
track: "https://apis.helena.express/v1/track/",
trackmultiple: "https://apis.helena.express/v1/trackmultiple/",
// Shipping rates
rates: "http://localhost/helena.express/apis/rates/",
rates: "https://apis.helena.express/v1/rates/",
// ZIP Code lookup
zipcodelookup: "http://localhost/helena.express/apis/zipcodelookup/",
zipcodelookup: "https://apis.helena.express/v1/zipcodelookup/",
// Get appointment iframe URL
appointmentredirect: "http://localhost/helena.express/apis/appointmentredirect/",
appointmentredirect: "https://apis.helena.express/v1/appointmentredirect/",
// Request home pickup
requestpickup: "http://localhost/helena.express/apis/requestpickup/",
requestpickup: "https://apis.helena.express/v1/requestpickup/",
// Drop and Send
dropandsendlocations: "http://localhost/helena.express/apis/dropandsend/locations/",
dropandsendpickup: "http://localhost/helena.express/apis/dropandsend/requestpickup/",
dropandsendlocations: "https://apis.helena.express/v1/dropandsend/locations/",
dropandsendpickup: "https://apis.helena.express/v1/dropandsend/requestpickup/",
// Fetch account data
getaccountinfo: "http://localhost/helena.express/apis/account/getinfo/",
getaccountinfo: "https://apis.helena.express/v1/account/getinfo/",
// Fetch tracking numbers associated with account
gettrackingnumbers: "http://localhost/helena.express/apis/account/gettrackingnumbers/",
gettrackingnumbers: "https://apis.helena.express/v1/account/gettrackingnumbers/",
// Account login/registration/onboarding endpoints
authorstartverify: "http://localhost/helena.express/apis/account/authorstartverify/",
verifyauthcode: "http://localhost/helena.express/apis/account/verifyauthcode/",
accountregister: "http://localhost/helena.express/apis/account/register/",
authorstartverify: "https://apis.helena.express/v1/account/authorstartverify/",
verifyauthcode: "https://apis.helena.express/v1/account/verifyauthcode/",
accountregister: "https://apis.helena.express/v1/account/register/",
// Setup saved payment method
redirecttopaymentsetup: "http://localhost/helena.express/apis/account/redirecttopaymentsetup/",
finishpaymentsetup: "http://localhost/helena.express/apis/account/finishpaymentsetup/",
redirecttopaymentsetup: "https://apis.helena.express/v1/account/redirecttopaymentsetup/",
finishpaymentsetup: "https://apis.helena.express/v1/account/finishpaymentsetup/",
// Send a telegram message
sendtelegram: "http://localhost/helena.express/apis/telegram",
sendtelegram: "https://apis.helena.express/v1/telegram/",
// Fetch shop items
shopitems: "http://localhost/helena.express/apis/shop/items",
shopitems: "https://apis.helena.express/v1/shop/items/",
// Create a shop order
shopbuy: "http://localhost/helena.express/apis/shop/buy",
shopbuy: "https://apis.helena.express/v1/shop/buy/",
// Get receipts linked with account
getreceipts: "http://localhost/helena.express/apis/account/getreceipts",
getreceipt: "http://localhost/helena.express/apis/account/getreceipt",
// Crypto: check balance and send transactions
walletbalance: "http://localhost/helena.express/apis/crypto/walletbalance",
getutxo: "http://localhost/helena.express/apis/crypto/getutxo",
broadcasttransaction: "http://localhost/helena.express/apis/crypto/broadcasttransaction",
cryptofees: "http://localhost/helena.express/apis/crypto/fees",
getreceipts: "https://apis.helena.express/v1/account/getreceipts/",
getreceipt: "https://apis.helena.express/v1/account/getreceipt/",
// Service area map
servicearea: "http://localhost/helena.express/apis/servicearea",
servicearea: "https://apis.helena.express/v1/servicearea/",
// Trailer schedule/dates/times/locations
trailerschedule: "https://helena.express/mobile/schedule.json",
// Money order verification
moneyorderverify: "http://localhost/helena.express/apis/moneyorder/verify"
// Physical locations
locations: "https://apis.helena.express/v1/locations/"
},
stripe_pubkey: "pk_test_51J6qFXCa1Fboir5UzPO3LCiMsVNiFP2lq4wR0dEcjJJVzAaJ3uRggDekZPB3qeYpMD3ayIYHKyD5sSn0IFLlEXMW001LqrvGSH",
branding: {

Loading…
Cancel
Save