teleren/devto huggingface dataset:
How to manage multiple Java JDK versions on macOS X
Tags: java, webdev
Published: 2020-04-16 10:11:05

---
title: How to manage multiple Java JDK versions on macOS X
published: true
date: Thu, 16 Apr 2020 10:10:13 GMT
tags: java, webdev
canonical_url: https://notiz.dev/blog/how-to-manage-multiple-java-versions-on-mac
---

Here is a quick tip on how to install multiple [Java JDK](https://www.oracle.com/java/technologies/javase-downloads.html#javasejdk) versions (8, …, 11, …, 14 etc.) on macOS X and how to switch between them for your applications.

## Installing Java JDK via Homebrew

Install multiple Java JDK versions using [Homebrew](https://brew.sh/). To install Homebrew run:

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

Now install the Java JDK version **11** or above using `brew cask`:

```bash
brew cask install java<version>

# latest version
brew cask install java

# LTS 11
brew cask install java11
```

> **Note** JDK versions prior **11** ( **8** , **9** and **10** ) are no longer supported.

[AdoptOpenJDK](https://adoptopenjdk.net/) provides older Java versions. To install the Java JDKs from AdoptOpenJDK:

```bash
# install from third party repository
brew tap adoptopenjdk/openjdk

brew cask install adoptopenjdk<version>

# Java 8
brew cask install adoptopenjdk8

# Java 9
brew cask install adoptopenjdk9

# Java 10
brew cask install adoptopenjdk10
```

## Switch Java JDK via alias

Setup your `JAVA_HOME` path in your `.zshrc` or `.bash_profile` for your primary Java version and add an export for each installed Java version.

```bash
export JAVA_HOME=$(/usr/libexec/java_home -v14)

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_14_HOME=$(/usr/libexec/java_home -v14)
```

To check the default Java version and installation path:

```bash
java -version # 14
```

Add an alias to your `.zshrc` or `.bash_profile` for each installed Java version. The alias exports `JAVA_HOME` with the selected `JAVA_VERSION_HOME`.

```bash
alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java14='export JAVA_HOME=$JAVA_14_HOME'
```

Now, to switch between the Java versions, enter an alias `java8` in your terminal. Execute `java -version` to verify that you are now using the correct Java version.

> **Note** : Alias **only** changes the Java version in the used terminal instance
En quoi Scrumban est une bonne pratique ?
Tags: agile, scrumban, scrum, kanban
Published: 2020-04-16 09:56:50

## Scrumban : qu'est-ce que c'est ?

Utiliser le _framework_ agile Scrumban permet de bénéficier à la fois des itérations Scrum et du concept des flux tirés du Kanban.

Grâce à Scrumban, l'équipe va pouvoir bénéficier des **rôles** Scrum :

- _Product Owner_
- Equipe de développement
- _Scrum Master_
- Parties prenantes

Et des **cérémonies** Scrum :

- _Sprint Planning_
- _Daily scrum_
- _Product Backlog Refinement_
- _Sprint Review_
- _Sprint Retrospective_

En revanche, en Scrumban, on va abandonner le fonctionnement en flux poussé pour adopter un fonctionnement en flux tiré. Plus clairement, l'équipe ne prévoit plus son travail pour 2 ou 3 semaines (selon la longueur du sprint) mais priorise le travail au fur et à mesure.

## Quel impact sur les cérémonies Scrum ?

Sur la plupart des cérémonies Scrum, ce _framework_ n'a pas d'impact. En revanche, le _Sprint Planning_ est effectué différemment.
En effet, au lieu de planifier la totalité des items pour le sprint, le planning va se concentrer à définir un objectif de sprint.

## Et sur le déroulé du sprint ?

Chaque item est proposé par ordre de priorité à l'équipe de développement lorsqu'il est prêt. Dès qu'un item est développé et prêt à aller en test, l'équipe de développement en prend un nouveau dans l'ordre de priorité.

## Quels indicateurs en Scrumban ?

En Scrumban, l'équipe pourra utiliser les indicateurs liés à Kanban tels que :

- le _lead time_
- le _cycle time_

 Vous trouverez plus d'explications dans cet article : ["_Kanban: Lead Time vs Cycle Time - Details Explained_"](https://kanbanize.com/kanban-resources/kanban-software/kanban-lead-cycle-time).

L'équipe pourra utiliser un tableau Kanban pour suivre son avancement.

## Pourquoi est-ce une bonne pratique ?

La pratique de Scrumban permet aux équipes de bénéficier des avantages de Scrum et du Kanban : elle permet de donner de la souplesse sur une planification qui reste parfois difficile à faire sur 2 ou 3 semaines. Elle peut être une bonne pratique lorsqu'un _backlog_ produit n'est pas suffisamment alimenté pour un sprint, l'équipe peut alors commencer à travailler et le _Product Owner_ continuer à alimenter le _backlog_ produit.

L'usage de Scrum permet à l'équipe de continuer à s'insérer dans une pratique d'amélioration continue et d'avoir un _feedback_ régulier des utilisateurs.

## Conclusion

En conclusion, si vous êtes dans une équipe qui ne peut pas prévoir son travail sur 2 ou 3 semaines (typiquement _data scientists_, équipe de suivi de production, équipe support...) ou si vous avez du mal à stabiliser vos sprints (trop de changements au cours d'un sprint, planning remis en cause...), vous devriez tester le Scrumban !
Day-4 Maximum Consecutive Ones
Tags: python, challenge, beginners
Published: 2020-04-16 09:43:03

---
title: Day-4 Maximum Consecutive Ones
published: true
description: 
tags: #python #challenge #beginners 
---
This problem is a part of LeetCode's Introduction to Data Structure Arrays - 101. This section covers the theoretical concepts related to Arrays first. Followed by problems to solve.

##### Problem Statement
Given a binary array, find the maximum number of consecutive 1s in this array.

```
Input: [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
    The maximum number of consecutive 1s is 3.
```

##### Note:
The input array will only contain 0 and 1.
The length of the input array is a positive integer and will not exceed 10,000

##### Solution Approach:
1. Create a dictionary which would have a count of 1's.
2. As the dictionary has both key, value. We keep incrementing the value of count corresponding to the key. As soon as a 0 is encountered no change is made to the dictionary. Instead, the variable count is again set to 0 and key is incremented by 1.
3. Finally, we have a dictionary where the count of consecutive ones is the value. And, the key just represents the count of windows of consecutive ones.
4. As the value of the maximum element is to be returned in the output. Sort the dictionary based on values in descending order. Return the 0th element.

```
class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        key = 0
        count = 0
        D = dict()
        for x in nums:
            if x:
                D[key] = count + 1
                count += 1
            else:
                count = 0
                key += 1
        if len(D) > 0:
            return sorted(D.values(), reverse=True)[0]
        else:
            return 0
```

##### Learnings:
1. Instead of a dictionary. Set can be used. As we are only concerned about the values.
2. The complexity of storing a value in the dictionary is O(1).
3. Complexity of D.values() is 0(1).



NOTE - 
1. class structure is the default code skeleton on Leetcode. Putting a small function inside of a class is not what I intend to do otherwise.
2. Libraries are purposefully not used. Interest is more in improving problem-solving. Then on calling a built-in method.
Low-code Limits Customization Flexibility: Myth or Reality?
Tags: programming, lowcode, 1c, productivity
Published: 2020-04-16 09:16:45

It’s not controversial to say that low-code has become a trend in the development of turnkey solutions for business. 
However, low-code is not traditionally the first choice for developing systems that handle complex business tasks. One of the main drawbacks associated with low-code development is the limited functionality of applications created. 
Often platforms do not provide an easy way to add custom code.

In this article, we will discuss if a low-code platform could be flexible enough to describe the logic of really sophisticated business processes.

Read more: https://clck.ru/MzcF9
JSX gotcha when conditionally rendering using `&&`
Tags: javascript, react, beginners, webdev
Published: 2020-04-16 09:09:29

There are tons of ways to conditionally render your React components, with one of them being the `&&` operator. For eg:

```
// this will only display MyComponent if displayData is a truthy value
{displayData && <MyComponent data={this.state.data} />}
```
But what if `data` is an array, and you want to make sure `data` isn't empty when rendering `MyComponent`. A common pattern is:

```
{this.state.data.length && <MyComponent data={this.state.data} />}
```

This works fine for the truthy values of `data` like when `data.length` is greater than `0`, but if `data.length` is equal to `0`, this creates problems. Instead of rendering nothing like we intend to do here, the value `0` is rendered. This is because:

```
// returns MyComponent and it is rendered by React.
{true && <MyComponent />}

// returns false and nothing is rendered by React.
{false && <MyComponent />}

// data.length returns 3, which is a truthy value, so MyComponent is rendered.
data = [1, 2, 3];
{data.length && <MyComponent />

// data.length returns 0, which is falsy value and 0 is rendered.
// Which is a problem as want nothing to be rendered.
data = [];
{data.length && <MyComponent />}
```

In the last case, `0` is rendered because unlike `true` or `false`, `0` is an actual valid. You can fix this issue by using a ternary operator whenever you want to conditionally render components by checking for the length of an array or by converting the condition to an expression that returns either `true` or `false`.

```
{data.length ? <MyComponent /> : null}

// or

{data.length > 0 && <MyComponent />}
```

Note this happens with other falsey values that are valid JSX syntax like `NaN` and `-0` too.
Haskell - Boolean Blindness == True
Tags: haskell
Published: 2020-04-16 09:02:53

---
title: Haskell - Boolean Blindness == True
published: true
description: 
tags: haskell
---


What does the title even mean? `True`? for what? Good? Bad? Useful? If it was `False`, would we see any meaning?

Even the state of a light bulb cannot be properly represented by booleans. Would `True` mean the light is on? or would it mean off?

What if the decision on whether Boolean Blindess is bad or good is represented with a sum type
```haskell
data Decision 
  = Bad
  | Good
  deriving Show

makeDecision :: Decision -> Text
makeDecision decision = case decision of
  Bad -> "Boolean blindness is " <> ( show Bad ) <> "!"
  Good -> "Boolean blindess is " <> ( show Good ) <> "!"
```
I think using the sum type gives it meaning. Now we can make a decision about Boolean Blindess.

I lessen confusion in my code by using booleans conservatively.
Bir Disk’i Bağlama (Sıfırdan oluşturulan " EXT4 " olan disk biçimi)
Tags: diskbağlama, ext4, fstab, acikkaynak
Published: 2020-04-16 08:57:11

---
title:  Bir Disk’i Bağlama (Sıfırdan oluşturulan " EXT4 " olan disk biçimi)
published: true
description: 
tags: #diskbağlama #EXT4 #fstab #acikkaynak 
---

**fdisk -l** ile disklerimizi listeliyoruz. Bağlamak istediğimiz diski görüyoruz.. Disk **/dev/sdb** şeklinde.
Sonrasında **df -h** ile kaç disk olduğu, kullanılan ve kalan alan miktara bakıyoruz. Henüz disk bağlama işlemini yapmadığımız için listede
göremiyoruz. (Yapacağımız çalışmanın sonunda diskimizi burada görmüş olacağız.)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4tme1u0mf5fu27986bsq.JPG)

Öncelikle **mkdir disk2** adında bir dizin oluşturalım. (Kök Dizinde)

**sudo fdisk dev/sdb** diyerek karşımıza çıkan alanda **m** yazıp **enter** diyerek kullanacağımız komutların bir listesini görürüz.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aiuabm6upduuzwrhy4vh.JPG)

Daha sonra **n** diyerek **“ add a new partition “** diyerek;
**p** yazarak **primary**'i seçiyoruz. Ardından **partition** olarak **1** diyoruz. **(sdb1 olacak çünkü)** first ve last sector de direk enter diyerek
geçiyoruz. Daha sonra **w** diyip kaydedip çıkıyoruz.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/maazbgzmy5wk22p9vj2o.JPG)

Daha sonra **fdisk dev/sdb** diyerek bu sefer çıkan ekran da aşağıda görüldüğü üzere önce **t** (tür belirleme ) ardından L diyerek karşımıza
çıkan ekrandan **83** ü seçerek **w** (değişlikleri kaydet ve çık ) diyip işlemi sonlandırıyoruz.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ufgzk3rd86npyfq5gyyg.JPG)

Yeni bölümü kullanmadan önce bir dosya sitemi ile biçimlendirmemiz gerekiyor. Aşağıda ki örnekte de görüldüğü üzere birinci diskteki 1 bölümü ext4 dosya sistemi ile biçimlendirdim. 

**mkfs.ext4 /dev/sdb1**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j8d4hq5z8sc0syke07wg.JPG)

Şimdi ise son olarak diskimizi fstab’ a ekliyoruz.
**nano /ets/fstab**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qadqsp7agz1w4pi9av0l.JPG)

Bilgisayarı yeniden başlattıktan sonra yazının başında da belirttiğim üzere **df -h** diyerek diskimizin (disk2) kota durumunu görüyoruz.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g657r74bf78tlz4x9co7.JPG)

[Açık Kaynak Yazılımları]
(https://www.acikkaynak.blog/)
Clonezilla İle Oluşturulmuş Bir İmajı Geri Yükleme  (Disk olarak alınan imaj) 
Tags: clonezilla, imajclonezilla, acikkaynak
Published: 2020-04-16 08:56:47

---
title:Clonezilla İle Oluşturulmuş Bir İmajı Geri Yükleme  (Disk olarak alınan imaj) 
published: true
description: 
tags: #clonezilla #imajclonezilla #acikkaynak #acikkaynak  
---
Clonezilla, acikkaynak yazılımı olan, disk yedeklemek ve geri yüklemek için hazırlanmış, GNU/Linux tabanlı özgür bir yazılımdır.

[Daha Detaylı Bilgi İçin Tıklayınız...]
(https://tr.wikipedia.org/wiki/Clonezilla)

Açılan sisteminizde karşınıza gelen Clonezilla grub ekranından **“Clonezilla Live (Default settings)”** seçeneğini seçiniz.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7v8jpqtzsgafprmo1adr.JPG)

**“Start Clonezilla”** seçeneğini seçiniz. Ve devamında görselde seçili olan alanları seçerek devam ediniz...

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9k2khj3k0juj9qfw63xv.JPG)

Bundan sonra ki aşamada sisteme bağladığımız usb yi listeden seçiniz... Seçtiğimiz disk içeriği listelenecek ve bu liste içerisinde bizim imajımız gözükecek... **İmajı seçiniz ve Enter**'a basınız. **(Benim kendi sistemim de imajım sdc1 diski olarak gözüktüğü için onu seçtim)**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7n4ovf7jq2o5bb34y6a5.JPG)

Beginner diyerek devam ediyoruz...

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4xttj3piuozp54cgcm5m.JPG)

Oluşturduğunuz imajı tüm disk olarak oluşturduğumuz için **“restore disk”** diyoruz.... **( Part olarak imaj almış olsaydık restore part diyecektik.)**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gdwgz02hon9n302t1hqq.JPG)

Sisteminize ait bilgiler içeren ve yüklemek istediğiniz imajın yüklendikten sonra diskinizdeki tüm verilerinizin silineceğini gösteren bu bölümü onaylayarak geçiniz. **( y sonra enter)** 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dbqls8b2v0cry3x323sz.JPG)

Sistem imajı yüklerken aşağıda ki gibi görülmektedir... İmaj yükleme işlemi bittikten sonra **Press “ Enter “ to contiune** kısmı gelecektir. **Enter** diyerek sonra ki adıma geçiniz... ( Kontrol işlemleri için ekran gelirse -scr No, skip ile başlayan seçeneği seçerek es geçebiliriz. Sonra yeniden başlat diyebiliriz....)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/833cczgdeom1zcdfci9i.JPG)


[Açık Kaynak Yazılımları]
(https://www.acikkaynak.blog/clonezilla-ile-olusturulmus-bir-imaji-geri-yukleme/)
Consistent Progress - Twilio Hackathon Update
Tags: devjournal, twiliohackathon, codenewbie, womenintech
Published: 2020-04-16 08:50:43

_This post was originally published on April 16, 2020 on [my blog](https://alexlsalt.github.io/blog)._

Still keepin' on keepin' on with my hackathon project today. Since it's Thursday, I'll also be sending out another Letters from Nelson newsletter.

I'll probably work on getting the newsletter all drafted up first today (to conserve all creative energy and lower the risk of feeling unmotivated to do it later today).

Then, I'll continue on with my Firebase authorization tutorial, which I'll probably finish tomorrow. After I learn how to create and store all new users (yay!!!) I'll add that functionality to my hackathon project. 

To complete it, I'll play around with and add the Twilio API as well as logic specific to the app.

Woooo! I love love love how this is all coming together. Consistently showing up and making incremental progress, that's what it's all about. Cheers!
TetraQuicky07: Ubuntu apt-get key errors
Tags: linux, bash, wsl, ubuntu
Published: 2020-04-16 08:40:11

Every now and then in ubuntu, you might get this error while updating package with apt:

```bash
$ sudo apt update
...
Err:6 https://apt.kitware.com/ubuntu bionic InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 291F9FF6FD385783
```

This might be several causes of this issue. The GPG signature server could have been temporarily down so you can re-force it simply by running:

```bash
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 291F9FF6FD385783
```

Using the same key that is normally causing you trouble (in this instance *291F9FF6FD385783*)

However recently I noticed that in some environment behind a strict proxy rules, and for example also under WSL in Windows, the access to the keyserver.ubuntu.com is actually blocked and cannot be reached.
This, for example, will give you the following error:
```bash
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 291
F9FF6FD385783
Executing: /tmp/apt-key-gpghome.nR1O15nnkM/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys 291F9FF6FD385783
gpg: keyserver receive failed: Server indicated a failure
```

I just discovered that you can use the port 80 for this. So, it is enough to just for something like:
```bash
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv
  291F9FF6FD385783
Executing: /tmp/apt-key-gpghome.prdsQcWrls/gpg.1.sh --keyserver hkp://keyserver.ubuntu.com:80 --recv 291F9FF6FD385783
gpg: key A8E5EF3A02600268: public key "Kitware Apt Archive Automatic Signing Key (2020) <debian@kitware.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
Reading package lists... Done
Building dependency tree
Reading state information... Done
```

And puff the trick is done.

P.S. ... yes use this kitware ppa to have always the latest cmake version available in ubuntu. I highly recommend it.
Dealing with requests on your open-source projects
Tags: discuss, psych, mentalhealth, motivation
Published: 2020-04-16 08:34:05

Hey everyone!

So, I launched a new project about 2-3 weeks ago, and I'm glad to report that it's still catching a lot of stars on GitHub... on one hand, it makes me highly motivated and happy to continue working on the project.

But then, now and again, I receive emails like this:
![Image URL](https://i.imgur.com/aUEjwq7.png)

I am at fault here cause I released a product out in the wild with, albeit, big problems but that's cause I assumed I would learn in the process. It's difficult to keep up the motivation when you hear that you've wasted someone's time or if someone calls your work useless.

I know I might not be alone here, others might have received emails like this too or gotten requests with no acknowledgment on their GitHub Issues. How do you keep going? How do you stay strong to keep supporting the app? 

I know an obvious answer would be just to focus on those who give constructive criticism, as opposed to those who just give feedback like this, but it's not that easy for me to let go.
Getting Started With WSL (Windows Subsystem for Linux )
Tags: wsl
Published: 2020-04-16 08:17:55

# in this article we are going to cover the installation and the usage of WSL
WSL allows you to run a real Linux environement on windows without a virtual machine
Once you have it setup you can open the command line and start working on the file system like you are on Linux, and that's in fact on Linux and windows at the same time , you can be working on your server code on one screen while working on  Adobe Photoshop on the other screen.
##*Note: WSL works only on windows 10*
## So lets get started
* Open PowerShell as an administrator (win + x ) and run the following Commande: 
```bash
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
* Install the Linux distro of your choice , go to Microsoft Store and type **"Linux"** to get the available distros

![Microsoft store](https://docs.microsoft.com/en-us/windows/wsl/media/store.png)

* Once the installation is complete , click on the launch button to initialize your distro
You will be prompt to create a new user account and its password

![Microsoft store](https://docs.microsoft.com/en-us/windows/wsl/media/ubuntuinstall.png)

* Update and upgrade your distro's packages 

```bash
sudo apt update && sudo apt upgrade
```

and that's it ! enjoy using your Linux distro on WSL , you can install all your dev tools like git, nodejs, docker and everything you need

check out the awesome tutorial from [**Fireship youtube channel**] (https://www.youtube.com/watch?v=-atblwgc63E&t=200s)
and the official documentation from [Microsoft](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
Cleaning up Zookeeper Logs and Snapshots
Tags: zookeeper, devops, sre, clickhouse
Published: 2020-04-16 08:17:11

# Problem

Zookeeper’s logs and snapshots are mostly responsible for its high disk usage. If your team makes use of these snapshots for specific purposes, it makes sense to back them up using your tool of preference.

My team uses ClickHouse and it uses Zookeeper for replication. So in our case, we don't need to keep snapshots.

# Solution

To clean up manually, all you have to do is run the cleanup script.

```bash
# Go to wherever zookeeper bin is installed in your server
cd /opt/zookeeper/bin 

# Run the script
./zkCleanup.sh -n 10
```

Where 10 is the number of old snaps/logs you want to keep, the value should be greater than or equal to 3.

Repeat the completed steps to all the Zookeeper replica server.

See the [script](https://github.com/apache/zookeeper/blob/master/bin/zkCleanup.sh) for reference.
چاپ عکس روی تابلو فرش کاشان
Tags: security
Published: 2020-04-16 08:14:22

چاپ عکس روی تابلو فرش کاشان یکی از جدیدترین تکنولوژی های تابلو فرش های ماشینی کاشان می باشد.
قبل تر ها در تابلو فرش های ماشینی تمامی طرح ها بافته می شدند.
بافته شدن طرح ها روی تابلو فرش ها فرایندی زمان بر بوده و علاوه بر این مدت زمان آماده شدن آن زیاد است
از انجا که هر فناوری و پیشرفت جدیدی که در هر زمینه ای ایجاد می شود ابتدا با مخالفت هایی روبرو می شود
ورود صنعت چاپ به فرش ماشینی و تابلو فرش ها نیز ابتدا با مخالفت هایی روبرو شد
اما امروزه تمامی مردم به کیفیت و خصوصیات این گونه از تابلو فرش ها اعتماد پیدا کرده اند
و بسیاری برای هدیه دادن از چاپ عکس روی تابلو فرش کاشان استفاده می کنند.
اما در این نوشته اطلاعات بیشتری درمورد انواع تابلو فرش چاپی در اختیار شما عزیزان قرار می دهیم .
How to download youtube thumbnail. 
Tags: download, youtube, thumbnail
Published: 2020-04-16 08:09:04

How to download youtube thumbnail online

There are lots of websites on the internet, but some websites are not quality content they are not providing good service on these websites lots of ads, redirect, popups, by these users gets irritating, for the solution. There is a new website which provides quality, without ads, popups, or redirects this website is ad-free. The website name is youtubethumbnaildownload.online