[
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributors' Guide\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. But it is\nalso important to follow the best practices so that there is no confusion.\n\n## Some Resources\n\nFor beginners, who are starting out with their first contributions, it might seem a bit tricky to work with **GitHub**, especially if you have no previous knowledge of **_Git_**.\n\nSo, here are a couple of resources to help you refresh / get started:\n\n1. [Git Cheatsheet](https://education.github.com/git-cheat-sheet-education.pdf)\n2. [GitHub Learning Lab](https://lab.github.com/githubtraining/introduction-to-github)\n3. [ZBunker's Complete Git Tutorial](https://https://youtube.com/playlist?list=PLbsliZj8JocK6vYXvm4Yn2ftfvxGgutQV) _(recommended if you are willing to devote some time)_\n\n## Programming Language\n\nYouTubeBot relies on Python as its core language. So, inorder to make contributions, you are expected to know the basics of Python. [Here](https://www.youtube.com/playlist?list=PLbsliZj8JocIez5TvsbMaVKgF-sxoal0C) is a great playlist to start with.\n\n## Non Technincal? No Problem\n\nYouTubeBot is evolving at a very fast rate. So many changes are being made to make it adaptive and upto date. This means, we change/update our documentations very often. Keeping a proper and neat documentation is what we are after. For those contributing towards documentation, knowing **Markdown** will be of great help.\n\nHere are some resources for you to get started:\n\n1. [Markdown Guide](https://www.markdownguide.org/basic-syntax/)\n2. [Markdown Lab](https://www.markdowntutorial.com/)\n\n## GitHub Workflow\n\nYou are free to choose your style of workflow as far as you are not making a PR from the main branch of your fork. This is not recommended and would create some problems while syncing your fork with the upstream repository.\n\nFor beginners, here's what you'd have to do:\n\n1. Fork the Project\n2. Clone your fork to your local machine via\n\n```\ngit clone https://github.com/YOUR_USERNAME/YoutubeBot.git\n```\n\n3. Create a branch in your local machine:\n\n```\ngit checkout -b <YOUR_BRANCH_NAME>\n```\n\n4. Make changes/commits to this branch\n\n```\ngit commit -m \"SOME_USEFUL_MSG_WITH_ISSUE_CODE\"\n```\n\n5. Push changes to your fork:\n\n```\ngit push origin <YOUR_BRANCH_NAME>\n```\n\n6. Create a PR from your fork to YouTubeBot main branch\n\n## Commit Ettiquette\n\nWe love our commits to look similar and homogeneous. We recently started following **_conventionalcommits_** guidelines to craft our commit messages. You too can follow this guide at <https://www.conventionalcommits.org/>\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## What does this PR do?\n\n<!-- Provide a description of what this PR does. -->\n\n## Test Plan\n\n<!-- Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. -->\n\n## Related PRs and Issues\n\n<!-- If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here. -->\n\n### Have you read the [Contributing Guidelines on issues](https://github.com/CYBERDEVILZ/YoutubeBot/blob/main/.github/CONTRIBUTING.md)?\n\n<!-- Write your answer here. -->"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n-   repo: https://github.com/python/black\n    rev: 21.7b0\n    hooks:\n    - id: black\n\n    repo: https://github.com/Yelp/detect-secrets\n    rev: v1.1.0\n    hooks:\n    - id: detect-secrets\n        \n    name: Detect secrets\n    description: Detects high entropy strings that are likely to be passwords.\n    entry: detect-secrets-hook\n    language: python\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# YouTubeBot Contributors' Guide\r\n\r\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are _greatly appreciated_. But it is\r\nalso important to follow the best practices so that there is no confusion.\r\n\r\n## Some Resources\r\n\r\nFor beginners, who are starting out with their first contributions, it might seem a bit tricky to work with *GitHub, especially if you have no previous knowledge of *Git\\*\\*.\r\n\r\nSo, here are a couple of resources to help you refresh / get started:\r\n\r\n1. [Git Cheatsheet](https://education.github.com/git-cheat-sheet-education.pdf)\r\n2. [GitHub Learning Lab](https://lab.github.com/githubtraining/introduction-to-github)\r\n\r\n## Programming Language\r\n\r\nYouTubeBot relies on Python as its core language. So, inorder to make contributions, you are expected to know the basics of Python. [Here](https://www.youtube.com/playlist?list=PLbsliZj8JocIez5TvsbMaVKgF-sxoal0C) is a great playlist to start with.\r\n\r\n## Non Technincal? No Problemo\r\n\r\nYouTubeBot is evolving at a very fast rate. So many changes are being made to make it adaptive and upto date. This means, we change/update our documentations very often. Keeping a proper and neat documentation is what we are after. For those contributing towards documentation, knowing _Markdown_ will be of great help.\r\n\r\nHere are some resources for you to get started:\r\n\r\n1. [Markdown Guide](https://www.markdownguide.org/basic-syntax/)\r\n2. [Markdown Lab](https://www.markdowntutorial.com/)\r\n\r\n## GitHub Workflow\r\n\r\nYou are free to choose your style of workflow as far as you are not making a PR from the main branch of your fork. This is not recommended and would create some problems while syncing your fork with the upstream repository.\r\n\r\nFor beginners, here's what you'd have to do:\r\n\r\n1. Fork the Project\r\n2. Clone your fork to your local machine via `git clone https://github.com/YOUR_USERNAME/YouTubeBot.git`\r\n3. Create a branch in your local machine: `git checkout -b <branchname>`\r\n4. Make changes/commits to this branch\r\n5. Push changes to your fork: `git push origin <branchname>`\r\n6. Open a PR from your fork to YouTubeBot main branch\r\n\r\n## Commit Ettiquette\r\n\r\nWe love our commits to look similar and homogeneous. We recently started following **conventionalcommits** guidelines to craft our commit messages. You too can follow this guide at <https://www.conventionalcommits.org/>\r\n"
  },
  {
    "path": "Chrome/README.md",
    "content": "\n# :warning: Driver must be in PATH\nMake sure that your driver must be included in **PATH** or else the script will fail to run.\n## Must have chrome version 94\nIf not, then delete the file named chromedriver.exe and download the apt chrome driver from https://sites.google.com/chromium.org/driver/downloads?authuser=0. Then add the driver to **PATH**\n"
  },
  {
    "path": "Chrome/YouTubeBot.py",
    "content": "import tkinter as tk\nimport tkinter.ttk as ttk\nfrom PIL import Image, ImageTk\nfrom selenium import webdriver\nimport time\nimport pyautogui\n\nheight = pyautogui.size()[1]\nwidth = pyautogui.size()[0]\nprint(\"resolution = \" + str(width) + \", \" + str(height))\nwindow  = tk.Tk()\nwindow.title(\"YouTube Bot\")\nwindow.resizable(0,0)\nwindow.configure(background=\"white\")\nwindow.rowconfigure([0], minsize=round(width/96), weight=0)\nwindow.columnconfigure([0,2], minsize=round(width/24), weight=0)\nwindow.columnconfigure(1, minsize=round(width/2.13), weight=0)\n\ndef fetch(x):\n    import requests as r\n    res = r.get(f\"https://img.youtube.com/vi/{x}/maxresdefault.jpg\")\n    with open(\"./images/image1.jpg\", \"wb\") as f:\n        f.write(res.content)\n\ndef filter():\n    x = url_input.get().strip().split(\"=\")[1].strip().split(\"&\")[0]\n    if x == \"\":\n        print(\"Can't find image\")\n        return\n    else:\n        try:\n            fetch(x)\n            global img0\n            img0 = Image.open(\"./images/image1.jpg\")\n            img0 = img0.resize((round(img0.size[0]*0.7*width/1920), round(img0.size[1]*0.7*width/1920)))\n            print(\"thumbnail size -> \" + str(img0.size[0]) + \", \" + str(img0.size[1]))\n            img0 = ImageTk.PhotoImage(img0)\n            thumbnail_frm.configure(image=img0)\n        except:\n            print(\"Permission error: writing to a file\")\n            return\n\ndef duration_split(duration):\n    hour = 0\n    min = 0\n    sec = 0\n    list = duration.split(\":\")\n    hour = int(list[0])\n    min = int(list[1])\n    sec = int(list[2])\n    return hour*3600 + min*60 + sec\n\n\ndef start():\n    dur = dur_entry.get()\n    loop = loop_entry.get()\n\n    if len(dur.split(\":\")) == 3:\n        dur = duration_split(dur)\n    else:\n        return\n    if loop == \"\":\n        return\n    else:\n        if loop.lower() == \"inf\":\n            loop = 999999999\n        else:\n            try:\n                loop = int(loop)\n            except:\n                return\n\n    while loop:\n        driver = webdriver.Chrome()\n        driver.get(url_input.get().strip())\n        plybtn = driver.find_element_by_class_name(\"ytp-play-button\")\n        time.sleep(3)\n        # ---> If the video doesnt start playing within three seconds of opening, then disable this  <--- #\n        plybtn.click()                      \n        time.sleep(dur)\n        driver.close()\n        loop -= 1\n    \n# ---> IMAGES <--- #\nimg0 = Image.open(\"./images/image.jpg\")\nimg0 = img0.resize((round(img0.size[0]*0.7*width/1920), round(img0.size[1]*0.7*width/1920)))\nprint(\"img0 size -> \" + str(img0.size[0]) + \", \" + str(img0.size[1]))\nimg0 = ImageTk.PhotoImage(img0)\nimg1 = Image.open(\"./images/youtubebot.png\")\nimg1 = img1.resize((round(img1.size[0]*0.5*width/1920), round(img1.size[1]*0.5*width/1920)))\nprint(\"img1 size -> \" + str(img1.size[0]) + \", \" + str(img1.size[1]))\nimg1 = ImageTk.PhotoImage(img1)\n\n# ---> TITLE OF THE GUI <--- #\ntitle = tk.Label(master=window, image=img1, font=(\"\", 40), bg=\"white\")\ntitle.grid(row=0, column=0, sticky=\"nsew\", pady=5, columnspan=3)\n\n# ---> DESCRIPTION <--- #\ndesc = tk.Label(master=window, text = \"Increase the number of views on any YouTube video.\", font=(\"aNYTHING\", 25), bg=\"white\")\ndesc.grid(row=1, column=0, pady=(5,30), columnspan=3)\n\n# ---> URL INPUT <--- #\nurl_label = tk.Label(master=window, text=\"URL of the Youtube Video \", font=(\"\", 15), bg=\"white\")\nurl_label.grid(row=2, column=0, padx=(15, 5), pady=(0, 5))\nurl_input = ttk.Entry(master=window, font=(\"\", 15))\nurl_input.grid(row=2, column=1, sticky=\"ew\", pady=(0, 5))\n# ---> SUBMIT BUTTON <--- #\nstyle = ttk.Style()\nstyle.configure(\"TButton\", font=(\"\", 15))\nurl_btn = ttk.Button(style='TButton', master=window, text=\"Submit\", command = filter)\nurl_btn.grid(row=2, column=2, padx=(3, 15), pady=(0, 5))\n\n# ---> YOUTUBE THUMBNAIL FRAME <--- #\nthumbnail_frm = tk.Label(master=window, image=img0, bg=\"red\")\nthumbnail_frm.grid(row=3, column=0, columnspan=3)\n\n# ---> BOTTOM FRAME <--- #\ndur_loop_frm = tk.Frame(master=window, bg=\"white\")\ndur_loop_frm.grid(row=4, column=0, columnspan=3, sticky=\"nsew\")\n# dur_loop_frm.columnconfigure([0], minsize=430, weight=1)\n# dur_loop_frm.columnconfigure([1], minsize=425, weight=1)\n# dur_loop_frm.columnconfigure(2, minsize=40, weight=1)\n# ---> DURATION <--- #\ndur_lbl = tk.Label(master=dur_loop_frm, text=\"Duration (hour:min:sec) \", font=(\"\", 15), bg=\"white\")\ndur_lbl.pack(side=\"left\", pady=10, padx=(15,3))\ndur_entry = ttk.Entry(master=dur_loop_frm, font=(\"\", 15))\ndur_entry.pack(side=\"left\")\n# ---> LOOP <--- #\nloop_lbl = tk.Label(master=dur_loop_frm, text=\"Loops (inf for infinity) \", font=(\"\", 15), bg=\"white\")\nloop_lbl.pack(side=\"left\", pady=10, padx=(15,3))\nloop_entry = ttk.Entry(master=dur_loop_frm, font=(\"\", 15))\nloop_entry.pack(side=\"left\")\n# ---> START BUTTON <--- #\ndur_loop_btn = ttk.Button(style = \"TButton\", master=dur_loop_frm, text=\"Start\", command=start)\ndur_loop_btn.pack(side=\"right\", padx=15)\n\nwindow.mainloop()"
  },
  {
    "path": "Firefox/README.md",
    "content": "# :warning: Driver must be in PATH\nMake sure that your driver must be included in **PATH** or else the script will fail to run. I have provided the Web Driver for FireFox (geckodriver.exe). Just add it to the **PATH** and Bob's your uncle.\n"
  },
  {
    "path": "Firefox/YouTubeBot.py",
    "content": "import tkinter as tk\r\nimport tkinter.ttk as ttk\r\nfrom PIL import Image, ImageTk\r\nfrom selenium import webdriver\r\nimport time\r\nimport pyautogui\r\n\r\nheight = pyautogui.size()[1]\r\nwidth = pyautogui.size()[0]\r\nprint(\"resolution = \" + str(width) + \", \" + str(height))\r\nwindow = tk.Tk()\r\nwindow.title(\"YouTube Bot\")\r\n\r\nwindow.resizable(0, 0)\r\nwindow.configure(background=\"white\")\r\nwindow.rowconfigure([0], minsize=round(width / 96), weight=0)\r\nwindow.columnconfigure([0, 2], minsize=round(width / 24), weight=0)\r\nwindow.columnconfigure(1, minsize=round(width / 2.13), weight=0)\r\n\r\n\r\ndef fetch(x):\r\n    import requests as r\r\n\r\n    res = r.get(f\"https://img.youtube.com/vi/{x}/maxresdefault.jpg\")\r\n    with open(\"./images/image1.jpg\", \"wb\") as f:\r\n        f.write(res.content)\r\n\r\n\r\ndef filter():\r\n    x = url_input.get().strip().split(\"=\")[1].strip().split(\"&\")[0]\r\n    if x == \"\":\r\n        print(\"Can't find image\")\r\n        return\r\n    else:\r\n        try:\r\n            fetch(x)\r\n            global img0\r\n            img0 = Image.open(\"./images/image1.jpg\")\r\n            img0 = img0.resize(\r\n                (\r\n                    round(img0.size[0] * 0.7 * width / 1920),\r\n                    round(img0.size[1] * 0.7 * width / 1920),\r\n                )\r\n            )\r\n            print(\"thumbnail size -> \" + str(img0.size[0]) + \", \" + str(img0.size[1]))\r\n            img0 = ImageTk.PhotoImage(img0)\r\n            thumbnail_frm.configure(image=img0)\r\n        except:\r\n            print(\"Permission error: writing to a file\")\r\n            return\r\n\r\n\r\ndef duration_split(duration):\r\n    hour = 0\r\n    min = 0\r\n    sec = 0\r\n    list = duration.split(\":\")\r\n    hour = int(list[0])\r\n    min = int(list[1])\r\n    sec = int(list[2])\r\n    return hour * 3600 + min * 60 + sec\r\n\r\n\r\ndef start():\r\n    dur = dur_entry.get()\r\n    loop = loop_entry.get()\r\n\r\n    if len(dur.split(\":\")) == 3:\r\n        dur = duration_split(dur)\r\n    else:\r\n        return\r\n    if loop == \"\":\r\n        return\r\n    else:\r\n        if loop.lower() == \"inf\":\r\n            loop = 999999999\r\n        else:\r\n            try:\r\n                loop = int(loop)\r\n            except:\r\n                return\r\n\r\n    while loop:\r\n        driver = webdriver.Firefox()\r\n        driver.get(url_input.get().strip())\r\n        plybtn = driver.find_element_by_class_name(\"ytp-play-button\")\r\n        time.sleep(3)\r\n        # ---> If the video doesnt start playing within three seconds of opening, then disable this  <--- #\r\n        plybtn.click()\r\n        time.sleep(dur)\r\n        driver.close()\r\n        loop -= 1\r\n\r\n\r\n# ---> IMAGES <--- #\r\nimg0 = Image.open(\"./images/image.jpg\")\r\nimg0 = img0.resize(\r\n    (round(img0.size[0] * 0.7 * width / 1920), round(img0.size[1] * 0.7 * width / 1920))\r\n)\r\nprint(\"img0 size -> \" + str(img0.size[0]) + \", \" + str(img0.size[1]))\r\nimg0 = ImageTk.PhotoImage(img0)\r\nimg1 = Image.open(\"./images/youtubebot.png\")\r\nimg1 = img1.resize(\r\n    (round(img1.size[0] * 0.5 * width / 1920), round(img1.size[1] * 0.5 * width / 1920))\r\n)\r\nprint(\"img1 size -> \" + str(img1.size[0]) + \", \" + str(img1.size[1]))\r\nimg1 = ImageTk.PhotoImage(img1)\r\n\r\n# ---> TITLE OF THE GUI <--- #\r\ntitle = tk.Label(master=window, image=img1, font=(\"\", 40), bg=\"white\")\r\ntitle.grid(row=0, column=0, sticky=\"nsew\", pady=5, columnspan=3)\r\n\r\n# ---> DESCRIPTION <--- #\r\ndesc = tk.Label(\r\n    master=window,\r\n    text=\"Increase the number of views on any YouTube video.\",\r\n    font=(\"aNYTHING\", 25),\r\n    bg=\"white\",\r\n)\r\ndesc.grid(row=1, column=0, pady=(5, 30), columnspan=3)\r\n\r\n# ---> URL INPUT <--- #\r\nurl_label = tk.Label(\r\n    master=window, text=\"URL of the Youtube Video \", font=(\"\", 15), bg=\"white\"\r\n)\r\nurl_label.grid(row=2, column=0, padx=(15, 5), pady=(0, 5))\r\nurl_input = ttk.Entry(master=window, font=(\"\", 15))\r\nurl_input.grid(row=2, column=1, sticky=\"ew\", pady=(0, 5))\r\n# ---> SUBMIT BUTTON <--- #\r\nstyle = ttk.Style()\r\nstyle.configure(\"TButton\", font=(\"\", 15))\r\nurl_btn = ttk.Button(style=\"TButton\", master=window, text=\"Submit\", command=filter)\r\nurl_btn.grid(row=2, column=2, padx=(3, 15), pady=(0, 5))\r\n\r\n# ---> YOUTUBE THUMBNAIL FRAME <--- #\r\nthumbnail_frm = tk.Label(master=window, image=img0, bg=\"red\")\r\nthumbnail_frm.grid(row=3, column=0, columnspan=3)\r\n\r\n# ---> BOTTOM FRAME <--- #\r\ndur_loop_frm = tk.Frame(master=window, bg=\"white\")\r\ndur_loop_frm.grid(row=4, column=0, columnspan=3, sticky=\"nsew\")\r\n# ---> DURATION <--- #\r\ndur_lbl = tk.Label(\r\n    master=dur_loop_frm, text=\"Duration (hour:min:sec) \", font=(\"\", 15), bg=\"white\"\r\n)\r\ndur_lbl.pack(side=\"left\", pady=10, padx=(15, 3))\r\ndur_entry = ttk.Entry(master=dur_loop_frm, font=(\"\", 15))\r\ndur_entry.pack(side=\"left\")\r\n# ---> LOOP <--- #\r\nloop_lbl = tk.Label(\r\n    master=dur_loop_frm, text=\"Loops (inf for infinity) \", font=(\"\", 15), bg=\"white\"\r\n)\r\nloop_lbl.pack(side=\"left\", pady=10, padx=(15, 3))\r\nloop_entry = ttk.Entry(master=dur_loop_frm, font=(\"\", 15))\r\nloop_entry.pack(side=\"left\")\r\n# ---> START BUTTON <--- #\r\ndur_loop_btn = ttk.Button(\r\n    style=\"TButton\", master=dur_loop_frm, text=\"Start\", command=start\r\n)\r\ndur_loop_btn.pack(side=\"right\", padx=15)\r\n\r\nwindow.mainloop()\r\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2021 CYBERDEVILZ - YoutubeBot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# YouTube Bot\n\n![License](https://img.shields.io/badge/LICENSE-MIT-brightgreen)\n![Issues](https://img.shields.io/github/issues/CYBERDEVILZ/YoutubeBot)\n![Stars](https://img.shields.io/github/stars/CYBERDEVILZ/YoutubeBot)\n![Contributors](https://img.shields.io/github/contributors/CYBERDEVILZ/YoutubeBot)\n![Forks](https://img.shields.io/github/forks/CYBERDEVILZ/YoutubeBot)\n\n## Increase views on your videos\n\n<kbd>![image](https://user-images.githubusercontent.com/55954313/135300836-7b827ab9-7c99-4f17-9191-60deed6c5c74.png)</kbd>\n\nYouTube Bot is an easy to use simple python script that makes use of selenium to automate the process of increasing views on your Youtube Videos.\n\n## Requirements\n\n* Any of the python3 versions may work for you, but we highly recommend using python 3.7+\n* Web Browser (Chrome or Firefox)\n* Drivers for their respective broswsers.\n  \n  We have included the drivers for the browsers in their respective folders. To get further info about drivers, or have any issues , kindly refer to the README.md files in those folders.\n\n## Installation and Setup\n\n- Make sure you have Python3 installed in your system.\n- Then install the necessary libraries and modules by typing `pip install -r requirements.txt`\n- Download the apt Web Drivers (I have already included the drivers, so no need to worry).\n- Add the drivers to the path and you are done!!\n\n## Usage\n- Add the URL of your YouTube video and hit Submit.\n- Add the duration (specify how much time the script should \"watch\" your video. Format is HH:MM:SS)\n- Add the number of times you want to execute the script (mention inf for infinite).\n- Finally click on the start button to execute it.\n  \n## Contribution\nIf you are a contributor and willing to contribute to our project. You are highly welcome to do that. Here are the few things you have to keep in mind while doing a contribution.\n- Make sure, you read the [Contributing Guidelines](https://github.com/CYBERDEVILZ/YoutubeBot/blob/main/.github/CONTRIBUTING.md) before starting with contributions.\n- Follow the coding conventions and best practices while making changes to the code.\n- Make use of the ISSUE and PULL_REQUEST templates in the [.github](https://github.com/CYBERDEVILZ/YoutubeBot/blob/main/.github/) folder.\n  \n<br>\n\nThanks for using our YouTube Bot!\n"
  },
  {
    "path": "requirements.txt",
    "content": "requests==2.26.0\nselenium==3.141.0\nPyAutoGUI==0.9.53\nPillow==9.0.1\nblack==21.7b0\npre-commit==2.15.0"
  }
]