Commit Graph

5168 Commits (fdbba7b020674270cb84bdffac79b2c241ed95ff)

Author SHA1 Message Date
NiLuJe c740ee3174 Kindle: Make sure Device:untar actually works
The fuse proxy strikes again... Fix #9704
2 years ago
NiLuJe 0382e0d4c2 OTM: Handle syntax errors at *both* stages when migrating
defaults.persistent.lua

We were pcall'ing the parsing, but not the execution...
The funky Lua syntax quirks means that it is possible to pass the former
but not the latter ;).

Fix #9700, de-facto regression since #9546
2 years ago
NiLuJe 5cb358f653 PocketBook: Move low-level input event type translation to the low-level
input modules.

There was a weird mix of touch being handled there, and key/msc here,
which was weird and made the logs extremely confusing to read.
2 years ago
NiLuJe 3dd87a38b3 Kindle: Oh, hey, turns out that was the new Basic
I'd completely forgotten they'd announced one ;o).
2 years ago
NiLuJe 43b021d37c Input: Allow disabling rotation_map entirely
(This involves moving it to the instance object to avoid inheritance).

Pocketbook: Disable rotation_map on the Era (fix #9556)
It would appear that InkView handles the translation for us, now...
2 years ago
NiLuJe 9470d473da Kindle: Lower some PM log messages to debug 2 years ago
NiLuJe b1504ea718 Kobo: Downgrade some suspend logging messages to debug, and *all*
standby logging messages to debug (except for warnings/errors, of course).
2 years ago
NiLuJe dbc559c0e0 USBMS: Add a human-readable log message when entering USBMS
Because apparently people are confused by the UIManager:quit ones...
2 years ago
NiLuJe cac37ad018 Kobo: Flag all the boards similar to the Libra 2 as unreliable (Clara 2E
& Nia).

And also disable the jump marker on those, like we did for the Libra 2.
2 years ago
NiLuJe bf574bfaaf GestureDetector: Only show the final adjustGesCoordinate log if the gesture actually was adjusted. 2 years ago
NiLuJe b656b9f5af Persist: Make sure data is flushed to disk on save
(i.e., do the usual flush & fsync dance, because FAT32 is the worst).
2 years ago
NiLuJe b523c2e8b9 InputContainer: Fall cleanup ;).
Get rid of the doc & seqtext fields, as they are not actually used (nor
are they particularly useful, the event handler's name should be pretty
self-explanatory).

Also, tweak the key_events documentation to highlight the quirks of the
API, especially as far as array nesting is involved...

Random drive-by cleanup of the declarations of key_events & ges_events
to re-use the existing instance object (now that we know they're sane
;p) for tables with a single member (less GC pressure).
2 years ago
Borys Lykah 9b2201a438
Initial hotpluggable keyboard handling (#9540)
* Added a new plugin external-keyboard. It listens to USB events. When keyboard is plugged in or plugged out, it updates device and input configuration accordingly.
* Added new fake events UsbDevicePlugIn and UsbDevicePlugOut that are emitted when a device is connected to a book reader that plays the role of USB host. The usage of the existing events UsbPlugIn and UsbPlugOut has not changed - they are used when a reader is connected to a host. The koreader-base has a related PR for those events.
* Did a small refactoring of initialization for the modules FocusManager and InputText. They check device keyboard capabilities on their when the module is first loaded and store it. Some of the initialization code has been extracted into functions, so that we can re-initialize them when keyboard is (dis)connected.
* Initial implementation centered around text input, and tested with USB keyboards on devices with OTG support.
* Said OTG shenanigans are so far supported on devices with debugfs & the chipidea driver, or sunxi devices.
2 years ago
hius07 a8ff3a6571 readerzoomin: add zoom mode translation, simplify zoom mode validation 2 years ago
hius07 0919c4ef17 readerkoptlistener: simplify zoom mode validation 2 years ago
weijiuqiao e8cd2ba498
WebDAV: fix bugs when start folder starts with "/" (#9688) 2 years ago
zwim d7c63edca6
Random optimizations (#9657) 2 years ago
zwim 31b16ba3e1
UIManager: get rid of self._running and self._run_forever (#9669) 2 years ago
hius07 d37803a8e7
Dispatcher: preserve profile name, show actions count (#9682)
(1) Preserve profile name when selecting the "Nothing" action.
(2) Show number of actions instead of "Many".
2 years ago
weijiuqiao ad89742e9b
Keyvaluepage: better alignment (#9672) 2 years ago
hius07 1d9c81de6e
ScrollableContainer: fix 'argc' (#9680) 2 years ago
Roygbyte 724db87755
ButtonDialog: add documentation about layout (#9505) 2 years ago
sonix-github eb56948fac
Keyboard: add Slovak virtual keyboard (#9656) 2 years ago
poire-z 48eb02318d
Dispatcher: avoid multiple cre rerenderings when many settings changed (#9651)
When a gesture/profile was updating multiple cre settings,
each setting handler would emit UpdatePos which each would
force a re-rendering.
When this might be happening, postpone the rerendering
until all are set.
Needs some bit of refactoring to the events at play:
introduce "DocumentRerendered" event, and use it where
we used "UpdatePos" or "UpdateToc" to mean exactly that.
2 years ago
hius07 d1abbbfdd8
Document settings submenu: add Save as default (#9643) 2 years ago
weijiuqiao edf7cc9a61
Vocabulary builder: support extracting context from pdfs (#9622)
Move getSelectedWordContext(), now document specific,
from ReaderHighlight into each document module.
2 years ago
weijiuqiao 58613d66e7
UI font fallbacks: use bold fonts if present for bold (#9621) 2 years ago
hius07 4d4b04359c
ReadHistory: refactoring with binary search (#9603)
Get rid of indexing and sorting, reduce flushing.
2 years ago
NiLuJe 54fae2987e
Support Android AArch64 (#9645)
c.f., https://github.com/koreader/koreader-base/pull/1540 & https://github.com/koreader/android-luajit-launcher/pull/390
2 years ago
NiLuJe 82b5f64178 time: Fix another subtle FP issue in split_s_us
The us part wasn't actually truncated properly.
2 years ago
NiLuJe 318d0e0ff0 UIManager: Modernize commented out debugging code
If you've ever enabled the main loop debugging, you'll know that
actually dumping the full window stack was *hilarious*.
Just print table counts, it's often good enough to debug what's
happening in the exceedingly rare cases you need this ;).
Also, it'll actually be readable, unlike the previous insanity ^^.
2 years ago
NiLuJe 390c875c80 Fix: key_events cannot be nil anymore since #9586 2 years ago
NiLuJe d2ac2ca6e7 Cleanup: Remove unused onAnyKeyPressed handlers
And simplify the few we do catch by using aliases instead of duplicated
functions;).
2 years ago
NiLuJe 78381c3afa ScreenSaverWidget: Actually enable the onAnyKeyPressed handler
Which allows us to exit the screensaver on, well, any key press ;o).
2 years ago
NiLuJe 854cbe9f94 Kobo: Unbreak frontlight toggle for some specific values
Because of floating point computery math stuff.

Regression since #9609
c.f., https://github.com/koreader/koreader/pull/9609#issuecomment-1288187080
2 years ago
poire-z 3dbcccb1a8
TextViewer: correct keyboard layout after long-press on Find (#9668) 2 years ago
hius07 e3fd612518
ConfigDialog: fix a bug with default values (#9666) 2 years ago
hius07 60a16c7e00
configdialog: fix bug with default values (#9662) 2 years ago
weijiuqiao bb03cf7310
Chinese keyboard: fix harmless typo (#9633) 2 years ago
weijiuqiao effddbc1ee
zh_keyboard: make number pad symbol mode (#9654)
This PR makes zh_keyboard's number pad symbol mode instead of shift mode, so that numbers are shown when the keyboard is called expecting numeral input.
2 years ago
NiLuJe 23c410344b
UIManager: Minor code cleanup (#9641)
* Remove a check made redundant by #9617
* Bump base (https://github.com/koreader/koreader-base/pull/1538)
2 years ago
NiLuJe d9eb6e9717
Kobo: Always use open/write/close for sysfs writes (#9635)
Also simplifies a few UIManager log messages (re: https://github.com/koreader/koreader-base/pull/1537)
2 years ago
hius07 2a354912f4
buttondialogtitle: align upper borders (#9631) 2 years ago
weijiuqiao ae8156ff9e Vietnamese keyboard: TELEX method backed by generic_ime 2 years ago
weijiuqiao 6a5a13dfc8 Generic keyboard IME bump: supports auto seperation when code is unique 2 years ago
yparitcher e424fcf5de
Dispatcher: Fix subtle bug with modified items being added twice to the sort index (#9628)
Discovered by @poire-z in https://github.com/koreader/koreader/pull/9531#issuecomment-1274839234
2 years ago
NiLuJe da65ac8b02
Cleanup various varargs shenanigans (#9624)
* Iterate over varargs directly via select if possible
* Use table.pack otherwise (https://github.com/koreader/koreader-base/pull/1535).
* This allows us to simplify a few Logger calls, as logger now handles nil values.
2 years ago
weijiuqiao 8508689cea
[feat] Add Thai keyboard (#9620)
This PR adds support for a Thai keyboard. Layout mostly copied from my phone, with difference in diacritics placements: phone has only one key for all of them, while here we have a couple more. Swipe in different directions needed for inputing them.
2 years ago
hius07 a728e3b5fa
ReaderStatus: save status summary (#9619) 2 years ago
zwim 4969811c08
Optimization: Use constant folding for divisions not a power of two (#9609) 2 years ago
zwim a24548ed3f
UIManager: Optimize binary insert (#9600)
* Optimiz
2 years ago
NiLuJe 68dcc4f36c
Bump base (#9618)
* Bump base (https://github.com/koreader/koreader-base/pull/1534)
* And some fixups following #9617
2 years ago
NiLuJe 6ac7a0cd40
UIManager: Fix handling of toast widgets in sendEvent (#9617)
The ultimate goal is for toast widgets (i.e., Notification when flagged as such) to:
  * Not stop event propagation
  * Close themselves when the event was emitted by user input.

Instead of doing event filtering in UIManager, we simply overload the onGesture & onKey* handlers in Notification to do just that, and just make sure UIManager will *send* those events to toasts, but without affecting the usual semantics of top widget selection and event propagation (which is as simple as just calling handleEvent on them unchecked ;p).

Thanks to @poire-z for the brainstorming in https://github.com/koreader/koreader/issues/9594 ;).

This also happens to fix a bug in which we might have looped on the top widget twice, because of an array vs. hash mishap ;).
2 years ago
NiLuJe ed96b15a3f
util: Add a set of binary searches implementation (#9614) 2 years ago
NiLuJe c9ff0071e3
DocSettings: Fix candidates sorting (#9607)
The candidates array had a very very very high chance of being sparse, which effectively broke the logic.
It was mostly harmless since said logic is only here for a long and varied history of backwards compatibility ;).
2 years ago
NiLuJe 2e1b40c997 ScreenSaver: When adding an overlay message to a top message, position
it *below* the top message, instead of *over* ;).
2 years ago
NiLuJe 5e6b783d27 ScreenSaver: Never inhibit the event message (reboot/poweroff), unless
specifically requested.

Using a custom message would effectively prevent the event message from
showing up, which is... bad.

(In fact, I'm half of the mind to get rid of the option to hide the
event messages, because it's a goddamned terrible idea).
2 years ago
NiLuJe a62f076e56 DictQuickLookup: The window_list array needs to be a static class member
Also, make sure references are actually dropped,
no matter how the widget is closed, by relying on onCloseWidget ;).

Enable the "long-press-on-close" trick on the actual Close button,
too, instead of only on the title bar's cross.

Fix: https://github.com/koreader/koreader/pull/9586#issuecomment-1272332275
2 years ago
NiLuJe 93ae341823
UIManager: Don't lose track of the original rotation on reboot/poweroff (#9606)
And, actually, stop enforcing Portrait; Screensaver already handles
rotation as necessary depending on the exact screensaver mode.

Fix https://www.mobileread.com/forums/showthread.php?t=349522
2 years ago
NiLuJe c0dffe2012
Kobo: Add a debug option to turn the charging LED on PM entry failure (#9601)
This should be fairly unintrusive, but still noticeable enough without having to watch the battery gauge like a hawk, or resort to actual monitoring via kernel logs and/or usb meter and/or multimeter...
2 years ago
NiLuJe eef938996f MultiDialog: Fix an extremely nasty API misuse
Stuff was poking at the class object, not the instance's :s.

Fix #9599
2 years ago
NiLuJe b1bcafa833 Persist: unbreak serialize for serpent 2 years ago
NiLuJe 39e0f84959 LuaDefaults: Simplify defaults.lua loading
Forget about the crazy filemanagersetdefaults shenanigans:
the previous code just did require("defaults"), so, $PWD it is ;).
2 years ago
yparitcher a916a5e8a2 Dispatcher: QuickMenu: Fix footgun
Fixes: #9594
2 years ago
NiLuJe ad22942108 LuaDefaults: Look for defaults.lua in $PWD first
As DataDir may not exist yet.

Fix #9593
2 years ago
NiLuJe 5c24470ea9
Logger: Use serpent instead of dump (#9588)
* Persist: support serpent, and use by default over dump (as we assume consistency > readability in Persist).
* Logger/Dbg: Use serpent instead of dump to dump tables (it's slightly more compact, honors __tostring, and will tag tables with their ref, which can come in handy when debugging).
* Dbg: Don't duplicate Logger's log function, just use it directly.
* Fontlist/ConfigDialog: Use serpent for the debug dump.
* Call `os.setlocale(C, "numeric")` on startup instead of peppering it around dump calls. It's process-wide, so it didn't make much sense.
* Trapper: Use LuaJIT's serde facilities instead of dump. They're more reliable in the face of funky input, much faster, and in this case, the data never makes it to human eyes, so a human-readable format didn't gain us anything.
2 years ago
NiLuJe fadee1f5dc
Clarify our OOP semantics across the codebase (#9586)
Basically:

* Use `extend` for class definitions
* Use `new` for object instantiations

That includes some minor code cleanups along the way:

* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
  * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2 years ago
NiLuJe 68b26c3a36
Keyboards/Menu: Lazy-load the layout-specific menu (#9584)
And do so only for the active layouts.

This prevents loading a potentially large amount of data without even having navigated to said menu (or having the layout enabled).
2 years ago
hius07 1ea7e16f3e
Cloud storage: add Dropbox short-lived tokens (#9496) 2 years ago
yparitcher 8a754cd271 Dispatcher: Fixes, Sort & QuickMenu
Fix condition check, simplify getNameFromItem

Allow sorting Dispatcher items and displaying them as a QuickMenu
2 years ago
hius07 c5505879c3
ConfigDialog: fix bug in DoubleSpinWidget default values (#9580) 2 years ago
hius07 b0eb0ce0e1
FileManager: add Select button to the file long-press menu (#9571) 2 years ago
poire-z 3bd27c3a76 ReaderFont: add "Font-family fonts" submenu
Allow associating a font to each of the generic
font-family names.

Bump crengine:
- CSS parsing: accept (and ignore) namesspaces
- isImage(): more checks for <object> as it can have inner content
- getFontFileNameAndFaceIndex(): returns if font has math support
- getFontFileNameAndFaceIndex(): returns if font has emojis
- CSS/Fonts: add support for font-family to font name mapping
2 years ago
poire-z defd9d1e02 TouchMenu: add support for checkmark_callback
Allows having a toggable checkmark on menu items
leading to a sub-menu.
2 years ago
poire-z 137b39416f ReaderLink:showAsFootnotePopup(): remove some logger.info() 2 years ago
weijiuqiao 24edbe162f Vocabulary builder: support manually adding words to vocabulary builder 2 years ago
weijiuqiao 91e5123ff0 Chinese keyboard: character level deletion apply to the last 2 chars 2 years ago
zwim 82d1381d49
Documentation: Fix documentation of infomessage (#9577) 2 years ago
NiLuJe 9bf19d1bb3
Assorted bag'o tweaks & fixes (#9569)
* UIManager: Support more specialized update modes for corner-cases:
  * A2, which we'll use for the VirtualKeyboards keys (they'd... inadvertently switched to UI with the highlight refactor).
  * NO_MERGE variants of ui & partial (for sunxi). Use `[ui]` in ReaderHighlight's popup, because of a Sage kernel bug that could otherwise make it translucent, sometimes completely so (*sigh*).
* UIManager: Assorted code cleanups & simplifications.
* Logger & dbg: Unify logging style, and code cleanups.
* SDL: Unbreak suspend/resume outside of the emulator (fix #9567).
* NetworkMgr: Cache the network status, and allow it to be queried. (Used by AutoSuspend to avoid repeatedly poking the system when computing the standby schedule delay).
* OneTimeMigration: Don't forget about `NETWORK_PROXY` & `STARDICT_DATA_DIR` when migrating `defaults.persistent.lua` (fix #9573)
* WakeupMgr: Workaround an apparent limitation of the RTC found on i.MX5 Kobo devices, where setting a wakealarm further than UINT16_MAX seconds in the future would apparently overflow and wraparound... (fix #8039, many thanks to @yfede for the extensive deep-dive and for actually accurately pinpointing the issue!).
* Kobo: Handle standby transitions at full CPU clock speeds, in order to limit the latency hit.
* UIManager: Properly quit on reboot & exit. This ensures our exit code is preserved, as we exit on our own terms (instead of being killed by the init system). This is important on platforms where exit codes are semantically meaningful (e.g., Kobo).
* UIManager: Speaking of reboot & exit, make sure the Screensaver shows in all circumstances (e.g., autoshutdown, re: #9542)), and that there aren't any extraneous refreshes triggered. (Additionally, fix a minor regression since #9448 about tracking this very transient state on Kobo & Cervantes).
* Kindle: ID the upcoming Scribe.
* Bump base (https://github.com/koreader/koreader-base/pull/1524)
2 years ago
weijiuqiao 05aba404b7
Keyboard: add Chinese stroke-based layout (#9572)
Basically it uses 5 keys for 5 basic stroke types and
inputs characters by their stroke order.
See https://en.wikipedia.org/wiki/Stroke_count_method
2 years ago
NiLuJe 8fcc712c76
Kobo: Clara 2E fixes (#9559)
* Handle the power button input device
* Handle the charging LED properly
* Handle the new Wi-Fi chip properly
* Handle frontlight warmth adjustments
* Handle the battery gauge properly
* Bump base (a lot of third-party updates) [https://github.com/koreader/koreader-base/pull/1523]
* Bump android-luajit-launcher to match the LuaJIT update [https://github.com/koreader/android-luajit-launcher/pull/386]

Fix #9552 (many thanks to @Bartvelp for bearing with my stupid tests ;)).
2 years ago
NiLuJe 2420557085
DocCache: Unbreak on !Linux platforms (#9566)
Regression since #9529
Fix #9565
2 years ago
NiLuJe 4d48b6e2fe
Misc: Use the ^ operator instead of math.pow (#9550)
And some minor code simplifications, thanks to @zwim ;).
2 years ago
NiLuJe 62059f8d68
Misc: Get rid of the legacy defaults.lua globals (#9546)
* This removes support for the following deprecated constants: `DTAP_ZONE_FLIPPING`, `DTAP_ZONE_BOOKMARK`, `DCREREADER_CONFIG_DEFAULT_FONT_GAMMA`
* The "Advanced settings" panel now highlights modified values in bold (think about:config in Firefox ;)).
* LuaData: Isolate global table lookup shenanigans, and fix a few issues in unused-in-prod codepaths.
* CodeStyle: Require module locals for Lua/C modules, too.
* ScreenSaver: Actually garbage collect our widget on close (ScreenSaver itself is not an instantiated object).
* DateTimeWidget: Code cleanups to ensure child widgets can be GC'ed.
2 years ago
hius07 46f729c248
ConfigDialog: show button with default values in spinwidgets (#9558) 2 years ago
hius07 46cdf8ed78
TextViewer: add navigation buttons (#9539) 2 years ago
NiLuJe b0d8919399
ImageViewer: Followup to #9529 (#9544)
* ImageViewer: Minor code cleanups
* GestureDetector: Fix the `distance` field of `two_finger_pan` & `two_finger_swipe` gestures so that it's no longer the double of the actual distance traveled. Get rid of existing workarounds throughout the codebase that had to deal with this quirk.
2 years ago
NiLuJe ab4b4b31bd
Kobo: Initial Clara 2E support (#9545)
Will need an actual tester to confirm FBInk gets the rotation right, as well as the touch input & frontlight situation.

* Bump base

https://github.com/koreader/koreader-base/pull/1519
https://github.com/koreader/koreader-base/pull/1521
2 years ago
poire-z a8c81a90c3
ReaderDict: fix use of dicts with ifo with DOS line endings (#9536)
Fixed in upstream sdcv, but we need to also do it in
our parsing of .ifo and picking out dict name.
Also includes minor bump of base/sdcv.
2 years ago
hius07 45e4f38c41
CloudStorage: remove cloudmgr (#9532)
Use downloadmgr instead.
2 years ago
NiLuJe 38919c22eb
ImageViewer: Clamp zoom factor to sane values (#9529)
Should avoid egregious values that would potentially alloc insanely large buffers (and likely fail to do so).

In the process, tweak the scale_factor computations when zooming so as to produce slightly less annoying behavior.
2 years ago
hius07 b81a407690
Profiles: add QuickMenu (#9526) 2 years ago
NiLuJe 83a2965d6b
Misc: Unify error logging on network errors (#9523)
Making sure we get the relevant information in the logs, and that the UI feedback (if any), is meaningful and readable.
2 years ago
hasezoey c8d84ffc77
Version::getShortVersion: handle "rev" being empty (#9502)
In which case we reply "unknown" instead of an empty string ;).
2 years ago
hasezoey 61415a3723
add custom mapping for tolino buttons (#9509) 2 years ago
NiLuJe 2fe2515ace
FontList: Always use the binary cache format (#9519)
Since I never actually needed to look into that data ever until today, let's just get rid of the weird debug-specific behavior.

Instead, just add a dedicated "Developer options" entry that will dump it on demand (and it'll be sorted to boot, which makes it 500% more usable).

Plus, since yesterday's change, the cache format switch between debug or not miiiight actually be crashy, so re-trigger the migration ;p.

* Includes a couple of noteworthy base bumps:

https://github.com/koreader/koreader-base/pull/1516 (update to sdcv 0.5.4 + fixes pending upstream)
https://github.com/koreader/koreader-base/pull/1517 (fix ffiUtil.orderedPairs with keys of mixed types)
2 years ago
Hannes Krumbiegel 29985c9c5c
Add Russian Wiktionary dictionary (#9517)
This adds a Russian-Russian dictionary that I created, extracted from Wiktionary.
2 years ago
NiLuJe 13e8213e0a
A random assortment of fixes (#9513)
* Android: Make sure sdcv can find the STL
* DocCache: Be less greedy when serializing to disk, and only do that for the *current* document ;).
* CanvasContext: Explicitly document API quirks.
* Fontlist: Switch the on-disk Persist format to zstd (it's ever so slightly faster).
* Bump base for https://github.com/koreader/koreader-base/pull/1515 (fix #9506)
2 years ago
hius07 e89d856ad9
textboxwidget: add math.floor (#9516) 2 years ago
hius07 56388aa491
TextViewer: add Find (#9507) 2 years ago