Commit Graph

4320 Commits

Author SHA1 Message Date
NianJiu
727f9e0a7e fix(ios): preserve active chat across foreground reconnects (#108241)
* fix(ios): preserve chat focus across reconnects

* chore(ios): sync native i18n inventory

* test(ios): strengthen reconnect ownership coverage

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:38:45 -07:00
pick-cat
c90833a62e fix(android): preserve emoji in tool detail previews (#108330)
* fix(android): preserve emoji in tool detail previews

* fix(android): sync i18n after tool detail utf16 preview

* proof(android): add UTF-16 tool display boundary proof script

Co-Authored-By: nebulacoder-v8.0 <noreply@zte.com.cn>

* chore: oxfmt proof-android-tool-display-utf16.mts

Co-Authored-By: nebulacoder-v8.0 <noreply@zte.com.cn>

* chore: remove redundant proof script

The Robolectric ToolDisplayRegistryTest already covers the UTF-16 boundary
behavior. The standalone Node.js proof script triggers CI checks (max-lines
ratchet, check-test-types, session-accessor-boundary) and provides no
additional coverage beyond the existing Android JVM tests.

Co-Authored-By: nebulacoder-v8.0 <noreply@zte.com.cn>

---------

Co-authored-by: nebulacoder-v8.0 <noreply@zte.com.cn>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:15:23 -07:00
Peter Lee
e08e1a0ca8 fix(ios): attach EKAlarm to reminders.add so due-time notifications fire (#106376)
* fix(ios): attach EKAlarm to reminders.add so due-time notifications fire

EKReminder.dueDateComponents only sets the deadline; without an explicit
EKAlarm, iOS does not produce lock-screen or banner notifications.

Closes #105523

* fix(ios): configure reminder due alerts

Co-authored-by: xialonglee <li.xialong@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:14:40 -07:00
Peter Steinberger
0d215c1cf0 fix(protocol): regenerate bundled clients for sessions thinkingLevel 2026-07-16 00:15:54 -07:00
dependabot[bot]
99ffe40569 build(deps): bump the android-deps group across 1 directory with 5 updates (#108167)
Bumps the android-deps group with 5 updates in the /apps/android directory:

| Package | From | To |
| --- | --- | --- |
| [gradle-wrapper](https://github.com/gradle/gradle) | `9.4.1` | `9.6.1` |
| [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java) | `1.84` | `1.85` |
| [org.junit.vintage:junit-vintage-engine](https://github.com/junit-team/junit-framework) | `6.1.1` | `6.1.2` |
| com.android.application | `9.2.1` | `9.3.0` |
| com.android.test | `9.2.1` | `9.3.0` |



Updates `gradle-wrapper` from 9.4.1 to 9.6.1
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.4.1...v9.6.1)

Updates `org.bouncycastle:bcprov-jdk18on` from 1.84 to 1.85
- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

Updates `org.junit.vintage:junit-vintage-engine` from 6.1.1 to 6.1.2
- [Release notes](https://github.com/junit-team/junit-framework/releases)
- [Commits](https://github.com/junit-team/junit-framework/compare/r6.1.1...r6.1.2)

Updates `com.android.application` from 9.2.1 to 9.3.0

Updates `com.android.test` from 9.2.1 to 9.3.0

Updates `com.android.test` from 9.2.1 to 9.3.0

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.bouncycastle:bcprov-jdk18on
  dependency-version: '1.85'
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: org.junit.vintage:junit-vintage-engine
  dependency-version: 6.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: android-deps
- dependency-name: com.android.application
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: com.android.test
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
- dependency-name: com.android.test
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: android-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 00:06:01 -07:00
Leon-SK668
66b09405d0 fix(android): preserve emoji in presence reason logs (#108103) 2026-07-16 00:03:24 -07:00
WhatsSkiLL
3e223756d4 fix(android): make onboarding layouts responsive (#108405)
* fix(android): make onboarding layouts responsive

* fix(android): order TogglePill modifier parameter

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-16 00:01:27 -07:00
Peter Steinberger
da59d6ade9 feat(onboarding): detect local inference providers (#108605)
* feat(onboarding): detect local inference providers

* fix(onboarding): satisfy inference choice lint

* chore(i18n): refresh onboarding locales

* chore: leave changelog to release automation

* chore(plugin-sdk): refresh API baseline

* fix(onboarding): preserve source config during local activation
2026-07-15 22:46:16 -07:00
Peter Steinberger
fabdfc90db chore(protocol): regenerate Swift gateway models for agentRuntime 2026-07-16 03:06:44 +01:00
Peter Steinberger
126b549a26 feat: run and reclaim cloud worker sessions from Control UI (#108398)
* feat(gateway): finish cloud worker session reclaim

* chore(gateway): refresh cloud worker artifacts

* fix(gateway): preserve recovery environment narrowing

* test(gateway): complete worker tunnel mock

* fix(gateway): harden cloud worker recovery

* fix(gateway): serialize forced worker teardown

* fix(gateway): handle replaced workspace directories

* fix(gateway): preserve forced destroy receiver

* test(ui): cover cloud worker reclaim flow

* fix(gateway): close final worker recovery races

* fix(ci): align cloud worker generated surfaces

* test(gateway): satisfy worker queue lint

* fix(gateway): recheck remote workspace after lease fence

* chore: move cloud worker release note to PR
2026-07-15 11:24:04 -07:00
WhatsSkiLL
4085121faa fix(android): enlarge voice note recording controls (#108307)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-15 11:31:00 -04:00
WhatsSkiLL
ae2b2ed05a fix(android): keep header logo in brand colors (#108199)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-15 11:30:11 -04:00
WhatsSkiLL
4bf77ca867 fix(android): wrap large segmented controls (#107574)
* fix(android): wrap large segmented controls

* fix(android): scope segmented control wrapping

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-15 11:29:47 -04:00
WhatsSkiLL
63f6cdf5f0 fix(android): outline providers back button (#106803)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-15 11:28:19 -04:00
Peter Steinberger
ff4ce42eab fix(linux): use the Clawd mascot for the desktop app icon (#108181)
The bundle/tray icon (icon.svg, icon-tile.svg and the generated
32/128/256/512 PNGs + icon.ico) still used the abstract two-pill
claw-mark. The product logo is the Clawd lobster mascot (already used in
the app header and ui/public/favicon.svg), so the app icon shown in the
Dock, taskbar, window, and tray now matches it: a static mascot on the
dark brand tile (transparent mascot for the tray). Regenerated from the
mascot SVG via rsvg-convert; build accepts the icon set.
2026-07-15 02:11:36 -07:00
Leon-SK668
8cc7cac556 fix(android): preserve emoji in app session labels (#108102) 2026-07-15 02:03:48 -07:00
Peter Steinberger
30bbe1b385 fix(system-agent): atomic approval migration + credential-scoped fallback
Final review findings:
- Wrap the operator-approval copy/drop/rename in a single immediate
  transaction so a crash mid-migration cannot strand or lose rows.
- The inference fallback marked a provider attempted before probing, so a
  stale requester credential blocked another agent's valid same-provider
  route. Dedup by credential owner and only retire a whole provider on
  provider-wide failures (auth/billing may differ per credential owner).

Refs #107237
2026-07-15 01:56:31 -07:00
Peter Steinberger
a97bdfb687 feat(agents): narrow gateway tool to read-only config
Phase 3 of #107237. Removes config.apply/config.patch/restart from the
regular-agent gateway tool (mirroring Phase 2's update.run removal); only
config.get and config.schema.lookup reads remain. Persistent config changes
and restarts now go exclusively through the human-approved openclaw
delegation path — closing the last unmediated agent config-write surface.
gateway stays owner-only/control-plane gated (config reads expose secrets and
host topology). Legacy setups can re-enable writes via the existing per-agent
tool allowlist; no new config key. Net -2271 LOC.

Refs #107237
2026-07-15 01:56:31 -07:00
Peter Steinberger
b1f4aac349 feat(agents): OpenClaw system-agent delegation
New openclaw delegation tool relays to openclaw.chat in-process; persistent
writes surface through the existing durable operator-approval registry as a
third system-agent kind (no parallel store), armed only by a human operator
in the Control UI — a delegated agent can never self-approve. Setup wizards
(channel/model/open-setup/open-tui) are refused in delegated mode so a
machine agent cannot complete setup or persist credentials unattended.
Vendor-neutral inference fallback ladder (requester route first, then other
authed providers by provider id). update.run removed from the gateway tool.
Caveman system-prompt fragment steers config/channels/plugins/agents/updates
to the openclaw tool. Doctor-owned state migration widens the approval-kind
constraint; runtime stays canonical-only.

Refs #107237
2026-07-15 01:56:31 -07:00
Peter Steinberger
db7c5d6a2c fix(macos): prevent Settings from opening with dashboard (#108074)
* fix(macos): keep settings explicit-only

* chore: defer release changelog

* chore(macos): refresh native i18n inventory

* refactor(macos): remove dead status router cleanup
2026-07-15 01:53:11 -07:00
Peter Steinberger
bfb015dbc5 fix(macos): silence Xcode 27 source warnings (#108081)
* fix(macos): silence Xcode 27 warnings

* fix(macos): silence remaining Swift 6.4 warnings
2026-07-15 01:49:23 -07:00
Peter Steinberger
bef86c8b88 fix(macos): skip post-update window for app-only updates (#108146)
* fix(macos): skip app-only update dialog

* fix(macos): preserve incomplete gateway recovery

* chore: leave release changelog ownership intact
2026-07-15 01:38:49 -07:00
Peter Steinberger
b65a2d836a feat(linux): discover gateways via Bonjour and open their dashboard (#108115)
New discovery.rs browses _openclaw-gw._tcp with a lifetime mdns-sd
browser, keeps a fullname-keyed snapshot (resolved updates replace,
goodbye/TTL removes), and mirrors the native clients' TXT contract and
direct-selection gate (resolved SRV endpoint routing; tailnetDns is a
hint only). The bootstrap page lists discovered gateways and connecting
navigates the dashboard WebView to the resolved endpoint, validated
against the live snapshot; remote selection cancels the local watchdog
so an in-flight local bootstrap cannot steal the WebView back.
2026-07-15 01:22:36 -07:00
Leon-SK668
9b6361a50c fix(android): preserve emoji in voice error status (#108101)
* fix(android): preserve emoji in voice error status

* chore(android): sync native i18n inventory

* fix(android): align voice status i18n allowlist
2026-07-15 01:16:27 -07:00
Peter Steinberger
f3e6042119 fix(ui): preserve explicit steer queue mode (#108121) 2026-07-15 01:09:55 -07:00
WhatsSkiLL
a0af118c0d fix(android): keep offline chat actions readable (#107404)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-15 00:15:03 -07:00
Peter Steinberger
0d7da61e9b fix(macos): hide update guide after app-only updates (#108034)
* fix(macos): hide update guide for app-only updates

* chore: defer release note to release changelog

* docs(macos): clarify app-only update completion

* chore(i18n): sync native update strings
2026-07-15 00:09:26 -07:00
Peter Steinberger
c31d19950f refactor(macos): tighten status item lifecycle 2026-07-14 23:57:05 -07:00
WhatsSkiLL
e6f3303cf2 fix(android): enlarge attachment remove touch target (#106737)
Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-14 23:13:14 -07:00
Peter Steinberger
596fb742fc fix(macos): update Peekaboo for Swift 6.2 (#107926) 2026-07-14 22:38:22 -07:00
Peter Steinberger
9384a40393 build(linux): allow macOS and Windows test builds of the desktop app (#108004)
The desktop companion crate was Linux-only. All platform-specific code
lives in canvas.rs (WebKitGTK, cairo, unix sockets, SO_PEERCRED), so:
move webkit2gtk/cairo-rs/libc under linux target dependencies, gate the
canvas module, its protocol registration, invoke handler, and exit
shutdown to Linux, add a USERPROFILE home fallback and an explicit
no-op installer error for Windows, and add the multi-size icon.ico
Windows resource. Linux behavior is unchanged; macOS/Windows builds are
for testing (macOS cargo build+test green locally; Windows aarch64-msvc
built and launched in a Windows 11 ARM VM).
2026-07-14 22:17:05 -07:00
Peter Steinberger
d61250ee7c fix(macos): keep left and right menu bar clicks reliable (#107786)
* fix(macos): stabilize menu bar click routing

* chore(macos): refresh native i18n inventory

* test(macos): avoid global menu event dispatch

* fix(macos): initialize status mouse router

* test(macos): avoid bare status button fixture

* test(macos): isolate status click routing
2026-07-14 21:12:58 -07:00
Kyle Klouzal
2333bd59db fix: keep yielded parent turns nonterminal (#95996)
* fix: keep yielded parent turns nonterminal

* fix: type chat final stop reasons

* test: isolate yielded session reconciliation

* fix: refresh yielded lifecycle generated surfaces

* test: register Codex lifecycle test shard

---------

Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-07-14 20:35:33 -06:00
Peter Steinberger
57d926b4fd fix: connect resumed native terminals reliably (#107688)
* fix: render resumed paired-node terminals

* fix(control-ui): connect native catalog terminals reliably

* chore: keep release notes in PR body

* fix(control-ui): require terminal reconnect cancellation

* fix(gateway): cancel timed-out terminal opens safely

* fix(control-ui): recover stalled terminal opens

* chore(ui): refresh i18n fallback baseline

* fix: preserve login shell path for resumed terminals

* refactor(plugin-sdk): avoid extra resolver export

* fix(gateway): normalize terminal open failures

* test(control-ui): split terminal readiness coverage

* docs: explain catalog terminal PATH restoration

* fix(control-ui): complete terminal readiness release gates

* fix(ci): remove unused shell resolver exports

* chore(plugin-sdk): refresh API baseline after rebase
2026-07-14 19:18:19 -07:00
Peter Steinberger
b1b5e212c0 fix(mac): keep dashboard navigation beside link browser (#107798)
* fix(mac): keep dashboard navigation beside link browser

* chore(i18n): refresh macOS browser source location

* test(ui): mirror responsive nav fixture state

* test(mac): respect constrained runner window size

* test(mac): measure laid-out browser split width

* test(mac): use constrained window layout width

* fix(mac): refresh split frames before restoring width

* chore(i18n): refresh macOS browser source location

* test(mac): use constrained window frame width

* test(mac): snapshot constrained split geometry

* test(mac): exercise feasible divider shrink

* test(mac): verify divider persistence callback

* test(mac): use current split dimension constant
2026-07-14 19:01:45 -07:00
Peter Steinberger
e905a682f7 feat(agents): session self-service tools
New grouped sessions tool (patch: label/pin/archive/model/thinking; group
CRUD; owner-gated; no reset/delete/compact). sessions_spawn gains visible +
worktree via sessions.create with admission reservation and abort-confirmed
rollback; a started run with no run id is aborted and deleted rather than
left orphaned. subagents tool reads the unified task_runs ledger tree-scoped
(subagent/acp/media/cron) and cancels detached runs, enforcing the
controlScope gate for leaf callers. session_status gains a cost line.
Agent-origin model patches record a fallback marker; runs failing on
auth/billing/model_not_found revert to the last working model (transient
errors never revert), and an independent thinkingLevel change realigns the
marker so revert cannot clobber it.

Refs #107237
2026-07-14 18:12:22 -07:00
Peter Steinberger
6f8903bc4d fix(macos): distinguish app and Gateway updates (#107793)
* fix(macos): clarify app-owned gateway updates

* fix(macos): sync update ownership translations

* fix(i18n): refresh control UI fallbacks

* fix(i18n): translate new control UI copy

* fix(ui): keep update routing live
2026-07-14 17:06:45 -07:00
Peter Steinberger
b363d5a293 feat(linux): canvas UI via CLI-node + Tauri app IPC bridge (#107633)
* feat(linux): canvas via CLI-node + Tauri app IPC bridge

* refactor: extract gateway helper modules

* build(linux-canvas): register plugin package in lockfile

* fix(linux-canvas): move canvas advertise test out of core, regen docs/protocol/deadcode

* fix(gateway): break node-catalog/registry import cycle via leaf normalize module; add canvas glossary term

* style: oxfmt invoke.ts and runtime.ts after buildNodeEventParams extraction

* fix(linux): load Canvas WebView via dedicated data_directory context

Wry's Linux/WebKitGTK incognito mode discards Tauri's registered
WebContext (wry webkitgtk/mod.rs), so the Canvas window got a fresh
ephemeral context without the openclaw-canvas:// scheme handler — the
bundled A2UI page never committed (stayed about:blank) and every A2UI
command timed out. Use an isolated cache-backed data_directory instead,
which keeps the protocol handler while still isolating Canvas storage
from the dashboard window.

* fix(linux): keep Canvas WebView ephemeral via incognito + data_directory

Autoreview flagged that a dedicated data_directory alone persists Canvas
browser state (cookies, localStorage, IndexedDB, service workers) across
restarts, so an agent that navigates Canvas to a site could leak an
authenticated session into a later session. iOS uses a non-persistent
store; Linux should match.

Add .incognito(true) alongside .data_directory(): the distinct directory
gives Tauri a fresh WebContext key so it still attaches the
openclaw-canvas:// protocol closure, and incognito makes Wry swap in a
fresh *ephemeral* context carrying those protocols. Live-verified on a
Wayland/WebKitGTK box: the bundled page still loads
(location.href=openclaw-canvas://localhost/index.html, openclawA2UI
present, A2UI renders) and the canvas-webview dir holds no persistent
cookie/storage files.
2026-07-14 16:05:14 -07:00
Peter Steinberger
890f20be06 feat(macos): coordinate app and Gateway updates (#107634)
* feat(macos): coordinate app and Gateway updates

* fix(macos): harden coordinated update recovery

* fix(gateway): reject mixed wake presence events

* chore: keep release notes in PR body

* chore(i18n): sync macOS update strings

* chore(generated): sync native artifacts

* style(macos): satisfy Swift checks

* chore(i18n): refresh update source locations

* fix(macos): localize post-update status

* fix(macos): satisfy post-update Swift lint

* chore(i18n): refresh post-update source locations

* test(gateway): isolate system-event routing state

* test(gateway): document system-event authorization
2026-07-14 14:59:32 -07:00
Peter Steinberger
f6653d1127 fix(macos): keep Connect Your AI choices in CLI order (#107642)
* fix(macos): align AI connection choices

* refactor(crestodian): extract setup auth options
2026-07-14 13:19:32 -07:00
Peter Steinberger
4f0e131cd2 feat(ui): run sessions on cloud workers (#107670)
* feat(ui): add cloud session targets

* test(ui): cover cloud session attachments

* test(ui): use recovery token fixture

* test(ui): record cloud locale fallbacks

* fix(ui): harden cloud session recovery

* fix(ui): track cloud handoff phase

* fix(ui): close cloud recovery escape paths

* fix(ui): finish cloud recovery hardening

* fix(ui): recover ambiguous cloud session creation

* fix(ui): isolate stale cloud creation recovery

* test(ui): preserve cloud recovery literals

* fix(ui): complete cloud session release artifacts

* chore: move cloud release note to PR body

* docs(ui): name cloud session menu exactly
2026-07-14 12:44:11 -07:00
Peter Steinberger
6e500d3248 chore(rename): reconcile with main #102197 plugin-install trust + regen baselines
Rebase onto main pulled in the ClawHub plugin-install trust check (#102197);
ported it into the renamed system-agent operations/tool/tests, refreshed
native i18n, deadcode, and max-lines baselines for the renamed paths.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
d66033315f style(macos): doc comment on storedPendingPayload
Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
69e9254e0e fix(ci): regen rename-affected generated surfaces and fix e2e entrypoint
native i18n inventory + per-locale artifacts resynced for the OpenClaw
strings; Kotlin gateway protocol enum regenerated instead of hand-edited;
deadcode baseline re-sorted; lint suppression allowlist entries moved to
sorted position; setup TTY check drops redundant boolean compares;
ring-zero first-run e2e calls the real 'openclaw setup' subcommand.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
6fdbe9a02a fix(system-agent): adopt retired pending key and re-enter shell on bare /openclaw
Review findings on the rename: macOS resume store now migrates activation
leases persisted under the retired crestodian UserDefaults key so an app
upgrade cannot orphan a live activation; open-tui results carry
returnToShell so bare /openclaw re-enters the OpenClaw shell instead of
exiting the CLI.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
985a13ba3a chore(i18n): prune retired crestodian strings and polish setup docs
android:i18n sync drops orphaned entries for the renamed key; wizard zh
locales reference openclaw setup; docs title disambiguates the system
agent from the product.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
a6a0716486 feat(setup): rename Crestodian to OpenClaw system agent
User-facing name is now OpenClaw (the system speaks); internal code name is
system-agent. Gateway methods crestodian.* -> openclaw.chat/openclaw.setup.*,
agent tool -> openclaw, reserved agent ids openclaw + retired crestodian.
openclaw setup routes: onboarding flags -> onboard, -m/--yes -> system agent,
bare configured interactive -> OpenClaw chat, unconfigured -> onboarding.
Hidden crestodian CLI and /crestodian TUI aliases kept; docs moved to
docs/cli/openclaw.md with redirect stub. macOS/Android strings in lockstep.

Refs #107237
2026-07-14 11:03:02 -07:00
Peter Steinberger
96eaf2be80 fix: restore recent native, browser, and audio behavior (#107631)
* fix: repair recent landed regressions

* chore: keep release changelog owned

* test(macos): align CLI fixtures with Node floor

* fix(macos): document Node runtime floor contract

* style(auto-reply): restore runtime mode formatting
2026-07-14 10:47:33 -07:00
Peter Steinberger
2bbf5e6ca0 fix(macos): prevent clipped and stalled onboarding (#107598)
* fix(macos): harden onboarding on short screens

* chore: keep release notes in PR body

* chore(i18n): refresh macOS onboarding inventory
2026-07-14 10:07:41 -07:00
Peter Steinberger
82d2a03d0a fix(swift): remove dead shared kit declarations (#107616) 2026-07-14 09:55:01 -07:00