Thanks to OpenMW, my SteamDeck has become a "Morrowind machine" -- it runs so well and it's so convenient to have all that world with me on the go. You can use https://luxtorpeda.gitlab.io which registers as one of the runtimes Steam uses to launch games -- Proton being one of them -- and behind the scenes Luxtorpeda will download and run OpenMW instead of Morrowind.exe.
HN user
stasm
They own the domain.
It seems like a wasted opportunity to set up a new domain (in this case: wikimedia.social) rather than use an existing one with a subdomain, e.g. social.wikimedia.org or social.wikimediafoundation.org. With a new domain I still have to do the work to verify whether the domain is indeed owned by the Wikimedia Foundation.
- # private... not sure why they didn't just use the "private" keyword, but I don't care. I almost always use TypeScript anyways
One of the reasons was to allow private and public fields of the same name, so that subclasses are free to add own public fields without accidentally discovering private fields of superclasses. There were many more considerations that went into the design: https://github.com/tc39/proposal-class-fields/blob/main/PRIV....
There was a heated debate about this and the choice of the # sigil back in 2015 at the time private fields were being designed: https://github.com/tc39/proposal-private-fields/issues/14.
When you rename or move a file that you're editing, its window instantly reflects the new name and location.
How does macOS achieve its reactivity? Is it two-way bindings? Events/messages? Immediate mode re-renders?
Tangentially related: https://js13kgames.com is currently going on -- the challenge is to build an HTML/CSS/JS game which compresses down to 13,312 bytes or less.
If it's something I want to read and then be done with it, I keep the tab open.
If it's something I may want to come back to, or something that I'd be sad if it disappeared from the web, I save it to a synced folder using the SingleFile extension which inlines all content into a single HTML file.
Type inference is one good reason. Similar syntax exists in a few modern languages, too: e.g. Rust and Swift. In languages with type inference it can be convenient that type annotations are in the postfix position relative to variable names:
let user = new User();
let user: User = new User();The second option shouldn't need to match as it is the default value anyway (signified by the *)
That's an interesting suggestion! Right now, the identifier between the brackets is required, but we could relax this in the future. In 1.0, we erred on the side of more conservative and explicit design, to improve the readability and discoverability of the syntax for translators.
The (2..4) range would work for Czech in this example (if I'm reading the CLDR right), but I'm afraid it wouldn't be sufficient for languages with more complex plural rules. Take the rule that returns "one" in Latvian, for example:
n % 10 = 1 and
n % 100 != 11 or
v = 2 and
f % 10 = 1 and
f % 100 != 11 or
v != 2 and
f % 10 = 1
…where n is the absolute value of the number, f is the visible fractional digits with trailing zeros, and v is _the number_ of visible fraction digits with trailing zeros. Some rules can get even more complex than that; see [0] and [1].It's safer and more robust to rely on the plural categories defined by the Unicode: (zero | one | two | few | many | other), and by the APIs provided by the platform (ICU, Intl.PluralRules, etc.).
[0] http://www.unicode.org/cldr/charts/latest/supplemental/langu...
[1] http://unicode.org/reports/tr35/tr35-numbers.html#Operands
You can get decent highlighting for basic Fluent messages by setting the editor to a mode for Properties files. For instance, whenever I type Fluent examples in GitHub, I use the following markdown:
```properties
# A comment
hello = Hello, world!
```
This is in fact by design. Properties files are quite nice for simple things. Fluent builds on top of them, and provides modern features like multiline text blocks (as long as it's indented, it's considered text continuation) and the micro-syntax for expressions: {$var}, {$var -> ...} etc.So far, I haven't had much time to invest in building proper highlighting modes for popular editors. There are ACE and Vim modes mentioned in other comments here, and also a slightly outdated https://atom.io/packages/language-ftl20n written by a contributor. I'd love to see more such contributions, and I'll be more than happy to help by reviewing code!
It's up to the localizer to define variants corresponding to the language's plural categories. For Russian, that's (one, few, many). Interestingly, this particular example could simplified to (few, *), because "раз" is good for both 1, 5, 11, 55, etc. See https://projectfluent.org/play/?id=7d22f87c04b23b86d9f9149d5... for an example of this in action.
Authoring tools can help here, too. Pontoon, Mozilla's translation management system, pre-populates plural variants based on the number of plural categories defined in Unicode's CLDR.
Thanks!
And it would result in combinatorial explosion of translation message versions if source code had to add special case for each quirk in each language.
This is the exact problem we designed Fluent to solve. If you get a chance to try it out, feel free to reach out to me if you questions. I'll be more than happy to help and to hear feedback.
Our goal was to design a simple DSL which is easy to read and make small edits to. Copying and pasting is a powerful learning method :)
We're also working on creating richer and more streamlined authoring experience in Pontoon, Mozilla's translation management system. You can read about the current state of Fluent support in Pontoon in my colleague's post at https://blog.mozilla.org/l10n/2019/04/11/implementing-fluent....
When Fluent formats translations, it returns simple strings (in the sense of primitive computer types). They can include markup which is parsed by a higher-level abstraction responsible for actually showing the translations somewhere in the UI. Take a look at https://github.com/projectfluent/fluent.js/wiki/DOM-Overlays in the experimental fluent-dom package, and their React equivalent, https://github.com/projectfluent/fluent.js/wiki/React-Overla....
It's possible to build this message in Fluent with nested selectors, or with adjacent selectors. I built an example using Polish, since that's a language I know best. (To be 100% correct in Polish, I'd need to use a different possessive pronoun, but doing so would actually remove the double use of gender from your question.)
https://projectfluent.org/play/?id=2d7ab4b7ed1c4d9656475614f...
It's a complex piece of UI and consequently, the resulting Fluent message is also quite complex. But possible to build :)
This is an excellent question and a very good use-case. I'm a Polish speaker myself, so I can definitely relate. It's also a good excuse for me to talk a little bit more about the advanced features of Fluent.
The Fluent Syntax is a simple declarative DSL. By design, it doesn't allow translators to build complex conditionals or use arithmetic. There is, however, an escape hatch. The problem you described can be solved in Fluent with a little bit of one-time help from the developer of the source code, through a feature of Fluent called custom functions.
Translations in Fluent can use functions to format values or decide between variants. There exist built-in functions like NUMBER and DATETIME. They are rarely used because the Fluent runtime calls them on numeric and temporal values implicitly, but they can be helpful when localizers wish to use custom formatting options.
weekday-today = Today is {DATETIME($today, weekday: "long")}.
See https://projectfluent.org/play/?id=a3540d4f02c104a634adbfc0e... for a live example of DATETIME.There can also be custom functions, defined during the initialization of the runtime. In Firefox, we use one such function called PLATFORM: https://searchfox.org/mozilla-central/rev/d33d470140ce3f9426.... It can be used as follows:
open-preferences = {PLATFORM() ->
[windows] Open Options
*[other] Open Preferences
}
The logic of custom functions is entirely up to developers and the localization needs of the UI. In https://github.com/projectfluent/fluent/issues/228#issuecomm..., for instance, I suggested using a custom function to handle negative and positive floor numbers.A custom function can also cater to the use-case you described. A simple and possibly naive implementation in JavaScript could look like the following one:
function NUMBER_HEAD(num) {
while (num > 999) {
num /= 1e3;
}
let first = num.toString()[0];
return num < 10 ? first
: num < 100 ? first + "x"
: first + "xx";
}
I wrote this with Polish in mind, but it could be useful to other languages in which numerals are named after the first thousand-triple, in a left to right order. Depending on the exact product requirements, the function could be called NUMBER_HEAD_POLISH, or perhaps NUMBER_HEAD_TRIPLE_FIRST_DIGIT :)Once defined, the function can be used as follows:
# The Polish copy can take advantage of the custom function.
page-of = {NUMBER_HEAD($pageTotal) ->
[1xx] Strona {$pageCurrent} ze {$pageTotal}
*[other] Strona {$pageCurrent} z {$pageTotal}
}
This method still requires some work from developers, but it only needs to happen once and in a single palce in code: where the Fluent runtime is initialized. Because they are code, custom functions can be reviewed and tested just as any other code in the code base, to help ensure that they do what they claim to :)Importantly, the use of the custom function is completely opt-in.
# The English copy doesn't need any special handling.
page-of = Page {$pageCurrent} of {$pageTotal}
All localization callsites remain unchanged, and all existing translations remain functional.There's a tool written by a Udacity developer which can be used to autoextract copy from React source code: https://github.com/udacity/fluent-react-utils/tree/master/pa...
It's something that I definitely plan to add. There's even an open issue about it! https://github.com/projectfluent/fluent.js/issues/185
This is a great point and something that we've seen come up very often in building UIs. The good practice which we recommend to developers at Mozilla is to avoid splitting or nesting messages, because it makes it harder for translators to see the entire translation at once.
We've taken a layered approach to designing Fluent: what we're announcing today is the 1.0 of the syntax and file format specification. The implementations are still maturing towards 1.0 quality, but let me quickly describe what our current thinking is.
For JavaScript, we're working on low-level library which implements a parser of Fluent files, and offers an agnostic API for formatting translations. On top of it we hope to see an ecosystem of glue-code libraries, or bindings, each satisfying the needs of a different use-case or framework.
I've been working on one such binding library called fluent-react. It's still in its 0.x days, but it's already used in a number of Mozilla projects (e.g. in Firefox DevTools). In fluent-react translations can contain limited markup. During rendering, the markup is sanitized and then matched against props defined by the developer in the source code, in a way that overlays the translation onto the source's structure. Hence, this feature is called Overlays. See https://github.com/projectfluent/fluent.js/wiki/React-Overla....
Here's how you could re-implement your example using fluent-react. Note that the <a>'s href is only defined in the prop to the Localized component.
<Localized
id="confirm"
$clickCount={7}
a={<a href="..."></a>}
>
{"Please <a>click here {$clickCount ->
[one] 1 time
*[other] {$clickCount} times
}</a> to confirm."}
</Localized>
I'd love to get more feedback on ideas in fluent-react. Please feel free to reach out if you have more questions!(Author of the blog post here.) Great question, thanks! Unicode defines six categories of plural forms: zero, one, two, few, many, and other. The names of these categories always appear in English. Unicode also maintains a collection of all mappings of numerical rules to these categories, for all languages supported by the CLDR. See http://www.unicode.org/cldr/charts/latest/supplemental/langu... for the mapping corresponding to the Czech grammar.
http://gamasutra.com/blogs/KylePittman/20150420/241442/CRT_S... is a well-explained and and a copiously illustrated write-up about why CRT emulation is essential to many pixel-art retro games.
I'm one of the creators of 'A moment lost in time.' Thanks for playing it and for the feedback. Are you on Linux by any chance? I've had some issues with the Pointer Lock API in Firefox on Linux.
I found that the one of the best ways to combat jetlag (at last on transatlantic long-haul flights) is to completely forgo eating on the plane. Instead, just drink a lot of water.
In fact, I usually try to have my last meal in the origin timezone at least 16 hours before the first breakfast in the destination timezone. I fly quite regularly from CET to PST and back, and this scheme has worked well for me.
I wouldn't mind if airlines stopped serving free food, thus giving me a choice of not eating at all for a reduced total price of the flight.
The whole ritual seems rooted in the old maritime traditions, while the rest of the experience including the travel time and the seating position, are different and modern.
The problem with this customization is that different styles end up with different allowed character counts in a single line. For linters to work as expected you still have to hardcode the number of spaces a tab should count as in the linter's config. At which point you could just use spaces and treat indentation as part of the content—not presentation.
I'd love to revive my N900. Do you have any recommendations about which OS to install on it these days?
A similar project created by the National Library of Poland: https://github.com/Polona/malakh
Example: http://polona.pl/item/8214762/2/
You can use http://refract.mkelly.me/ to install Slack as a standalone web app (in Firefox and Chrome). I've done this to many service which I use frequently: Trello, IRCCloud, Messenger, Inbox, etc. and it works really well. The added benefit is that I don't need to be logged into these services on my main profile.
Maciej makes a great point about diminishing returns. We're quite good at extrapolating trend lines and yet we're terrible at predicting the future because it's very hard to guess where optimizations will happen. The 'good enough' seems to be the bane of any futuristic outlook. Technological progress seems to obey the laws of friction; it behaves like light which refracts when it enters a denser substance.
I'm still learning to embrace the 'good enough.' For instance, minimalism only works if it's good enough for the users. I feel like this predicate is often forgotten and we end up with designs which are minimal for their own sake.
Have you tried pinning tabs that you'd like to persist? Both Firefox and Chrome support this; just right click on a tab and choose "Pin tab" from the context menu.
There's some negativity in the early comments here, but I'd like to applaud the effort of making this a dead-simple self-hosted, FTP-friendly solution. We need more experiments around federated self-owned networks which are appealing to end users.
Is the code hosted somewhere on a VCS?