Makka/base poc

Description
This PR allows retirement of BCT on Base using Axelar.
Related Ticket
Closes #2334
How to Test
Test URL: https://base-git-makka-base-poc-klimadao.vercel.app/

Bridge some Klima over to Base on Squid Router - https://v2.app.squidrouter.com/?chains=137%2C8453&tokens=0x4e78011Ce80ee02d2c3e649Fb657E45898257815%2C0xDCEFd8C8fCc492630B943ABcaB3429F12Ea9Fea2
Ensure you have some ETH on base for gas fees.
Navigate to the base landing page, enter the details in the required fields including the quantity.
Happy path - Click "Retire Carbon" and attempt to execute a retirement, if successful - you should receive a "Transaction complete" message with a link to the transaction on Axelar where the progress can be tracked.
Once the transaction is complete (generally can take up to 30 minutes). Verify the retirement was successful with the correct data - should be visible under your [wallet address on carbonmark - example.
Error handling - Ensure the error messages on required fields are valid (i.e. insufficient balance, no quantity added, empty retirement message, empty beneficiary string, wrong network (anything other than base currently), logged out user etc...
Further Error handling - Ensure appropriate messages are shown in the transaction modal when a user for example rejects the transaction.

@Atmosfearful is it possible to give access rights to myself and the guys who will be QA'ing this on the base project? I currently have no access to the preview links for base.

Retire without KLIMA
I did two retirements with two different wallets. With one wallet, it worked without issue. The other one did not have any KLIMA in it, which results in this error on clicking Submit in the web form:

In these cases, the user shouldn't even get this far imo. There should be some sort of "Insufficient balance" message or so, preventing them from clicking the RETIRE CARBON or SUBMIT button in the first place. Right now, user has no idea what's happening 😕
Numbers error

This error occurs when you enter a value of more than about 840,000 tonnes in the retire field. Exact value is somewhere between 830k and 840k. Unlikely to ever be a real world problem, but an error is an error I guess 😎
--
Everything else seems to work for now, but I'm gonna give it a more in-depth test tomorrow morning. The retired tonne does show up on Carbonmark, even if it took a while even after it was confirmed on Axelar. Not a big deal though. Looks pretty good overall 🫡

Everything else seems to work for now, but I'm gonna give it a more in-depth test tomorrow morning. The retired tonne does show up on Carbonmark, even if it took a while even after it was confirmed on Axelar. Not a big deal though. Looks pretty good overall 🫡

Thanks for the thorough testing as always @0xtapi.

There was a missed case in my logic for calculating if it's an insufficient balance, so great catch. I believe this should be fixed now, if the user has no Klima, they should see "Insufficient balance" in their wallet when they change the quantity.

When an error is returned (like the one you've shown in the screenshot) - instead the user should now see a message on the button saying "Quantity too large" - happy to change this text to something more appropriate if you have any ideas? I've added a max length of 10 digits to the quantity input.

Let me know if there are any other suggestions and I'll jump on them and try get this over the line. 😃

There was a missed case in my logic for calculating if it's an insufficient balance, so great catch. I believe this should be fixed now, if the user has no Klima, they should see "Insufficient balance" in their wallet when they change the quantity.
When an error is returned (like the one you've shown in the screenshot) - instead the user should now see a message on the button saying "Quantity too large" - happy to change this text to something more appropriate if you have any ideas? I've also added a max length of 10 digits to the quantity input.

INSUFFICIENT BALANCE works, I can't click the button anymore 🫡
QUANTITY TOO LARGE works as well, 10 digit limit is also in place. Can't really think of a better message... seems on point! But I wonder: Why is 900k considered too large, but 800k is fine? How is a 'too large' number determined?

Functionally, I can't find anything wrong. I tried breaking it in a few ways (odd beneficiary/message, weird tonne amount, etc.), but couldn't. Looks like It Just Works™.
--
I have a few more ideas which might actually be too much as this is just a proof of concept, but I'm still gonna drop them in here for now. If it's too much work to implement any of this, we can push it to future iterations.

Right now, after a retirement has been submitted, the user gets the "View on Axelar" link. If that link isn't clicked and user closes that modal, they have no way to access that link again, so there's also no way of tracking the transaction (unless they're tech savvy, go to Axelar manually, input their wallet address, etc.). Imo, that Axelar link should be available somewhere, somehow, until the transaction is completed.

Same goes for the link to Carbonmark: Should this maybe be displayed to the user somewhere so they have a place where they can permanently access their retirement? 🤔 Or do we expect end users not to make use of this interface too much anyway, so it wouldn't be worth it to implement this? 🤔

Feel free to ignore these if they're beyond the scope of this PoC, I can bring them up in the meeting tomorrow instead 🫡

I have a few more ideas which might actually be too much as this is just a proof of concept, but I'm still gonna drop them in here for now. If it's too much work to implement any of this, we can push it to future iterations.

Right now, after a retirement has been submitted, the user gets the "View on Axelar" link. If that link isn't clicked and user closes that modal, they have no way to access that link again, so there's also no way of tracking the transaction (unless they're tech savvy, go to Axelar manually, input their wallet address, etc.). Imo, that Axelar link should be available somewhere, somehow, until the transaction is completed.
Same goes for the link to Carbonmark: Should this maybe be displayed to the user somewhere so they have a place where they can permanently access their retirement? 🤔 Or do we expect end users not to make use of this interface too much anyway, so it wouldn't be worth it to implement this? 🤔

Feel free to ignore these if they're beyond the scope of this PoC, I can bring them up in the meeting tomorrow instead 🫡 If these are out of scope, I'll set this to QA Done.

thanks for the ideas but those should go into an enhancement issue or a new Bet. This is a PoC and we should ship what we have if it passes QA.


the source language is assumed to be English.

I get a "Language of the translation is the same as source language" error when I open a file to translate into English (I am using Esperanto as the source language).
Source language should be an option, it should not be forced to English.

Source language is not assumed to be English, as you, well, assume. It is detected, pretty reliably (emphasis on pretty, e.g. mixed language content fails for obvious reasons, Esperanto may well fall into "too exotic to work" category).
Therefore, having followed this document would have been beneficial, because e.g. attached file would have informed reasons for misdetection and would have made fixing any issues possible. Can you please provide it?
The PO file format is the thing that assumes (for not unreasonable reasons) that source code is in English, not Poedit. Poedit does in fact support an extension for specifying source language, and it is documented.

Source language is not assumed to be English, as you, well, assume. It is detected, pretty reliably (emphasis on pretty, e.g. mixed language content fails for obvious reasons, Esperanto may well fall into "too exotic to work" category).
Therefore, having followed this document would have been beneficial, because e.g. attached file would have informed reasons for misdetection and would have made fixing any issues possible. Can you please provide it?
The PO file format is the thing that assumes (for not unreasonable reasons) that source code is in English, not Poedit. Poedit does in fact support an extension for specifying source language, and it is documented.

Thank you very much for this clear and complete answer.
I searched unsuccessfully in the PO documentation for the field for the source language.
I am glad to learn that poedit manages an additional field for this purpose, which is perfect for me.

Thank you very much for this clear and complete answer.
I searched unsuccessfully in the PO documentation for the field for the source language.
I am glad to learn that poedit manages an additional field for this purpose, which is perfect for me.

Thank you very much for this clear and complete answer.

Perhaps you could demonstrate your thanks by doing what I politely asked you to do (this being the 3rd time), instead of closing the issue?

Thank you very much for this clear and complete answer.

Perhaps you could demonstrate your thanks by doing what I politely asked you to do (this being the 3rd time), instead of closing the issue?

poedit version : 2.2.1
operating system : linux debian 10 (buster)
example file attached.
komenci.md.po.zip

poedit version : 2.2.1
operating system : linux debian 10 (buster)
example file attached.
komenci.md.po.zip


Add awesome free during covid

Hi, I'm currently curating the free during Covid19 resources, e.g. online courses, software, and many others. Is it possible if I include it here? Here is the repository https://github.com/kulkultech/free-during-covid

https://github.com/sindresorhus/awesome/blob/main/create-list.md

Thanks @sindresorhus


 Affected replicas: {countSlaves}' >> /tmp/recovery.log"
  ],
  "PreFailoverProcesses": [
    "echo 'Will recover from {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ],
  "PostFailoverProcesses": [
    "echo '(for all types) Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostUnsuccessfulFailoverProcesses": [],
  "PostMasterFailoverProcesses": [
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Promoted: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostIntermediateMasterFailoverProcesses": [
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "CoMasterRecoveryMustPromoteOtherCoMaster": true,
  "DetachLostSlavesAfterMasterFailover": true,
  "ApplyMySQLPromotionAfterMasterFailover": true,
  "PreventCrossDataCenterMasterFailover": false,
  "MasterFailoverDetachSlaveMasterHost": false,
  "MasterFailoverLostInstancesDowntimeMinutes": 0,
  "PostponeSlaveRecoveryOnLagMinutes": 0,
  "OSCIgnoreHostnameFilters": [],
  "GraphiteAddr": "",
  "GraphitePath": "",
  "GraphiteConvertHostnameDotsToUnderscores": true
}

Logs,
[mysql] 2019/02/18 18:40:40 packets.go:36: unexpected EOF
2019-02-18 18:40:40 ERROR invalid connection
2019-02-18 18:40:40 ERROR ReadTopologyInstance(xx.xx.3.145:3307) show variables like 'maxscale%': invalid connection
[mysql] 2019/02/18 18:40:40 packets.go:36: unexpected EOF
[mysql] 2019/02/18 18:40:40 packets.go:36: unexpected EOF
2019-02-18 18:40:40 INFO auditType:emergently-read-topology-instance instance:xx.xx.3.145:3307 cluster:xx.xx.3.145:3307 message:UnreachableMaster
2019-02-18 18:40:41 DEBUG analysis: IsMaster: true, LastCheckValid: false, LastCheckPartialSuccess: false, CountReplicas: 2, CountValidReplicatingReplicas: 1, CountLaggingReplicas: 0, CountDelayedReplicas: 0,
2019-02-18 18:40:41 WARNING executeCheckAndRecoverFunction: ignoring analysisEntry that has no action plan: FirstTierSlaveFailingToConnectToMaster; key: db04:3307
[mysql] 2019/02/18 18:40:41 connection.go:372: invalid connection
[mysql] 2019/02/18 18:40:41 packets.go:36: unexpected EOF
[mysql] 2019/02/18 18:40:41 connection.go:372: invalid connection
2019-02-18 18:40:41 ERROR invalid connection
2019-02-18 18:40:41 ERROR ReadTopologyInstance(db03:3307) show variables like 'maxscale%': invalid connection
[mysql] 2019/02/18 18:40:41 packets.go:36: unexpected EOF
2019-02-18 18:40:41 ERROR dial tcp xx.xx.3.145:3307: connect: connection refused
[mysql] 2019/02/18 18:40:41 packets.go:36: unexpected EOF
[mysql] 2019/02/18 18:40:41 connection.go:372: invalid connection
2019-02-18 18:40:41 INFO auditType:emergently-read-topology-instance instance:db03:3307 cluster:db03:3307 message:FirstTierSlaveFailingToConnectToMaster
2019-02-18 18:40:41 INFO auditType:emergently-read-topology-instance instance:xx.xx.3.145:3307 cluster:xx.xx.3.145:3307 message:UnreachableMaster
[martini] Started GET /api/leader-check for xx.xx.3.145:53940
[martini] Completed 200 OK in 744.56µs
[martini] Started GET /api/topology/db03 for xx.xx.3.145:53944
2019-02-18 18:40:41 DEBUG instanceKey: db03:3307
2019-02-18 18:40:41 DEBUG instanceKey: db04:3307
2019-02-18 18:40:41 DEBUG instanceKey: db05:3307
[martini] Completed 200 OK in 7.660114ms
2019-02-18 18:40:42 INFO executeCheckAndRecoverFunction: proceeding with UnreachableMaster detection on db03:3307; isActionable?: false; skipProcesses: false
2019-02-18 18:40:42 INFO topology_recovery: detected UnreachableMaster failure on db03:3307
2019-02-18 18:40:42 INFO topology_recovery: Running 1 OnFailureDetectionProcesses hooks
2019-02-18 18:40:42 DEBUG orchestrator/raft: applying command 2960: write-recovery-step
2019-02-18 18:40:42 INFO topology_recovery: Running OnFailureDetectionProcesses hook 1 of 1: echo 'Detected UnreachableMaster on db03:3307. Affected replicas: 2' >> /tmp/recovery.log
2019-02-18 18:40:42 DEBUG orchestrator/raft: applying command 2961: write-recovery-step
2019-02-18 18:40:42 INFO CommandRun(echo 'Detected UnreachableMaster on db03:3307. Affected replicas: 2' >> /tmp/recovery.log,[])
2019-02-18 18:40:42 INFO CommandRun/running: bash /tmp/orchestrator-process-cmd-952131171
2019-02-18 18:40:42 INFO CommandRun:

2019-02-18 18:40:42 INFO CommandRun successful. exit status 0
2019-02-18 18:40:42 INFO topology_recovery: Completed OnFailureDetectionProcesses hook 1 of 1 in 5.099655ms
2019-02-18 18:40:42 INFO auditType:emergently-read-topology-instance instance:db05:3307 cluster:db03:3307 message:UnreachableMaster
2019-02-18 18:40:42 INFO auditType:emergently-read-topology-instance instance:db04:3307 cluster:db03:3307 message:UnreachableMaster
2019-02-18 18:40:42 DEBUG orchestrator/raft: applying command 2962: write-recovery-step
2019-02-18 18:40:42 DEBUG raft leader is xx.xx.3.145:10008 (this host); state: Leader
2019-02-18 18:40:42 INFO topology_recovery: done running OnFailureDetectionProcesses hooks
2019-02-18 18:40:42 DEBUG orchestrator/raft: applying command 2963: write-recovery-step
2019-02-18 18:40:42 DEBUG orchestrator/raft: applying command 2964: register-failure-detection
2019-02-18 18:40:42 INFO executeCheckAndRecoverFunction: proceeding with UnreachableMaster recovery on db03:3307; isRecoverable?: false; skipProcesses: false
[martini] Started GET /api/leader-check for xx.xx.3.145:53948
[martini] Completed 200 OK in 861.648µs
[martini] Started GET /api/topology/db03 for xx.xx.3.145:53952
2019-02-18 18:40:42 DEBUG instanceKey: db03:3307
2019-02-18 18:40:42 DEBUG instanceKey: db04:3307
2019-02-18 18:40:42 DEBUG instanceKey: db05:3307
[martini] Completed 200 OK in 7.588265ms
2019-02-18 18:40:43 DEBUG analysis: IsMaster: true, LastCheckValid: false, LastCheckPartialSuccess: false, CountReplicas: 2, CountValidReplicatingReplicas: 0, CountLaggingReplicas: 0, CountDelayedReplicas: 0,
2019-02-18 18:40:43 WARNING executeCheckAndRecoverFunction: ignoring analysisEntry that has no action plan: FirstTierSlaveFailingToConnectToMaster; key: db05:3307
2019-02-18 18:40:43 INFO executeCheckAndRecoverFunction: proceeding with DeadMaster detection on xx.xx.3.145:3307; isActionable?: true; skipProcesses: false
2019-02-18 18:40:43 INFO executeCheckAndRecoverFunction: proceeding with DeadMaster detection on db03:3307; isActionable?: true; skipProcesses: false
[mysql] 2019/02/18 18:40:43 connection.go:372: invalid connection
[mysql] 2019/02/18 18:40:43 connection.go:372: invalid connection
2019-02-18 18:40:43 ERROR dial tcp xx.xx.3.145:3307: connect: connection refused

cat /tmp/recovery.log
Detected DeadMaster on corpdb03:3307. Affected replicas: 2
PS: Doing a graceful switch over it works. When I kill MySQL to trigger abnormal crash, failover is not triggering.

"RecoverMasterClusterFilters": [
    "_master_pattern_"
  ],

please see the docs. https://github.com/github/orchestrator/blob/master/docs/configuration-recovery.md#configuration-recovery


getPathname with params

Is your feature request related to a problem? Please describe.
I'm using the sitemap generation for my app following the example provided here.
However when I try to run that script I get an error saying: Error: Insufficient params provided for localized pathname. because I have some pathnames that take in some route params.
Describe the solution you'd like
It'd be great if the getPathname function that we get from calling createLocalizedPathnamesNavigation would take in a params object like the router.replace method does: router.replace({ pathname, params, query }, { locale }) (i.e.: getPathname({locale, href, params}))
Describe alternatives you've considered
Generating the sitemap entries for routes that have params in a more manual fashion by putting together the urls with their params in each language. This would however lead to less maintainable code.

getPathname does indeed support params on the href property. href is the same that you're passing to router.replace for example.
This question has come up a few times already though, I've now clarified this a bit in #1275. Hope this helps!

That's great and I can confirm it does work as expected but I think there's some issue with the type definition for getPathname since I'm getting this type error:
Type error: Object literal may only specify known properties, and 'params' does not exist in type '{ pathname: string; } & { query?: Record<string, SearchParamValue> | undefined; }'.

when calling getPathname({ locale, href: { pathname, params } })
Which is actually the reason why I did not know that I could pass in a params object.

That's great and I can confirm it does work as expected but I think there's some issue with the type definition for getPathname since I'm getting this type error:
Type error: Object literal may only specify known properties, and 'params' does not exist in type '{ pathname: string; } & { query?: Record<string, SearchParamValue> | undefined; }'.

when calling getPathname({ locale, href: { pathname, params } })
Which is actually the reason why I did not know that I could pass in a params object.
(Sidenote: since we're at it I caught a typo on the updated docs PR #1275: "If you're use the same pathnames for all locales...")

Thanks, fixed the typo in https://github.com/amannn/next-intl/commit/3ef6bea230912f57c31693f9e613f9d8f230c79a!
It's actually not a bug in the types, getPathname validates that only known string values can be passed to the href, not any kind of string.
E.g.:
const test: string = '/asdf';

// ❌ Type 'string' is not assignable to type '"/" | "/about"
getPathname({locale: 'en', href: test});

// ✅ Works
getPathname({locale: 'en', href: '/about'});

Similarly, getPathname validates that only pathnames with dynamic segments can receive the params object. The updated sitemap docs show valid cases where string values match with params.
In case you need to provide arbitrary string values, you might want to // @ts-ignore the expression.

Maybe I'm missing something on my setup then because I'm not using arbitrary strings and still getting that type error. Here's a minimal reproduction of the error following my current setup architecture:
import { createLocalizedPathnamesNavigation } from "next-intl/navigation"
import { Pathnames, LocalePrefix } from "next-intl/routing"

export const locales = ["es", "pt", "en"] as const

export const pathnames: Pathnames<typeof locales> = {
  "/": "/",
  "/companies/[slug]": {
    es: "/empresas/[slug]",
    pt: "/empresas/[slug]",
    en: "/companies/[slug]",
  },
}

export const localePrefix: LocalePrefix<typeof locales> = "always"

export const { Link, getPathname, redirect, usePathname, useRouter } = createLocalizedPathnamesNavigation({
  locales,
  pathnames,
  localePrefix,
})

type Href = Parameters<typeof getPathname>[0]["href"]

const test: Href = { pathname: "/companies/[slug]", params: { slug } }

const test2: Href = { pathname: "/test" }

I'm getting this error for the test const:
Object literal may only specify known properties, and 'params' does not exist in type '{ pathname: string; } & { query?: Record<string, SearchParamValue> | undefined; }'

And no error for test2 even though /test should not be a valid pathname value since it's not included in pathnames.
I'm also not getting any intellisense autocomplete suggestions for the pathname of the Href

Oh right, I think you had the same issue that I just fixed in that PR before. See here: https://github.com/amannn/next-intl/pull/1275/files#diff-28315a1743287da414ba279f75543ef824afe446dcfbe5fa579f5c07df2485b1
The key is using satisfies for pathnames. The docs already had this correct but I noticed this error in the example.


Write error when dimension not also a coord var

Reported by ansley b manke on 19 Apr 2016 20:26 UTC
See also #2227.  That ticket also has to do with a dimension and 2-D coordinate variable having the same name.
When writing data which comes from a file with a dimension that is not also a coordinate variable, we changed the WRITE to write out only the dimension but not a coordinate variable. But if the write is a subset in the direction of such a dimension, we need to save the coordinates too.
Muyin ran into this trying to write a subset of variables from a dataset which stores curvilinear coordinate variables on an i,j grid defined with dimensions but not coordinate variables.  The WRITE fails:
yes? use example.nc
yes? show dat
     currently SET data sets:
    1> ./example.nc  (default)
 name     title                             I         J         K         L         M         N
 TEMP     Potential Temperature            1:320     1:384     1:1       1:1       ...       ...
 LON      Longitude                        1:320     1:384     ...       ...       ...       ...
 LAT      Latitude                         1:320     1:384     ...       ...       ...       ...

yes? save/clobber/file=my_subset.nc/i=300:320/j=180:200 temp
 LISTing to file my_subset.nc
 **TMAP ERR: Requested data range is outside of data set limits
             Expected: TEMP[        300 :         320 ](I=) Found: TEMP[          1 :          21 ](I=)

The write has saved the dimension and its size, but we need the coordinate values to be written to complete the write operation.
I'll attach a short file with 1 dimension which also shows this; based on our DSG files for the SOCAT data where the dimension OBS doesn't correspond to a coordinate variable.
yes? use nodim.nc
yes? sh dat
     currently SET data sets:
    1> ./nodim.nc  (default)
 name     title                             I         J         K         L         M         N
 EXPOCODE expocode                         ...       ...       ...       ...       1:1       ...
 NUM_OBS  Number of observations           ...       ...       ...       ...       1:1       ...
 TEMP     sea surface temperature          1:51      ...       ...       ...       ...       ...

yes? save/file=a.nc/clobber/i=20:25 temp
 LISTing to file a.nc
 **TMAP ERR: Requested data range is outside of data set limits
             Expected: TEMP[         20 :          25 ](I=) Found: TEMP[          1 :           6 ](I=)

Migrated-From: http://dunkel.pmel.noaa.gov/trac/ferret/ticket/2401

Comment by ansley.b.manke on 19 Apr 2016 23:34 UTC
Fixed.  If we're writing a subset, then write the coordinates - they are no longer a simple dimension with 1,2,3,...dim-size.

Attachment from ansley.b.manke on 19 Apr 2016 20:26 UTC
REPLACE THIS TEXT WITH UPLOADED FILE ./attachments/TRAC_2401_GIT_1673/nodim.nc


Refactor raft state handling

Overview
This commit changes the state handling of the raft log. The actions for related to each raft state are strictly confined within that state's loop. To transition between states, the raft log now much clean up all its actions before moving on.
This fixes issues where goroutines were kicked off for one state but were delayed in their scheduling so they would begin after the log had already changed to another state.

This is a big change, difficult to grok it all. I'll take another pass after feedback and a green build.

OK, took a second pass. Still a big change. :-)
I do have some questions outstanding about the previous comments, I would like to get some feedback on those. I can follow at a very high-level what is going on, and the tests seem better. If you're happy I think you can merge.


Set up a logger during tests.

This makes debugging Internal Server Errors during tests significantly easier.

This change is

Current coverage is 82.04% (diff: 100%)

Merging #100 into master will decrease coverage by 0.04%

@@             master       #100   diff @@
==========================================
  Files            24         24
  Lines          1971       1972     +1
  Methods           0          0
  Messages          0          0
  Branches        283        283
==========================================
  Hits           1618       1618
  Misses          235        235
- Partials        118        119     +1

Powered by Codecov. Last update 452309c...d590f8c

Reviewed 1 of 1 files at r1.
Review status: all files reviewed at latest revision, all discussions resolved.

Comments from Reviewable


v1.0.1 disconnects in CuteChess

this happens suddenly, but every game - sometimes at move 15, sometimes at move 4 - see also [#1]
i let it play 4 games 5m+3s, this was the first one :
[Event "engine vs engine"]
[Site "Holland"]
[Date "2024.08.17"]
[Round "?"]
[White "Euwe v1.0.1"]
[Black "4KU v5.0"]
[Result "0-1"]
[FEN "rnbqkbnr/ppp1pppp/8/4N3/4P3/3p4/PPPP1PPP/RNBQKB1R w KQkq - 0 4"]
[GameDuration "00:05:59"]
[PlyCount "30"]
[SetUp "1"]
[Termination "abandoned"]
[TimeControl "300+3"]

1. Bxd3 {+1.00/9 11s} Nd7 {-1.37/25 14s} 2. Nxd7 {+0.98/10 11s}
Bxd7 {-1.33/26 11s} 3. Nc3 {+0.91/10 11s} e5 {-1.12/25 10s}
4. Qh5 {+0.92/11 11s} Qe7 {-1.19/24 10s} 5. Nd5 {+0.81/11 11s}
Nf6 {-1.09/30 10s} 6. Nxe7 {+0.78/12 11s} Nxh5 {-0.94/31 14s}
7. Nd5 {+0.84/11 11s} Rc8 {-1.11/26 8.8s} 8. g3 {+0.83/10 11s}
Be6 {-1.12/25 9.4s} 9. O-O {+0.87/9 11s} c6 {-1.28/24 8.3s}
10. Ne3 {+0.91/11 11s} Nf6 {-1.34/26 30s} 11. b3 {+0.90/11 11s}
Rd8 {-1.29/26 8.0s} 12. Bb2 {+0.94/11 11s} Nd7 {-1.44/25 13s}
13. Rfd1 {+0.88/10 11s} Nc5 {-1.30/26 7.0s} 14. Be2 {+0.90/10 11s}
Nxe4 {-1.39/27 7.5s} 15. d3 {+0.94/11 11s} Nf6 {-1.38/27 25s, White disconnects}
0-1

ZIPped CuteChess log pane output : euwe-v1-0-1-disconnect-cutechess-log.zip
CuteChess can also log to stderr. I didn't find a way in CuteChess GUI (v1.3.1) to set the stderrFile path but this can be done by hand in ~/.config/cutechess.json for each configured engine. Here also your [DEBUG] messages are logged.
This was the log tail of the messages in stderrFile :
euwe-engine-v1.0.1-compiled-HP-commit-6f51934: chess-engine-lib/GameState.cpp:689: Piece GameState::makeSinglePieceMove(const Move&): Assertion `move.to == enPassantTarget_' failed.

Thanks for reporting!
I hadn't ran a full game in debug mode in a while. Clearly some bugs snuck in which the debug checks were able to catch.
I think I found and fixed the relevant issues. I ran ~150 games between two copies of the latest version of the code built in debug mode, and no crashes or other issues occurred.
Let me know if the issue is fixed on the latest revision!

All went well (a few adjustments aside).
I will close this Issue now.


WinGet for Linux

Description of the new feature / enhancement
My idea would be if you could make a functioning version of winget for Linux
Proposed technical implementation details
Please don't take this serious, although it would be funny

you already have Snap, apt, and brew for Linux. Winget is just like those Linux package managers but for Windows. The name itself  suggests that.

I agree @vedantmgoyal2009.
One option would be to for Linux can do  query in WinGet repository, logically not upgrade nothing, only query and search.
If the idea is valid

What a great Idea, one Package Source and deploy it on multiple Clients. Real Use Case for me is, deploy for example Visual Studio Code in Package Repository and i could it deploy on Windows, Linux a.s.o.. Create it one time and deploy it everywhere ;-).
For now i have to create a package for winget, a package for snap or others. Multiple maintenance for each target platform :-( Not so great idea.


Add option to stop saving personally identifiable information YOURLS does not need/use

As far as I can tell by looking in the user interface, as stored in the
db, ip_address, and user_agent are unused and click_time is only used to
the day, but stored is seconds. Without that data, the data stored in
the db is pretty safe to call not personally identifiable, which is what
I want, and seems like a good config option that other users would want.
I know there is an option to not store anything in yourls_log, but the
data that appears to be actually used, like country, and day of click,
is generally not personally identifiable, so I should be able to keep
that data.
Also, after implementing this, a way to remove old data would be good
too.
Technical details regarding my environment

YOURLS version: 1.7.2

Plugins enabled: none

PHP version: doesn't matter

Bug description
What is the current behavior?

see above
What is the expected or desired behavior?
see above
Reproducible bug summary
see above.

The general philosophy of the project is not to add options. Where possible we're more prone to remove options, actually, and let users adapt YOURLS behaviour to their liking with plugins.

If it's not an option, it should be the default then.  This should
be reopened.
Look at what a, maybe the, most popular free software for traffic
analysis does for ip address privacy: https://matomo.org/docs/privacy/
The current situation is frankly a horrible default for privacy and
should have been made that way in the first place, and it's still worth
correcting.
Afaik, what I've suggested is not possible with the plugin api.

With the coming law regarding data collection (GDPR/RGPD), I've to admit that YOURLS is not compliant at all out the box. IP collection, location gathering, etc. which are, merged with timestamp data, personally identifiable information.
I remember me suggesting to move location resolution in a plugin, this is a new strong argument.
Regarding IP, this is more complicated, but yes, it should be dropped or moved to anonymized fingerprints.

Just wondering if anyone knows how the big names are handling this?  One big draw of all shorteners is the data collected.  What do Google and Bitly do? Did they stop collecting this kind of data? It seems many YOURLS data collection features are in some way copied from the big boys.

@ozh https://github.com/sas101/yourls-pseudonymize is good but it
doesn't do enough. It would need to drop more ipv6 and ipv4 data, reduce
time resolution, get rid of user agent.  But I guess I was wrong about
what is possible with a plugin. Also, the YOURLS plugin list has 0
plugins, and google searches didn't lead me to that plugin. So, I didn't
know about that plugin at all.
Right now for GPDR, my best guess is to turn on the option to not store
anything in yourls_log, archive the YOURLS html pages that show
aggregate analysis, then wipe out yourls_log. Then I will look and wait
for a url shortener which can do more analysis while only storing
aggregate data and not personally identifiable data. It's not something
I have the time to implement myself.

*GDPR (i don't use the post edit features because it requires nonfree javascript)

Oh, and one of my coworkers pointed out, I was probably wrong about
YOURLS not using ip data. It probably uses it to identify visitors for
deduplication. Is that right? It shouldn't be too hard to just turn that
off and still collect number of visitors per day and the country they
are from.

IP of URL submitter is also stored but I think that's out of the scope (if concerned people could just display on their public interface a warning like "if you shorten a URL your IP will be stored and you're OK with this")

if concerned people could just display on their public interface a warning like "if you shorten a URL your IP will be stored and you're OK with this"

Ha ha, good try, but that does not match GDPR rules! 😉
In all cases, IP storage is avoidable by doing all IP-processing before putting it in the DB, i.e. on the fly.

What about this? https://github.com/fenuz/yourls-anonymize-log

@Teki: Thanks, this is a quick hack, which overrides the filter for getting IPs and user agents and makes them return empty strings. Alas, geolocation is not possible any more and so no country code will be stored. But it is in my opinion enough to anonymize YOURLS, since a precise click time is no personal data without IP and/or user agent.

Cool, this is perfect. But you don't need to add it to anonymize-log since you override the database insert which actually logs the redirect data and now stores only blank fields except for the time and the keyword. This would also have the advantage of generating and storing the country code.
Additionally, one could make the timestamp more inexact, like the OP suggested.

I added it to the Plug-in because I don't want to alter the core.

Of course you should not alter the core. I meant your code is already a complete working plug-in (without meta header), so you don't need to add it to anonymize-log, but you can simply overwrite it.

But then adding new short URLs would still record IP addresses.

Which IP is stored where? Adding a new short URL stores my (admin) IP address, yes. But I don't see where IP addresses by using (old or new) short ULRs are stored. Could you please elaborate?
While typing I've got an idea what you could mean. If you let users add short URLs then their IPs would be logged in the table 'yourls_url'. Therefore, you have to hook additionally to the action "insert_link" (https://github.com/YOURLS/YOURLS/blob/master/includes/functions.php#L163) an remove the storing of the IP address.
Since I am not letting any users add links I don't need to do this. But for the sake of completeness it should be added to the plug-in, when storing country codes.

That's exactly what I meant. If you are the only one who can add links it doesn't matter for you.