main c0c3a2ea5f20 cached
258 files
1.3 MB
379.5k tokens
404 symbols
1 requests
Download .txt
Showing preview only (1,357K chars total). Download the full file or copy to clipboard to get everything.
Repository: Anarios/return-youtube-dislike
Branch: main
Commit: c0c3a2ea5f20
Files: 258
Total size: 1.3 MB

Directory structure:
gitextract_0m063igu/

├── .babelrc
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature-request.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── build.yaml
│       ├── commentcommands.yml
│       └── weblint.yml
├── .gitignore
├── .nvmrc
├── CONTRIBUTING.md
├── CONTRIBUTINGar.md
├── CONTRIBUTINGaz.md
├── CONTRIBUTINGbg.md
├── CONTRIBUTINGcn.md
├── CONTRIBUTINGda.md
├── CONTRIBUTINGde.md
├── CONTRIBUTINGes.md
├── CONTRIBUTINGfr.md
├── CONTRIBUTINGgr.md
├── CONTRIBUTINGhu.md
├── CONTRIBUTINGid.md
├── CONTRIBUTINGja.md
├── CONTRIBUTINGkr.md
├── CONTRIBUTINGnl.md
├── CONTRIBUTINGpl.md
├── CONTRIBUTINGpt_BR.md
├── CONTRIBUTINGru.md
├── CONTRIBUTINGsv.md
├── CONTRIBUTINGtr.md
├── CONTRIBUTINGuk.md
├── CONTRIBUTINGvi.md
├── Docs/
│   ├── FAQ.md
│   ├── FAQar.md
│   ├── FAQaz.md
│   ├── FAQbg.md
│   ├── FAQcn.md
│   ├── FAQde.md
│   ├── FAQfr.md
│   ├── FAQid.md
│   ├── FAQnl.md
│   ├── FAQpl.md
│   ├── FAQpt_BR.md
│   ├── FAQru.md
│   ├── FAQtr.md
│   ├── FAQuk.md
│   ├── FAQvi.md
│   ├── Guide__Installing.md
│   ├── Guide__Installingvi.md
│   ├── Guide__Troubleshooting.md
│   ├── Guide__Troubleshootingvi.md
│   ├── Privacy Policy
│   ├── Privacy Policyvi
│   ├── SECURITY-FAQ.md
│   ├── SECURITY-FAQaz.md
│   ├── SECURITY-FAQbg.md
│   ├── SECURITY-FAQcn.md
│   ├── SECURITY-FAQde.md
│   ├── SECURITY-FAQfr.md
│   ├── SECURITY-FAQid.md
│   ├── SECURITY-FAQnl.md
│   ├── SECURITY-FAQpl.md
│   ├── SECURITY-FAQpt_BR.md
│   ├── SECURITY-FAQru.md
│   ├── SECURITY-FAQtr.md
│   ├── SECURITY-FAQuk.md
│   ├── SECURITY-FAQvi.md
│   ├── SECURITY_FAQar.md
│   ├── readme.md
│   ├── readmeaz.md
│   ├── readmecn.md
│   ├── readmefr.md
│   ├── readmeid.md
│   ├── readmenl.md
│   ├── readmept_BR.md
│   ├── readmetr.md
│   └── readmevi.md
├── Extensions/
│   ├── UserScript/
│   │   └── Return Youtube Dislike.user.js
│   └── combined/
│       ├── _locales/
│       │   ├── az/
│       │   │   └── messages.json
│       │   ├── cs/
│       │   │   └── messages.json
│       │   ├── de/
│       │   │   └── messages.json
│       │   ├── el/
│       │   │   └── messages.json
│       │   ├── en/
│       │   │   └── messages.json
│       │   ├── es/
│       │   │   └── messages.json
│       │   ├── fr/
│       │   │   └── messages.json
│       │   ├── hu/
│       │   │   └── messages.json
│       │   ├── id/
│       │   │   └── messages.json
│       │   ├── it/
│       │   │   └── messages.json
│       │   ├── ja/
│       │   │   └── messages.json
│       │   ├── ko/
│       │   │   └── messages.json
│       │   ├── nl/
│       │   │   └── messages.json
│       │   ├── pl/
│       │   │   └── messages.json
│       │   ├── pt_BR/
│       │   │   └── messages.json
│       │   ├── ru/
│       │   │   └── messages.json
│       │   ├── sv_SE/
│       │   │   └── messages.json
│       │   ├── tr/
│       │   │   └── messages.json
│       │   ├── uk/
│       │   │   └── messages.json
│       │   ├── vi/
│       │   │   └── messages.json
│       │   ├── zh_CN/
│       │   │   └── messages.json
│       │   └── zh_TW/
│       │       └── messages.json
│       ├── changelog/
│       │   ├── 3/
│       │   │   └── changelog_3.0.html
│       │   ├── 4/
│       │   │   ├── changelog.css
│       │   │   └── changelog_4.0.html
│       │   ├── changelog.css
│       │   └── changelog.js
│       ├── content-style.css
│       ├── manifest-chrome.json
│       ├── manifest-firefox.json
│       ├── manifest-safari.json
│       ├── menu-fixer.js
│       ├── popup.css
│       ├── popup.html
│       ├── popup.js
│       ├── readme.md
│       ├── ryd.background.js
│       ├── ryd.changelog.js
│       ├── ryd.content-script.js
│       └── src/
│           ├── bar.js
│           ├── buttons.js
│           ├── changelog/
│           │   └── index.js
│           ├── config.js
│           ├── events.js
│           ├── patreon.js
│           ├── premiumAnalytics/
│           │   ├── activity/
│           │   │   ├── index.js
│           │   │   ├── index.spec.js
│           │   │   ├── time.js
│           │   │   └── time.spec.js
│           │   ├── constants.js
│           │   ├── index.js
│           │   ├── index.spec.js
│           │   ├── lifecycle.js
│           │   ├── lists/
│           │   │   └── index.js
│           │   ├── logging.js
│           │   ├── logging.spec.js
│           │   ├── map/
│           │   │   ├── index.js
│           │   │   └── index.spec.js
│           │   ├── panel.js
│           │   ├── panel.spec.js
│           │   ├── render.js
│           │   ├── requests.js
│           │   ├── state.js
│           │   ├── state.spec.js
│           │   ├── teaser/
│           │   │   ├── index.js
│           │   │   └── index.spec.js
│           │   ├── theme.js
│           │   ├── theme.spec.js
│           │   ├── tierNotice.js
│           │   ├── utils.js
│           │   └── utils.spec.js
│           ├── starRating.js
│           ├── state.js
│           ├── utils.js
│           └── utils.spec.js
├── LICENSE
├── README.md
├── READMEar.md
├── READMEaz.md
├── READMEbg.md
├── READMEcn.md
├── READMEda.md
├── READMEde.md
├── READMEes.md
├── READMEfr.md
├── READMEgr.md
├── READMEhu.md
├── READMEid.md
├── READMEja.md
├── READMEkr.md
├── READMEnl.md
├── READMEpl.md
├── READMEpt_BR.md
├── READMEru.md
├── READMEsv.md
├── READMEtr.md
├── READMEuk.md
├── READMEvi.md
├── Website/
│   ├── .eslintignore
│   ├── .eslintrc.js
│   ├── README.md
│   ├── READMEaz.md
│   ├── READMEbg.md
│   ├── READMEde.md
│   ├── READMEnl.md
│   ├── READMEtr.md
│   ├── READMEvi.md
│   ├── _locales/
│   │   ├── az.ts
│   │   ├── cs.ts
│   │   ├── de.ts
│   │   ├── en.ts
│   │   ├── es.ts
│   │   ├── fr.ts
│   │   ├── hu.ts
│   │   ├── id.ts
│   │   ├── it-IT.ts
│   │   ├── ja.ts
│   │   ├── ko.ts
│   │   ├── nl.ts
│   │   ├── pl.ts
│   │   ├── pt_BR.ts
│   │   ├── ru.ts
│   │   ├── sv.ts
│   │   ├── tr.ts
│   │   ├── uk.ts
│   │   └── vi.ts
│   ├── layouts/
│   │   ├── default.vue
│   │   └── error.vue
│   ├── nuxt.config.js
│   ├── package.json
│   ├── pages/
│   │   ├── debug.vue
│   │   ├── docs/
│   │   │   ├── endpoints.vue
│   │   │   ├── fetching.vue
│   │   │   ├── index.vue
│   │   │   ├── url.vue
│   │   │   └── usage-rights.vue
│   │   ├── docs.vue
│   │   ├── donate.vue
│   │   ├── faq.vue
│   │   ├── help.vue
│   │   ├── index.vue
│   │   ├── install.vue
│   │   ├── links.vue
│   │   └── pay/
│   │       └── crypto.vue
│   ├── raw_assets/
│   │   └── abstract.afdesign
│   └── store/
│       ├── README.md
│       ├── READMEbg.md
│       ├── READMEde.md
│       ├── READMEnl.md
│       ├── READMEtr.md
│       └── READMEvi.md
├── extension-description-store-ar.txt
├── extension-description-store-az.txt
├── extension-description-store-bg.txt
├── extension-description-store-cs.txt
├── extension-description-store-de.txt
├── extension-description-store-el.txt
├── extension-description-store-en.txt
├── extension-description-store-es.txt
├── extension-description-store-fr.txt
├── extension-description-store-hu.txt
├── extension-description-store-id.txt
├── extension-description-store-it.txt
├── extension-description-store-ja.txt
├── extension-description-store-ko.txt
├── extension-description-store-nl.txt
├── extension-description-store-pl.txt
├── extension-description-store-pt_BR.txt
├── extension-description-store-pt_PT.txt
├── extension-description-store-ru.txt
├── extension-description-store-sv_SE.txt
├── extension-description-store-tr.txt
├── extension-description-store-uk.txt
├── extension-description-store-vi.txt
├── extension-description-store-zh_CN.txt
├── extension-description-store-zh_TW.txt
├── jest.config.js
├── package.json
└── webpack.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": ["@babel/preset-env"],
  "plugins": ["rewire"]
}


================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto


================================================
FILE: .github/FUNDING.yml
================================================
patreon: returnyoutubedislike
custom: "https://returnyoutubedislike.com/donate"


================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug Report
description: File a bug report!
# title: "(Bug): "
labels: ["bug"]
body:
  - type: checkboxes
    attributes:
      label: Have you tried to find similar issues (open or recently closed)?
      options:
        - label: "Yes, this issue is not a duplicate"
          required: true
  - type: input
    attributes:
      label: Browser
      description: Which browser are you using?
      placeholder: "Example: Google Chrome"
    validations:
      required: true
  - type: input
    attributes:
      label: Browser Version
      description: Which browser version are you using?
      placeholder: "Example: Chromium v95"
    validations:
      required: true
  - type: dropdown
    attributes:
      label: "Extension or Userscript?"
      options:
        - Extension
        - Userscript
    validations:
      required: true
  - type: input
    attributes:
      label: Extension/Userscript Version
      description: Which extension/userscript version are you using?
      placeholder: "Example: Version 0.0.0.1"
    validations:
      required: true
  - type: input
    attributes:
      label: Video link where you see the problem
      description: Video link where you see the problem
      placeholder: "Example: https://www.youtube.com/watch?v=s4-gMgdsnHQ"
    validations:
      required: true
  - type: textarea
    attributes:
      label: What happened?
      description: Also tell us, what did you expect to happen?
      placeholder: Tell us what you see!
      value: "A bug happened!"
    validations:
      required: true
  - type: textarea
    attributes:
      label: How to reproduce/recreate?
      description: Detailed steps to reproduce/recreate it.
      placeholder: "We need to be able to reproduce/recreate that bug/event in order to fix it. Please write the steps in detail."
      value: "Tell us how it happened with detailed steps for us."
    validations:
      required: true
  - type: dropdown
    attributes:
      label: "Will you be available for follow-up questions to help developers diagnose & fix the issue?"
      options:
        - "Yes"
        - "No"
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: Feature Request
description: Request or suggest a new feature!
# title: "(Feature Request): "
labels: ["enhancement"]
body:
  - type: dropdown
    attributes:
      label: Extension or Userscript?
      options:
        - Extension
        - Userscript
        - Both
    validations:
      required: true
  - type: textarea
    attributes:
      label: Request or suggest a new feature!
      placeholder: I want to suggest...
    validations:
      required: true
  - type: textarea
    attributes:
      label: Ways to implement this!
      placeholder: We can implement it by...
  - type: checkboxes
    attributes:
      label: Can you work on this?
      options:
        - label: "Yes"
        - label: "No"
  - type: dropdown
    attributes:
      label: "Will you be available for follow-up questions to help developers implement this?"
      options:
        - "Yes"
        - "No"
    validations:
      required: true


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
  - package-ecosystem: "npm"
    directory: "/Website"
    schedule:
      interval: "daily"


================================================
FILE: .github/workflows/build.yaml
================================================
name: Test Build Extension

on:
  push:
    branches:
      - main
    paths:
      - Extensions/combined/**
  pull_request:
    branches:
      - main
    paths:
      - Extensions/combined/**

jobs:
  build:
    runs-on: ubuntu-24.04

    defaults:
      run:
        working-directory: ./Extensions/combined

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'

      - name: Install dependencies
        run: npm ci

      - name: Build extension
        run: npm run build

      - name: Upload Chrome artifact
        uses: actions/upload-artifact@v4
        with:
          name: ryd-chrome
          path: ./Extensions/combined/dist/chrome

      - name: Upload Firefox artifact
        uses: actions/upload-artifact@v4
        with:
          name: ryd-firefox
          path: ./Extensions/combined/dist/firefox

      - name: Upload Safari artifact
        uses: actions/upload-artifact@v4
        with:
          name: ryd-safari
          path: ./Extensions/combined/dist/safari


================================================
FILE: .github/workflows/commentcommands.yml
================================================
name: Comment Commands

on:
  issue_comment:
    types: [created]

jobs:
  assign-commenter:
    runs-on: ubuntu-24.04
    if: |
      contains(github.event.comment.body, '/assignme') ||
      contains(github.event.comment.body, '/assign me')
    steps:
      - name: Assigning commenter
        run: |
          curl \
            -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees \
            -d '{"assignees":["${{ github.event.comment.user.login }}"]}'

  request-issue-framing-improvement:
    runs-on: ubuntu-24.04
    if: |
      contains(github.event.comment.body, '/improve') && (
        github.event.comment.author_association == 'OWNER' ||
        github.event.comment.author_association == 'COLLABORATOR' ||
        github.event.comment.author_association == 'CONTRIBUTOR'
      )
    steps:
      - name: Request issue framing improvement
        run: |
          curl \
            -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments \
            -d '{"body":"This issue is put on hold due to low quality. No reviews or fixes will be performed at this time. Eventually, it will be closed. While we appreciate your effort writing, we are not able to further investigate it. Please improve it by writing a better title or providing more details, and you may re-open it."}'

  add-duplicate-label:
    runs-on: ubuntu-24.04
    if: |
      contains(github.event.comment.body, '/duplicate') && (
        github.event.comment.author_association == 'OWNER' ||
        github.event.comment.author_association == 'COLLABORATOR' ||
        github.event.comment.author_association != 'CONTRIBUTOR'
      )
    steps:
      - name: Add duplicate label
        run: |
          curl \
            -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/labels \
            -d '{"labels":["duplicate"]}'


================================================
FILE: .github/workflows/weblint.yml
================================================
# This workflow lints the code in /Website, if any was committed

name: Website Lint

on:
  push:
    branches: 
      - main
    paths:
      - Website/**
  pull_request:
    branches: 
      - main
    paths:
      - Website/**

jobs:
  weblint:
    runs-on: ubuntu-24.04

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install dependencies
        run: npm install
        working-directory: Website

      - name: Run lint
        run: npm run lint
        working-directory: Website


================================================
FILE: .gitignore
================================================
*cert
*Backend
.DS_Store
package-lock.json

# Website node modules and build output
Website/package-lock.json

# AI assistant artifacts
.claude/
CLAUDE.md
Website/.editorconfig
Website/node_modules
Website/.nuxt
Website/dist/
Website/_nuxt

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

node_modules

# Build files
Extensions/combined/bundled-content-script.js

# Dist Files
Extensions/combined/dist/*
package-lock.json
Website/package-lock.json


================================================
FILE: .nvmrc
================================================
v12.18.4

================================================
FILE: CONTRIBUTING.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Welcome To Return YouTube Dislikes contributing guide

Thank you for investing your time in contributing to our project! All your changes will be reflected in the next version of the extension (or the [website](https://www.returnyoutubedislike.com/)).

## Getting Started

Please use Prettier with default settings for formatting.

#### Prerequisites

You need to have node and npm installed to create the bundled version of the source.

Versions used when setting up:

- node: 12.18.4
- npm: 6.14.6

To create the `bundled-content-script.js` that contains most of the business logic of this extension you have to install all dependencies first.

1. Go to the root of the repo and run:

```
npm install
```

2. Run the following command to create `bundled-content-script.js` which is used in `manifest.json`

```
npm start // to create the build file(s) and start a file watcher that hot-reloads on save

// or

npm run build // to create the build file(s) once
```

Congratulations, You are now ready to develop!

If you are new to developing Chrome extensions, or need extra help, please see [this YouTube tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Issues

#### Opening a new issue

If you have any issues with the extension, please search to make sure the issue isn't already reported. If it isn't, open an issue, using the issue form is highly recommended but not mandatory.

#### Solving an issue

If you found an issue that you feel you might be able to solve, don't be shy. Open a PR with the fix and make sure to mention the issue you are fixing.

### Feature Request

#### Opening a new feature request

If you have an idea for the extension, feel free to open a feature request, but please search it before to make sure the feature isn't already suggested. Using the feature form is highly recommended but not mandatory

#### Implementing a feature request

If you found a feature that you feel you might be able to implement, don't be shy. Open a PR with the fix and make sure to mention the feature you are implementing.

### What PRs do we accept?

- Issue fixes.
- Feature implementation.
- Typos or better and easier words to use.
- Website contributions.


================================================
FILE: CONTRIBUTINGar.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# مرحبًا بكم في دليل المساهمة في Return YouTube Dislikes

شكرًا لك على استثمار وقتك في المساهمة في مشروعنا! سيتم عكس جميع تغييراتك في الإصدار التالي من الامتداد (أو [الموقع](https://www.returnyoutubedislike.com/)).

## البدء

يرجى استخدام Prettier بالإعدادات الافتراضية للتنسيق.

#### المتطلبات الأساسية

تحتاج إلى تثبيت node و npm لإنشاء النسخة المجمعة من المصدر.

الإصدارات المستخدمة عند الإعداد:

- node: 12.18.4
- npm: 6.14.6

لإنشاء `bundled-content-script.js` الذي يحتوي على معظم منطق العمل لهذا الامتداد، يجب عليك تثبيت جميع التبعيات أولاً.

1. انتقل إلى جذر المستودع وقم بتشغيل:

```
npm install
```

2. قم بتشغيل الأمر التالي لإنشاء `bundled-content-script.js` الذي يستخدم في `manifest.json`

```
npm start // لإنشاء ملف(ات) البناء وبدء مراقب الملفات الذي يعيد التحميل تلقائيًا عند الحفظ

// أو

npm run build // لإنشاء ملف(ات) البناء مرة واحدة
```

تهانينا، أنت الآن جاهز للتطوير!

إذا كنت جديدًا في تطوير ملحقات Chrome، أو تحتاج إلى مساعدة إضافية، يرجى مشاهدة [هذا الفيديو التعليمي على YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### المشاكل

#### فتح مشكلة جديدة

إذا كانت لديك أي مشاكل مع الامتداد، يرجى البحث للتأكد من أن المشكلة لم يتم الإبلاغ عنها بالفعل. إذا لم تكن كذلك، افتح مشكلة، يوصى بشدة باستخدام نموذج المشكلة ولكنه ليس إلزاميًا.

#### حل مشكلة

إذا وجدت مشكلة تشعر أنك قد تكون قادرًا على حلها، لا تخجل. افتح PR مع الإصلاح وتأكد من ذكر المشكلة التي تقوم بإصلاحها.

### طلب ميزة

#### فتح طلب ميزة جديدة

إذا كانت لديك فكرة للامتداد، لا تتردد في فتح طلب ميزة، ولكن يرجى البحث أولاً للتأكد من أن الميزة لم يتم اقتراحها بالفعل. يوصى بشدة باستخدام نموذج الميزة ولكنه ليس إلزاميًا.

#### تنفيذ طلب ميزة

إذا وجدت ميزة تشعر أنك قد تكون قادرًا على تنفيذها، لا تخجل. افتح PR مع الإصلاح وتأكد من ذكر الميزة التي تقوم بتنفيذها.

### ما PRs التي نقبلها؟

- إصلاحات المشاكل.
- تنفيذ الميزات.
- الأخطاء المطبعية أو الكلمات الأفضل والأسهل للاستخدام.
- مساهمات الموقع.


================================================
FILE: CONTRIBUTINGaz.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# "YouTube Dislike Sayını Geri Qaytar" layihəsinə qatqı qaydalarına Xoş Gəlmisiniz

Layihəmizə qatqı etmək üçün vaxt ayırdığınız üçün təşəkkür edirik! Bütün dəyişiklikləriniz uzantının növbəti versiyasına (və ya [internet saytına](https://www.returnyoutubedislike.com/)) əlavə ediləcəkdir.

## Başlamaq

Formatlama üçün xahiş olunur ki, Prettier-i standart parametrlərdə istifadə edin.

#### Tələblər

Layihənin paketlənmiş versiyasını yaratmaq üçün node və npm quraşdırılmalıdır.

Quraşdırma zamanı istifadə olunan versiyalar:

- node: 12.18.4  
- npm: 6.14.6  

Bu uzantının əsas məntiqini ehtiva edən `bundled-content-script.js` faylını yaratmaq üçün əvvəlcə bütün asılılıqları quraşdırmalısınız.

1. Deponun əsas qovluğuna keçin və aşağıdakı əmri icra edin:

```
npm install
```

2. `manifest.json` içərisində istifadə olunan `bundled-content-script.js` faylını yaratmaq üçün aşağıdakı əmri çalışdırın.

```
npm start // fayl yaradılarkən və saxlanarkən avtomatik yenilənən fayl izləyicisini başlatmaq üçün

// ya da

npm run build // faylları yalnız bir dəfə yaratmaq üçün
```

Təbriklər, artıq inkişaf etməyə hazırsınız!

Chrome uzantılarının inkişafına yeni başlamısınızsa və ya əlavə yardıma ehtiyacınız varsa, lütfən [bu YouTube dərsinə](https://www.youtube.com/watch?v=mdOj6HYE3_0) baxın.

### Issue'lar

#### Yeni bir issue açmaq

Uzantı ilə bağlı hər hansı bir probleminiz varsa, problemin əvvəllər bildirilmədiyindən əmin olmaq üçün axtarış aparın. Əgər daha əvvəl bildirilməyibsə, bir mövzu açın. Problem formunun istifadəsi şiddətlə tövsiyə olunur, lakin məcburi deyil.

#### Bir issue'yu həll etmək

Həll edə biləcəyinizi düşündüyünüz bir problem tapsanız, çəkinmədən çalışın. Problemi həll edən bir PR açın və həll etdiyiniz problemi müəyyənləşdirdiyinizdən əmin olun.

### Xüsusiyyət İstəkləri

#### Yeni bir xüsusiyyət istəyi açmaq

Uzantı haqqında bir ideyanız varsa, yeni bir xüsusiyyət istəyi açmaqdan çəkinməyin, lakin xüsusiyyətin daha əvvəl təklif olunmadığından əmin olmaq üçün axtarış edin. Xüsusiyyət formasının istifadəsi şiddətlə tövsiyə olunur, lakin məcburi deyil.

#### Bir xüsusiyyət istəyini tətbiq etmək

Tətbiq edə biləcəyinizi düşündüyünüz bir xüsusiyyət tapsanız, çəkinmədən çalışın. Xüsusiyyəti tətbiq edən bir PR açın və əlavə etdiyiniz xüsusiyyəti qeyd etdiyinizdən əmin olun.

### Hansı PR növlərini qəbul edirik?

- Problem həlləri.  
- Xüsusiyyət tətbiqləri.  
- Yazı səhvləri və ya daha aydın ifadələr.  
- Sayt qatqıları.
```


================================================
FILE: CONTRIBUTINGbg.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Добре дошли в ръководството за сътрудничество на Return YouTube Dislikes

Благодарим ви, че отделяте време за принос към нашия проект! Всички вашите промени ще се отразят в следващата версия на разширението (или на [уебсайта](https://www.returnyoutubedislike.com/)).

## Започване

Моля, използвайте Prettier с настройките по подразбиране за форматиране.

#### Изисквания

Трябва да имате инсталирани node и npm, за да създадете обединената версия на изходния код.

Използвани версии при настройване:

- node: 12.18.4
- npm: 6.14.6

За да създадете `bundled-content-script.js`, който съдържа повечето от бизнес логиката на това разширение, трябва първо да инсталирате всички зависимости.

1. Отидете в коренната папка на хранилището и изпълнете:

```
npm install
```

2. Изпълнете следната команда, за да създадете `bundled-content-script.js`, който се използва в `manifest.json`

```
npm start // за създаване на файл(ове) за сборка и стартиране на файлов наблюдател, който рестартира автоматично след запазване

// или

npm run build // за създаване на файл(ове) за сборка веднъж
```

Поздравления, вече сте готови за разработка!

Ако сте нов в разработката на разширения за Chrome или ви трябва допълнителна помощ, моля вижте [този урок на YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Проблеми

#### Отваряне на нов проблем

Ако имате проблеми с разширението, моля, направете търсене, за да се уверите, че проблемът вече не е сигнализиран. Ако не е, отворете проблема (issue), използването на формуляра за проблем е настоятелно препоръчително, но не задължително.

#### Решаване на проблем

Ако сте открили проблем, който чувствате, че можете да решите, не бъдете срамежливи. Направете PR с решението и се уверете, че споменавате проблема, който решавате.

### Заявки за функционалности

#### Отваряне на нова заявка за функционалност

Ако имате идея за разширението, не се колебайте да отворите заявка за функционалност, но моля, направете търсене, за да се уверите, че функционалността вече не е предложена. Използването на формуляра за функционалности е настоятелно препоръчително, но не задължително.

#### Изпълнение на заявка за функционалност

Ако сте открили функционалност, която чувствате, че можете да изпълните, не бъдете срамежливи. Отворете PR с решението и се уверете, че споменавате функционалността, която изпълнявате.

### Какви PR-ове приемаме?

- Коригиране на проблеми.
- Изпълнение на функционалности.
- Правописни грешки или по-добри и по-лесни думи за употреба.
- Приноси към уебсайта.


================================================
FILE: CONTRIBUTINGcn.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# 欢迎来到 Return YouTube Dislikes 贡献指南

感谢您花时间为我们的项目做出贡献!您的所有更改都将反映在扩展的下一个版本中(或 [网站](https://www.returnyoutubedislike.com/))。

## 入门

请使用 Prettier 的默认设置进行格式化。

#### 先决条件

您需要安装 node 和 npm 才能创建源代码的捆绑版本。

设置时使用的版本:

- node:12.18.4
- npm:6.14.6

要创建包含此扩展的大部分业务逻辑的 `bundled-content-script.js`,您必须先安装所有依赖项。

1. 转到 repo 的根目录并运行:

```
npm install
```

2. 运行以下命令创建 `manifest.json` 中使用的 `bundled-content-script.js`

```
npm start // 创建构建文件并启动在保存时热重载的文件观察器

// 或

npm run build // 创建构建文件一次
```

恭喜,您现在可以开始开发了!

如果您是 Chrome 扩展程序开发新手,或者需要额外帮助,请参阅[此 YouTube 教程](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### 问题

#### 打开新问题

如果您对扩展程序有任何问题,请搜索以确保该问题尚未被报告。如果没有,请打开一个问题,强烈建议使用问题表单,但这不是强制性的。

#### 解决问题

如果您发现一个您认为可以解决的问题,请随时提出来,不必客气。打开带有修复程序的 PR,并确保提及您正在修复的问题。

### 功能请求

#### 打开新的功能请求

如果您对扩展程序有想法,请随时打开功能请求,但请先搜索以确保该功能尚未被建议。强烈建议使用功能表单,但这不是强制性的

#### 实现功能请求

如果您发现您认为可以实现的功能,请随时提出来,不必客气。打开带有修复的 PR,并确保提及您正在实现的功能。

### 我们接受哪些 PR?

- 问题修复。
- 功能实现。
- 拼写错误或更好、更易用的词语。
- 网站贡献。


================================================
FILE: CONTRIBUTINGda.md
================================================
Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Velkommen til Return YouTube Dislike bidragsvejledning

Tak fordi du bruger din tid på at bidrage til vores projekt! Alle dine ændringer vil blive afspejlet i den næste version af udvidelsen (eller på [websitet](https://www.returnyoutubedislike.com/)).

## Kom godt i gang

Brug venligst Prettier med standardindstillinger til formatering.

#### Forudsætninger

Du skal have Node og npm installeret for at kunne opbygge den bundtede version af koden.

Versioner brugt ved opsætning:

- node: 12.18.4
- npm: 6.14.6

For at oprette `bundled-content-script.js`, som indeholder størstedelen af udvidelsens forretningslogik, skal du først installere alle afhængigheder.

1. Gå til rodmappen af repoet og kør:

```
npm install
```

2. Kør følgende kommando for at oprette `bundled-content-script.js`, som bruges i `manifest.json`

```
npm start // opret build-fil(er) og start en watcher, der genindlæser ved gem

// eller

npm run build // opret build-fil(er) én gang
```

Tillykke, du er nu klar til at udvikle!

Hvis du er ny i udvikling af Chrome‑udvidelser eller har brug for ekstra hjælp, se [denne YouTube‑vejledning](https://www.youtube.com/watch?v=mdOj6HYE3_0).

### Issues

#### Opret en ny issue

Hvis du har problemer med udvidelsen, så søg først for at sikre, at problemet ikke allerede er rapporteret. Hvis ikke, opret en issue. Det anbefales stærkt at bruge issue‑skabelonen, men det er ikke påkrævet.

#### Løs en issue

Hvis du har fundet et problem, du mener, du kan løse, så tøv ikke. Opret en PR med rettelsen, og husk at nævne den issue, du løser.

### Feature‑ønsker

#### Opret et nyt feature‑ønske

Hvis du har en idé til udvidelsen, er du velkommen til at oprette et feature‑ønske, men søg venligst først for at sikre, at det ikke allerede er foreslået. Brug af feature‑skabelonen anbefales, men er ikke påkrævet.

#### Implementér et feature‑ønske

Hvis du har fundet et feature, som du kan implementere, så tøv ikke. Opret en PR med implementeringen, og husk at nævne det feature, du implementerer.

### Hvilke PR’er accepterer vi?

- Fejlrettelser.
- Implementering af funktioner.
- Ret stavefejl eller brug bedre og enklere formuleringer.
- Bidrag til websitet.


================================================
FILE: CONTRIBUTINGde.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Willkommen beim Leitfaden für Beitragende von Return YouTube Dislikes

Vielen Dank, dass du deine Zeit investierst, um zu unserem Projekt beizutragen! Alle deine Änderungen werden in der nächsten Version der Erweiterung (oder der [Website](https://www.returnyoutubedislike.com/)) reflektiert.

## Erste Schritte

Bitte verwende Prettier mit den Standardeinstellungen für die Formatierung.

#### Voraussetzungen

Du musst Node und npm installiert haben, um die gebündelte Version der Quelle zu erstellen.

Verwendete Versionen beim Einrichten:

- Node: 12.18.4
- npm: 6.14.6

Um die `bundled-content-script.js` zu erstellen, die den Großteil der Geschäftslogik dieser Erweiterung enthält, musst du zuerst alle Abhängigkeiten installieren.

1. Gehe zum Root-Verzeichnis des Repos und führe aus:

```
npm install
```

2. Führe den folgenden Befehl aus, um `bundled-content-script.js` zu erstellen, das in `manifest.json` verwendet wird:

```
npm start // um die Build-Datei(en) zu erstellen und einen Datei-Watcher zu starten, der bei jedem Speichern neu lädt

// oder

npm run build // um die Build-Datei(en) einmal zu erstellen
```

Herzlichen Glückwunsch, du bist jetzt bereit zum Entwickeln!

Wenn du neu in der Entwicklung von Chrome-Erweiterungen bist oder zusätzliche Hilfe benötigst, sieh dir bitte [dieses YouTube-Tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0) an.

### Probleme

#### Öffnen eines neuen Problems

Wenn du Probleme mit der Erweiterung hast, suche bitte, um sicherzustellen, dass das Problem noch nicht gemeldet wurde. Wenn nicht, öffne ein Problem. Die Verwendung des Problemformulars wird dringend empfohlen, ist aber nicht zwingend erforderlich.

#### Lösung eines Problems

Wenn du ein Problem gefunden hast, das du lösen könntest, sei nicht schüchtern. Öffne einen PR mit der Lösung und vergewissere dich, dass du das behobene Problem erwähnst.

### Feature-Anfrage

#### Öffnen einer neuen Feature-Anfrage

Wenn du eine Idee für die Erweiterung hast, kannst du gerne eine Feature-Anfrage öffnen, aber suche bitte zuerst, um sicherzustellen, dass das Feature noch nicht vorgeschlagen wurde. Die Verwendung des Feature-Formulars wird dringend empfohlen, ist aber nicht zwingend erforderlich.

#### Implementierung einer Feature-Anfrage

Wenn du ein Feature gefunden hast, das du implementieren könntest, sei nicht schüchtern. Öffne einen PR mit der Implementierung und vergewissere dich, dass du das implementierte Feature erwähnst.

### Welche PRs akzeptieren wir?

- Fehlerbehebungen.
- Implementierung von Funktionen.
- Rechtschreibfehler oder bessere und einfachere Wörter zur Verwendung.
- Beiträge zur Website.


================================================
FILE: CONTRIBUTINGes.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Bienvenido(a) a la guía de contribución de Return YouTube Dislikes

¡Gracias por invertir tiempo en contribuir al proyecto! Todos sus cambios serán mostrados en la siguiente versión de la extensión (o en la [pagina web](https://www.returnyoutubedislike.com/))

## Empecemos

Por favor, utiliza Prettier con la configuración predeterminada para el formateo

#### Requisitos previos

Necesita tener instalados node y npm para crear la versión empaquetada del código fuente

Versiones utilizadas durante la configuración:

- node: 12.18.4
- npm: 6.14.6

Para crear el archivo `bundled-content-script.js` que contiene la mayor parte de la lógica de negocio de esta extensión, primero debe instalar todas las dependencias

1. Ve a la raíz del repositorio y ejecute:

```
npm install
```

2. Ejecuta el siguiente comando para crear `bundled-content-script.js`, el cual se utiliza en `manifest.json`

```
npm start // para crear el/los archivo(s) de compilación y comenzar un observador de archivos que se recargue automáticamente al guardar cambios

// o

npm run build // para crear el/los archivo(s) de compilación una vez
```

¡Felicitaciones! ¡Ahora estás listo(a) para desarrollar!

Si eres nuevo/a en el desarrollo de extensiones de Chrome o necesitas ayuda adicional, por favor consulta [este tutorial en YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Problemas

#### Abrir un nuevo problema

Si tiene algún problema con la extensión, por favor verifique si el problema ya ha sido reportado. Si no lo ha sido, abre un problema. Se recomienda encarecidamente utilizar el formulario de problema, pero no es obligatorio.

#### Resolver un problema

Si encontró un problema que crea que pueda resolver, no dude en hacerlo. Abra una solicitud de extracción (PR) con la solución y asegúrese de mencionar el problema que está solucionando

### Solicitud de función

#### Abrir una nueva solicitud de función

If you have an idea for the extension, feel free to open a feature request, but please search it before to make sure the feature isn't already suggested. Using the feature form is highly recommended but not mandatory

#### Implementando una solicitud de funcionalidad

Si encontró una función que pueda implementar, no dude en hacerlo. Abra una solicitud de extracción (PR) con la solución y asegúrese de mencionar la función que está implementando

### ¿Qué PRs aceptamos?

- Corrección de problemas.
- Implementación de funciones.
- Corrección de errores tipográficos o uso de palabras mejores y más sencillas.
- Contribuciones al sitio web.


================================================
FILE: CONTRIBUTINGfr.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Bienvenue dans le guide de contribution à Return YouTube Dislikes

Merci d'investir votre temps pour contribuer à notre projet ! Toutes vos modifications seront prises en compte dans la prochaine version de l'extension (ou du site web).

## Pour commencer

Veuillez utiliser [Prettier](https://prettier.io/) avec les paramètres par défaut pour le formatage du code.

#### Prérequis

Vous devez avoir installé node et npm pour créer la version bundle depuis le code source.

Versions utilisées lors de la mise en place :

- node: 12.18.4
- npm: 6.14.6

Pour créer le fichier `bundled-content-script.js` qui contient la plupart de la logique de cette extension, vous devez d'abord installer toutes les dépendances.

1. Allez à la racine du repo et exécutez :

```
npm install
```

2. Exécutez la commande suivante pour créer le fichier `bundled-content-script.js` qui est utilisé dans le fichier `manifest.json`.

```
npm start // pour créer le(s) fichier(s) de construction et lancer un observateur de fichiers qui recharge à chaud lors de la sauvegarde.

// ou

npm run build // pour créer le(s) fichier(s) de construction une seule fois
```

Félicitations, vous êtes maintenant prêt·e à développer !

Si vous n'avez jamais développé d'extensions pour Chrome ou si vous avez besoin d'une aide supplémentaire, consultez [ce tutoriel YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0) (en anglais).

### Problèmes (aussi appelé issues en anglais)

#### Signaler un problème

Si vous rencontrez des problèmes avec l'extension, vérifiez que le problème n'a pas déjà été signalé. Si ce n'est pas le cas, [signalez le problème](https://github.com/Anarios/return-youtube-dislike/issues/new?assignees=&labels=bug&template=bug.yml&title=%28Bug%29%3A+), en utilisant le formulaire qui est fortement recommandé mais pas obligatoire.

#### Résoudre un problème

Si vous avez trouvé un problème que vous pensez pouvoir résoudre, ne soyez pas timide. Ouvrez une [PR](https://github.com/Anarios/return-youtube-dislike/pulls) [(C'est quoi ?)](https://blog.zenika.com/2017/01/24/pull-request-demystifie/) avec la solution et assurez-vous de mentionner le problème que vous résolvez (écrivez # puis le numéro de l'issue).

### Demande de fonctionnalité (aussi appelé feature request en anglais)

#### Ouverture d'une nouvelle demande de fonctionnalité

Si vous avez une idée pour l'extension, n'hésitez pas à [ouvrir une demande de fonctionnalité](https://github.com/Anarios/return-youtube-dislike/issues/new?assignees=&labels=enhancement&template=feature-request.yml&title=%28Feature+Request%29%3A+), mais veuillez effectuer une recherche préalable pour vous assurer que la fonctionnalité n'est pas déjà proposée. L'utilisation du formulaire de demande de fonctionnalité est fortement recommandée mais pas obligatoire.

#### Implémenter une demande de fonctionnalité

Si vous avez trouvé une fonctionnalité que vous pensez pouvoir mettre en œuvre, ne soyez pas timide. Ouvrez une [PR](https://github.com/Anarios/return-youtube-dislike/pulls) [(C'est quoi ?)](https://blog.zenika.com/2017/01/24/pull-request-demystifie/) avec le correctif et assurez-vous de mentionner la fonctionnalité que vous implémentez (écrivez # puis le numéro de l'issue).

### Quels PR acceptons-nous ?

- Correction de problèmes.
- Implémentation de fonctionnalités.
- Fautes de frappe ou utilisation de mots plus simples et plus efficaces.
- Contributions au site web.


================================================
FILE: CONTRIBUTINGgr.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Welcome To Return YouTube Dislikes contributing guide

Σας ευχαριστούμε που αφιερώσατε χρόνο για να συνεισφέρετε στο έργο μας! Όλες οι αλλαγές σας θα εμφανιστούν στην επόμενη έκδοση της επέκτασης (ή στην [ιστοσελίδα](https://www.returnyoutubedislike.com/)).

## Ξεκινώντας

Παρακαλώ χρησιμοποιήστε το Prettier με τις προκαθορισμένες ρυθμίσεις για τη μορφοποίηση.

#### Προαπαιτούμενα

Πρέπει να έχετε το node και το npm εγκαταστημένο για να δημιουργήσετε την ομαδοποιημένη έκδοση της πηγής.

Εκδόσεις για την εγκατάσταση:

- node: 12.18.4
- npm: 6.14.6

Για να δημιουργήσετε το `bundled-content-script.js` που περιέχει το περισσότερο business logic αυτής της επέκτασης πρέπει να εγκαταστήσετε όλα τα  dependencies πρώτα.

1. Πηγαίντε στη ρίζα (root) του repo και εκτελέστε:

```
npm install
```

2. Εκτελέστε την ακόλουθη εντολή για να δημιουργήσετε το `bundled-content-script.js` το οποίο χρησιμοποιείται στο `manifest.json`

```
npm start // για να δημιουργήσετε τα build file(s) και να ξεκινήσετε ένα πρόγραμμα παρακολούθυησης αρχείων που τα φορτώνει ξανά κατά την αποθήκευση

// ή

npm run build // για να δημιουργήσετε τα build file(s) μία φορά
```

Συγχαρητήρια, τώρα είστε έτοιμος να δημιουργήσετε!

Εάν είστε νέος στη δημιουργία επεκτάσεων στο Chrome, ή χρειάζεστε επιπλέον βοήθεια, παρακαλώ δείτε [αυτόν τον οδηγό στο YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Ζητήματα

#### Δημιουργώντας ένα νέο ζήτημα

Εάν αντιμετωπίζετε κάποιο πρόβλημα με την επέκταση, παρακαλώ κάντε μια αναζήτηση για να σιγουρευτείτε ότι το ζήτημα δεν έχει αναφερθεί ήδη. Αν δεν είναι, δημιουργήστε ένα νέο ζήτημα χρησιμοποιώντας την φόρμα ζητημάτων η οποία συστήνεται αλλά δεν είναι απαραίτητη.

#### Λύνοντας ένα ζήτημα

Εάν βρήκατε ένα ζήτημα που πιστεύετε ότι ίσως μπορέσετε να λύσετε, μην ντρέπεστε. Ανοίξτε ένα PR με την επιδιόρθωση και φροντίστε να αναφέρετε το πρόβλημα που επιδιορθώνετε.

### Αίτηση για νέα λειτουργίας

#### Άνοιγμα αιτήματος νέας λειτουργίας

Εάν έχετε μια ιδέα για την επέκταση, μη διστάσετε να ανοίξετε ένα αίτημα λειτουργίας, αλλά ψάξτε το προηγουμένως για να βεβαιωθείτε ότι η λειτουργία δεν έχει ήδη προταθεί. Η χρήση της φόρμας για νέες λειτουργίες συστήνεται αλλά δεν είναι απαραίτητη.

#### Υλοποιώντας ένα αίτημα νέας λειτουργίας

Αν βρήκατε μια δυνατότητα που πιστεύετε ότι μπορεί να μπορέσετε να εφαρμόσετε, μην ντρέπεστε. Ανοίξτε ένα PR με την επιδιόρθωση και φροντίστε να αναφέρετε τη δυνατότητα που εφαρμόζετε.

### Τι PR δεχόμαστε;

- Διορθώσεις ζητημάτων.
- Υλοποίηση νέων λειτουργιών.
- Τυπογραφικά λάθη ή καλύτερες και πιο εύκολες λέξεις στη χρήση.
- Συνεισφορές στην ιστοσελίδα.


================================================
FILE: CONTRIBUTINGhu.md
================================================
Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Üdvözlünk a Return YouTube Dislike közreműködői útmutatójában

Köszönjük, hogy időt szánsz a projekthez való hozzájárulásra! Minden módosításod meg fog jelenni a bővítmény következő verziójában (vagy a [weboldalon](https://www.returnyoutubedislike.com/)).

## Kezdő lépések

Kérjük, a formázáshoz használd a Prettier eszközt alapértelmezett beállításokkal.

#### Előkövetelmények

A forrás kimenetének elkészítéséhez szükséged lesz a Node és az npm telepítésére.

Az előkészítéskor használt verziók:

- node: 12.18.4
- npm: 6.14.6

A `bundled-content-script.js` létrehozásához (ami a bővítmény üzleti logikájának nagy részét tartalmazza) először telepíteni kell az összes függőséget.

1. Lépj a repó gyökerébe és futtasd:

```
npm install
```

2. Futtasd az alábbi parancsot a `bundled-content-script.js` elkészítéséhez, amelyet a `manifest.json` használ:

```
npm start // a build fájl(ok) létrehozása és egy watcher indítása, amely mentéskor újratölt

// vagy

npm run build // a build fájl(ok) egyszeri létrehozása
```

Gratulálunk, készen állsz a fejlesztésre!

Ha új vagy a Chrome‑bővítmények fejlesztésében, vagy extra segítségre van szükséged, nézd meg [ezt a YouTube‑oktatóanyagot](https://www.youtube.com/watch?v=mdOj6HYE3_0).

### Hibák és problémák

#### Új issue megnyitása

Ha problémád van a bővítménnyel, először keress rá, hogy nem jelentették‑e már. Ha nem, nyiss egy issue‑t. Erősen ajánlott az issue űrlap használata, de nem kötelező.

#### Egy issue megoldása

Ha találtál egy problémát, amit meg tudsz oldani, ne habozz. Nyiss egy PR‑t a javítással, és mindenképp említsd meg, melyik issue‑t javítod.

### Funkciókérések

#### Új funkciókérés megnyitása

Ha van egy ötleted a bővítményhez, nyugodtan nyiss funkciókérést, de előtte keresd meg, hogy nem javasolták‑e már. A funkció űrlap használata ajánlott, de nem kötelező.

#### Funkciókérés megvalósítása

Ha találtál egy funkciót, amit meg tudsz valósítani, ne habozz. Nyiss egy PR‑t a megvalósítással, és említsd meg a funkciót, amit implementálsz.

### Milyen PR‑okat fogadunk el?

- Hibajavítások.
- Funkciók implementálása.
- Elírások javítása, jobb és egyszerűbb megfogalmazások.
- Közreműködések a weboldalon.


================================================
FILE: CONTRIBUTINGid.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Selamat datang di petunjuk kontribusi Return Youtube Dislikes

Terima kasih telah menggunakan waktumu untuk berkontribusi pada proyek kami! Semua perubahan akan diaplikasikan pada versi extension selanjutnya (atau [website](https://www.returnyoutubedislike.com/)).

## Mula-mula

Tolong gunakan Prettier dengan setting bawaan untuk melakukan formatting.

#### Prerequisites

Kamu harus menginstall node dan npm untuk membuat versi bundled dari source code.

Versi yang digunakan:

- node: 12.18.4
- npm: 6.14.6

Untuk membuat `bundled-content-script.js` yang memiliki semua logic dari extension ini, kamu harus menginstall semua dependency terlebih dahulu.

1. Masuk ke root dari repo dan jalankan:

```
npm install
```

2. Jalankan command berikut untuk membuat `bundled-content-script.js` yang akan digunakan di `manifest.json`

```
npm start // untuk membuat build file dan menjalankan file watcher yang akan melakukan hot-reloads ketika menyimpan.

// atau

npm run build // untuk membuat build file satu kali.
```

Selamat, kamu sekarang sudah siap untuk melakukan develop!

Jika kamu baru dalam melakukan develop extension Chrome, atau membutuhkan bantuan tambahan, tolong kunjungi [tutorial Youtube ini](https://www.youtube.com/watch?v=mdOj6HYE3_0).

### Issues

#### Membuat issue baru

Jika kamu menemuakan issue mengenai extension, tolong cari terlebih dahulu untuk memastikan issue tersebuat telah di laporkan. Jika belum, buat issue baru, direkomendasikan menggunakan form issue tapi tidak harus.

#### Menyelesaikan issue

Jika kamu menemukan issue yang dapat kamu selesaikan, jangan malu. Buat PR dan pastikan untuk mention issue yang sedang diperbaiki.

### Rqeust Fitur

#### Membuat request fitur

Jika kamu memiliki ide mengenai extension, silakan untuk membuat request fitur, tapi tolong cari terlebih dahulu untuk memastikan fitur tersebut belum direquest oleh orang lain. Direkomendasikan menggunakan form request fitur tapi tidak harus.

#### Implementasi request fitur

Jika kamu menemukan request fitur yang dapat kamu kerjakan, jangan malu. Buat PR dan pastikan untuk mention request fitur yang sedang dikerjakan.

### PR apa saja yang kami terima?

- Memperbaiki issue.
- Implementasi fitur.
- Typo atau improvisasi kata dan kalimat.
- Kontribusi website.


================================================
FILE: CONTRIBUTINGja.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Return YouTube Dislike へのコントリビュートガイドへようこそ

本プロジェクトへのご協力に時間を割いていただきありがとうございます! 皆さまの変更は、拡張機能の次のリリース(または[ウェブサイト](https://www.returnyoutubedislike.com/))に反映されます。

## はじめに

フォーマットには Prettier をデフォルト設定のまま使用してください。

#### 前提条件

ソースのバンドル版を作成するには、Node と npm をインストールする必要があります。

セットアップ時のバージョン:

- node: 12.18.4
- npm: 6.14.6

この拡張機能の大部分のロジックを含む `bundled-content-script.js` を作成するには、まず依存関係をインストールします。

1. リポジトリのルートに移動して、以下を実行します:

```
npm install
```

2. `manifest.json` で使用される `bundled-content-script.js` を作成するには、次のコマンドを実行します。

```
npm start // ビルドファイルを作成し、保存時に自動リロードするウォッチャーを開始

// または

npm run build // 一度だけビルドファイルを作成
```

おめでとうございます。これで開発を始める準備ができました!

Chrome 拡張の開発が初めて、または追加のヘルプが必要な場合は、[こちらの YouTube チュートリアル](https://www.youtube.com/watch?v=mdOj6HYE3_0)をご覧ください。

### Issue について

#### 新しい Issue を作成する

拡張機能に問題がある場合は、既に報告されていないか検索してください。未報告であれば Issue を作成してください。Issue フォームの使用は強く推奨しますが必須ではありません。

#### Issue を解決する

解決できそうな Issue を見つけた場合は、遠慮なく修正の PR を作成し、修正した Issue を必ず明記してください。

### 機能リクエスト

#### 新しい機能リクエストを作成する

拡張機能に関するアイデアがある場合は、自由に機能リクエストを作成してください。ただし、既に提案されていないか事前に検索してください。機能フォームの使用は強く推奨しますが必須ではありません。

#### 機能リクエストを実装する

実装できそうな機能を見つけた場合は、遠慮なく実装の PR を作成し、実装する機能を必ず明記してください。

### 受け付ける PR

- 不具合修正
- 機能の実装
- 誤字修正や、より良く簡潔な表現への改善
- ウェブサイトへの貢献


================================================
FILE: CONTRIBUTINGkr.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Return YouTube Dislike 기여 가이드에 오신 것을 환영합니다

프로젝트에 기여해 주셔서 감사합니다! 여러분의 변경 사항은 확장 프로그램의 다음 버전(또는 [웹사이트](https://www.returnyoutubedislike.com/))에 반영됩니다.

## 시작하기

코드 포매팅에는 기본 설정의 Prettier를 사용해 주세요.

#### 사전 준비물

소스의 번들 버전을 만들려면 Node와 npm이 설치되어 있어야 합니다.

설정 시 사용한 버전:

- node: 12.18.4
- npm: 6.14.6

이 확장 프로그램의 대부분의 비즈니스 로직을 담은 `bundled-content-script.js`를 생성하려면 먼저 모든 의존성을 설치해야 합니다.

1. 저장소 루트로 이동하여 다음을 실행하세요:

```
npm install
```

2. `manifest.json`에서 사용하는 `bundled-content-script.js`를 생성하려면 다음 명령을 실행하세요:

```
npm start // 빌드 파일을 생성하고 저장 시 자동 새로고침하는 감시자 시작

// 또는

npm run build // 빌드 파일을 한 번만 생성
```

축하합니다. 이제 개발할 준비가 되었습니다!

Chrome 확장 프로그램 개발이 처음이거나 추가 도움이 필요하다면 [이 YouTube 튜토리얼](https://www.youtube.com/watch?v=mdOj6HYE3_0)을 참고하세요.

### 이슈

#### 새 이슈 만들기

확장 프로그램에 문제가 있다면, 먼저 동일한 이슈가 이미 보고되지 않았는지 검색해 주세요. 없다면 이슈를 생성해 주세요. 이슈 템플릿 사용을 권장하지만 필수는 아닙니다.

#### 이슈 해결하기

해결할 수 있을 것 같은 이슈를 찾았다면 주저하지 마세요. 수정 사항으로 PR을 열고, 해결 중인 이슈를 꼭 언급해 주세요.

### 기능 요청

#### 새 기능 요청 만들기

확장 프로그램에 대한 아이디어가 있다면 기능 요청을 자유롭게 열어 주세요. 다만, 이미 제안된 내용이 아닌지 먼저 검색해 주세요. 기능 템플릿 사용을 권장하지만 필수는 아닙니다.

#### 기능 요청 구현하기

구현할 수 있을 것 같은 기능을 찾았다면 주저하지 마세요. 구현 내용으로 PR을 열고, 구현하는 기능을 꼭 언급해 주세요.

### 어떤 PR을 수락하나요?

- 버그 수정
- 기능 구현
- 오타 수정 또는 더 좋고 간결한 표현으로 개선
- 웹사이트 관련 기여


================================================
FILE: CONTRIBUTINGnl.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Welkom bij de YouTube Dislikes bijdragengids

Bedankt voor het investeren van uw tijd in het bijdragen aan ons project! Al uw wijzigingen worden weergegeven in de volgende versie van de extensie (of de [website](https://www.returnyoutubedislike.com/)).

## Aan de slag

Gebruik Prettier met standaardinstellingen voor opmaak.

#### Vereisten

U moet node en npm hebben geïnstalleerd om de gebundelde versie van de broncode te maken.

Versies gebruikt bij het instellen:

- node: 12.18.4
- npm: 6.14.6

Om de `bundled-content-script.js` te maken die de meeste bedrijfslogica van deze extensie bevat, moet u eerst alle afhankelijkheden installeren.

1. Ga naar de hoofdmap van de repo en voer het volgende uit:

```
npm install
```

2. Voer de volgende opdracht uit om `bundled-content-script.js` aan te maken dat wordt gebruikt in `manifest.json`

```
npm start // om het (de) buildbestand(en) te maken en een bestandswachter te starten die bij het opslaan opnieuw wordt geladen

// of

npm run build // om het (de) buildbestand(en) eenmaal te maken
```

Gefeliciteerd, je bent nu klaar om te ontwikkelen!

Als je nieuw bent in het ontwikkelen van Chrome-extensies of extra hulp nodig hebt, bekijk dan [deze YouTube-tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Problemen

#### Een nieuw probleem openen

Als je problemen hebt met de extensie, zoek dan eerst of het probleem nog niet is gemeld. Als dit niet het geval is, open dan een probleem, het gebruik van het probleemformulier wordt sterk aanbevolen, maar is niet verplicht.

#### Een probleem oplossen

Als je een probleem hebt gevonden waarvan je denkt dat je het zou kunnen oplossen, wees dan niet verlegen. Open een PR met de oplossing en vermeld het probleem dat u aan het oplossen bent.

### Functieverzoek:

#### Een nieuw functieverzoek openen

Als je een idee hebt voor de extensie, kun je een functieverzoek openen, maar zoek het eerst op om er zeker van te zijn dat de functie niet al is voorgesteld. Het gebruik van het functieformulier wordt sterk aanbevolen, maar is niet verplicht.

#### Een functieverzoek implementeren

Als je een functie hebt gevonden waarvan je denkt dat je die zou kunnen implementeren, wees dan niet verlegen. Open een PR met de oplossing en zorg ervoor dat u de functie vermeldt die u implementeert.

### Welke PR's accepteren we?

- Probleemoplossingen.
- Implementatie van functies.
- Typefouten of betere en gemakkelijkere woorden om te gebruiken.
- Website bijdragen.


================================================
FILE: CONTRIBUTINGpl.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Witamy w przewodniku współtworzenia Return YouTube Dislike

Dziękujemy za zainwestowanie czasu w rozwój naszego projektu! Wszystkie Twoje zmiany znajdą się w następnej wersji rozszerzenia ([bądź strony](https://www.returnyoutubedislike.com/)).

## Początek

Prosimy używać Prettier z domyślnymi ustawieniami do formatowania.

#### Wymagania wstępne

Musisz mieć zainstalowane node i npm, aby utworzyć dołączoną wersję źródła.

Wersje używane przy ustawianiu:

- node: 12.18.4
- npm: 6.14.6

Aby utworzyć `bundled-content-script.js`, które zawiera większość logiki tego rozszerzenia, musisz najpierw zainstalować wszystkie zależności.

1. Przejdź do korzenia tego repo i uruchom:

```
npm install
```

2. Użyj polecenia poniżej aby stworzyć `bundled-content-script.js`, które jest używane w `manifest.json`

```
npm start // aby utworzyć plik(i) build-u i uruchomić obserwatora pliku, który przeładowuje po zapisie

// lub

npm run build // aby jednorazowo utworzyć plik(i) build-u
```

Gratulacje, jesteś gotów pisać!

Jeśli jesteś nowy w pisaniu rozszerzeń do Chrome, lub potrzebujesz dodatkowej pomocy, obejrzyj [ten poradnik na YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Problemy

#### Otwieranie nowego problemu

Jeśli masz jakiekolwiek problemy z rozszerzeniem, najpierw wyszukaj go aby upewnić się, że dany problem nie został już zgłoszony. Jeżeli nie, otwórz problem. Używanie formularza problemu jest zalecane, ale nie jest konieczne.

#### Rozwiązywanie problemu

Jeżeli znalazłeś problem, który myślisz, że jesteś w stanie rozwiązać, nie wstydź się. Otwórz PR z fix-em i opisz problem, który naprawiasz.

### Prośba o funkcjonalność

#### Otwieranie nowej prośby o funkcjonalność

Jeżeli masz pomysł na rozszerzenie, śmiało otwórz nowe żądanie o funkcjonalność, ale prosimy o wyszukanie swojego pomysłu, aby upewnić się, że nie został on już zasugerowany. Używanie formularza jest zalecane, ale nie jest konieczne.

#### Implementacja prośby o funkcjonalność

Jeżeli znalazłeś pomysł na funkcjonalność, którą myślisz, że jesteś w stanie zaimplementować, nie wstydź się. Otwórz PR z fix-em, i opisz funkcjonalność, którą implementujesz.

### Jakie PR-y przyjmujemy?

- Naprawy problemów.
- Implementacja funkcjonalności.
- Literówki lub lepsze i łatwiejsze w zrozumieniu słowa.
- Współtworzenie strony.


================================================
FILE: CONTRIBUTINGpt_BR.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Bem-vindo ao guia de contribuição do Return YouTube Dislikes

Obrigado por investir seu tempo contribuindo para o nosso projeto! Todas as mudanças serão refletidas na próxima versão da extensão (ou do [website](https://www.returnyoutubedislike.com/)).

## Começando

Por favor use o Prettier com as configurações padrão de formatação.

#### Pré requisitos

Você precisa ter o node e o npm instalados para criar o pacote a partir do código-fonte.

Versões usadas na configuração:

- node: 12.18.4
- npm: 6.14.6

Para criar o `bundled-content-script.js` que contém muita da lógica de negócio dessa extensão você precisará instalar todas as dependências primeiro.

1. Vá para a raiz do repositório e execute:

```
npm install
```

2. Execute o comando a seguir para criar o `bundled-content-script.js` que será usado no `manifest.json`

```
npm start // Para criar os arquivos de build e iniciar um file watcher que recarrega o conteúdo automaticamente ao salvar

// ou

npm run build // Para criar os arquivos de build apenas uma vez
```

Parabéns, agora você está pronto para desenvolver!

Se você é novo no desenvolvimento de extensões para o Chrome, ou precisa de ajuda extra, por favor dê uma olhada [nesse tutorial do YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Problemas(Issues)

#### Abrindo uma nova issue

Se você tiver qualquer problema com a extensão, por favor pesquise nas issues do nosso repositório para ter certeza de que o problema já não foi reportado. Se não foi, abra uma issue, usar o formulário de issues é altamente recomendado mas não é obrigatório.

#### Resolvendo issues

Se você encontrou uma issue que você sente que é capaz de corrigir, não tenha vergonha. Abra uma PR com a correção e certifique-se de mencionar a issue que você está corrigindo.

### Sugerir um nova funcionalidade(Feature request)

#### Abrindo uma feature request

Se você tem uma ideia de funcionalidade para a extensão, sinta-se livre para abrir uma feature request no nosso repositório, mas por favor certifique-se de que a funcionalidade já não foi sugerida. Usar o formulário de features é altamente recomendado mas não é obrigatório.

#### Implementando uma feature request

Se você encontrou uma feature request que você sente que é capaz de implementar, não tenha vergonha. Abra uma PR com a implementação e certifique-se de mencionar a feature request que você está implementando.

### Quais PRs nós aceitamos?

- Correção de problemas.
- Implementação de funcionalidades.
- Erros de digitação e palavras melhores ou mais fáceis de entender.
- Contribuições para o Website.


================================================
FILE: CONTRIBUTINGru.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Добро пожаловать в руководство по внесению вклада Return YouTube Dislikes

Благодарим вас за то, что вы потратили своё время на участие в нашем проекте! Все ваши изменения будут отражены в следующей версии расширения (или на [сайте](https://www.returnyoutubedislike.com/)).

## Приступая к работе

Пожалуйста, используйте Prettier с настройками по умолчанию для форматирования кода.

#### Необходимое

Вам необходимо иметь установленные node и npm, чтобы создать bundled-версию источника.

Версии, используемые при настройке:

- node: 12.18.4
- npm: 6.14.6

Для создания `bundled-content-script.js` который содержит большую часть бизнес-логики этого расширения, вы должны сначала установить все зависимости.

1. Перейдите в корень репозитория и выполните следующее:

```
npm install
```

2. Выполните следующую команду, чтобы создать `bundled-content-script.js`, который используется в `manifest.json`

```
npm start // для создания файла(ов) сборки и запуска наблюдателя за файлами, который выполняет hot-reload при сохранении

// или

npm run build // для создания файла(ов) сборки один раз
```

Поздравляем, теперь вы готовы к разработке!

Если вы новичок в разработке расширений Chrome или вам нужна дополнительная помощь, посмотрите [это руководство на YouTube (англ.)](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Вопросы

#### Открытие нового вопроса/проблемы

Если у вас возникли проблемы с расширением, пожалуйста, поищите, чтобы убедиться, что о проблеме ещё не сообщалось. Если это не так, откройте вопрос(issue), использование формы проблемы настоятельно рекомендуется, но не является обязательным.

#### Решение вопроса

Если вы нашли проблему, которую, как вам кажется, вы можете решить, не стесняйтесь. Откройте запрос на извлечение(pull request) с исправлением и обязательно укажите вопрос, который вы устраняете.

### Запрос функции

#### Открытие запроса на новую функцию

Если у вас есть идея для расширения, не стесняйтесь открыть запрос на функцию, но, пожалуйста, прежде поищите другие запросы, чтобы убедиться, что функция уже не предложена. Использование формы запроса функции настоятельно рекомендуется, но не является обязательным

#### Внедрение запроса на функцию

Если вы нашли функцию, которую, как вам кажется, вы могли бы реализовать, не стесняйтесь. Откройте запрос на извлечение(pull request) с исправлением и обязательно укажите функцию, которую вы реализуете.

### Какие запросы на извлечение(pull request) мы принимаем?

- Исправления проблем.
- Внедрения новых функций.
- Исправления опечаток и упрощение текста.
- Улучшения сайта.


================================================
FILE: CONTRIBUTINGsv.md
================================================
Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# Välkommen till Return YouTube Dislike – bidragsguide

Tack för att du lägger tid på att bidra till vårt projekt! Alla dina ändringar kommer att synas i nästa version av tillägget (eller på [webbplatsen](https://www.returnyoutubedislike.com/)).

## Kom igång

Använd gärna Prettier med standardinställningar för formatering.

#### Förutsättningar

Du behöver ha Node och npm installerat för att skapa den bundlade versionen av koden.

Versioner som användes vid uppsättning:

- node: 12.18.4
- npm: 6.14.6

För att skapa `bundled-content-script.js`, som innehåller större delen av tilläggets logik, behöver du först installera alla beroenden.

1. Gå till repo‑ts roten och kör:

```
npm install
```

2. Kör följande kommando för att skapa `bundled-content-script.js`, som används i `manifest.json`:

```
npm start // skapar build‑fil(er) och startar en filbevakare som laddar om vid spara

// eller

npm run build // skapar build‑fil(er) en gång
```

Grattis! Du är nu redo att utveckla.

Om du är ny på att utveckla Chrome‑tillägg, eller behöver extra hjälp, se [den här YouTube‑guiden](https://www.youtube.com/watch?v=mdOj6HYE3_0).

### Ärenden (Issues)

#### Skapa ett nytt ärende

Om du har problem med tillägget, sök först för att säkerställa att ärendet inte redan är rapporterat. Om inte, skapa ett ärende. Det rekommenderas starkt att använda ärendeformuläret, men det är inte obligatoriskt.

#### Lösa ett ärende

Om du hittat ett ärende du tror att du kan lösa, tveka inte. Öppna en PR med lösningen och nämn vilket ärende du åtgärdar.

### Funktionsförslag

#### Skapa ett nytt funktionsförslag

Har du en idé för tillägget? Skapa gärna ett funktionsförslag, men sök först för att se till att förslaget inte redan finns. Att använda funktionsformuläret rekommenderas men är inte obligatoriskt.

#### Implementera ett funktionsförslag

Om du hittat en funktion du kan implementera, tveka inte. Öppna en PR med implementationen och nämn vilken funktion du implementerar.

### Vilka PR:er accepterar vi?

- Buggfixar.
- Implementering av funktioner.
- Rättning av stavfel eller förbättrade, enklare formuleringar.
- Bidrag till webbplatsen.


================================================
FILE: CONTRIBUTINGtr.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)

# "YouTube Dislike Sayısını Geri Getir"in katkı kılavuzuna Hoş Geldiniz

Projemize katkıda bulunmak için zaman ayırdığınız için teşekkür ederiz! Tüm değişiklikleriniz, uzantının bir sonraki sürümüne (veya [internet sitesi](https://www.returnyoutubedislike.com/)ne) yansıtılacaktır.

## Başlarken

Lütfen formatlama işlemi için, Prettier'i varsayılan ayarlardayken kullanın.

#### Ön Şartlar

Kaynağın paketlenmiş sürümünü oluşturmak için node ve npm'nin kurulu olması gerekir.

Kurulum sırasında kullanılan sürümler:

- node: 12.18.4
- npm: 6.14.6

Bu uzantının iş mantığının çoğunu içeren `bundled-content-script.js`yi oluşturmak için, önce tüm bağımlılıkları yüklemeniz gerekir.

1. Deponun köküne gidin ve şu komutu çalıştırın:

```
npm install
```

2. `manifest.json` içinde kullanılan `bundled-content-script.js` dosyasını oluşturmak için aşağıdaki komutu çalıştırın.

```
npm start // derleme dosyasının/dosyalarının oluşturulması ve kaydedilmesi sırasında çalışırken yeniden yüklenen bir dosya izleyicisini başlatmak için

// ya da

npm run build // derleme dosyasını/dosyalarını bir kez oluşturmak için
```

Tebrikler, artık geliştirmeye hazırsınız!

Chrome uzantıları geliştirme konusunda yeniyseniz veya fazladan yardıma ihtiyacınız olursa lütfen [bu YouTube öğreticisi](https://www.youtube.com/watch?v=mdOj6HYE3_0)ne bakın.

### Issue'lar

#### Yeni bir issue başlatmak

Uzantıyla ilgili herhangi bir sorununuz varsa, sorunun önceden bildirilmediğinden emin olmak için lütfen arama yapın. Eğer daha önce bildirilmediyse, bir konu açın. Sorun formunu kullanmanız şiddetle tavsiye edilir ancak zorunlu değildir.

#### Bir issue'yu çözmek

Çözebileceğinizi düşündüğünüz bir sorun bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve düzelttiğiniz sorunu belirttiğinizden emin olun.

### Özellik Talebi

#### Yeni bir özellik talebi açmak

Uzantı hakkında bir fikriniz varsa, bir özellik isteği açmaktan çekinmeyin, ancak özelliğin daha önce önerilmediğinden emin olmak için lütfen önce arama yapın. Özellik formunun kullanılması şiddetle tavsiye edilir ancak zorunlu değildir.

#### Bir özellik isteğini uygulamak

Uygulayabileceğinizi düşündüğünüz bir özellik bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve uyguladığınız özelliği belirttiğinizden emin olun.

### Hangi tür PR'leri kabul ediyoruz?

- Sorun düzeltmeleri.
- Özellik uygulaması.
- Yazım hataları veya daha anlaşılabilir ve kullanımı daha kolay kelimeler.
- Site katkıları.


================================================
FILE: CONTRIBUTINGuk.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Вітаємо у посібнику внеску в Return YouTube Dislikes

Дякуємо, що вкладаєте свій час у розвиток нашого проєкту! Усі ваші зміни буде відображено в наступній версії розширення (або ж [вебсайту](https://www.returnyoutubedislike.com/)).

## Почнімо працювати

Будь ласка, використовуйте Prettier із налаштуваннями за замовчуванням для форматування коду.

#### Заздалегідь

Вам потрібно встановити node і npm, щоб створити bundled версію джерела.

Версії, що використовувались при налаштуванні:

- node: 12.18.4
- npm: 6.14.6

Для створення `bundled-content-script.js`, який містить більшу частину бізнес-логіки цього розширення, спочатку потрібно встановити всі залежності.

1. Перейдіть в корінь репозиторію та виконайте наступне:

```
npm install
```

2. Виконайте наступну команду, щоб створити `bundled-content-script.js`, який використовується в `manifest.json`

```
npm start // для створення файлу(ів) збірки та запуску спостерігача за файлами, який виконує hot-reload при збереженні

// або ж

npm run build // для створення файлу(ів) збірки один раз
```

Вітаємо, тепер ви готові до розробки!

Якщо ви новачок у розробці розширення Chrome або вам потрібна додаткова допомога, перегляньте [це керівництво на YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0) (англ.)

### Проблеми

#### Відкриття нової проблеми

Якщо у вас виникли проблеми з розширенням, здійсніть пошук і переконайтеся, що про цю проблему ще не повідомляли. Якщо ні, створіть Issue, використання форми проблеми наполегливо рекомендується, але не є обов’язковим.

#### Вирішення проблеми

Якщо ви знайшли проблему, і гадаєте, що можете її вирішити, не соромтеся. Створіть Pull Request на вилучення з виправленням і обов'язково вкажіть проблему, яку ви усуваєте.

### Запит функції

#### Відкриття запиту на нову функцію

Якщо у вас є ідея щодо розширення, не соромтеся створіть Pull Request, але, будь ласка, здійсніть пошук і переконайтеся, що ця функція ще не запропонована. Використання форми функції наполегливо рекомендується, але не є обов’язковим.

#### Реалізація запиту функції

Якщо ви знайшли функцію, і гадаєте, що можете її реалізувати, не соромтеся. Створіть Pull Request із виправленням і обов’язково вкажіть функцію, яку ви впроваджуєте.

### Які Pull Request ми приймаємо?

- Виправлення проблем.
- Впровадження нових функцій.
- Виправлення помилок та спрощення тексту.
- Поліпшення сайту.


================================================
FILE: CONTRIBUTINGvi.md
================================================
Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTINGbg.md), [中文](CONTRIBUTINGcn.md), [Dansk](CONTRIBUTINGda.md), [Deutsch](CONTRIBUTINGde.md), [Español](CONTRIBUTINGes.md), [Français](CONTRIBUTINGfr.md), [Ελληνικά](CONTRIBUTINGgr.md), [Magyar](CONTRIBUTINGhu.md), [Bahasa Indonesia](CONTRIBUTINGid.md), [日本語](CONTRIBUTINGja.md), [한국어](CONTRIBUTINGkr.md), [Nederlands](CONTRIBUTINGnl.md), [Polski](CONTRIBUTINGpl.md), [Português do Brasil](CONTRIBUTINGpt_BR.md), [русский](CONTRIBUTINGru.md), [Svenska](CONTRIBUTINGsv.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md), [Tiếng Việt](CONTRIBUTINGvi.md)


# Chào mừng tới Hướng dẫn Đóng góp của Return YouTube Dislike (Trả lại số lượt Không thích trên YouTube) <!-- # Welcome To Return YouTube Dislikes contributing guide -->

Cảm ơn bạn đã dành thời gian để đóng góp cho dự án của chúng tôi! Tất cả các thay đổi của bạn sẽ được hiển thị trong phiên bản tiếp theo của tiện ích mở rộng này (hoặc của [trang mạng](https://www.returnyoutubedislike.com/)).

## Bắt đầu <!-- ## Getting Started -->

Hãy dùng [Prettier](https://prettier.io/) với thiết lập mặc định để định dạng mã.

#### Yêu cầu sơ bộ <!-- ### Prerequisites -->

Bạn cần phải cài **node** và **npm** để tạo bản đóng gói của mã nguồn.

Các phiên bản được dùng khi cài đặt:

- node: 12.18.4
- npm: 6.14.6

Dể có thể tạo tệp `bundled-content-script.js`, trong đó có chứa hầu hết các lôgic kinh doanh của tiện ích mở rộng này, trước tiên bạn phải cài các đối tượng phụ thuộc.

1. Tới thư mục gốc của kho mã nguồn và chạy lệnh:

```
npm install
```

2. Chạy lệnh dưới đây để tạo `bundled-content-script.js`, sẽ dùng tới trong `manifest.json`

```
npm start // để tạo (các) tệp xây dựng và khởi chạy một trình quan sát tập tin, đảm nhiệm việc tự động tải lại dự án khi có thay đổi được lưu

// hoặc

npm run build // để tạo (các) tệp xây dựng chỉ một lần
```

Chúc mừng! Bạn đã sẵn sàng để phát triển chương trình!

Nếu bạn chưa bao giờ phát triển tiện ích mở rộng cho Chrome hoặc cần sự trợ giúp, hãy xem [hướng dẫn này trên YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0)

### Vấn đề <!-- ### Issues -->

#### Tạo một vấn đề mới <!-- #### Opening a new issue -->

Nếu bạn có bất kì vấn đề gì với tiện ích mở rộng này, trước tiên hãy đọc qua danh sách các vấn đề đang có. Nếu vấn đề của bạn không có trong danh sách các vấn đề, hãy [tạo một vấn đề](https://github.com/Anarios/return-youtube-dislike/issues/new?assignees=&labels=bug&template=bug.yml&title=%28Bug%29%3A+). Dùng mẫu đơn vấn đề nếu có thể, nhưng không bắt buộc.

#### Giải quyết một vấn đề <!-- #### Solving an issue -->

Nếu bạn cảm thấy có thể giải quyết một vấn đề nào đó, đừng ngần ngại. Hãy tạo một [yêu cầu kéo](https://github.com/Anarios/return-youtube-dislike/pulls) cho sự thay đổi của bạn và nhớ hãy ghi tên lỗi mà bạn giải quyết.

### Yêu cầu Tính năng <!-- ### Feature Request -->

#### Tạo một yêu cầu tính năng mới <!-- #### Opening a new feature request -->

Nếu bạn có một ý tưởng dành cho tiện ích mở rộng này, hãy mạnh dạn [tạo một yêu cầu chức năng](https://github.com/Anarios/return-youtube-dislike/issues/new?assignees=&labels=enhancement&template=feature-request.yml&title=%28Feature+Request%29%3A+), nhưng hãy chắc rằng bạn đã tìm và không thấy yêu cầu tính năng y hệt trong danh sách yêu cầu tính năng. Dùng mẫu đơn yêu cầu tính năng nếu có thể, nhưng không bắt buộc.

#### Thực hiện một yêu cầu tính năng <!-- #### Implementing a feature request -->

Nếu bạn cảm thấy có thể thực hiện một tính năng nào đó, đừng ngần ngại. Hãy tạo một [yêu cầu kéo](https://github.com/Anarios/return-youtube-dislike/pulls) cho sự thay đổi của bạn và nhớ hãy ghi tên tính năng mà bạn thực hiện.

### Những yêu cầu kéo mà chúng tôi chấp nhận? <!-- ### What PRs do we accept? -->

- Giải quyết vấn đề.
- Thực hiện tính năng.
- Sửa lỗi chính tả hoặc đề xuất cách dùng từ tốt hơn.
- Đóng góp cho trang mạng.


================================================
FILE: Docs/FAQ.md
================================================
Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [Português do Brasil](FAQpt_BRmd), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)


# Frequently Asked Questions

## Before asking a question on GitHub or Discord, please refer to this.

<br>

### **1. Where does this extension get the data?**

A Combination of Google APIs and scraped data.

We save all available data to our DB for it to be available after Google shuts down dislike counts in their API.

<br>

### **2. Video dislike count doesn't update**

Right now video dislikes are cached, and aren't updated very frequently. Once every 2-3 days, not more often.

Yeah, it's not ideal, but it is what it is. Working on improving how often we can update them.

<br>

### **3. How does this work?**

The extension collects the video id of the video you are watching, fetches the dislike (and other fields like views, likes etc) using our API, if this is the first time the video was fetched by our API, it will use the YouTube API to get the data, then stores the data in a database for caching (cached for around 2-3 days) and archiving purposes and returns it to you. The extension then displays the dislikes to you.

<br>

### **4. What will happen after the YouTube API stops returning the dislike count?**

The backend will switch to using a combination of archived dislike stats, estimates extrapolated from extension user data and estimates based on view/like ratios for videos whose dislikes weren't archived and for outdated dislike archives.

<br>

### **5. How is the dislike count calculated?**

RYD uses the votes from its users to extrapolate the dislike count.

- If the video was uploaded after the API was shut down:

  $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$

- If the RYD database somehow had the actual like and dislike count (provided by the uploader or from the archive), the dislike count will be calculated based on both - the users' votes and the archived value. The archived value will have less influence on the final count as it ages.

<br>

---

This in video form

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## I have security / privacy concerns

See [this page](SECURITY-FAQ.md) for more info.


================================================
FILE: Docs/FAQar.md
================================================
اقرأ هذا بلغات أخرى: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [Português do Brasil](FAQpt_BRmd)

# الأسئلة الشائعة

## قبل طرح سؤال على GitHub أو Discord، يرجى الرجوع إلى هذا.

<br>

### **1. من أين تحصل هذه الإضافة على البيانات؟**

مزيج من واجهات برمجة تطبيقات Google والبيانات المستخرجة.

نحن نحفظ جميع البيانات المتاحة في قاعدة بياناتنا لتكون متاحة بعد أن تقوم Google بإيقاف عداد عدم الإعجاب في واجهة برمجة التطبيقات الخاصة بهم.

<br>

### **2. عداد عدم الإعجاب بالفيديو لا يتم تحديثه**

حاليًا، يتم تخزين عدم الإعجاب بالفيديو مؤقتًا، ولا يتم تحديثه بشكل متكرر. مرة كل 2-3 أيام، وليس أكثر.

نعم، إنه ليس مثاليًا، لكنه ما هو عليه. نعمل على تحسين عدد مرات التحديث.

<br>

### **3. كيف يعمل هذا؟**

تجمع الإضافة معرف الفيديو الذي تشاهده، وتسترجع عدم الإعجاب (وحقول أخرى مثل المشاهدات، الإعجابات، إلخ) باستخدام واجهة برمجة التطبيقات الخاصة بنا، إذا كانت هذه هي المرة الأولى التي يتم فيها استرجاع الفيديو بواسطة واجهة برمجة التطبيقات الخاصة بنا، فستستخدم واجهة برمجة تطبيقات YouTube للحصول على البيانات، ثم تخزن البيانات في قاعدة بيانات للتخزين المؤقت (مخزنة مؤقتًا لمدة 2-3 أيام) ولأغراض الأرشفة وتعيدها إليك. ثم تعرض الإضافة عدم الإعجاب لك.

<br>

### **4. ماذا سيحدث بعد أن تتوقف واجهة برمجة تطبيقات YouTube عن إرجاع عداد عدم الإعجاب؟**

سيتحول الخلفية إلى استخدام مزيج من إحصائيات عدم الإعجاب المؤرشفة، والتقديرات المستخلصة من بيانات مستخدمي الإضافة والتقديرات بناءً على نسب المشاهدة/الإعجاب للفيديوهات التي لم يتم أرشفة عدم الإعجاب بها ولأرشيفات عدم الإعجاب القديمة.

<br>

### **5. كيف يتم حساب عداد عدم الإعجاب؟**

تستخدم RYD أصوات مستخدميها لاستخلاص عداد عدم الإعجاب.

- إذا تم تحميل الفيديو بعد إيقاف واجهة برمجة التطبيقات:

  $$ \textup{عداد عدم الإعجاب في RYD} = \left( \frac{\textup{عداد عدم الإعجاب لمستخدمي RYD}}{\textup{عداد الإعجاب لمستخدمي RYD}} \right) \times \textup{عداد الإعجاب العام} $$

- إذا كانت قاعدة بيانات RYD تحتوي بطريقة ما على عداد الإعجاب وعدم الإعجاب الفعلي (مقدم من الناشر أو من الأرشيف)، فسيتم حساب عداد عدم الإعجاب بناءً على كل من - أصوات المستخدمين والقيمة المؤرشفة. سيكون للقيمة المؤرشفة تأثير أقل على العد النهائي مع مرور الوقت.

<br>

---

هذا في شكل فيديو

[![شرح IReturn YouTube Dislike](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## لدي مخاوف بشأن الأمان / الخصوصية

انظر [هذه الصفحة](SECURITY-FAQ.md) لمزيد من المعلومات.

================================================
FILE: Docs/FAQaz.md
================================================
Bunu digər dillərdə oxuyun: [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md)

# Tez-tez verilən suallar

## GitHub və ya Discord-da sual verməzdən əvvəl bura nəzər salın.

<br>

### **1.Bu uzantı məlumatları haradan əldə edir??**

Google API-lərin və silinmiş məlumatların birləşməsi.Google API-lərin və silinmiş məlumatların birləşməsi.

Google öz API-də bəyənməmə saylarını bağladıqdan sonra istifadə oluna bilməsi üçün bütün mövcud məlumatları verilənlər bazamızda saxlayırıq.
<br>

### **2. Videonun bəyənməmə sayı yenilənmir**

Hazırda videonun bəyənməmələri keşlənir və tez-tez yenilənmir. Hər 2-3 gündə, daha tez-tez deyil.

Bəli, bu ideal deyil, amma olduğu kimidir. Biz bunları daha tez-tez necə yeniləyə biləcəyimizi anlamaq üzərində işləyirik.
<br>

### **3. Bu uzantı necə işləyir?**

Artırma bizim API-dən istifadə edərək baxdığınız videonun video identifikatorunu götürür, bəyənmədiklərini (və baxışlar, bəyənmələr və s. kimi digər sahələri) alır; video API tərəfindən ilk dəfə alınırsa, YouTube API-dən istifadə edir. Məlumatları əldə etmək üçün o, keşləmə (təxminən 2-3 gün ərzində yaddaşda saxlanılır) və arxivləşdirmə məqsədləri üçün verilənlər bazasında saxlanılır və sizə qaytarılır. Daha sonra uzantı sizə bəyənmədiyinizləri göstərir.

<br>

### **4. YouTube API bəyənməmə saylarını qaytarmağı dayandırdıqda nə baş verir?**

Backend arxivləşdirilmiş bəyənməmə statistikası, genişləndirmə istifadəçi məlumatlarından ekstrapolyasiya edilmiş təxminlər və arxivləşdirilməmiş videolar və köhnə bəyənməmə arxivləri üçün baxış/bəyənmə nisbətlərinə əsaslanan təxminlərin birləşməsindən istifadə etməyə keçəcək.

<br>

### **5. Bəyənməmələrin sayı necə hesablanır?**

YDS bəyənməmələrin sayını hesablamaq üçün istifadəçilərinin səslərindən istifadə edir.

- Video API bağlandıqdan sonra yüklənibsə:

  $$ \textup{YDS Bəyənməmə Sayısı} = \left( \frac{\textup{YDS İstifadəçiləri Saymağı Bəyənirlər}}{\textup{YDS İstifadəçilərinin Bəyənmədiyi Say}} \right) \times \textup{İctimai Bəyənmə Sayısı} $$

- Əgər YDS verilənlər bazasında hansısa şəkildə real bəyənmə və bəyənməmə sayları varsa (yükləyən və ya arxivdən təqdim olunur), bəyənməmə sayı həm istifadəçilərin səsləri, həm də arxivləşdirilmiş dəyər əsasında hesablanacaq. Arxivləşdirilmiş dəyər yaşlandıqca son hesaba daha az təsir edəcək.
<br>

---

Bu video formada

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Məxfilik/təhlükəsizliklə bağlı narahatlıqlarım var
Ətraflı məlumat üçün [bu səyfə](SECURITY-FAQtr.md)ya baxın.


================================================
FILE: Docs/FAQbg.md
================================================
Прочетете това на други езици:  [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md)


# Често задавани въпроси

## Преди да зададете въпрос в GitHub или Discord, моля, обърнете се към това.

<br>

### **1. Откъде взема разширението тези данни?**

Комбинация от Google APIs и скрейпнати данни.

Запазваме всички налични данни в нашата база данни, за да бъдат налични след като Google затвори броя на дизлайковете в техния API.

<br>

### **2. Броят на дизлайковете на видеото не се обновява**

В момента дизлайковете на видеата се кешират и не се обновяват много често. Веднъж на всеки 2-3 дни, не по-често.

Да, не е идеално, но каквото, такова. Работим по подобрение на това, колко често можем да ги актуализираме.

<br>

### **3. HКак работи това?**

Разширението взима video id на видеото, което гледате, извлича дизлайковете (и други полета като гледания, харесвания и т.н.) чрез нашия API. Ако това е първият път, когато видеото беше извлечено от нашия API, той ще използва YouTube API, за да получи данните, след което ще ги запази в база данни за кеширане (кеширане за около 2-3 дни) и архивиране и ще ги върне. Разширението след това ви показва дизлайковете.

<br>

### **4. Какво ще стане, след като YouTube API спре да връща броя на дизлайковете?**

Бекендът ще премине към използване на комбинация от архивирани статистики за дизлайкове, оценки екстраполирани от данните на потребителите на разширението и оценки на базата на съотношението гледания/харесвания за видеа, чиито дизлайкове не са били архивирани и за стари архиви с дизлайкове.

<br>

### **5. Как се изчислява броят на дизлайковете?**

RYD използва гласовете от своите потребители, за да екстраполира броя на дизлайковете.

- Ако видеото е качено след като API е затворил:

  $$ \textup{RYD Брой на дизлайковете} = \left( \frac{\textup{RYD Брой на дизлайковете от потребителите}}{\textup{RYD Брой на харесвания от потребителите}} \right) \times \textup{Общ брой харесвания} $$

- Ако базата данни на RYD по някакъв начин има реалния брой на харесвания и дизлайкове (предоставени от качителя или от архива), броят на дизлайковете ще бъде изчислен на базата и на гласовете на потребителите, и на архивната стойност. Архивната стойност ще има по-малко влияние върху крайния брой, докато остарее.

<br>

---

Това във видео форма

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Имам опасения относно сигурността / личните данни

Вижте [тази страница](SECURITY-FAQbg.md) за повече информация.


================================================
FILE: Docs/FAQcn.md
================================================
以其他语言阅读: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [Português do Brasil](FAQpt_BRmd)


# 常见问题

## 在 GitHub 或 Discord 上提问之前,请先参阅此内容.

<br>

### **1. 此扩展程序从哪里获取数据?**

Google API 和抓取数据的组合。

我们将所有可用数据保存到我们的数据库中,以便 Google 关闭其 API 中的不喜欢计数后仍可用。

<br>

### **2. 视频不喜欢计数未更新**

目前,视频的点赞信息会被缓存,更新频率不高。每 2-3 天更新一次,不会更频繁。

这并不理想,但这就是现状。我们正在努力提高更新频率。

<br>

### **3. 这是如何运作的?**

该扩展程序会收集您正在观看的视频的视频 ID,使用我们的 API 获取不喜欢的内容(以及其他字段,如观看次数、喜欢次数等),如果这是我们的 API 首次获取该视频,它将使用 YouTube API 获取数据,然后将数据存储在数据库中以供缓存(缓存约 2-3 天)和存档,并将其返回给您。然后,该扩展程序会向您显示不喜欢的内容。

<br>

### **4. YouTube API 停止返回不喜欢计数后会发生什么?**

后端将切换到使用已存档的不喜欢统计数据、从扩展用户数据推断出的估计值以及基于未存档的不喜欢的视频和过时的不喜欢存档的观看/喜欢比率的估计值的组合。

<br>

### **5. 如何计算不喜欢数?**

RYD 使用用户的投票来推断不喜欢的数量。

- 如果视频是在 API 关闭后上传的:

  $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$

- 如果 RYD 数据库以某种方式拥有实际的喜欢和不喜欢计数(由上传者提供或来自存档),则不喜欢计数将根据用户的投票和存档值计算。存档值随着时间的推移对最终计数的影响会越来越小。

<br>

---

这是视频形式

[![IReturn YouTube 不喜欢解释](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## I have security / privacy concerns

有关详细信息,请参阅[此页面](SECURITY-FAQ.md)。

================================================
FILE: Docs/FAQde.md
================================================
Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md)

# Häufig gestellte Fragen

## Bevor Sie eine Frage auf GitHub oder Discord stellen, sehen Sie bitte hier nach.

<br>

### **1. Woher stammt die Datenquelle dieser Erweiterung?**

Eine Kombination aus Google-APIs und gescrapten Daten.

Wir speichern alle verfügbaren Daten in unserer Datenbank, damit sie verfügbar sind, nachdem Google die Anzahl der Dislikes in ihrer API abschaltet.

<br>

### **2. Die Anzahl der Dislikes bei Videos aktualisiert sich nicht**

Aktuell werden die Dislikes bei Videos zwischengespeichert und nicht sehr häufig aktualisiert. Etwa alle 2-3 Tage, nicht öfter.

Ja, das ist nicht ideal, aber es ist wie es ist. Wir arbeiten daran, wie oft wir sie aktualisieren können, zu verbessern.

<br>

### **3. Wie funktioniert das?**

Die Erweiterung sammelt die Video-ID des von Ihnen angesehenen Videos, ruft die Dislikes (und andere Felder wie Aufrufe, Likes usw.) über unsere API ab. Wenn dies das erste Mal ist, dass das Video von unserer API abgerufen wurde, wird die YouTube-API verwendet, um die Daten zu erhalten. Anschließend werden die Daten für den Zwischenspeicher (ca. 2-3 Tage zwischengespeichert) und Archivierungszwecke in einer Datenbank gespeichert und an Sie zurückgegeben. Die Erweiterung zeigt Ihnen dann die Dislikes an.

<br>

### **4. Was passiert, wenn die YouTube-API aufhört, die Anzahl der Dislikes zurückzugeben?**

Das Backend wird auf eine Kombination aus archivierten Dislike-Statistiken, Schätzungen, die aus den Daten der Erweiterungsnutzer extrapoliert werden, und Schätzungen basierend auf Ansichts-/Like-Verhältnissen für Videos, deren Dislikes nicht archiviert wurden, und veralteten Dislike-Archiven umstellen.

<br>

### **5. Wie wird die Anzahl der Dislikes berechnet?**

RYD verwendet die Stimmen seiner Benutzer, um die Anzahl der Dislikes zu extrapolieren.

- Wenn das Video nach dem Abschalten der API hochgeladen wurde:

  $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$

- Wenn die RYD-Datenbank auf irgendeine Weise die tatsächliche Anzahl von Likes und Dislikes enthielt (vom Ersteller bereitgestellt oder aus dem Archiv), wird die Anzahl der Dislikes basierend auf beiden - den Stimmen der Benutzer und dem archivierten Wert - berechnet. Der archivierte Wert wird mit zunehmendem Alter weniger Einfluss auf die endgültige Zählung haben.

<br>

---

Dies in Videoform

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Ich habe Sicherheits-/Privatsphärebedenken

Siehe [diese Seite](SECURITY-FAQde.md) für weitere Informationen.


================================================
FILE: Docs/FAQfr.md
================================================
Lisez ceci dans d'autres langues : [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Foire Aux Questions

## Avant de poser une question sur GitHub ou Discord, veuillez vous référer à ceci.

### **1. Où cette extension obtient-elle les données ?**

Une combinaison d'API de Google et de données scrapées.

Nous sauvegardons toutes les données disponibles dans notre base de données pour qu'elles soient disponibles après que Google ait supprimé le compteur de dislikes dans son API.

### **2. Le nombre de dislikes sur les vidéos n'est pas mis à jour**

Actuellement, les dislike sont mis en cache et ne sont pas mis à jour très fréquemment. Une fois tous les 2-3 jours, pas plus souvent.

Oui, ce n'est pas idéal, mais c'est ce que c'est. Nous travaillons à améliorer la fréquence des mises à jour.

### **3. Comment cela fonctionne-t-il ?**

L'extension collecte l'ID de la vidéo que vous regardez, récupère les dislikes (et d'autres champs comme les vues, les likes etc.) en utilisant notre API, si c'est la première fois que la vidéo a été récupérée par notre API, elle utilisera l'API YouTube pour obtenir les données, puis stocke les données dans une base de données pour la mise en cache (mise en cache pendant environ 2-3 jours) et à des fins d'archivage et vous les renvoie. L'extension vous affiche ensuite les dislikes.

### **4. Que se passera-t-il lorsque l'API YouTube ne renverra plus le nombre de dislikes ?**

Le backend utilisera une combinaison de statistiques du nombre de dislikes archivées, d'estimations extrapolées à partir des données d'extension des utilisateurs et d'estimations basées sur les ratios vues/likes pour les vidéos dont les dislikes n'ont pas été archivées et pour les archives dont le nombre de dislikes est obsolète.

## Je suis préoccupé par la sécurité / la confidentialité

Voir [cette page](SECURITY-FAQfr.md) pour plus d'informations.


================================================
FILE: Docs/FAQid.md
================================================
Baca ini dibahasa lain: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [Português do Brasil](FAQpt_BRmd)


# Pertayaan yang Sering Ditanyakan

## Sebelum bertanya di GitHub atau Discord, tolong lihat halaman ini.

<br>

### **1. Darimana extension ini mendapatkan datanya?**

Kombinasi dari API Google dan scraping data.

Kami telah menyimpan semua data yang ada kedalam DB agar datanya tetap ada meskipun setelah Google menghapus jumlah dislike dari API mereka.

<br>

### **2. Jumlah dislike video tidak update**


Sekarang jumlah dislike video dicache, dan tidak update selalu.
Sekali setiap 2-3 hari, tidak lebih dari itu.

Benar, itu tidak ideal, tapi inilah yang bisa kami lakukan dan kami sedang melakukan improvisasi agar dapat melakukan update sesering mungkin.

<br>

### **3. Bagaimana cara kerjanya?**

Extension mengumpulkan id dari video yang sedang ditonton, mengambil data dislike (dan lainnya seperti jumlah views, likes, dll) menggunakan API kami, jika video ini pertama kali diambil datanya menggunakan API kami, API yang digunakan akan diubah ke API Youtube untuk mengambil datanya dan datanya akan disimpan kedalam database kami untuk dilakukan cache (untuk 2-3 hari) yang bertujuan untuk pengarsipan data dan datanya dikembalikan ke kamu. Lalu extension akan menampilkan jumlah dislike ke kamu.

<br>

### **4. Apa yang akan terjadi setelah API Youtube menghapus jumlah dislike?**

Bagian backend akan berganti dengan menggunakan kombinasi dari data arsip dislike, estimasi perkiraan dari pengguna, dan estimasi berdasarkan jumlah rasio view/like untuk video yang dislikenya tidak diarsip dan arsip dislike yang sudah tua.

<br>

### **5. Bagaimana cara menghitung jumlah dislike?**

RYD mernggunakan sistem voting dari pengguna untuk memperkirakan jumlah dislike.

- Jika video diupload setelah API dislike dihapus:

  $$ \textup{Jumlah RYD Dislike} = \left( \frac{\textup{Jumlah RYD Dislike Pengguna}}{\textup{Jumlah RYD Like Pengguna}} \right) \times \textup{Jumlah Public Like Publik} $$

- Jika entah bagaimana Database RYD memiliki data jumlah asli dari like dan dislike (diberikan dari pengupload atau arsip), jumlah dislike akan dihitung berdasarkan jumlah voting dari pengguna dan arsip. Semakin tua data arsip maka semakin sedikit pengaruhnya ke hasil akhir perhitungan dislike.

<br>

---

Berikut adalah form video

[![Mengenai IReturn YouTube Dislike](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Saya memiliki masalah keamanan/privasi

Lihat [halaman ini](SECURITY-FAQid.md) untuk informasi lebih lanjut.


================================================
FILE: Docs/FAQnl.md
================================================
Lees dit in andere talen: [Engels](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Veel Gestelde Vragen

## Raadpleeg deze voordat u een vraag stelt op GitHub of Discord.

<br>

### **1. Waar haalt deze extensie de gegevens vandaan?**

Een combinatie van Google API's en geschraapte gegevens.

We slaan alle beschikbare gegevens op in onze database, zodat deze beschikbaar is nadat Google het aantal dislikes in hun API heeft stopgezet.

<br>

### **2. Het aantal video-dislikes wordt niet bijgewerkt**

Op dit moment worden video's die niet leuk zijn in het cachegeheugen opgeslagen en worden niet erg vaak bijgewerkt. Eens in de 2-3 dagen, niet vaker.

Ja, het is niet ideaal, maar het is wat het is. Werken aan het verbeteren van hoe vaak we ze kunnen bijwerken.

<br>

### **3. Hoe werkt dit?**

De extensie verzamelt de video-ID van de video die je aan het bekijken bent, haalt de dislike (en andere velden zoals views, likes etc) op met behulp van onze API. Als dit de eerste keer is dat de video wordt opgehaald door onze API, zal deze de YouTube API gebruiken om de gegevens op te halen, slaat de gegevens vervolgens op in een database voor caching (cache voor ongeveer 2-3 dagen) en archiveringsdoeleinden en stuurt ze naar u terug. De extensie geeft vervolgens de antipathieën aan u weer.

<br>

### **4. Wat gebeurt er nadat de YouTube API stopt met het teruggeven van het aantal dislikes?**

De backend zal overschakelen naar het gebruik van een combinatie van afkeer statistieken en afkeer archieven, schattingen geëxtrapoleerd uit gebruikersgegevens van extensies en schattingen op basis van weergave/vind-ik-leuk-verhoudingen voor video's waarvan de afkeuren niet zijn gearchiveerd en voor verouderde afkeer-archieven.

<br>

### **5. Hoe wordt het aantal dislikes berekend?**

RYD gebruikt de stemmen van zijn gebruikers om het aantal dislikes te extrapoleren.

- Als de video is geüpload nadat de API was afgesloten:

  $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Like Count}}{\textup{RYD Users Dislike Count}} \right) \times \textup{Public Like Count} $$

- Als de RYD-database op de een of andere manier het werkelijke aantal likes en dislikes had (geleverd door de uploader of uit het archief), wordt het aantal dislikes berekend op basis van zowel de stemmen van de gebruikers als de gearchiveerde waarde. De gearchiveerde waarde heeft minder invloed op de uiteindelijke telling naarmate deze ouder wordt.

<br>

---

Dit in videovorm

[![IReturn YouTube Dislike Uitgelegd (Engels)](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Ik heb zorgen over de beveiliging/privacy

Bekijk [deze pagina](SECURITY-FAQnl.md) voor meer informatie.


================================================
FILE: Docs/FAQpl.md
================================================
Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Często zadawane pytania

## Przeczytaj poniższe przed zadawaniem pytań na GitHubie lub Discordzie.

<br>

### **1.Skąd rozszerzenie otrzymuje swoje dane?**

Kombinacja API Google i danych scrape-owanych.

Zapisujemy wszystkie dostępne dane do naszej bazy danych, żeby były dostępne po tym jak Google wyłączy liczniki łapek w dół w swoim API.

<br>

### **2. Licznik łapek w dół się nie aktualizuje**

Na chwile obecną łapki w dół są buforowane i nie są bardzo często aktualizowane. Raz na 2-3 dni, nie częściej.

No nie jest to idealne, ale tak już jest. Pracujemy nad tym jak częściej możemy to aktualizować.

<br>

### **3. Jak to działa?**

Rozszerzenie zbiera ID filmu, którego oglądasz, pobiera ilość łapek w dół (i inne pola, takie jak wyświetlenia, łapki w górę itd.) za pomocą naszego API. Jeżeli film jest pierwszy raz pobrany przez nasze API, zostanie użyte YouTube API do pobrania danych, a potem przechowania w bazie danych do buforu (przez jakieś 2-3 dni) i archiwizacji, po czym zwracane jest Tobie. Rozszerzenie potem wyświetla ilość łapek w dół.

<br>

### **4. Co się wydarzy gdy YouTube API przestanie zwracać liczbę łapek w dół?**

Backend przełączy się na używanie kombinacji zarchiwizowanych statystyk łapek w dół, szacunków ekstrapolowanych z danych użytkowników rozszerzenia i szacowań opartych na stosunkach wyświetleń/łapek w górę dla filmów, których ilość łapek w dół nie została zarchiwizowana i dla przestarzałych archiwów.

<br>

### **5. Jak wyliczana jest liczba łapek w dół?**

RYD używa głosów użytkowników, aby ekstrapolować liczbę łapek w dół.

- Jeżeli film został wrzucony przed wyłączeniem API:

  $$ \textup{Liczba łapek w dół RYD} = \left( \frac{\textup{Liczba łapek w dół użytkowników RYD}}{\textup{Liczba łapek w górę użytkowników RYD}} \right) \times \textup{Publiczna liczba łapek w górę} $$

- Jeśli baza danych RYD jakimś cudem miałaby prawidłową liczbę łapek w górę i dół (zapewnione przez twórce lub z archiwum), liczba łapek w dół będzie obliczana w oparciu jednocześnie głosów użytkowników i wartości zarchiwizowanych. Zarchiwizowana wartość będzie miała mniejszy wpływ na ostateczną liczbę z biegiem czasu.

<br>

---

To samo w formie filmu.

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Mam zastrzeżenia co do bezpieczeństwa / prywatności

Przejdź [tutaj](SECURITY-FAQ.md) aby uzyskać więcej informacji.


================================================
FILE: Docs/FAQpt_BR.md
================================================
Leia isso em outros Idiomas: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md)

# Frequently Asked Questions

## Before asking a question on GitHub or Discord, please refer to this.

<br>

### **1. Where does this extension get the data?**

A Combination of Google APIs and scraped data.

We save all available data to our DB for it to be available after Google shuts down dislike counts in their API.

<br>

### **2. Video dislike count doesn't update**

Right now video dislikes are cached, and aren't updated very frequenly. Once every 2-3 days, not more often.

Yeah, it's not ideal, but it is what it is. Working on improving how often we can update them.

<br>

### **3. How does this work?**

The extension collects the video id of the video you are watching, fetches the dislike (and other fields like views, likes etc) using our API, if this is the first time the video was fetched by our API, it will use the YouTube API to get the data, then stores the data in a database for caching (cached for around 2-3 days) and archiving purposes and returns it to you. The extension then displays the dislikes to you.

<br>

### **4. What will happen after the YouTube API stops returning the dislike count?**

The backend will switch to using a combination of archived dislike stats, estimates extrapolated from extension user data and estimates based on view/like ratios for videos whose dislikes weren't archived and for outdated dislike archives.

<br>

### **5. How is the dislike count calculated?**

RYD uses the votes from its users to extrapolate the dislike count.

- If the video was uploaded after the API was shut down:

  $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$

- If the RYD database somehow had the actual like and dislike count (provided by the uploader or from the archive), the dislike count will be calculated based on both - the users' votes and the archived value. The archived value will have less influence on the final count as it ages.

<br>

---

Essa a This in video form

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## I have security / privacy concerns

See [this page](SECURITY-FAQpt_BR.md) for more info.


================================================
FILE: Docs/FAQru.md
================================================
Read this in other languages: [English](FAQ.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Часто задаваемые вопросы

## Прежде чем задать вопрос на GitHub или в Discord, пожалуйста, ознакомьтесь с этим.

### **1. Откуда это расширение получает данные?**

Комбинация API Google и старых данных.

Мы сохраняем все имеющиеся данные в нашей базе данных, чтобы они были доступны после того, как Google прекратит подсчёт отметок «Не нравится» в своём API.

### **2. Количество не понравившихся видео не обновляется**

В настоящее время видео с отметками «Не нравится» кэшируются и обновляются не очень часто. Раз в 2-3 дня, не чаще.

Да, это не идеально, но это то, что есть. Мы работаем над тем, чтобы улучшить частоту их обновления.

### **3. Как это работает?**

Расширение собирает идентификатор видео, которое вы смотрите, извлекает данные об отметках «Не нравится» (и другие поля, такие как просмотры, отметки «Нравится» и т.д.) с помощью нашего API, если видео было извлечено нашим API впервые, оно использует YouTube API для получения данных, затем сохраняет данные в базе данных для кэширования (кэшируются около 2-3 дней) и архивирования и возвращает их вам. После этого расширение отображает отметки «Не нравится» вам.

### **4. Что произойдёт после того, как API YouTube перестанет возвращать данные о количестве отметок «Не нравится»?**

Внутренняя часть нашего сервера переключится на использование комбинации архивных статистик отметок «Не нравится», оценок, экстраполированных из данных о пользователях расширения, и оценок, основанных на соотношении просмотров и отметок «Нравится» для видео, чьи отметки «Не нравится» не были заархивированы, и для устаревших архивов с отметками «Не нравится».

## Я беспокоюсь о безопасности / конфиденциальности

Более подробную информацию смотрите на [этой странице](SECURITY-FAQ.md).


================================================
FILE: Docs/FAQtr.md
================================================
Bunu diğer dillerde okuyun: [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [українська](FAQuk.md), [Polski](FAQpl.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Sıkça Sorulan Sorular

## GitHub'da veya Discord'da bir soru sormadan önce, lütfen buraya göz atın.

<br>

### **1. Bu uzantı verileri nereden alıyor?**

Google API'lerinin ve kazınmış verilerin bir kombinasyonu.

Google, API'lerinde dislike sayılarını kapattıktan sonra kullanılabilir olması için mevcut tüm verileri DB'mize kaydederiz.

<br>

### **2. Video'nun dislike sayısı güncellenmiyor**

Şu anda video dislike'ları önbelleğe alınır ve çok sık güncellenmez. Her 2-3 günde bir, daha sık değil.

Evet, ideal değil, ama olan bu. Bunları nasıl daha sık güncelleyebileceğimizi öğrenmeye çalışıyoruz.

<br>

### **3. Bu uzantı nasıl çalışıyor?**

Uzantı, izlediğiniz videonun video kimliğini alır, dislike'larını (ve görüntülemeleri, like'ları vb. diğer alanları) API'mizi kullanarak getirir; video, API'miz tarafından ilk kez getiriliyorsa YouTube API'sini kullanır. Verileri almak için, verileri önbelleğe alma (yaklaşık 2-3 gün önbelleğe alınır) ve arşivleme amacıyla bir veritabanında saklanır ve size geri döndürülür. Uzantı daha sonra size dislike'ları gösterir.

<br>

### **4. YouTube API'si, dislike sayısını döndürmeyi durdurduğunda ne olacak?**

Backend, arşivlenmiş dislike istatistikleri, uzantı kullanıcı verilerinden tahmin edilen tahminler ve like'ları arşivlenmemiş videolar ve eski dislike arşivleri için izlenme/like oranlarına dayalı tahminlerin bir kombinasyonunu kullanmaya geçecektir.

<br>

### **5. Dislike sayısı nasıl hesaplanıyor?**

YDS, dislike sayısını tahmin etmek için kullanıcılarının oylarını kullanır.

- Video, API kapatıldıktan sonra yüklendiyse:

  $$ \textup{YDS'nin Dislike Sayısı} = \left( \frac{\textup{YDS Kullanıcılarının Like Sayısı}}{\textup{YDS Kullanıcılarının Dislike Sayısı}} \right) \times \textup{Halka Açık Like Sayısı} $$

- YDS veritabanı bir şekilde gerçek like ve dislike sayısına sahipse (yükleyici tarafından veya arşivden sağlanır), dislike sayısı hem kullanıcıların oyları hem de arşivlenen değer temelinde hesaplanacaktır. Arşivlenen değer, eskidikçe son sayım üzerinde daha az etkiye sahip olacaktır.

<br>

---

Bu video şeklinde

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Gizlilik / güvenlik hakkında endişelerim var

Daha fazla bilgi için [bu sayfa](SECURITY-FAQtr.md)ya göz atın.


================================================
FILE: Docs/FAQuk.md
================================================
Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [Deutsch](FAQde.md), [العربية](FAQar.md), [Bahasa Indonesia](FAQid.md), [中文](FAqcn.md), [български](FAQbg.md), [Tiếng Việt](FAQvi.md)

# Часті питання

## Перш ніж задавати питання на GitHub або у Discord, будь ласка, ознайомтеся з цим.

<br>

### **1. Звідки це розширення отримує дані?**

Комбінація Google API та старих даних.

Ми зберігаємо всі доступні дані в нашій базі, аби вони були доступні після того, як Google вимкне лічильник відміток «Не подобається» у своєму API.

<br>

### **2. Лічильник «Не подобається» не оновлюється**

Наразі відео з відмітками «Не подобається» кешуються і оновлюються не надто часто. Не частіше, ніж раз в 2-3 дні.

Так, це не ідеально, але маємо те, що маємо. Ми працюємо над тим, щоб збільшити частоту їх оновлення.

<br>

### **3. Як це працює?**

Розширення отримує ID відео, яке ви переглядаєте, та дізнається кількість відміток «Не подобається» (та інші дані: перегляди, відмітки «Подобається» тощо) за допомогою нашого API, якщо відео було витягнуте нашим API вперше, воно використовує YouTube API для отримання даних, потім зберігає дані в базі даних для кешування (кешуються близько 2-3 днів) та архівування й повертає їх вам. Після цього розширення відображає відмітки «Не подобається» вам.

<br>

### **4. Що станеться після того, як YouTube API перестане повертати кількість відміток «Не подобається»?**

Сервер перейде на використання комбінації заархівованих статистичних даних відміток «Не подобається» екстрапольованих із даними .

<br>

### **5. Як розраховується кількість відміток «Не подобається»?**

RYD використовує відмітки своїх користувачів, щоб екстраполювати кількість відміток «Не подобається».

- Якщо відео було завантажено після вимкнення API:

  $$ \textup{К-ть відміток «Не подобається» у RYD} = \left( \frac{\textup{К-ть відміток «Подобається» серед користувачів RYD}}{\textup{К-ть відміток «Не подобається» серед користувачів RYD}} \right) \times \textup{Публічна к-ть відміток «Подобається»} $$

- Якщо база даних RYD якимось чином мала фактичну кількість відміток «Подобається» та «Не подобається» (надану завантажувачем або з архіву), кількість відміток «Не подобається» буде розраховано на основі відміток користувачів і архівного значення. Архівне значення матиме менший вплив на остаточний підрахунок у міру актуальності.

<br>

---

Це все, але у відео форматі

[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Я турбуюся про безпеку/конфіденційність

Детальніше про це дивіться [тут](SECURITY-FAQuk.md).


================================================
FILE: Docs/FAQvi.md
================================================
Đọc bằng các ngôn ngữ khác: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), [Polski](FAQpl.md)


# Câu Hỏi Thường Gặp <!-- # Frequently Asked Questions -->

## Trước khi đưa ra bất kì câu hỏi nào trên GitHub hay trên Discord, vui lòng đọc hết trang này. <!-- ## Before asking a question on GitHub or Discord, please refer to this. -->

<br>

### **1. Tiện ích mở rộng này lấy dữ liệu từ đâu?** <!-- ### Where does this extension get the data? -->

Kết hợp dữ liệu lấy từ API của Google và dữ liệu thu thập được.

Chúng tôi lưu giữ tất cả dữ liệu mà chúng tôi có được vào cơ sở dữ liệu của chúng tôi, kể từ khi Google loại bỏ số lượt đánh giá "không thích" khỏi API của họ.

<br>

### **2. Số lượt "không thích" không được cập nhật** <!-- ### Video dislike count doesn't update -->

Hiện tại, các lượt đánh giá "không thích" sẽ được lưu lại và số lượt đánh giá tổng được hiển thị không được cập nhật thường xuyên. Thông thường, cứ mỗi 2 đến 3 ngày, chứ không ngắn hơn.

Đồng ý rằng điều này không đáng mong chờ, nhưng hiện tại thì tiện ích hoạt động như vậy. Chúng tôi đang cố gắng cải thiện tần suất nhật số lượt đánh giá.

<br>

### **3. Cách thức hoạt động của tiện ích mở rộng này?** <!-- ### How does this work? -->

Tiện ích này thu thập ID của vi-đê-ô mà bạn đang xem, truy vấn đánh giá của vi-đê-ô (bao gồm số lượt "không thích", số lượt "thích", số lượt xem, v.v.) bằng API của chúng tôi. Nếu đây là đầu tiên diễn ra truy vấn tới API của chúng tôi đối với vi-đê-ô này, tiện ích sẽ sử dụng API của YouTube sẽ truy vấn các thông tin cần thiết, sau đó lưu trữ các thông tin này vào cơ sở dữ liệu cho mục đích truy vấn nhanh (trong vòng 2 đến 3 ngày) và cho mục đích lưu trữ và sẽ trả kết quả truy vấn về cho bạn. Lúc này, tiện ích sẽ hiện thị số lượt đánh giá "không thích" cho bạn xem.

<br>

### **4. Việc gì sẽ diễn ra sau khi API của YouTube ngừng cung cấp số lượt "không thích"?** <!-- ### What will happen after the YouTube API stops returning the dislike count? -->

Đầu sau của tiện ích sẽ chuyển sang sử dụng kết hợp dữ liệu đã được lưu trữ về số lượt đánh giá "không thích", những ước tính ngoại suy từ dữ liệu người dùng của tiện ích và những ước tính dựa trên tỉ lệ lượt xem/lượt "thích" đối với những vi-đê-ô chưa lưu được số lượt "không thích" và đối với các kho lưu trữ số lượt "không thích" lỗi thời. 

<br>

### **5. Số lượt đánh giá "không thích" được tính như thế nào?** <!-- ### How is the dislike count calculated? -->

RYD sử dụng đánh giá từ người dùng để ngoại suy số lượt đánh giá "không thích".

- Nếu vi-đê-ô được đăng tải sau khi API của YouTube loại bỏ trường `dislike`:

  $$ \textup{Số lượt "Không thích" của RYD} = \left( \frac{\textup{Số lượt "Không thích" từ Người dùng của RYD}}{\textup{Số lượt "Thích" từ Người dùng của RYD}} \right) \times \textup{Số lượt "Thích" từ API của YouTube} $$

- Nếu cơ sở dữ liệu của RYD có được số lượt đánh giá "thích" và "không thích" thực (được cung cấp bởi chủ vi-đê-ô hay từ kho lưu trữ), số lượt đánh giá "không thích" sẽ được tính dựa trên đồng thời (1) đánh giá từ người dùng của tiện ích và (2) số liệu được lưu trữ. Số liệu được lưu trữ sẽ càng ngày càng kém quan trọng trong việc tính toán số lượt đánh giá.

<br>

---

Vi-đê-ô thông tin về Return YouTube Dislike:

[Giải thích về Return YouTube Dislike (Tiếng Anh)](https://www.youtube.com/watch?v=GSmmtv-0yYQ)

---

<br>

## Tôi có thắc mắc về tính bảo mật / quyền riêng tư <!-- ## I have security / privacy concerns -->

Vui lòng tham khảo [trang này](SECURITY-FAQvi.md) để biết thêm thông tin.


================================================
FILE: Docs/Guide__Installing.md
================================================
**Contents**

- [Downloading](#downloading)
  - [Desktop (all OS supported by these browsers)](#desktop-all-os-supported-by-these-browsers)
    - [Chromium Based Browsers](#chromium-based-browsers)
    - [Firefox Based Browsers](#firefox-based-browsers)
  - [Mobile](#mobile)
    - [Android](#android)
    - [iOS](#ios)
    - [Userscript](#userscript)
- [Installation](#installation)
  - [Desktop](#desktop)
    - [**Chromium based browsers**](#chromium-based-browsers-1)
      - [From Chrome Webstore](#from-chrome-webstore)
      - [From crx/zip file](#from-crxzip-file)
      - [From unzipped folder](#from-unzipped-folder)
    - [**Firefox Based Browsers**](#firefox-based-browsers-1)
      - [From addon store](#from-addon-store)
      - [From xpi/jar/zip file](#from-xpijarzip-file)
  - [Mobile](#mobile-1)
    - [Android](#android-1)
      - [App from Play Store](#app-from-play-store)
      - [On Firefox](#on-firefox)
    - [iOS](#ios-1)
- [Using](#using)
- [Updating](#updating)
  - [Extension / Addon](#extension--addon)
- [Miscellaneous](#miscellaneous)
  - [Using YouTube website as an app with an extension](#using-youtube-website-as-an-app-with-an-extension)
    - [Desktop](#desktop-1)
      - [Chromium Based Browsers](#chromium-based-browsers-2)
      - [Firefox Based Browsers](#firefox-based-browsers-2)
    - [Mobile](#mobile-2)
      - [Firefox Based Browsers](#firefox-based-browsers-3)
      - [Chromium Based Browsers](#chromium-based-browsers-3)

<br>

<br>

## Downloading

### Desktop (all OS supported by these browsers)

<br>

#### [Chromium Based Browsers][4]

This extension has been tested to work on these browsers.

- [Google Chrome][1]
- [Microsoft Edge][1]
- [Brave][1]
- [Opera][1]

It should be able to work on [all Chromium-based browsers (list here)][4]. But that isn't guaranteed.

<br>

#### [Firefox Based Browsers][5]

- [Firefox][2]
- This addon should be able to run on most of the [Firefox-based browsers][5]. But isn't guaranteed.

<br>

### Mobile

#### Android

1. **F-Droid Store**

- [Show Youtube Dislikes](https://f-droid.org/en/packages/com.jesperh.showyoutubedislikes/)

  [Download from here (Click here)](https://f-droid.org/en/packages/com.jesperh.showyoutubedislikes/)

  The source code is available at [github.com/jesperbakhandskemager/view-youtube-dislike](https://github.com/jesperbakhandskemager/view-youtube-dislike)

  You can download the apk file from
  [https://github.com/jesperbakhandskemager/view-youtube-dislike/releases/](https://github.com/jesperbakhandskemager/view-youtube-dislike/releases/)

  **Note: This app is NOT made by the original author of the extension**.

2. [**Firefox Nightly**][2]

- This addon should be able to run on most of the [Firefox-based browsers][5]. But isn't guaranteed.

3. [**Chromium Based browsers**][4]

Most [**Chromium Based browsers**][4] **don't support extensions on Android or iOS**

However, [Kiwi Browser](https://kiwibrowser.com/) does. You can refer to this video - [Google Chrome Extensions on Android with Kiwi Browser!](https://youtu.be/T6J0T_-oim4)

<br>

#### iOS

No Support on Firefox

You can have a look at these pages for more information (the reason why it's not available on Firefox):

- [https://support.mozilla.org/en-US/kb/add-ons-firefox-ios]
- [https://support.mozilla.org/en-US/questions/1101350]

For now, you can try this

- [For Jailbroken iOS - **WE TAKE NO RESPONSIBILITY. USE AT YOUR OWN RISK**](https://chariz.com/get/return-youtube-dislike)

  This is an iOS port [**developed by a separate team**](https://github.com/PoomSmart/Return-YouTube-Dislikes) not related to the owner of github.com/Anarios/return-youtube-dislike

#### Userscript

[Download from here](https://returnyoutubedislike.com/install)

<br>

<br>

## Installation

### Desktop

<br>

#### [**Chromium based browsers**][4]

<br>

##### From Chrome Webstore

1. [Go to website (click here)][1]
2. Click install
3. Wait for the extension to download and
4. 🙂 Installed !!

<br>

##### From crx/zip file

1. Download the crx/zip file.
2. Type [`chrome://extensions`][6] in address bar
3. Search for the "Developer Mode" switch and turn it on.
4. Open the folder and the browser side by side.
5. Drag and drop the crx/zip file in [chrome://extensions][6] tab
6. Click on "Add extension"
7. Installation Completed 🎉
8. Remember to **turn off the "developer mode"** if not needed

<br>

##### From unzipped folder

1. Download the crx/zip file.
2. Go to [`chrome://extensions`][6]
3. Search for the "Developer Mode" switch and turn it on.
4. Click on "Load Unpacked"
5. Navigate to the folder & select it
6. The extension should be installed 🎉
7. Remember to **turn off the "developer mode"** if not needed

<br>

#### [**Firefox Based Browsers**][5]

##### From addon store

1. Go to the addon store and find the extension or [click here][2].
2. Click on `Add to Firefox`
3. Done 🎉 The extension should be installed.

<br>

##### From xpi/jar/zip file

1. Type `about:addons` in the address bar and press "Enter". Alternatively, You can use
   `Ctrl` + `Shift` + `A` on Windows and
   `Cmd` + `Shift` + `A` on Mac and
2. Click on the Setting Gear icon `⚙`.
3. Click on `Install Add-on From File...`
4. Locate and click on the .xpi/.jar/.zip file.
5. Select and click to open it.
6. Done 🎉 The extension should be installed.

<br>

### Mobile

#### Android

##### App from Play Store

- Although app(s) which use this API exist, they aren't official.

##### On Firefox

1. Install Firefox Nightly. Refer to this blog post for the procedure: [Expanded extension support in Firefox for Android Nightly](https://blog.mozilla.org/addons/2020/09/29/expanded-extension-support-in-firefox-for-android-nightly/)
2. Install the extension in it from [addon store][2]
3. If you want - install the site as an app. For that procedure [go here](#firefox-based-browsers-3).

#### iOS

- [For iOS click here](#ios)
- Only available on Firefox-based browsers because Chromium-based browsers for the Android platform don't support installing extensions.

<br>

<br>

## Using

No more steps are required, it should start working right away.

If required you can restart your browser.

**🎉 🎊 Congratulations** 🥳 🎊

<br>

<br>

## Updating

### Extension / Addon

On [Chromium based browsers][4]

- [from webstore][1]
- sideloading from [crx/zip file](#from-crxzip-file) or [unzipped folder](#from-unzipped-folder)

On [Firefox based browsers][5]

- [from addon store][2]
- [sideloading from xpi/jar/zip file](#from-xpijarzip-file)

On [Firefox based browsers][5] for mobile

- [from addon store][2]

<br>

<br>

## Miscellaneous

### Using YouTube website as an app with an extension

#### Desktop

##### Chromium Based Browsers

0. Go to YouTube
1. Tap on menu button (`☰` / `⋯` / `⋮`)
2. Click on "Install YouTube"
3. 🎉Done!

<br>

##### Firefox Based Browsers

**⚠ Doesn't work on newer versions.**

1. Type [`about:config`](about:config) in address bar & press `Enter` key.
2. When warned `Proceed with Caution` click on `Accept the Risk and Continue`
3. Locate and click on the search bar on the page.
4. Type `browser.ssb.enable`.
5. click on `⇋` and make sure the state is set to `true`.
6. Restart the browser and Open YouTube.
7. Click on `⋮` located in the upper right corner
8. Click `Install this website as an app` or `Install this website as an app` which depends on the version you are using.
9. Done! 🎉 You should be able to see the site's app in the start menu.

You can also refer here (for pictures):

[How to Enable the Site-Specific Browser (SSB) in Firefox - Make Tech Easier](https://www.maketecheasier.com/enable-site-specific-browser-firefox)

<br>

#### Mobile

##### Firefox Based Browsers

0. Install the extension
1. Go to YouTube
2. Tap on the three dots `⋮` located at the bottom right corner of the screen.
3. Turn on "Desktop Site".
4. Refresh the page.
5. Wait for it to completely load.
6. Tap again on the three dots `⋮` located at the bottom right corner of the screen.
7. You will see an option as `Install`. Tap on it.
8. Tap - `Add` when asked `Add to Home screen?`
9. Enjoy the YT site as a Firefox nightly app !!

<br>

##### [Chromium Based Browsers][4]

But still - here are the steps:

1. Go to YouTube
2. Tap on the three dots `⋮` located at the bottom right corner of the screen.
3. Turn on "Desktop Site".
4. Refresh the page and wait for it to completely load.
5. Tap again on the three dots `⋮` located at the bottom right corner of the screen.
6. You will see an option as `Install`. Tap on it.
7. When asked `Install App` tap on `Yes`
8. Tap - `Add` when asked `Add to Home screen?`
9. Enjoy the YT site as an app !!

<br>

<br>

<!-- links -->

[1]: https://chrome.google.com/webstore/detail/return-youtube-dislike/gebbhagfogifgggkldgodflihgfeippi
[2]: https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/
[3]: https://github.com/Anarios/return-youtube-dislike/raw/main/Extensions/UserScript/Return%20Youtube%20Dislike.user.js
[4]: https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium
[5]: https://en.wikipedia.org/wiki/Category:Web_browsers_based_on_Firefox
[6]: chrome://extensions


================================================
FILE: Docs/Guide__Installingvi.md
================================================
**Mục lục**

- [Downloading](#downloading)
  - [Desktop (all OS supported by these browsers)](#desktop-all-os-supported-by-these-browsers)
    - [Chromium Based Browsers](#chromium-based-browsers)
    - [Firefox Based Browsers](#firefox-based-browsers)
  - [Mobile](#mobile)
    - [Android](#android)
    - [iOS](#ios)
    - [Userscript](#userscript)
- [Installation](#installation)
  - [Desktop](#desktop)
    - [**Chromium based browsers**](#chromium-based-browsers-1)
      - [From Chrome Webstore](#from-chrome-webstore)
      - [From crx/zip file](#from-crxzip-file)
      - [From unzipped folder](#from-unzipped-folder)
    - [**Firefox Based Browsers**](#firefox-based-browsers-1)
      - [From addon store](#from-addon-store)
      - [From xpi/jar/zip file](#from-xpijarzip-file)
  - [Mobile](#mobile-1)
    - [Android](#android-1)
      - [App from Play Store](#app-from-play-store)
      - [On Firefox](#on-firefox)
    - [iOS](#ios-1)
- [Using](#using)
- [Updating](#updating)
  - [Extension / Addon](#extension--addon)
- [Miscellaneous](#miscellaneous)
  - [Using YouTube website as an app with an extension](#using-youtube-website-as-an-app-with-an-extension)
    - [Desktop](#desktop-1)
      - [Chromium Based Browsers](#chromium-based-browsers-2)
      - [Firefox Based Browsers](#firefox-based-browsers-2)
    - [Mobile](#mobile-2)
      - [Firefox Based Browsers](#firefox-based-browsers-3)
      - [Chromium Based Browsers](#chromium-based-browsers-3)

<br>

<br>

## Downloading

### Desktop (all OS supported by these browsers)

<br>

#### [Chromium Based Browsers][4]

This extension has been tested to work on these browsers.

- [Google Chrome][1]
- [Microsoft Edge][1]
- [Brave][1]
- [Opera][1]

It should be able to work on [all Chromium-based browsers (list here)][4]. But that isn't guaranteed.

<br>

#### [Firefox Based Browsers][5]

- [Firefox][2]
- This addon should be able to run on most of the [Firefox-based browsers][5]. But isn't guaranteed.

<br>

### Mobile

#### Android

1. **F-Droid Store**

- [Show Youtube Dislikes](https://f-droid.org/en/packages/com.jesperh.showyoutubedislikes/)

  [Download from here (Click here)](https://f-droid.org/en/packages/com.jesperh.showyoutubedislikes/)

  The source code is available at [github.com/jesperbakhandskemager/view-youtube-dislike](https://github.com/jesperbakhandskemager/view-youtube-dislike)

  You can download the apk file from
  [https://github.com/jesperbakhandskemager/view-youtube-dislike/releases/](https://github.com/jesperbakhandskemager/view-youtube-dislike/releases/)

  **Note: This app is NOT made by the original author of the extension**.

2. [**Firefox Nightly**][2]

- This addon should be able to run on most of the [Firefox-based browsers][5]. But isn't guaranteed.

3. [**Chromium Based browsers**][4]

Most [**Chromium Based browsers**][4] **don't support extensions on Android or iOS**

However, [Kiwi Browser](https://kiwibrowser.com/) does. You can refer to this video - [Google Chrome Extensions on Android with Kiwi Browser!](https://youtu.be/T6J0T_-oim4)

<br>

#### iOS

No Support on Firefox

You can have a look at these pages for more information (the reason why it's not available on Firefox):

- [https://support.mozilla.org/en-US/kb/add-ons-firefox-ios]
- [https://support.mozilla.org/en-US/questions/1101350]

For now, you can try this

- [For Jailbroken iOS - **WE TAKE NO RESPONSIBILITY. USE AT YOUR OWN RISK**](https://chariz.com/get/return-youtube-dislike)

  This is an iOS port [**developed by a separate team**](https://github.com/PoomSmart/Return-YouTube-Dislikes) not related to the owner of github.com/Anarios/return-youtube-dislike

#### Userscript

[Download from here](https://returnyoutubedislike.com/install)

<br>

<br>

## Installation

### Desktop

<br>

#### [**Chromium based browsers**][4]

<br>

##### From Chrome Webstore

1. [Go to website (click here)][1]
2. Click install
3. Wait for the extension to download and
4. 🙂 Installed !!

<br>

##### From crx/zip file

1. Download the crx/zip file.
2. Type [`chrome://extensions`][6] in address bar
3. Search for the "Developer Mode" switch and turn it on.
4. Open the folder and the browser side by side.
5. Drag and drop the crx/zip file in [chrome://extensions][6] tab
6. Click on "Add extension"
7. Installation Completed 🎉
8. Remember to **turn off the "developer mode"** if not needed

<br>

##### From unzipped folder

1. Download the crx/zip file.
2. Go to [`chrome://extensions`][6]
3. Search for the "Developer Mode" switch and turn it on.
4. Click on "Load Unpacked"
5. Navigate to the folder & select it
6. The extension should be installed 🎉
7. Remember to **turn off the "developer mode"** if not needed

<br>

#### [**Firefox Based Browsers**][5]

##### From addon store

1. Go to the addon store and find the extension or [click here][2].
2. Click on `Add to Firefox`
3. Done 🎉 The extension should be installed.

<br>

##### From xpi/jar/zip file

1. Type `about:addons` in the address bar and press "Enter". Alternatively, You can use
   `Ctrl` + `Shift` + `A` on Windows and
   `Cmd` + `Shift` + `A` on Mac and
2. Click on the Setting Gear icon `⚙`.
3. Click on `Install Add-on From File...`
4. Locate and click on the .xpi/.jar/.zip file.
5. Select and click to open it.
6. Done 🎉 The extension should be installed.

<br>

### Mobile

#### Android

##### App from Play Store

- Although app(s) which use this API exist, they aren't official.

##### On Firefox

1. Install Firefox Nightly. Refer to this blog post for the procedure: [Expanded extension support in Firefox for Android Nightly](https://blog.mozilla.org/addons/2020/09/29/expanded-extension-support-in-firefox-for-android-nightly/)
2. Install the extension in it from [addon store][2]
3. If you want - install the site as an app. For that procedure [go here](#firefox-based-browsers-3).

#### iOS

- [For iOS click here](#ios)
- Only available on Firefox-based browsers because Chromium-based browsers for the Android platform don't support installing extensions.

<br>

<br>

## Using

No more steps are required, it should start working right away.

If required you can restart your browser.

**🎉 🎊 Congratulations** 🥳 🎊

<br>

<br>

## Updating

### Extension / Addon

On [Chromium based browsers][4]

- [from webstore][1]
- sideloading from [crx/zip file](#from-crxzip-file) or [unzipped folder](#from-unzipped-folder)

On [Firefox based browsers][5]

- [from addon store][2]
- [sideloading from xpi/jar/zip file](#from-xpijarzip-file)

On [Firefox based browsers][5] for mobile

- [from addon store][2]

<br>

<br>

## Miscellaneous

### Using YouTube website as an app with an extension

#### Desktop

##### Chromium Based Browsers

0. Go to YouTube
1. Tap on menu button (`☰` / `⋯` / `⋮`)
2. Click on "Install YouTube"
3. 🎉Done!

<br>

##### Firefox Based Browsers

**⚠ Doesn't work on newer versions.**

1. Type [`about:config`](about:config) in address bar & press `Enter` key.
2. When warned `Proceed with Caution` click on `Accept the Risk and Continue`
3. Locate and click on the search bar on the page.
4. Type `browser.ssb.enable`.
5. click on `⇋` and make sure the state is set to `true`.
6. Restart the browser and Open YouTube.
7. Click on `⋮` located in the upper right corner
8. Click `Install this website as an app` or `Install this website as an app` which depends on the version you are using.
9. Done! 🎉 You should be able to see the site's app in the start menu.

You can also refer here (for pictures):

[How to Enable the Site-Specific Browser (SSB) in Firefox - Make Tech Easier](https://www.maketecheasier.com/enable-site-specific-browser-firefox)

<br>

#### Mobile

##### Firefox Based Browsers

0. Install the extension
1. Go to YouTube
2. Tap on the three dots `⋮` located at the bottom right corner of the screen.
3. Turn on "Desktop Site".
4. Refresh the page.
5. Wait for it to completely load.
6. Tap again on the three dots `⋮` located at the bottom right corner of the screen.
7. You will see an option as `Install`. Tap on it.
8. Tap - `Add` when asked `Add to Home screen?`
9. Enjoy the YT site as a Firefox nightly app !!

<br>

##### [Chromium Based Browsers][4]

But still - here are the steps:

1. Go to YouTube
2. Tap on the three dots `⋮` located at the bottom right corner of the screen.
3. Turn on "Desktop Site".
4. Refresh the page and wait for it to completely load.
5. Tap again on the three dots `⋮` located at the bottom right corner of the screen.
6. You will see an option as `Install`. Tap on it.
7. When asked `Install App` tap on `Yes`
8. Tap - `Add` when asked `Add to Home screen?`
9. Enjoy the YT site as an app !!

<br>

<br>

<!-- links -->

[1]: https://chrome.google.com/webstore/detail/return-youtube-dislike/gebbhagfogifgggkldgodflihgfeippi
[2]: https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/
[3]: https://github.com/Anarios/return-youtube-dislike/raw/main/Extensions/UserScript/Return%20Youtube%20Dislike.user.js
[4]: https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium
[5]: https://en.wikipedia.org/wiki/Category:Web_browsers_based_on_Firefox
[6]: chrome://extensions


================================================
FILE: Docs/Guide__Troubleshooting.md
================================================
Troubleshooting Guide

**Index**

- [Extension](#extension)
  - [Basic checks](#basic-checks)
  - [Check API status](#check-api-status)
  - [Install certificates](#install-certificates)
  - [Check for logs in the console](#check-for-logs-in-the-console)
    - [In Chromium Based browsers](#in-chromium-based-browsers)
    - [In Firefox Based Browsers](#in-firefox-based-browsers)
  - [Check for conflicting extensions](#check-for-conflicting-extensions)
  - [Known conflicts](#known-conflicts)
- [iOS app](#ios-app)
- [YouTube Vanced app](#youtube-vanced--app)
- [Contact in Discord Server](#contact-in-discord-server)
- [Useful Links](#useful-links)

<br>

## Extension

(for Windows & Macs)

### Basic checks

1. Make sure you have the latest version of the extension installed. ([Click Here to check](https://chrome.google.com/webstore/detail/return-youtube-dislike/gebbhagfogifgggkldgodflihgfeippi#:~:text=Report%20abuse-,Version,-2.0.0.3))
2. Close all the tabs & restart your browser
3. Reinstall the extension.
4. [Check API status](#check-api-status)
5. [Check Cloudflare status](https://www.cloudflarestatus.com/)
6. [If you are on Windows 7 read this](#install-certificates)

<br>

### Check API status

If the basic checks didn't resolve anything

[See if you get any response from this link (click here)](https://returnyoutubedislikeapi.com/votes?videoId=QOFEgexls14)

- If you **don't see something like** this, then the **API is down** and **everything is fine on your side**.
  `{"id":"QOFEgexls14","dateCreated":"2021-12-28T02:53:20.995329Z","likes":2968,"dislikes":204,"rating":4.725047080979285,"viewCount":29157,"deleted":false}`
- If you see some responses but not in the above format (with likes and dislikes) then probably you are being rate-limited. It is done to prevent bot attacks and database vandalization. It depends on IP (its hash - which is never stored in non-volatile storage) for its countermeasures. If many people are accessing the server from the same IP (as in the case of public/institutional Wi-Fi) then it's possible that the IP is being rate-limited. If that's the case, there's no way for us to differentiate you from a bot/attacker.

**If you see "Certificate error" and [if you are on Windows 7 (or earlier) read this](#install-certificates)**

<br><br>

### Install certificates

**Applies for Windows 7 (and earlier) only**

and only for [Chromium Based Browsers][1]

- [Chromium-based browsers][1] don't have their own certificate manager.
- They use Windows' certificates manager.
- Microsoft has officially dropped the support for Windows 7

You will have to install the latest certificates for that.

You can follow this guide:

[Fix error NET::ERR CERT DATE INVALID - Your connection is not private - Windows 7 - 2021](https://youtu.be/JYZLxP2Z8G4)

If you don't want to install the certificate from Google Drive

- Here is the official link to the certificate [**x1.i.lencr.org**](http://x1.i.lencr.org/).
- **You will have to close all the tabs** before downloading this certificate.

**The thumbprint of real certificate is `cabd2a79a1076a31f21d253635cb039d4329a5e8`**

**To make sure that you have installed the correct certificate, you should consider checking if the thumbprints match.** To do this you can follow this guide: [How to check a certificate's thumbprint](https://knowledge.digicert.com/solution/SO9840.html)

<br>

### Check for logs in the console

#### [In Chromium Based browsers][1]

1. In Developer tools, go to [`console` panel](https://developer.chrome.com/docs/devtools/open/#console).
   - For Windows press `Ctrl` + `Shift` + `J` all at once
   - For Mac press `Cmd` + `Option` + `J` all at once
2. Find `filter` box in the newly appeared window.
3. Type `Return`.
4. Check the [Check API Status](#check-api-status) and see if you get similar responses.
5. If you see any errors in red [please contact us][4] and report them in our [discord server][3]

<!-- If ever needed
   - For Android refer to this article: [Remote debug Android devices](https://developer.chrome.com/docs/devtools/remote-debugging/) -->

<br>

#### [In Firefox Based Browsers][2]

1. Open Browser Console
   - For standard keyboard layout press `Ctrl` + `Shift` + `K` all at once
   - For Mac keyboard layout press `Cmd` + `Option` + `K` all at once
   - For Android refer to this article: [Remotely debugging Firefox <36 for Android](https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Firefox_for_Android)
2. Find `Filter Output` box in the newly appeared window.
3. Type `Return`.
4. If you see any errors in red [please contact us][4] and report them in our [discord server][3]

<br>

### Check for conflicting extensions

Some privacy and/or security-focused extensions such as ad- or script-blockers, as well as YouTube customization plugins might prevent the extension from working correctly.  
Try to disable all other extensions and test whether the extension works.  
If it does, find the extension(s) preventing RYD from working correctly and re-configure them in a way that'd stop them from interfering.

<br>

### Known conflicts

> ### scriptSafe
>
> **Solution:** Trust `returnyoutubedislikeapi.com` manually
>
> ![trust returnyoutubedislikeapi.com manually](https://cdn.discordapp.com/attachments/821116437720334397/929814357708247060/unknown.png)

<br>

> ### uMatrix
>
> **Solution:** Allow XHR for `returnyoutubedislikeapi.com` manually
>
> ![Allow XHR for `returnyoutubedislikeapi.com` manually](https://media.discordapp.net/attachments/821116437720334397/929813724238336141/unknown.png)

<br>

<br>

## iOS app

Coming soon. Please have patience.

<br>

<br>

## YouTube Vanced app

Coming soon. Please have patience.

<br>

<br>

## Contact in Discord Server

**Only if nothing mentioned above helped and you still have a problem.**

[Discord server link: https://discord.gg/mYnESY4Md5][3]

0. Join the discord server if you haven't already
1. Go to the #Bugs-and-problems channel
2. There, thoroughly describe:
   - your problem
   - what you have tried and what didn't work
   - results of the troubleshooting steps

<!-- {
  "update_frequency" : "low"
} -->

<br>

<br>

## Useful Links

[List of Chromium Based Browsers][1]

[List of Firefox Based Browsers][2]

[Return-YouTube-Dislike Discord Server][3]

<!-- links -->

[1]: https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium
[2]: https://en.wikipedia.org/wiki/Category:Web_browsers_based_on_Firefox
[3]: https://discord.gg/mYnESY4Md5
[4]: #contact-in-discord-server


================================================
FILE: Docs/Guide__Troubleshootingvi.md
================================================
Hướng dẫn Khắc phục Sự cố

**Mục lục**

- [Extension](#extension)
  - [Basic checks](#basic-checks)
  - [Check API status](#check-api-status)
  - [Install certificates](#install-certificates)
  - [Check for logs in the console](#check-for-logs-in-the-console)
    - [In Chromium Based browsers](#in-chromium-based-browsers)
    - [In Firefox Based Browsers](#in-firefox-based-browsers)
  - [Check for conflicting extensions](#check-for-conflicting-extensions)
  - [Known conflicts](#known-conflicts)
- [iOS app](#ios-app)
- [YouTube Vanced app](#youtube-vanced--app)
- [Contact in Discord Server](#contact-in-discord-server)
- [Useful Links](#useful-links)

<br>

## Extension

(for Windows & Macs)

### Basic checks

1. Make sure you have the latest version of the extension installed. ([Click Here to check](https://chrome.google.com/webstore/detail/return-youtube-dislike/gebbhagfogifgggkldgodflihgfeippi#:~:text=Report%20abuse-,Version,-2.0.0.3))
2. Close all the tabs & restart your browser
3. Reinstall the extension.
4. [Check API status](#check-api-status)
5. [Check Cloudflare status](https://www.cloudflarestatus.com/)
6. [If you are on Windows 7 read this](#install-certificates)

<br>

### Check API status

If the basic checks didn't resolve anything

[See if you get any response from this link (click here)](https://returnyoutubedislikeapi.com/votes?videoId=QOFEgexls14)

- If you **don't see something like** this, then the **API is down** and **everything is fine on your side**.
  `{"id":"QOFEgexls14","dateCreated":"2021-12-28T02:53:20.995329Z","likes":2968,"dislikes":204,"rating":4.725047080979285,"viewCount":29157,"deleted":false}`
- If you see some responses but not in the above format (with likes and dislikes) then probably you are being rate-limited. It is done to prevent bot attacks and database vandalization. It depends on IP (its hash - which is never stored in non-volatile storage) for its countermeasures. If many people are accessing the server from the same IP (as in the case of public/institutional Wi-Fi) then it's possible that the IP is being rate-limited. If that's the case, there's no way for us to differentiate you from a bot/attacker.

**If you see "Certificate error" and [if you are on Windows 7 (or earlier) read this](#install-certificates)**

<br><br>

### Install certificates

**Applies for Windows 7 (and earlier) only**

and only for [Chromium Based Browsers][1]

- [Chromium-based browsers][1] don't have their own certificate manager.
- They use Windows' certificates manager.
- Microsoft has officially dropped the support for Windows 7

You will have to install the latest certificates for that.

You can follow this guide:

[Fix error NET::ERR CERT DATE INVALID - Your connection is not private - Windows 7 - 2021](https://youtu.be/JYZLxP2Z8G4)

If you don't want to install the certificate from Google Drive

- Here is the official link to the certificate [**x1.i.lencr.org**](http://x1.i.lencr.org/).
- **You will have to close all the tabs** before downloading this certificate.

**The thumbprint of real certificate is `cabd2a79a1076a31f21d253635cb039d4329a5e8`**

**To make sure that you have installed the correct certificate, you should consider checking if the thumbprints match.** To do this you can follow this guide: [How to check a certificate's thumbprint](https://knowledge.digicert.com/solution/SO9840.html)

<br>

### Check for logs in the console

#### [In Chromium Based browsers][1]

1. In Developer tools, go to [`console` panel](https://developer.chrome.com/docs/devtools/open/#console).
   - For Windows press `Ctrl` + `Shift` + `J` all at once
   - For Mac press `Cmd` + `Option` + `J` all at once
2. Find `filter` box in the newly appeared window.
3. Type `Return`.
4. Check the [Check API Status](#check-api-status) and see if you get similar responses.
5. If you see any errors in red [please contact us][4] and report them in our [discord server][3]

<!-- If ever needed
   - For Android refer to this article: [Remote debug Android devices](https://developer.chrome.com/docs/devtools/remote-debugging/) -->

<br>

#### [In Firefox Based Browsers][2]

1. Open Browser Console
   - For standard keyboard layout press `Ctrl` + `Shift` + `K` all at once
   - For Mac keyboard layout press `Cmd` + `Option` + `K` all at once
   - For Android refer to this article: [Remotely debugging Firefox <36 for Android](https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Firefox_for_Android)
2. Find `Filter Output` box in the newly appeared window.
3. Type `Return`.
4. If you see any errors in red [please contact us][4] and report them in our [discord server][3]

<br>

### Check for conflicting extensions

Some privacy and/or security-focused extensions such as ad- or script-blockers, as well as YouTube customization plugins might prevent the extension from working correctly.  
Try to disable all other extensions and test whether the extension works.  
If it does, find the extension(s) preventing RYD from working correctly and re-configure them in a way that'd stop them from interfering.

<br>

### Known conflicts

> ### scriptSafe
>
> **Solution:** Trust `returnyoutubedislikeapi.com` manually
>
> ![trust returnyoutubedislikeapi.com manually](https://cdn.discordapp.com/attachments/821116437720334397/929814357708247060/unknown.png)

<br>

> ### uMatrix
>
> **Solution:** Allow XHR for `returnyoutubedislikeapi.com` manually
>
> ![Allow XHR for `returnyoutubedislikeapi.com` manually](https://media.discordapp.net/attachments/821116437720334397/929813724238336141/unknown.png)

<br>

<br>

## iOS app

Coming soon. Please have patience.

<br>

<br>

## YouTube Vanced app

Coming soon. Please have patience.

<br>

<br>

## Contact in Discord Server

**Only if nothing mentioned above helped and you still have a problem.**

[Discord server link: https://discord.gg/mYnESY4Md5][3]

0. Join the discord server if you haven't already
1. Go to the #Bugs-and-problems channel
2. There, thoroughly describe:
   - your problem
   - what you have tried and what didn't work
   - results of the troubleshooting steps

<!-- {
  "update_frequency" : "low"
} -->

<br>

<br>

## Useful Links

[List of Chromium Based Browsers][1]

[List of Firefox Based Browsers][2]

[Return-YouTube-Dislike Discord Server][3]

<!-- links -->

[1]: https://en.wikipedia.org/wiki/Chromium_(web_browser)#Browsers_based_on_Chromium
[2]: https://en.wikipedia.org/wiki/Category:Web_browsers_based_on_Firefox
[3]: https://discord.gg/mYnESY4Md5
[4]: #contact-in-discord-server


================================================
FILE: Docs/Privacy Policy
================================================
The only data collected from users is their likes and dislikes made while the extension is installed.

No personal info, account name or watch history is collected or saved.

Users are identified by a random user ID, which is not directly linked to any of their accounts, the only purpose of this user ID is to make voting process possible.

None of the saved data is shared with any third parties.


================================================
FILE: Docs/Privacy Policyvi
================================================
Dữ liệu duy nhất được thu nhập: số lượt đánh giá "thích" và "không thích" trong thời gian tiện ích mở rộng này được cài.

Dữ liệu không được thu thập cũng như không lưu trữ: thông tin cá nhân, tên tài khoản, lịch sử xem vi-đê-ô.

Người dùng được gán cho một ID người dùng ngẫu nhiên. ID người dùng này không có bất kì mối liên hệ nào tới những tài khoản của người dùng. Mục đích duy nhất của việc dùng ID người dùng là để thực hiện chức năng đánh giá vi-đê-ô.

Dữ liệu được lưu trữ không được chia sẻ với bất kì bên thứ ba nào.


================================================
FILE: Docs/SECURITY-FAQ.md
================================================
Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Security

### Are you tracking my viewing history?

No. The extension's code is public and you can see it for yourself. The only information being sent is the video ID, which is required to fetch the dislike count for the videos. There are no additional headers being sent. Over the communication layer, your public IP will be exposed to the server, as well as the time when the request was made. However, none of these are uniquely identifying you in any way. Assuming a zero-trust environment, the best we could get is a dynamic IP. Which, today is yours, tomorrow is your neighbor's. If you're really worried about your IP being traced, you probably already use a VPN.

### Can you uniquely identify me if I dislike?

Yes. When you dislike a video, we create a randomly generated unique ID for you that is not tied to your Google account. This is done to prevent botting. But there is no way to tie this random Id to you or your personal YouTube account.

### What information do you have, exactly?

Just the video ID. Not your comments, not your username, not who you've shared the video with, not any additional metadata. Nothing. Just the video ID.

### How is my IP stored?

The backend keeps unhashed IP addresses in volatile memory (RAM) only. These addresses aren't stored on a hard drive, and therefore aren't logged. We hash the IP addresses, and that's stored instead. This is done to prevent database vandalism.

### I heard some discussion over OAuth, and access to my YouTube account!

This feature will be optional, and very much opt-in. If you are a YouTube creator, and would like to share your dislike stats with us, you can. The way [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) was structured, it's actually very secure. You can revoke access to your account at any time, and can give very specific permissions to us. We will not ask for any permissions that aren't required. We'll only ask for permissions to view your video stats.

### How can I trust this dislike count?

We have implemented measures to prevent bot attacks and are gonna continue to work on improving the effectiveness of the bot prevention system: this will help us keep the dislike count as a good representative of the actual count. Of course it will never be 100% accurate so it's up to you to decide whether you trust the count or not.

### Why don't you share the backend code?

We will share it at some point - but there's really no real reason to share it right now. It gives a false sense of security - because in a zero-trust system, we could just as well disclose one version but deploy another. There are plenty of reasons to keep the code hidden, specifically, how we battle spam. Hiding/Obfuscating the spam handling code is a fairly standard practice.


================================================
FILE: Docs/SECURITY-FAQaz.md
================================================
Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md)

# Təhlükəsizlik

### Baxış tarixçəmi izləyirsiniz?

Xeyr. Artırmanın kodu ictimaiyyətə açıqdır və siz bunu özünüz görə bilərsiniz. Göndərilən yeganə məlumat videolar üçün bəyənməmə sayını almaq üçün tələb olunan video ID-dir. Göndərilən başqa əlavə başlıq yoxdur. Rabitə təbəqəsi vasitəsilə ictimai IP-niz serverə və sorğunun edildiyi vaxta məruz qalacaq. Bununla belə, bunların heç biri sizi heç bir şəkildə unikal şəkildə müəyyənləşdirmir. Sıfır etibar mühitini fərz etsək, əldə edə biləcəyimiz ən yaxşısı dinamik IP-dir. Bu İP bu gün sənin, sabah qonşunun ola bilər. Əgər həqiqətən IP-nizin izlənilməsindən narahatsınızsa, yəqin ki, artıq VPN-dən istifadə edirsiniz.

### Videonu bəyənməsəm, məni unikal şəkildə tanıya bilərsiniz??

Bəli. Videonu bəyənmədiyiniz zaman biz sizin üçün Google hesabınızla əlaqəli olmayan təsadüfi yaradılmış unikal ID yaradırıq. Bu, botlardan istifadənin qarşısını almaq üçün edilir. Bununla belə, bu təsadüfi identifikatoru sizə və ya şəxsi YouTube hesabınıza bağlamağın heç bir yolu yoxdur.

### Sizdə dəqiq olaraq hansı məlumat var??

Sadəcə video identifikatoru. Şərhləriniz, istifadəçi adınız, videonu kiminlə paylaşdığınız, heç bir əlavə metadata deyil. heç nə. Sadəcə video identifikatoru.

### Mənim IP ünvanım necə saxlanılır?

Backend yalnız müvəqqəti yaddaşda (RAM) haşiyələnməmiş IP ünvanlarını saxlayır. Bu ünvanlar sabit diskdə saxlanmır və buna görə də qeyd olunmur. Biz IP ünvanlarını hash edirik və əvəzinə onlar saxlanılır. Bu, verilənlər bazası vandalizminin qarşısını almaq üçün edilir.

### OAuth vasitəsilə YouTube hesabıma daxil olmaq haqqında bəzi mübahisələr eşitdim!

Bu xüsusiyyət istəyə bağlı olacaq və çox üstünlük təşkil edəcək. Əgər siz YouTube yaradıcısısınızsa və bəyənmədiyiniz statistikanı bizimlə bölüşmək istəyirsinizsə, bunu edə bilərsiniz. [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) Qurulma şəkli, əslində çox təhlükəsizdir. İstənilən vaxt hesabınıza girişi ləğv edə və bizə çox xüsusi icazələr verə bilərsiniz. Biz heç bir lazımsız icazə istəməyəcəyik. Biz yalnız video statistikanıza baxmaq üçün icazə istəyəcəyik.
### Bu sayda bəyənməmələrə necə etibar edə bilərəm??

Biz bot hücumlarının qarşısını almaq üçün tədbirlər gördük və anti-bot sisteminin effektivliyini artırmaq üçün işi davam etdirəcəyik: bu, bəyənməmələrin sayını real rəqəmin yaxşı nümayəndəsi kimi saxlamağa kömək edəcək. Əlbəttə ki, bu, heç vaxt 100% dəqiq olmayacaq, ona görə də hesaba etibar edib etməmək sizə bağlıdır.

### Niyə backend kodunu paylaşmırsınız?
Biz bunu nə vaxtsa paylaşacağıq - lakin hazırda paylaşmaq üçün həqiqətən heç bir səbəb yoxdur. Bu, yanlış təhlükəsizlik hissi verə bilər - çünki sıfır inamlı sistemdə biz bir versiyanı ifşa edə, digərini yerləşdirə bilərik. Kodu gizli saxlamağın bir çox səbəbi var, xüsusən də spamla necə mübarizə aparırıq. Spam emalı kodunu ört-basdır etmək/gizlətmək olduqca standart təcrübədir.

================================================
FILE: Docs/SECURITY-FAQbg.md
================================================
Прочетете това на други езици:  [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md)


# Сигурност

### Проследявате ли историята на гледанията ми?

Не. Кода на разширението е публичен и може да го видите сами. Единствената информация, която се изпраща, е идентификаторът на видеото, който е необходим, за да вземе броя на дизлайковете за видеата. Няма допълнителни заглавия, изпращани. Чрез комуникационния слой вашите обществени IP адреси ще бъдат изложени на сървъра, както и времето, в което беше направен заявката. Обаче нито едно от тези не ви идентифицира уникално по никакъв начин. Предполагайки среда с нулево доверие, най-доброто, което можем да получим, е динамичен IP адрес. Който днес е вашият, утре е на вашия съсед. Ако наистина се притеснявате, че вашият IP адрес бива проследен, вероятно вече използвате VPN.

### Можете ли да ме идентифицирате уникално, ако дизлайкна?

Да. Когато дизлайкнете видео, създаваме случайно генериран уникален идентификатор за вас, който не е свързан с вашия Google акаунт. Това се прави, за да предотвратим бот атаки. Но няма начин този случаен идентификатор да бъде свързан с вас или с вашия личен акаунт на YouTube.

### Какви точно информация имате?

Само идентификатора на видеото. Нито вашите коментари, нито потребителското ви име, нито на кого сте споделили видеото, нито допълнителни метаданни. Нищо. Само идентификатора на видеото.

### Как се съхранява моят IP адрес?

Бекендът държи незакодирани IP адреси само в изменяемата памет (RAM). Те не се съхраняват на твърд диск и следователно не се записват. Ние кодираме IP адресите, и това се съхранява. Това се прави, за да се предотврати вандализмът върху базата данни.

### Чух за OAuth и достъп до акаунта ми на YouTube!

Тази функция ще бъде по избор и изключително от ваш избор. Ако сте създател на YouTube и искате да споделите статистиката за дизлайковете с нас, можете. Структурата на [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) е наистина много сигурна. Всеки път можете да отмените достъпа до акаунта си и да дадете много конкретни разрешения на нас. Няма да поискаме никакви разрешения, които не са необходими. Ще поискаме само разрешения за преглед на статистиката на вашите видеа.

### Как мога да се доверя на този брой дизлайкове?

Въведохме мерки за предотвратяване на атаки с ботове и ще продължим да работим по подобряване на ефективността на системата за предотвратяване на ботове: това ще ни помогне да поддържаме броя на дизлайковете като добър представител на реалния брой. Разбира се, той никога няма да бъде 100% точен, така че решението дали да вярвате на броя или не, зависи от вас.

### Защо не споделяте кода на бекенда?

Ще го споделим на някакъв етап - но наистина няма реална причина да го споделяме в момента. Това създава лъжливо чувство за сигурност - защото в среда с нулево доверие можем съвсем спокойно да разкрием една версия, но да развием друга. Има много причини да държим кода скрит, специално начина, по който се борим срещу спама. Скриването/затъмняването на кода за борба със спама е стандартна практика.


================================================
FILE: Docs/SECURITY-FAQcn.md
================================================
阅读其他语言版本:[русский](SECURITY-FAQru.md)、[Nederlands](SECURITY_FAQnl.md)、[Français](SECURITY-FAQfr.md)、[Türkçe](SECURITY-FAQtr.md)、[українська](SECURITY-FAQk.md)、[Polski](SECURITY-FAQpl.md)、[Deutsch](SECURITY-FAQde.md)

# 安全

### 您是否在跟踪我的观看历史记录?

否。扩展程序的代码是公开的,您可以自己查看。发送的唯一信息是视频 ID,这是获取视频的不喜欢计数所必需的。没有发送其他标头。在通信层上,您的公共 IP 以及发出请求的时间将暴露给服务器。但是,这些都不能以任何方式唯一地识别您。假设一个零信任环境,我们能得到的最好东西就是动态 IP。今天是你的,明天是你的邻居的。如果你真的担心你的 IP 被追踪,你可能已经使用了 VPN。

### 如果我不喜欢,你能唯一地识别我吗?

是。当你不喜欢某个视频时,我们会为你创建一个随机生成的唯一 ID,该 ID 不与你的 Google 帐户绑定。这样做是为了防止机器人。但是没有办法将这个随机 ID 绑定到你或你的个人 YouTube 帐户。

### 你到底有什么信息?

只有视频 ID。不是你的评论,不是你的用户名,不是你与谁分享了视频,也不是任何其他元数据。什么都没有。只有视频 ID。

### 我的 IP 如何存储?

后端仅将未散列的 IP 地址保存在易失性存储器 (RAM) 中。这些地址不存储在硬盘上,因此不会被记录。我们对 IP 地址进行散列,然后将其存储起来。这样做是为了防止数据库遭到破坏。

### 我听到一些关于 OAuth 和访问我的 YouTube 帐户的讨论!

此功能是可选的,并且非常可选择加入。如果您是 YouTube 创作者,并且想与我们分享您的不喜欢统计数据,您可以这样做。 [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) 的结构方式实际上非常安全。您可以随时撤销对您帐户的访问权限,并可以向我们授予非常具体的权限。我们不会要求任何不必要的权限。我们只会要求查看您的视频统计数据的权限。

### 我如何信任这个不喜欢计数?

我们已经实施了防止机器人攻击的措施,并将继续努力提高机器人预防系统的有效性:这将帮助我们将不喜欢计数保持为实际计数的良好代表。当然,它永远不会 100% 准确,因此由您决定是否信任计数。

### 您为什么不共享后端代码?

我们会在某个时候共享它 - 但现在真的没有真正的理由共享它。它给人一种虚假的安全感 - 因为在零信任系统中,我们也可以披露一个版本但部署另一个版本。隐藏代码的原因有很多,特别是我们如何对抗垃圾邮件。隐藏/混淆垃圾邮件处理代码是一种相当标准的做法。

================================================
FILE: Docs/SECURITY-FAQde.md
================================================
Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md)


# Sicherheit

### Verfolgen Sie meine Anzeigehistorie?

Nein. Der Code der Erweiterung ist öffentlich und Sie können ihn selbst einsehen. Die einzige übermittelte Information ist die Video-ID, die benötigt wird, um die Anzahl der Dislikes für die Videos abzurufen. Es werden keine zusätzlichen Header gesendet. Über die Kommunikationsschicht wird Ihre öffentliche IP-Adresse an den Server übermittelt, sowie die Zeit, zu der die Anfrage gestellt wurde. Keine dieser Informationen identifiziert Sie auf eindeutige Weise. Unter der Annahme einer Zero-Trust-Umgebung ist das Beste, was wir bekommen können, eine dynamische IP. Die heute Ihnen gehört, gehört morgen Ihrem Nachbarn. Wenn Sie sich wirklich Sorgen machen, dass Ihre IP zurückverfolgt wird, verwenden Sie wahrscheinlich bereits ein VPN.

### Können Sie mich eindeutig identifizieren, wenn ich etwas dislike?

Ja. Wenn Sie ein Video nicht mögen, erstellen wir eine zufällig generierte eindeutige ID für Sie, die nicht mit Ihrem Google-Konto verknüpft ist. Dies geschieht, um das Botting zu verhindern. Es gibt jedoch keine Möglichkeit, diese zufällige ID mit Ihnen oder Ihrem persönlichen YouTube-Konto zu verknüpfen.

### Welche Informationen haben Sie genau?

Nur die Video-ID. Nicht Ihre Kommentare, nicht Ihren Benutzernamen, nicht mit wem Sie das Video geteilt haben, keine zusätzlichen Metadaten. Nichts. Nur die Video-ID.

### Wie wird meine IP gespeichert?

Der Backend speichert nicht gehashte IP-Adressen nur im flüchtigen Speicher (RAM). Diese Adressen werden nicht auf einer Festplatte gespeichert und daher nicht protokolliert. Wir hashen die IP-Adressen und speichern diese stattdessen. Dies geschieht, um Datenbankvandalismus zu verhindern.

### Ich habe etwas über OAuth gehört und den Zugriff auf mein YouTube-Konto!

Diese Funktion wird optional sein und sehr stark opt-in. Wenn Sie ein YouTube-Ersteller sind und Ihre Dislike-Statistiken mit uns teilen möchten, können Sie dies tun. Die Art und Weise, wie [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) strukturiert wurde, ist tatsächlich sehr sicher. Sie können den Zugriff auf Ihr Konto jederzeit widerrufen und uns sehr spezifische Berechtigungen erteilen. Wir werden nicht nach Berechtigungen fragen, die nicht erforderlich sind. Wir werden nur um Berechtigungen bitten, um Ihre Video-Statistiken anzeigen zu können.

### Wie kann ich diesem Dislike-Zähler vertrauen?

Wir haben Maßnahmen implementiert, um Bot-Angriffe zu verhindern, und werden weiterhin daran arbeiten, die Effektivität des Bot-Präventionssystems zu verbessern: Dies wird uns helfen, den Dislike-Zähler als gute Repräsentation der tatsächlichen Anzahl zu halten. Natürlich wird es nie zu 100% genau sein, also liegt es an Ihnen zu entscheiden, ob Sie dem Zähler vertrauen oder nicht.

### Warum teilen Sie den Backend-Code nicht?

Wir werden ihn irgendwann teilen - aber es gibt wirklich keinen echten Grund, ihn jetzt zu teilen. Es vermittelt ein falsches Sicherheitsgefühl - denn in einem Zero-Trust-System könnten wir genauso gut eine Version offenlegen, aber eine andere bereitstellen. Es gibt viele Gründe, den Code verborgen zu halten, insbesondere wie wir gegen Spam kämpfen. Das Verbergen/Verfremden des Spam-Behandlungscodes ist eine ziemlich standardmäßige Praxis.


================================================
FILE: Docs/SECURITY-FAQfr.md
================================================
Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Sécurité

### Est-ce que vous traquez l'historique des vidéos que je visionne ?

Non. Le code de l'extension est public et vous pouvez le voir par vous-même. La seule information envoyée est l'ID de la vidéo, qui est nécessaire pour récupérer le nombre de dislikes des vidéos. Aucun en-tête (headers) supplémentaire n'est envoyé. Sur la [couche de communication](https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI#Caract%C3%A9risation_r%C3%A9sum%C3%A9e_des_couches), votre adresse IP publique sera exposée au serveur, ainsi que l'heure à laquelle la demande a été faite. Toutefois, aucun de ces éléments ne permet de vous identifier de manière unique. Dans un environnement où vous ne pouvez avoir confiance en personne (zero-trust environment), le mieux que l'on puisse obtenir est une IP dynamique. Qui, aujourd'hui est la vôtre, demain est celle de votre voisin. Si vous êtes vraiment inquiet que votre IP soit tracée, vous utilisez probablement déjà un VPN.

### Pouvez-vous m'identifier de manière unique si je dislike ?

Oui. Lorsque vous dislikez une vidéo, nous créons pour vous un identifiant unique généré de manière aléatoire et non lié à votre compte Google. Cette mesure vise à empêcher les robots. Mais il n'y a aucun moyen de lier cet identifiant aléatoire à vous ou à votre compte YouTube personnel.

### Quelles sont les informations dont vous disposez, exactement ?

Juste l'ID de la vidéo. Pas vos commentaires, pas votre nom d'utilisateur, pas les personnes avec qui vous avez partagé la vidéo, pas de métadonnées supplémentaires. Rien. Juste l'ID de la vidéo.

### Comment mon IP est-elle stockée ?

Le backend conserve les adresses IP non hachées uniquement dans la mémoire volatile (RAM). Ces adresses ne sont pas stockées sur un disque dur et ne sont donc pas enregistrées. Nous hachons les adresses IP et stockons ça à la place. Ceci est fait pour empêcher le vandalisme de la base de données.

### J'ai entendu des discussions sur OAuth, et l'accès à mon compte YouTube !

Cette fonctionnalité sera facultative et fera l'objet d'une demande d'adhésion. Si vous êtes un créateur YouTube et que vous souhaitez partager vos statistiques de dislikes avec nous, vous pouvez le faire. La façon dont [OAuth](https://fr.wikipedia.org/wiki/OAuth) a été structuré, c'est en fait très sûr. Vous pouvez révoquer l'accès à votre compte à tout moment et nous donner des autorisations très spécifiques. Nous ne demanderons pas d'autorisations qui ne sont pas nécessaires. Nous ne vous demanderons que l'autorisation de consulter les statistiques de vos vidéos.

### Comment puis-je faire confiance à ce compte de dislikes ?

Nous avons mis en place des mesures pour prévenir les attaques de robots et nous allons continuer à travailler pour améliorer l'efficacité du système de prévention des robots : cela nous aidera à faire en sorte que le nombre de dislikes soit une bonne représentation du nombre réel. Bien entendu, il ne sera jamais précis à 100 %, c'est donc à vous de décider si vous lui faites confiance ou non.

### Pourquoi ne pas partager le code du backend ?

Nous la partagerons à un moment donné - mais il n'y a pas vraiment de raison de la partager pour le moment. Cela donne un faux sentiment de sécurité, car dans un système zero-trust, nous pourrions tout aussi bien publier une version et en déployer une autre. Il y a de nombreuses raisons de garder le code caché, notamment pour lutter contre le spam. Cacher/dissimuler le code de traitement du spam est une pratique assez standard.


================================================
FILE: Docs/SECURITY-FAQid.md
================================================
Baca ini dibahasa lain: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md)

# Keamanan

### Apakah kalian melacak riwayat video yang saya tonton?

Tidak, Kode extension bersifat publik dan kamu dapat melihatnya sendiri. Informasi yang kami ambil hanya id dari video, yang diperlukan untuk pengambilan jumlah dislike. Tidak ada tambahan data headers lainnya. Pada communication layer, IP Publik kamu akan terekspos ke server, bersamaan dengan waktu ketika requestnya dibuat. Meskipun begitu, data ini tidaklah bersifat unik atau mengidentifikasikan kamu dalam bentuk apapun. Asumsikan environment yang tidak terpercaya, hal terbaik yang dapat kami ambil adalah IP dinamis. Yang bisa saja hari ini adalah milikmu, besok milik tetanggamu. Jika kamu merasa khawati jika IP-mu dilacak, kamu mungkin telah menggunakan VPN.

### Bisakah kalian mengidentifikasi saya ketika saya dislike suatu video?

Iya. Ketika kamu dislike suatu video, kami membuat id yang digenerate secara acak untukmu yang tidak ada hubungannya dengan akun Google. Ini dilakukan untuk menghindari bot. Tapi tidak mungkin untuk mencari kamu atau akun Youtube-mu menggunakan id acak ini.

### Informasi apa saja yang kalian punya?

Hanya id dari video. Bukan komentarmu, bukan usernamemu, bukan siapa saja orang yang pernah kamu kirimkan video, bukan metadata tambahan. Tidak ada. Hanya id dari video.

### Bagaimana IP saya disimpan?

Backend menyimpan alamat IP yang tidak di hash hanya di dalam RAM. Alamat ini tidak disimpan di hard drive, sehingga tidak di log. Kami melakukan hash terhadap alamat IP dan menyimpan yang itu. Ini dilakukan untuk mencegah perusakan database.

### Saya pernah mendengar diskusi mengenai OAuth, dan akses ke akun Youtube saya!

Fitur ini bersifat opsional, dan banyak yang berpartisipasi. Jika kamu merupakan seorang Youtuber, dan mau membagikan data dislikenya kepada kami, kamu bisa melakukannya. Dengan cara [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) yang terstruktur, dan sangat aman. Kamu dapat menghapus akses ke akunmu kapanpun, dan bisa menentukan data mana yang mau dibagikan dan tidak dibagikan secara spesifik. Kami tidak akan meminta izin apapun yang bersifat tidak wajib. Kami hanya akan meminta izin untuk melihat data video kamu.

### Bagaimana bisa saya percaya jumlah dislike ini?

Kami telah melakukan tidakan pencegahan dari penyerangan bot dan akan terus mengimprovisasi keefektifan sistem dari pecegahan bot tersebut: ini akan membantu kami menjaga jumlah dislike agar tetap bisa menjadi representasi dari jumlah yang asli. Tentu jumlahnya tidak akan akurat 100% jadi pada akhirnya itu semua terserah padamu untuk percaya atau tidak dengan jumlah dislikenya.

### Mengapa kamu tidak memberikan kode backend?

Kami akan memberikannya nanti pada satu waktu - tapi tidak ada alasan khusus untuk memberikanny sekarang. Itu memberikan rasa keamanan yang salah - karena pada sistem yang tidak terpercaya, kami bisa saja memberikan versi yang berdeda dengan yang kami deploy. Ada beberapa alsan lain untuk tetap menyembunyikan kodenya, terutama untuk memerangi spam. Menyembunyikan/menyamarkan kode penanganan spam adalah praktik yang cukup standar dilakukan.


================================================
FILE: Docs/SECURITY-FAQnl.md
================================================
Lees dit in andere talen: [English](SECURITY_FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Veiligheid

### Houd je mijn kijkgeschiedenis bij?

Nee. De code van de extensie is openbaar en u kunt deze zelf zien. De enige informatie die wordt verzonden, is de video-ID, die
nodig is om het aantal dislikes voor de video's op te halen. Er worden geen extra headers verzonden. Via de communicatielaag
wordt uw openbare IP-adres zichtbaar voor de server, evenals het tijdstip waarop het verzoek is gedaan. Geen van deze
identificeert u echter op enigerlei wijze uniek. Uitgaande van een zero-trust-omgeving, is het beste wat we kunnen krijgen een
dynamisch IP-adres. Wat vandaag van jou is, morgen van je buurman. Als u zich echt zorgen maakt dat uw IP-adres wordt
getraceerd, gebruikt u waarschijnlijk al een VPN.

### Kun je me uniek identificeren als ik een hekel heb?

Ja. Als je een video niet leuk vindt, maken we een willekeurig gegenereerde unieke ID voor je die niet is gekoppeld aan je
Google-account. Dit wordt gedaan om botting te voorkomen. Maar er is geen manier om deze willekeurige id aan jou of je
persoonlijke YouTube-account te koppelen.

### Welke informatie heb je precies?

Alleen de video-ID. Niet je opmerkingen, niet je gebruikersnaam, niet met wie je de video hebt gedeeld, geen aanvullende
metadata. Niks. Alleen de video-ID.

### Hoe wordt mijn IP opgeslagen?

De backend bewaart niet-gehashte IP-adressen alleen in vluchtig geheugen (RAM). Deze adressen worden niet opgeslagen op een
harde schijf en worden daarom niet gelogd. We hashen de IP-adressen en dat wordt in plaats daarvan opgeslagen. Dit wordt gedaan
om databasevandalisme te voorkomen.

### Ik hoorde wat discussie over OAuth en toegang tot mijn YouTube-account!

Deze functie zal optioneel zijn, en zeer veel opt-in. Als je een YouTube-creator bent en je wilt je afkeerstatistieken met ons delen, dan kan dat. De weg [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) gestructureerd was, is het eigenlijk heel veilig. U kunt op elk moment de toegang tot uw account intrekken en ons zeer specifieke machtigingen geven. We zullen geen toestemming vragen die niet vereist zijn. We vragen alleen toestemming om je videostatistieken te bekijken.

### Hoe kan ik deze afkeertelling vertrouwen?

We hebben maatregelen genomen om botaanvallen te voorkomen en zullen blijven werken aan het verbeteren van de effectiviteit van het botpreventiesysteem: dit zal ons helpen het aantal afkeer als een goede vertegenwoordiger van het werkelijke aantal te houden. Natuurlijk zal het nooit 100% nauwkeurig zijn, dus het is aan jou om te beslissen of je de telling vertrouwt of niet.

### Waarom deel je de backend-code niet?

We zullen het op een gegeven moment delen - maar er is echt geen echte reden om het nu te delen. Het geeft een vals gevoel van veiligheid - omdat we in een zero-trust-systeem net zo goed de ene versie kunnen onthullen, maar een andere kunnen implementeren. Er zijn tal van redenen om de code verborgen te houden, met name hoe we spam bestrijden. Het verbergen/verduisteren van de spamverwerkingscode is een vrij standaardpraktijk.


================================================
FILE: Docs/SECURITY-FAQpl.md
================================================
Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Security

### Czy śledzicie moją historię wyświetleń?

Nie. Kod rozszerzenia jest publiczny i można samemu to zobaczyć. Jedyne informacje, które są wysyłane, to ID filmu, które jest wymagane do pobrania liczby łapek w dół dla filmów. Nie są wysyłane żadne dodatkowe nagłówki. W warstwie sieciowej, Twój adres IP będzie jawny dla serwera wraz z czasem wykonania żądania. Jednakże, żadne z tych danych nie identyfikują Ciebie jednoznacznie w żaden sposób. Zakładając środowisko zerowego zaufania, najczulsze dane, jakie możemy otrzymać, jest dynamiczny adres IP, który dzisiaj jest Twój, a jutro Twojego sąsiada. Jeżeli boisz się śledzenia poprzez adres IP, pewnie już korzystasz z VPN.

### Czy możecie mnie jednoznacznie zidentyfikować, jeżeli zostawię łapkę w dół?

Tak. Kiedy zostawiasz łapkę w dół, tworzymy losowo generowane ID dla Ciebie, które nie jest związane z Twoim kontem Google. Powodem takiego rozwiązania jest zapobieganie botowaniu. Mimo to, nie ma sposobu powiązania tego losowego ID z Tobą lub Twoim osobistym kontem Google.

### Jakie informacje wy macie, konkretnie?

Tylko ID filmu. Komentarze - nie. Nazwa użytkownika - nie. Osoby, którym udostępniłeś film - nie. Jakiekolwiek dodatkowe metadane - nie. Nic. Tylko ID filmu.

### Jak mój adres IP jest przechowywany?

Backend trzyma niehashowane adresy IP tylko w pamięci zmiennej (RAM). Te adresy nie są przechowywane na dysku twardym, przez co nie są rejestrowane. Zamiast tego przechowujemy zhashowany adres IP. Jest to zrobione po to aby zapobiec wandalizmom.

### Słyszałem jakąś dyskusję o OAuth, i dostępie do mojego konta YouTube.

Ta funkcjonalność będzie opcjonalna i z całą pewnością wymagała ręcznego dołączenia. Jeżeli jesteś twórcą na YouTube i chcesz podzielić się z nami swoimi statystykami, to możesz. Sposób w jaki [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) został ustrukturyzowany jest właściwie bardzo bezpieczny. Możesz wycofać dostęp do konta w każdej chwili i dać nam specyficzne uprawnienia. Nie będziemy prosić o żadne uprawnienia, które nie są wymagane. Poprosimy tylko o możliwość wyświetlenia statystyk filmów.

### Jak bardzo mogę ufać licznikowi łapek w dół?

Zaimplementowaliśmy środki zapobiegające atakom botów i będziemy kontynuować pracę nad systemem zapobiegającym botom: to pomoże nam utrzymać licznik łapek w dół jako dobrą reprezentację prawdziwej wartości. Oczywiście, wartość ta nigdy nie będzie w 100% dokładna, więc to czy zaufasz tej liczbie zależy tylko od Ciebie.

### Dlaczego nie udostępnicie kodu backendu?

Kiedyś go udostępnimy - ale nie ma za bardzo sensu robić to teraz. Wprowadziłoby to fałszywe poczucie bezpieczeństwa - bo w systemie zerowego zaufania równie dobrze moglibyśmy przedstawić jeden system, a uruchomić inny. Jest dużo powodów do ukrywania kodu, specyficznie do walki ze spamem. Ukrywanie/Obfuskacja kodu jest dość standardową praktyką.


================================================
FILE: Docs/SECURITY-FAQpt_BR.md
================================================
Leia isso em outros idiomas: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md)

# Segurança

### Are you tracking my viewing history?

No. The extension's code is public and you can see it for yourself. The only information being sent is the video ID, which is required to fetch the dislike count for the videos. There are no additional headers being sent. Over the communication layer, your public IP will be exposed to the server, as well as the time when the request was made. However, none of these are uniquely identifying you in any way. Assuming a zero-trust environment, the best we could get is a dynamic IP. Which, today is yours, tomorrow is your neighbor's. If you're really worried about your IP being traced, you probably already use a VPN.

### Can you uniquely identify me if I dislike?

Yes. When you dislike a video, we create a randomly generated unique ID for you that is not tied to your Google account. This is done to prevent botting. But there is no way to tie this random Id to you or your personal YouTube account.

### Quais as informações que você tem, exatamente?

Somente seu video ID. Não temos seus comentarios, seu nome de usuario, ou qualquer outro Not your comments, not your username, not who you've shared the video with, not any additional metadata. NADA. Apenas seu Video ID.

### How is my IP stored?

The backend keeps unhashed IP addresses in volatile memory (RAM) only. These addresses aren't stored on a hard drive, and therefore aren't logged. We hash the IP addresses, and that's stored instead. This is done to prevent database vandalism.

### I heard some discussion over OAuth, and access to my YouTube account!

This feature will be optional, and very much opt-in. If you are a YouTube creator, and would like to share your dislike stats with us, you can. The way [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) was structured, it's actually very secure. You can revoke access to your account at any time, and can give very specific permissions to us. We will not ask for any permissions that aren't required. We'll only ask for permissions to view your video stats.

### How can I trust this dislike count?

We have implemented measures to prevent bot attacks and are gonna continue to work on improving the effectiveness of the bot prevention system: this will help us keep the dislike count as a good representative of the actual count. Of course it will never be 100% accurate so it's up to you to decide whether you trust the count or not.

### Why don't you share the backend code?

We will share it at some point - but there's really no real reason to share it right now. It gives a false sense of security - because in a zero-trust system, we could just as well disclose one version but deploy another. There are plenty of reasons to keep the code hidden, specifically, how we battle spam. Hiding/Obfuscating the spam handling code is a fairly standard practice.


================================================
FILE: Docs/SECURITY-FAQru.md
================================================
Прочитать на других языках: [English](SECURITY-FAQ.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Безопасность

### Вы отслеживаете мою историю просмотров?

Нет. Код расширения находится в открытом доступе, и вы можете ознакомиться с ним самостоятельно. Единственная передаваемая информация - это идентификатор видео, который необходим для получения данных о количестве просмотров видео. Никаких дополнительных заголовков не передаётся. На коммуникационном уровне серверу будет передан ваш публичный IP-адрес, а также время, когда был сделан запрос. Однако ничто из этого не идентифицирует вас каким-либо образом. Предполагая среду с нулевым доверием, лучшее, что мы можем получить, это динамический IP. Который сегодня ваш, а завтра - вашего соседа. Если вы действительно беспокоитесь о том, что ваш IP может быть отслежен, вы, вероятно, уже используете какой-нибудь VPN.

### Можете ли вы однозначно идентифицировать меня, если я оставил отметку «Не нравится»?

Да. Когда вы оставляете видео отметку «Не нравится», мы создаём для вас случайно созданный уникальный идентификатор, который не привязан к вашему аккаунту Google. Это делается для избежания ботов. Но нет никакого способа привязать этот случайный идентификатор к вам или вашему личному аккаунту YouTube.

### Какой именно информацией вы располагаете?

Только идентификатор видео. Ни ваших комментариев, ни вашего имени пользователя, ни того, с кем вы поделились видео, ни каких-либо дополнительных метаданных. Ничего. Только идентификатор видео.

### Как хранится мой IP-адрес?

Внутренняя часть нашего сервера хранит нехешированные IP-адреса только в энергозависимой памяти (ОЗУ). Эти адреса не хранятся на жёстком диске и поэтому не регистрируются. Мы хэшируем IP-адреса, и оно хранится вместо них. Это сделано для предотвращения вандализма в базе данных.

### Я слышал обсуждение OAuth и доступа к моему аккаунту на YouTube!

Эта функция будет необязательной и очень нужной. Если вы являетесь создателем YouTube и хотите поделиться с нами статистикой отметок «Не нравится», вы можете это сделать. По своей структуре [OAuth](<https://ru.wikipedia.org/wiki/OAuth#:~:text=%D0%B1%D0%B5%D0%B7%20%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D1%87%D0%B8%20%D0%B5%D0%B9%20(%D1%82%D1%80%D0%B5%D1%82%D1%8C%D0%B5%D0%B9%20%D1%81%D1%82%D0%BE%D1%80%D0%BE%D0%BD%D0%B5)%20%D0%BB%D0%BE%D0%B3%D0%B8%D0%BD%D0%B0%20%D0%B8%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8F>) очень безопасен. Вы можете отозвать доступ к своему аккаунту в любое время, и можете дать нам ограниченные разрешения. Мы не будем запрашивать никаких разрешений, которые не требуются. Мы будем запрашивать разрешения только для просмотра статистики ваших видео.

### Как я могу доверять этому счётчику отметок «Не нравится»?

Мы приняли меры по предотвращению атак ботов и собираемся продолжать работать над повышением эффективности системы предотвращения ботов: это поможет нам сохранить подсчёт отметок «Не нравится» как хороший представитель фактического количества. Конечно, он никогда не будет точным на 100%, поэтому вы сами решаете, доверять ему или нет.

### Почему бы вам не поделиться кодом внутренней части своего сервера?

Мы поделимся им в какой-то момент - но сейчас нет никаких реальных причин делиться ею. Это даёт ложное чувство безопасности - ведь в системе с нулевым доверием мы можем с таким же успехом раскрыть одну версию, но развернуть другую. Есть много причин держать код в тайне, в частности, как мы боремся со спамом. Скрытие и запутывание кода обработки спама - это довольно стандартная практика.


================================================
FILE: Docs/SECURITY-FAQtr.md
================================================
Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Güvenlik

### İzleme geçmişimi takip ediyor musunuz?

Hayır. Uzantının kodu herkese açıktır ve kendiniz görebilirsiniz. Gönderilen tek bilgi, videolar için dislike sayısını almak için gereken video kimliğidir. Gönderilen başka bir ek header yoktur. İletişim katmanı üzerinden, genel IP'niz sunucuya ve isteğin yapıldığı zamana maruz kalacaktır. Ancak, bunların hiçbiri sizi hiçbir şekilde benzersiz bir şekilde tanımlamıyor. Sıfır güven ortamını varsayarsak, elde edebileceğimizin en iyisi dinamik bir IP'dir. Ki, bu IP bugün sizin, yarın komşunuzun olabilir. IP'nizin izlenmesinden gerçekten endişeleniyorsanız, muhtemelen zaten bir VPN kullanıyorsunuzdur.

### Bir videoya dislike atarsam, beni benzersiz bir şekilde tanımlayabilir misiniz?

Evet. Bir videoya dislike attığınızda, sizin için Google hesabınızla bağlantılı olmayan rastgele oluşturulmuş benzersiz bir kimlik oluştururuz. Bu, bot kullanılmasını önlemek için yapılır. Ancak bu rastgele kimliği, size veya kişisel YouTube hesabınıza bağlamanın bir yolu yoktur.

### Tam olarak hangi bilgilere sahipsiniz, gerçekten?

Sadece video ID'si. Yorumlarınızı değil, kullanıcı adınızı değil, videoyu kiminle paylaştığınız değil, ek meta verilerinden hiçbiri değil. Hiç bir şey. Sadece video ID'si.

### IP adresim nasıl saklanıyor?

Backend, karma olmayan IP adreslerini yalnızca geçici bellekte (RAM'de) tutar. Bu adresler, bir sabit sürücüde depolanmaz ve bu nedenle günlüğe kaydedilmez. IP adreslerini hash ederiz ve bunun yerine depolanır. Bu, veri tabanı vandalizmini önlemek için yapılır.

### OAuth üzerinden YouTube hesabıma erişmek konusunda bazı tartışmalar duydum!

Bu özellik isteğe bağlı olacak ve çok fazla tercih edilecek. Bir YouTube içerik üreticisiyseniz ve dislike istatistiklerinizi bizimle paylaşmak istiyorsanız, bunu yapabilirsiniz. [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) yapılandırılma şekli, aslında çok güvenlidir. Hesabınıza erişimi istediğiniz zaman iptal edebilir ve bize çok özel izinler verebilirsiniz. Gerekli olmayan herhangi bir izini istemeyeceğiz. Yalnızca video istatistiklerinizi görüntülemek için izin isteyeceğiz.

### Bu dislike sayısına nasıl güvenebilirim?

Bot saldırılarını önlemek için önlemler aldık ve bot önleme sisteminin etkinliğini arttırmak için çalışmaya devam edeceğiz: bu, dislike sayısını gerçek sayının iyi bir temsilcisi olarak tutmamıza yardımcı olacaktır. Tabii ki hiçbir zaman %100 doğru olmayacaktır, bu yüzden sayıma güvenip güvenmemek size kalmıştır.

### Neden backend kodunu paylaşmıyorsunuz?

Bir noktada paylaşacağız - ama şu anda paylaşmak için ortada gerçekten gerçek bir sebep yok. Yanlış bir güvenlik hissi verebilir - çünkü sıfır güvenli bir sistemde, bir sürümü ifşa edebilir, ancak bir başkasını devreye alabiliriz. Özellikle spam ile nasıl mücadele ettiğimiz gibi, kodu gizli tutmak için birçok neden vardır. İstenmeyen posta işleme kodunu örtmek/gizlemek oldukça standart bir uygulamadır.


================================================
FILE: Docs/SECURITY-FAQuk.md
================================================
Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [Polski](SECURITY-FAQpl.md), [Deutsch](SECURITY-FAQde.md), [العربية](SECURITY-FAQar.md), [Bahasa Indonesia](SECURITY-FAQid.md), [中文](SECURITY-FAQcn.md), [български](SECURITY-FAQbg.md), [Tiếng Việt](SECURITY-FAQvi.md)

# Безпека

### Ви відстежуєте мою історію переглядів?

Ні. Код розширення знаходиться у відкритому доступі, і ви можете ознайомитись з ним самостійно. Єдина інформація, що передається - це ID відео, який необхідний для отримання даних про кількість відміток. Жодних додаткових заголовків не передається. На комунікаційному рівні серверу буде передано вашу публічну IP-адресу, а також час, коли було зроблено запит. Однак ніщо з цього ніяк не здатно вас ідентифіквати. Припускаючи середовище з нульовою довірою, найцінніше, що ми можемо отримати це динамічний IP. Який сьогодні ваш, а завтра – вашого сусіда. Якщо ви дійсно турбуєтеся про те, що ваш IP може бути відстежений, ви, ймовірно, вже використовуєте якийсь VPN.

### Чи можете ви однозначно ідентифікувати мене, коли я залишаю відмітку «Не подобається»?

Так. Коли ви залишаєте відео позначку «Не подобається», ми створюємо для вас випадковий унікальний ID, який не прив'язаний до вашого облікового запису Google. Це робиться для уникнення атаки ботів. Але немає жодного способу зв'язати цей випадковий ID до вас або вашого особистого облікового запису YouTube.

### Якою саме інформацією ви володієте?

Лише ID відео. Ні ваших коментарів, ні вашого імені користувача, ні того, з ким ви поділилися відео, ні будь-яких інших додаткових метаданих. Нічого. Лише ID відео.

### Як зберігається моя IP-адреса?

Внутрішня частина нашого сервера зберігає нехешовані IP-адреси лише в енергозалежній пам'яті (ОЗП). Ці адреси не зберігаються на жорсткому диску і тому ніде не записані. Ми хешуємо IP-адреси, і вони зберігаються замість інших. Це зроблено для запобігання вандалізму у базі даних.

### Я чув дискусію щодо OAuth і доступу до мого облікового запису YouTube!

Ця функція буде необов'язковою та дуже необхідною. Якщо ви творець YouTube і хочете поділитися з нами кількістю ваших відміток «Не подобається», ви зможете це зробити. За структурою [OAuth](https://uk.wikipedia.org/wiki/OAuth#:~:text=%D0%B1%D0%B5%D0%B7%20%D0%BD%D0%B5%D0%BE%D0%B1%D1%85%D1%96%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%96%20%D0%B2%D0%B2%D0%BE%D0%B4%D1%83%20%D1%96%D0%BC%D0%B5%D0%BD%D1%96%20%D0%BA%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87%D0%B0%20%D1%82%D0%B0%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8E) надбезпечний. Ви зможете відкликати доступ до свого облікового запису в будь-яку мить, і зможете дати нам обмежені дозволи. Ми не будемо вимагати жодних дозволів, крім необжідних. Ми будемо вимагати лише дозволи перегляду статистики ваших відео.

### Наскільки достовірна ця кількость відміток «Не подобається»?

Ми вжили заходів щодо запобігання атакам ботів і збираємося продовжувати працювати над підвищенням ефективності цієї сисеми надалі: це допоможе нам зберегти підрахунок відміток «Не подобається» як хороше представлення фактичної кількості. Звичайно, він ніколи не буде точним на всі 100%, тож ви самі вирішуєте, довіряти йому чи ні.

### Чому б вам не поділитися внутрішнім кодом вашого сервера?

Ми поділимося ним у якийсь момент – але зараз немає жодних причин це робити. Це дасть хибне почуття безпеки - адже в системі з нульовою довірою ми можемо з таким самим успіхом поділитися однією версією, але розгорнути іншу. Є багато причин тримати код у таємниці, зокрема, як ми боремося зі спамом. Приховування та затьмарення коду обробки спаму є доволі стандартною практикою.


================================================
FILE: Docs/SECURITY-FAQvi.md
================================================
Đọc bằng các ngôn ngữ khác: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md), [Polski](SECURITY-FAQpl.md), [Tiếng Việt](SECURITY-FAQvi.md)


# Tính Bảo mật

### Tiện ích mở rộng này có theo dõi lịch sử xem vi-đê-ô của tôi không?

Không. Mã nguồn của tiện ích mở rộng này được cung cấp công khai và bạn có thể kiểm tra mã nguồn nếu muốn. Thông tin duy nhất được tiện ích này gửi đi là ID của vi-đê-ô vì việc truy vấn số lượt đánh giá "không thích" cần ID của vi-đê-ô. Không thông tin nào khác được gửi đi. Ở lớp truyền tải, máy chủ sẽ biết được địa chỉ IP của bạn cũng như thời điểm mà truy vấn được tạo. Tuy nhiên, những thông tin này không thể định danh chính xác bạn. Giả sử với môi trường bất tín, chúng tôi cùng lắm chỉ có thể biết được địa chỉ IP động. Địa chỉ IP động là của bạn ngày hôm nay, nhưng sẽ là của người khác vào ngày mai. Nếu bạn lo lắng rằng địa chỉ IP của mình bị theo dõi, bạn có thể sử dụng mạng riêng ảo.

### Nhóm phát triển có thể định danh chính xác tôi không nếu như tôi có đánh giá "không thích"?

Có. Khi bạn đưa ra đánh giá "không thích" với một vi-đê-ô, chúng tội sẽ tạo ra một số định danh duy nhất ngẫu nhiên cho bạn, nhưng số định danh này không có bất kì mối liên hệ nào với tài khoản Google của bạn. Việc tạo số định danh là nhằm tránh người dùng bot. Không có bất kì cách nào để liên hệ số định danh này với bạn hay với tài khoản YouTube của bạn.

### Chính xác thì thông tin nào được thu thập?

Chỉ có ID của vi-đê-ô sẽ được thu thập. Bình luận của bạn, không. Tên người dùng của bạn, không. Thông tin của người mà bạn chia sẻ vi-đê-ô, không. Siêu dữ liệu khác, không. Không có bất kì thông tin nào khác được thu thập. Chỉ duy nhất ID của vi-đê-ô.

### Địa chỉ IP của tôi được lưu trữ ra sao?

Đầu sau chỉ giữ địa chỉ IP không được băm trong bộ nhớ khả biến (RAM). Những địa chỉ này không được lưu vào bộ nhớ bất biến (như ổ đĩa cứng) và như vậy không bị ghi chép lại. Chúng tôi băm địa chỉ IP rồi mới lưu lại những địa chỉ đã băm. Việc lưu địa chỉ đã băm là nhằm tránh việc phá hoại cơ sở dữ liệu.

### Tôi có bắt gặp một số cuộc thảo luận về OAuth cũng như về việc truy cập tài khoản YouTube của tôi!

Tính năng sắp có này là tùy chọn. Nếu bạn là nhà sáng tạo nội dung trên YouTube và bạn mong muốn chia sẽ số liệu đánh giá "không thích" với chúng tôi, chúng tôi rất hoan nghênh. Cách thức hoạt động của [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) giúp đảm bảo tính bảo mật. Bạn có thể hủy bỏ các truy cập vào tài khoản của bạn bất cứ lúc nào bạn muốn và cũng như có thể đưa ra bất kì sự cho phép cụ thể nào. Chúng tôi sẽ không đòi hỏi bất kì sự cho phép nào không cần thiết. Chúng tôi chỉ xin được cấp phép để xem số liệu về vi-đê-ô của bạn.

### Số lượt đánh giá "không thích" có đáng tin cậy không?

Chúng tôi đã và đa
Download .txt
gitextract_0m063igu/

├── .babelrc
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature-request.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── build.yaml
│       ├── commentcommands.yml
│       └── weblint.yml
├── .gitignore
├── .nvmrc
├── CONTRIBUTING.md
├── CONTRIBUTINGar.md
├── CONTRIBUTINGaz.md
├── CONTRIBUTINGbg.md
├── CONTRIBUTINGcn.md
├── CONTRIBUTINGda.md
├── CONTRIBUTINGde.md
├── CONTRIBUTINGes.md
├── CONTRIBUTINGfr.md
├── CONTRIBUTINGgr.md
├── CONTRIBUTINGhu.md
├── CONTRIBUTINGid.md
├── CONTRIBUTINGja.md
├── CONTRIBUTINGkr.md
├── CONTRIBUTINGnl.md
├── CONTRIBUTINGpl.md
├── CONTRIBUTINGpt_BR.md
├── CONTRIBUTINGru.md
├── CONTRIBUTINGsv.md
├── CONTRIBUTINGtr.md
├── CONTRIBUTINGuk.md
├── CONTRIBUTINGvi.md
├── Docs/
│   ├── FAQ.md
│   ├── FAQar.md
│   ├── FAQaz.md
│   ├── FAQbg.md
│   ├── FAQcn.md
│   ├── FAQde.md
│   ├── FAQfr.md
│   ├── FAQid.md
│   ├── FAQnl.md
│   ├── FAQpl.md
│   ├── FAQpt_BR.md
│   ├── FAQru.md
│   ├── FAQtr.md
│   ├── FAQuk.md
│   ├── FAQvi.md
│   ├── Guide__Installing.md
│   ├── Guide__Installingvi.md
│   ├── Guide__Troubleshooting.md
│   ├── Guide__Troubleshootingvi.md
│   ├── Privacy Policy
│   ├── Privacy Policyvi
│   ├── SECURITY-FAQ.md
│   ├── SECURITY-FAQaz.md
│   ├── SECURITY-FAQbg.md
│   ├── SECURITY-FAQcn.md
│   ├── SECURITY-FAQde.md
│   ├── SECURITY-FAQfr.md
│   ├── SECURITY-FAQid.md
│   ├── SECURITY-FAQnl.md
│   ├── SECURITY-FAQpl.md
│   ├── SECURITY-FAQpt_BR.md
│   ├── SECURITY-FAQru.md
│   ├── SECURITY-FAQtr.md
│   ├── SECURITY-FAQuk.md
│   ├── SECURITY-FAQvi.md
│   ├── SECURITY_FAQar.md
│   ├── readme.md
│   ├── readmeaz.md
│   ├── readmecn.md
│   ├── readmefr.md
│   ├── readmeid.md
│   ├── readmenl.md
│   ├── readmept_BR.md
│   ├── readmetr.md
│   └── readmevi.md
├── Extensions/
│   ├── UserScript/
│   │   └── Return Youtube Dislike.user.js
│   └── combined/
│       ├── _locales/
│       │   ├── az/
│       │   │   └── messages.json
│       │   ├── cs/
│       │   │   └── messages.json
│       │   ├── de/
│       │   │   └── messages.json
│       │   ├── el/
│       │   │   └── messages.json
│       │   ├── en/
│       │   │   └── messages.json
│       │   ├── es/
│       │   │   └── messages.json
│       │   ├── fr/
│       │   │   └── messages.json
│       │   ├── hu/
│       │   │   └── messages.json
│       │   ├── id/
│       │   │   └── messages.json
│       │   ├── it/
│       │   │   └── messages.json
│       │   ├── ja/
│       │   │   └── messages.json
│       │   ├── ko/
│       │   │   └── messages.json
│       │   ├── nl/
│       │   │   └── messages.json
│       │   ├── pl/
│       │   │   └── messages.json
│       │   ├── pt_BR/
│       │   │   └── messages.json
│       │   ├── ru/
│       │   │   └── messages.json
│       │   ├── sv_SE/
│       │   │   └── messages.json
│       │   ├── tr/
│       │   │   └── messages.json
│       │   ├── uk/
│       │   │   └── messages.json
│       │   ├── vi/
│       │   │   └── messages.json
│       │   ├── zh_CN/
│       │   │   └── messages.json
│       │   └── zh_TW/
│       │       └── messages.json
│       ├── changelog/
│       │   ├── 3/
│       │   │   └── changelog_3.0.html
│       │   ├── 4/
│       │   │   ├── changelog.css
│       │   │   └── changelog_4.0.html
│       │   ├── changelog.css
│       │   └── changelog.js
│       ├── content-style.css
│       ├── manifest-chrome.json
│       ├── manifest-firefox.json
│       ├── manifest-safari.json
│       ├── menu-fixer.js
│       ├── popup.css
│       ├── popup.html
│       ├── popup.js
│       ├── readme.md
│       ├── ryd.background.js
│       ├── ryd.changelog.js
│       ├── ryd.content-script.js
│       └── src/
│           ├── bar.js
│           ├── buttons.js
│           ├── changelog/
│           │   └── index.js
│           ├── config.js
│           ├── events.js
│           ├── patreon.js
│           ├── premiumAnalytics/
│           │   ├── activity/
│           │   │   ├── index.js
│           │   │   ├── index.spec.js
│           │   │   ├── time.js
│           │   │   └── time.spec.js
│           │   ├── constants.js
│           │   ├── index.js
│           │   ├── index.spec.js
│           │   ├── lifecycle.js
│           │   ├── lists/
│           │   │   └── index.js
│           │   ├── logging.js
│           │   ├── logging.spec.js
│           │   ├── map/
│           │   │   ├── index.js
│           │   │   └── index.spec.js
│           │   ├── panel.js
│           │   ├── panel.spec.js
│           │   ├── render.js
│           │   ├── requests.js
│           │   ├── state.js
│           │   ├── state.spec.js
│           │   ├── teaser/
│           │   │   ├── index.js
│           │   │   └── index.spec.js
│           │   ├── theme.js
│           │   ├── theme.spec.js
│           │   ├── tierNotice.js
│           │   ├── utils.js
│           │   └── utils.spec.js
│           ├── starRating.js
│           ├── state.js
│           ├── utils.js
│           └── utils.spec.js
├── LICENSE
├── README.md
├── READMEar.md
├── READMEaz.md
├── READMEbg.md
├── READMEcn.md
├── READMEda.md
├── READMEde.md
├── READMEes.md
├── READMEfr.md
├── READMEgr.md
├── READMEhu.md
├── READMEid.md
├── READMEja.md
├── READMEkr.md
├── READMEnl.md
├── READMEpl.md
├── READMEpt_BR.md
├── READMEru.md
├── READMEsv.md
├── READMEtr.md
├── READMEuk.md
├── READMEvi.md
├── Website/
│   ├── .eslintignore
│   ├── .eslintrc.js
│   ├── README.md
│   ├── READMEaz.md
│   ├── READMEbg.md
│   ├── READMEde.md
│   ├── READMEnl.md
│   ├── READMEtr.md
│   ├── READMEvi.md
│   ├── _locales/
│   │   ├── az.ts
│   │   ├── cs.ts
│   │   ├── de.ts
│   │   ├── en.ts
│   │   ├── es.ts
│   │   ├── fr.ts
│   │   ├── hu.ts
│   │   ├── id.ts
│   │   ├── it-IT.ts
│   │   ├── ja.ts
│   │   ├── ko.ts
│   │   ├── nl.ts
│   │   ├── pl.ts
│   │   ├── pt_BR.ts
│   │   ├── ru.ts
│   │   ├── sv.ts
│   │   ├── tr.ts
│   │   ├── uk.ts
│   │   └── vi.ts
│   ├── layouts/
│   │   ├── default.vue
│   │   └── error.vue
│   ├── nuxt.config.js
│   ├── package.json
│   ├── pages/
│   │   ├── debug.vue
│   │   ├── docs/
│   │   │   ├── endpoints.vue
│   │   │   ├── fetching.vue
│   │   │   ├── index.vue
│   │   │   ├── url.vue
│   │   │   └── usage-rights.vue
│   │   ├── docs.vue
│   │   ├── donate.vue
│   │   ├── faq.vue
│   │   ├── help.vue
│   │   ├── index.vue
│   │   ├── install.vue
│   │   ├── links.vue
│   │   └── pay/
│   │       └── crypto.vue
│   ├── raw_assets/
│   │   └── abstract.afdesign
│   └── store/
│       ├── README.md
│       ├── READMEbg.md
│       ├── READMEde.md
│       ├── READMEnl.md
│       ├── READMEtr.md
│       └── READMEvi.md
├── extension-description-store-ar.txt
├── extension-description-store-az.txt
├── extension-description-store-bg.txt
├── extension-description-store-cs.txt
├── extension-description-store-de.txt
├── extension-description-store-el.txt
├── extension-description-store-en.txt
├── extension-description-store-es.txt
├── extension-description-store-fr.txt
├── extension-description-store-hu.txt
├── extension-description-store-id.txt
├── extension-description-store-it.txt
├── extension-description-store-ja.txt
├── extension-description-store-ko.txt
├── extension-description-store-nl.txt
├── extension-description-store-pl.txt
├── extension-description-store-pt_BR.txt
├── extension-description-store-pt_PT.txt
├── extension-description-store-ru.txt
├── extension-description-store-sv_SE.txt
├── extension-description-store-tr.txt
├── extension-description-store-uk.txt
├── extension-description-store-vi.txt
├── extension-description-store-zh_CN.txt
├── extension-description-store-zh_TW.txt
├── jest.config.js
├── package.json
└── webpack.config.js
Download .txt
SYMBOL INDEX (404 symbols across 39 files)

FILE: Extensions/UserScript/Return Youtube Dislike.user.js
  constant LIKED_STATE (line 43) | const LIKED_STATE = "LIKED_STATE";
  constant DISLIKED_STATE (line 44) | const DISLIKED_STATE = "DISLIKED_STATE";
  constant NEUTRAL_STATE (line 45) | const NEUTRAL_STATE = "NEUTRAL_STATE";
  function cLog (line 54) | function cLog(text, subtext = "") {
  function isInViewport (line 61) | function isInViewport(element) {
  function getButtons (line 76) | function getButtons() {
  function getDislikeButton (line 103) | function getDislikeButton() {
  function getLikeButton (line 121) | function getLikeButton() {
  function getLikeTextContainer (line 129) | function getLikeTextContainer() {
  function getDislikeTextContainer (line 137) | function getDislikeTextContainer() {
  function createObserver (line 154) | function createObserver(options, callback) {
  function isVideoLiked (line 199) | function isVideoLiked() {
  function isVideoDisliked (line 206) | function isVideoDisliked() {
  function isVideoNotLiked (line 213) | function isVideoNotLiked() {
  function isVideoNotDisliked (line 220) | function isVideoNotDisliked() {
  function checkForUserAvatarButton (line 227) | function checkForUserAvatarButton() {
  function getState (line 238) | function getState() {
  function setLikes (line 248) | function setLikes(likesCount) {
  function setDislikes (line 256) | function setDislikes(dislikesCount) {
  function getLikeCountFromButton (line 269) | function getLikeCountFromButton() {
  function createRateBar (line 330) | function createRateBar(likes, dislikes) {
  function setState (line 408) | function setState() {
  function updateDOMDislikes (line 451) | function updateDOMDislikes() {
  function likeClicked (line 456) | function likeClicked() {
  function dislikeClicked (line 481) | function dislikeClicked() {
  function setInitialState (line 506) | function setInitialState() {
  function getVideoId (line 510) | function getVideoId() {
  function isVideoLoaded (line 523) | function isVideoLoaded() {
  function roundDown (line 539) | function roundDown(num) {
  function numberFormat (line 547) | function numberFormat(numberState) {
  function getNumberFormatter (line 557) | function getNumberFormatter(optionSelect) {
  function getColorFromTheme (line 600) | function getColorFromTheme(voteIsLike) {
  function setEventListeners (line 630) | function setEventListeners(evt) {

FILE: Extensions/combined/changelog/changelog.js
  function localizeHtmlPage (line 25) | function localizeHtmlPage() {
  function createLink (line 52) | function createLink(url, id) {

FILE: Extensions/combined/menu-fixer.js
  function debounceAsync (line 1) | function debounceAsync(func, wait, renderer) {

FILE: Extensions/combined/popup.js
  function localizeHtmlPage (line 24) | function localizeHtmlPage() {
  function createLink (line 52) | function createLink(url, id) {
  function initPatreonAuth (line 98) | function initPatreonAuth() {
  function initConfig (line 368) | function initConfig() {
  function initializeVersionNumber (line 382) | function initializeVersionNumber() {
  function compareVersions (line 400) | function compareVersions(latestStr, currentStr) {
  function initializeDisableVoteSubmission (line 419) | function initializeDisableVoteSubmission() {
  function initializeDisableLogging (line 425) | function initializeDisableLogging() {
  function initializeColoredThumbs (line 431) | function initializeColoredThumbs() {
  function initializeColoredBar (line 437) | function initializeColoredBar() {
  function initializeColorTheme (line 443) | function initializeColorTheme() {
  function initializeTooltipPercentage (line 449) | function initializeTooltipPercentage() {
  function initializeTooltipPercentageMode (line 455) | function initializeTooltipPercentageMode() {
  function initializeNumberDisplayFormat (line 461) | function initializeNumberDisplayFormat() {
  function updateNumberDisplayFormatContent (line 468) | function updateNumberDisplayFormatContent() {
  function initializeNumberDisplayReformatLikes (line 476) | function initializeNumberDisplayReformatLikes() {
  function initializeHidePremiumTeaser (line 482) | function initializeHidePremiumTeaser() {
  function storageChangeHandler (line 490) | function storageChangeHandler(changes, area) {
  function handleDisableVoteSubmissionChangeEvent (line 520) | function handleDisableVoteSubmissionChangeEvent(value) {
  function handleDisableLoggingChangeEvent (line 525) | function handleDisableLoggingChangeEvent(value) {
  function handleColoredThumbsChangeEvent (line 530) | function handleColoredThumbsChangeEvent(value) {
  function handleColoredBarChangeEvent (line 535) | function handleColoredBarChangeEvent(value) {
  function handleColorThemeChangeEvent (line 540) | function handleColorThemeChangeEvent(value) {
  function updateColorThemePreviewContent (line 549) | function updateColorThemePreviewContent(themeName) {
  function handleNumberDisplayFormatChangeEvent (line 554) | function handleNumberDisplayFormatChangeEvent(value) {
  function handleShowTooltipPercentageChangeEvent (line 559) | function handleShowTooltipPercentageChangeEvent(value) {
  function handleTooltipPercentageModeChangeEvent (line 564) | function handleTooltipPercentageModeChangeEvent(value) {
  function handleNumberDisplayReformatLikesChangeEvent (line 573) | function handleNumberDisplayReformatLikesChangeEvent(value) {
  function handleHidePremiumTeaserChangeEvent (line 578) | function handleHidePremiumTeaserChangeEvent(value) {
  function getNumberFormatter (line 584) | function getNumberFormatter(optionSelect) {
  function getColorFromTheme (line 635) | function getColorFromTheme(colorTheme, voteIsLike) {

FILE: Extensions/combined/ryd.background.js
  constant CHANGELOG_STORAGE_KEY (line 7) | const CHANGELOG_STORAGE_KEY = "lastShownChangelogVersion";
  constant PENDING_CHANGELOG_STORAGE_KEY (line 8) | const PENDING_CHANGELOG_STORAGE_KEY = "pendingChangelogVersion";
  function broadcastPatreonStatus (line 18) | function broadcastPatreonStatus(authenticated, user, sessionToken) {
  function handlePatreonAuthComplete (line 47) | function handlePatreonAuthComplete(user, sessionToken, done) {
  function getIdentityApi (line 66) | function getIdentityApi() {
  function launchWebAuthFlow (line 72) | function launchWebAuthFlow(url) {
  function extractOAuthParams (line 91) | function extractOAuthParams(responseUrl) {
  function openChangelogTab (line 241) | function openChangelogTab(version) {
  function scheduleChangelogVersion (line 255) | function scheduleChangelogVersion(version) {
  function clearPendingChangelogVersion (line 274) | function clearPendingChangelogVersion() {
  function showPendingChangelogIfNeeded (line 290) | function showPendingChangelogIfNeeded() {
  function persistChangelogVersion (line 321) | function persistChangelogVersion(version) {
  function maybeShowChangelog (line 341) | function maybeShowChangelog(details) {
  function sendVote (line 433) | async function sendVote(videoId, vote, depth = 1) {
  function register (line 480) | async function register() {
  function countLeadingZeroes (line 515) | function countLeadingZeroes(uInt8View, limit) {
  function solvePuzzle (line 542) | async function solvePuzzle(puzzle) {
  function generateUserID (line 565) | function generateUserID(length = 36) {
  function storageChangeHandler (line 583) | function storageChangeHandler(changes, area) {
  function handleDisableVoteSubmissionChangeEvent (line 616) | function handleDisableVoteSubmissionChangeEvent(value) {
  function handleDisableLoggingChangeEvent (line 625) | function handleDisableLoggingChangeEvent(value) {
  function handleNumberDisplayFormatChangeEvent (line 629) | function handleNumberDisplayFormatChangeEvent(value) {
  function handleShowTooltipPercentageChangeEvent (line 633) | function handleShowTooltipPercentageChangeEvent(value) {
  function handleTooltipPercentageModeChangeEvent (line 637) | function handleTooltipPercentageModeChangeEvent(value) {
  function changeIcon (line 644) | function changeIcon(iconName) {
  function handleColoredThumbsChangeEvent (line 650) | function handleColoredThumbsChangeEvent(value) {
  function handleColoredBarChangeEvent (line 654) | function handleColoredBarChangeEvent(value) {
  function handleColorThemeChangeEvent (line 658) | function handleColorThemeChangeEvent(value) {
  function handleNumberDisplayReformatLikesChangeEvent (line 665) | function handleNumberDisplayReformatLikesChangeEvent(value) {
  function handleHidePremiumTeaserChangeEvent (line 669) | function handleHidePremiumTeaserChangeEvent(value) {
  function initExtConfig (line 675) | function initExtConfig() {
  function initializeDisableVoteSubmission (line 688) | function initializeDisableVoteSubmission() {
  function initializeDisableLogging (line 699) | function initializeDisableLogging() {
  function initializeColoredThumbs (line 709) | function initializeColoredThumbs() {
  function initializeColoredBar (line 719) | function initializeColoredBar() {
  function initializeColorTheme (line 729) | function initializeColorTheme() {
  function initializeNumberDisplayFormat (line 739) | function initializeNumberDisplayFormat() {
  function initializeTooltipPercentage (line 749) | function initializeTooltipPercentage() {
  function initializeTooltipPercentageMode (line 759) | function initializeTooltipPercentageMode() {
  function initializeNumberDisplayReformatLikes (line 769) | function initializeNumberDisplayReformatLikes() {
  function initializeHidePremiumTeaser (line 779) | function initializeHidePremiumTeaser() {
  function isChrome (line 790) | function isChrome() {
  function isFirefox (line 794) | function isFirefox() {

FILE: Extensions/combined/ryd.content-script.js
  function ensureShortsNavigationObserver (line 16) | function ensureShortsNavigationObserver() {
  function checkForInitialization (line 53) | async function checkForInitialization() {
  function triggerInitializationCycle (line 81) | async function triggerInitializationCycle() {
  function setEventListeners (line 104) | async function setEventListeners() {

FILE: Extensions/combined/src/bar.js
  function createRateBar (line 12) | function createRateBar(likes, dislikes) {

FILE: Extensions/combined/src/buttons.js
  function getButtons (line 4) | function getButtons() {
  function getLikeButton (line 36) | function getLikeButton() {
  function getLikeTextContainer (line 50) | function getLikeTextContainer() {
  function getDislikeButton (line 54) | function getDislikeButton() {
  function createDislikeTextContainer (line 84) | function createDislikeTextContainer() {
  function getDislikeTextContainer (line 117) | function getDislikeTextContainer() {
  function checkForSignInButton (line 131) | function checkForSignInButton() {

FILE: Extensions/combined/src/changelog/index.js
  constant PATREON_JOIN_URL (line 4) | const PATREON_JOIN_URL = "https://www.patreon.com/join/returnyoutubedisl...
  constant SUPPORT_DOC_URL (line 5) | const SUPPORT_DOC_URL = config.links?.help ?? "https://returnyoutubedisl...
  constant COMMUNITY_URL (line 6) | const COMMUNITY_URL = config.links?.discord ?? "https://discord.gg/mYnES...
  function initChangelogPage (line 8) | function initChangelogPage() {
  function setup (line 16) | function setup() {
  function applyLocaleMetadata (line 23) | function applyLocaleMetadata() {
  function localizeHtmlPage (line 34) | function localizeHtmlPage() {
  function decorateScreenshotPlaceholders (line 49) | function decorateScreenshotPlaceholders() {
  function getPlaceholderLabelKey (line 65) | function getPlaceholderLabelKey(type) {
  function bindActions (line 78) | function bindActions() {
  function openExternal (line 106) | function openExternal(url, browser) {

FILE: Extensions/combined/src/config.js
  constant DEV_API_URL (line 1) | const DEV_API_URL = "https://localhost:7258";
  constant PROD_API_URL (line 2) | const PROD_API_URL = "https://returnyoutubedislikeapi.com";
  function getApiUrl (line 41) | function getApiUrl() {
  function getApiEndpoint (line 45) | function getApiEndpoint(endpoint) {
  function getChangelogUrl (line 49) | function getChangelogUrl() {

FILE: Extensions/combined/src/events.js
  function sendVote (line 25) | function sendVote(vote) {
  function updateDOMDislikes (line 35) | function updateDOMDislikes() {
  function likeClicked (line 40) | function likeClicked() {
  function dislikeClicked (line 68) | function dislikeClicked() {
  function addLikeDislikeEventListener (line 96) | function addLikeDislikeEventListener() {
  function createSmartimationObserver (line 112) | function createSmartimationObserver() {
  function storageChangeHandler (line 137) | function storageChangeHandler(changes, area) {
  function handleDisableVoteSubmissionChangeEvent (line 167) | function handleDisableVoteSubmissionChangeEvent(value) {
  function handleColoredThumbsChangeEvent (line 171) | function handleColoredThumbsChangeEvent(value) {
  function handleColoredBarChangeEvent (line 175) | function handleColoredBarChangeEvent(value) {
  function handleColorThemeChangeEvent (line 179) | function handleColorThemeChangeEvent(value) {
  function handleNumberDisplayFormatChangeEvent (line 184) | function handleNumberDisplayFormatChangeEvent(value) {
  function handleNumberDisplayReformatLikesChangeEvent (line 188) | function handleNumberDisplayReformatLikesChangeEvent(value) {
  function handleHidePremiumTeaserChangeEvent (line 192) | function handleHidePremiumTeaserChangeEvent(value) {

FILE: Extensions/combined/src/patreon.js
  function initPatreonFeatures (line 14) | function initPatreonFeatures() {
  function enablePremiumFeatures (line 53) | function enablePremiumFeatures() {
  function disablePremiumFeatures (line 63) | function disablePremiumFeatures() {
  function isPatreonUser (line 70) | function isPatreonUser() {
  function getPatreonTier (line 74) | function getPatreonTier() {

FILE: Extensions/combined/src/premiumAnalytics/activity/index.js
  function setActivityTranslator (line 13) | function setActivityTranslator(translator) {
  function resetActivityTranslator (line 21) | function resetActivityTranslator() {
  function translateActivity (line 25) | function translateActivity(key, substitutions) {
  constant MS_PER_MINUTE (line 35) | const MS_PER_MINUTE = 60 * 1000;
  constant MS_PER_HOUR (line 36) | const MS_PER_HOUR = 60 * 60 * 1000;
  constant MS_PER_DAY (line 37) | const MS_PER_DAY = 24 * MS_PER_HOUR;
  constant MS_PER_WEEK (line 38) | const MS_PER_WEEK = 7 * MS_PER_DAY;
  function pickFirstFinite (line 40) | function pickFirstFinite(...values) {
  function ensureActivityChart (line 49) | function ensureActivityChart() {
  function renderActivityChart (line 61) | function renderActivityChart(timeSeries) {
  function clearActivityChart (line 245) | function clearActivityChart() {
  function resetChartZoom (line 250) | function resetChartZoom() {
  function resizeActivityChart (line 272) | function resizeActivityChart() {
  function disposeActivityChart (line 276) | function disposeActivityChart() {
  function registerZoomSelectionListener (line 284) | function registerZoomSelectionListener(listener) {
  function unregisterZoomSelectionListener (line 290) | function unregisterZoomSelectionListener(listener) {
  function createDataZoom (line 294) | function createDataZoom(bounds, selection) {
  function resolveBucketSize (line 337) | function resolveBucketSize(label) {
  function formatBucketDescription (line 350) | function formatBucketDescription(label, bucketMs) {
  function formatBucketNumber (line 395) | function formatBucketNumber(value) {
  function approximately (line 400) | function approximately(value, target) {
  function normalizeSeriesPoints (line 404) | function normalizeSeriesPoints(points, bucketMs) {
  function handleDataZoom (line 454) | function handleDataZoom(event) {
  function resolveZoomValue (line 487) | function resolveZoomValue(payload, valueKey, percentKey, minBound, maxBo...

FILE: Extensions/combined/src/premiumAnalytics/activity/index.spec.js
  function getMessage (line 59) | function getMessage(key, substitutions) {
  function createPanel (line 76) | function createPanel() {

FILE: Extensions/combined/src/premiumAnalytics/activity/time.js
  function computeChartBounds (line 4) | function computeChartBounds(points, timeline, bucketSizeMs) {
  function updateGlobalBounds (line 28) | function updateGlobalBounds(bounds) {
  function clampRangeToBounds (line 48) | function clampRangeToBounds(range, bounds) {
  function combineBounds (line 64) | function combineBounds(primary = {}, fallback = {}) {
  function resolvePreferredLower (line 70) | function resolvePreferredLower(primary, fallback) {
  function resolvePreferredUpper (line 80) | function resolvePreferredUpper(primary, fallback) {

FILE: Extensions/combined/src/premiumAnalytics/activity/time.spec.js
  function initializeState (line 13) | function initializeState() {

FILE: Extensions/combined/src/premiumAnalytics/constants.js
  constant MS_PER_DAY (line 1) | const MS_PER_DAY = 24 * 60 * 60 * 1000;
  constant EXPANDABLE_SECTIONS (line 2) | const EXPANDABLE_SECTIONS = new Set(["activity", "map", "lists"]);

FILE: Extensions/combined/src/premiumAnalytics/index.spec.js
  function getMessage (line 139) | function getMessage(key, substitutions) {

FILE: Extensions/combined/src/premiumAnalytics/lifecycle.js
  function initPremiumAnalytics (line 22) | function initPremiumAnalytics() {
  function handleNavigation (line 45) | function handleNavigation() {
  function handleRangePreset (line 66) | function handleRangePreset(rangeDays) {
  function handleRangeAnchorChange (line 81) | function handleRangeAnchorChange(anchor) {
  function handleModeChange (line 95) | function handleModeChange(mode) {
  function handleChartExpand (line 102) | function handleChartExpand(chartKey) {
  function handleChartSelection (line 131) | function handleChartSelection(range) {
  function teardownPanel (line 153) | function teardownPanel() {
  function teardownPremiumAnalytics (line 171) | function teardownPremiumAnalytics() {
  function updatePremiumSession (line 181) | function updatePremiumSession({ token, active, membershipTier }) {
  function resolveVideoId (line 217) | function resolveVideoId() {
  function resizeCharts (line 223) | function resizeCharts() {

FILE: Extensions/combined/src/premiumAnalytics/lists/index.js
  function createPlaceholder (line 4) | function createPlaceholder() {
  function renderEntry (line 8) | function renderEntry({ countryCode, countryName, likes, dislikes }, type) {
  function updateCountryList (line 16) | function updateCountryList(container, entries, type) {

FILE: Extensions/combined/src/premiumAnalytics/logging.js
  constant LOG_PREFIX (line 1) | const LOG_PREFIX = '[PremiumAnalytics]';
  function logTimeBounds (line 3) | function logTimeBounds(label, bounds) {
  function logRangeSelection (line 13) | function logRangeSelection(label, range) {
  function logFetchRequest (line 23) | function logFetchRequest(videoId, params) {
  function logZoomPreview (line 27) | function logZoomPreview(label, bounds) {

FILE: Extensions/combined/src/premiumAnalytics/map/index.js
  function setMapTranslator (line 14) | function setMapTranslator(translator) {
  function resetMapTranslator (line 22) | function resetMapTranslator() {
  function translateMessage (line 26) | function translateMessage(key, substitutions) {
  constant NORMALIZED_WORLD_FEATURES (line 36) | const NORMALIZED_WORLD_FEATURES = normalizeWorldFeatures(worldFeatures);
  constant WORLD_FEATURE_COLLECTION (line 37) | const WORLD_FEATURE_COLLECTION = { type: "FeatureCollection", features: ...
  constant NORMALIZED_US_STATE_FEATURES (line 40) | const NORMALIZED_US_STATE_FEATURES = normalizeWorldFeatures(usStateFeatu...
  constant US_STATE_FEATURE_COLLECTION (line 41) | const US_STATE_FEATURE_COLLECTION = { type: "FeatureCollection", feature...
  constant US_STATE_NAME_BY_CODE (line 43) | const US_STATE_NAME_BY_CODE = {
  constant CANONICAL_SYNONYM_GROUPS (line 101) | const CANONICAL_SYNONYM_GROUPS = [
  constant CANONICAL_SYNONYM_LOOKUP (line 121) | const CANONICAL_SYNONYM_LOOKUP = buildSynonymLookup(CANONICAL_SYNONYM_GR...
  constant FEATURE_NAME_BY_CANONICAL (line 122) | const FEATURE_NAME_BY_CANONICAL = buildFeatureCanonicalMap(NORMALIZED_WO...
  constant ISO_TO_FEATURE_NAME (line 123) | const ISO_TO_FEATURE_NAME = buildIsoToFeatureNameMap(FEATURE_NAME_BY_CAN...
  constant US_STATE_FEATURE_CANONICAL_MAP (line 124) | const US_STATE_FEATURE_CANONICAL_MAP = buildStateCanonicalMap(NORMALIZED...
  function ensureMapChart (line 126) | function ensureMapChart() {
  function renderMap (line 138) | function renderMap(countries) {
  function resolveMapContext (line 241) | function resolveMapContext(state) {
  function buildCountryEntries (line 274) | function buildCountryEntries(entries) {
  function buildSubdivisionEntries (line 297) | function buildSubdivisionEntries(entries, countryCode) {
  function resolveSubdivisionFeatureName (line 328) | function resolveSubdivisionFeatureName(countryCode, subdivisionCode, fal...
  function filterSubdivisionsForCountry (line 359) | function filterSubdivisionsForCountry(subdivisions, countryCode) {
  function initializeMapInteractions (line 368) | function initializeMapInteractions(mapChart) {
  function handleMapClick (line 379) | function handleMapClick(params) {
  function bindMapResetButton (line 409) | function bindMapResetButton() {
  function updateMapResetButtonVisibility (line 424) | function updateMapResetButtonVisibility() {
  function disposeMapChart (line 434) | function disposeMapChart() {
  function clearMapChart (line 443) | function clearMapChart() {
  function resizeMapChart (line 447) | function resizeMapChart() {
  function resolveVisualMapConfig (line 451) | function resolveVisualMapConfig(values, mode) {
  function formatMapTooltip (line 499) | function formatMapTooltip(params) {
  function resolveMapRegionName (line 517) | function resolveMapRegionName(countryCode, fallbackName) {
  function buildStateCanonicalMap (line 555) | function buildStateCanonicalMap(features) {
  function buildFeatureCanonicalMap (line 566) | function buildFeatureCanonicalMap(features) {
  function buildSynonymLookup (line 595) | function buildSynonymLookup(groups) {
  function buildIsoToFeatureNameMap (line 611) | function buildIsoToFeatureNameMap(featureCanonicalMap) {
  function findFeatureNameByCanonical (line 628) | function findFeatureNameByCanonical(name, featureCanonicalMap) {
  function canonicalizeName (line 634) | function canonicalizeName(name) {
  function expandAbbreviations (line 646) | function expandAbbreviations(name) {
  function normalizeIsoCode (line 663) | function normalizeIsoCode(code) {
  function normalizeWorldFeatures (line 678) | function normalizeWorldFeatures(features) {
  function normalizeGeometry (line 689) | function normalizeGeometry(geometry) {
  function normalizeRing (line 706) | function normalizeRing(ring) {

FILE: Extensions/combined/src/premiumAnalytics/map/index.spec.js
  function getMessage (line 113) | function getMessage(key, substitutions) {
  function setupI18nMock (line 127) | function setupI18nMock() {
  function createChartStub (line 135) | function createChartStub() {
  function setupPanel (line 149) | function setupPanel() {

FILE: Extensions/combined/src/premiumAnalytics/panel.js
  function configurePanelCallbacks (line 12) | function configurePanelCallbacks(newCallbacks) {
  function ensurePanel (line 16) | function ensurePanel() {
  function updateRangeButtons (line 48) | function updateRangeButtons() {
  function updateRangeAnchorButtons (line 60) | function updateRangeAnchorButtons() {
  function updateModeButtons (line 75) | function updateModeButtons() {
  function setListsLoading (line 84) | function setListsLoading() {
  function setFooterMessage (line 90) | function setFooterMessage(text) {
  function setPanelExpanded (line 97) | function setPanelExpanded(expanded) {
  function togglePanelExpanded (line 102) | function togglePanelExpanded() {
  function setLoadingState (line 106) | function setLoadingState(isLoading) {
  function setActivityBucketLabel (line 111) | function setActivityBucketLabel(text) {
  function renderSummary (line 122) | function renderSummary(summary) {
  function bindUiControls (line 167) | function bindUiControls(container) {
  function createPanelMarkup (line 203) | function createPanelMarkup() {
  function createModeControls (line 275) | function createModeControls() {
  function createRangeAnchorControls (line 290) | function createRangeAnchorControls() {
  function formatRangeLabel (line 312) | function formatRangeLabel(days) {
  function resolveRangeAnchor (line 318) | function resolveRangeAnchor() {
  function formatRangeWindowLabel (line 323) | function formatRangeWindowLabel(anchor) {
  function formatDayCount (line 346) | function formatDayCount(count) {
  function applyExpansionState (line 355) | function applyExpansionState() {
  function applyChartExpansionState (line 368) | function applyChartExpansionState() {
  function positionExpandedPanel (line 390) | function positionExpandedPanel(panel, button) {
  function resetPanelPosition (line 405) | function resetPanelPosition(panel, button) {
  function positionExpandedSection (line 414) | function positionExpandedSection(section, button) {
  function resetSectionPosition (line 442) | function resetSectionPosition(section, button) {
  function applyLoadingState (line 454) | function applyLoadingState() {
  function formatSelectedPeriod (line 461) | function formatSelectedPeriod() {
  function formatDate (line 475) | function formatDate(ms) {
  function resolveAnchorRect (line 482) | function resolveAnchorRect() {
  function applyAnchorPosition (line 505) | function applyAnchorPosition(target, rect, { maxWidthFallback }) {

FILE: Extensions/combined/src/premiumAnalytics/panel.spec.js
  function getMessage (line 22) | function getMessage(key, substitutions) {
  function mountSecondaryContainer (line 40) | function mountSecondaryContainer() {

FILE: Extensions/combined/src/premiumAnalytics/render.js
  function renderAnalytics (line 17) | function renderAnalytics(data) {

FILE: Extensions/combined/src/premiumAnalytics/requests.js
  constant HOURLY_THRESHOLD_DAYS (line 11) | const HOURLY_THRESHOLD_DAYS = 7;
  constant HOURLY_THRESHOLD_MS (line 12) | const HOURLY_THRESHOLD_MS = HOURLY_THRESHOLD_DAYS * MS_PER_DAY;
  constant MS_PER_HOUR (line 13) | const MS_PER_HOUR = 60 * 60 * 1000;
  function requestAnalytics (line 15) | function requestAnalytics({ selection } = {}) {
  function commitSelectionFetch (line 108) | function commitSelectionFetch(selection) {
  function scheduleSelectionFetch (line 114) | function scheduleSelectionFetch(selection) {
  function normalizeSelection (line 118) | function normalizeSelection(selection) {
  function msToIso (line 128) | function msToIso(ms) {
  function handleError (line 135) | function handleError(status, code) {
  function resolveAnchor (line 159) | function resolveAnchor() {
  function resolveBucket (line 164) | function resolveBucket(selection, rangeDays) {

FILE: Extensions/combined/src/premiumAnalytics/state.js
  constant RANGE_OPTIONS (line 1) | const RANGE_OPTIONS = [7, 30, 90, 0];
  constant RANGE_ANCHORS (line 2) | const RANGE_ANCHORS = ["first", "last"];
  constant COUNTRY_LIMIT (line 3) | const COUNTRY_LIMIT = 12;
  function resetStateForVideo (line 40) | function resetStateForVideo() {
  function resetSessionState (line 60) | function resetSessionState() {
  function setSession (line 66) | function setSession(token, isActive, membershipTier = "none") {

FILE: Extensions/combined/src/premiumAnalytics/state.spec.js
  function resetGlobals (line 15) | function resetGlobals() {

FILE: Extensions/combined/src/premiumAnalytics/teaser/index.js
  constant PATREON_JOIN_URL (line 5) | const PATREON_JOIN_URL = "https://www.patreon.com/join/returnyoutubedisl...
  constant CHANGELOG_URL (line 6) | const CHANGELOG_URL = getChangelogUrl();
  constant TEASER_SUPPRESSION_REASON_LEGACY (line 8) | const TEASER_SUPPRESSION_REASON_LEGACY = "legacy";
  constant TEASER_SUPPRESSION_REASON_PREMIUM (line 9) | const TEASER_SUPPRESSION_REASON_PREMIUM = "premium";
  constant TEASER_SUPPRESSION_REASON_SETTINGS (line 10) | const TEASER_SUPPRESSION_REASON_SETTINGS = "settings";
  function initPremiumTeaser (line 22) | async function initPremiumTeaser() {
  function setTeaserSuppressed (line 37) | function setTeaserSuppressed(shouldSuppress, reason = TEASER_SUPPRESSION...
  function applySettingsSuppression (line 67) | function applySettingsSuppression(shouldHide, persist = false) {
  function syncSuppressionWithSettings (line 84) | async function syncSuppressionWithSettings() {
  function handleNavigation (line 118) | function handleNavigation() {
  function resolveVideoId (line 139) | function resolveVideoId() {
  function fetchAndRender (line 151) | function fetchAndRender(videoId) {
  function ensurePanel (line 207) | function ensurePanel() {
  function removePanel (line 258) | function removePanel(includeStrayNodes = false) {
  function resetState (line 272) | function resetState() {
  function setLoading (line 280) | function setLoading(isLoading) {
  function showError (line 290) | function showError() {
  function updateCounts (line 299) | function updateCounts(payload) {
  function normalizeNumber (line 316) | function normalizeNumber(value) {
  function createPanelMarkup (line 327) | function createPanelMarkup() {
  function openTab (line 386) | function openTab(url) {
  function handleManualDismiss (line 415) | function handleManualDismiss(event) {

FILE: Extensions/combined/src/premiumAnalytics/teaser/index.spec.js
  function getMessage (line 20) | function getMessage(key, substitutions) {
  function mountSecondary (line 47) | function mountSecondary() {
  function flushPromises (line 112) | async function flushPromises() {

FILE: Extensions/combined/src/premiumAnalytics/theme.js
  function getTextColor (line 1) | function getTextColor() {
  function getMutedTextColor (line 5) | function getMutedTextColor() {
  function getBorderColor (line 9) | function getBorderColor(alpha = 0.15) {
  function getSurfaceColor (line 14) | function getSurfaceColor(lightAlpha = 0.06, darkAlpha = 0.02) {
  function getHoverFillColor (line 20) | function getHoverFillColor(lightAlpha = 0.18, darkAlpha = 0.18) {
  function isDarkTheme (line 26) | function isDarkTheme() {
  function parseColor (line 43) | function parseColor(value) {

FILE: Extensions/combined/src/premiumAnalytics/tierNotice.js
  constant PATREON_UPGRADE_URL (line 3) | const PATREON_UPGRADE_URL = "https://www.patreon.com/join/returnyoutubed...
  function ensureListeners (line 11) | function ensureListeners() {
  function handleNavigation (line 17) | function handleNavigation() {
  function createPanelMarkup (line 41) | function createPanelMarkup() {
  function wireCta (line 57) | function wireCta(panel) {
  function removePanel (line 66) | function removePanel() {
  function resetState (line 73) | function resetState() {
  function showTierNotice (line 77) | function showTierNotice() {
  function hideTierNotice (line 83) | function hideTierNotice() {

FILE: Extensions/combined/src/premiumAnalytics/utils.js
  function sanitizeCount (line 1) | function sanitizeCount(value) {
  function toEpoch (line 9) | function toEpoch(value) {
  function capitalize (line 15) | function capitalize(value) {
  function debounce (line 19) | function debounce(fn, delay) {
  function safeJson (line 27) | function safeJson(response) {

FILE: Extensions/combined/src/starRating.js
  function createStarRating (line 2) | function createStarRating(rating, isMobile) {

FILE: Extensions/combined/src/state.js
  constant LIKED_STATE (line 14) | const LIKED_STATE = "LIKED_STATE";
  constant DISLIKED_STATE (line 15) | const DISLIKED_STATE = "DISLIKED_STATE";
  constant NEUTRAL_STATE (line 16) | const NEUTRAL_STATE = "NEUTRAL_STATE";
  function isMobile (line 64) | function isMobile() {
  function isShorts (line 68) | function isShorts() {
  function isNewDesign (line 72) | function isNewDesign() {
  function isRoundedDesign (line 76) | function isRoundedDesign() {
  function isLikesDisabled (line 112) | function isLikesDisabled() {
  function isVideoLiked (line 120) | function isVideoLiked() {
  function isVideoDisliked (line 130) | function isVideoDisliked() {
  function getState (line 140) | function getState(storedData) {
  function setLikes (line 151) | function setLikes(likesCount) {
  function setDislikes (line 156) | function setDislikes(dislikesCount) {
  function getLikeCountFromButton (line 183) | function getLikeCountFromButton() {
  function processResponse (line 201) | function processResponse(response, storedData) {
  function displayError (line 236) | function displayError(error) {
  function setState (line 240) | async function setState(storedData) {
  function setInitialState (line 270) | async function setInitialState() {
  function initExtConfig (line 274) | async function initExtConfig() {
  function initializeSelectors (line 288) | async function initializeSelectors() {
  function initializeDisableVoteSubmission (line 303) | function initializeDisableVoteSubmission() {
  function initializeDisableLogging (line 313) | function initializeDisableLogging() {
  function initializeColoredThumbs (line 326) | function initializeColoredThumbs() {
  function initializeColoredBar (line 336) | function initializeColoredBar() {
  function initializeColorTheme (line 346) | function initializeColorTheme() {
  function initializeNumberDisplayFormat (line 356) | function initializeNumberDisplayFormat() {
  function initializeTooltipPercentage (line 366) | function initializeTooltipPercentage() {
  function initializeTooltipPercentageMode (line 376) | function initializeTooltipPercentageMode() {
  function initializeNumberDisplayReformatLikes (line 386) | function initializeNumberDisplayReformatLikes() {
  function initializeHidePremiumTeaser (line 396) | function initializeHidePremiumTeaser() {

FILE: Extensions/combined/src/utils.js
  function numberFormat (line 3) | function numberFormat(numberState) {
  function getNumberFormatter (line 7) | function getNumberFormatter(optionSelect) {
  function localize (line 49) | function localize(localeString, substitutions) {
  function getBrowser (line 73) | function getBrowser() {
  function getVideoId (line 84) | function getVideoId(url) {
  function isInViewport (line 98) | function isInViewport(element) {
  function isShortsLoaded (line 113) | function isShortsLoaded(videoId) {
  function isVideoLoaded (line 146) | function isVideoLoaded() {
  function initializeLogging (line 173) | function initializeLogging() {
  function getColorFromTheme (line 183) | function getColorFromTheme(voteIsLike) {
  function querySelector (line 211) | function querySelector(selectors, element) {
  function querySelectorAll (line 221) | function querySelectorAll(selectors) {
  function createObserver (line 232) | function createObserver(options, callback) {

FILE: Extensions/combined/src/utils.spec.js
  function resetGlobals (line 71) | function resetGlobals() {

FILE: webpack.config.js
  class MirrorJsOutputsPlugin (line 34) | class MirrorJsOutputsPlugin {
    method constructor (line 35) | constructor(targetDirs) {
    method apply (line 39) | apply(compiler) {
Condensed preview — 258 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,403K chars).
[
  {
    "path": ".babelrc",
    "chars": 64,
    "preview": "{\n  \"presets\": [\"@babel/preset-env\"],\n  \"plugins\": [\"rewire\"]\n}\n"
  },
  {
    "path": ".gitattributes",
    "chars": 66,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 80,
    "preview": "patreon: returnyoutubedislike\ncustom: \"https://returnyoutubedislike.com/donate\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "chars": 2159,
    "preview": "name: Bug Report\ndescription: File a bug report!\n# title: \"(Bug): \"\nlabels: [\"bug\"]\nbody:\n  - type: checkboxes\n    attri"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "chars": 936,
    "preview": "name: Feature Request\ndescription: Request or suggest a new feature!\n# title: \"(Feature Request): \"\nlabels: [\"enhancemen"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 296,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n  -"
  },
  {
    "path": ".github/workflows/build.yaml",
    "chars": 1128,
    "preview": "name: Test Build Extension\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - Extensions/combined/**\n  pull_requ"
  },
  {
    "path": ".github/workflows/commentcommands.yml",
    "chars": 2387,
    "preview": "name: Comment Commands\n\non:\n  issue_comment:\n    types: [created]\n\njobs:\n  assign-commenter:\n    runs-on: ubuntu-24.04\n "
  },
  {
    "path": ".github/workflows/weblint.yml",
    "chars": 535,
    "preview": "# This workflow lints the code in /Website, if any was committed\n\nname: Website Lint\n\non:\n  push:\n    branches: \n      -"
  },
  {
    "path": ".gitignore",
    "chars": 585,
    "preview": "*cert\n*Backend\n.DS_Store\npackage-lock.json\n\n# Website node modules and build output\nWebsite/package-lock.json\n\n# AI assi"
  },
  {
    "path": ".nvmrc",
    "chars": 8,
    "preview": "v12.18.4"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2905,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGar.md",
    "chars": 2604,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGaz.md",
    "chars": 3188,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGbg.md",
    "chars": 3245,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGcn.md",
    "chars": 1672,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGda.md",
    "chars": 2874,
    "preview": "Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTI"
  },
  {
    "path": "CONTRIBUTINGde.md",
    "chars": 3367,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGes.md",
    "chars": 3277,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGfr.md",
    "chars": 4149,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGgr.md",
    "chars": 3343,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGhu.md",
    "chars": 2879,
    "preview": "Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTI"
  },
  {
    "path": "CONTRIBUTINGid.md",
    "chars": 2999,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGja.md",
    "chars": 1951,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGkr.md",
    "chars": 1951,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGnl.md",
    "chars": 3198,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGpl.md",
    "chars": 3045,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGpt_BR.md",
    "chars": 3314,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGru.md",
    "chars": 3293,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGsv.md",
    "chars": 2837,
    "preview": "Read this in other languages: [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz.md), [български](CONTRIBUTI"
  },
  {
    "path": "CONTRIBUTINGtr.md",
    "chars": 3176,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGuk.md",
    "chars": 3100,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "CONTRIBUTINGvi.md",
    "chars": 3996,
    "preview": "Read this in other languages: [English](CONTRIBUTING.md), [العربية](CONTRIBUTINGar.md), [Azərbaycan dili](CONTRIBUTINGaz"
  },
  {
    "path": "Docs/FAQ.md",
    "chars": 2598,
    "preview": "Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [ук"
  },
  {
    "path": "Docs/FAQar.md",
    "chars": 2440,
    "preview": "اقرأ هذا بلغات أخرى: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська]"
  },
  {
    "path": "Docs/FAQaz.md",
    "chars": 2695,
    "preview": "Bunu digər dillərdə oxuyun: [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [украї"
  },
  {
    "path": "Docs/FAQbg.md",
    "chars": 2664,
    "preview": "Прочетете това на други езици:  [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [T"
  },
  {
    "path": "Docs/FAQcn.md",
    "chars": 1311,
    "preview": "以其他语言阅读: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md), "
  },
  {
    "path": "Docs/FAQde.md",
    "chars": 2934,
    "preview": "Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [ук"
  },
  {
    "path": "Docs/FAQfr.md",
    "chars": 2097,
    "preview": "Lisez ceci dans d'autres langues : [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), ["
  },
  {
    "path": "Docs/FAQid.md",
    "chars": 2714,
    "preview": "Baca ini dibahasa lain: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українсь"
  },
  {
    "path": "Docs/FAQnl.md",
    "chars": 2946,
    "preview": "Lees dit in andere talen: [Engels](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [українська]("
  },
  {
    "path": "Docs/FAQpl.md",
    "chars": 2760,
    "preview": "Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Tür"
  },
  {
    "path": "Docs/FAQpt_BR.md",
    "chars": 2504,
    "preview": "Leia isso em outros Idiomas: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [укр"
  },
  {
    "path": "Docs/FAQru.md",
    "chars": 2038,
    "preview": "Read this in other languages: [English](FAQ.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [укра"
  },
  {
    "path": "Docs/FAQtr.md",
    "chars": 2654,
    "preview": "Bunu diğer dillerde okuyun: [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Français](FAQfr.md), [украї"
  },
  {
    "path": "Docs/FAQuk.md",
    "chars": 2700,
    "preview": "Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md), [Deutsch"
  },
  {
    "path": "Docs/FAQvi.md",
    "chars": 3612,
    "preview": "Đọc bằng các ngôn ngữ khác: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkç"
  },
  {
    "path": "Docs/Guide__Installing.md",
    "chars": 9173,
    "preview": "**Contents**\n\n- [Downloading](#downloading)\n  - [Desktop (all OS supported by these browsers)](#desktop-all-os-supported"
  },
  {
    "path": "Docs/Guide__Installingvi.md",
    "chars": 9172,
    "preview": "**Mục lục**\n\n- [Downloading](#downloading)\n  - [Desktop (all OS supported by these browsers)](#desktop-all-os-supported-"
  },
  {
    "path": "Docs/Guide__Troubleshooting.md",
    "chars": 6541,
    "preview": "Troubleshooting Guide\n\n**Index**\n\n- [Extension](#extension)\n  - [Basic checks](#basic-checks)\n  - [Check API status](#ch"
  },
  {
    "path": "Docs/Guide__Troubleshootingvi.md",
    "chars": 6547,
    "preview": "Hướng dẫn Khắc phục Sự cố\n\n**Mục lục**\n\n- [Extension](#extension)\n  - [Basic checks](#basic-checks)\n  - [Check API statu"
  },
  {
    "path": "Docs/Privacy Policy",
    "chars": 399,
    "preview": "The only data collected from users is their likes and dislikes made while the extension is installed.\n\nNo personal info,"
  },
  {
    "path": "Docs/Privacy Policyvi",
    "chars": 528,
    "preview": "Dữ liệu duy nhất được thu nhập: số lượt đánh giá \"thích\" và \"không thích\" trong thời gian tiện ích mở rộng này được cài."
  },
  {
    "path": "Docs/SECURITY-FAQ.md",
    "chars": 3221,
    "preview": "Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.m"
  },
  {
    "path": "Docs/SECURITY-FAQaz.md",
    "chars": 3189,
    "preview": "Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md),"
  },
  {
    "path": "Docs/SECURITY-FAQbg.md",
    "chars": 3272,
    "preview": "Прочетете това на други езици:  [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md"
  },
  {
    "path": "Docs/SECURITY-FAQcn.md",
    "chars": 1287,
    "preview": "阅读其他语言版本:[русский](SECURITY-FAQru.md)、[Nederlands](SECURITY_FAQnl.md)、[Français](SECURITY-FAQfr.md)、[Türkçe](SECURITY-FA"
  },
  {
    "path": "Docs/SECURITY-FAQde.md",
    "chars": 3640,
    "preview": "Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.m"
  },
  {
    "path": "Docs/SECURITY-FAQfr.md",
    "chars": 3920,
    "preview": "Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl"
  },
  {
    "path": "Docs/SECURITY-FAQid.md",
    "chars": 3394,
    "preview": "Baca ini dibahasa lain: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [T"
  },
  {
    "path": "Docs/SECURITY-FAQnl.md",
    "chars": 3483,
    "preview": "Lees dit in andere talen: [English](SECURITY_FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türk"
  },
  {
    "path": "Docs/SECURITY-FAQpl.md",
    "chars": 3339,
    "preview": "Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md),"
  },
  {
    "path": "Docs/SECURITY-FAQpt_BR.md",
    "chars": 3203,
    "preview": "Leia isso em outros idiomas: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md"
  },
  {
    "path": "Docs/SECURITY-FAQru.md",
    "chars": 3830,
    "preview": "Прочитать на других языках: [English](SECURITY-FAQ.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), "
  },
  {
    "path": "Docs/SECURITY-FAQtr.md",
    "chars": 3390,
    "preview": "Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md),"
  },
  {
    "path": "Docs/SECURITY-FAQuk.md",
    "chars": 3692,
    "preview": "Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), ["
  },
  {
    "path": "Docs/SECURITY-FAQvi.md",
    "chars": 3823,
    "preview": "Đọc bằng các ngôn ngữ khác: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), ["
  },
  {
    "path": "Docs/SECURITY_FAQar.md",
    "chars": 2689,
    "preview": "اقرأ هذا بلغات أخرى: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türk"
  },
  {
    "path": "Docs/readme.md",
    "chars": 1243,
    "preview": "Read this in other languages: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md), [Bahasa Indones"
  },
  {
    "path": "Docs/readmeaz.md",
    "chars": 1326,
    "preview": "Read this in other languages: [English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md)\n\n**İçerikler**\n\n-"
  },
  {
    "path": "Docs/readmecn.md",
    "chars": 992,
    "preview": "阅读其他语言版本:[English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md)\n\n**目录**\n\n- [指南]"
  },
  {
    "path": "Docs/readmefr.md",
    "chars": 1146,
    "preview": "Lisez ceci dans d'autres langues : [English](readme.md), [Nederlands](readmenl.md), [Türkçe](readmetr.md), [Bahasa Indon"
  },
  {
    "path": "Docs/readmeid.md",
    "chars": 1251,
    "preview": "Baca ini dibahasa lain: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md)\n\n**Isi**\n\n- [Petunjuk]"
  },
  {
    "path": "Docs/readmenl.md",
    "chars": 1277,
    "preview": "Read this in other languages: [English](readme.md), [Français](readmefr.md), [Türkçe](readmetr.md), [Bahasa Indonesia](r"
  },
  {
    "path": "Docs/readmept_BR.md",
    "chars": 1215,
    "preview": "Leia isso em outros idiomas: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md), [Bahasa Indonesi"
  },
  {
    "path": "Docs/readmetr.md",
    "chars": 1300,
    "preview": "Read this in other languages: [English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md), [Bahasa Indonesi"
  },
  {
    "path": "Docs/readmevi.md",
    "chars": 1331,
    "preview": "Đọc bằng các ngôn ngữ khác: [English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr."
  },
  {
    "path": "Extensions/UserScript/Return Youtube Dislike.user.js",
    "chars": 23430,
    "preview": "// ==UserScript==\n// @name         Return YouTube Dislike\n// @namespace    https://www.returnyoutubedislike.com/\n// @hom"
  },
  {
    "path": "Extensions/combined/_locales/az/messages.json",
    "chars": 15936,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API statusu:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Oflayn\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/cs/messages.json",
    "chars": 15641,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Stav API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiStat"
  },
  {
    "path": "Extensions/combined/_locales/de/messages.json",
    "chars": 16408,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API‑Status:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/el/messages.json",
    "chars": 16820,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Κατάσταση API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Εκτός λειτουργίας\"\n"
  },
  {
    "path": "Extensions/combined/_locales/en/messages.json",
    "chars": 15189,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API Status:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/es/messages.json",
    "chars": 16797,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Estado de la API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Fuera de línea\"\n"
  },
  {
    "path": "Extensions/combined/_locales/fr/messages.json",
    "chars": 17000,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"État de l’API :\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Hors ligne\"\n  },\n "
  },
  {
    "path": "Extensions/combined/_locales/hu/messages.json",
    "chars": 16417,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API állapot:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiS"
  },
  {
    "path": "Extensions/combined/_locales/id/messages.json",
    "chars": 15831,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Status API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/it/messages.json",
    "chars": 16512,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Stato API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSta"
  },
  {
    "path": "Extensions/combined/_locales/ja/messages.json",
    "chars": 12944,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API の状態:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"オフライン\"\n  },\n  \"apiStatusO"
  },
  {
    "path": "Extensions/combined/_locales/ko/messages.json",
    "chars": 12936,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API 상태:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"오프라인\"\n  },\n  \"apiStatusOnl"
  },
  {
    "path": "Extensions/combined/_locales/nl/messages.json",
    "chars": 16270,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API‑status:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/pl/messages.json",
    "chars": 16153,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Status API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/pt_BR/messages.json",
    "chars": 16421,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Status da API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"ap"
  },
  {
    "path": "Extensions/combined/_locales/ru/messages.json",
    "chars": 16262,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Состояние API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Офлайн\"\n  },\n  \"api"
  },
  {
    "path": "Extensions/combined/_locales/sv_SE/messages.json",
    "chars": 15844,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API‑status:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Offline\"\n  },\n  \"apiSt"
  },
  {
    "path": "Extensions/combined/_locales/tr/messages.json",
    "chars": 16082,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API durumu:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Çevrimdışı\"\n  },\n  \"ap"
  },
  {
    "path": "Extensions/combined/_locales/uk/messages.json",
    "chars": 16230,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Стан API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Офлайн\"\n  },\n  \"apiStatu"
  },
  {
    "path": "Extensions/combined/_locales/vi/messages.json",
    "chars": 16344,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"Trạng thái API:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"Ngoại tuyến\"\n  },\n"
  },
  {
    "path": "Extensions/combined/_locales/zh_CN/messages.json",
    "chars": 11995,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API 状态:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"离线\"\n  },\n  \"apiStatusOnlin"
  },
  {
    "path": "Extensions/combined/_locales/zh_TW/messages.json",
    "chars": 12022,
    "preview": "{\n  \"apiStatusLabel\": {\n    \"message\": \"API 狀態:\"\n  },\n  \"apiStatusOffline\": {\n    \"message\": \"離線\"\n  },\n  \"apiStatusOnlin"
  },
  {
    "path": "Extensions/combined/changelog/3/changelog_3.0.html",
    "chars": 3693,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <meta content=\"text/html; charset=utf-8\" />\n    <title title=\"__MSG_extensionName__\""
  },
  {
    "path": "Extensions/combined/changelog/4/changelog.css",
    "chars": 8899,
    "preview": ":root {\n  color-scheme: light dark;\n  --ryd-bg: linear-gradient(135deg, #050505 0%, #141414 45%, #3c0a0f 100%);\n  --ryd-"
  },
  {
    "path": "Extensions/combined/changelog/4/changelog_4.0.html",
    "chars": 5526,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-w"
  },
  {
    "path": "Extensions/combined/changelog/changelog.css",
    "chars": 930,
    "preview": "/* Variables */\n:root {\n  --primary: #ff4444;\n  --accent: #581111;\n\n  --background: #111;\n  --secondary: #272727;\n  --te"
  },
  {
    "path": "Extensions/combined/changelog/changelog.js",
    "chars": 3097,
    "preview": "/*   Config   */\nconst config = {\n  advanced: false,\n  disableVoteSubmission: false,\n  coloredThumbs: false,\n  coloredBa"
  },
  {
    "path": "Extensions/combined/content-style.css",
    "chars": 15465,
    "preview": ":root {\n  /* --yt-spec-icon-disabled: #f44 !important;\n  --yt-spec-text-primary: #4f4 !important; */\n  /* --yt-spec-gene"
  },
  {
    "path": "Extensions/combined/manifest-chrome.json",
    "chars": 1184,
    "preview": "{\n  \"name\": \"__MSG_extensionName__\",\n  \"description\": \"__MSG_extensionDesc__\",\n  \"default_locale\": \"en\",\n  \"version\": \"_"
  },
  {
    "path": "Extensions/combined/manifest-firefox.json",
    "chars": 1248,
    "preview": "{\n  \"name\": \"__MSG_extensionName__\",\n  \"description\": \"__MSG_extensionDesc__\",\n  \"default_locale\": \"en\",\n  \"version\": \"_"
  },
  {
    "path": "Extensions/combined/manifest-safari.json",
    "chars": 804,
    "preview": "{\n  \"name\": \"__MSG_extensionName__\",\n  \"description\": \"__MSG_extensionDesc__\",\n  \"default_locale\": \"en\",\n  \"version\": \"_"
  },
  {
    "path": "Extensions/combined/menu-fixer.js",
    "chars": 1806,
    "preview": "function debounceAsync(func, wait, renderer) {\n  let timeout;\n  let lastCallTime = 0;\n\n  return async function (...args)"
  },
  {
    "path": "Extensions/combined/popup.css",
    "chars": 5314,
    "preview": "/* Variables */\n:root {\n  color-scheme: dark;\n\n  --primary: #cc2929;\n  --primary: #f39090;\n  --secondary: #502e2e;\n  --t"
  },
  {
    "path": "Extensions/combined/popup.html",
    "chars": 9773,
    "preview": "<!doctype html>\n<html>\n\n  <!---   HEADER   -->\n  <head>\n    <meta content=\"text/html; charset=utf-8\" />\n    <title title"
  },
  {
    "path": "Extensions/combined/popup.js",
    "chars": 24704,
    "preview": "import { config as appConfig, getApiUrl, getApiEndpoint } from \"./src/config.js\";\n\n/*   Config   */\nconst config = {\n  a"
  },
  {
    "path": "Extensions/combined/readme.md",
    "chars": 697,
    "preview": "# Extension Source\n\n## Guide to Compiling\n\n## Compiling to Development (Testing)\n\n<ol>\n    <li>Go to the root directory "
  },
  {
    "path": "Extensions/combined/ryd.background.js",
    "chars": 24081,
    "preview": "import { config, getApiUrl, getApiEndpoint, getChangelogUrl } from \"./src/config\";\n\nconst apiUrl = getApiUrl();\nconst vo"
  },
  {
    "path": "Extensions/combined/ryd.changelog.js",
    "chars": 75,
    "preview": "import { initChangelogPage } from \"./src/changelog\";\n\ninitChangelogPage();\n"
  },
  {
    "path": "Extensions/combined/ryd.content-script.js",
    "chars": 3172,
    "preview": "import { getButtons } from \"./src/buttons\";\nimport { isShorts, setInitialState, initExtConfig } from \"./src/state\";\nimpo"
  },
  {
    "path": "Extensions/combined/src/bar.js",
    "chars": 4783,
    "preview": "import { getButtons, getDislikeButton, getLikeButton } from \"./buttons\";\nimport {\n  extConfig,\n  isMobile,\n  isLikesDisa"
  },
  {
    "path": "Extensions/combined/src/buttons.js",
    "chars": 4277,
    "preview": "import { isMobile, isShorts, extConfig } from \"./state\";\nimport { isInViewport, querySelector, querySelectorAll } from \""
  },
  {
    "path": "Extensions/combined/src/changelog/index.js",
    "chars": 3430,
    "preview": "import { config } from \"../config\";\nimport { getBrowser, localize } from \"../utils\";\n\nconst PATREON_JOIN_URL = \"https://"
  },
  {
    "path": "Extensions/combined/src/config.js",
    "chars": 1663,
    "preview": "const DEV_API_URL = \"https://localhost:7258\";\nconst PROD_API_URL = \"https://returnyoutubedislikeapi.com\";\n\nconst runtime"
  },
  {
    "path": "Extensions/combined/src/events.js",
    "chars": 5745,
    "preview": "import {\n  getBrowser,\n  getVideoId,\n  numberFormat,\n  createObserver,\n} from \"./utils\";\nimport {\n  checkForSignInButton"
  },
  {
    "path": "Extensions/combined/src/patreon.js",
    "chars": 2534,
    "preview": "import { initPremiumAnalytics, teardownPremiumAnalytics, updatePremiumSession } from \"./premiumAnalytics\";\nimport {\n  in"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/activity/index.js",
    "chars": 15826,
    "preview": "import * as echarts from \"echarts\";\n\nimport { analyticsState } from \"../state\";\nimport { setActivityBucketLabel } from \""
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/activity/index.spec.js",
    "chars": 15922,
    "preview": "/**\n * @jest-environment jsdom\n */\n\njest.mock(\"echarts\", () => {\n  return {\n    init: jest.fn(() => {\n      const zrHand"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/activity/time.js",
    "chars": 2618,
    "preview": "import { sanitizeCount, toEpoch } from \"../utils\";\nimport { analyticsState } from \"../state\";\n\nexport function computeCh"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/activity/time.spec.js",
    "chars": 2816,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport { analyticsState, resetStateForVideo } from \"../state\";\nimport {\n  computeCha"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/constants.js",
    "chars": 152,
    "preview": "const MS_PER_DAY = 24 * 60 * 60 * 1000;\nconst EXPANDABLE_SECTIONS = new Set([\"activity\", \"map\", \"lists\"]);\n\nexport { MS_"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/index.js",
    "chars": 147,
    "preview": "export { initPremiumAnalytics, teardownPremiumAnalytics, updatePremiumSession } from \"./lifecycle\";\nexport { requestAnal"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/index.spec.js",
    "chars": 16229,
    "preview": "/**\n * @jest-environment jsdom\n */\n\njest.mock(\"../config\", () => ({\n  __esModule: true,\n  getApiEndpoint: jest.fn((path)"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/lifecycle.js",
    "chars": 6357,
    "preview": "import { analyticsState, resetStateForVideo, setSession } from \"./state\";\nimport {\n  configurePanelCallbacks,\n  ensurePa"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/lists/index.js",
    "chars": 980,
    "preview": "import { sanitizeCount } from \"../utils\";\nimport { localize } from \"../../utils\";\n\nfunction createPlaceholder() {\n  retu"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/logging.js",
    "chars": 963,
    "preview": "const LOG_PREFIX = '[PremiumAnalytics]';\n\nexport function logTimeBounds(label, bounds) {\n  if (!bounds) return;\n  consol"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/logging.spec.js",
    "chars": 1576,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport {\n  logTimeBounds,\n  logRangeSelection,\n  logFetchRequest,\n  logZoomPreview,\n"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/map/index.js",
    "chars": 21407,
    "preview": "import * as echarts from \"echarts\";\nimport { feature } from \"topojson-client\";\nimport countryCodeLookup from \"country-co"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/map/index.spec.js",
    "chars": 13842,
    "preview": "/**\n * @jest-environment jsdom\n */\n\njest.mock(\"echarts\", () => {\n  const registerMap = jest.fn();\n  const init = jest.fn"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/panel.js",
    "chars": 18628,
    "preview": "import { analyticsState, RANGE_OPTIONS, RANGE_ANCHORS } from \"./state\";\nimport { sanitizeCount } from \"./utils\";\nimport "
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/panel.spec.js",
    "chars": 10170,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport { analyticsState, resetStateForVideo } from \"./state\";\nimport {\n  configurePa"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/render.js",
    "chars": 3118,
    "preview": "import { analyticsState } from \"./state\";\nimport {\n  ensurePanel,\n  renderSummary,\n  updateRangeButtons,\n  updateRangeAn"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/requests.js",
    "chars": 5857,
    "preview": "import { getApiEndpoint } from \"../config\";\nimport { analyticsState, COUNTRY_LIMIT } from \"./state\";\nimport { ensurePane"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/state.js",
    "chars": 2267,
    "preview": "export const RANGE_OPTIONS = [7, 30, 90, 0];\nexport const RANGE_ANCHORS = [\"first\", \"last\"];\nexport const COUNTRY_LIMIT "
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/state.spec.js",
    "chars": 4835,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport {\n  analyticsState,\n  resetStateForVideo,\n  resetSessionState,\n  setSession,\n"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/teaser/index.js",
    "chars": 12022,
    "preview": "import { getApiEndpoint, getChangelogUrl } from \"../../config\";\nimport { getBrowser, getVideoId, localize } from \"../../"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/teaser/index.spec.js",
    "chars": 6880,
    "preview": "/**\n * @jest-environment jsdom\n */\n\njest.mock(\"../../config\", () => ({\n  getApiEndpoint: jest.fn((path) => `https://api."
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/theme.js",
    "chars": 2361,
    "preview": "export function getTextColor() {\n  return getComputedStyle(document.documentElement).getPropertyValue(\"--yt-spec-text-pr"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/theme.spec.js",
    "chars": 2250,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport { getTextColor, getMutedTextColor, getBorderColor, getSurfaceColor, getHoverF"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/tierNotice.js",
    "chars": 2320,
    "preview": "import { localize } from \"../utils\";\n\nconst PATREON_UPGRADE_URL = \"https://www.patreon.com/join/returnyoutubedislike/che"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/utils.js",
    "chars": 742,
    "preview": "export function sanitizeCount(value) {\n  const number = Number(value);\n  if (!Number.isFinite(number) || number <= 0) {\n"
  },
  {
    "path": "Extensions/combined/src/premiumAnalytics/utils.spec.js",
    "chars": 2426,
    "preview": "/**\n * @jest-environment jsdom\n */\n\nimport {\n  sanitizeCount,\n  toEpoch,\n  capitalize,\n  debounce,\n  safeJson,\n} from \"."
  },
  {
    "path": "Extensions/combined/src/starRating.js",
    "chars": 2947,
    "preview": "\nfunction createStarRating(rating, isMobile) {\n  let starRating = document.createElement(\"label\");\n\n  let starSlider = d"
  },
  {
    "path": "Extensions/combined/src/state.js",
    "chars": 12724,
    "preview": "import { getLikeButton, getDislikeButton, getButtons, getLikeTextContainer, getDislikeTextContainer } from \"./buttons\";\n"
  },
  {
    "path": "Extensions/combined/src/utils.js",
    "chars": 7113,
    "preview": "import { extConfig, isShorts } from \"./state\";\n\nfunction numberFormat(numberState) {\n  return getNumberFormatter(extConf"
  },
  {
    "path": "Extensions/combined/src/utils.spec.js",
    "chars": 14053,
    "preview": "/**\n * @jest-environment jsdom\n */\n\njest.mock(\"./state\", () => {\n  const extConfig = {\n    disableVoteSubmission: false,"
  },
  {
    "path": "LICENSE",
    "chars": 35149,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 5037,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEar.md",
    "chars": 4815,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEaz.md",
    "chars": 4983,
    "preview": "[![Chrome Web Mağazası](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ra"
  },
  {
    "path": "READMEbg.md",
    "chars": 5107,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEcn.md",
    "chars": 3808,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEda.md",
    "chars": 5040,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEde.md",
    "chars": 5735,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEes.md",
    "chars": 5277,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEfr.md",
    "chars": 5115,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEgr.md",
    "chars": 5148,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEhu.md",
    "chars": 5041,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEid.md",
    "chars": 5403,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEja.md",
    "chars": 4618,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEkr.md",
    "chars": 4795,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEnl.md",
    "chars": 5038,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEpl.md",
    "chars": 4918,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEpt_BR.md",
    "chars": 5629,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEru.md",
    "chars": 5169,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEsv.md",
    "chars": 5383,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEtr.md",
    "chars": 5495,
    "preview": "[![Chrome Web Mağazası](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ra"
  },
  {
    "path": "READMEuk.md",
    "chars": 5074,
    "preview": "[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Ratin"
  },
  {
    "path": "READMEvi.md",
    "chars": 5799,
    "preview": "[![Cửa hàng Chrome Trực tuyến](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Đánh"
  },
  {
    "path": "Website/.eslintignore",
    "chars": 186,
    "preview": "# js vendor file with import/require\nassets/vendor/**\n# static vendor file . use with nuxt.config.js script\nstatic/**\n# "
  },
  {
    "path": "Website/.eslintrc.js",
    "chars": 571,
    "preview": "module.exports = {\n  root: true,\n  env: {\n    node: true,\n    browser: true,\n  },\n  parserOptions: {\n    parser: \"babel-"
  },
  {
    "path": "Website/README.md",
    "chars": 3553,
    "preview": "Read this in other languages: [Nederlands](READMEnl.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md), [български](READ"
  },
  {
    "path": "Website/READMEaz.md",
    "chars": 3656,
    "preview": "Digər dillərdə oxuyun: [Nederlands](READMEnl.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md)\n\n# return-youtube-dislik"
  },
  {
    "path": "Website/READMEbg.md",
    "chars": 3868,
    "preview": "Прочетете това на други езици: [English](README.md), [Nederlands](READMEnl.md), [Türkçe](READMEtr.md)\n\n# return-youtube-"
  },
  {
    "path": "Website/READMEde.md",
    "chars": 3904,
    "preview": "Read this in other languages: [English](README.md), [Nederlands](READMEnl.md), [Türkçe](READMEtr.md)\n\n# return-youtube-d"
  },
  {
    "path": "Website/READMEnl.md",
    "chars": 3622,
    "preview": "Read this in other languages: [English](README.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md), [български](READMEbg."
  },
  {
    "path": "Website/READMEtr.md",
    "chars": 3739,
    "preview": "Read this in other languages: [English](README.md), [Nederlands](READMEnl.md), [Deutsch](READMEde.md), [български](READM"
  },
  {
    "path": "Website/READMEvi.md",
    "chars": 3632,
    "preview": "Đọc bằng các ngôn ngữ khác: [English](README.md), [Nederlands](READMEnl.md), [Türkçe](READMEtr.md)\n\n# return-youtube-dis"
  },
  {
    "path": "Website/_locales/az.ts",
    "chars": 7075,
    "preview": "import { az } from \"vuetify/src/locale\";\n// By HAJİAGHA SADİKHOV\nexport default {\n  ...az,\n  home: {\n    name: \"Ana Səhi"
  },
  {
    "path": "Website/_locales/cs.ts",
    "chars": 6977,
    "preview": "import { cs } from \"vuetify/src/locale\";\n// By Fjuro\nexport default {\n  ...cs,\n  home: {\n    name: \"Domů\",\n    title: \"R"
  },
  {
    "path": "Website/_locales/de.ts",
    "chars": 7577,
    "preview": "import { en } from \"vuetify/src/locale\";\n// By tubyoub\nexport default {\n  ...en,\n  home: {\n    name: \"Startseite\",\n    t"
  },
  {
    "path": "Website/_locales/en.ts",
    "chars": 6775,
    "preview": "import { en } from \"vuetify/src/locale\";\n\nexport default {\n  ...en,\n  home: {\n    name: \"Home\",\n    title: \"Return YouTu"
  },
  {
    "path": "Website/_locales/es.ts",
    "chars": 7843,
    "preview": "import { es } from \"vuetify/src/locale\";\n// By Alejandro Gayol\nexport default {\n  ...es,\n  home: {\n    name: \"Inicio\",\n "
  },
  {
    "path": "Website/_locales/fr.ts",
    "chars": 7947,
    "preview": "import { fr } from \"vuetify/src/locale\";\n\nexport default {\n  ...fr,\n  home: {\n    name: \"Accueil\",\n    title: \"Return Yo"
  },
  {
    "path": "Website/_locales/hu.ts",
    "chars": 7608,
    "preview": "import { hu } from 'vuetify/src/locale';\n// By Gergely Pap\nexport default {\n    ...hu,\n    home: {\n        name: 'Főolda"
  },
  {
    "path": "Website/_locales/id.ts",
    "chars": 7103,
    "preview": "import { id } from \"vuetify/src/locale\";\n\nexport default {\n  ...id,\n  home: {\n    name: \"Beranda\",\n    title: \"Return Yo"
  },
  {
    "path": "Website/_locales/it-IT.ts",
    "chars": 7370,
    "preview": "import { en } from \"vuetify/src/locale\";\n\nexport default {\n  ...en,\n  home: {\n    name: \"Home\",\n    title: \"Return YouTu"
  },
  {
    "path": "Website/_locales/ja.ts",
    "chars": 4645,
    "preview": "import { ja } from \"vuetify/src/locale\";\n\nexport default {\n  ...ja,\n  home: {\n    name: \"ホーム\",\n    title: \"Return YouTub"
  },
  {
    "path": "Website/_locales/ko.ts",
    "chars": 4910,
    "preview": "import { ko } from \"vuetify/src/locale\";\n//libaraldev\nexport default {\n  ...ko,\n  home: {\n    name: \"홈\",\n    title: \"Ret"
  },
  {
    "path": "Website/_locales/nl.ts",
    "chars": 7478,
    "preview": "import { nl } from \"vuetify/src/locale\";\n\nexport default {\n  ...nl,\n  home: {\n    name: \"Home\",\n    title: \"Return YouTu"
  },
  {
    "path": "Website/_locales/pl.ts",
    "chars": 7216,
    "preview": "import { pl } from \"vuetify/src/locale\";\n// by itsbudyn#6502\nexport default {\n  ...pl,\n  home: {\n    name: \"Strona główn"
  },
  {
    "path": "Website/_locales/pt_BR.ts",
    "chars": 7065,
    "preview": "import { pt_BR } from \"vuetify/src/locale\";\n// by Unnamed-orbert\nexport default {\n  ...pt_BR,\n  home: {\n    name: \"Inici"
  }
]

// ... and 58 more files (download for full content)

About this extraction

This page contains the full source code of the Anarios/return-youtube-dislike GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 258 files (1.3 MB), approximately 379.5k tokens, and a symbol index with 404 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!