Commit Graph

79 Commits

Author SHA1 Message Date
dependabot[bot]
01f0d6c1ac
Bump micromatch from 4.0.5 to 4.0.8
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-02 00:03:56 +00:00
Leslie H
9c90da7398
Bump minio to v8.0.0 (#991) 2024-06-03 15:20:10 +00:00
George Gevoian
5c35501654 (core) Upgrade browser testing dependencies
Summary: Upgrades mocha-webdriver to 0.3.3 and updates any affected tests.

Test Plan: Existing tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: dsagal, paulfitz

Differential Revision: https://phab.getgrist.com/D4246
2024-05-08 19:39:28 -04:00
George Gevoian
3aeff3c547 (core) Downgrade typeorm to 0.3.17
Summary:
SaaS bundling still uses browserify, which can't handle bundling typeorm
0.3.18 and beyond.

Also fixes an unrelated, flaky Notification test.

Test Plan: Existing tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D4243
2024-04-30 16:13:33 -04:00
Jordi Gutiérrez Hermoso
61cb80d4e3 (core) Security updates for package.json following version bump update from grist-core
Summary: Fix the build and tests following version bump from [#921](https://github.com/gristlabs/grist-core/pull/921) from grist-core

Test Plan: Existing tests pass

Reviewers: georgegevoian, jordigh

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4239
2024-04-29 18:50:56 -04:00
fflorent
b04304342d Strict version in package.json 2024-04-29 14:54:36 -04:00
fflorent
71b282669d Fix moment version (so the parseDate pass) 2024-04-29 14:54:36 -04:00
fflorent
144f09ca36 Attempt yarn-audit-fix 2024-04-29 14:54:36 -04:00
fflorent
54a8f63f28 Fix yarn.lock 2024-04-29 14:54:36 -04:00
Florent
4a9b6fea9d
Shutdown Doc worker when it is not considered as available in Redis #831 (#856)
* Shutdown Doc worker when it is not considered as available in Redis
* Use isAffirmative for GRIST_MANAGED_WORKERS
* Upgrade Sinon for the tests
* Run Smoke test with pages in English
* Add logic in /status endpoint
2024-04-04 10:25:42 -04:00
Jonathan Perret
96b652fb52
Support HTTP long polling as an alternative to WebSockets (#859)
The motivation for supporting an alternative to WebSockets is that while all browsers supported by Grist offer native WebSocket support, some networking environments do not allow WebSocket traffic.

Engine.IO is used as the underlying implementation of HTTP long polling. The Grist client will first attempt a regular WebSocket connection, using the same protocol and endpoints as before, but fall back to long polling using Engine.IO if the WebSocket connection fails.

Include these changes:
- CORS websocket requests are now rejected as a stronger security measure. This shouldn’t affect anything in practice; but previously it could be possible to make unauthenticated websocket requests from another origin.
- GRIST_HOST variable no longer affects CORS responses (also should not affect anything in practice, as it wasn't serving a useful purpose)
2024-03-28 13:22:20 -04:00
Dmitry S
11afc08f65 (core) Improve API Console and link from Document Settings.
Summary:
Changes to building and serving:
- Remove unpkg dependencies, add npm module for swagger-ui-dist instead.
- Move apiconsole JS logic into core/app/client/apiconsole.ts, and use TypeScript.
- Add symlinks to swagger in static/ and core/static/.
- Refactor loadScript, and add loadCssFile; use these to load swagger-ui resources.

Changes to console itself:
- Support docId, workspaceId, orgId URL parameters. When present, the matching
  value in dropdowns is moved to the front and marked as "(Current)".
- Fix the ordering of example values, particularly for workspaces.
- Remove unwanted example values.
- Hide confusing "Authorize" button.
- Hide API keys, and rely consistently on cookies for executing API calls.

Integration into Grist:
- Added a button to Document Settings, just under document ID in "API".
- The button opens a separate page, passing in org, workspace, and doc info for the current doc.

Test Plan: Only tested manually, no automated tests yet.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D4173
2024-01-29 10:08:19 -05:00
Dmitry S
be0b4a1968 (core) Use slugify module to construct slugs in urlIds, addressing a long-standing TODO.
Summary:
This offers better handling for accented and non-English characters,
e.g. "Événements" becomes "Evenements" (rather than "vnements") and
"таблиця" becomes "tablicya" rather than an empty string.

Test Plan:
Added a test case. Existing documents will auto-redirect to
newly-generated names. In cases where it's different, that's probably for the
best.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4176
2024-01-29 10:02:27 -05:00
Jarosław Sadziński
a424450cbe (core) Forms feature
Summary:
A new widget type Forms. For now hidden behind GRIST_EXPERIMENTAL_PLUGINS().
This diff contains all the core moving parts as a serves as a base to extend this functionality
further.

Test Plan: New test added

Reviewers: georgegevoian

Reviewed By: georgegevoian

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D4130
2023-12-20 13:23:12 +01:00
Jarosław Sadziński
1116f2d227 (core) Updating dependencies
Summary: Updating npm packages in preparation for forms feature

Test Plan: Existing

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4142
2023-12-12 20:05:24 +01:00
Dmitry S
09c84734db (core) Enable the 'none' option in ColorSelect for cell and header text styles
Test Plan: Added a test case

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4120
2023-12-04 19:13:52 -05:00
Paul Fitzpatrick
de13a2fd7a
include the @gristlabs/grist-widget package, so Calendar is always available (#745)
The Calendar feature was implemented as a custom widget. To make it
available offline, we prepare a package that includes it, and add that
to Grist. The PluginManager is configured to find it.

An optional `GRIST_SKIP_BUNDLED_WIDGETS` flag is added to disable
widgets bundled this way from being used. This may be needed by
the tests in grist-widget to avoid getting an echo :-)
2023-11-28 09:28:15 -05:00
Jarosław Sadziński
dda1b5cf1b (core) Fixing packages after merge with core
Summary: Reconciling package.json between core and hosted version.

Test Plan: Existing

Reviewers: JakubSerafin

Reviewed By: JakubSerafin

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D4115
2023-11-14 13:34:18 +01:00
Florent
a4998b4b21
Add native OIDC support in Grist #707 (#717) 2023-11-09 14:56:39 -05:00
Florent
38c8476aff
Add option to serve Prometheus metrics #671 (#693)
Co-authored-by: Florent FAYOLLE <florent.fayolle@beta.gouv.fr>
2023-10-24 17:36:53 -04:00
George Gevoian
f1cf92aca1 (core) Polish new Add Column menu
Summary: Fixes and features for the unreleased Add Column menu.

Test Plan: Manual.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D4076
2023-10-17 15:39:53 -04:00
George Gevoian
0cadb93d25 (core) Update dependencies
Summary:
Changes the minimum version of Node to 18, and updates the Docker images and GitHub workflows to build Grist with Node 18.

Also updates various dependencies and scripts to support building running tests with arm64 builds of Node.

Test Plan: Existing tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3968
2023-10-11 17:36:58 -04:00
George Gevoian
f38df564a9 (core) Add Command API to Grist Plugin API
Summary:
The new Command API provides limited access to Grist Commands from within cusotm
widgets. This includes the ability to perform undo and redo, which is bound to
the same keyboard shortcut as Grist by default.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: paulfitz, jarek

Differential Revision: https://phab.getgrist.com/D4050
2023-09-27 13:25:18 -04:00
Dmitry
c9489e4a61
Fix ManyFetches test, and include into grist-core a needed upgrade to the 'ws' package. (#614)
This is a follow-up fix to 526a5df157.
2023-08-07 18:39:14 -04:00
George Gevoian
ea8a59c5e9 (core) Implement AI Assistant UI V2
Summary:
Implements the latest design of the Formula AI Assistant.

Also switches out brace to the latest build of ace.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3949
2023-07-13 10:30:35 -04:00
Paul Fitzpatrick
bcbf57d590 (core) bump mocha version to allow parallel tests; move more tests to core
Summary:
This uses a newer version of mocha in grist-core so that tests can be run in parallel. That allows more tests to be moved without slowing things down overall. Tests moved are venerable browser tests; only the ones that "just work" or worked without too much trouble to are moved, in order to keep the diff from growing too large. Will wrestle with more in follow up.

Parallelism is at the file level, rather than the individual test.

The newer version of mocha isn't needed for grist-saas repo; tests are parallelized in our internal CI by other means. I've chosen to allocate files to workers in a cruder way than our internal CI, based on initial characters rather than an automated process. The automated process would need some reworking to be compatible with mocha running in parallel mode.

Test Plan: this diff was tested first on grist-core, then ported to grist-saas so saas repo history will correctly track history of moved files.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3927
2023-06-27 02:55:34 -04:00
Dmitry S
d191859be7 (core) For exporting XLSX, do it memory-efficiently in a worker thread.
Summary:
- Excel exports were awfully memory-inefficient, causing occasional docWorker
  crashes. The fix is to use the "streaming writer" option of ExcelJS
  https://github.com/exceljs/exceljs#streaming-xlsx-writercontents. (Empirically
  on one example, max memory went down from 3G to 100M)
- It's also CPU intensive and synchronous, and can block node for tens of
  seconds. The fix is to use a worker-thread. This diff uses "piscina" library
  for a pool of threads.
- Additionally, adds ProcessMonitor that logs memory and cpu usage,
  particularly when those change significantly.
- Also introduces request cancellation, so that a long download cancelled by
  the user will cancel the work being done in the worker thread.

Test Plan:
Updated previous export tests; memory and CPU performance tested
manually by watching output of ProcessMonitor.

Difference visible in these log excerpts:

Before (total time to serve request 22 sec):
```
Telemetry processMonitor heapUsedMB=2187, heapTotalMB=2234, cpuAverage=1.13, intervalMs=17911
Telemetry processMonitor heapUsedMB=2188, heapTotalMB=2234, cpuAverage=0.66, intervalMs=5005
Telemetry processMonitor heapUsedMB=2188, heapTotalMB=2234, cpuAverage=0, intervalMs=5005
Telemetry processMonitor heapUsedMB=71, heapTotalMB=75, cpuAverage=0.13, intervalMs=5002
```
After (total time to server request 18 sec):
```
Telemetry processMonitor heapUsedMB=109, heapTotalMB=144, cpuAverage=0.5, intervalMs=5001
Telemetry processMonitor heapUsedMB=109, heapTotalMB=144, cpuAverage=1.39, intervalMs=5002
Telemetry processMonitor heapUsedMB=94, heapTotalMB=131, cpuAverage=1.13, intervalMs=5000
Telemetry processMonitor heapUsedMB=94, heapTotalMB=131, cpuAverage=1.35, intervalMs=5001
```
Note in "Before" that heapTotalMB goes up to 2GB in the first case, and "intervalMs" of 17 seconds indicates that node was unresponsive for that long. In the second case, heapTotalMB stays low, and the main thread remains responsive the whole time.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3906
2023-06-01 12:06:48 -04:00
Jakub Serafin
37347a79c0 (core) Currency from grist column is persistent when exporting to excel
Summary:
- when grist table is exported, currency is check and introduced in cell format in the form of "[currency symbol] [value]" (for example: zł 10000, $ 5000) . It's not what some cultures should display currences, but it's close enought
- when no symbol is defined for the currency, currency 3 letters code is used instead
- when currency is unknown, we are falling back to "$"

Test Plan: - nbrowser test scenario added for that purpose, please check Currences.xlsx to see output format exported.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3886
2023-05-08 10:39:01 +02:00
Paul Fitzpatrick
8810aa3bd3 (core) port test/home tests
Summary:
This ports the useful parts of the test/home tests to test/nbrowser (a chunk of the DocMenu tests were already covered).

I ripped out a chunk of test/browser code that is now no longer used.

I made a few changes to unrelated tests that happened to fail.

Test Plan: ported tests

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3888
2023-05-04 14:45:04 -04:00
github-actions[bot]
e325977653
automated update to translation keys (#472)
Co-authored-by: Paul's Grist Bot <paul+bot@getgrist.com>
2023-03-27 11:32:59 -04:00
George Gevoian
be8e13df64 (core) Add initial tutorials implementation
Summary:
Documents can now be flagged as tutorials, which causes them to display
Markdown-formatted slides from a special GristDocTutorial table. Tutorial
documents are forked on open, and remember the last slide a user was on.
They can be restarted too, which prepares a new fork of the tutorial.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3813
2023-03-22 10:09:02 -04:00
Paul Fitzpatrick
cbf925aa00 (core) updates from grist-core 2023-02-21 10:49:19 -05:00
Paul Fitzpatrick
6109b89d1b (core) update node-sqlite3 version to include memory leak fix
Summary:
This updates node-sqlite3 to include the a memory fix
from https://github.com/gristlabs/node-sqlite3/pull/12

Test Plan:
node-sqlite3 has a new test script; all existing
Grist tests should pass

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D3803
2023-02-14 12:57:15 -05:00
Paul Fitzpatrick
f7f76fb5e7
A set of tweaks to simplify electron packaging (#421)
* Replace `ormconfig.js` with a newer mechanism of configuring
    TypeORM that can be included in the source code properly.
    The path to `ormconfig.js` has always been awkward to handle,
    and eliminating the file makes building different Grist setups
    a bit simpler.
  * Remove `electron` package. It is barely used, just for some old
    remnants of an older attempt at electron packaging. It was used
    for two types, which I left at `any` for now. More code pruning is
    no doubt possible here, but I'd rather do it when Electron packaging
    has solidified.
  * Add a hook for replacing the login system, and for adding some
    extra middleware the login system may need.
  * Add support for some more possible locations of Python, which
    arise when a standalone version of it is included in the Electron
    package. This isn't very general purpose, just configurations
    that I found useful.
  * Support using grist-core within a yarn workspace - the only tweak
    needed was webpack related.
  * Allow an external ID to be optionally associated with documents.
2023-02-13 15:52:17 -05:00
Paul Fitzpatrick
95bb03ea33 (core) use latest @gristlabs/sqlite3 version
Summary:
This uses a version of @gristlabs/sqlite3 which has prebuilt binaries for
lots of platforms (falling back to compilation if needed).

Test Plan: manually confirmed faster installs in various situations

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3790
2023-02-03 09:14:16 -05:00
Jarosław Sadziński
90d3ee037a (core) User language switcher
Summary:
New language selector on the Account page for logged-in users.
New icon for switching language for an anonymous user.

For anonymous users, language is stored in a cookie grist_user_locale.
Language is stored in user settings for authenticated users and takes
precedence over what is stored in the cookie.

Test Plan: New tests

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3766
2023-01-26 09:47:14 +01:00
Jarosław Sadziński
654514c18d Rebasing main 2023-01-03 17:25:54 +01:00
Jarosław Sadziński
dcefd4a81b Adding basing setup for eslint 2023-01-03 17:18:44 +01:00
Louis Delbosc
4165c35dd3 Add translation keys generator script 2023-01-03 16:01:45 +01:00
Paul Fitzpatrick
e564d31582 (core) give preliminary support in core for storing snapshots in S3-compatible stores via minio-js client
Summary:
This is a first pass at snapshot support using the MinIO client, suitable
for use against a MinIO server or other S3-compatible storage (including
the original AWS S3).

In Grist Labs monorepo tests, it is run against AWS S3. It can be manually
configured to run again a MinIO server, and these tests pass. There are no
core tests just yet.

Next step would be to move external storage tests to core, and configure
workflow to run tests against a transient MinIO server.

Test Plan: applied same tests as for Azure and S3 (via AWS client)

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3729
2022-12-21 11:41:31 -05:00
Jarosław Sadziński
92d4fca855 (core) Adding DELETE /api/docs/webhooks/queue endpoint to clear the queue
Summary:
Creating an API endpoint to cancel any queued webhook messages from
a document.

Test Plan: Updated

Reviewers: paulfitz, georgegevoian

Reviewed By: paulfitz, georgegevoian

Differential Revision: https://phab.getgrist.com/D3713
2022-12-01 12:23:19 +01:00
Jarosław Sadziński
64710b60f3 (core) Moving nbrowser tests to grist-core
Summary:
Moving bulk of nbrowser tests to core. Some tests were split and only part of them were moved.
Tests that are left are either: not suitable for grist-core (like billing) or are failing during browser tests (are not reliable).
Four fixtures directory (uploads, docs, exports-csv/excel) where completely moved to grist-core and are linked as folders.
Those changes allows to add an nbrowser test in grist-core or in the main test folder without any need to link it or link a fixture document.

Other changes:
- testrun.sh has been modified, now it runs tests from both folders (test and core/test),
- TestServer used in grist-core is now adding sample orgs and users (kiwi and others),

Test modified
- SelectionSummary: now it is run on a bigScreen, it was failing randomly
- Billing.ts: relative paths were used
- DateEditor: added waitForServer - it was failing in browser mode
- FrozenColumns, ImportFromGDrive, Printing: updated import paths
- UserManager.ts: was split into two parts (it assumed limited products)
- ViewLayoutResize.ts: this test is still in main repo, it is still failing in browser mode tests

Test Plan: Existing

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: dsagal, paulfitz

Differential Revision: https://phab.getgrist.com/D3664
2022-10-25 17:22:54 +02:00
Jarosław Sadziński
5219932a1f (core) i18
Summary:
Adding initial work for localization support.

Summary in https://grist.quip.com/OtZKA6RHdQ6T/Internationalization-and-Localization

Test Plan: Not yet

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3633
2022-09-29 18:02:09 +02:00
Paul Fitzpatrick
1a091f1dd5 (core) another bundle of dependabot suggestions
Summary:
Version changes suggested by dependabot for security issues that
may or may not affect us (it is easier to apply the changes than
to figure out if the issues are relevant).

 * understore 1.12.1
 * ini 1.3.7, 1.3.8
 * electron 19.0.9
 * js-yaml 3.13.1, 3.14.1
 * highlight.js 10.7.3
 * file-type 16.5.4

Test Plan: existing tests pass

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3629
2022-09-12 14:20:09 -04:00
Paul Fitzpatrick
99a207b1fc (core) another batch of dependabot updates
Summary:
Another batch of updates suggested by dependabot.

 * jsdom 16.5.0
 * terser 5.14.2
 * y18n 4.0.3
 * cached-path-relative 1.1.0
 * tar 4.4.19
 * saml2-js 2.0.5
 * jszip 3.10.1
 * path-parse 1.0.7
 * ws 6.2.2
 * normalize-url 4.5.1
 * lodash 4.17.21
 * elliptic 6.5.4
 * glob-parent 5.1.2

The only substantial change is the login bundle got slightly bigger (I think because of lodash).

Test Plan: existing tests pass

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3627
2022-09-09 13:34:08 -04:00
Paul Fitzpatrick
bde44323c5 (core) apply some dependabot suggestions
Summary:
This applies the set of dependabot suggestions that are currently
passing tests on grist-core. There are a lot more suggestions to
come, an unusual number are not passing tests because tests were
briefly broken.

The list of suggestions is extracted from:

https://api.github.com/repos/gristlabs/grist-core/pulls?search=status:success+state:open

And then applied using:

  yarn upgrade package1@version1 package2@version2 ....

After application, any new entries in package.json are pruned, leaving
just updated entries and yarn.lock changes.

Non-trivial code updates include:
 * A change related to axios typing
 * A change related to jquery dropping `size()` in favor of `length`

Test Plan: existing tests should pass

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3621
2022-09-07 14:15:34 -04:00
Jarosław Sadziński
2438a63255 (core) Moving widget tests to core
Summary:
- Custom widget tests are now in grist-core
- Adding buildtools for grist-plugin-api.js

Test Plan: Existing tests

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3617
2022-09-06 17:17:14 +02:00
Paul Fitzpatrick
d7b3fb972c (core) upgrade typeorm so we can support newer postgres
Summary:
upgrade typeorm version, so Grist can run against newer versions of postgres.

Dusted off some old benchmarking code to verify that important queries don't get slower. They don't appear to, unlike for some intermediate versions of typeorm I tried in the past.

Most of the changes are because `findOne` changed how it interprets its arguments, and the value it returns when nothing is found. For the return value, I stuck with limiting its impact by emulating old behavior (returning undefined rather than null) rather than propagating the change out to parts of the code unrelated to the database.

Test Plan: existing tests pass; manual testing with postgres 10 and 14

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3613
2022-09-02 15:34:21 -04:00
Jarosław Sadziński
a52d56f613 (core) Moving client and common tests to core
Summary:
- Moved /test/client and /test/common to core.
- Moved two files (CircularArray and RecentItems) from app/common to core/app/common.
- Moved resetOrg test to gen-server.
- `testrun.sh` is now invoking common and client test from core.
- Added missing packages to core's package.json (and revealed underscore as it is used in the main app).
- Removed Coord.js as it is not used anywhere.

Test Plan: Existing tests

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3590
2022-08-23 19:20:10 +02:00
Paul Fitzpatrick
103c795aa2 (core) make sure grist core yarn lockfile is tested
Summary:
This tweaks the grist core testing in our monorepo to match build
conditions for grist core docker images. It updates the grist core
yarn.lock which has become a little stale.

Test Plan: updated test

Reviewers: georgegevoian

Reviewed By: georgegevoian

Subscribers: georgegevoian

Differential Revision: https://phab.getgrist.com/D3584
2022-08-15 14:44:52 -04:00