MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.14k stars 19.21k forks source link

Time for Marlin 2.0 release? #7951

Closed thinkyhead closed 6 years ago

thinkyhead commented 6 years ago

Is Marlin 2.0.x ready to take over and become the new current release?

There are very few PRs in the queue at this time, and many of those are now being targeted first for the bugfix-2.0.x branch. I've tried to make sure that the bugfix-1.1.x and bugfix-2.0.x branches are in parity with each other, and the slow, systematic approach has worked well. But, it's extra work to keep up with both, and with AVR stable in 2.0.x it feels mostly redundant.

Considerations

Marlin 1.1.x Maintenance Mode

The bugfix-1.1.x branch can continue to receive any new features and bug fixes that go into Marlin 2.0.x, but in the long term it will be retired. We can designate that all new features should go to Marlin 2.0.x first, and only added to 1.1.x if they seem useful (or easy) to do. Although it can be left open to allow work to continue in the 1.1.x branch for a while, the natural tendency will be for most attention to go to the 2.0.x branch and 1.1.x will naturally retire.

Right now applying patches to both versions is easy, because there hasn't been any divergence in core code, but as APIs change and mature, it will be less fun to back-port to 1.1.x. So, the sooner we transition, the better…

Todos, Quibbles, Caveats

What, if anything, is currently blocking 2.0.x from being ready for the world? Let's fix what we can, make a list of what still needs work and add that to the README, and try to push this out in its as-yet-unfinished form by —say— November 1…?

p3p commented 6 years ago

The main thing blocking the AVR 2.0 platform is the Arduino builder issue (as far as I know I have no idea how tested the platform is), we will get a lot of issues relating to broken builds until that is fixed by them.

As for the 32 bit there are a few things I've noticed in the last few days to do with the timer type defines and a few places in stepper.cpp that has code paths (depending on config) that still use AVR specific things, also the minimum stepper pulse code is using the wrong timers ticks per us, but overall the general part of the HAL seems to be getting there.

LPC1768/9: when you go outside a default RAMPS build and need general i2c spi, serial there probably will still be issues (though getting better), clock setup still needs to detect lpc1769 and set the clocks properly. I'm going to be generalising the pinmapping as it isn't clear that all LPC1768/9 boards use the Re-ARM mapping as it makes no difference what number points to what port/pin.

alexxy commented 6 years ago

I run printter with Dondolo extruder on AVR (MKS gen 1.4) using bugfix-2.0.x

Roxy-3D commented 6 years ago

November 1st might be pushing it a little bit. I would like for the v2.0.0 release to have better support for the Re-ARM board. I feel we should have 'almost complete' support of the feature set on at least one 32-bit board. And it would be really good to have fully checked out native support for the real Smoothieboard.

Right now, the BabyStepping doesn't work in the 32-bit versions. M100 won't compile and link because we haven't done the work to identify the equivalent names for things like __BSS_END and __BRK_VAL. Pretty much, turning on strange options causes problems in the 32-bit code.

It would be a mistake to release the current code as v2.0.0 without getting the 32-bit stuff more checked out. How about we do a 'feature freeze' on v1.1.x and get more people using v2.0.0? And when we have a 32-bit reference platform that is more checked out, we circle back and have the discussion about whether we are ready to release or not?

The big problem is there are a lot of people with 32-bit boards running Smoothieware. If they hear Marlin v2.0.0 supports 32-bit some number of them are going to dive into the pool head first and be sorely disappointed by what is currently there. We are better off waiting a few extra weeks and getting everything nicely polished.

teemuatlut commented 6 years ago

How about we do a 'feature freeze' on v1.1.x

We've had a feature freeze since June.

I'd say release v2.0 as soon as we're confident in the Re-ARM and AVR platforms to work reasonably well. I want to see the feature freeze end and also get rid of the two parallel branches.

Roxy-3D commented 6 years ago

We've had a feature freeze since June.

It would be very easy to disprove this statement.

I want to see the feature freeze end and also get rid of the two parallel branches.

Yes. Everybody wants that to end.

p3p commented 6 years ago

@Roxy-3D as long as the AVR 2.0 platform works then maintaining 2 branches is a lot of extra work (for @thinkyhead) for no gain, If each platforms level of functionality is very clearly stated I don't see an issue with the release (other than the Arduino build issue for AVR).

Right now, the BabyStepping doesn't work in the 32-bit versions. M100 won't compile and link because we haven't done the work to identify the equivalent names for things like __BSS_END and __BRK_VAL.

Didn't know about the M100 issue, __bss_end is a standard linker define so is available (can be fixed with a define) but __brkval is specific to the AVR malloc implementation, we could probably work around that with an sbrk(0) call but I'm not familiar with what AVR do.

Have you checked the pin for activity when trying babystepping?

Roxy-3D commented 6 years ago

but __brkval is specific to the AVR malloc implementation, we could probably work around that with an sbrk(0) call but I'm not familiar with what AVR do.

Actually... Marlin used to do malloc()'s but there should be no malloc()'s in the code right now. It maybe we need a reference to malloc() in the M100 code to pull in that symbol. It should not be hard to get going. And in fact, M100 is only for developer types anyway. But my point is a few extra weeks (4 or 6 weeks) to get things more polished would make the release much more stable.

I know it is a lot of extra work having two branches. That is why I suggested we do a feature freeze on v1.1.x and only put new stuff into v2.0.0. And that extra activity, and new features might help us get some extra test time on it.

Have you checked the pin for activity when trying babystepping?

No, I got side tracked. I'm chasing down a weird problem right now. That Max7219 8x8 LED Matrix had its 3 control signals connected to the ethernet port. It works just fine. Right up until I do a bunch of Z-Axis movements. It gets confused when that happens. It is almost like the Z-Axis movement is toggling pins on the ethernet port. I don't really believe that. But that is what it looks like.

I just finished moving the 3 control pins to the second Extruder on the RAMPS board. I'm just trying to get it working again. I was going to see if the LED Matrix still goes crazy. If it does... I'm wondering if we have to make the WRITE() macro atomic. I'm not far enough into it to know that is happening. And I don't have a logic analyzer which would be a big help. But I'll have more information soon...

UPDATE: Even driving the Max7219 8x8 LED Matrix from different pins (the 2nd Extruder), I see the corruption. I'm going to make the pin WRITE() macros atomic and see if that helps.

Phr3d13 commented 6 years ago

can someone help me get anet a8 sd related issues sorted before 2.0 release?

thinkyhead commented 6 years ago

Good feedback, thank you. The main concerns are all reasonable.


Level Up…

I don't want to leap without a strong consensus, but I don't relish doing this dual-integration work for a whole lot longer if there's a way we can put 2.0 out as the current AVR and common code release. I don't think we need to remove the incomplete HALs as long as we're clear they are at alpha and beta stages.

If we further mitigate all potential confusion about the completeness of these HALs by inserting #error messages to strongly warn users that they are still in-development, I think that would be enough to secure 2.0.x from n00bs. I know that in the past we set a precedent by doing RC releases, but I think that would just drag on, and… simpler is better (which is why I chose a Performa over a Quadra), so just going for it with 2.0.0 would be my bold and sassy choice. We can make it clear in the front-facing README that we have differing levels of confidence in some HALs and some features, and that if you use them you're a beta tester, but this is the shape of things to come.

Do you think we'd get more testing and feedback this way, and shake out the bugs? Maybe some of the vendors that still hack Marlin 1.0.2 would stop and take some notice… What else would you suggest to make 2.0.x safe for public consumption?

teemuatlut commented 6 years ago

In addition to #error messages on features not supported on a specific platform, it might also be useful to have a #warning Platform is still in beta testing! message for certain unfinished HALs.

alex-gh commented 6 years ago

For Smoothieboard users, the platform we need to support best is Due (SAM3X8E)

Smoothieboard v1 is based on LPC1769. It is the Duet board that is SAM3X8E based.

teemuatlut commented 6 years ago

Duet Wifi is SAM4E8E.

I'll be doing some SAM3X8E testing with the Archim2.0 board.

dot-bob commented 6 years ago

The biggest thing I see 2.0 lacking at this point is the dreaded "D" word i.e. documentation. Perhaps a getting started guide, migrating, code layout overview, and setting up a compiler for 2.0.x. If we had this the transition from 1.1.x AVR platform to 2.0.x should be relatively painless. An official guide on getting a 32 bit build going (with disclaimers) should help many get on board with their 32 bit platforms.

ImplementOfWar commented 6 years ago

I wish that MKS SBASE took priority as the litmus for a release candidate. When the price of entry is 45$ rather then 150$. The "majority" of Marlin user's aren't going to want to spend 150$ on a control board to play with the new "Marlin 32 bit".

Spawn32 commented 6 years ago

@ImplementOfWar MKS SBASE as a few days back runs Marlin 2.0 just fine, so just order one :)

p3p commented 6 years ago

@ImplementOfWar We aimed for LPC1768 Re-ARM as it was a direct replacement for Arduino Mega boards, will be plug and play for the majority of RAMPS configurations, and is $45... because of that choice we will also support (currently in testing) the MKS SBASE and other Smoothieware compatible boards.

@Spawn32 is that you guaranteeing support :wink:

Roxy-3D commented 6 years ago

Besides what p3p said.... It is important on a big project like this to have 'critical mass'. Panucatt Devices sent out 8 Re-ARM boards (internationally) to serious Marlin Developers and Testers. Even with that 'Critical Mass', I'm fighting problems because I'm doing things nobody else has done.

Today I merged a fix for Baby Stepping to fix ALL of the 32-bit boards. Not just Re-ARM. https://github.com/MarlinFirmware/Marlin/pull/8001 Tomorrow I'll be merging some fixes for the Re-ARM HAL's EEPROM emulation. (It turns out... UBL can't save a mesh yet on Re-ARM.)

   - while (file_size < E2END && res == FR_OK) {
   + while (file_size <= E2END && res == FR_OK) {

The other 32-bit boards can borrow heavily from any thing in the Re-ARM HAL. It really doesn't matter which 32-bit board is the 'Reference Platform'. What matters is there is a 32-bit platform that is working with ALL of Marlin's features. At that point, getting other 32-bit boards to do the same is much simplified.

If the makers of MKS SBASE had offered to send out some boards to help us get Marlin running on 32-bit platforms... We probably would have accepted them. But Re-ARM is a very good 'middle ground' because a lot of us have RAMPS type systems. This gives us a common ground as we move forward. And from a user base perspective.... Half of the users have RAMPS based systems. Re-ARM makes a lot of sense to use as a 'Reference Platform'. Half of the users can unplug the Atmega-2560 and plug in a Re-ARM board if they decide they are ready to move into the 32-bit world.

No Apologies offered!!!!!

PS. If you think Re-ARM was not a well thought out decision... Read https://github.com/MarlinFirmware/Marlin/issues/3851 At 444 posts over a year and a half with the top 32-bit minds contributing.... Maybe Re-ARM isn't a 'Perfect' choice. But I have no regrets about the decision.

Spawn32 commented 6 years ago

@p3p Lol, yes, guaranteeing support as long it's something i can fix 😃 (btw, can't fix magic smoke) @Roxy-3D fully understand you opinion, i dont know the history here, so coulden't have known ... 😄

marcio-ao commented 6 years ago

I have a brand new Archim board from Ultimachine and am eager to get it to work with main-line Marlin (as opposed to Marlin4Due). What is the best way to get started? Is "bugfix-2.0.x" the most up-to-date branch? Any gotchas I should know about?

teemuatlut commented 6 years ago

https://github.com/teemuatlut/Marlin/tree/Archim2 Tested by UltiMachine to work at least on a basic level. I just haven't made the PR yet. You'll also need my TMC2130Stepper library.

marcio-ao commented 6 years ago

@teemuatlut : Cool! I'll give it a try, thank you!

SCiunczyk commented 6 years ago

I'v been using v2.0 for four weeks on my PS3Steel with RUMBA board. Instead of small issue #7999 I have zero problems. I vote YES.

Grogyan commented 6 years ago

We recently had a long weekend where I live, and I had hoped to give the 2.0 a whirl. However it still does not compile, #8010 raised relating to thermocouples

Roxy-3D commented 6 years ago

Especially with AVR compile failures... It would be very good to attach the Configuration.h files. With the configuration.h files, it should be easy to duplicate (and resolve) the failure.

marcio-ao commented 6 years ago

Has anyone gotten the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER to work on the Archim? All I get is garbage on the LCD display.

Roxy-3D commented 6 years ago

How fast is the Archim board? I tried looking it up, but there isn't much information about it. If it is noticeably faster than the other boards, you probably have to mess with the configured delays (to get good quality signals).

marcio-ao commented 6 years ago

This is the board I am using. Not sure how fast it is, but I'll try to find out. The timing delays are a good idea. I had forgotten about that.

https://github.com/ultimachine/Archim/wiki/Archim-v2.0

marcio-ao commented 6 years ago

@Roxy-3D: I have no idea how to tune these delays. However, by trial and error I managed to find these values that seem to work:

define CPU_ST7920_DELAY_1 DELAY_10_NOP; DELAY_5_NOP; DELAY_3_NOP

define CPU_ST7920_DELAY_2 DELAY_10_NOP; DELAY_5_NOP; DELAY_3_NOP

define CPU_ST7920_DELAY_3 DELAY_10_NOP

It's a bit crazy though, since these are much larger than the other values.

Roxy-3D commented 6 years ago

Do you have a logic analyzer? It would be interesting to know the actual length of each of those delays. My guess is the Archim board is very fast. And as a result, you need unusually long delays when talking to the LCD Panel.

marcio-ao commented 6 years ago

@Roxy-3D: On further experimentation, this seems to work most consistently on my board:

  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
  #define CPU_ST7920_DELAY_2 DELAY_20_NOP; DELAY_10_NOP
  #define CPU_ST7920_DELAY_3 DELAY_20_NOP; DELAY_10_NOP

It seems like CPU_ST7920_DELAY_1 should always be zero, because data is read by the LCD on the low to high transition of the SCLK, and CPU_ST7920_DELAY_1 + CPU_ST7920_DELAY_2 must equal CPU_ST7920_DELAY_3 to ensure a balanced SCLK waveform, as can be seen from the following code:

  #define ST7920_SND_BIT \
    WRITE(ST7920_CLK_PIN, LOW);        ST7920_DELAY_1; \
    WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_DELAY_2; \
    WRITE(ST7920_CLK_PIN, HIGH);       ST7920_DELAY_3; \
    val <<= 1

Curiously, this pattern is not followed for any of the other boards. I suspect this code could be simplified to using a single delay and that it likely would work for all the boards this way:

  #define ST7920_HALF_PERIOD_DELAY DELAY_20_NOP; DELAY_10_NOP

  #define ST7920_SND_BIT \
    WRITE(ST7920_CLK_PIN, LOW); \
    WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_HALF_PERIOD_DELAY; \
    WRITE(ST7920_CLK_PIN, HIGH);         ST7920_HALF_PERIOD_DELAY; \
    val <<= 1
marcio-ao commented 6 years ago

Of course, it's a big risk to change it now without testing it out with all the boards, but I suspect that the code as it is written is probably overly complex.

teemuatlut commented 6 years ago

FYI: Archim2 = SAM3X8E = DUE, but with custom UltiMachine core to suit the USB isolator and some other minor things.

AnHardt commented 6 years ago

The facts are http://www.lcd-module.de/eng/pdf/zubehoer/st7920_chinese.pdf page 37-38

AVRs execute not more than 1 assembler instruction per cycle. Most last longer. nop is one cycle. A 16MHz AVR has a cycle time of 1/16MHz = 62.5ns

This loop was specifically made for 16MHz AVRs by compiling with defined optimization settings, disassembling and counting cycles. The naked (without nops) loop is fast enough to violate CLK low pulse length (by a fraction of an instruction), but works for almost all RAMPS REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER combinations when the cables are reasonably short (original length). One nop for ST7920_DELAY_3 was put in by default to fulfill the ST7920s low pulse specifications. Even 20MHz AVRs (50ns) do not need more than one nop to fulfill the datasheet requirements. This loop can't be made faster on 16MHz AVR. That was my target and we (me and @thinkyhead ) reached it. Dot. Due to sloppy made boards, cables, displays some more nops have been introduced for special cases.

But this was never made for 80 and more MHz processors. Here throwing in the datasheet values in exact working delay functions seems to be the simpler way. Ideally they should not wait bussy.

EDIT: Sorry. Wanted to say: This macro is used in an manually unrolled loop.

PS: With 16/20MHz AVRs you can't violate the 40ns times. That is no problem with fast enough prozessors. More delays may be needed.

PPS: Don't touch this loop for 8 bit AVRs. Make your own one.

Roxy-3D commented 6 years ago

We need an RTOS under Marlin on the 32-bit processors! I wonder if there is some other work we can identify that the processor can do while it twiddles its thumbs on these long waits?

Once we get 32-bits truly supported... Maybe we can start kicking around the idea of getting an RTOS in place?

fiveangle commented 6 years ago

We need an RTOS under Marlin on the 32-bit processors! I wonder if there is some other work we can identify that the processor can do while it twiddles its thumbs on these long waits?

Marlin running in the simavr emulator engine sitting on top of an RTOS would do the trick I suppose 🤣

marcio-ao commented 6 years ago

@AnHardt: Ah, actual numbers. I'll have to figure out how close my guesses are to the actual specification.

The refresh performance is fantastic on this board, BTW.

@thinkyhead: I recall you posted in another thread you said you wanted to see an animated Marlin jumping in the logo. I think with these new 32-bit boards we may finally have enough horsepower and memory for something like that! :D

marcio-ao commented 6 years ago

This may be entirely off topic, but I'll throw it out anyway. One of our projects involves evaluating the BeagleBone Black for 3D printing. One of the interesting things about this board is that it uses a Sitara ARM Cortex-A8 with two so called "programmable real-time units". While there is currently 3D printing FW being developed for that board from scratch (Redeem), I've often wondered whether Marlin could be made to run on the PRUs and provide a time-tested solution. This would allow the BeagleBone Black to run Marlin on one of the two PRUs and free the main processing core to run host software. The specs for the processor and PRU are here:

https://www.ti.com/product/am3358

I realize porting Marlin to the PRU would be a huge project, but I'm just curious whether it would be even possible given the specs. Any thoughts? AFAIK, the PRUs are not programmable by the Arduino toolkit, which I suspect would be a big obstacle to actually doing it.

fiveangle commented 6 years ago

AFAIK, the PRUs are not programmable by the Arduino toolkit, which I suspect would be a big obstacle to actually doing it.

Re-ARM boards aren't either, yet some of us have them running Marlin (I'm unfortunately not one of them - still need to tinker with getting it going. Mine at least has a lifeless stepper attached ! ;)

If the PRU is supported by PlatformIO, the build chain is probably not an issue.

marcio-ao commented 6 years ago

@fiveangle: At first glace, I don't see anything on PlatformIO related to PRU, Sitara, or BeagleBone. I hadn't heard of the Re-ARM. I'll read up on it.

dot-bob commented 6 years ago

We need an RTOS under Marlin on the 32-bit processors! I wonder if there is some other work we can identify that the processor can do while it twiddles its thumbs on these long waits?

Once we get 32-bits truly supported... Maybe we can start kicking around the idea of getting an RTOS in place?

FreeRTOS would be a good candidate for this. Low memory footprint and most if not all microcontrollers currently used with Marlin 2.0 already have a port to it (I think even the atmega).

Roxy-3D commented 6 years ago

Yes, in previous discussions, FreeRTOS always was suggested as a possibility. If we were to put an RTOS under Marlin, one of the first things to do is have a separate (low priority) process to update the LCD Panels.

Another easy substitution would be to have a small process that did the A to D conversion for the various temperatures and put those values some where they can be accessed with no delays. Right now the code doing A to D conversions has to kick off the start of the conversion in one place, and then check if it is done in another place. That works, but it makes for complicated code.

alex-gh commented 6 years ago

Another possibility would be to put the important code in interrupts and use the ARM NVIC as a kind of a preemptive scheduler.

Non critical code can run in the main loop where it can busy loop all it wants.

AnHardt commented 6 years ago

Thinking about REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and the 32 bit processors.

In addition to what i saied in https://github.com/MarlinFirmware/Marlin/issues/7951#issuecomment-339148175 . The better idea, then tuning U8GLIB_ST7920_128X64_RRD for each ot the 32biters, would be to use one of the stock u8glib devices here: https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/Marlin/src/lcd/ultralcd_impl_DOGM.h#L166-L170 @olikraus already did all the work. U8GLIB_ST7920_128X64_RRD was made in a time where u8glib had only a 8 strip device, to get a bit more speed for the 8bit AVRs.

#elif ENABLED(U8GLIB_ST7920)
  #if defined(__AVR__)
    //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes
                                                                              // No 4 stripe device available from u8glib.
    //U8GLIB_ST7920_128X64_1X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 8 stripes
    U8GLIB_ST7920_128X64_RRD u8g(0); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT
  #else
    U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS);  // Original u8glib device. 2 stripes
                                                                             // No 4 stripe device available from u8glib.
    //U8GLIB_ST7920_128X64_1X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS);// Original u8glib 
  #endif
#elif ENABLED(CARTESIO_UI)

More stock devices are available for example when connected to hardware SPI. https://github.com/olikraus/u8glib/wiki/device#st7920-128x64

victorpv commented 6 years ago

@thinkyhead I just noticed this discussion. The STM32F1 HAL is going pretty well. We have the steppers, ADC, FETs, SDCard working. Still need to work on the LCD part, but I think the same drivers will likely work across all 32 bit platforms. I believe some trianic code may be also specific for AVR. I would think if the AVR has not broken, may be good to release 2.0 already, and we keep working on the HALs. That way you don't have to keep pushing fixes to 2 different code bases.

Roxy-3D commented 6 years ago

If we were going to do that... My vote would be we modify that position a little bit. Let's stop pushing any changes to either branch for a week or two. No new code. And lets just fix the random bugs that show up. That at least lets the code stabilize and get hardened before we bless it with a v2.0.0 label.

And... it accomplishes the goal of not doing big complicated Pull Requests to two branches.

psavva commented 6 years ago

@thinkyhead , need any help closing some of the 660+ issues? I regularly monitor the issues in any case and try help folks whenever I can... I see a lot of the issue should be closed, but the reporter doesn't close it, even after confirming that the issue is resolved...

This should help filter out real issues for a more stable 2.0

Roxy-3D commented 6 years ago

psavva, for any serious issue in 32-bit land, #7076 has the current state of the world. Maybe we should have a similar thread that just has current issues that should be resolved for the 1.1.x freeze and the switch to v2.0.0 ? I am very interested in how the Marlin community wants that to happen.

If you start a check list of things that we should have resolved or at least discussed... I have one or two bug fix items to start the check off with.

locutus40 commented 6 years ago

I know i might get screamed at or shunned for asking this but the 2.0 when released.. whats a good board a 32 bit board that will work with it that can use the mks touch screen?

awaiting the omg you cant post that here lol

psavva commented 6 years ago

Do you really need to wait for some official release? Go rogue and use the bugfix version :)

On Sun, 25 Feb 2018, 8:47 AM Ed, notifications@github.com wrote:

I know i might get screamed at or shunned for asking this but the 2.0 when released.. whats a good board a 32 bit board that will work with it that can use the mks touch screen?

awaiting the omg you cant post that here lol

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/MarlinFirmware/Marlin/issues/7951#issuecomment-368287871, or mute the thread https://github.com/notifications/unsubscribe-auth/ABYypmHv7qW5g11yGTwLQcoDD1HpSZ0sks5tYQIDgaJpZM4P3B7Y .

thinkyhead commented 6 years ago

@locutus40 — Follow #7076