Compare commits

..
1363 changed files with 143511 additions and 74802 deletions
+28
View File
@@ -0,0 +1,28 @@
name: Qodana Configuration Upload
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
upload-qodana-config:
runs-on: [self-hosted, Linux, X64, default]
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Run Qodana Configuration Uploader
env:
QODANA_CONFIGURATIONS_TOKEN: ${{ secrets.QODANA_CONFIGURATIONS_TOKEN }}
run: |
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
-e QODANA_CONFIGURATIONS_TOKEN=$QODANA_CONFIGURATIONS_TOKEN \
jetbrains/qodana-configuration-uploader:latest \
--global-configs-file qodana-global-configurations.yaml \
--qodana-host https://qodana.cloud
+3 -7
View File
@@ -7,13 +7,9 @@ on:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
upload-qodana-config:
runs-on: [self-hosted, Linux, X64, default]
timeout-minutes: 10
steps:
- name: Checkout repository
@@ -24,9 +20,9 @@ jobs:
QODANA_CONFIGURATIONS_TOKEN: ${{ secrets.QODANA_CONFIGURATIONS_TOKEN }}
run: |
docker run --rm \
-v "$(pwd):/workspace" \
-v $(pwd):/workspace \
-w /workspace \
-e QODANA_CONFIGURATIONS_TOKEN \
jetbrains/qodana-configuration-uploader@sha256:f4786ceea616048c3401cf0b0345d2220d22a2ec7b046fd48cbbfc522e6efe30 \
-e QODANA_CONFIGURATIONS_TOKEN=$QODANA_CONFIGURATIONS_TOKEN \
jetbrains/qodana-configuration-uploader:latest \
--global-configs-file qodana-global-configurations.yaml \
--qodana-host https://qodana.cloud
-291
View File
@@ -1,291 +0,0 @@
name: Mobile Store Artifacts
on:
workflow_dispatch:
inputs:
version_name:
description: Store version name, for example 1.4.0
required: false
type: string
version_code:
description: Store build number/version code
required: false
type: string
push:
tags:
- "mobile-v*"
workflow_run:
workflows:
- Automated Tests
types:
- completed
branches:
- master
permissions:
contents: read
concurrency:
group: mobile-store-artifacts-${{ github.ref_name }}
cancel-in-progress: true
jobs:
android:
name: Android AAB
if: >
github.event_name != 'workflow_run' ||
(github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == github.event.repository.default_branch)
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Install Android SDK packages
shell: bash
run: |
set -euo pipefail
yes | sdkmanager --licenses >/dev/null || true
sdkmanager "platforms;android-36" "build-tools;36.0.0"
- name: Resolve mobile version
shell: bash
env:
INPUT_VERSION_NAME: ${{ inputs.version_name }}
INPUT_VERSION_CODE: ${{ inputs.version_code }}
run: |
set -euo pipefail
version_name="$INPUT_VERSION_NAME"
if [[ -z "$version_name" && "$GITHUB_REF_NAME" == mobile-v* ]]; then
version_name="${GITHUB_REF_NAME#mobile-v}"
fi
if [[ -z "$version_name" ]]; then
version_name="0.0.${GITHUB_RUN_NUMBER}"
fi
version_code="${INPUT_VERSION_CODE:-$GITHUB_RUN_NUMBER}"
echo "MOBILE_VERSION_NAME=$version_name" >> "$GITHUB_ENV"
echo "MOBILE_VERSION_CODE=$version_code" >> "$GITHUB_ENV"
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Decode Android signing key
shell: bash
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: |
set -euo pipefail
test -n "$ANDROID_KEYSTORE_BASE64"
test -n "$ANDROID_KEYSTORE_PASSWORD"
test -n "$ANDROID_KEY_ALIAS"
test -n "$ANDROID_KEY_PASSWORD"
keystore_path="$RUNNER_TEMP/android-release.keystore"
node -e "const fs = require('fs'); fs.writeFileSync(process.argv[1], Buffer.from(process.env.ANDROID_KEYSTORE_BASE64, 'base64'))" "$keystore_path"
echo "ANDROID_KEYSTORE_FILE=$keystore_path" >> "$GITHUB_ENV"
echo "ANDROID_KEYSTORE_PASSWORD=$ANDROID_KEYSTORE_PASSWORD" >> "$GITHUB_ENV"
echo "ANDROID_KEY_ALIAS=$ANDROID_KEY_ALIAS" >> "$GITHUB_ENV"
echo "ANDROID_KEY_PASSWORD=$ANDROID_KEY_PASSWORD" >> "$GITHUB_ENV"
- name: Build and sync Android shell
run: |
npm run mobile:android:sync
npm run mobile:permissions:check
npm run mobile:android:signing:check
- name: Build signed Android App Bundle
working-directory: android
run: ./gradlew --no-daemon bundleRelease
- name: Verify Android App Bundle signature
run: jarsigner -verify -certs -verbose android/app/build/outputs/bundle/release/app-release.aab >/dev/null
- name: Upload Android artifact
uses: actions/upload-artifact@v4
with:
name: truck-wash-android-${{ env.MOBILE_VERSION_NAME }}-${{ github.event.workflow_run.head_sha || github.sha }}
path: android/app/build/outputs/bundle/release/app-release.aab
if-no-files-found: error
retention-days: 14
ios:
name: iOS IPA
if: github.event_name != 'workflow_run'
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
ref: ${{ github.sha }}
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Resolve mobile version
shell: bash
env:
INPUT_VERSION_NAME: ${{ inputs.version_name }}
INPUT_VERSION_CODE: ${{ inputs.version_code }}
run: |
set -euo pipefail
version_name="$INPUT_VERSION_NAME"
if [[ -z "$version_name" && "$GITHUB_REF_NAME" == mobile-v* ]]; then
version_name="${GITHUB_REF_NAME#mobile-v}"
fi
if [[ -z "$version_name" ]]; then
version_name="0.0.${GITHUB_RUN_NUMBER}"
fi
version_code="${INPUT_VERSION_CODE:-$GITHUB_RUN_NUMBER}"
echo "MOBILE_VERSION_NAME=$version_name" >> "$GITHUB_ENV"
echo "MOBILE_VERSION_CODE=$version_code" >> "$GITHUB_ENV"
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Build and sync iOS shell
run: |
npm run build
npx cap sync ios
npm run mobile:permissions:check
- name: Install Apple signing assets
shell: bash
env:
IOS_CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_BASE64 }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
IOS_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_PROVISION_PROFILE_BASE64 }}
IOS_KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
test -n "$IOS_CERTIFICATE_BASE64"
test -n "$IOS_CERTIFICATE_PASSWORD"
test -n "$IOS_PROVISION_PROFILE_BASE64"
test -n "$IOS_KEYCHAIN_PASSWORD"
test -n "$APPLE_TEAM_ID"
certificate_path="$RUNNER_TEMP/apple-distribution.p12"
profile_path="$RUNNER_TEMP/app-store.mobileprovision"
keychain_path="$RUNNER_TEMP/app-signing.keychain-db"
profile_plist="$RUNNER_TEMP/profile.plist"
node -e "const fs = require('fs'); fs.writeFileSync(process.argv[1], Buffer.from(process.env.IOS_CERTIFICATE_BASE64, 'base64'))" "$certificate_path"
node -e "const fs = require('fs'); fs.writeFileSync(process.argv[1], Buffer.from(process.env.IOS_PROVISION_PROFILE_BASE64, 'base64'))" "$profile_path"
security create-keychain -p "$IOS_KEYCHAIN_PASSWORD" "$keychain_path"
security set-keychain-settings -lut 21600 "$keychain_path"
security unlock-keychain -p "$IOS_KEYCHAIN_PASSWORD" "$keychain_path"
security import "$certificate_path" -P "$IOS_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$keychain_path"
security list-keychain -d user -s "$keychain_path" $(security list-keychains -d user | tr -d '"')
security set-key-partition-list -S apple-tool:,apple: -s -k "$IOS_KEYCHAIN_PASSWORD" "$keychain_path"
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
security cms -D -i "$profile_path" > "$profile_plist"
profile_uuid="$(/usr/libexec/PlistBuddy -c 'Print UUID' "$profile_plist")"
profile_name="$(/usr/libexec/PlistBuddy -c 'Print Name' "$profile_plist")"
cp "$profile_path" "$HOME/Library/MobileDevice/Provisioning Profiles/$profile_uuid.mobileprovision"
echo "APPLE_TEAM_ID=$APPLE_TEAM_ID" >> "$GITHUB_ENV"
echo "IOS_KEYCHAIN_PATH=$keychain_path" >> "$GITHUB_ENV"
echo "IOS_PROFILE_UUID=$profile_uuid" >> "$GITHUB_ENV"
echo "IOS_PROFILE_NAME=$profile_name" >> "$GITHUB_ENV"
- name: Resolve Swift packages
run: xcodebuild -resolvePackageDependencies -project ios/App/App.xcodeproj -scheme App
- name: Archive iOS app
run: |
xcodebuild \
-project ios/App/App.xcodeproj \
-scheme App \
-configuration Release \
-destination "generic/platform=iOS" \
-archivePath "$RUNNER_TEMP/TruckWash.xcarchive" \
archive \
DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="Apple Distribution" \
PROVISIONING_PROFILE_SPECIFIER="$IOS_PROFILE_NAME" \
MARKETING_VERSION="$MOBILE_VERSION_NAME" \
CURRENT_PROJECT_VERSION="$MOBILE_VERSION_CODE"
- name: Export iOS IPA
shell: bash
run: |
set -euo pipefail
export_method="app-store-connect"
if ! xcodebuild -help 2>&1 | grep -q "app-store-connect"; then
export_method="app-store"
fi
export_options="$RUNNER_TEMP/ExportOptions.plist"
cat > "$export_options" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>$export_method</string>
<key>signingStyle</key>
<string>manual</string>
<key>teamID</key>
<string>$APPLE_TEAM_ID</string>
<key>provisioningProfiles</key>
<dict>
<key>io.truckwash.app</key>
<string>$IOS_PROFILE_NAME</string>
</dict>
<key>stripSwiftSymbols</key>
<true/>
<key>manageAppVersionAndBuildNumber</key>
<false/>
</dict>
</plist>
EOF
xcodebuild \
-exportArchive \
-archivePath "$RUNNER_TEMP/TruckWash.xcarchive" \
-exportPath "$RUNNER_TEMP/ios-export" \
-exportOptionsPlist "$export_options"
- name: Upload iOS artifact
uses: actions/upload-artifact@v4
with:
name: truck-wash-ios-${{ env.MOBILE_VERSION_NAME }}-${{ github.sha }}
path: ${{ runner.temp }}/ios-export/*.ipa
if-no-files-found: error
retention-days: 14
- name: Clean up Apple signing assets
if: always()
shell: bash
run: |
if [[ -n "${IOS_KEYCHAIN_PATH:-}" ]]; then
security delete-keychain "$IOS_KEYCHAIN_PATH" || true
fi
if [[ -n "${IOS_PROFILE_UUID:-}" ]]; then
rm -f "$HOME/Library/MobileDevice/Provisioning Profiles/$IOS_PROFILE_UUID.mobileprovision"
fi
+14 -83
View File
@@ -1,35 +1,30 @@
name: Frontend Release
on:
workflow_run:
workflows:
- Automated Tests
types:
- completed
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
actions: read
concurrency:
group: frontend-release-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: true
group: frontend-release-${{ github.ref }}
cancel-in-progress: false
jobs:
build-upload-and-verify:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push'
runs-on: [self-hosted, Linux, X64, default]
env:
RELEASE_BASE_URL: https://api-v2.truckwash.io/master/frontend
PLAYWRIGHT_BASE_URL: https://dev.truckwash.io
PLAYWRIGHT_RELEASE_STATIC_BASE_URL: https://api-v2.truckwash.io/master/frontend
PLAYWRIGHT_BASE_URL: https://api-v2.truckwash.io/master/frontend
PLAYWRIGHT_RELEASE_API_BASE_URL: https://api-v2.truckwash.io
PLAYWRIGHT_RELEASE_API_PING_PATHS: /master/api/ping
PLAYWRIGHT_RELEASE_API_PING_PATHS: /ping,/master/api/ping,/canary/api/ping,/stable/api/ping
RELEASE_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
RELEASE_EXPECTED_BUILD_ID: ${{ github.run_id }}-${{ github.run_attempt }}
RELEASE_EXPECTED_COMMIT: ${{ github.event.workflow_run.head_sha }}
RELEASE_EXPECTED_COMMIT: ${{ github.sha }}
RELEASE_WAIT_INITIAL_SECONDS: 45
RELEASE_WAIT_TIMEOUT_SECONDS: 600
RELEASE_POLL_INTERVAL_SECONDS: 10
@@ -38,114 +33,54 @@ jobs:
uses: actions/checkout@v5
with:
fetch-depth: 0
ref: ${{ github.event.workflow_run.head_sha }}
- name: Check release commit is current
id: branch-head
run: |
latest_sha="$(git ls-remote origin "refs/heads/$RELEASE_BRANCH" | awk '{print $1}')"
if [[ -z "$latest_sha" ]]; then
echo "Could not resolve origin/$RELEASE_BRANCH." >&2
exit 1
fi
if [[ "$latest_sha" != "$RELEASE_EXPECTED_COMMIT" ]]; then
echo "current=false" >> "$GITHUB_OUTPUT"
echo "Skipping stale release for $RELEASE_EXPECTED_COMMIT; origin/$RELEASE_BRANCH is $latest_sha."
exit 0
fi
echo "current=true" >> "$GITHUB_OUTPUT"
echo "Release commit is current for $RELEASE_BRANCH."
env:
RELEASE_BRANCH: ${{ github.event.workflow_run.head_branch }}
- name: Setup Node.js
if: steps.branch-head.outputs.current == 'true'
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Install dependencies
if: steps.branch-head.outputs.current == 'true'
run: npm ci --legacy-peer-deps
- name: Check AI workflow sync
if: steps.branch-head.outputs.current == 'true'
run: node scripts/sync-ai-workflow.mjs --check
- name: Source and i18n checks
if: steps.branch-head.outputs.current == 'true'
run: |
npm run text:check-encoding
npm run i18n:v2:source-check
- name: Unit tests
if: steps.branch-head.outputs.current == 'true'
run: npm run test:unit
env:
VITEST_BATCH_SIZE: 5
- name: Build release artifact
if: steps.branch-head.outputs.current == 'true'
run: npm run build
- name: Install Playwright Chromium
if: steps.branch-head.outputs.current == 'true'
run: node scripts/install-playwright-browsers.mjs chromium
run: npx playwright install --with-deps chromium
- name: Production Playwright gate
if: steps.branch-head.outputs.current == 'true'
run: npm run test:e2e:prod
- name: Upload dist artifact
if: steps.branch-head.outputs.current == 'true'
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: frontend-dist-${{ env.RELEASE_BUILD_ID }}
path: dist
retention-days: 3
- name: Request Release Manager auto sync
if: steps.branch-head.outputs.current == 'true'
run: |
test -n "$RELEASE_MANAGER_GATE_TOKEN" || (echo "RELEASE_MANAGER_GATE_TOKEN is required" >&2; exit 1)
response_file="$(mktemp)"
status_code="$(curl --show-error --silent \
--output "$response_file" \
--write-out "%{http_code}" \
-X POST "$RELEASE_MANAGER_GATE_URL" \
-H "Authorization: Bearer $RELEASE_MANAGER_GATE_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"environment_url\":\"$RELEASE_BASE_URL\",\"channel_slug\":\"stable\",\"app\":\"frontend\",\"repository\":\"$RELEASE_REPOSITORY\",\"branch\":\"$RELEASE_BRANCH\",\"expected_commit\":\"$RELEASE_EXPECTED_COMMIT\",\"build_id\":\"$RELEASE_EXPECTED_BUILD_ID\",\"workflow_url\":\"$RELEASE_WORKFLOW_URL\",\"auto_sync\":true,\"wait_timeout_seconds\":300,\"poll_interval_seconds\":10,\"required_checks\":[\"api_gateway\"]}")"
if [[ "$status_code" =~ ^2 ]]; then
cat "$response_file"
elif [[ "$status_code" == "504" ]]; then
echo "Release Manager auto sync request reached the gateway timeout; continuing to artifact wait."
else
cat "$response_file" >&2
echo "Release Manager auto sync request failed with HTTP $status_code." >&2
exit 1
fi
env:
RELEASE_MANAGER_GATE_URL: ${{ secrets.RELEASE_MANAGER_GATE_URL || 'https://api.truckwash.io/release/gate/test-runs' }}
RELEASE_MANAGER_GATE_TOKEN: ${{ secrets.RELEASE_MANAGER_GATE_TOKEN }}
RELEASE_REPOSITORY: ${{ github.repository }}
RELEASE_BRANCH: ${{ github.event.workflow_run.head_branch }}
RELEASE_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
retention-days: 14
- name: Wait for Coolify release artifact
if: steps.branch-head.outputs.current == 'true'
run: npm run release:verify-upload
- name: Public live Playwright gate
if: steps.branch-head.outputs.current == 'true'
run: npm run test:e2e:live:public
env:
NODE_OPTIONS: --use-system-ca
- name: Credentialed live Playwright gate
if: steps.branch-head.outputs.current == 'true'
run: npm run test:e2e:live:roles
env:
NODE_OPTIONS: --use-system-ca
@@ -158,35 +93,31 @@ jobs:
PLAYWRIGHT_DEPARTMENT_ID: ${{ secrets.PLAYWRIGHT_DEPARTMENT_ID }}
- name: Record Release Manager gate
if: steps.branch-head.outputs.current == 'true'
run: |
test -n "$RELEASE_MANAGER_GATE_TOKEN" || (echo "RELEASE_MANAGER_GATE_TOKEN is required" >&2; exit 1)
release_gate_build_id="${RELEASE_VERIFIED_BUILD_ID:-$RELEASE_EXPECTED_BUILD_ID}"
curl --fail --show-error --silent \
-X POST "$RELEASE_MANAGER_GATE_URL" \
-H "Authorization: Bearer $RELEASE_MANAGER_GATE_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"environment_url\":\"$RELEASE_BASE_URL\",\"channel_slug\":\"stable\",\"app\":\"frontend\",\"repository\":\"$RELEASE_REPOSITORY\",\"branch\":\"$RELEASE_BRANCH\",\"expected_commit\":\"$RELEASE_EXPECTED_COMMIT\",\"build_id\":\"$release_gate_build_id\",\"workflow_url\":\"$RELEASE_WORKFLOW_URL\",\"auto_sync\":true,\"wait_timeout_seconds\":300,\"poll_interval_seconds\":10,\"required_checks\":[\"static_artifact\",\"api_gateway\"]}"
--data "{\"environment_url\":\"$RELEASE_BASE_URL\",\"channel_slug\":\"stable\",\"app\":\"frontend\",\"repository\":\"$RELEASE_REPOSITORY\",\"branch\":\"$RELEASE_BRANCH\",\"expected_commit\":\"$RELEASE_EXPECTED_COMMIT\",\"build_id\":\"$RELEASE_EXPECTED_BUILD_ID\",\"workflow_url\":\"$RELEASE_WORKFLOW_URL\",\"auto_sync\":true,\"wait_timeout_seconds\":300,\"poll_interval_seconds\":10,\"required_checks\":[\"static_artifact\",\"api_gateway\"]}"
env:
RELEASE_MANAGER_GATE_URL: ${{ secrets.RELEASE_MANAGER_GATE_URL || 'https://api.truckwash.io/release/gate/test-runs' }}
RELEASE_MANAGER_GATE_TOKEN: ${{ secrets.RELEASE_MANAGER_GATE_TOKEN }}
RELEASE_REPOSITORY: ${{ github.repository }}
RELEASE_BRANCH: ${{ github.event.workflow_run.head_branch }}
RELEASE_BRANCH: ${{ github.ref_name }}
RELEASE_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Update server version after verification
if: steps.branch-head.outputs.current == 'true'
run: npm run release:update-server-version
env:
SERVER_UPDATE_TOKEN: ${{ secrets.SERVER_UPDATE_TOKEN }}
RELEASE_VERSION: ${{ github.event.workflow_run.head_sha }}
RELEASE_VERSION: ${{ github.sha }}
- name: Upload Playwright report
if: failure() && steps.branch-head.outputs.current == 'true'
continue-on-error: true
if: failure()
uses: actions/upload-artifact@v4
with:
name: frontend-release-playwright-${{ env.RELEASE_BUILD_ID }}
path: output/playwright
if-no-files-found: ignore
retention-days: 3
retention-days: 14
+45 -564
View File
@@ -3,44 +3,7 @@ name: Automated Tests
on:
pull_request:
push:
branches:
- main
- master
- dev
workflow_dispatch:
inputs:
mode:
description: "What to run for a manual dispatch."
required: true
type: choice
default: full
options:
- full
- targeted
- targeted-then-full
target_specs:
description: "Comma- or newline-separated Playwright spec paths under tests/e2e."
required: false
type: string
default: "tests/e2e/superuser-department-overview.spec.js"
target_projects:
description: "JSON array of Playwright projects for targeted mode."
required: false
type: string
default: '["chromium-desktop","chromium-mobile","chromium-tablet","webkit-mobile","webkit-desktop"]'
target_grep:
description: "Optional Playwright grep pattern for targeted mode."
required: false
type: string
default: ""
runner:
description: "Runner pool for this manually dispatched test run"
required: false
default: "self-hosted"
type: choice
options:
- self-hosted
- github-hosted
schedule:
- cron: "0 2 * * *"
@@ -48,35 +11,14 @@ permissions:
contents: read
concurrency:
group: frontend-tests-${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.head_ref || github.ref_name }}
group: frontend-tests-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Repository variables used as CI runner and credit controls:
# - FRONTEND_CI_STANDARD_RUNNER: JSON runs-on value for format/build/unit jobs.
# - FRONTEND_CI_E2E_RUNNER: JSON runs-on value for Playwright jobs.
# - FRONTEND_CI_PR_E2E_MAX_PARALLEL: numeric Playwright PR job parallelism.
# - FRONTEND_CI_FULL_E2E_MAX_PARALLEL: numeric full-suite job parallelism.
# GitHub-hosted example: ["ubuntu-22.04"], with PR parallelism 2 and full parallelism 1.
jobs:
format-tests:
runs-on: ${{ fromJSON(vars.FRONTEND_CI_STANDARD_RUNNER || '["self-hosted","Linux","X64","pleno","frontend"]') }}
timeout-minutes: 15
# CI runs on the repository's self-hosted runner pool.
runs-on: [self-hosted, Linux, X64, default]
steps:
- name: Repair self-hosted workspace permissions
if: ${{ contains(vars.FRONTEND_CI_STANDARD_RUNNER || 'self-hosted', 'self-hosted') }}
shell: bash
run: |
if [[ -d "$GITHUB_WORKSPACE" ]]; then
sudo -n chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE" 2>/dev/null || true
foreign_entry="$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 2 ! -user "$(id -u)" -print -quit 2>/dev/null || true)"
if [[ -n "$foreign_entry" ]]; then
trash="$GITHUB_WORKSPACE/../_workspace-trash-$GITHUB_RUN_ID-$GITHUB_JOB"
rm -rf "$trash" 2>/dev/null || true
mv "$GITHUB_WORKSPACE" "$trash" 2>/dev/null || true
mkdir -p "$GITHUB_WORKSPACE"
fi
fi
- name: Checkout repository
uses: actions/checkout@v5
@@ -84,6 +26,7 @@ jobs:
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Check AI workflow sync
run: node scripts/sync-ai-workflow.mjs --check
@@ -96,24 +39,8 @@ jobs:
build-and-unit:
needs: format-tests
runs-on: ${{ fromJSON(vars.FRONTEND_CI_STANDARD_RUNNER || '["self-hosted","Linux","X64","pleno","frontend"]') }}
timeout-minutes: 30
runs-on: [self-hosted, Linux, X64, default]
steps:
- name: Repair self-hosted workspace permissions
if: ${{ contains(vars.FRONTEND_CI_STANDARD_RUNNER || 'self-hosted', 'self-hosted') }}
shell: bash
run: |
if [[ -d "$GITHUB_WORKSPACE" ]]; then
sudo -n chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE" 2>/dev/null || true
foreign_entry="$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 2 ! -user "$(id -u)" -print -quit 2>/dev/null || true)"
if [[ -n "$foreign_entry" ]]; then
trash="$GITHUB_WORKSPACE/../_workspace-trash-$GITHUB_RUN_ID-$GITHUB_JOB"
rm -rf "$trash" 2>/dev/null || true
mv "$GITHUB_WORKSPACE" "$trash" 2>/dev/null || true
mkdir -p "$GITHUB_WORKSPACE"
fi
fi
- name: Checkout repository
uses: actions/checkout@v5
@@ -121,16 +48,11 @@ jobs:
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Lint
run: npm run lint
- name: Check i18n source consistency
run: npm run i18n:v2:check
- name: Build sanity check
run: npm run build
@@ -139,219 +61,11 @@ jobs:
env:
VITEST_BATCH_SIZE: 5
e2e-targeted:
if: >
github.event_name == 'workflow_dispatch' &&
(inputs.mode == 'targeted' || inputs.mode == 'targeted-then-full')
needs: build-and-unit
name: E2E-targeted-${{ matrix.project }}
# Use GitHub-hosted runners to avoid self-hosted desktop contention and sleep/power events.
runs-on: ubuntu-24.04
timeout-minutes: 35
strategy:
fail-fast: false
matrix:
project: ${{ fromJSON(inputs.target_projects || '["chromium-desktop"]') }}
env:
MATRIX_PROJECT: ${{ matrix.project }}
PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-targeted-${{ matrix.project }}
PLAYWRIGHT_REPORTER_MODE: line-html
PLAYWRIGHT_WORKERS: 1
PLAYWRIGHT_VIDEO_MODE: on-first-retry
TARGET_GREP: ${{ inputs.target_grep }}
TARGET_SPECS: ${{ inputs.target_specs }}
RUN_ID: ${{ github.run_id }}
steps:
- name: Normalize workspace permissions
shell: bash
run: |
if [[ -d "$GITHUB_WORKSPACE" ]]; then
sudo -n chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE" 2>/dev/null || true
foreign_entry="$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 2 ! -user "$(id -u)" -print -quit 2>/dev/null || true)"
if [[ -n "$foreign_entry" ]]; then
trash="$GITHUB_WORKSPACE/../_workspace-trash-$GITHUB_RUN_ID-$GITHUB_JOB"
rm -rf "$trash" 2>/dev/null || true
mv "$GITHUB_WORKSPACE" "$trash" 2>/dev/null || true
mkdir -p "$GITHUB_WORKSPACE"
fi
fi
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
- name: Run targeted Playwright specs in container
shell: bash
run: |
set -euo pipefail
case "$MATRIX_PROJECT" in
chromium-mobile) project_offset=1 ;;
chromium-desktop) project_offset=2 ;;
chromium-tablet) project_offset=3 ;;
webkit-mobile) project_offset=31 ;;
webkit-desktop) project_offset=32 ;;
webkit-tablet) project_offset=33 ;;
firefox-mobile) project_offset=61 ;;
firefox-desktop) project_offset=62 ;;
firefox-tablet) project_offset=63 ;;
*) echo "Unsupported Playwright project: $MATRIX_PROJECT" >&2; exit 1 ;;
esac
port_seed=$((20000 + (RUN_ID % 20000) + project_offset))
lock_root="${PLAYWRIGHT_PORT_LOCK_ROOT:-/tmp/pleno-playwright-port-locks}"
mkdir -p "$lock_root"
chmod 1777 "$lock_root" 2>/dev/null || true
find "$lock_root" -mindepth 1 -maxdepth 1 -type d -mmin +360 -exec rmdir {} \; 2>/dev/null || true
playwright_port_lock=""
playwright_dev_port=""
for ((candidate = port_seed; candidate < port_seed + 1000; candidate += 1)); do
lock_dir="${lock_root}/${candidate}.lock"
if ! mkdir "$lock_dir" 2>/dev/null; then
continue
fi
if ss -H -ltn "sport = :${candidate}" 2>/dev/null | grep -q .; then
rmdir "$lock_dir" || true
continue
fi
playwright_port_lock="$lock_dir"
playwright_dev_port="$candidate"
break
done
if [[ -z "$playwright_dev_port" ]]; then
echo "Unable to find a free Playwright dev-server port." >&2
exit 1
fi
trap 'if [[ -n "${playwright_port_lock:-}" ]]; then rmdir "$playwright_port_lock" 2>/dev/null || true; fi' EXIT
if docker info >/dev/null 2>&1; then
docker_cmd=(docker)
elif sudo -n docker info >/dev/null 2>&1; then
docker_cmd=(sudo docker)
else
echo "Docker is not available to the runner user, and sudo docker is not available." >&2
exit 1
fi
mkdir -p output/playwright
scripts/ci/runner-diagnostics.sh "before targeted Playwright ${MATRIX_PROJECT}" -- "${docker_cmd[@]}"
SYSTEMD_INHIBIT_REASON="Frontend targeted Playwright ${MATRIX_PROJECT}" \
scripts/ci/with-systemd-inhibit.sh "${docker_cmd[@]}" run --rm --ipc=host --network host \
--volume "$PWD:/source:ro" \
--volume "$PWD/output/playwright:/work/output/playwright" \
--workdir /work \
--env HOME=/tmp \
--env CI="${CI:-}" \
--env PLAYWRIGHT_ARTIFACT_NAMESPACE="$PLAYWRIGHT_ARTIFACT_NAMESPACE" \
--env PLAYWRIGHT_REPORTER_MODE="$PLAYWRIGHT_REPORTER_MODE" \
--env PLAYWRIGHT_WORKERS="$PLAYWRIGHT_WORKERS" \
--env PLAYWRIGHT_VIDEO_MODE="$PLAYWRIGHT_VIDEO_MODE" \
--env PLAYWRIGHT_DEV_PORT="$playwright_dev_port" \
--env MATRIX_PROJECT="$MATRIX_PROJECT" \
--env TARGET_GREP="$TARGET_GREP" \
--env TARGET_SPECS="$TARGET_SPECS" \
mcr.microsoft.com/playwright:v1.58.2-noble \
bash -lc '
set -euo pipefail
tar --exclude=./output/playwright -C /source -cf - . | tar -C /work -xf -
git config --global --add safe.directory /work
install_dependencies() {
local attempt
for attempt in 1 2 3; do
if npm ci --legacy-peer-deps --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000; then
return 0
fi
if [[ "$attempt" == "3" ]]; then
return 1
fi
echo "npm ci failed on attempt ${attempt}; retrying..." >&2
sleep 20
done
}
install_dependencies
ulimit -n 16384 || true
mapfile -t spec_args < <(printf "%s\n" "$TARGET_SPECS" | tr "," "\n" | sed "s/^[[:space:]]*//;s/[[:space:]]*$//;/^$/d")
if [[ "${#spec_args[@]}" -eq 0 && -z "${TARGET_GREP:-}" ]]; then
echo "Provide at least one spec path or grep pattern." >&2
exit 1
fi
for spec_path in "${spec_args[@]}"; do
if [[ "$spec_path" == /* || "$spec_path" == *".."* || "$spec_path" != tests/e2e/* ]]; then
echo "Targeted spec must stay under tests/e2e: $spec_path" >&2
exit 1
fi
if [[ ! -f "$spec_path" ]]; then
echo "Targeted spec does not exist: $spec_path" >&2
exit 1
fi
done
args=("${spec_args[@]}")
if [[ -n "${TARGET_GREP:-}" ]]; then
args+=(--grep "$TARGET_GREP")
fi
args+=(--project="$MATRIX_PROJECT")
npx playwright test "${args[@]}"
'
- name: Runner diagnostics after Playwright failure
if: failure() || cancelled()
continue-on-error: true
run: scripts/ci/runner-diagnostics.sh "after targeted Playwright ${{ matrix.project }}"
- name: Upload Playwright report
if: failure() || cancelled()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: playwright-report-targeted-${{ matrix.project }}
path: |
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}-*
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}
if-no-files-found: ignore
retention-days: 1
e2e-pr:
if: >
always() &&
github.event_name != 'schedule' &&
needs.build-and-unit.result == 'success' &&
!(github.event_name == 'workflow_dispatch' && inputs.mode == 'targeted') &&
(
github.event_name != 'workflow_dispatch' ||
inputs.mode == 'full' ||
needs.e2e-targeted.result == 'success'
)
needs: [build-and-unit, e2e-targeted]
name: E2E-pr-${{ matrix.suite }}-${{ matrix.project }}
runs-on: ${{ fromJSON(vars.FRONTEND_CI_E2E_RUNNER || '["self-hosted","Linux","X64","pleno","frontend","docker"]') }}
timeout-minutes: 45
strategy:
fail-fast: false
max-parallel: ${{ fromJSON(vars.FRONTEND_CI_PR_E2E_MAX_PARALLEL || '2') }}
matrix:
suite: [core, changed]
project: [chromium-desktop, chromium-mobile]
env:
PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-pr-${{ matrix.suite }}-${{ matrix.project }}
PLAYWRIGHT_REPORTER_MODE: line-html
PLAYWRIGHT_WORKERS: 1
PLAYWRIGHT_VIDEO_MODE: on-first-retry
if: github.event_name != 'schedule'
needs: build-and-unit
runs-on: [self-hosted, Linux, X64, default]
steps:
- name: Repair self-hosted workspace permissions
if: ${{ contains(vars.FRONTEND_CI_E2E_RUNNER || 'self-hosted', 'self-hosted') }}
shell: bash
run: |
if [[ -d "$GITHUB_WORKSPACE" ]]; then
sudo -n chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE" 2>/dev/null || true
foreign_entry="$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 2 ! -user "$(id -u)" -print -quit 2>/dev/null || true)"
if [[ -n "$foreign_entry" ]]; then
trash="$GITHUB_WORKSPACE/../_workspace-trash-$GITHUB_RUN_ID-$GITHUB_JOB"
rm -rf "$trash" 2>/dev/null || true
mv "$GITHUB_WORKSPACE" "$trash" 2>/dev/null || true
mkdir -p "$GITHUB_WORKSPACE"
fi
fi
- name: Checkout repository
uses: actions/checkout@v5
with:
@@ -365,206 +79,70 @@ jobs:
EVENT_NAME: ${{ github.event_name }}
HEAD_SHA: ${{ github.sha }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PUSH_BEFORE_SHA: ${{ github.event.before }}
run: |
set -euo pipefail
zero_sha="0000000000000000000000000000000000000000"
if [[ "$EVENT_NAME" == "pull_request" && -n "$PR_BASE_SHA" ]]; then
base_ref="$PR_BASE_SHA"
head_ref="$PR_HEAD_SHA"
elif [[ -z "$PUSH_BEFORE_SHA" || "$PUSH_BEFORE_SHA" == "$zero_sha" ]]; then
git fetch --no-tags --prune origin "$DEFAULT_BRANCH"
base_ref="origin/$DEFAULT_BRANCH"
head_ref="$HEAD_SHA"
else
base_ref="$PUSH_BEFORE_SHA"
head_ref="$HEAD_SHA"
fi
if [[ "$EVENT_NAME" == "pull_request" && -n "$PR_HEAD_SHA" ]]; then
head_ref="$PR_HEAD_SHA"
else
head_ref="$HEAD_SHA"
fi
echo "base=$base_ref" >> "$GITHUB_OUTPUT"
echo "head=$head_ref" >> "$GITHUB_OUTPUT"
echo "head=$HEAD_SHA" >> "$GITHUB_OUTPUT"
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Run Playwright PR suite in container
shell: bash
env:
DIFF_BASE_REF: ${{ steps.playwright-diff.outputs.base }}
DIFF_HEAD_REF: ${{ steps.playwright-diff.outputs.head }}
MATRIX_SUITE: ${{ matrix.suite }}
MATRIX_PROJECT: ${{ matrix.project }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
case "$MATRIX_SUITE" in
core) suite_offset=0 ;;
changed) suite_offset=10 ;;
*) echo "Unsupported Playwright PR suite: $MATRIX_SUITE" >&2; exit 1 ;;
esac
case "$MATRIX_PROJECT" in
chromium-desktop) project_offset=1 ;;
chromium-mobile) project_offset=2 ;;
*) echo "Unsupported Playwright PR project: $MATRIX_PROJECT" >&2; exit 1 ;;
esac
port_seed=$((20000 + (RUN_ID % 20000) + suite_offset + project_offset))
lock_root="${PLAYWRIGHT_PORT_LOCK_ROOT:-/tmp/pleno-playwright-port-locks}"
mkdir -p "$lock_root"
chmod 1777 "$lock_root" 2>/dev/null || true
find "$lock_root" -mindepth 1 -maxdepth 1 -type d -mmin +360 -exec rmdir {} \; 2>/dev/null || true
playwright_port_lock=""
playwright_dev_port=""
for ((candidate = port_seed; candidate < port_seed + 1000; candidate += 1)); do
lock_dir="${lock_root}/${candidate}.lock"
if ! mkdir "$lock_dir" 2>/dev/null; then
continue
fi
if ss -H -ltn "sport = :${candidate}" 2>/dev/null | grep -q .; then
rmdir "$lock_dir" || true
continue
fi
playwright_port_lock="$lock_dir"
playwright_dev_port="$candidate"
break
done
if [[ -z "$playwright_dev_port" ]]; then
echo "Unable to find a free Playwright dev-server port." >&2
exit 1
fi
trap 'if [[ -n "${playwright_port_lock:-}" ]]; then rmdir "$playwright_port_lock" 2>/dev/null || true; fi' EXIT
if docker info >/dev/null 2>&1; then
docker_cmd=(docker)
elif sudo -n docker info >/dev/null 2>&1; then
docker_cmd=(sudo docker)
else
echo "Docker is not available to the runner user, and sudo docker is not available." >&2
exit 1
fi
mkdir -p output/playwright
scripts/ci/runner-diagnostics.sh "before Playwright PR ${MATRIX_SUITE}/${MATRIX_PROJECT}" -- "${docker_cmd[@]}"
SYSTEMD_INHIBIT_REASON="Frontend Playwright PR ${MATRIX_SUITE}/${MATRIX_PROJECT}" \
scripts/ci/with-systemd-inhibit.sh "${docker_cmd[@]}" run --rm --ipc=host --network host \
--volume "$PWD:/source:ro" \
--volume "$PWD/output/playwright:/work/output/playwright" \
--workdir /work \
--env HOME=/tmp \
--env CI="${CI:-}" \
--env PLAYWRIGHT_ARTIFACT_NAMESPACE="$PLAYWRIGHT_ARTIFACT_NAMESPACE" \
--env PLAYWRIGHT_REPORTER_MODE="$PLAYWRIGHT_REPORTER_MODE" \
--env PLAYWRIGHT_WORKERS="$PLAYWRIGHT_WORKERS" \
--env PLAYWRIGHT_VIDEO_MODE="$PLAYWRIGHT_VIDEO_MODE" \
--env PLAYWRIGHT_DEV_PORT="$playwright_dev_port" \
--env MATRIX_SUITE="$MATRIX_SUITE" \
--env MATRIX_PROJECT="$MATRIX_PROJECT" \
--env DIFF_BASE_REF="$DIFF_BASE_REF" \
--env DIFF_HEAD_REF="$DIFF_HEAD_REF" \
mcr.microsoft.com/playwright:v1.58.2-noble \
bash -lc '
set -euo pipefail
tar --exclude=./output/playwright -C /source -cf - . | tar -C /work -xf -
git config --global --add safe.directory /work
install_dependencies() {
local attempt
for attempt in 1 2 3; do
if npm ci --legacy-peer-deps --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000; then
return 0
fi
if [[ "$attempt" == "3" ]]; then
return 1
fi
echo "npm ci failed on attempt ${attempt}; retrying..." >&2
sleep 20
done
}
install_dependencies
ulimit -n 16384 || true
if [[ "$MATRIX_SUITE" == "core" ]]; then
PLAYWRIGHT_ARTIFACT_NAMESPACE="${PLAYWRIGHT_ARTIFACT_NAMESPACE}-ct" npm run test:ct -- --project="$MATRIX_PROJECT"
npx playwright test --grep @smoke --project="$MATRIX_PROJECT"
npm run test:e2e:pr -- --core-only --project="$MATRIX_PROJECT"
else
npm run test:e2e:pr -- --changed-only --project="$MATRIX_PROJECT" --base="$DIFF_BASE_REF" --head="$DIFF_HEAD_REF"
fi
'
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Runner diagnostics after Playwright failure
if: failure() || cancelled()
continue-on-error: true
run: scripts/ci/runner-diagnostics.sh "after Playwright PR ${{ matrix.suite }}/${{ matrix.project }}"
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Run Playwright PR tests
run: npm run test:e2e:pr -- --base="${{ steps.playwright-diff.outputs.base }}" --head="${{ steps.playwright-diff.outputs.head }}"
- name: Upload Playwright report
if: failure() || cancelled()
continue-on-error: true
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report-pr-${{ matrix.suite }}-${{ matrix.project }}
path: |
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}-*
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}
name: playwright-report-pr
path: output/playwright
if-no-files-found: ignore
retention-days: 1
retention-days: 7
e2e-full:
if: >
always() &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.ref_name == github.event.repository.default_branch) &&
!(github.event_name == 'workflow_dispatch' && inputs.mode == 'targeted') &&
needs.build-and-unit.result == 'success' &&
(github.event_name == 'schedule' || needs.e2e-pr.result == 'success') &&
(
github.event_name != 'workflow_dispatch' ||
inputs.mode == 'full' ||
needs.e2e-targeted.result == 'success'
)
needs: [build-and-unit, e2e-pr, e2e-targeted]
name: E2E-full-${{ matrix.browser_label }}-${{ matrix.device }}-${{ matrix.role }}
runs-on: ${{ fromJSON(vars.FRONTEND_CI_E2E_RUNNER || '["self-hosted","Linux","X64","pleno","frontend","docker"]') }}
timeout-minutes: 60
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.ref_name == github.event.repository.default_branch
needs: build-and-unit
name: E2E-full-${{ matrix.role }}-${{ matrix.browser_label }}-${{ matrix.device }}
runs-on: [self-hosted, Linux, X64, default]
strategy:
fail-fast: false
max-parallel: ${{ fromJSON(vars.FRONTEND_CI_FULL_E2E_MAX_PARALLEL || '1') }}
matrix:
browser: [chromium, webkit, firefox]
device: [mobile, desktop, tablet]
role: [superuser, admin, customer, subuser]
role: [customer, subuser, admin, superuser]
browser: [chromium, firefox, webkit]
device: [mobile, tablet, desktop]
include:
- browser: chromium
browser_label: Chromium
browser_install: chromium
- browser: webkit
browser_label: WebKit
browser_install: webkit
- browser: firefox
browser_label: Firefox
browser_install: firefox
- browser: webkit
browser_label: WebKit
browser_install: webkit
env:
PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-full-${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}
PLAYWRIGHT_ARTIFACT_NAMESPACE: e2e-full-${{ matrix.role }}-${{ matrix.browser }}-${{ matrix.device }}
PLAYWRIGHT_REPORTER_MODE: line-html
PLAYWRIGHT_WORKERS: 1
PLAYWRIGHT_VIDEO_MODE: off
steps:
- name: Repair self-hosted workspace permissions
if: ${{ contains(vars.FRONTEND_CI_E2E_RUNNER || 'self-hosted', 'self-hosted') }}
shell: bash
run: |
if [[ -d "$GITHUB_WORKSPACE" ]]; then
sudo -n chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE" 2>/dev/null || true
foreign_entry="$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 2 ! -user "$(id -u)" -print -quit 2>/dev/null || true)"
if [[ -n "$foreign_entry" ]]; then
trash="$GITHUB_WORKSPACE/../_workspace-trash-$GITHUB_RUN_ID-$GITHUB_JOB"
rm -rf "$trash" 2>/dev/null || true
mv "$GITHUB_WORKSPACE" "$trash" 2>/dev/null || true
mkdir -p "$GITHUB_WORKSPACE"
fi
fi
- name: Checkout repository
uses: actions/checkout@v5
@@ -572,122 +150,25 @@ jobs:
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
- name: Run full Playwright slice in container
shell: bash
env:
MATRIX_ROLE: ${{ matrix.role }}
MATRIX_BROWSER: ${{ matrix.browser }}
MATRIX_DEVICE: ${{ matrix.device }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
case "$MATRIX_ROLE" in
superuser) role_offset=0 ;;
admin) role_offset=100 ;;
customer) role_offset=200 ;;
subuser) role_offset=300 ;;
*) echo "Unsupported Playwright role: $MATRIX_ROLE" >&2; exit 1 ;;
esac
case "$MATRIX_BROWSER" in
chromium) browser_offset=0 ;;
webkit) browser_offset=30 ;;
firefox) browser_offset=60 ;;
*) echo "Unsupported Playwright browser: $MATRIX_BROWSER" >&2; exit 1 ;;
esac
case "$MATRIX_DEVICE" in
mobile) device_offset=1 ;;
desktop) device_offset=2 ;;
tablet) device_offset=3 ;;
*) echo "Unsupported Playwright device: $MATRIX_DEVICE" >&2; exit 1 ;;
esac
port_seed=$((20000 + (RUN_ID % 20000) + role_offset + browser_offset + device_offset))
lock_root="${PLAYWRIGHT_PORT_LOCK_ROOT:-/tmp/pleno-playwright-port-locks}"
mkdir -p "$lock_root"
chmod 1777 "$lock_root" 2>/dev/null || true
find "$lock_root" -mindepth 1 -maxdepth 1 -type d -mmin +360 -exec rmdir {} \; 2>/dev/null || true
playwright_port_lock=""
playwright_dev_port=""
for ((candidate = port_seed; candidate < port_seed + 1000; candidate += 1)); do
lock_dir="${lock_root}/${candidate}.lock"
if ! mkdir "$lock_dir" 2>/dev/null; then
continue
fi
if ss -H -ltn "sport = :${candidate}" 2>/dev/null | grep -q .; then
rmdir "$lock_dir" || true
continue
fi
playwright_port_lock="$lock_dir"
playwright_dev_port="$candidate"
break
done
if [[ -z "$playwright_dev_port" ]]; then
echo "Unable to find a free Playwright dev-server port." >&2
exit 1
fi
trap 'if [[ -n "${playwright_port_lock:-}" ]]; then rmdir "$playwright_port_lock" 2>/dev/null || true; fi' EXIT
if docker info >/dev/null 2>&1; then
docker_cmd=(docker)
elif sudo -n docker info >/dev/null 2>&1; then
docker_cmd=(sudo docker)
else
echo "Docker is not available to the runner user, and sudo docker is not available." >&2
exit 1
fi
mkdir -p output/playwright
scripts/ci/runner-diagnostics.sh "before Playwright full ${MATRIX_BROWSER}/${MATRIX_DEVICE}/${MATRIX_ROLE}" -- "${docker_cmd[@]}"
SYSTEMD_INHIBIT_REASON="Frontend Playwright full ${MATRIX_BROWSER}/${MATRIX_DEVICE}/${MATRIX_ROLE}" \
scripts/ci/with-systemd-inhibit.sh "${docker_cmd[@]}" run --rm --ipc=host --network host \
--volume "$PWD:/source:ro" \
--volume "$PWD/output/playwright:/work/output/playwright" \
--workdir /work \
--env HOME=/tmp \
--env CI="${CI:-}" \
--env PLAYWRIGHT_ARTIFACT_NAMESPACE="$PLAYWRIGHT_ARTIFACT_NAMESPACE" \
--env PLAYWRIGHT_REPORTER_MODE="$PLAYWRIGHT_REPORTER_MODE" \
--env PLAYWRIGHT_WORKERS="$PLAYWRIGHT_WORKERS" \
--env PLAYWRIGHT_VIDEO_MODE="$PLAYWRIGHT_VIDEO_MODE" \
--env PLAYWRIGHT_DEV_PORT="$playwright_dev_port" \
--env MATRIX_ROLE="$MATRIX_ROLE" \
--env MATRIX_BROWSER="$MATRIX_BROWSER" \
--env MATRIX_DEVICE="$MATRIX_DEVICE" \
mcr.microsoft.com/playwright:v1.58.2-noble \
bash -lc '
set -euo pipefail
tar --exclude=./output/playwright -C /source -cf - . | tar -C /work -xf -
git config --global --add safe.directory /work
install_dependencies() {
local attempt
for attempt in 1 2 3; do
if npm ci --legacy-peer-deps --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000; then
return 0
fi
if [[ "$attempt" == "3" ]]; then
return 1
fi
echo "npm ci failed on attempt ${attempt}; retrying..." >&2
sleep 20
done
}
install_dependencies
ulimit -n 16384 || true
npm run test:e2e:full:slice -- --role="$MATRIX_ROLE" --project="$MATRIX_BROWSER-$MATRIX_DEVICE"
'
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Runner diagnostics after Playwright failure
if: failure() || cancelled()
continue-on-error: true
run: scripts/ci/runner-diagnostics.sh "after Playwright full ${{ matrix.browser }}/${{ matrix.device }}/${{ matrix.role }}"
- name: Install Playwright browsers
run: npx playwright install --with-deps ${{ matrix.browser_install }}
- name: Run full Playwright slice
run: npm run test:e2e:full:slice -- --role="${{ matrix.role }}" --project="${{ matrix.browser }}-${{ matrix.device }}"
- name: Upload Playwright report
if: failure() || cancelled()
continue-on-error: true
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report-full-${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}
name: playwright-report-full-${{ matrix.role }}-${{ matrix.browser }}-${{ matrix.device }}
path: |
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}/report
output/playwright/${{ env.PLAYWRIGHT_ARTIFACT_NAMESPACE }}/test-results
output/playwright/test-lists/${{ matrix.browser }}-${{ matrix.device }}-${{ matrix.role }}.txt
output/playwright/test-lists/${{ matrix.role }}-${{ matrix.browser }}-${{ matrix.device }}.txt
if-no-files-found: ignore
retention-days: 1
retention-days: 14
-9
View File
@@ -8,7 +8,6 @@ pnpm-debug.log*
lerna-debug.log*
node_modules
node_modules.codex-permission-blocked-*
.DS_Store
dist
dist-ssr
@@ -16,14 +15,6 @@ coverage
*.local
dev-dist
# Mobile build and signing outputs
/app/build/
/app-release*.aab
/app-release*.apk
/app-release*.idsig
*.keystore
*.jks
/cypress/videos/
/cypress/screenshots/
-4
View File
@@ -1,4 +0,0 @@
{
"version": 1,
"setupCompletedAt": "2026-06-07T11:37:04.444Z"
}
+7 -51
View File
@@ -96,22 +96,16 @@ Artifacts and summaries:
## Playwright Full E2E
Run the permanent grouped full-suite entrypoint with a hard max of 5 total workers across the browser-engine groups:
Run the permanent grouped full-suite entrypoint with a hard max of 5 total workers across:
- Chromium
- WebKit
- Firefox
- `chromium-(desktop|tablet|mobile)`
- `firefox-(desktop|tablet|mobile)`
- `webkit-(desktop|tablet|mobile)`
```sh
npm run test:e2e:ci
```
The full CI matrix is ordered by browser engine, then device class, then user role:
- browsers: `chromium`, `webkit`, `firefox`
- devices: `mobile`, `desktop`, `tablet`
- roles: `superuser`, `admin`, `customer`, `subuser`
Run a single full-suite slice for one role and one Playwright project:
```sh
@@ -123,7 +117,7 @@ Default worker allocation:
```sh
PLAYWRIGHT_PARALLEL_WORKERS_CHROMIUM=2
PLAYWRIGHT_PARALLEL_WORKERS_FIREFOX=1
PLAYWRIGHT_PARALLEL_WORKERS_WEBKIT=1
PLAYWRIGHT_PARALLEL_WORKERS_WEBKIT=2
```
Optional overrides:
@@ -132,56 +126,18 @@ Optional overrides:
PLAYWRIGHT_PARALLEL_BASE_PORT=5191
PLAYWRIGHT_PARALLEL_WORKERS_CHROMIUM=2
PLAYWRIGHT_PARALLEL_WORKERS_FIREFOX=1
PLAYWRIGHT_PARALLEL_WORKERS_WEBKIT=1
PLAYWRIGHT_PARALLEL_WORKERS_WEBKIT=2
```
The runner fails fast if the combined worker count exceeds 5.
GitHub Actions keeps the full browser/device/role matrix stable by capping full-suite
matrix parallelism at 2 jobs, running each full slice with `PLAYWRIGHT_WORKERS=1`,
wrapping Docker Playwright runs with `systemd-inhibit` when available, and setting
`PLAYWRIGHT_VIDEO_MODE=off` for the full matrix. The E2E network harness serves
Font Awesome from local fixtures so WebKit page loads and visual snapshots do not
depend on CDN/TLS availability. Traces and screenshots are still retained on
failure.
Artifacts and summaries:
- `output/playwright/ci-parallel-report/index.html`
- `output/playwright/ci-parallel-chromium/report/index.html`
- `output/playwright/ci-parallel-firefox/report/index.html`
- `output/playwright/ci-parallel-webkit/report/index.html`
- `output/playwright/test-lists/<project>-<role>.txt`
- `output/playwright/test-lists/<role>-<project>.txt` (legacy compatibility copy)
## Android App Icon
The Play Store Android package is built from the Capacitor project in `android/`.
The legacy Bubblewrap/TWA project at the repository root is not used by
`npm run mobile:android:bundle`.
The source image for the native launcher icon is:
```text
public/favicons/web-app-manifest-512x512.png
```
Regenerate the checked-in launcher assets after changing that source image:
```sh
npm run mobile:android:icons
```
Check that the generated Android launcher assets are current:
```sh
npm run mobile:android:icons:check
```
`npm run mobile:android:sync` runs the icon generator before building and syncing
the Capacitor Android project. The generator updates `android/app/src/main/res`
launcher assets, `public/icons/icon-192x192.png`, `public/icons/icon-512x512.png`,
and `store_icon.png`.
- `output/playwright/test-lists/<role>-<project>.txt`
## Bubblewrap (TWA) Build and Install
BIN
View File
Binary file not shown.
-101
View File
@@ -1,101 +0,0 @@
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore
# Built application files
*.apk
*.aar
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/
# Google Services (e.g. APIs or Firebase)
# google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
# Version control
vcs.xml
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
# Android Profiling
*.hprof
# Cordova plugins for Capacitor
capacitor-cordova-android-plugins
# Copied web assets
app/src/main/assets/public
# Generated Config files
app/src/main/assets/capacitor.config.json
app/src/main/assets/capacitor.plugins.json
app/src/main/res/xml/config.xml
-2
View File
@@ -1,2 +0,0 @@
/build/*
!/build/.npmkeep
-77
View File
@@ -1,77 +0,0 @@
apply plugin: 'com.android.application'
def mobileEnv = { String name, String defaultValue = null ->
return System.getenv(name) ?: (project.hasProperty(name) ? project.property(name).toString() : defaultValue)
}
def releaseStoreFile = mobileEnv('ANDROID_KEYSTORE_FILE')
def hasReleaseSigning = releaseStoreFile &&
mobileEnv('ANDROID_KEYSTORE_PASSWORD') &&
mobileEnv('ANDROID_KEY_ALIAS') &&
mobileEnv('ANDROID_KEY_PASSWORD')
android {
namespace = "io.truckwash.twa"
compileSdk = rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "io.truckwash.twa"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode Integer.parseInt(mobileEnv('MOBILE_VERSION_CODE', '1'))
versionName mobileEnv('MOBILE_VERSION_NAME', '1.0')
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
signingConfigs {
release {
if (hasReleaseSigning) {
storeFile file(releaseStoreFile)
storePassword mobileEnv('ANDROID_KEYSTORE_PASSWORD')
keyAlias mobileEnv('ANDROID_KEY_ALIAS')
keyPassword mobileEnv('ANDROID_KEY_PASSWORD')
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (hasReleaseSigning) {
signingConfig signingConfigs.release
}
}
}
}
repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation project(':capacitor-android')
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
implementation project(':capacitor-cordova-android-plugins')
}
apply from: 'capacitor.build.gradle'
try {
def servicesJSON = file('google-services.json')
if (servicesJSON.text) {
apply plugin: 'com.google.gms.google-services'
}
} catch(Exception e) {
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
}
-19
View File
@@ -1,19 +0,0 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
}
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-geolocation')
}
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
-21
View File
@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -1,26 +0,0 @@
package io.truckwash.twa;
import static org.junit.Assert.*;
import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("io.truckwash.twa", appContext.getPackageName());
}
}
-53
View File
@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation|density"
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
@@ -1,5 +0,0 @@
package io.truckwash.twa;
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

@@ -1,34 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
@@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#0787BB</color>
</resources>
@@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name">Truck Wash</string>
<string name="title_activity_main">Truck Wash</string>
<string name="package_name">io.truckwash.twa</string>
<string name="custom_url_scheme">io.truckwash.twa</string>
</resources>
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:background">@null</item>
</style>
<style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<item name="android:background">@drawable/splash</item>
</style>
</resources>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
</paths>
@@ -1,18 +0,0 @@
package io.truckwash.twa;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
-29
View File
@@ -1,29 +0,0 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.13.0'
classpath 'com.google.gms:google-services:4.4.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
apply from: "variables.gradle"
allprojects {
repositories {
google()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
-6
View File
@@ -1,6 +0,0 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
include ':capacitor-geolocation'
project(':capacitor-geolocation').projectDir = new File('../node_modules/@capacitor/geolocation/android')
-22
View File
@@ -1,22 +0,0 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
Binary file not shown.
-7
View File
@@ -1,7 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-251
View File
@@ -1,251 +0,0 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed 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
#
# https://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.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
-94
View File
@@ -1,94 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-5
View File
@@ -1,5 +0,0 @@
include ':app'
include ':capacitor-cordova-android-plugins'
project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
apply from: 'capacitor.settings.gradle'
-16
View File
@@ -1,16 +0,0 @@
ext {
minSdkVersion = 24
compileSdkVersion = 36
targetSdkVersion = 36
androidxActivityVersion = '1.11.0'
androidxAppCompatVersion = '1.7.1'
androidxCoordinatorLayoutVersion = '1.3.0'
androidxCoreVersion = '1.17.0'
androidxFragmentVersion = '1.8.9'
coreSplashScreenVersion = '1.2.0'
androidxWebkitVersion = '1.14.0'
junitVersion = '4.13.2'
androidxJunitVersion = '1.3.0'
androidxEspressoCoreVersion = '3.7.0'
cordovaAndroidVersion = '14.0.1'
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -3
View File
@@ -56,9 +56,9 @@ android {
defaultConfig {
applicationId "io.truckwash.twa"
minSdkVersion 21
targetSdkVersion 36
versionCode 7
versionName "7"
targetSdkVersion 35
versionCode 6
versionName "6"
// The name for the application
resValue "string", "appName", twaManifest.name
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Automatically generated file. DO NOT MODIFY -->
<!-- Value from default config. -->
<bool name="enableNotification">true</bool>
<!-- Value from default config. -->
<bool name="enableSiteSettingsShortcut">true</bool>
<!-- Value from default config. -->
<color name="backgroundColor">#0787BB</color>
<!-- Value from default config. -->
<color name="colorPrimary">#063651</color>
<!-- Value from default config. -->
<color name="colorPrimaryDark">#000000</color>
<!-- Value from default config. -->
<color name="navigationColor">#000000</color>
<!-- Value from default config. -->
<color name="navigationColorDark">#000000</color>
<!-- Value from default config. -->
<color name="navigationDividerColor">#000000</color>
<!-- Value from default config. -->
<color name="navigationDividerColorDark">#000000</color>
<!-- Value from default config. -->
<integer name="splashScreenFadeOutDuration">300</integer>
<!-- Value from default config. -->
<string name="appName" translatable="false">Truck Wash</string>
<!-- Value from default config. -->
<string name="fallbackType" translatable="false">customtabs</string>
<!-- Value from default config. -->
<string name="fullScopeUrl" translatable="false">https://truckwash.io/</string>
<!-- Value from default config. -->
<string name="generatorApp" translatable="false">bubblewrap-cli</string>
<!-- Value from default config. -->
<string name="hostName" translatable="false">truckwash.io</string>
<!-- Value from default config. -->
<string name="launchHandlerClientMode" translatable="false">navigate-existing</string>
<!-- Value from default config. -->
<string name="launchUrl" translatable="false">https://truckwash.io/</string>
<!-- Value from default config. -->
<string name="launcherName" translatable="false">Truck Wash</string>
<!-- Value from default config. -->
<string name="orientation" translatable="false">portrait</string>
<!-- Value from default config. -->
<string name="providerAuthority" translatable="false">io.truckwash.twa.fileprovider</string>
<!-- Value from default config. -->
<string name="webManifestUrl" translatable="false">https://truckwash.io/manifest.webmanifest</string>
</resources>
@@ -0,0 +1,55 @@
-keep class androidx.core.app.CoreComponentFactory { <init>(); }
-keep class androidx.core.content.FileProvider { <init>(); }
-keep class androidx.profileinstaller.ProfileInstallReceiver { <init>(); }
-keep class androidx.startup.InitializationProvider { <init>(); }
-keep class com.google.android.gms.common.api.GoogleApiActivity { <init>(); }
-keep class com.google.androidbrowserhelper.locationdelegation.PermissionRequestActivity { <init>(); }
-keep class com.google.androidbrowserhelper.trusted.FocusActivity { <init>(); }
-keep class com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity { <init>(); }
-keep class com.google.androidbrowserhelper.trusted.NotificationPermissionRequestActivity { <init>(); }
-keep class com.google.androidbrowserhelper.trusted.WebViewFallbackActivity { <init>(); }
-keep class io.truckwash.twa.Application { <init>(); }
-keep class io.truckwash.twa.DelegationService { <init>(); }
-keep class io.truckwash.twa.LauncherActivity { <init>(); }
-keep class android.widget.Space { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.app.AlertController$RecycleListView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.view.menu.ActionMenuItemView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.view.menu.ExpandedMenuView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.view.menu.ListMenuItemView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ActionBarContainer { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ActionBarContextView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ActionBarOverlayLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ActionMenuView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ActivityChooserView$InnerLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.AlertDialogLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ButtonBarLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ContentFrameLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.DialogTitle { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.FitWindowsFrameLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.FitWindowsLinearLayout { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.SearchView$SearchAutoComplete { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.Toolbar { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.appcompat.widget.ViewStubCompat { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.browser.browseractions.BrowserActionsFallbackMenuView { <init>(android.content.Context, android.util.AttributeSet); }
-keep class androidx.core.widget.NestedScrollView { <init>(android.content.Context, android.util.AttributeSet); }
@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../../outputs/apk/release/output-metadata.json
@@ -0,0 +1,2 @@
appMetadataVersion=1.1
androidGradlePluginVersion=8.9.1
@@ -0,0 +1,18 @@
{
"version": 3,
"artifactType": {
"type": "BUNDLE",
"kind": "RegularFile"
},
"applicationId": "io.truckwash.twa",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"outputFile": "../../../../outputs/bundle/release/app-release.aab"
}
],
"elementType": "File"
}
@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../bundle_ide_model/release/produceReleaseBundleIdeListingFile/output-metadata.json
@@ -0,0 +1,222 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Google Inc. All Rights Reserved.
Licensed 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.
-->
<!--
The "package" attribute is rewritten by the Gradle build with the value of applicationId.
It is still required here, as it is used to derive paths, for instance when referring
to an Activity by ".MyActivity" instead of the full name. If more Activities are added to the
application, the package attribute will need to reflect the correct path in order to use
the abbreviated format.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.truckwash.twa"
android:versionCode="6"
android:versionName="6" >
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="35" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
<permission
android:name="io.truckwash.twa.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
android:protectionLevel="signature" />
<uses-permission android:name="io.truckwash.twa.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" />
<application
android:name="io.truckwash.twa.Application"
android:allowBackup="true"
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/appName"
android:manageSpaceActivity="com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity"
android:supportsRtl="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<meta-data
android:name="asset_statements"
android:resource="@string/assetStatements" />
<meta-data
android:name="web_manifest_url"
android:value="@string/webManifestUrl" />
<meta-data
android:name="twa_generator"
android:value="@string/generatorApp" />
<activity android:name="com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity" >
<meta-data
android:name="android.support.customtabs.trusted.MANAGE_SPACE_URL"
android:value="@string/launchUrl" />
</activity>
<activity
android:name="io.truckwash.twa.LauncherActivity"
android:alwaysRetainTaskState="true"
android:exported="true"
android:label="@string/launcherName" >
<meta-data
android:name="android.support.customtabs.trusted.DEFAULT_URL"
android:value="@string/launchUrl" />
<meta-data
android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR"
android:resource="@color/colorPrimary" />
<meta-data
android:name="android.support.customtabs.trusted.LAUNCH_HANDLER_CLIENT_MODE"
android:value="@string/launchHandlerClientMode" />
<meta-data
android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR_DARK"
android:resource="@color/colorPrimaryDark" />
<meta-data
android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR"
android:resource="@color/navigationColor" />
<meta-data
android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR_DARK"
android:resource="@color/navigationColorDark" />
<meta-data
android:name="androix.browser.trusted.NAVIGATION_BAR_DIVIDER_COLOR"
android:resource="@color/navigationDividerColor" />
<meta-data
android:name="androix.browser.trusted.NAVIGATION_BAR_DIVIDER_COLOR_DARK"
android:resource="@color/navigationDividerColorDark" />
<meta-data
android:name="android.support.customtabs.trusted.SPLASH_IMAGE_DRAWABLE"
android:resource="@drawable/splash" />
<meta-data
android:name="android.support.customtabs.trusted.SPLASH_SCREEN_BACKGROUND_COLOR"
android:resource="@color/backgroundColor" />
<meta-data
android:name="android.support.customtabs.trusted.SPLASH_SCREEN_FADE_OUT_DURATION"
android:value="@integer/splashScreenFadeOutDuration" />
<meta-data
android:name="android.support.customtabs.trusted.FILE_PROVIDER_AUTHORITY"
android:value="@string/providerAuthority" />
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
<meta-data
android:name="android.support.customtabs.trusted.FALLBACK_STRATEGY"
android:value="@string/fallbackType" />
<meta-data
android:name="android.support.customtabs.trusted.SCREEN_ORIENTATION"
android:value="@string/orientation" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="@string/hostName"
android:scheme="https" />
</intent-filter>
</activity>
<activity android:name="com.google.androidbrowserhelper.trusted.FocusActivity" />
<activity
android:name="com.google.androidbrowserhelper.trusted.WebViewFallbackActivity"
android:configChanges="orientation|screenSize" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="@string/providerAuthority"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
<service
android:name="io.truckwash.twa.DelegationService"
android:enabled="@bool/enableNotification"
android:exported="@bool/enableNotification" >
<meta-data
android:name="android.support.customtabs.trusted.SMALL_ICON"
android:resource="@drawable/ic_notification_icon" />
<intent-filter>
<action android:name="android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
<activity android:name="com.google.androidbrowserhelper.trusted.NotificationPermissionRequestActivity" />
<activity android:name="com.google.androidbrowserhelper.locationdelegation.PermissionRequestActivity" />
<activity
android:name="com.google.android.gms.common.api.GoogleApiActivity"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="io.truckwash.twa.androidx-startup"
android:exported="false" >
<meta-data
android:name="androidx.emoji2.text.EmojiCompatInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.profileinstaller.ProfileInstallerInitializer"
android:value="androidx.startup" />
</provider>
<receiver
android:name="androidx.profileinstaller.ProfileInstallReceiver"
android:directBootAware="false"
android:enabled="true"
android:exported="true"
android:permission="android.permission.DUMP" >
<intent-filter>
<action android:name="androidx.profileinstaller.action.INSTALL_PROFILE" />
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SKIP_FILE" />
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.SAVE_PROFILE" />
</intent-filter>
<intent-filter>
<action android:name="androidx.profileinstaller.action.BENCHMARK_OPERATION" />
</intent-filter>
</receiver>
</application>
</manifest>
@@ -0,0 +1,873 @@
Landroidx/activity/a;
Landroidx/activity/ComponentActivity$4;
Landroidx/lifecycle/j;
Landroidx/lifecycle/k;
HSPLandroidx/activity/ComponentActivity$4;->h(Landroidx/lifecycle/l;Landroidx/lifecycle/g$a;)V
Landroidx/activity/b;
Landroidx/core/app/b;
Landroidx/lifecycle/l;
Landroidx/lifecycle/E;
Landroidx/lifecycle/f;
LI/d;
Landroidx/activity/c;
HSPLandroidx/activity/c;-><init>(Z)V
HSPLandroidx/activity/c;->a()V
PLandroidx/activity/c;->b(Landroidx/activity/a;)V
HSPLandroidx/activity/c;->c(Z)V
Landroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;
PLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;->d()V
HSPLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;->h(Landroidx/lifecycle/l;Landroidx/lifecycle/g$a;)V
Landroidx/activity/OnBackPressedDispatcher;
HSPLandroidx/activity/OnBackPressedDispatcher;->a(Landroidx/activity/c;)Landroidx/activity/a;
Lc/a;
Lc/d;
Lc/e;
Lc/f;
Lc/g;
Lc/h;
Lc/i;
HSPLc/i;-><clinit>()V
Ld/a;
HSPLd/a;-><init>(II)V
Le/a;
Lg/b;
Lh/a;
HSPLh/a;-><init>(Landroid/content/Context;)V
HSPLh/a;->a(Landroid/content/Context;)Lh/a;
HSPLh/a;->b()I
HSPLh/a;->c()I
HSPLh/a;->d()Z
Lh/b;
HSPLh/b;-><clinit>()V
HSPLh/b;-><init>(Landroid/content/Context;)V
Li/a;
Ls/b;
HSPLi/a;-><init>(Landroid/content/Context;IIIILjava/lang/CharSequence;)V
Landroidx/appcompat/view/menu/a;
Landroidx/appcompat/view/menu/h;
HSPLandroidx/appcompat/view/menu/a;-><init>(Landroid/content/Context;II)V
HSPLandroidx/appcompat/view/menu/a;->k(Landroid/content/Context;Landroidx/appcompat/view/menu/d;)V
PLandroidx/appcompat/view/menu/a;->a(Landroidx/appcompat/view/menu/d;Z)V
HSPLandroidx/appcompat/view/menu/a;->f(Landroidx/appcompat/view/menu/h$a;)V
HSPLandroidx/appcompat/view/menu/a;->j(Z)V
Landroidx/appcompat/view/menu/d$a;
Landroidx/appcompat/view/menu/d$b;
Landroidx/appcompat/view/menu/d;
Ls/a;
HSPLandroidx/appcompat/view/menu/d;-><clinit>()V
HSPLandroidx/appcompat/view/menu/d;-><init>(Landroid/content/Context;)V
HSPLandroidx/appcompat/view/menu/d;->b(Landroidx/appcompat/view/menu/h;Landroid/content/Context;)V
PLandroidx/appcompat/view/menu/d;->close()V
PLandroidx/appcompat/view/menu/d;->d(Z)V
HSPLandroidx/appcompat/view/menu/d;->h(Z)V
HSPLandroidx/appcompat/view/menu/d;->q()V
HSPLandroidx/appcompat/view/menu/d;->r()Ljava/util/ArrayList;
HSPLandroidx/appcompat/view/menu/d;->v()Ljava/util/ArrayList;
HSPLandroidx/appcompat/view/menu/d;->A()Ljava/util/ArrayList;
HSPLandroidx/appcompat/view/menu/d;->hasVisibleItems()Z
HSPLandroidx/appcompat/view/menu/d;->H(Z)V
HSPLandroidx/appcompat/view/menu/d;->M(Landroidx/appcompat/view/menu/d$a;)V
HSPLandroidx/appcompat/view/menu/d;->setQwertyMode(Z)V
HSPLandroidx/appcompat/view/menu/d;->U(Z)V
HSPLandroidx/appcompat/view/menu/d;->size()I
HSPLandroidx/appcompat/view/menu/d;->V()V
HSPLandroidx/appcompat/view/menu/d;->W()V
Landroidx/appcompat/view/menu/h$a;
Landroidx/appcompat/view/menu/i;
Landroidx/appcompat/widget/a$a;
HSPLandroidx/appcompat/widget/a$a;-><init>(Landroidx/appcompat/widget/a;)V
Landroidx/appcompat/widget/a;
HSPLandroidx/appcompat/widget/a;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
Landroidx/appcompat/widget/b;
HSPLandroidx/appcompat/widget/b;-><init>(Landroidx/appcompat/widget/ActionBarContainer;)V
HSPLandroidx/appcompat/widget/b;->draw(Landroid/graphics/Canvas;)V
HSPLandroidx/appcompat/widget/b;->getOpacity()I
HSPLandroidx/appcompat/widget/b;->getOutline(Landroid/graphics/Outline;)V
Landroidx/appcompat/widget/ActionBarContainer;
HSPLandroidx/appcompat/widget/ActionBarContainer;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/ActionBarContainer;->drawableStateChanged()V
HSPLandroidx/appcompat/widget/ActionBarContainer;->jumpDrawablesToCurrentState()V
HSPLandroidx/appcompat/widget/ActionBarContainer;->onFinishInflate()V
HSPLandroidx/appcompat/widget/ActionBarContainer;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/ActionBarContainer;->onMeasure(II)V
HSPLandroidx/appcompat/widget/ActionBarContainer;->setTabContainer(Landroidx/appcompat/widget/G;)V
PLandroidx/appcompat/widget/ActionBarContainer;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
Landroidx/appcompat/widget/ActionBarContextView;
HSPLandroidx/appcompat/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
PLandroidx/appcompat/widget/ActionBarContextView;->onDetachedFromWindow()V
Landroidx/appcompat/widget/ActionBarOverlayLayout$a;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout$a;-><init>(Landroidx/appcompat/widget/ActionBarOverlayLayout;)V
Landroidx/appcompat/widget/ActionBarOverlayLayout$b;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout$b;-><init>(Landroidx/appcompat/widget/ActionBarOverlayLayout;)V
Landroidx/appcompat/widget/ActionBarOverlayLayout$c;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout$c;-><init>(Landroidx/appcompat/widget/ActionBarOverlayLayout;)V
Landroidx/appcompat/widget/ActionBarOverlayLayout$d;
Landroidx/appcompat/widget/ActionBarOverlayLayout$e;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout$e;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Landroidx/appcompat/widget/ActionBarOverlayLayout;
Landroidx/core/view/o;
Landroidx/core/view/p;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;-><clinit>()V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->h(Landroid/view/View;Landroid/graphics/Rect;ZZZZ)Z
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->k(Landroid/util/AttributeSet;)Landroidx/appcompat/widget/ActionBarOverlayLayout$e;
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->l(Landroid/view/View;)Landroidx/appcompat/widget/u;
PLandroidx/appcompat/widget/ActionBarOverlayLayout;->m()V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->n(Landroid/content/Context;)V
PLandroidx/appcompat/widget/ActionBarOverlayLayout;->onDetachedFromWindow()V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->onMeasure(II)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->f(Landroid/view/View;Landroid/view/View;II)Z
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->onWindowVisibilityChanged(I)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->q()V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->setActionBarVisibilityCallback(Landroidx/appcompat/widget/ActionBarOverlayLayout$d;)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->setHasNonEmbeddedTabs(Z)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->setWindowTitle(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/ActionBarOverlayLayout;->shouldDelayChildPressedState()Z
Landroidx/appcompat/widget/c$d$a;
Landroidx/appcompat/widget/y;
HSPLandroidx/appcompat/widget/c$d$a;-><init>(Landroidx/appcompat/widget/c$d;Landroid/view/View;Landroidx/appcompat/widget/c;)V
Landroidx/appcompat/widget/c$d;
Landroidx/appcompat/widget/l;
Landroidx/appcompat/widget/ActionMenuView$a;
HSPLandroidx/appcompat/widget/c$d;-><init>(Landroidx/appcompat/widget/c;Landroid/content/Context;)V
Landroidx/appcompat/widget/c$f;
HSPLandroidx/appcompat/widget/c$f;-><init>(Landroidx/appcompat/widget/c;)V
Landroidx/appcompat/widget/c;
HSPLandroidx/appcompat/widget/c;-><init>(Landroid/content/Context;)V
PLandroidx/appcompat/widget/c;->w()Z
HSPLandroidx/appcompat/widget/c;->h()Z
PLandroidx/appcompat/widget/c;->z()Z
PLandroidx/appcompat/widget/c;->A()Z
HSPLandroidx/appcompat/widget/c;->k(Landroid/content/Context;Landroidx/appcompat/view/menu/d;)V
PLandroidx/appcompat/widget/c;->a(Landroidx/appcompat/view/menu/d;Z)V
HSPLandroidx/appcompat/widget/c;->D(Z)V
HSPLandroidx/appcompat/widget/c;->E(Landroidx/appcompat/widget/ActionMenuView;)V
HSPLandroidx/appcompat/widget/c;->j(Z)V
Landroidx/appcompat/widget/ActionMenuView$e;
Landroidx/appcompat/widget/ActionMenuView;
Landroidx/appcompat/widget/z;
HSPLandroidx/appcompat/widget/ActionMenuView;-><init>(Landroid/content/Context;)V
HSPLandroidx/appcompat/widget/ActionMenuView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
PLandroidx/appcompat/widget/ActionMenuView;->w()V
HSPLandroidx/appcompat/widget/ActionMenuView;->C(Landroidx/appcompat/view/menu/d;)V
PLandroidx/appcompat/widget/ActionMenuView;->onDetachedFromWindow()V
HSPLandroidx/appcompat/widget/ActionMenuView;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/ActionMenuView;->onMeasure(II)V
HSPLandroidx/appcompat/widget/ActionMenuView;->G()Landroidx/appcompat/view/menu/d;
HSPLandroidx/appcompat/widget/ActionMenuView;->H(Landroidx/appcompat/view/menu/h$a;Landroidx/appcompat/view/menu/d$a;)V
HSPLandroidx/appcompat/widget/ActionMenuView;->setOnMenuItemClickListener(Landroidx/appcompat/widget/ActionMenuView$e;)V
HSPLandroidx/appcompat/widget/ActionMenuView;->setOverflowReserved(Z)V
HSPLandroidx/appcompat/widget/ActionMenuView;->setPopupTheme(I)V
HSPLandroidx/appcompat/widget/ActionMenuView;->setPresenter(Landroidx/appcompat/widget/c;)V
Landroidx/appcompat/widget/e;
HSPLandroidx/appcompat/widget/e;-><init>(Landroid/view/View;)V
HSPLandroidx/appcompat/widget/e;->b()V
HSPLandroidx/appcompat/widget/e;->e(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/e;->k()Z
Landroidx/appcompat/widget/f$a;
Landroidx/appcompat/widget/D$f;
HSPLandroidx/appcompat/widget/f$a;-><init>()V
HSPLandroidx/appcompat/widget/f$a;->f([II)Z
HSPLandroidx/appcompat/widget/f$a;->a(Landroidx/appcompat/widget/D;Landroid/content/Context;I)Landroid/graphics/drawable/Drawable;
HSPLandroidx/appcompat/widget/f$a;->b(Landroid/content/Context;I)Landroid/content/res/ColorStateList;
HSPLandroidx/appcompat/widget/f$a;->d(Landroid/content/Context;ILandroid/graphics/drawable/Drawable;)Z
HSPLandroidx/appcompat/widget/f$a;->c(Landroid/content/Context;ILandroid/graphics/drawable/Drawable;)Z
Landroidx/appcompat/widget/f;
HSPLandroidx/appcompat/widget/f;-><clinit>()V
HSPLandroidx/appcompat/widget/f;-><init>()V
HSPLandroidx/appcompat/widget/f;->a()Landroid/graphics/PorterDuff$Mode;
HSPLandroidx/appcompat/widget/f;->b()Landroidx/appcompat/widget/f;
HSPLandroidx/appcompat/widget/f;->e(Landroid/content/Context;I)Landroid/content/res/ColorStateList;
HSPLandroidx/appcompat/widget/f;->f()V
Landroidx/appcompat/widget/g;
HSPLandroidx/appcompat/widget/g;-><init>(Landroid/widget/EditText;)V
HSPLandroidx/appcompat/widget/g;->a(Landroid/text/method/KeyListener;)Landroid/text/method/KeyListener;
HSPLandroidx/appcompat/widget/g;->c(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/g;->e(Z)V
Landroidx/appcompat/widget/h;
HSPLandroidx/appcompat/widget/h;-><init>(Landroid/widget/TextView;)V
HSPLandroidx/appcompat/widget/h;->a([Landroid/text/InputFilter;)[Landroid/text/InputFilter;
HSPLandroidx/appcompat/widget/h;->b(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/h;->d(Z)V
Landroidx/appcompat/widget/j;
HSPLandroidx/appcompat/widget/j;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/j;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/j;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
Landroidx/appcompat/widget/k;
HSPLandroidx/appcompat/widget/k;-><init>(Landroid/widget/ImageView;)V
HSPLandroidx/appcompat/widget/k;->b()V
HSPLandroidx/appcompat/widget/k;->c()V
HSPLandroidx/appcompat/widget/k;->g(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/l;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/l;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/l;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
Landroidx/appcompat/widget/n;
HSPLandroidx/appcompat/widget/n;-><init>(Landroid/widget/TextView;)V
Landroidx/appcompat/widget/o$a;
Landroidx/core/content/res/h$e;
HSPLandroidx/appcompat/widget/o$a;-><init>(Landroidx/appcompat/widget/o;IILjava/lang/ref/WeakReference;)V
HSPLandroidx/appcompat/widget/o$a;->f(I)V
Landroidx/appcompat/widget/o;
HSPLandroidx/appcompat/widget/o;-><init>(Landroid/widget/TextView;)V
HSPLandroidx/appcompat/widget/o;->b()V
HSPLandroidx/appcompat/widget/o;->d(Landroid/content/Context;Landroidx/appcompat/widget/f;I)Landroidx/appcompat/widget/J;
HSPLandroidx/appcompat/widget/o;->m(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/o;->o(ZIIII)V
HSPLandroidx/appcompat/widget/o;->q(Landroid/content/Context;I)V
HSPLandroidx/appcompat/widget/o;->y(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/o;->C(Landroid/content/Context;Landroidx/appcompat/widget/L;)V
Landroidx/appcompat/widget/p;
Landroidx/core/widget/h;
HSPLandroidx/appcompat/widget/p;-><init>(Landroid/content/Context;)V
HSPLandroidx/appcompat/widget/p;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/p;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/p;->r()V
HSPLandroidx/appcompat/widget/p;->drawableStateChanged()V
HSPLandroidx/appcompat/widget/p;->getEmojiTextViewHelper()Landroidx/appcompat/widget/h;
HSPLandroidx/appcompat/widget/p;->getText()Ljava/lang/CharSequence;
HSPLandroidx/appcompat/widget/p;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/p;->onMeasure(II)V
HSPLandroidx/appcompat/widget/p;->onTextChanged(Ljava/lang/CharSequence;III)V
HSPLandroidx/appcompat/widget/p;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/p;->setCompoundDrawablesWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/p;->setFilters([Landroid/text/InputFilter;)V
HSPLandroidx/appcompat/widget/p;->setTextAppearance(Landroid/content/Context;I)V
HSPLandroidx/appcompat/widget/p;->setTypeface(Landroid/graphics/Typeface;I)V
Landroidx/appcompat/widget/q$b;
Landroidx/appcompat/widget/q$d;
HSPLandroidx/appcompat/widget/q$b;-><init>()V
Landroidx/appcompat/widget/q$c;
HSPLandroidx/appcompat/widget/q$c;-><init>()V
HSPLandroidx/appcompat/widget/q$d;-><init>()V
Landroidx/appcompat/widget/q;
HSPLandroidx/appcompat/widget/q;-><clinit>()V
HSPLandroidx/appcompat/widget/q;-><init>(Landroid/widget/TextView;)V
HSPLandroidx/appcompat/widget/q;->j()I
HSPLandroidx/appcompat/widget/q;->o(Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/q;->y()Z
Landroidx/appcompat/widget/ContentFrameLayout$a;
Landroidx/appcompat/widget/ContentFrameLayout;
HSPLandroidx/appcompat/widget/ContentFrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/ContentFrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/ContentFrameLayout;->getMinWidthMajor()Landroid/util/TypedValue;
HSPLandroidx/appcompat/widget/ContentFrameLayout;->getMinWidthMinor()Landroid/util/TypedValue;
HSPLandroidx/appcompat/widget/ContentFrameLayout;->onAttachedToWindow()V
PLandroidx/appcompat/widget/ContentFrameLayout;->onDetachedFromWindow()V
HSPLandroidx/appcompat/widget/ContentFrameLayout;->onMeasure(II)V
HSPLandroidx/appcompat/widget/ContentFrameLayout;->setAttachListener(Landroidx/appcompat/widget/ContentFrameLayout$a;)V
Landroidx/appcompat/widget/u;
Landroidx/appcompat/widget/v;
HSPLandroidx/appcompat/widget/y;-><init>(Landroid/view/View;)V
HSPLandroidx/appcompat/widget/z;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/z;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/z;->getVirtualChildCount()I
HSPLandroidx/appcompat/widget/z;->p(IIII)V
HSPLandroidx/appcompat/widget/z;->s(II)V
HSPLandroidx/appcompat/widget/z;->onInitializeAccessibilityNodeInfo(Landroid/view/accessibility/AccessibilityNodeInfo;)V
HSPLandroidx/appcompat/widget/z;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/z;->onMeasure(II)V
HSPLandroidx/appcompat/widget/z;->setBaselineAligned(Z)V
HSPLandroidx/appcompat/widget/z;->setDividerDrawable(Landroid/graphics/drawable/Drawable;)V
Landroidx/appcompat/widget/D$c;
Lp/h;
Landroidx/appcompat/widget/D;
Landroidx/appcompat/widget/E;
Landroidx/appcompat/widget/F;
HSPLandroidx/appcompat/widget/F;-><init>()V
HSPLandroidx/appcompat/widget/F;->a()I
HSPLandroidx/appcompat/widget/F;->d()I
HSPLandroidx/appcompat/widget/F;->e(II)V
HSPLandroidx/appcompat/widget/F;->f(Z)V
HSPLandroidx/appcompat/widget/F;->g(II)V
Landroidx/appcompat/widget/H;
HSPLandroidx/appcompat/widget/H;-><clinit>()V
HSPLandroidx/appcompat/widget/H;->a(Landroid/view/View;Landroid/content/Context;)V
Landroidx/appcompat/widget/I;
HSPLandroidx/appcompat/widget/I;-><clinit>()V
HSPLandroidx/appcompat/widget/I;->a(Landroid/content/Context;)Z
HSPLandroidx/appcompat/widget/I;->b(Landroid/content/Context;)Landroid/content/Context;
Landroidx/appcompat/widget/K;
Landroidx/appcompat/widget/L;
HSPLandroidx/appcompat/widget/L;-><init>(Landroid/content/Context;Landroid/content/res/TypedArray;)V
HSPLandroidx/appcompat/widget/L;->a(IZ)Z
HSPLandroidx/appcompat/widget/L;->b(II)I
HSPLandroidx/appcompat/widget/L;->c(I)Landroid/content/res/ColorStateList;
HSPLandroidx/appcompat/widget/L;->d(II)I
HSPLandroidx/appcompat/widget/L;->e(II)I
HSPLandroidx/appcompat/widget/L;->f(I)Landroid/graphics/drawable/Drawable;
HSPLandroidx/appcompat/widget/L;->g(IF)F
HSPLandroidx/appcompat/widget/L;->h(IILandroidx/core/content/res/h$e;)Landroid/graphics/Typeface;
HSPLandroidx/appcompat/widget/L;->i(II)I
HSPLandroidx/appcompat/widget/L;->j(II)I
HSPLandroidx/appcompat/widget/L;->k(II)I
HSPLandroidx/appcompat/widget/L;->l(II)I
HSPLandroidx/appcompat/widget/L;->m(I)Ljava/lang/String;
HSPLandroidx/appcompat/widget/L;->n(I)Ljava/lang/CharSequence;
HSPLandroidx/appcompat/widget/L;->o()Landroid/content/res/TypedArray;
HSPLandroidx/appcompat/widget/L;->p(I)Z
HSPLandroidx/appcompat/widget/L;->q(Landroid/content/Context;I[I)Landroidx/appcompat/widget/L;
HSPLandroidx/appcompat/widget/L;->r(Landroid/content/Context;Landroid/util/AttributeSet;[I)Landroidx/appcompat/widget/L;
HSPLandroidx/appcompat/widget/L;->s(Landroid/content/Context;Landroid/util/AttributeSet;[III)Landroidx/appcompat/widget/L;
HSPLandroidx/appcompat/widget/L;->u()V
Landroidx/appcompat/widget/Toolbar$a;
HSPLandroidx/appcompat/widget/Toolbar$a;-><init>(Landroidx/appcompat/widget/Toolbar;)V
Landroidx/appcompat/widget/Toolbar$b;
HSPLandroidx/appcompat/widget/Toolbar$b;-><init>(Landroidx/appcompat/widget/Toolbar;)V
Landroidx/appcompat/widget/Toolbar$f;
HSPLandroidx/appcompat/widget/Toolbar$f;-><init>(Landroidx/appcompat/widget/Toolbar;)V
HSPLandroidx/appcompat/widget/Toolbar$f;->h()Z
HSPLandroidx/appcompat/widget/Toolbar$f;->k(Landroid/content/Context;Landroidx/appcompat/view/menu/d;)V
PLandroidx/appcompat/widget/Toolbar$f;->a(Landroidx/appcompat/view/menu/d;Z)V
HSPLandroidx/appcompat/widget/Toolbar$f;->j(Z)V
Landroidx/appcompat/widget/Toolbar$g;
HSPLandroidx/appcompat/widget/Toolbar$g;-><init>(II)V
Landroidx/appcompat/widget/Toolbar;
HSPLandroidx/appcompat/widget/Toolbar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
HSPLandroidx/appcompat/widget/Toolbar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
HSPLandroidx/appcompat/widget/Toolbar;->b(Ljava/util/List;I)V
HSPLandroidx/appcompat/widget/Toolbar;->c(Landroid/view/View;Z)V
HSPLandroidx/appcompat/widget/Toolbar;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
HSPLandroidx/appcompat/widget/Toolbar;->f()V
HSPLandroidx/appcompat/widget/Toolbar;->i()V
HSPLandroidx/appcompat/widget/Toolbar;->j()V
HSPLandroidx/appcompat/widget/Toolbar;->k()Landroidx/appcompat/widget/Toolbar$g;
HSPLandroidx/appcompat/widget/Toolbar;->o(Landroid/view/View;I)I
HSPLandroidx/appcompat/widget/Toolbar;->p(I)I
HSPLandroidx/appcompat/widget/Toolbar;->getContentInsetEnd()I
HSPLandroidx/appcompat/widget/Toolbar;->getContentInsetStart()I
HSPLandroidx/appcompat/widget/Toolbar;->getCurrentContentInsetEnd()I
HSPLandroidx/appcompat/widget/Toolbar;->getCurrentContentInsetLeft()I
HSPLandroidx/appcompat/widget/Toolbar;->getCurrentContentInsetRight()I
HSPLandroidx/appcompat/widget/Toolbar;->getCurrentContentInsetStart()I
HSPLandroidx/appcompat/widget/Toolbar;->q(Landroid/view/View;)I
HSPLandroidx/appcompat/widget/Toolbar;->getNavigationContentDescription()Ljava/lang/CharSequence;
HSPLandroidx/appcompat/widget/Toolbar;->getNavigationIcon()Landroid/graphics/drawable/Drawable;
HSPLandroidx/appcompat/widget/Toolbar;->getSubtitle()Ljava/lang/CharSequence;
HSPLandroidx/appcompat/widget/Toolbar;->getTitle()Ljava/lang/CharSequence;
HSPLandroidx/appcompat/widget/Toolbar;->r(Landroid/view/View;)I
HSPLandroidx/appcompat/widget/Toolbar;->s(Ljava/util/List;[I)I
HSPLandroidx/appcompat/widget/Toolbar;->getWrapper()Landroidx/appcompat/widget/u;
PLandroidx/appcompat/widget/Toolbar;->t()Z
HSPLandroidx/appcompat/widget/Toolbar;->w(Landroid/view/View;)Z
HSPLandroidx/appcompat/widget/Toolbar;->z(Landroid/view/View;I[II)I
HSPLandroidx/appcompat/widget/Toolbar;->A(Landroid/view/View;IIII[I)I
HSPLandroidx/appcompat/widget/Toolbar;->B(Landroid/view/View;IIIII)V
PLandroidx/appcompat/widget/Toolbar;->onDetachedFromWindow()V
HSPLandroidx/appcompat/widget/Toolbar;->onLayout(ZIIII)V
HSPLandroidx/appcompat/widget/Toolbar;->onMeasure(II)V
HSPLandroidx/appcompat/widget/Toolbar;->onRtlPropertiesChanged(I)V
HSPLandroidx/appcompat/widget/Toolbar;->setCollapsible(Z)V
HSPLandroidx/appcompat/widget/Toolbar;->F(II)V
HSPLandroidx/appcompat/widget/Toolbar;->setNavigationContentDescription(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/Toolbar;->setNavigationIcon(Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/Toolbar;->setNavigationOnClickListener(Landroid/view/View$OnClickListener;)V
HSPLandroidx/appcompat/widget/Toolbar;->setPopupTheme(I)V
HSPLandroidx/appcompat/widget/Toolbar;->setSubtitle(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/Toolbar;->G(Landroid/content/Context;I)V
HSPLandroidx/appcompat/widget/Toolbar;->setTitle(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/Toolbar;->H(Landroid/content/Context;I)V
HSPLandroidx/appcompat/widget/Toolbar;->I()Z
HSPLandroidx/appcompat/widget/Toolbar;->J(Landroid/view/View;)Z
Landroidx/appcompat/widget/P$a;
HSPLandroidx/appcompat/widget/P$a;-><init>(Landroidx/appcompat/widget/P;)V
Landroidx/appcompat/widget/P;
HSPLandroidx/appcompat/widget/P;-><init>(Landroidx/appcompat/widget/Toolbar;Z)V
HSPLandroidx/appcompat/widget/P;-><init>(Landroidx/appcompat/widget/Toolbar;ZII)V
HSPLandroidx/appcompat/widget/P;->e()Landroid/content/Context;
HSPLandroidx/appcompat/widget/P;->g(I)V
HSPLandroidx/appcompat/widget/P;->h(I)V
HSPLandroidx/appcompat/widget/P;->l(Landroid/graphics/drawable/Drawable;)V
HSPLandroidx/appcompat/widget/P;->o(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/P;->c(Landroid/view/Window$Callback;)V
HSPLandroidx/appcompat/widget/P;->b(Ljava/lang/CharSequence;)V
HSPLandroidx/appcompat/widget/P;->q()V
Landroidx/appcompat/widget/Q;
HSPLandroidx/appcompat/widget/Q;->a(Landroid/view/View;Ljava/lang/CharSequence;)V
Landroidx/appcompat/widget/W;
HSPLandroidx/appcompat/widget/W;-><clinit>()V
HSPLandroidx/appcompat/widget/W;->b()Z
HSPLandroidx/appcompat/widget/W;->c()Z
Landroidx/appcompat/widget/X;
HSPLandroidx/appcompat/widget/X;-><clinit>()V
HSPLandroidx/appcompat/widget/X;->a(Landroid/view/View;)Z
LE/b;
LE/c;
HSPLE/c;-><clinit>()V
Landroidx/fragment/app/a;
Landroidx/fragment/app/y;
Landroidx/fragment/app/q$h;
HSPLandroidx/fragment/app/a;-><init>(Landroidx/fragment/app/q;)V
HSPLandroidx/fragment/app/a;->i(I)V
HSPLandroidx/fragment/app/a;->g(ILandroidx/fragment/app/Fragment;Ljava/lang/String;I)V
HSPLandroidx/fragment/app/a;->k()V
HSPLandroidx/fragment/app/a;->m(Ljava/util/ArrayList;Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/a;->a(Ljava/util/ArrayList;Ljava/util/ArrayList;)Z
HSPLandroidx/fragment/app/a;->n()V
Landroidx/fragment/app/d;
Landroidx/fragment/app/E;
HSPLandroidx/fragment/app/d;-><init>(Landroid/view/ViewGroup;)V
Landroidx/fragment/app/Fragment$a;
HSPLandroidx/fragment/app/Fragment$a;-><init>(Landroidx/fragment/app/Fragment;)V
Landroidx/fragment/app/Fragment$c;
Landroidx/fragment/app/g;
HSPLandroidx/fragment/app/Fragment$c;-><init>(Landroidx/fragment/app/Fragment;)V
Landroidx/fragment/app/Fragment$d;
HSPLandroidx/fragment/app/Fragment$d;-><init>()V
Landroidx/fragment/app/Fragment$e;
PLandroidx/fragment/app/Fragment$e;->a(Landroid/view/View;)V
Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/Fragment;-><clinit>()V
HSPLandroidx/fragment/app/Fragment;-><init>()V
HSPLandroidx/fragment/app/Fragment;->h()Landroidx/fragment/app/g;
HSPLandroidx/fragment/app/Fragment;->i()Landroidx/fragment/app/Fragment$d;
HSPLandroidx/fragment/app/Fragment;->equals(Ljava/lang/Object;)Z
HSPLandroidx/fragment/app/Fragment;->j()Landroidx/fragment/app/e;
HSPLandroidx/fragment/app/Fragment;->n()Landroidx/fragment/app/q;
HSPLandroidx/fragment/app/Fragment;->o()Landroid/content/Context;
HSPLandroidx/fragment/app/Fragment;->v()Landroid/view/View;
HSPLandroidx/fragment/app/Fragment;->w(Landroid/os/Bundle;)Landroid/view/LayoutInflater;
HSPLandroidx/fragment/app/Fragment;->g()Landroidx/lifecycle/g;
HSPLandroidx/fragment/app/Fragment;->x()I
HSPLandroidx/fragment/app/Fragment;->z()Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/Fragment;->A()Landroidx/fragment/app/q;
HSPLandroidx/fragment/app/Fragment;->E()F
HSPLandroidx/fragment/app/Fragment;->b()Landroidx/savedstate/a;
HSPLandroidx/fragment/app/Fragment;->M()Landroid/view/View;
HSPLandroidx/fragment/app/Fragment;->c()Landroidx/lifecycle/D;
HSPLandroidx/fragment/app/Fragment;->N()V
PLandroidx/fragment/app/Fragment;->O()V
HSPLandroidx/fragment/app/Fragment;->P()Z
HSPLandroidx/fragment/app/Fragment;->S()Z
HSPLandroidx/fragment/app/Fragment;->U(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->V(Landroid/os/Bundle;)V
PLandroidx/fragment/app/Fragment;->b0()V
PLandroidx/fragment/app/Fragment;->c0()V
HSPLandroidx/fragment/app/Fragment;->d0(Landroid/os/Bundle;)Landroid/view/LayoutInflater;
HSPLandroidx/fragment/app/Fragment;->f0(Landroid/content/Context;Landroid/util/AttributeSet;Landroid/os/Bundle;)V
PLandroidx/fragment/app/Fragment;->h0()V
HSPLandroidx/fragment/app/Fragment;->j0(Z)V
HSPLandroidx/fragment/app/Fragment;->k0()V
HSPLandroidx/fragment/app/Fragment;->m0()V
PLandroidx/fragment/app/Fragment;->n0()V
HSPLandroidx/fragment/app/Fragment;->o0(Landroid/view/View;Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->p0(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->q0(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->r0()V
HSPLandroidx/fragment/app/Fragment;->t0(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->u0(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
HSPLandroidx/fragment/app/Fragment;->v0(Landroid/view/LayoutInflater;Landroid/view/ViewGroup;Landroid/os/Bundle;)V
PLandroidx/fragment/app/Fragment;->w0()V
PLandroidx/fragment/app/Fragment;->x0()V
HSPLandroidx/fragment/app/Fragment;->y0(Landroid/os/Bundle;)Landroid/view/LayoutInflater;
PLandroidx/fragment/app/Fragment;->B0()V
HSPLandroidx/fragment/app/Fragment;->C0(Landroid/view/Menu;)Z
HSPLandroidx/fragment/app/Fragment;->D0()V
HSPLandroidx/fragment/app/Fragment;->E0()V
HSPLandroidx/fragment/app/Fragment;->G0()V
PLandroidx/fragment/app/Fragment;->H0()V
HSPLandroidx/fragment/app/Fragment;->I0()V
HSPLandroidx/fragment/app/Fragment;->L0()Landroid/content/Context;
HSPLandroidx/fragment/app/Fragment;->M0()Landroid/view/View;
HSPLandroidx/fragment/app/Fragment;->N0(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->O0()V
HSPLandroidx/fragment/app/Fragment;->P0(Landroid/os/Bundle;)V
HSPLandroidx/fragment/app/Fragment;->Q0(IIII)V
HSPLandroidx/fragment/app/Fragment;->R0(Landroid/view/View;)V
HSPLandroidx/fragment/app/Fragment;->S0(I)V
HSPLandroidx/fragment/app/Fragment;->T0(Z)V
HSPLandroidx/fragment/app/Fragment;->U0(F)V
HSPLandroidx/fragment/app/Fragment;->V0(Ljava/util/ArrayList;Ljava/util/ArrayList;)V
HSPLandroidx/fragment/app/Fragment;->toString()Ljava/lang/String;
Landroidx/fragment/app/e;
HSPLandroidx/fragment/app/g;-><init>()V
Landroidx/fragment/app/h;
PLandroidx/fragment/app/h;->a(Landroid/view/View;)V
HSPLandroidx/fragment/app/h;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
HSPLandroidx/fragment/app/h;->dispatchDraw(Landroid/graphics/Canvas;)V
HSPLandroidx/fragment/app/h;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z
PLandroidx/fragment/app/h;->removeView(Landroid/view/View;)V
Landroidx/fragment/app/i;
HSPLandroidx/fragment/app/i;-><clinit>()V
HSPLandroidx/fragment/app/i;-><init>()V
HSPLandroidx/fragment/app/i;->b(Ljava/lang/ClassLoader;Ljava/lang/String;)Z
HSPLandroidx/fragment/app/i;->c(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
Landroidx/fragment/app/j;
Landroidx/fragment/app/k;
HSPLandroidx/fragment/app/k;-><init>(Landroidx/fragment/app/q;)V
HSPLandroidx/fragment/app/k;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
Landroidx/fragment/app/l;
HSPLandroidx/fragment/app/l;-><init>(Landroidx/fragment/app/q;)V
HSPLandroidx/fragment/app/l;->a(Landroidx/fragment/app/Fragment;Landroid/os/Bundle;Z)V
HSPLandroidx/fragment/app/l;->b(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/l;->c(Landroidx/fragment/app/Fragment;Landroid/os/Bundle;Z)V
PLandroidx/fragment/app/l;->d(Landroidx/fragment/app/Fragment;Z)V
PLandroidx/fragment/app/l;->e(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/l;->f(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/l;->g(Landroidx/fragment/app/Fragment;Landroid/os/Bundle;Z)V
HSPLandroidx/fragment/app/l;->h(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/l;->j(Landroidx/fragment/app/Fragment;Z)V
PLandroidx/fragment/app/l;->k(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/l;->l(Landroidx/fragment/app/Fragment;Landroid/view/View;Landroid/os/Bundle;Z)V
PLandroidx/fragment/app/l;->m(Landroidx/fragment/app/Fragment;Z)V
Landroidx/fragment/app/q$a;
HSPLandroidx/fragment/app/q$a;-><init>(Landroidx/fragment/app/q;Z)V
Landroidx/fragment/app/q$b;
Landroidx/core/view/l;
HSPLandroidx/fragment/app/q$b;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/q$c;
HSPLandroidx/fragment/app/q$c;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/q$d;
Landroidx/fragment/app/F;
HSPLandroidx/fragment/app/q$d;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/FragmentManager$6;
Landroidx/fragment/app/q$f;
Landroidx/fragment/app/u;
Landroidx/fragment/app/q;
HSPLandroidx/fragment/app/q;-><clinit>()V
HSPLandroidx/fragment/app/q;-><init>()V
HSPLandroidx/fragment/app/q;->h(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/w;
HSPLandroidx/fragment/app/q;->i(Landroidx/fragment/app/u;)V
HSPLandroidx/fragment/app/q;->j(Landroidx/fragment/app/j;Landroidx/fragment/app/g;Landroidx/fragment/app/Fragment;)V
HSPLandroidx/fragment/app/q;->l()Landroidx/fragment/app/y;
HSPLandroidx/fragment/app/q;->m()Z
HSPLandroidx/fragment/app/q;->n()V
PLandroidx/fragment/app/q;->o()V
HSPLandroidx/fragment/app/q;->p()Ljava/util/Set;
HSPLandroidx/fragment/app/q;->q(Ljava/util/ArrayList;II)Ljava/util/Set;
HSPLandroidx/fragment/app/q;->r(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/w;
HSPLandroidx/fragment/app/q;->t()V
HSPLandroidx/fragment/app/q;->v()V
HSPLandroidx/fragment/app/q;->w(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
PLandroidx/fragment/app/q;->x()V
PLandroidx/fragment/app/q;->y()V
HSPLandroidx/fragment/app/q;->C(Landroidx/fragment/app/Fragment;)V
PLandroidx/fragment/app/q;->D()V
HSPLandroidx/fragment/app/q;->E(Landroid/view/Menu;)Z
HSPLandroidx/fragment/app/q;->F()V
HSPLandroidx/fragment/app/q;->G()V
HSPLandroidx/fragment/app/q;->H()V
HSPLandroidx/fragment/app/q;->I(I)V
PLandroidx/fragment/app/q;->J()V
HSPLandroidx/fragment/app/q;->K()V
HSPLandroidx/fragment/app/q;->L()V
PLandroidx/fragment/app/q;->M()V
HSPLandroidx/fragment/app/q;->N(Z)V
HSPLandroidx/fragment/app/q;->O(Z)Z
HSPLandroidx/fragment/app/q;->Q(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroidx/fragment/app/q;->R(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
HSPLandroidx/fragment/app/q;->S(Ljava/lang/String;)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/q;->T(I)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/q;->Y(Ljava/util/ArrayList;Ljava/util/ArrayList;)Z
HSPLandroidx/fragment/app/q;->Z()I
HSPLandroidx/fragment/app/q;->a0(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/t;
HSPLandroidx/fragment/app/q;->b0()Landroidx/fragment/app/g;
HSPLandroidx/fragment/app/q;->c0(Landroidx/fragment/app/Fragment;)Landroid/view/ViewGroup;
HSPLandroidx/fragment/app/q;->d0()Landroidx/fragment/app/i;
HSPLandroidx/fragment/app/q;->e0()Landroidx/fragment/app/j;
HSPLandroidx/fragment/app/q;->f0()Landroidx/fragment/app/l;
HSPLandroidx/fragment/app/q;->g0()Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/q;->h0()Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/q;->i0()Landroidx/fragment/app/F;
HSPLandroidx/fragment/app/q;->j0()LF/c$c;
HSPLandroidx/fragment/app/q;->k0(Landroid/view/View;)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/q;->l0(Landroidx/fragment/app/Fragment;)Landroidx/lifecycle/D;
PLandroidx/fragment/app/q;->o0()Z
HSPLandroidx/fragment/app/q;->p0(I)Z
HSPLandroidx/fragment/app/q;->q0(Landroidx/fragment/app/Fragment;)Z
HSPLandroidx/fragment/app/q;->t0(Landroidx/fragment/app/Fragment;)Z
HSPLandroidx/fragment/app/q;->u0(Landroidx/fragment/app/Fragment;)Z
HSPLandroidx/fragment/app/q;->v0(I)Z
HSPLandroidx/fragment/app/q;->w0()Z
HSPLandroidx/fragment/app/q;->x0(IZ)V
HSPLandroidx/fragment/app/q;->y0()V
HSPLandroidx/fragment/app/q;->A0(Landroidx/fragment/app/w;)V
HSPLandroidx/fragment/app/q;->C0(Ljava/util/ArrayList;Ljava/util/ArrayList;)V
HSPLandroidx/fragment/app/q;->H0(Landroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/q;->J0(Landroidx/fragment/app/Fragment;)V
HSPLandroidx/fragment/app/q;->M0()V
HSPLandroidx/fragment/app/q;->N0()V
Landroidx/fragment/app/r;
HSPLandroidx/fragment/app/r;-><init>()V
Landroidx/fragment/app/t$a;
Landroidx/lifecycle/A$b;
HSPLandroidx/fragment/app/t$a;-><init>()V
HSPLandroidx/fragment/app/t$a;->b(Ljava/lang/Class;)Landroidx/lifecycle/z;
Landroidx/fragment/app/t;
Landroidx/lifecycle/z;
HSPLandroidx/fragment/app/t;-><clinit>()V
HSPLandroidx/fragment/app/t;-><init>(Z)V
PLandroidx/fragment/app/t;->f(Landroidx/fragment/app/Fragment;)V
PLandroidx/fragment/app/t;->g(Ljava/lang/String;)V
HSPLandroidx/fragment/app/t;->i(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/t;
HSPLandroidx/fragment/app/t;->k(Landroidx/fragment/app/Fragment;)Landroidx/lifecycle/D;
PLandroidx/fragment/app/t;->d()V
HSPLandroidx/fragment/app/t;->m(Z)V
PLandroidx/fragment/app/t;->n(Landroidx/fragment/app/Fragment;)Z
Landroidx/fragment/app/w$a;
HSPLandroidx/fragment/app/w$a;-><init>(Landroidx/fragment/app/w;Landroid/view/View;)V
HSPLandroidx/fragment/app/w$a;->onViewAttachedToWindow(Landroid/view/View;)V
Landroidx/fragment/app/w$b;
HSPLandroidx/fragment/app/w$b;-><clinit>()V
Landroidx/fragment/app/w;
HSPLandroidx/fragment/app/w;-><init>(Landroidx/fragment/app/l;Landroidx/fragment/app/x;Landroidx/fragment/app/Fragment;)V
HSPLandroidx/fragment/app/w;->a()V
HSPLandroidx/fragment/app/w;->b()V
HSPLandroidx/fragment/app/w;->c()V
HSPLandroidx/fragment/app/w;->d()I
HSPLandroidx/fragment/app/w;->e()V
HSPLandroidx/fragment/app/w;->f()V
PLandroidx/fragment/app/w;->g()V
PLandroidx/fragment/app/w;->h()V
PLandroidx/fragment/app/w;->i()V
HSPLandroidx/fragment/app/w;->j()V
HSPLandroidx/fragment/app/w;->k()Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/w;->m()V
PLandroidx/fragment/app/w;->n()V
HSPLandroidx/fragment/app/w;->o()V
PLandroidx/fragment/app/w;->r()V
HSPLandroidx/fragment/app/w;->s(I)V
HSPLandroidx/fragment/app/w;->t()V
PLandroidx/fragment/app/w;->u()V
Landroidx/fragment/app/x;
HSPLandroidx/fragment/app/x;-><init>()V
HSPLandroidx/fragment/app/x;->a(Landroidx/fragment/app/Fragment;)V
HSPLandroidx/fragment/app/x;->b()V
HSPLandroidx/fragment/app/x;->c(Ljava/lang/String;)Z
HSPLandroidx/fragment/app/x;->d(I)V
HSPLandroidx/fragment/app/x;->e(Ljava/lang/String;)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/x;->f(I)Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/x;->h(Landroidx/fragment/app/Fragment;)I
HSPLandroidx/fragment/app/x;->i()Ljava/util/List;
HSPLandroidx/fragment/app/x;->j()Ljava/util/List;
HSPLandroidx/fragment/app/x;->l(Ljava/lang/String;)Landroidx/fragment/app/w;
HSPLandroidx/fragment/app/x;->m()Ljava/util/List;
PLandroidx/fragment/app/x;->n()Landroidx/fragment/app/t;
HSPLandroidx/fragment/app/x;->p(Landroidx/fragment/app/w;)V
PLandroidx/fragment/app/x;->q(Landroidx/fragment/app/w;)V
HSPLandroidx/fragment/app/x;->r()V
HSPLandroidx/fragment/app/x;->y(Landroidx/fragment/app/t;)V
Landroidx/fragment/app/y$a;
HSPLandroidx/fragment/app/y$a;-><init>(ILandroidx/fragment/app/Fragment;)V
HSPLandroidx/fragment/app/y$a;-><init>(ILandroidx/fragment/app/Fragment;Z)V
HSPLandroidx/fragment/app/y;-><init>(Landroidx/fragment/app/i;Ljava/lang/ClassLoader;)V
HSPLandroidx/fragment/app/y;->d(Landroidx/fragment/app/y$a;)V
HSPLandroidx/fragment/app/y;->g(ILandroidx/fragment/app/Fragment;Ljava/lang/String;I)V
HSPLandroidx/fragment/app/y;->h(Z)Landroidx/fragment/app/y;
Landroidx/fragment/app/C;
HSPLandroidx/fragment/app/C;-><init>(Landroidx/fragment/app/Fragment;Landroidx/lifecycle/D;)V
HSPLandroidx/fragment/app/C;->g()Landroidx/lifecycle/g;
HSPLandroidx/fragment/app/C;->b()Landroidx/savedstate/a;
HSPLandroidx/fragment/app/C;->d(Landroidx/lifecycle/g$a;)V
HSPLandroidx/fragment/app/C;->e()V
HSPLandroidx/fragment/app/C;->h(Landroid/os/Bundle;)V
PLandroidx/fragment/app/C;->i(Landroid/os/Bundle;)V
Landroidx/fragment/app/E$a;
HSPLandroidx/fragment/app/E$a;-><init>(Landroidx/fragment/app/E;Landroidx/fragment/app/E$d;)V
HSPLandroidx/fragment/app/E$a;->run()V
Landroidx/fragment/app/E$b;
HSPLandroidx/fragment/app/E$b;-><init>(Landroidx/fragment/app/E;Landroidx/fragment/app/E$d;)V
HSPLandroidx/fragment/app/E$b;->run()V
Landroidx/fragment/app/E$c;
HSPLandroidx/fragment/app/E$c;-><clinit>()V
Landroidx/fragment/app/E$d;
Landroidx/fragment/app/E$e;
HSPLandroidx/fragment/app/E$d;-><init>(Landroidx/fragment/app/E$e$c;Landroidx/fragment/app/E$e$b;Landroidx/fragment/app/w;Landroidx/core/os/b;)V
HSPLandroidx/fragment/app/E$d;->c()V
HSPLandroidx/fragment/app/E$d;->l()V
Landroidx/fragment/app/E$e$a;
Landroidx/core/os/b$a;
HSPLandroidx/fragment/app/E$e$a;-><init>(Landroidx/fragment/app/E$e;)V
Landroidx/fragment/app/E$e$b;
HSPLandroidx/fragment/app/E$e$b;-><clinit>()V
HSPLandroidx/fragment/app/E$e$b;-><init>(Ljava/lang/String;I)V
HSPLandroidx/fragment/app/E$e$b;->values()[Landroidx/fragment/app/E$e$b;
Landroidx/fragment/app/E$e$c;
HSPLandroidx/fragment/app/E$e$c;-><clinit>()V
HSPLandroidx/fragment/app/E$e$c;-><init>(Ljava/lang/String;I)V
HSPLandroidx/fragment/app/E$e$c;->a(Landroid/view/View;)V
HSPLandroidx/fragment/app/E$e$c;->b(I)Landroidx/fragment/app/E$e$c;
HSPLandroidx/fragment/app/E$e$c;->values()[Landroidx/fragment/app/E$e$c;
HSPLandroidx/fragment/app/E$e;-><init>(Landroidx/fragment/app/E$e$c;Landroidx/fragment/app/E$e$b;Landroidx/fragment/app/Fragment;Landroidx/core/os/b;)V
HSPLandroidx/fragment/app/E$e;->a(Ljava/lang/Runnable;)V
HSPLandroidx/fragment/app/E$e;->b()V
HSPLandroidx/fragment/app/E$e;->c()V
HSPLandroidx/fragment/app/E$e;->e()Landroidx/fragment/app/E$e$c;
HSPLandroidx/fragment/app/E$e;->f()Landroidx/fragment/app/Fragment;
HSPLandroidx/fragment/app/E$e;->g()Landroidx/fragment/app/E$e$b;
HSPLandroidx/fragment/app/E$e;->h()Z
HSPLandroidx/fragment/app/E$e;->k(Landroidx/fragment/app/E$e$c;Landroidx/fragment/app/E$e$b;)V
HSPLandroidx/fragment/app/E;-><init>(Landroid/view/ViewGroup;)V
HSPLandroidx/fragment/app/E;->a(Landroidx/fragment/app/E$e$c;Landroidx/fragment/app/E$e$b;Landroidx/fragment/app/w;)V
HSPLandroidx/fragment/app/E;->b(Landroidx/fragment/app/E$e$c;Landroidx/fragment/app/w;)V
PLandroidx/fragment/app/E;->d(Landroidx/fragment/app/w;)V
HSPLandroidx/fragment/app/E;->g()V
HSPLandroidx/fragment/app/E;->h(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/E$e;
HSPLandroidx/fragment/app/E;->i(Landroidx/fragment/app/Fragment;)Landroidx/fragment/app/E$e;
HSPLandroidx/fragment/app/E;->j()V
HSPLandroidx/fragment/app/E;->l(Landroidx/fragment/app/w;)Landroidx/fragment/app/E$e$b;
HSPLandroidx/fragment/app/E;->n(Landroid/view/ViewGroup;Landroidx/fragment/app/q;)Landroidx/fragment/app/E;
HSPLandroidx/fragment/app/E;->o(Landroid/view/ViewGroup;Landroidx/fragment/app/F;)Landroidx/fragment/app/E;
HSPLandroidx/fragment/app/E;->p()V
HSPLandroidx/fragment/app/E;->q()V
HSPLandroidx/fragment/app/E;->r(Z)V
LF/c$a;
HSPLF/c$a;->a()[LF/c$a;
HSPLF/c$a;-><clinit>()V
HSPLF/c$a;-><init>(Ljava/lang/String;I)V
LF/c$c$a;
HSPLF/c$c$a;-><init>()V
HSPLF/c$c$a;-><init>(Lt0/d;)V
LF/c$c;
HSPLF/c$c;-><clinit>()V
HSPLF/c$c;-><init>(Ljava/util/Set;LF/c$b;Ljava/util/Map;)V
HSPLF/c$c;->a()Ljava/util/Set;
LF/c;
HSPLF/c;-><clinit>()V
HSPLF/c;-><init>()V
HSPLF/c;->b(Landroidx/fragment/app/Fragment;)LF/c$c;
HSPLF/c;->e(LF/d;)V
LF/d;
HSPLF/d;-><init>(Landroidx/fragment/app/Fragment;Ljava/lang/String;)V
Landroidx/lifecycle/d;
HSPLandroidx/lifecycle/d;-><init>()V
HSPLandroidx/lifecycle/d;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
PLandroidx/lifecycle/d;->onActivityDestroyed(Landroid/app/Activity;)V
PLandroidx/lifecycle/d;->onActivityPaused(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/d;->onActivityResumed(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/d;->onActivityStarted(Landroid/app/Activity;)V
PLandroidx/lifecycle/d;->onActivityStopped(Landroid/app/Activity;)V
Landroidx/lifecycle/i$a;
HSPLandroidx/lifecycle/i$a;-><init>()V
HSPLandroidx/lifecycle/i$a;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
Landroidx/lifecycle/i;
HSPLandroidx/lifecycle/i;-><clinit>()V
HSPLandroidx/lifecycle/i;->a(Landroid/content/Context;)V
Landroidx/lifecycle/m$b;
HSPLandroidx/lifecycle/m$b;-><init>(Landroidx/lifecycle/k;Landroidx/lifecycle/g$b;)V
HSPLandroidx/lifecycle/m$b;->a(Landroidx/lifecycle/l;Landroidx/lifecycle/g$a;)V
Landroidx/lifecycle/m;
Landroidx/lifecycle/g;
HSPLandroidx/lifecycle/m;-><init>(Landroidx/lifecycle/l;)V
HSPLandroidx/lifecycle/m;-><init>(Landroidx/lifecycle/l;Z)V
HSPLandroidx/lifecycle/m;->a(Landroidx/lifecycle/k;)V
HPLandroidx/lifecycle/m;->d(Landroidx/lifecycle/l;)V
HSPLandroidx/lifecycle/m;->e(Landroidx/lifecycle/k;)Landroidx/lifecycle/g$b;
HSPLandroidx/lifecycle/m;->f(Ljava/lang/String;)V
HSPLandroidx/lifecycle/m;->g(Landroidx/lifecycle/l;)V
HSPLandroidx/lifecycle/m;->b()Landroidx/lifecycle/g$b;
HSPLandroidx/lifecycle/m;->h(Landroidx/lifecycle/g$a;)V
HSPLandroidx/lifecycle/m;->i()Z
HSPLandroidx/lifecycle/m;->j(Landroidx/lifecycle/g$b;)V
HSPLandroidx/lifecycle/m;->k()V
HSPLandroidx/lifecycle/m;->l(Landroidx/lifecycle/g$b;)V
HSPLandroidx/lifecycle/m;->c(Landroidx/lifecycle/k;)V
HSPLandroidx/lifecycle/m;->m()V
Landroidx/lifecycle/LiveData$a;
HSPLandroidx/lifecycle/LiveData$a;-><init>(Landroidx/lifecycle/LiveData;)V
HSPLandroidx/lifecycle/LiveData$a;->run()V
Landroidx/lifecycle/LiveData$LifecycleBoundObserver;
Landroidx/lifecycle/LiveData$b;
PLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->i()V
HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->h(Landroidx/lifecycle/l;Landroidx/lifecycle/g$a;)V
HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->j()Z
HSPLandroidx/lifecycle/LiveData$b;->d(Z)V
HSPLandroidx/lifecycle/LiveData$b;->i()V
Landroidx/lifecycle/LiveData;
HSPLandroidx/lifecycle/LiveData;-><clinit>()V
HSPLandroidx/lifecycle/LiveData;-><init>()V
HSPLandroidx/lifecycle/LiveData;->a(Ljava/lang/String;)V
HSPLandroidx/lifecycle/LiveData;->b(I)V
HSPLandroidx/lifecycle/LiveData;->c(Landroidx/lifecycle/LiveData$b;)V
HSPLandroidx/lifecycle/LiveData;->d(Landroidx/lifecycle/LiveData$b;)V
HSPLandroidx/lifecycle/LiveData;->e()V
HSPLandroidx/lifecycle/LiveData;->f()V
HSPLandroidx/lifecycle/LiveData;->g(Landroidx/lifecycle/q;)V
HSPLandroidx/lifecycle/LiveData;->h(Ljava/lang/Object;)V
Landroidx/lifecycle/p;
HSPLandroidx/lifecycle/p;-><init>()V
HSPLandroidx/lifecycle/p;->h(Ljava/lang/Object;)V
Landroidx/lifecycle/ProcessLifecycleInitializer;
LJ/a;
HSPLandroidx/lifecycle/ProcessLifecycleInitializer;-><init>()V
HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->c(Landroid/content/Context;)Landroidx/lifecycle/l;
HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->b(Landroid/content/Context;)Ljava/lang/Object;
HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->a()Ljava/util/List;
Landroidx/lifecycle/t;
HSPLandroidx/lifecycle/t;-><clinit>()V
HSPLandroidx/lifecycle/t;-><init>()V
HSPLandroidx/lifecycle/t;->g()Landroidx/lifecycle/g;
Landroidx/lifecycle/u$c;
HSPLandroidx/lifecycle/u$c;-><init>()V
HSPLandroidx/lifecycle/u$c;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
PLandroidx/lifecycle/u$c;->onActivityDestroyed(Landroid/app/Activity;)V
PLandroidx/lifecycle/u$c;->onActivityPaused(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/u$c;->onActivityPostCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
HSPLandroidx/lifecycle/u$c;->onActivityPostResumed(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/u$c;->onActivityPostStarted(Landroid/app/Activity;)V
PLandroidx/lifecycle/u$c;->onActivityPreDestroyed(Landroid/app/Activity;)V
PLandroidx/lifecycle/u$c;->onActivityPrePaused(Landroid/app/Activity;)V
PLandroidx/lifecycle/u$c;->onActivityPreStopped(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/u$c;->onActivityResumed(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/u$c;->onActivityStarted(Landroid/app/Activity;)V
PLandroidx/lifecycle/u$c;->onActivityStopped(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/u$c;->registerIn(Landroid/app/Activity;)V
Landroidx/lifecycle/u;
HSPLandroidx/lifecycle/u;-><init>()V
HSPLandroidx/lifecycle/u;->a(Landroidx/lifecycle/g$a;)V
HSPLandroidx/lifecycle/u;->b(Landroidx/lifecycle/u$a;)V
HSPLandroidx/lifecycle/u;->c(Landroidx/lifecycle/u$a;)V
HSPLandroidx/lifecycle/u;->d(Landroidx/lifecycle/u$a;)V
HSPLandroidx/lifecycle/u;->onActivityCreated(Landroid/os/Bundle;)V
PLandroidx/lifecycle/u;->onDestroy()V
PLandroidx/lifecycle/u;->onPause()V
HSPLandroidx/lifecycle/u;->onResume()V
HSPLandroidx/lifecycle/u;->onStart()V
PLandroidx/lifecycle/u;->onStop()V
HSPLandroidx/lifecycle/z;-><init>()V
PLandroidx/lifecycle/z;->a()V
PLandroidx/lifecycle/z;->d()V
Landroidx/lifecycle/A;
HSPLandroidx/lifecycle/A;-><init>(Landroidx/lifecycle/D;Landroidx/lifecycle/A$b;)V
HSPLandroidx/lifecycle/A;->a(Ljava/lang/Class;)Landroidx/lifecycle/z;
HSPLandroidx/lifecycle/A;->b(Ljava/lang/String;Ljava/lang/Class;)Landroidx/lifecycle/z;
Landroidx/lifecycle/D;
HSPLandroidx/lifecycle/D;-><init>()V
PLandroidx/lifecycle/D;->a()V
HSPLandroidx/lifecycle/D;->b(Ljava/lang/String;)Landroidx/lifecycle/z;
HSPLandroidx/lifecycle/D;->d(Ljava/lang/String;Landroidx/lifecycle/z;)V
Landroidx/lifecycle/F;
HSPLandroidx/lifecycle/F;->a(Landroid/view/View;Landroidx/lifecycle/l;)V
Landroidx/lifecycle/G;
HSPLandroidx/lifecycle/G;->a(Landroid/view/View;Landroidx/lifecycle/E;)V
Landroidx/startup/a;
HSPLandroidx/startup/a;-><clinit>()V
HSPLandroidx/startup/a;-><init>(Landroid/content/Context;)V
HSPLandroidx/startup/a;->a()V
HSPLandroidx/startup/a;->b(Landroid/os/Bundle;)V
HSPLandroidx/startup/a;->c(Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroidx/startup/a;->d(Ljava/lang/Class;Ljava/util/Set;)Ljava/lang/Object;
HSPLandroidx/startup/a;->e(Landroid/content/Context;)Landroidx/startup/a;
HSPLandroidx/startup/a;->f(Ljava/lang/Class;)Ljava/lang/Object;
HSPLandroidx/startup/a;->g(Ljava/lang/Class;)Z
Landroidx/appcompat/widget/N;
HSPLandroidx/appcompat/widget/N;-><init>(Landroidx/appcompat/widget/Toolbar;)V
HSPLandroidx/appcompat/widget/N;->run()V
Landroidx/fragment/app/m;
Lw/a;
HSPLandroidx/fragment/app/m;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/n;
HSPLandroidx/fragment/app/n;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/o;
HSPLandroidx/fragment/app/o;-><init>(Landroidx/fragment/app/q;)V
Landroidx/fragment/app/p;
HSPLandroidx/fragment/app/p;-><init>(Landroidx/fragment/app/q;)V
Landroidx/lifecycle/s;
HSPLandroidx/lifecycle/s;-><init>(Landroidx/lifecycle/t;)V
Lh/c;
HSPLh/c;->a(Ljava/lang/Object;)V
@@ -0,0 +1,10 @@
{
"version": 3,
"artifactType": {
"type": "COMPATIBLE_SCREEN_MANIFEST",
"kind": "Directory"
},
"applicationId": "io.truckwash.twa",
"variantName": "release",
"elements": []
}
@@ -0,0 +1,89 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations: If you don't want to optimize, use the proguard-android.txt configuration file
# instead of this one, which turns off the optimization flags.
-allowaccessmodification
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**
@@ -0,0 +1,95 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize steps (and performs some
# of these optimizations on its own).
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
-dontoptimize
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**
@@ -0,0 +1,89 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations can be turned on and off in the 'postProcessing' DSL block.
# The configuration below is applied if optimizations are enabled.
-allowaccessmodification
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**
@@ -0,0 +1,5 @@
31=0/.dm
2147483647=0/.dm
28=1/.dm
29=1/.dm
30=1/.dm
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\main\assets"/></dataSet><dataSet config="release" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\release\assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\build\intermediates\shader_assets\release\compileReleaseShaders\out"/></dataSet></merger>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\main\jniLibs"/></dataSet><dataSet config="release" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\release\jniLibs"/></dataSet></merger>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\main\shaders"/></dataSet><dataSet config="release" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="C:\Users\2jepp\WebstormProjects\pleno-vue\app\src\release\shaders"/></dataSet></merger>
@@ -0,0 +1,4 @@
#Thu Jan 22 13:48:32 CET 2026
base.0=C\:\\Users\\2jepp\\WebstormProjects\\pleno-vue\\app\\build\\intermediates\\dex\\release\\minifyReleaseWithR8\\classes.dex
renamed.0=classes.dex
path.0=classes.dex

Some files were not shown because too many files have changed in this diff Show More