Repository: scribble-rs/scribble.rs Branch: master Commit: 018e84862221 Files: 92 Total size: 1.2 MB Directory structure: gitextract_v5hmk19x/ ├── .dockerignore ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── docker-image-update.yml │ ├── release.yml │ ├── test-and-build.yml │ └── test-pr.yml ├── .gitignore ├── .golangci.yml ├── .vscode/ │ ├── launch.json │ └── settings.json ├── LICENSE ├── README.md ├── cmd/ │ └── scribblers/ │ └── main.go ├── fly.Dockerfile ├── fly.toml ├── fly_deploy.sh ├── go.mod ├── go.sum ├── internal/ │ ├── api/ │ │ ├── createparse.go │ │ ├── createparse_test.go │ │ ├── doc.go │ │ ├── http.go │ │ ├── v1.go │ │ └── ws.go │ ├── config/ │ │ └── config.go │ ├── frontend/ │ │ ├── doc.go │ │ ├── http.go │ │ ├── index.go │ │ ├── index.js │ │ ├── lobby.go │ │ ├── lobby.js │ │ ├── lobby_test.go │ │ ├── resources/ │ │ │ ├── draw.js │ │ │ ├── error.css │ │ │ ├── index.css │ │ │ ├── lobby.css │ │ │ └── root.css │ │ ├── templates/ │ │ │ ├── error.html │ │ │ ├── favicon.html │ │ │ ├── footer.html │ │ │ ├── index.html │ │ │ ├── lobby.html │ │ │ └── non-static-css.html │ │ └── templating_test.go │ ├── game/ │ │ ├── data.go │ │ ├── data_test.go │ │ ├── lobby.go │ │ ├── lobby_test.go │ │ ├── shared.go │ │ ├── words/ │ │ │ ├── ar │ │ │ ├── de │ │ │ ├── en_gb │ │ │ ├── en_us │ │ │ ├── fa │ │ │ ├── fr │ │ │ ├── he │ │ │ ├── it │ │ │ ├── nl │ │ │ ├── pl │ │ │ ├── ru │ │ │ └── ua │ │ ├── words.go │ │ └── words_test.go │ ├── metrics/ │ │ └── metrics.go │ ├── sanitize/ │ │ └── sanitize.go │ ├── state/ │ │ ├── doc.go │ │ ├── lobbies.go │ │ └── lobbies_test.go │ ├── translations/ │ │ ├── ar.go │ │ ├── de_DE.go │ │ ├── doc.go │ │ ├── en_us.go │ │ ├── es_ES.go │ │ ├── fa.go │ │ ├── fr_FR.go │ │ ├── he.go │ │ ├── pl.go │ │ ├── translations.go │ │ └── translations_test.go │ └── version/ │ └── version.go ├── linux.Dockerfile ├── tools/ │ ├── compare_en_words.sh │ ├── sanitizer/ │ │ ├── README.md │ │ └── main.go │ ├── simulate/ │ │ └── main.go │ ├── skribbliohintsconverter/ │ │ ├── README.md │ │ ├── english.json │ │ ├── german.json │ │ └── main.go │ ├── statcollector/ │ │ └── main.go │ └── translate.sh └── windows.Dockerfile ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ # We are going with a whitelisting approach, to avoid accidentally bleeding # too much into our container. This reduces the amount of cache miss and # potentially speeds up the build. * # All non-test Go Code !internal/ !pkg/ !cmd/ **_test.go # Go Modules !go.mod !go.sum # While the dockerfile aren't needed inside of the Dockerfile, fly.io requires # them for remote bulding and uses this dockerignore to filter what's sent to # the remote builder. !linux.Dockerfile !windows.Dockerfile !public ================================================ FILE: .gitattributes ================================================ * text eol=lf *.otf binary *.png binary *.wav binary ================================================ FILE: .github/workflows/docker-image-update.yml ================================================ name: docker image update on: workflow_run: workflows: [Build] branches: [v**] types: [completed] jobs: main: runs-on: ${{ matrix.os }} strategy: max-parallel: 3 matrix: os: [ubuntu-latest, windows-2022] include: - os: ubuntu-latest platforms: linux/amd64,linux/arm/v7,linux/arm64 file: linux.Dockerfile buildArgs: VERSION=${{ github.event.workflow_run.head_branch }} tags: latest, ${{ github.event.workflow_run.head_branch }} multiPlatform: true - os: windows-2022 platforms: windows/amd64 file: windows.Dockerfile buildArgs: VERSION=${{ github.event.workflow_run.head_branch }} tags: windows-latest, windows-${{ github.event.workflow_run.head_branch }} multiPlatform: false steps: - name: Checkout uses: actions/checkout@v4 - name: Build and push id: docker_build uses: mr-smithers-excellent/docker-build-push@v6 with: multiPlatform: ${{ matrix.multiPlatform }} registry: docker.io dockerfile: ${{ matrix.file }} image: biosmarcel/scribble.rs buildArgs: ${{ matrix.buildArgs }} platform: ${{ matrix.platforms }} tags: ${{ matrix.tags }} username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} ================================================ FILE: .github/workflows/release.yml ================================================ name: Publish release on: workflow_run: workflows: [Build] branches: [v**] types: [completed] jobs: publish-release: runs-on: ubuntu-latest # Kinda bad since it might release on any branch starting with v, but it'll do for now. # Tag filtering in "on:" doesn't work, since the inital build trigger gets lost. # github.ref is therefore also being reset to "refs/head/master". if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: Download linux artifact uses: dawidd6/action-download-artifact@v6 with: workflow: test-and-build.yml name: scribblers-linux-x64 - name: Download macos artifact uses: dawidd6/action-download-artifact@v6 with: workflow: test-and-build.yml name: scribblers-macos-x64 - name: Download windows artifact uses: dawidd6/action-download-artifact@v6 with: workflow: test-and-build.yml name: scribblers-x64.exe - name: Create release uses: softprops/action-gh-release@v1 with: name: ${{ github.event.workflow_run.head_branch }} tag_name: ${{ github.event.workflow_run.head_branch }} files: | scribblers-linux-x64 scribblers-macos-x64 scribblers-x64.exe ================================================ FILE: .github/workflows/test-and-build.yml ================================================ name: Build on: push jobs: test-and-build: strategy: matrix: include: - platform: windows-latest binary_name: scribblers-x64.exe - platform: ubuntu-latest binary_name: scribblers-linux-x64 - platform: macos-latest binary_name: scribblers-macos-x64 runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 with: # Workaround to get tags, getting git describe to work. fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version: 1.25.5 - name: Run tests shell: bash run: | go test -v -race ./... - name: Build artifact shell: bash env: # Disable CGO to get "more static" binaries. They aren't really static ... # since it can still happen that part of the stdlib access certain libs, but # whatever, this will probs do for our usecase. (Can't quite remember # anymore, but I have had issues with this in the past) :D CGO_ENABLED: 0 run: | go build -trimpath -ldflags "-w -s -X 'github.com/scribble-rs/scribble.rs/internal/version.Version=$(git describe --tags --dirty)'" -o ${{ matrix.binary_name }} ./cmd/scribblers - name: Upload build artifact uses: actions/upload-artifact@v4 with: name: ${{ matrix.binary_name }} path: ./${{ matrix.binary_name }} ================================================ FILE: .github/workflows/test-pr.yml ================================================ name: Run tests on: pull_request jobs: run-tests: strategy: matrix: go-version: [1.25.5] platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - name: Install Go uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} - name: Run tests run: | go test -v -race -count=3 ./... ================================================ FILE: .gitignore ================================================ # Executable names /scribblers *.exe __debug_bin # IntelliJ state .idea/ # Folder that contains code used for trying stuff locally playground/ # Temporary output text files *.out # System metadata files .DS_Store # Configuration files .env # Anything temporary *.tmp # Profiling results *.pprof # Additional files for hosting. Workaround for now ig. public/ ================================================ FILE: .golangci.yml ================================================ linters: enable-all: true disable: ## These are deprecated - exportloopref ## These are too strict for our taste # Whitespace linter - wsl # Demands a newline before each return - nlreturn # Magic numbers - mnd # function, line and variable length - funlen - lll - varnamelen # testpackages must be named _test for reduced visibility to package # details. - testpackage # I don't really care about cyclopmatic complexity - cyclop - gocognit # I don't see the harm in returning an interface - ireturn # Too many false positives, due to easyjson rn - recvcheck # While aligned tags look nice, i can't be arsed doing it manually. - tagalign ## Useful, but we won't use it for now, maybe later # Allows us to define rules for dependencies - depguard # For some reason, imports aren't sorted right now. - gci # For now, we'll stick with our globals and inits. Everything needs to be # rewrite to be more testable and safe to teardown and reset. - gochecknoglobals - gochecknoinits # Seems to be very useful, but is also a very common usecase, so we'll # ignore it for now - exhaustruct # Requires certain types of tags, such as json or mapstructure. # While very useful, I don't care right now. - musttag # Not wrapping errors - err113 - wrapcheck # Code duplications - dupl ## Provides no real value - testifylint # Broken - goimports linters-settings: govet: disable: - fieldalignment gocritic: disabled-checks: # This has false positives and provides little value. - ifElseChain gosec: excludes: # weak number generator stuff; mostly false positives, as we don't do # security sensitive things anyway. - G404 revive: rules: - name: var-naming disabled: true stylecheck: checks: ["all", "-ST1003"] run: exclude-files: - ".*_easyjson.go" issues: exclude-rules: - path: translations\\[^e][^n].*?\.go linters: # Too many potential false positives - misspell # Exclude some linters from running on tests files. In tests, we often have # code that is rather unsafe and only has one purpose, or furthermore things # that indicate an issue in production, but are fine for testing only small # units. - path: _test\.go linters: - funlen - cyclop - forcetypeassert - varnamelen # The tools aren't part of the actual production code and therefore we don't # care about codequality much right now. - path: tools/ text: .+ ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Start server", "type": "go", "request": "launch", "mode": "debug", "program": "${workspaceFolder}/cmd/scribblers/main.go", "cwd": "${workspaceFolder}" } ] } ================================================ FILE: .vscode/settings.json ================================================ { "html.format.templating": true, "go.lintTool": "golangci-lint", "go.useLanguageServer": true, "gopls": { "formatting.gofumpt": true, }, } ================================================ FILE: LICENSE ================================================ BSD 3-Clause License Copyright (c) 2019, scribble-rs All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================

Scribble.rs

![demo](.github/demo.png) Scribble.rs is a free and privacy respecting pictionary game. There's no advertisements and you don't need an account to play. It is an alternative to the web-based drawing game skribbl.io. ## Play now There are some community hosted versions of the game (feel free to host your own instance and add it here!): - [scribblers.bios-marcel.link](https://scribblers.bios-marcel.link) (Official instance, Note that the instance may not respond instantly, as it automatically shuts down if no traffic is received.) - [scribble.bixilon.de](https://scribble.bixilon.de) (community instance maintained by @Bixilon) - [scribble.drifty.win](https://scribble.drifty.win) (community instance maintained by @driftywinds for better latency in Asia) ## Join The Discord Feel free to join the community Discord server to find people to play, talk, get help or whatever else: https://discord.gg/cE5BKP2UnE Note, the server is NOT very active. ## Donations I haven't really accepted donations for a long time. But I think the project is polished enough now to dare taking some money. Right now the hosting is very minimal and there's no domain. The server is located in amsterdam and many people playing seem to be from outside of europe. So it'd be nice to have a decentralised deployment to provide a nice experience for everyone. So donations would go towards infrastructure and a domain! In the future I might add some fun little benefits for donators, I have no clear vision of it yet though. You can donate via Ko-Fi: https://ko-fi.com/biosmarcel ## Configuration Configuration is read from environment variables or a `.env` file located in the working directory. Available settings: | Key | Description | Default | Required | | ----------------------------------------- | ---------------------------------------------------------------- | ------- | -------- | | PORT | HTTP port that the server listens to. | 8080 | True | | NETWORK_ADDRESS | TCP address that the server listens to. | | False | | ROOT_PATH | Changes the path (after your domain) that the server listens to. | | False | | CORS_ALLOWED_ORIGINS | | * | False | | CORS_ALLOW_CREDENTIALS | | | False | | LOBBY_CLEANUP_INTERVAL | | 90s | False | | LOBBY_CLEANUP_PLAYER_INACTIVITY_THRESHOLD | | 75s | False | For more up-to-date configuration, read the [config.go](/internal/config/config.go) file. ## Docker It is recommended that you run the server via Docker, as this will rule out almost all compatibility issues. Starting from v0.8.5, docker images are only built on tagged pushes. Each git tag becomes a docker tag, however `latest` will always point to the latest version released via GitHub. ### Linux Docker Download the image: ```shell docker pull biosmarcel/scribble.rs:latest ``` ### Windows Docker Only use this one if you want to run a native Windows container. Otherwise use the Linux variant, as that's the default mode on Windows: ```shell docker pull biosmarcel/scribble.rs:windows-latest ``` ### Running the Docker container Run the following, replacing `` with the port you want the container to be reachable from outside: ```shell docker run --pull always --env PORT=8080 -p :8080 biosmarcel/scribble.rs:latest ``` For example: ```shell docker run --pull always --env PORT=8080 -p 80:8080 biosmarcel/scribble.rs:latest ``` Note that you can change `8080` too, but it is the internal port of the container and you shouldn't have to change it under normal circumstances. ## Building / Running Dependencies: * [go](https://go.dev/doc/install) version 1.25.0 or later * [git](https://git-scm.com/) (You can also download a .zip from Github) In order to download and build, open a terminal and execute: ```shell git clone https://github.com/scribble-rs/scribble.rs.git cd scribble.rs go build ./cmd/scribblers ``` This will produce a portable binary called `scribblers` or `scribblers.exe` if you are on Windows. ## Pre-compiled binaries In the [Releases](https://github.com/scribble-rs/scribble.rs/releases) section you can find the latest stable release. Alternatively each commit uploads artifacts which will be available for a certain time. **Note that these binaries might not necessarily be compatible with your system. In this case, please use Docker or compile them yourself.** ## nginx Since Scribble.rs uses WebSockets, when running it behind an nginx reverse proxy, you have to configure nginx to support that. You will find an example configuration on the [related Wiki page](https://github.com/scribble-rs/scribble.rs/wiki/reverse-proxy-(nginx)). Other reverse proxies may require similar configuration. If you are using a well known reverse proxy, you are free to contribute a configuration to the wiki. ## Server-Side Metrics While there's a Prometheus metrics endpoint at `/v1/metrics`, it currently doesn't expose a lot of information. If there are any requests for certain data, I'd be willing to extend it, as long as it doesn't expose any personal data. While I do have a dashboard for it, my hoster (fly.io) sadly doesn't support public dashboards right now, so the data will remain closed for now. ## Contributing There are many ways you can contribute: * Update / Add documentation in the wiki of the GitHub repository * Create feature requests and bug reports * Solve issues by creating Pull Requests * If you are changing / adding behaviour, make an issue beforehand * Tell your friends about the project For contributions guidelines, see: https://github.com/scribble-rs/scribble.rs/wiki/Contributing ### Translations For translations, please always use the `en_us.go` as your base. Other translations might not be up-to-date. This will cause you to have missing keys or translate obsolete keys. ## Credits These resources are by people unrelated to the project, whilst not every of these resources requires attribution as per license, we'll do it either way ;) If you happen to find a mistake here, please make a PR. If you are one of the authors and feel like we've wronged you, please reach out. Some of these were slightly altered if the license allowed it. Treat each of the files in this repository with the same license terms as the original file. * Logo - All rights reserved, excluded from BSD-3 licensing * Background - All rights reserved, excluded from BSD-3 licensing * Favicon - All rights reserved, excluded from BSD-3 licensing * Rubber Icon - Made by [Pixel Buddha](https://www.flaticon.com/authors/pixel-buddha) from [flaticon.com](https://flaticon.com) * Fill Bucket Icon - Made by [inipagistudio](https://www.flaticon.com/authors/inipagistudio) from [flaticon.com](https://flaticon.com) * Kicking Icon - [Kicking Icon #309402](https://icon-library.net/icon/kicking-icon-4.html) * Sound / No sound Icon - Made by Viktor Erikson (If this is you or you know who this is, send me a link to that persons Homepage) * Profile Icon - Made by [kumakamu](https://www.iconfinder.com/kumakamu) * [Help Icon](https://www.iconfinder.com/icons/211675/help_icon) - Made by Ionicons * [Fullscreen Icon](https://www.iconfinder.com/icons/298714/screen_full_icon) - Made by Github * [Pencil Icon](https://github.com/twitter/twemoji/blob/8e58ae4/svg/270f.svg) * [Drawing Tablet Pen Icon](https://www.iconfinder.com/icons/8665767/pen_icon) * [Checkmark Icon](https://commons.wikimedia.org/wiki/File:Green_check_icon_with_gradient.svg) * [Fill Icon](https://commons.wikimedia.org/wiki/File:Circle-icons-paintcan.svg) * [Trash Icon](https://www.iconfinder.com/icons/315225/trash_can_icon) - Made by [Yannick Lung](https://yannicklung.com) * [Undo Icon](https://www.iconfinder.com/icons/308948/arrow_undo_icon) - Made by [Ivan Boyko](https://www.iconfinder.com/visualpharm) * [Alarmclock Icon](https://www.iconfinder.com/icons/4280508/alarm_outlined_alert_clock_icon) - Made by [Kit of Parts](https://www.iconfinder.com/kitofparts) * https://www.iconfinder.com/icons/808399/load_turn_turnaround_icon TODO ================================================ FILE: cmd/scribblers/main.go ================================================ package main import ( "fmt" "log" "net/http" "os" "os/signal" "path" "runtime/pprof" "strings" "syscall" "time" "github.com/go-chi/cors" "github.com/scribble-rs/scribble.rs/internal/api" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/frontend" "github.com/scribble-rs/scribble.rs/internal/state" "github.com/scribble-rs/scribble.rs/internal/version" ) func main() { cfg, err := config.Load() if err != nil { log.Fatalln("error loading configuration:", err) } log.Printf("Starting Scribble.rs version '%s'\n", version.Version) if cfg.CPUProfilePath != "" { log.Println("Starting CPU profiling ....") cpuProfileFile, err := os.Create(cfg.CPUProfilePath) if err != nil { log.Fatal("error creating cpuprofile file:", err) } if err := pprof.StartCPUProfile(cpuProfileFile); err != nil { log.Fatal("error starting cpu profiling:", err) } } router := http.NewServeMux() corsWrapper := cors.Handler(cors.Options{ AllowedOrigins: cfg.CORS.AllowedOrigins, AllowCredentials: cfg.CORS.AllowCredentials, }) register := func(method, path string, handler http.HandlerFunc) { // Each path needs to start with a slash anyway, so this is convenient. if !strings.HasPrefix(path, "/") { path = "/" + path } log.Printf("Registering route: %s %s\n", method, path) router.HandleFunc(fmt.Sprintf("%s %s", method, path), corsWrapper(handler).ServeHTTP) } // Healthcheck for deployments with monitoring if required. register("GET", path.Join(cfg.RootPath, "health"), func(writer http.ResponseWriter, _ *http.Request) { writer.WriteHeader(http.StatusOK) }) api.NewHandler(cfg).SetupRoutes(cfg.RootPath, register) frontendHandler, err := frontend.NewHandler(cfg) if err != nil { log.Fatal("error setting up frontend:", err) } frontendHandler.SetupRoutes(register) if cfg.LobbyCleanup.Interval > 0 { state.LaunchCleanupRoutine(cfg.LobbyCleanup) } signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT) go func() { defer os.Exit(0) log.Printf("Received %s, gracefully shutting down.\n", <-signalChan) state.ShutdownLobbiesGracefully() if cfg.CPUProfilePath != "" { pprof.StopCPUProfile() log.Println("Finished CPU profiling.") } }() address := fmt.Sprintf("%s:%d", cfg.NetworkAddress, cfg.Port) log.Println("Started, listening on: http://" + address) httpServer := &http.Server{ Addr: address, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" && r.URL.Path[len(r.URL.Path)-1] == '/' { r.URL.Path = r.URL.Path[:len(r.URL.Path)-1] } router.ServeHTTP(w, r) }), ReadHeaderTimeout: 10 * time.Second, } log.Fatalln(httpServer.ListenAndServe()) } ================================================ FILE: fly.Dockerfile ================================================ # # Builder for Golang # # We explicitly use a certain major version of go, to make sure we don't build # with a newer verison than we are using for CI tests, as we don't directly # test the produced binary but from source code directly. FROM docker.io/golang:1.25.5 AS builder WORKDIR /app # This causes caching of the downloaded go modules and makes repeated local # builds much faster. We must not copy the code first though, as a change in # the code causes a redownload. COPY go.mod go.sum ./ RUN go mod download -x # Import that this comes after mod download, as it breaks caching. ARG VERSION="dev" # Copy actual codebase, since we only have the go.mod and go.sum so far. COPY . /app/ ENV CGO_ENABLED=0 RUN go build -trimpath -ldflags "-w -s -X 'github.com/scribble-rs/scribble.rs/internal/version.Version=${VERSION}'" -tags timetzdata -o ./scribblers ./cmd/scribblers # # Runner # FROM scratch # Additionally hosted files COPY public /public COPY --from=builder /app/scribblers /scribblers # The scratch image doesn't contain any certificates, therefore we use # the builders certificate, so that we can send HTTP requests. COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ ENTRYPOINT ["/scribblers"] # Random uid to avoid having root privileges. Linux doesn't care that there's no user for it. USER 248:248 ================================================ FILE: fly.toml ================================================ # See https://fly.io/docs/reference/configuration/ app = "scribblers" # "fra" is only for paying customers primary_region = "ams" [metrics] port = 8080 path = "/v1/metrics" [build] dockerfile = "fly.Dockerfile" [deploy] strategy = "immediate" [env] ROOT_URL = "https://scribblers.bios-marcel.link" ALLOW_INDEXING = true SERVE_DIRECTORIES = ":/public" LOBBY_SETTING_BOUNDS_MAX_MAX_PLAYERS = 100 [http_service] internal_port = 8080 force_https = true auto_stop_machines = true auto_start_machines = true # Allows true scale to zero min_machines_running = 0 processes = ["app"] [[http_service.checks]] grace_period = "10s" interval = "30s" timeout = "5s" method = "GET" path = "/health" ================================================ FILE: fly_deploy.sh ================================================ #!/bin/sh flyctl deploy --build-arg "VERSION=$(git describe --tag)" ================================================ FILE: go.mod ================================================ module github.com/scribble-rs/scribble.rs go 1.25.0 require ( github.com/Bios-Marcel/discordemojimap/v2 v2.0.6 github.com/Bios-Marcel/go-petname v0.0.1 github.com/caarlos0/env/v11 v11.4.0 github.com/go-chi/cors v1.2.2 github.com/gofrs/uuid/v5 v5.4.0 github.com/lxzan/gws v1.9.0 github.com/prometheus/client_golang v1.23.2 github.com/stretchr/testify v1.11.1 github.com/subosito/gotenv v1.6.0 golang.org/x/text v0.35.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.66.1 // indirect github.com/prometheus/procfs v0.16.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/sys v0.35.0 // indirect google.golang.org/protobuf v1.36.8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) ================================================ FILE: go.sum ================================================ github.com/Bios-Marcel/discordemojimap/v2 v2.0.6 h1:VjNAT59riXBTKeKEqVb83irOZJ52a9qVy9HxzlL7C04= github.com/Bios-Marcel/discordemojimap/v2 v2.0.6/go.mod h1:caQqGZkTnvXOLXjChOpjzXQUMy2C1Y61ImtdVzEOvss= github.com/Bios-Marcel/go-petname v0.0.1 h1:FELp77IS2bulz77kFXUOHqRJHXoOlL0lJUf6no5S0cQ= github.com/Bios-Marcel/go-petname v0.0.1/go.mod h1:67IdwdIEuQBRISkUQJd4b/DvOYscEo8dNpq0D2gPHoA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/caarlos0/env/v11 v11.4.0 h1:Kcb6t5kIIr4XkoQC9AF2j+8E1Jsrl3Wz/hhm1LtoGAc= github.com/caarlos0/env/v11 v11.4.0/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0= github.com/gofrs/uuid/v5 v5.4.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lxzan/gws v1.9.0 h1:my3sfqb0GjwP+gRONjNWVzcBrpud0IP3vj9soIt9pXo= github.com/lxzan/gws v1.9.0/go.mod h1:gXHSCPmTGryWJ4icuqy8Yho32E4YIMHH0fkDRYJRbdc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ================================================ FILE: internal/api/createparse.go ================================================ package api import ( "errors" "fmt" "strconv" "strings" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" "golang.org/x/text/cases" ) // ParsePlayerName checks if the given value is a valid playername. Currently // this only includes checkin whether the value is empty or only consists of // whitespace character. func ParsePlayerName(value string) (string, error) { trimmed := strings.TrimSpace(value) if trimmed == "" { return trimmed, errors.New("the player name must not be empty") } return trimmed, nil } // ParseLanguage checks whether the given value is part of the // game.SupportedLanguages array. The input is trimmed and lowercased. func ParseLanguage(value string) (*game.LanguageData, string, error) { toLower := strings.ToLower(strings.TrimSpace(value)) for languageKey, data := range game.WordlistData { if toLower == languageKey { return &data, languageKey, nil } } return nil, "", errors.New("the given language doesn't match any supported language") } func ParseScoreCalculation(value string) (game.ScoreCalculation, error) { toLower := strings.ToLower(strings.TrimSpace(value)) switch toLower { case "", "chill": return game.ChillScoring, nil case "competitive": return game.CompetitiveScoring, nil } return nil, errors.New("the given score calculation doesn't match any supported algorithm") } // ParseDrawingTime checks whether the given value is an integer between // the lower and upper bound of drawing time. All other invalid // input, including empty strings, will return an error. func ParseDrawingTime(cfg *config.Config, value string) (int, error) { return parseIntValue(value, cfg.LobbySettingBounds.MinDrawingTime, cfg.LobbySettingBounds.MaxDrawingTime, "drawing time") } // ParseRounds checks whether the given value is an integer between // the lower and upper bound of rounds played. All other invalid // input, including empty strings, will return an error. func ParseRounds(cfg *config.Config, value string) (int, error) { return parseIntValue(value, cfg.LobbySettingBounds.MinRounds, cfg.LobbySettingBounds.MaxRounds, "rounds") } // ParseMaxPlayers checks whether the given value is an integer between // the lower and upper bound of maximum players per lobby. All other invalid // input, including empty strings, will return an error. func ParseMaxPlayers(cfg *config.Config, value string) (int, error) { return parseIntValue(value, cfg.LobbySettingBounds.MinMaxPlayers, cfg.LobbySettingBounds.MaxMaxPlayers, "max players amount") } // ParseCustomWords checks whether the given value is a string containing comma // separated values (or a single word). Empty strings will return an empty // (nil) array and no error. An error is only returned if there are empty words. // For example these wouldn't parse: // // wordone,,wordtwo // , // wordone, func ParseCustomWords(lowercaser cases.Caser, value string) ([]string, error) { trimmedValue := strings.TrimSpace(value) if trimmedValue == "" { return nil, nil } result := strings.Split(trimmedValue, ",") for index, item := range result { trimmedItem := lowercaser.String(strings.TrimSpace(item)) if trimmedItem == "" { return nil, errors.New("custom words must not be empty") } result[index] = trimmedItem } return result, nil } // ParseClientsPerIPLimit checks whether the given value is an integer between // the lower and upper bound of maximum clients per IP. All other invalid // input, including empty strings, will return an error. func ParseClientsPerIPLimit(cfg *config.Config, value string) (int, error) { return parseIntValue(value, cfg.LobbySettingBounds.MinClientsPerIPLimit, cfg.LobbySettingBounds.MaxClientsPerIPLimit, "clients per IP limit") } // ParseCustomWordsPerTurn checks whether the given value is an integer between // 0 and 100. All other invalid input, including empty strings, will return an // error. func ParseCustomWordsPerTurn(cfg *config.Config, value string) (int, error) { return parseIntValue(value, 1, cfg.LobbySettingBounds.MaxWordsPerTurn, "custom words per turn") } func ParseWordsPerTurn(cfg *config.Config, value string) (int, error) { return parseIntValue(value, 1, cfg.LobbySettingBounds.MaxWordsPerTurn, "words per turn") } func newIntOutOfBounds(value, valueName string, lower, upper int) error { if upper != -1 { return fmt.Errorf("the value '%s' must be an integer between %d and %d, but was: '%s'", valueName, lower, upper, value) } return fmt.Errorf("the value '%s' must be an integer larger than %d, but was: '%s'", valueName, lower, value) } func parseIntValue(toParse string, lower, upper int, valueName string) (int, error) { var value int if parsed, err := strconv.ParseInt(toParse, 10, 64); err != nil { return 0, newIntOutOfBounds(toParse, valueName, lower, upper) } else { value = int(parsed) } if value < lower || (upper > -1 && value > upper) { return 0, newIntOutOfBounds(toParse, valueName, lower, upper) } return value, nil } // ParseBoolean checks whether the given value is either "true" or "false". // The checks are case-insensitive. If an empty string is supplied, false // is returned. All other invalid input will return an error. func ParseBoolean(valueName, value string) (bool, error) { if value == "" { return false, nil } if strings.EqualFold(value, "true") { return true, nil } if strings.EqualFold(value, "false") { return false, nil } return false, fmt.Errorf("the %s value must be a boolean value ('true' or 'false)", valueName) } ================================================ FILE: internal/api/createparse_test.go ================================================ package api import ( "reflect" "testing" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" "golang.org/x/text/cases" "golang.org/x/text/language" ) func Test_parsePlayerName(t *testing.T) { t.Parallel() tests := []struct { name string value string want string wantErr bool }{ {"empty name", "", "", true}, {"blank name", " ", "", true}, {"one letter name", "a", "a", false}, {"normal name", "Scribble", "Scribble", false}, {"name with space in the middle", "Hello World", "Hello World", false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParsePlayerName(testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parsePlayerName() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parsePlayerName() = %v, want %v", got, testCase.want) } }) } } func Test_parseDrawingTime(t *testing.T) { t.Parallel() tests := []struct { name string value string want int wantErr bool }{ {"empty value", "", 0, true}, {"space", " ", 0, true}, {"less than minimum", "59", 0, true}, {"more than maximum", "301", 0, true}, {"maximum", "300", 300, false}, {"minimum", "60", 60, false}, {"something valid", "150", 150, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseDrawingTime(&config.Default, testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseDrawingTime() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parseDrawingTime() = %v, want %v", got, testCase.want) } }) } } func Test_parseRounds(t *testing.T) { t.Parallel() tests := []struct { name string value string want int wantErr bool }{ {"empty value", "", 0, true}, {"space", " ", 0, true}, {"less than minimum", "0", 0, true}, {"more than maximum", "21", 0, true}, {"maximum", "20", 20, false}, {"minimum", "1", 1, false}, {"something valid", "15", 15, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseRounds(&config.Default, testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseRounds() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parseRounds() = %v, want %v", got, testCase.want) } }) } } func Test_parseMaxPlayers(t *testing.T) { t.Parallel() tests := []struct { name string value string want int wantErr bool }{ {"empty value", "", 0, true}, {"space", " ", 0, true}, {"less than minimum", "1", 0, true}, {"more than maximum", "25", 0, true}, {"maximum", "24", 24, false}, {"minimum", "2", 2, false}, {"something valid", "15", 15, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseMaxPlayers(&config.Default, testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseMaxPlayers() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parseMaxPlayers() = %v, want %v", got, testCase.want) } }) } } func Test_parseCustomWords(t *testing.T) { t.Parallel() tests := []struct { name string value string want []string wantErr bool }{ {"emtpty", "", nil, false}, {"spaces", " ", nil, false}, {"spaces with comma in middle", " , ", nil, true}, {"single word", "hello", []string{"hello"}, false}, {"single word upper to lower", "HELLO", []string{"hello"}, false}, {"single word with spaces around", " hello ", []string{"hello"}, false}, {"two words", "hello,world", []string{"hello", "world"}, false}, {"two words with spaces around", " hello , world ", []string{"hello", "world"}, false}, {"sentence and word", "What a great day, hello ", []string{"what a great day", "hello"}, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseCustomWords(cases.Lower(language.English), testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseCustomWords() error = %v, wantErr %v", err, testCase.wantErr) return } if !reflect.DeepEqual(got, testCase.want) { t.Errorf("parseCustomWords() = %v, want %v", got, testCase.want) } }) } } func Test_parseCustomWordsPerTurn(t *testing.T) { t.Parallel() cfg := &config.Config{ LobbySettingBounds: game.SettingBounds{ MinCustomWordsPerTurn: 1, MinWordsPerTurn: 1, MaxWordsPerTurn: 3, }, } tests := []struct { name string value string want int wantErr bool }{ {"empty value", "", 0, true}, {"space", " ", 0, true}, {"less than minimum, zero", "0", 0, true}, {"less than minimum, negative", "-1", 0, true}, {"more than maximum", "4", 0, true}, {"minimum", "1", 1, false}, {"maximum", "3", 3, false}, {"something valid", "2", 2, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseCustomWordsPerTurn(cfg, testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseCustomWordsPerTurn() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parseCustomWordsPerTurn() = %v, want %v", got, testCase.want) } }) } } func Test_parseWordsPerTurn(t *testing.T) { t.Parallel() cfg := &config.Config{ LobbySettingBounds: game.SettingBounds{ MinCustomWordsPerTurn: 1, MinWordsPerTurn: 1, MaxWordsPerTurn: 10, }, } tests := []struct { name string value string want int wantErr bool }{ {"empty value", "", 0, true}, {"space", " ", 0, true}, {"less than minimum, zero", "0", 0, true}, {"less than minimum, negative", "-1", 0, true}, {"minimum", "1", 1, false}, {"something valid", "10", 10, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseWordsPerTurn(cfg, testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("ParseWordsPerTurn() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("ParseWordsPerTurn() = %v, want %v", got, testCase.want) } }) } } func Test_parseBoolean(t *testing.T) { t.Parallel() tests := []struct { name string value string want bool wantErr bool }{ {"empty value", "", false, false}, {"space", " ", false, true}, {"garbage", "garbage", false, true}, {"true", "true", true, false}, {"true upper", "TRUE", true, false}, {"true mixed casing", "TruE", true, false}, {"false", "false", false, false}, {"false upper", "FALSE", false, false}, {"false mixed casing", "FalsE", false, false}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { t.Parallel() got, err := ParseBoolean("name", testCase.value) if (err != nil) != testCase.wantErr { t.Errorf("parseBoolean() error = %v, wantErr %v", err, testCase.wantErr) return } if got != testCase.want { t.Errorf("parseBoolean() = %v, want %v", got, testCase.want) } }) } } ================================================ FILE: internal/api/doc.go ================================================ // Package api the public APIs for both the HTTP and the WS endpoints. // These are being used by the official client and can also be used by third // party clients. On top of that this package contains some util code regarding // http/ws that can be used by other packages. In order to register the // endpoints you have to call SetupRoutes. package api ================================================ FILE: internal/api/http.go ================================================ package api import ( "net/http" "path" "strings" "github.com/scribble-rs/scribble.rs/internal/metrics" ) // SetupRoutes registers the /v1/ endpoints with the http package. func (handler *V1Handler) SetupRoutes(rootPath string, register func(string, string, http.HandlerFunc)) { v1 := path.Join(rootPath, "v1") metrics.SetupRoute(func(metricsHandler http.HandlerFunc) { register("GET", path.Join(v1, "metrics"), metricsHandler) }) register("GET", path.Join(v1, "stats"), handler.getStats) // These exist only for the public API. We version them in order to ensure // backwards compatibility as far as possible. register("GET", path.Join(v1, "lobby"), handler.getLobbies) register("POST", path.Join(v1, "lobby"), handler.postLobby) register("PATCH", path.Join(v1, "lobby", "{lobby_id}"), handler.patchLobby) // We support both path parameter and cookie. register("PATCH", path.Join(v1, "lobby"), handler.patchLobby) // The websocket is shared between the public API and the official client register("GET", path.Join(v1, "lobby", "{lobby_id}", "ws"), handler.websocketUpgrade) // We support both path parameter and cookie. register("GET", path.Join(v1, "lobby", "ws"), handler.websocketUpgrade) register("POST", path.Join(v1, "lobby", "{lobby_id}", "player"), handler.postPlayer) } // remoteAddressToSimpleIP removes unnecessary clutter from the input, // reducing it to a simple IPv4. We expect two different formats here. // One being http.Request#RemoteAddr (127.0.0.1:12345) and the other // being forward headers, which contain brackets, as there's no proper // API, but just a string that needs to be parsed. func remoteAddressToSimpleIP(input string) string { address := input lastIndexOfDoubleColon := strings.LastIndex(address, ":") if lastIndexOfDoubleColon != -1 { address = address[:lastIndexOfDoubleColon] } return strings.TrimSuffix(strings.TrimPrefix(address, "["), "]") } // GetIPAddressFromRequest extracts the clients IP address from the request. // This function respects forwarding headers. func GetIPAddressFromRequest(request *http.Request) string { // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded // The following logic has been implemented according to the spec, therefore please // refer to the spec if you have a question. forwardedAddress := request.Header.Get("X-Forwarded-For") if forwardedAddress != "" { // Since the field may contain multiple addresses separated by commas, we use the first // one, which according to the docs is supposed to be the client address. clientAddress := strings.TrimSpace(strings.Split(forwardedAddress, ",")[0]) return remoteAddressToSimpleIP(clientAddress) } standardForwardedHeader := request.Header.Get("Forwarded") if standardForwardedHeader != "" { targetPrefix := "for=" // Since forwarded can contain more than one field, we search for one specific field. for part := range strings.SplitSeq(standardForwardedHeader, ";") { trimmed := strings.TrimSpace(part) if after, ok := strings.CutPrefix(trimmed, targetPrefix); ok { // FIXME Maybe checking for a valid IP-Address would make sense here, not sure tho. address := remoteAddressToSimpleIP(after) // Since the documentation doesn't mention which quotes are used, I just remove all ;) return strings.NewReplacer("`", "", "'", "", "\"", "", "[", "", "]", "").Replace(address) } } } return remoteAddressToSimpleIP(request.RemoteAddr) } ================================================ FILE: internal/api/v1.go ================================================ // This file contains the API methods for the public API package api import ( json "encoding/json" "errors" "fmt" "log" "net/http" "strconv" "strings" "github.com/gofrs/uuid/v5" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/scribble-rs/scribble.rs/internal/state" "golang.org/x/text/cases" "golang.org/x/text/language" ) var ErrLobbyNotExistent = errors.New("the requested lobby doesn't exist") type V1Handler struct { cfg *config.Config } func NewHandler(cfg *config.Config) *V1Handler { return &V1Handler{ cfg: cfg, } } func marshalToHTTPWriter(data any, writer http.ResponseWriter) (bool, error) { bytes, err := json.Marshal(data) if err != nil { return false, err } writer.Header().Set("Content-Type", "application/json") writer.Header().Set("Content-Length", strconv.Itoa(len(bytes))) _, err = writer.Write(bytes) return true, err } type LobbyEntries []*LobbyEntry // LobbyEntry is an API object for representing a join-able public lobby. type LobbyEntry struct { LobbyID string `json:"lobbyId"` Wordpack string `json:"wordpack"` Scoring string `json:"scoring"` State game.State `json:"state"` PlayerCount int `json:"playerCount"` MaxPlayers int `json:"maxPlayers"` Round int `json:"round"` Rounds int `json:"rounds"` DrawingTime int `json:"drawingTime"` MaxClientsPerIP int `json:"maxClientsPerIp"` CustomWords bool `json:"customWords"` } func (handler *V1Handler) getLobbies(writer http.ResponseWriter, _ *http.Request) { // REMARK: If paging is ever implemented, we might want to maintain order // when deleting lobbies from state in the state package. lobbies := state.GetPublicLobbies() lobbyEntries := make(LobbyEntries, 0, len(lobbies)) for _, lobby := range lobbies { // While one would expect locking the lobby here, it's not very // important to get 100% consistent results here. lobbyEntries = append(lobbyEntries, &LobbyEntry{ LobbyID: lobby.LobbyID, PlayerCount: lobby.GetConnectedPlayerCount(), MaxPlayers: lobby.MaxPlayers, Round: lobby.Round, Rounds: lobby.Rounds, DrawingTime: lobby.DrawingTime, CustomWords: len(lobby.CustomWords) > 0, MaxClientsPerIP: lobby.ClientsPerIPLimit, Wordpack: lobby.Wordpack, State: lobby.State, Scoring: lobby.ScoreCalculation.Identifier(), }) } if started, err := marshalToHTTPWriter(lobbyEntries, writer); err != nil { if !started { http.Error(writer, err.Error(), http.StatusInternalServerError) } return } } func (handler *V1Handler) postLobby(writer http.ResponseWriter, request *http.Request) { if err := request.ParseForm(); err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } var requestErrors []string // The lobby ID is normally autogenerated and it isn't advisble to set it // yourself, but for certain integrations / automations this can be useful. // However, to avoid any kind of abuse, this needs to be a valid UUID at // least. lobbyId := request.Form.Get("lobby_id") if lobbyId != "" { var err error _, err = uuid.FromString(lobbyId) if err != nil { requestErrors = append(requestErrors, err.Error()) } } scoreCalculation, scoreCalculationInvalid := ParseScoreCalculation(request.Form.Get("score_calculation")) languageRawValue := strings.ToLower(strings.TrimSpace(request.Form.Get("language"))) languageData, languageKey, languageInvalid := ParseLanguage(languageRawValue) drawingTime, drawingTimeInvalid := ParseDrawingTime(handler.cfg, request.Form.Get("drawing_time")) rounds, roundsInvalid := ParseRounds(handler.cfg, request.Form.Get("rounds")) maxPlayers, maxPlayersInvalid := ParseMaxPlayers(handler.cfg, request.Form.Get("max_players")) customWordsPerTurn, customWordsPerTurnInvalid := ParseCustomWordsPerTurn(handler.cfg, request.Form.Get("custom_words_per_turn")) clientsPerIPLimit, clientsPerIPLimitInvalid := ParseClientsPerIPLimit(handler.cfg, request.Form.Get("clients_per_ip_limit")) publicLobby, publicLobbyInvalid := ParseBoolean("public", request.Form.Get("public")) wordsPerTurn, wordsPerTurnInvalid := ParseWordsPerTurn(handler.cfg, request.Form.Get("words_per_turn")) if wordsPerTurn < customWordsPerTurn { wordsPerTurnInvalid = errors.New("words per turn must be greater than or equal to custom words per turn") } var lowercaser cases.Caser if languageInvalid != nil { lowercaser = cases.Lower(language.English) } else { lowercaser = languageData.Lowercaser() } customWords, customWordsInvalid := ParseCustomWords(lowercaser, request.Form.Get("custom_words")) if scoreCalculationInvalid != nil { requestErrors = append(requestErrors, scoreCalculationInvalid.Error()) } if languageInvalid != nil { requestErrors = append(requestErrors, languageInvalid.Error()) } if drawingTimeInvalid != nil { requestErrors = append(requestErrors, drawingTimeInvalid.Error()) } if roundsInvalid != nil { requestErrors = append(requestErrors, roundsInvalid.Error()) } if maxPlayersInvalid != nil { requestErrors = append(requestErrors, maxPlayersInvalid.Error()) } if customWordsInvalid != nil { requestErrors = append(requestErrors, customWordsInvalid.Error()) } if customWordsPerTurnInvalid != nil { requestErrors = append(requestErrors, customWordsPerTurnInvalid.Error()) } else { if languageRawValue == "custom" && len(customWords) == 0 { requestErrors = append(requestErrors, "custom words must be provided when using custom language") } } if clientsPerIPLimitInvalid != nil { requestErrors = append(requestErrors, clientsPerIPLimitInvalid.Error()) } if publicLobbyInvalid != nil { requestErrors = append(requestErrors, publicLobbyInvalid.Error()) } if wordsPerTurnInvalid != nil { requestErrors = append(requestErrors, wordsPerTurnInvalid.Error()) } if len(requestErrors) != 0 { http.Error(writer, strings.Join(requestErrors, ";"), http.StatusBadRequest) return } playerName := GetPlayername(request) lobbySettings := &game.EditableLobbySettings{ Rounds: rounds, DrawingTime: drawingTime, MaxPlayers: maxPlayers, CustomWordsPerTurn: customWordsPerTurn, ClientsPerIPLimit: clientsPerIPLimit, Public: publicLobby, WordsPerTurn: wordsPerTurn, } player, lobby, err := game.CreateLobby(lobbyId, playerName, languageKey, lobbySettings, customWords, scoreCalculation) if err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } // Due to the fact the IDs can be chosen manually, there's a big clash // potential! However, since we only allow specifying this via the rest API // we treat this here. This can't be treated in the game package right now // anyway though, as there'd be an import cycle. if state.GetLobby(lobby.LobbyID) != nil { http.Error(writer, "lobby id already in use", http.StatusBadRequest) return } lobby.WriteObject = WriteObject lobby.WritePreparedMessage = WritePreparedMessage player.SetLastKnownAddress(GetIPAddressFromRequest(request)) SetGameplayCookies(writer, request, player, lobby) lobbyData := CreateLobbyData(handler.cfg, lobby) if started, err := marshalToHTTPWriter(lobbyData, writer); err != nil { if !started { http.Error(writer, err.Error(), http.StatusInternalServerError) } return } // We only add the lobby if everything else was successful. state.AddLobby(lobby) } func (handler *V1Handler) postPlayer(writer http.ResponseWriter, request *http.Request) { lobby := state.GetLobby(request.PathValue("lobby_id")) if lobby == nil { http.Error(writer, ErrLobbyNotExistent.Error(), http.StatusNotFound) return } var lobbyData *LobbyData lobby.Synchronized(func() { player := GetPlayer(lobby, request) if player == nil { if !lobby.HasFreePlayerSlot() { http.Error(writer, "lobby already full", http.StatusUnauthorized) return } requestAddress := GetIPAddressFromRequest(request) if !lobby.CanIPConnect(requestAddress) { http.Error(writer, "maximum amount of players per IP reached", http.StatusUnauthorized) return } newPlayer := lobby.JoinPlayer(GetPlayername(request)) newPlayer.SetLastKnownAddress(requestAddress) // Use the players generated usersession and pass it as a cookie. SetGameplayCookies(writer, request, newPlayer, lobby) } else { player.SetLastKnownAddress(GetIPAddressFromRequest(request)) } lobbyData = CreateLobbyData(handler.cfg, lobby) }) if lobbyData != nil { if started, err := marshalToHTTPWriter(lobbyData, writer); err != nil { if !started { http.Error(writer, err.Error(), http.StatusInternalServerError) } return } } } func GetDiscordInstanceId(request *http.Request) string { discordInstanceId := request.URL.Query().Get("instance_id") if discordInstanceId == "" { cookie, _ := request.Cookie("discord-instance-id") if cookie != nil { discordInstanceId = cookie.Value } } return discordInstanceId } const discordDomain = "1320396325925163070.discordsays.com" func SetDiscordCookies(w http.ResponseWriter, request *http.Request) { discordInstanceId := GetDiscordInstanceId(request) if discordInstanceId != "" { http.SetCookie(w, &http.Cookie{ Name: "discord-instance-id", Value: discordInstanceId, Domain: discordDomain, Path: "/", SameSite: http.SameSiteNoneMode, Partitioned: true, Secure: true, }) } } // SetGameplayCookies takes the players usersession and lobby id // and sets them as a cookie. func SetGameplayCookies( w http.ResponseWriter, request *http.Request, player *game.Player, lobby *game.Lobby, ) { discordInstanceId := GetDiscordInstanceId(request) if discordInstanceId != "" { http.SetCookie(w, &http.Cookie{ Name: "usersession", Value: player.GetUserSession().String(), Domain: discordDomain, Path: "/", SameSite: http.SameSiteNoneMode, Partitioned: true, Secure: true, }) http.SetCookie(w, &http.Cookie{ Name: "lobby-id", Value: lobby.LobbyID, Domain: discordDomain, Path: "/", SameSite: http.SameSiteNoneMode, Partitioned: true, Secure: true, }) } else { // For the discord case, we need both, as the discord specific cookies // aren't available during the readirect from ssrCreate to ssrEnter. http.SetCookie(w, &http.Cookie{ Name: "usersession", Value: player.GetUserSession().String(), Path: "/", SameSite: http.SameSiteStrictMode, }) http.SetCookie(w, &http.Cookie{ Name: "lobby-id", Value: lobby.LobbyID, Path: "/", SameSite: http.SameSiteStrictMode, }) } } func (handler *V1Handler) patchLobby(writer http.ResponseWriter, request *http.Request) { userSession, err := GetUserSession(request) if err != nil { log.Printf("error getting user session: %v", err) http.Error(writer, "no valid usersession supplied", http.StatusBadRequest) return } if userSession == uuid.Nil { http.Error(writer, "no usersession supplied", http.StatusBadRequest) return } lobby := state.GetLobby(GetLobbyId(request)) if lobby == nil { http.Error(writer, ErrLobbyNotExistent.Error(), http.StatusNotFound) return } if err := request.ParseForm(); err != nil { http.Error(writer, fmt.Sprintf("error parsing request query into form (%s)", err), http.StatusBadRequest) return } var requestErrors []string // Uneditable properties if request.Form.Get("custom_words") != "" { requestErrors = append(requestErrors, "can't modify custom_words in existing lobby") } if request.Form.Get("language") != "" { requestErrors = append(requestErrors, "can't modify language in existing lobby") } // Editable properties maxPlayers, maxPlayersInvalid := ParseMaxPlayers(handler.cfg, request.Form.Get("max_players")) drawingTime, drawingTimeInvalid := ParseDrawingTime(handler.cfg, request.Form.Get("drawing_time")) rounds, roundsInvalid := ParseRounds(handler.cfg, request.Form.Get("rounds")) customWordsPerTurn, customWordsPerTurnInvalid := ParseCustomWordsPerTurn(handler.cfg, request.Form.Get("custom_words_per_turn")) clientsPerIPLimit, clientsPerIPLimitInvalid := ParseClientsPerIPLimit(handler.cfg, request.Form.Get("clients_per_ip_limit")) publicLobby, publicLobbyInvalid := ParseBoolean("public", request.Form.Get("public")) wordsPerTurn, wordsPerTurnInvalid := ParseWordsPerTurn(handler.cfg, request.Form.Get("words_per_turn")) if wordsPerTurn < customWordsPerTurn { wordsPerTurnInvalid = errors.New("words per turn must be greater than or equal to custom words per turn") } owner := lobby.GetOwner() if owner == nil || owner.GetUserSession() != userSession { http.Error(writer, "only the lobby owner can edit the lobby", http.StatusForbidden) return } if maxPlayersInvalid != nil { requestErrors = append(requestErrors, maxPlayersInvalid.Error()) } if drawingTimeInvalid != nil { requestErrors = append(requestErrors, drawingTimeInvalid.Error()) } if roundsInvalid != nil { requestErrors = append(requestErrors, roundsInvalid.Error()) } else { currentRound := lobby.Round if rounds < currentRound { requestErrors = append(requestErrors, fmt.Sprintf("rounds must be greater than or equal to the current round (%d)", currentRound)) } } if customWordsPerTurnInvalid != nil { requestErrors = append(requestErrors, customWordsPerTurnInvalid.Error()) } if clientsPerIPLimitInvalid != nil { requestErrors = append(requestErrors, clientsPerIPLimitInvalid.Error()) } if publicLobbyInvalid != nil { requestErrors = append(requestErrors, publicLobbyInvalid.Error()) } if wordsPerTurnInvalid != nil { requestErrors = append(requestErrors, wordsPerTurnInvalid.Error()) } if len(requestErrors) != 0 { http.Error(writer, strings.Join(requestErrors, ";"), http.StatusBadRequest) return } // We synchronize as late as possible to avoid unnecessary lags. // The previous code here isn't really prone to bugs due to lack of sync. lobby.Synchronized(func() { // While changing maxClientsPerIP and maxPlayers to a value lower than // is currently being used makes little sense, we'll allow it, as it doesn't // really break anything. lobby.MaxPlayers = maxPlayers lobby.CustomWordsPerTurn = customWordsPerTurn lobby.ClientsPerIPLimit = clientsPerIPLimit lobby.Public = publicLobby lobby.Rounds = rounds lobby.WordsPerTurn = wordsPerTurn if lobby.State == game.Ongoing { lobby.DrawingTimeNew = drawingTime } else { lobby.DrawingTime = drawingTime } lobbySettingsCopy := lobby.EditableLobbySettings lobbySettingsCopy.DrawingTime = drawingTime lobby.Broadcast(&game.Event{Type: game.EventTypeLobbySettingsChanged, Data: lobbySettingsCopy}) }) } func (handler *V1Handler) getStats(writer http.ResponseWriter, _ *http.Request) { if started, err := marshalToHTTPWriter(state.Stats(), writer); err != nil { if !started { http.Error(writer, err.Error(), http.StatusInternalServerError) } return } } // SuggestedBrushSizes is suggested brush sizes value used for // Lobbydata objects. A unit test makes sure these values are ordered // and within the specified bounds. var SuggestedBrushSizes = [4]uint8{8, 16, 24, 32} // GameConstants are values that are lobby-independent and can't be changed via // settings, neither at compile time nor at startup time. type GameConstants struct { // DrawingBoardBaseWidth is the internal canvas width and is needed for // correctly up- / downscaling drawing instructions. Deprecated, but kept for compat. DrawingBoardBaseWidth uint16 `json:"drawingBoardBaseWidth"` // DrawingBoardBaseHeight is the internal canvas height and is needed for // correctly up- / downscaling drawing instructions. Deprecated, but kept for compat. DrawingBoardBaseHeight uint16 `json:"drawingBoardBaseHeight"` // MinBrushSize is the minimum amount of pixels the brush can draw in. MinBrushSize uint8 `json:"minBrushSize"` // MaxBrushSize is the maximum amount of pixels the brush can draw in. MaxBrushSize uint8 `json:"maxBrushSize"` // CanvasColor is the initially (empty) color of the canvas. CanvasColor uint8 `json:"canvasColor"` // SuggestedBrushSizes are suggestions for the different brush sizes // that the user can choose between. These brushes are guaranteed to // be ordered from low to high and stay with the bounds. SuggestedBrushSizes [4]uint8 `json:"suggestedBrushSizes"` } var GameConstantsData = &GameConstants{ DrawingBoardBaseWidth: game.DrawingBoardBaseWidth, DrawingBoardBaseHeight: game.DrawingBoardBaseHeight, MinBrushSize: game.MinBrushSize, MaxBrushSize: game.MaxBrushSize, CanvasColor: 0, /* White */ SuggestedBrushSizes: SuggestedBrushSizes, } // LobbyData is the data necessary for correctly configuring a lobby. // While unofficial clients will probably need all of these values, the // official webclient doesn't use all of them as of now. type LobbyData struct { game.SettingBounds game.EditableLobbySettings *GameConstants IsWordpackRtl bool } // CreateLobbyData creates a ready to use LobbyData object containing data // from the passed Lobby. func CreateLobbyData(cfg *config.Config, lobby *game.Lobby) *LobbyData { return &LobbyData{ SettingBounds: cfg.LobbySettingBounds, EditableLobbySettings: lobby.EditableLobbySettings, GameConstants: GameConstantsData, IsWordpackRtl: lobby.IsWordpackRtl, } } // GetUserSession accesses the usersession from an HTTP request and // returns the session. The session can either be in the cookie or in // the header. If no session can be found, an empty string is returned. func GetUserSession(request *http.Request) (uuid.UUID, error) { var userSession string if sessionCookie, err := request.Cookie("usersession"); err == nil && sessionCookie.Value != "" { userSession = sessionCookie.Value } else { userSession = request.Header.Get("Usersession") } if userSession == "" { return uuid.Nil, nil } id, err := uuid.FromString(userSession) if err != nil { return uuid.Nil, fmt.Errorf("error parsing user session: %w", err) } return id, nil } // GetPlayer returns the player object that matches the usersession in the // supplied HTTP request and lobby. If no user session is set, we return nil. func GetPlayer(lobby *game.Lobby, request *http.Request) *game.Player { userSession, err := GetUserSession(request) if err != nil { log.Printf("error getting user session: %v", err) return nil } if userSession == uuid.Nil { return nil } return lobby.GetPlayerBySession(userSession) } // GetPlayername either retrieves the playername from a cookie, the URL form. // If no preferred name can be found, we return an empty string. func GetPlayername(request *http.Request) string { if err := request.ParseForm(); err == nil { username := request.Form.Get("username") if username != "" { return username } } if usernameCookie, err := request.Cookie("username"); err == nil { if usernameCookie.Value != "" { return usernameCookie.Value } } return "" } // GetLobbyId returns either the lobby id from the URL or from a cookie. func GetLobbyId(request *http.Request) string { lobbyId := request.PathValue("lobby_id") if lobbyId == "" { cookie, _ := request.Cookie("lobby-id") lobbyId = cookie.Value } return lobbyId } ================================================ FILE: internal/api/ws.go ================================================ package api import ( json "encoding/json" "errors" "fmt" "log" "net/http" "runtime/debug" "time" "github.com/gofrs/uuid/v5" "github.com/lxzan/gws" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/scribble-rs/scribble.rs/internal/metrics" "github.com/scribble-rs/scribble.rs/internal/state" ) var ( ErrPlayerNotConnected = errors.New("player not connected") upgrader = gws.NewUpgrader(&socketHandler{}, &gws.ServerOption{ Recovery: gws.Recovery, ParallelEnabled: true, PermessageDeflate: gws.PermessageDeflate{Enabled: true}, }) ) func (handler *V1Handler) websocketUpgrade(writer http.ResponseWriter, request *http.Request) { userSession, err := GetUserSession(request) if err != nil { log.Printf("error getting user session: %v", err) http.Error(writer, "no valid usersession supplied", http.StatusBadRequest) return } if userSession == uuid.Nil { // This issue can happen if you illegally request a websocket // connection without ever having had a usersession or your // client having deleted the usersession cookie. http.Error(writer, "you don't have access to this lobby;usersession not set", http.StatusUnauthorized) return } lobbyId := GetLobbyId(request) if lobbyId == "" { http.Error(writer, "lobby id missing", http.StatusBadRequest) return } lobby := state.GetLobby(lobbyId) if lobby == nil { http.Error(writer, ErrLobbyNotExistent.Error(), http.StatusNotFound) return } lobby.Synchronized(func() { player := lobby.GetPlayerBySession(userSession) if player == nil { http.Error(writer, "you don't have access to this lobby;usersession unknown", http.StatusUnauthorized) return } socket, err := upgrader.Upgrade(writer, request) if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) return } metrics.TrackPlayerConnect() player.SetWebsocket(socket) socket.Session().Store("player", player) socket.Session().Store("lobby", lobby) lobby.OnPlayerConnectUnsynchronized(player) go socket.ReadLoop() }) } const ( pingInterval = 10 * time.Second pingWait = 5 * time.Second ) type socketHandler struct{} func (c *socketHandler) resetDeadline(socket *gws.Conn) { if err := socket.SetDeadline(time.Now().Add(pingInterval + pingWait)); err != nil { log.Printf("error resetting deadline: %s\n", err) } } func (c *socketHandler) OnOpen(socket *gws.Conn) { c.resetDeadline(socket) } func extract(x any, _ bool) any { return x } func (c *socketHandler) OnClose(socket *gws.Conn, _ error) { defer socket.Session().Delete("player") defer socket.Session().Delete("lobby") player, ok := extract(socket.Session().Load("player")).(*game.Player) if !ok { return } lobby, ok := extract(socket.Session().Load("lobby")).(*game.Lobby) if !ok { return } metrics.TrackPlayerDisconnect() lobby.OnPlayerDisconnect(player) player.SetWebsocket(nil) } func (c *socketHandler) OnPing(socket *gws.Conn, _ []byte) { c.resetDeadline(socket) _ = socket.WritePong(nil) } func (c *socketHandler) OnPong(socket *gws.Conn, _ []byte) { c.resetDeadline(socket) } func (c *socketHandler) OnMessage(socket *gws.Conn, message *gws.Message) { defer message.Close() defer c.resetDeadline(socket) player, ok := extract(socket.Session().Load("player")).(*game.Player) if !ok { return } lobby, ok := extract(socket.Session().Load("lobby")).(*game.Lobby) if !ok { return } bytes := message.Bytes() handleIncommingEvent(lobby, player, bytes) } func handleIncommingEvent(lobby *game.Lobby, player *game.Player, data []byte) { defer func() { if err := recover(); err != nil { log.Printf("Error occurred in incomming event listener.\n\tError: %s\n\tPlayer: %s(%s)\nStack %s\n", err, player.Name, player.ID, string(debug.Stack())) // FIXME Should this lead to a disconnect? } }() var event game.EventTypeOnly if err := json.Unmarshal(data, &event); err != nil { log.Printf("Error unmarshalling message: %s\n", err) err := WriteObject(player, game.Event{ Type: game.EventTypeSystemMessage, Data: fmt.Sprintf("error parsing message, please report this issue via Github: %s!", err), }) if err != nil { log.Printf("Error sending errormessage: %s\n", err) } return } if err := lobby.HandleEvent(event.Type, data, player); err != nil { log.Printf("Error handling event: %s\n", err) } } func WriteObject(player *game.Player, object any) error { socket := player.GetWebsocket() if socket == nil || !player.Connected { return ErrPlayerNotConnected } bytes, err := json.Marshal(object) if err != nil { return fmt.Errorf("error marshalling payload: %w", err) } // We write async, as broadcast always uses the queue. If we use write, the // order will become messed up, potentially causing issues in the frontend. socket.WriteAsync(gws.OpcodeText, bytes, func(err error) { if err != nil { log.Println("Error responding to player:", err.Error()) } }) return nil } func WritePreparedMessage(player *game.Player, message *gws.Broadcaster) error { socket := player.GetWebsocket() if socket == nil || !player.Connected { return ErrPlayerNotConnected } return message.Broadcast(socket) } ================================================ FILE: internal/config/config.go ================================================ package config import ( "fmt" "log" "maps" "os" "reflect" "strings" "time" "github.com/caarlos0/env/v11" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/subosito/gotenv" ) type LobbySettingDefaults struct { Public string `env:"PUBLIC"` DrawingTime string `env:"DRAWING_TIME"` Rounds string `env:"ROUNDS"` MaxPlayers string `env:"MAX_PLAYERS"` CustomWords string `env:"CUSTOM_WORDS"` CustomWordsPerTurn string `env:"CUSTOM_WORDS_PER_TURN"` ClientsPerIPLimit string `env:"CLIENTS_PER_IP_LIMIT"` Language string `env:"LANGUAGE"` ScoreCalculation string `env:"SCORE_CALCULATION"` WordsPerTurn string `env:"WORDS_PER_TURN"` } type CORS struct { AllowedOrigins []string `env:"ALLOWED_ORIGINS"` AllowCredentials bool `env:"ALLOW_CREDENTIALS"` } type LobbyCleanup struct { // Interval is the interval in which the cleanup routine will run. If set // to `0`, the cleanup routine will be disabled. Interval time.Duration `env:"INTERVAL"` // PlayerInactivityThreshold is the time after which a player counts as // inactivity and won't keep the lobby up. Note that cleaning up a lobby can // therefore take up to Interval + PlayerInactivityThreshold. PlayerInactivityThreshold time.Duration `env:"PLAYER_INACTIVITY_THRESHOLD"` } type Config struct { // NetworkAddress is empty by default, since that implies listening on // all interfaces. For development usecases, on windows for example, this // is very annoying, as windows will nag you with firewall prompts. NetworkAddress string `env:"NETWORK_ADDRESS"` // RootPath is the path directly after the domain and before the // scribblers paths. For example if you host scribblers on painting.com // but already host a different website on that domain, then your API paths // might have to look like this: painting.com/scribblers/v1 RootPath string `env:"ROOT_PATH"` // RootURL is similar to RootPath, but contains only the protocol and // domain. So it could be https://painting.com. This is required for some // non critical functionality, such as metadata tags. RootURL string `env:"ROOT_URL"` // CanonicalURL specifies the original domain, in case we are accessing the // site via some other domain, such as scribblers.fly.dev CanonicalURL string `env:"CANONICAL_URL"` // AllowIndexing will control whether the noindex, nofollow meta tag is // added to the home page. AllowIndexing bool `env:"ALLOW_INDEXING"` // ServeDirectories is a map of `path` to `directory`. All directories are // served under the given path. ServeDirectories map[string]string `env:"SERVE_DIRECTORIES"` CPUProfilePath string `env:"CPU_PROFILE_PATH"` // LobbySettingDefaults is used for the server side rendering of the lobby // creation page. It doesn't affect the default values of lobbies created // via the API. LobbySettingDefaults LobbySettingDefaults `envPrefix:"LOBBY_SETTING_DEFAULTS_"` LobbySettingBounds game.SettingBounds `envPrefix:"LOBBY_SETTING_BOUNDS_"` Port uint16 `env:"PORT"` CORS CORS `envPrefix:"CORS_"` LobbyCleanup LobbyCleanup `envPrefix:"LOBBY_CLEANUP_"` } var Default = Config{ Port: 8080, LobbySettingDefaults: LobbySettingDefaults{ Public: "false", DrawingTime: "120", Rounds: "4", MaxPlayers: "24", CustomWordsPerTurn: "3", ClientsPerIPLimit: "2", Language: "english", ScoreCalculation: "chill", WordsPerTurn: "3", }, LobbySettingBounds: game.SettingBounds{ MinDrawingTime: 60, MaxDrawingTime: 300, MinRounds: 1, MaxRounds: 20, MinMaxPlayers: 2, MaxMaxPlayers: 24, MinClientsPerIPLimit: 1, MaxClientsPerIPLimit: 24, MinCustomWordsPerTurn: 1, MaxWordsPerTurn: 6, MinWordsPerTurn: 1, }, CORS: CORS{ AllowedOrigins: []string{"*"}, AllowCredentials: false, }, LobbyCleanup: LobbyCleanup{ Interval: 90 * time.Second, PlayerInactivityThreshold: 75 * time.Second, }, } // Load loads the configuration from the environment. If a .env file is // available, it will be loaded as well. Values found in the environment // will overwrite whatever is load from the .env file. func Load() (*Config, error) { envVars := make(map[string]string) dotEnvPath := ".env" if _, err := os.Stat(dotEnvPath); err != nil { if !os.IsNotExist(err) { return nil, fmt.Errorf("error checking for existence of .env file: %w", err) } } else { envFileContent, err := gotenv.Read(dotEnvPath) if err != nil { return nil, fmt.Errorf("error reading .env file: %w", err) } maps.Copy(envVars, envFileContent) } // Add local environment variables to EnvVars map for _, keyValuePair := range os.Environ() { pair := strings.SplitN(keyValuePair, "=", 2) // For some reason, gitbash can contain the variable `=::=::\` which // gives us a pair where the first entry is empty. if pair[0] == "" { continue } envVars[pair[0]] = pair[1] } config := Default if err := env.ParseWithOptions(&config, env.Options{ Environment: envVars, OnSet: func(key string, value any, isDefault bool) { if !reflect.ValueOf(value).IsZero() { log.Printf("Setting '%s' to '%v' (isDefault: %v)\n", key, value, isDefault) } }, }); err != nil { return nil, fmt.Errorf("error parsing environment variables: %w", err) } // Prevent user error and let the code decide when we need slashes. config.RootURL = strings.TrimSuffix(config.RootURL, "/") if config.CanonicalURL == "" { config.CanonicalURL = config.RootURL } config.RootPath = strings.Trim(config.RootPath, "/") return &config, nil } ================================================ FILE: internal/frontend/doc.go ================================================ // Package frontend contains the HTTP endpoints for delivering the official // web client. In order to register the endpoints you have to call SetupRoutes. package frontend ================================================ FILE: internal/frontend/http.go ================================================ package frontend import ( "embed" "encoding/hex" "fmt" "hash" "html/template" "net/http" "os" "path" "strings" "github.com/gofrs/uuid/v5" "github.com/scribble-rs/scribble.rs/internal/translations" ) var ( //go:embed templates/* templateFS embed.FS pageTemplates *template.Template //go:embed resources/* frontendResourcesFS embed.FS ) func init() { var err error pageTemplates, err = template.ParseFS(templateFS, "templates/*") if err != nil { panic(fmt.Errorf("error loading templates: %w", err)) } } // BasePageConfig is data that all pages require to function correctly, no matter // whether error page or lobby page. type BasePageConfig struct { checksums map[string]string hash hash.Hash // Version is the tagged source code version of this build. Can be empty for dev // builds. Untagged commits will be of format `tag-N-gSHA`. Version string `json:"version"` // Commit that was deployed, if we didn't deploy a concrete tag. Commit string `json:"commit"` // RootPath is the path directly after the domain and before the // scribble.rs paths. For example if you host scribblers on painting.com // but already host a different website, then your API paths might have to // look like this: painting.com/scribblers/v1. RootPath string `json:"rootPath"` // RootURL is similar to RootPath, but contains only the protocol and // domain. So it could be https://painting.com. This is required for some // non critical functionality, such as metadata tags. RootURL string `json:"rootUrl"` // CanonicalURL specifies the original domain, in case we are accessing the // site via some other domain, such as scribblers.fly.dev CanonicalURL string `json:"canonicalUrl"` // AllowIndexing will control whether the noindex, nofollow meta tag is // added to the home page. AllowIndexing bool `env:"ALLOW_INDEXING"` } var fallbackChecksum = uuid.Must(uuid.NewV4()).String() func (baseConfig *BasePageConfig) Hash(key string, bytes []byte) error { _, alreadyExists := baseConfig.checksums[key] if alreadyExists { return fmt.Errorf("duplicate hash key '%s'", key) } if _, err := baseConfig.hash.Write(bytes); err != nil { return fmt.Errorf("error hashing '%s': %w", key, err) } baseConfig.checksums[key] = hex.EncodeToString(baseConfig.hash.Sum(nil)) baseConfig.hash.Reset() return nil } // CacheBust is a string that is appended to all resources to prevent // browsers from using cached data of a previous version, but still have // long lived max age values. func (baseConfig *BasePageConfig) withCacheBust(file string) string { checksum, found := baseConfig.checksums[file] if !found { // No need to crash over return fmt.Sprintf("%s?cache_bust=%s", file, fallbackChecksum) } return fmt.Sprintf("%s?cache_bust=%s", file, checksum) } func (baseConfig *BasePageConfig) WithCacheBust(file string) template.HTMLAttr { return template.HTMLAttr(baseConfig.withCacheBust(file)) } func (handler *SSRHandler) cspMiddleware(handleFunc http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Security-Policy", "base-uri 'self'; default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' data:") handleFunc.ServeHTTP(w, r) } } // SetupRoutes registers the official webclient endpoints with the http package. func (handler *SSRHandler) SetupRoutes(register func(string, string, http.HandlerFunc)) { registerWithCsp := func(s1, s2 string, hf http.HandlerFunc) { register(s1, s2, handler.cspMiddleware(hf)) } var genericFileHandler http.HandlerFunc if dir := handler.cfg.ServeDirectories[""]; dir != "" { delete(handler.cfg.ServeDirectories, "") fileServer := http.FileServer(http.FS(os.DirFS(dir))) genericFileHandler = fileServer.ServeHTTP } for route, dir := range handler.cfg.ServeDirectories { fileServer := http.FileServer(http.FS(os.DirFS(dir))) fileHandler := http.StripPrefix( "/"+path.Join(handler.cfg.RootPath, route)+"/", http.HandlerFunc(fileServer.ServeHTTP), ).ServeHTTP registerWithCsp( // Trailing slash means wildcard. "GET", path.Join(handler.cfg.RootPath, route)+"/", fileHandler, ) } indexHandler := handler.cspMiddleware(handler.indexPageHandler) register("GET", handler.cfg.RootPath, http.StripPrefix( "/"+handler.cfg.RootPath, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "" || r.URL.Path == "/" { indexHandler(w, r) return } if genericFileHandler != nil { genericFileHandler.ServeHTTP(w, r) } })).ServeHTTP) fileServer := http.FileServer(http.FS(frontendResourcesFS)) registerWithCsp( "GET", path.Join(handler.cfg.RootPath, "resources", "{file}"), http.StripPrefix( "/"+handler.cfg.RootPath, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Duration of 1 year, since we use cachebusting anyway. w.Header().Set("Cache-Control", "public, max-age=31536000") fileServer.ServeHTTP(w, r) }), ).ServeHTTP, ) registerWithCsp("GET", path.Join(handler.cfg.RootPath, "lobby.js"), handler.lobbyJs) registerWithCsp("GET", path.Join(handler.cfg.RootPath, "index.js"), handler.indexJs) registerWithCsp("GET", path.Join(handler.cfg.RootPath, "lobby", "{lobby_id}"), handler.ssrEnterLobby) registerWithCsp("POST", path.Join(handler.cfg.RootPath, "lobby"), handler.ssrCreateLobby) } // errorPageData represents the data that error.html requires to be displayed. type errorPageData struct { *BasePageConfig // ErrorMessage displayed on the page. ErrorMessage string Translation *translations.Translation Locale string } // userFacingError will return the occurred error as a custom html page to the caller. func (handler *SSRHandler) userFacingError(w http.ResponseWriter, errorMessage string, translation *translations.Translation) { err := pageTemplates.ExecuteTemplate(w, "error-page", &errorPageData{ BasePageConfig: handler.basePageConfig, ErrorMessage: errorMessage, Translation: translation, }) // This should never happen, but if it does, something is very wrong. if err != nil { panic(err) } } func isHumanAgent(userAgent string) bool { return strings.Contains(userAgent, "gecko") || strings.Contains(userAgent, "chrome") || strings.Contains(userAgent, "opera") || strings.Contains(userAgent, "safari") } ================================================ FILE: internal/frontend/index.go ================================================ package frontend import ( //nolint:gosec //We just use this for cache busting, so it's secure enough "crypto/md5" "errors" "fmt" "log" "net/http" txtTemplate "text/template" "github.com/scribble-rs/scribble.rs/internal/api" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/scribble-rs/scribble.rs/internal/state" "github.com/scribble-rs/scribble.rs/internal/translations" "github.com/scribble-rs/scribble.rs/internal/version" "golang.org/x/text/cases" "golang.org/x/text/language" _ "embed" ) //go:embed lobby.js var lobbyJsRaw string //go:embed index.js var indexJsRaw string type indexJsData struct { *BasePageConfig Translation *translations.Translation Locale string } // This file contains the API for the official web client. type SSRHandler struct { cfg *config.Config basePageConfig *BasePageConfig lobbyJsRawTemplate *txtTemplate.Template indexJsRawTemplate *txtTemplate.Template } func NewHandler(cfg *config.Config) (*SSRHandler, error) { basePageConfig := &BasePageConfig{ checksums: make(map[string]string), hash: md5.New(), Version: version.Version, Commit: version.Commit, RootURL: cfg.RootURL, CanonicalURL: cfg.CanonicalURL, AllowIndexing: cfg.AllowIndexing, } if cfg.RootPath != "" { basePageConfig.RootPath = "/" + cfg.RootPath } if basePageConfig.CanonicalURL == "" { basePageConfig.CanonicalURL = basePageConfig.RootURL } indexJsRawTemplate, err := txtTemplate. New("index-js"). Parse(indexJsRaw) if err != nil { return nil, fmt.Errorf("error parsing index js template: %w", err) } lobbyJsRawTemplate, err := txtTemplate. New("lobby-js"). Parse(lobbyJsRaw) if err != nil { return nil, fmt.Errorf("error parsing lobby js template: %w", err) } lobbyJsRawTemplate.AddParseTree("footer", pageTemplates.Tree) entries, err := frontendResourcesFS.ReadDir("resources") if err != nil { return nil, fmt.Errorf("error reading resource directory: %w", err) } //nolint:gosec //We just use this for cache busting, so it's secure enough for _, entry := range entries { bytes, err := frontendResourcesFS.ReadFile("resources/" + entry.Name()) if err != nil { return nil, fmt.Errorf("error reading resource %s: %w", entry.Name(), err) } if err := basePageConfig.Hash(entry.Name(), bytes); err != nil { return nil, fmt.Errorf("error hashing resource %s: %w", entry.Name(), err) } } if err := basePageConfig.Hash("index.js", []byte(indexJsRaw)); err != nil { return nil, fmt.Errorf("error hashing: %w", err) } if err := basePageConfig.Hash("lobby.js", []byte(lobbyJsRaw)); err != nil { return nil, fmt.Errorf("error hashing: %w", err) } handler := &SSRHandler{ cfg: cfg, basePageConfig: basePageConfig, lobbyJsRawTemplate: lobbyJsRawTemplate, indexJsRawTemplate: indexJsRawTemplate, } return handler, nil } func (handler *SSRHandler) indexJs(writer http.ResponseWriter, request *http.Request) { translation, locale := determineTranslation(request) pageData := &indexJsData{ BasePageConfig: handler.basePageConfig, Translation: translation, Locale: locale, } writer.Header().Set("Content-Type", "text/javascript") // Duration of 1 year, since we use cachebusting anyway. writer.Header().Set("Cache-Control", "public, max-age=31536000") writer.WriteHeader(http.StatusOK) if err := handler.indexJsRawTemplate.ExecuteTemplate(writer, "index-js", pageData); err != nil { log.Printf("error templating JS: %s\n", err) } } // indexPageHandler servers the default page for scribble.rs, which is the // page to create or join a lobby. func (handler *SSRHandler) indexPageHandler(writer http.ResponseWriter, request *http.Request) { translation, locale := determineTranslation(request) createPageData := handler.createDefaultIndexPageData() createPageData.Translation = translation createPageData.Locale = locale api.SetDiscordCookies(writer, request) discordInstanceId := api.GetDiscordInstanceId(request) if discordInstanceId != "" { lobby := state.GetLobby(discordInstanceId) if lobby != nil { handler.ssrEnterLobbyNoChecks(lobby, writer, request, func() *game.Player { return api.GetPlayer(lobby, request) }) return } } err := pageTemplates.ExecuteTemplate(writer, "index", createPageData) if err != nil { log.Printf("Error templating home page: %s\n", err) } } func (handler *SSRHandler) createDefaultIndexPageData() *IndexPageData { return &IndexPageData{ BasePageConfig: handler.basePageConfig, SettingBounds: handler.cfg.LobbySettingBounds, Languages: game.SupportedLanguages, ScoreCalculations: game.SupportedScoreCalculations, LobbySettingDefaults: handler.cfg.LobbySettingDefaults, } } // IndexPageData defines all non-static data for the lobby create page. type IndexPageData struct { *BasePageConfig config.LobbySettingDefaults game.SettingBounds Translation *translations.Translation Locale string Errors []string Languages map[string]string ScoreCalculations []string } // ssrCreateLobby allows creating a lobby, optionally returning errors that // occurred during creation. func (handler *SSRHandler) ssrCreateLobby(writer http.ResponseWriter, request *http.Request) { if err := request.ParseForm(); err != nil { http.Error(writer, err.Error(), http.StatusBadRequest) return } scoreCalculation, scoreCalculationInvalid := api.ParseScoreCalculation(request.Form.Get("score_calculation")) languageRawValue := request.Form.Get("language") languageData, languageKey, languageInvalid := api.ParseLanguage(languageRawValue) drawingTime, drawingTimeInvalid := api.ParseDrawingTime(handler.cfg, request.Form.Get("drawing_time")) rounds, roundsInvalid := api.ParseRounds(handler.cfg, request.Form.Get("rounds")) maxPlayers, maxPlayersInvalid := api.ParseMaxPlayers(handler.cfg, request.Form.Get("max_players")) customWordsPerTurn, customWordsPerTurnInvalid := api.ParseCustomWordsPerTurn(handler.cfg, request.Form.Get("custom_words_per_turn")) clientsPerIPLimit, clientsPerIPLimitInvalid := api.ParseClientsPerIPLimit(handler.cfg, request.Form.Get("clients_per_ip_limit")) publicLobby, publicLobbyInvalid := api.ParseBoolean("public", request.Form.Get("public")) wordsPerTurn, wordsPerTurnInvalid := api.ParseWordsPerTurn(handler.cfg, request.Form.Get("words_per_turn")) if wordsPerTurn < customWordsPerTurn { wordsPerTurnInvalid = errors.New("words per turn must be greater than or equal to custom words per turn") } var lowercaser cases.Caser if languageInvalid != nil { lowercaser = cases.Lower(language.English) } else { lowercaser = languageData.Lowercaser() } customWords, customWordsInvalid := api.ParseCustomWords(lowercaser, request.Form.Get("custom_words")) api.SetDiscordCookies(writer, request) // Prevent resetting the form, since that would be annoying as hell. pageData := IndexPageData{ BasePageConfig: handler.basePageConfig, SettingBounds: handler.cfg.LobbySettingBounds, LobbySettingDefaults: config.LobbySettingDefaults{ Public: request.Form.Get("public"), DrawingTime: request.Form.Get("drawing_time"), Rounds: request.Form.Get("rounds"), MaxPlayers: request.Form.Get("max_players"), CustomWords: request.Form.Get("custom_words"), CustomWordsPerTurn: request.Form.Get("custom_words_per_turn"), ClientsPerIPLimit: request.Form.Get("clients_per_ip_limit"), Language: request.Form.Get("language"), ScoreCalculation: request.Form.Get("score_calculation"), WordsPerTurn: request.Form.Get("words_per_turn"), }, Languages: game.SupportedLanguages, ScoreCalculations: game.SupportedScoreCalculations, } if scoreCalculationInvalid != nil { pageData.Errors = append(pageData.Errors, scoreCalculationInvalid.Error()) } if languageInvalid != nil { pageData.Errors = append(pageData.Errors, languageInvalid.Error()) } if drawingTimeInvalid != nil { pageData.Errors = append(pageData.Errors, drawingTimeInvalid.Error()) } if roundsInvalid != nil { pageData.Errors = append(pageData.Errors, roundsInvalid.Error()) } if maxPlayersInvalid != nil { pageData.Errors = append(pageData.Errors, maxPlayersInvalid.Error()) } if customWordsInvalid != nil { pageData.Errors = append(pageData.Errors, customWordsInvalid.Error()) } if customWordsPerTurnInvalid != nil { pageData.Errors = append(pageData.Errors, customWordsPerTurnInvalid.Error()) } else { if languageRawValue == "custom" && len(customWords) == 0 { pageData.Errors = append(pageData.Errors, "custom words must be provided when using custom language") } } if clientsPerIPLimitInvalid != nil { pageData.Errors = append(pageData.Errors, clientsPerIPLimitInvalid.Error()) } if publicLobbyInvalid != nil { pageData.Errors = append(pageData.Errors, publicLobbyInvalid.Error()) } if wordsPerTurnInvalid != nil { pageData.Errors = append(pageData.Errors, wordsPerTurnInvalid.Error()) } translation, locale := determineTranslation(request) pageData.Translation = translation pageData.Locale = locale if len(pageData.Errors) != 0 { err := pageTemplates.ExecuteTemplate(writer, "index", pageData) if err != nil { http.Error(writer, err.Error(), http.StatusInternalServerError) } return } playerName := api.GetPlayername(request) var lobbyId string discordInstanceId := api.GetDiscordInstanceId(request) if discordInstanceId != "" { lobbyId = discordInstanceId // Workaround, since the discord proxy potentially always has the same // IP address, preventing all players from connecting. clientsPerIPLimit = maxPlayers } lobbySettings := &game.EditableLobbySettings{ Rounds: rounds, DrawingTime: drawingTime, MaxPlayers: maxPlayers, CustomWordsPerTurn: customWordsPerTurn, ClientsPerIPLimit: clientsPerIPLimit, Public: publicLobby, WordsPerTurn: wordsPerTurn, } player, lobby, err := game.CreateLobby(lobbyId, playerName, languageKey, lobbySettings, customWords, scoreCalculation) if err != nil { pageData.Errors = append(pageData.Errors, err.Error()) if err := pageTemplates.ExecuteTemplate(writer, "index", pageData); err != nil { handler.userFacingError(writer, err.Error(), translation) } return } lobby.WriteObject = api.WriteObject lobby.WritePreparedMessage = api.WritePreparedMessage player.SetLastKnownAddress(api.GetIPAddressFromRequest(request)) api.SetGameplayCookies(writer, request, player, lobby) // We only add the lobby if we could do all necessary pre-steps successfully. state.AddLobby(lobby) // Workaround for discord activity case not correctly being able to read // user session, as the cookie isn't being passed. if discordInstanceId != "" { handler.ssrEnterLobbyNoChecks(lobby, writer, request, func() *game.Player { return player }) return } http.Redirect(writer, request, handler.basePageConfig.RootPath+"/lobby/"+lobby.LobbyID, http.StatusFound) } ================================================ FILE: internal/frontend/index.js ================================================ const discordInstanceId = getCookie("discord-instance-id"); const rootPath = `${discordInstanceId ? ".proxy/" : ""}{{.RootPath}}`; Array.from(document.getElementsByClassName("number-input")).forEach( (number_input) => { const input = number_input.children.item(1); const decrement_button = number_input.children.item(0); decrement_button.addEventListener("click", function () { input.stepDown(); }); const increment_button = number_input.children.item(2); increment_button.addEventListener("click", function () { input.stepUp(); }); }, ); // We'll keep using the ssr endpoint for now. With this listener, we // can fake in the form data for "public" depending on which button // we submitted via. This is a dirty hack, but works for now. document.getElementById("lobby-create").addEventListener("submit", (event) => { const check_box = document.getElementById("public-check-box"); if (event.submitter.id === "create-public") { check_box.value = "true"; check_box.setAttribute("checked", ""); } else { check_box.value = "false"; check_box.removeAttribute("checked"); } return true; }); const lobby_list_placeholder = document.getElementById( "lobby-list-placeholder-text", ); const lobby_list_loading_placeholder = document.getElementById( "lobby-list-placeholder-loading", ); const lobby_list = document.getElementById("lobby-list"); lobby_list_placeholder.innerHTML = '{{.Translation.Get "no-lobbies-yet"}}'; const getLobbies = () => { return new Promise((resolve, reject) => { fetch(`${rootPath}/v1/lobby`) .then((response) => { response.json().then(resolve); }) .catch(reject); }); }; const set_lobby_list_placeholder = (text, visible) => { if (visible) { lobby_list_placeholder.style.display = "flex"; lobby_list_placeholder.innerHTML = "" + text + ""; } else { lobby_list_placeholder.style.display = "none"; } }; const set_lobby_list_loading = (loading) => { if (loading) { set_lobby_list_placeholder("", false); lobby_list_loading_placeholder.style.display = "flex"; } else { lobby_list_loading_placeholder.style.display = "none"; } }; const language_to_flag = (language) => { switch (language) { case "english": return "\u{1f1fa}\u{1f1f8}"; case "english_gb": return "\u{1f1ec}\u{1f1e7}"; case "german": return "\u{1f1e9}\u{1f1ea}"; case "ukrainian": return "\u{1f1fa}\u{1f1e6}"; case "russian": return "\u{1f1f7}\u{1f1fa}"; case "italian": return "\u{1f1ee}\u{1f1f9}"; case "french": return "\u{1f1eb}\u{1f1f7}"; case "dutch": return "\u{1f1f3}\u{1f1f1}"; case "polish": return "\u{1f1f5}\u{1f1f1}"; case "hebrew": return "\u{1f1ee}\u{1f1f1}"; } }; const set_lobbies = (lobbies, visible) => { const new_lobby_nodes = lobbies.map((lobby) => { const lobby_list_item = document.createElement("div"); lobby_list_item.className = "lobby-list-item"; const language_flag = document.createElement("span"); language_flag.className = "language-flag"; language_flag.setAttribute("title", lobby.wordpack); language_flag.setAttribute("english", lobby.wordpack); language_flag.innerText = language_to_flag(lobby.wordpack); const lobby_list_rows = document.createElement("div"); lobby_list_rows.className = "lobby-list-rows"; const lobby_list_row_a = document.createElement("div"); lobby_list_row_a.className = "lobby-list-row"; const new_custom_tag = (text) => { const tag = document.createElement("span"); tag.className = "custom-tag"; tag.innerText = text; return tag; }; if (lobby.customWords) { lobby_list_row_a.appendChild( new_custom_tag('{{.Translation.Get "custom-words"}}'), ); } if (lobby.state === "ongoing") { lobby_list_row_a.appendChild( new_custom_tag('{{.Translation.Get "ongoing"}}'), ); } if (lobby.state === "gameover") { lobby_list_row_a.appendChild( new_custom_tag('{{.Translation.Get "game-over-lobby"}}'), ); } if (lobby.scoring === "chill") { lobby_list_row_a.appendChild( new_custom_tag('{{.Translation.Get "chill"}}'), ); } else if (lobby.scoring === "competitive") { lobby_list_row_a.appendChild( new_custom_tag('{{.Translation.Get "competitive"}}'), ); } const lobby_list_row_b = document.createElement("div"); lobby_list_row_b.className = "lobby-list-row"; const create_info_pair = (icon, text) => { const element = document.createElement("div"); element.className = "lobby-list-item-info-pair"; const image = document.createElement("img"); image.className = "lobby-list-item-icon lobby-list-icon-loading"; image.setAttribute("loading", "lazy"); image.addEventListener("load", function () { image.classList.remove("lobby-list-icon-loading"); }); image.setAttribute("src", icon); const span = document.createElement("span"); span.innerText = text; element.replaceChildren(image, span); return element; }; const user_pair = create_info_pair( `{{.RootPath}}/resources/{{.WithCacheBust "user.svg"}}`, `${lobby.playerCount}/${lobby.maxPlayers}`, ); const round_pair = create_info_pair( `{{.RootPath}}/resources/{{.WithCacheBust "round.svg"}}`, `${lobby.round}/${lobby.rounds}`, ); const time_pair = create_info_pair( `{{.RootPath}}/resources/{{.WithCacheBust "clock.svg"}}`, `${lobby.drawingTime}`, ); lobby_list_row_b.replaceChildren(user_pair, round_pair, time_pair); lobby_list_rows.replaceChildren(lobby_list_row_a, lobby_list_row_b); const join_button = document.createElement("button"); join_button.className = "join-button"; join_button.innerText = '{{.Translation.Get "join"}}'; join_button.addEventListener("click", (event) => { window.location.href = `{{.RootPath}}/lobby/${lobby.lobbyId}`; }); lobby_list_item.replaceChildren( language_flag, lobby_list_rows, join_button, ); return lobby_list_item; }); lobby_list.replaceChildren(...new_lobby_nodes); if (lobbies && lobbies.length > 0 && visible) { lobby_list.style.display = "flex"; set_lobby_list_placeholder("", false); } else { lobby_list.style.display = "none"; set_lobby_list_placeholder( '{{.Translation.Get "no-lobbies-yet"}}', true, ); } }; const refresh_lobby_list = () => { set_lobbies([], false); set_lobby_list_loading(true); getLobbies() .then((data) => { set_lobbies(data, true); }) .catch((err) => { set_lobby_list_placeholder(err, true); }) .finally(() => { set_lobby_list_loading(false); }); }; refresh_lobby_list(); document .getElementById("refresh-lobby-list-button") .addEventListener("click", refresh_lobby_list); function getCookie(name) { let cookie = {}; document.cookie.split(";").forEach(function (el) { let split = el.split("="); cookie[split[0].trim()] = split.slice(1).join("="); }); return cookie[name]; } // Makes sure, that navigating back after creating a lobby also shows it in the list. window.addEventListener("pageshow", (event) => { if (event.persisted) { refresh_lobby_list(); } }); ================================================ FILE: internal/frontend/lobby.go ================================================ package frontend import ( "log" "net/http" "strings" "github.com/scribble-rs/scribble.rs/internal/api" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/scribble-rs/scribble.rs/internal/state" "github.com/scribble-rs/scribble.rs/internal/translations" "golang.org/x/text/language" ) type lobbyPageData struct { *BasePageConfig *api.LobbyData Translation *translations.Translation Locale string } type lobbyJsData struct { *BasePageConfig *api.GameConstants Translation *translations.Translation Locale string } func (handler *SSRHandler) lobbyJs(writer http.ResponseWriter, request *http.Request) { translation, locale := determineTranslation(request) pageData := &lobbyJsData{ BasePageConfig: handler.basePageConfig, GameConstants: api.GameConstantsData, Translation: translation, Locale: locale, } writer.Header().Set("Content-Type", "text/javascript") // Duration of 1 year, since we use cachebusting anyway. writer.Header().Set("Cache-Control", "public, max-age=31536000") writer.WriteHeader(http.StatusOK) if err := handler.lobbyJsRawTemplate.ExecuteTemplate(writer, "lobby-js", pageData); err != nil { log.Printf("error templating JS: %s\n", err) } } // ssrEnterLobby opens a lobby, either opening it directly or asking for a lobby. func (handler *SSRHandler) ssrEnterLobby(writer http.ResponseWriter, request *http.Request) { translation, _ := determineTranslation(request) lobby := state.GetLobby(request.PathValue("lobby_id")) if lobby == nil { handler.userFacingError(writer, translation.Get("lobby-doesnt-exist"), translation) return } userAgent := strings.ToLower(request.UserAgent()) if !isHumanAgent(userAgent) { writer.WriteHeader(http.StatusForbidden) handler.userFacingError(writer, translation.Get("forbidden"), translation) return } handler.ssrEnterLobbyNoChecks(lobby, writer, request, func() *game.Player { return api.GetPlayer(lobby, request) }) } func (handler *SSRHandler) ssrEnterLobbyNoChecks( lobby *game.Lobby, writer http.ResponseWriter, request *http.Request, getPlayer func() *game.Player, ) { translation, locale := determineTranslation(request) requestAddress := api.GetIPAddressFromRequest(request) api.SetDiscordCookies(writer, request) var pageData *lobbyPageData lobby.Synchronized(func() { player := getPlayer() if player == nil { if !lobby.HasFreePlayerSlot() { handler.userFacingError(writer, translation.Get("lobby-full"), translation) return } if !lobby.CanIPConnect(requestAddress) { handler.userFacingError(writer, translation.Get("lobby-ip-limit-excceeded"), translation) return } newPlayer := lobby.JoinPlayer(api.GetPlayername(request)) newPlayer.SetLastKnownAddress(requestAddress) api.SetGameplayCookies(writer, request, newPlayer, lobby) } else { if player.Connected && player.GetWebsocket() != nil { handler.userFacingError(writer, translation.Get("lobby-open-tab-exists"), translation) return } player.SetLastKnownAddress(requestAddress) api.SetGameplayCookies(writer, request, player, lobby) } pageData = &lobbyPageData{ BasePageConfig: handler.basePageConfig, LobbyData: api.CreateLobbyData(handler.cfg, lobby), Translation: translation, Locale: locale, } }) // If the pagedata isn't initialized, it means the synchronized block has exited. // In this case we don't want to template the lobby, since an error has occurred // and probably already has been handled. if pageData != nil { if err := pageTemplates.ExecuteTemplate(writer, "lobby-page", pageData); err != nil { log.Printf("Error templating lobby: %s\n", err) } } } func determineTranslation(r *http.Request) (*translations.Translation, string) { languageTags, _, err := language.ParseAcceptLanguage(r.Header.Get("Accept-Language")) if err == nil { for _, languageTag := range languageTags { fullLanguageIdentifier := languageTag.String() fullLanguageIdentifierLowercased := strings.ToLower(fullLanguageIdentifier) translation := translations.GetLanguage(fullLanguageIdentifierLowercased) if translation != nil { return translation, fullLanguageIdentifierLowercased } baseLanguageIdentifier, _ := languageTag.Base() baseLanguageIdentifierLowercased := strings.ToLower(baseLanguageIdentifier.String()) translation = translations.GetLanguage(baseLanguageIdentifierLowercased) if translation != nil { return translation, baseLanguageIdentifierLowercased } } } return translations.DefaultTranslation, "en-us" } ================================================ FILE: internal/frontend/lobby.js ================================================ String.prototype.format = function () { return [...arguments].reduce((p, c) => p.replace(/%s/, c), this); }; const discordInstanceId = getCookie("discord-instance-id"); const rootPath = `${discordInstanceId ? ".proxy/" : ""}{{.RootPath}}`; let socketIsConnecting = false; let hasSocketEverConnected = false; let socket; const reconnectDialogId = "reconnect-dialog"; function showReconnectDialogIfNotShown() { const previousReconnectDialog = document.getElementById(reconnectDialogId); //Since the content is constant, there's no need to ever show two. if ( previousReconnectDialog === undefined || previousReconnectDialog === null ) { showTextDialog( reconnectDialogId, '{{.Translation.Get "connection-lost"}}', `{{.Translation.Get "connection-lost-text"}}`, ); } } //Makes sure that the server notices that the player disconnects. //Otherwise a refresh (on chromium based browsers) can lead to the server //thinking that there's already an open tab with this lobby. window.onbeforeunload = () => { //Avoid unintentionally reestablishing connection. socket.onclose = null; if (socket) { socket.close(); } }; const messageInput = document.getElementById("message-input"); const playerContainer = document.getElementById("player-container"); const wordContainer = document.getElementById("word-container"); const chat = document.getElementById("chat"); const messageContainer = document.getElementById("message-container"); const roundSpan = document.getElementById("rounds"); const maxRoundSpan = document.getElementById("max-rounds"); const timeLeftValue = document.getElementById("time-left-value"); const drawingBoard = document.getElementById("drawing-board"); const centerDialogs = document.getElementById("center-dialogs"); const waitChooseDialog = document.getElementById("waitchoose-dialog"); const waitChooseDrawerSpan = document.getElementById("waitchoose-drawer"); const namechangeDialog = document.getElementById("namechange-dialog"); const namechangeFieldStartDialog = document.getElementById( "namechange-field-start-dialog", ); const namechangeField = document.getElementById("namechange-field"); const lobbySettingsButton = document.getElementById("lobby-settings-button"); const lobbySettingsDialog = document.getElementById("lobbysettings-dialog"); const startDialog = document.getElementById("start-dialog"); const forceStartButton = document.getElementById("force-start-button"); const gameOverDialog = document.getElementById("game-over-dialog"); const gameOverDialogTitle = document.getElementById("game-over-dialog-title"); const gameOverScoreboard = document.getElementById("game-over-scoreboard"); const forceRestartButton = document.getElementById("force-restart-button"); const wordDialog = document.getElementById("word-dialog"); const wordPreSelected = document.getElementById("word-preselected"); const wordButtonContainer = document.getElementById("word-button-container"); const kickDialog = document.getElementById("kick-dialog"); const kickDialogPlayers = document.getElementById("kick-dialog-players"); const soundToggleLabel = document.getElementById("sound-toggle-label"); let sound = localStorage.getItem("sound") !== "false"; updateSoundIcon(); const penToggleLabel = document.getElementById("pen-pressure-toggle-label"); let penPressure = localStorage.getItem("penPressure") !== "false"; updateTogglePenIcon(); function showTextDialog(id, title, message) { const messageNode = document.createElement("span"); messageNode.innerText = message; showDialog(id, title, messageNode); } const menu = document.getElementById("menu"); function hideMenu() { menu.hidePopover(); } function showDialog(id, title, contentNode, buttonBar) { hideMenu(); const newDialog = document.createElement("div"); newDialog.classList.add("center-dialog"); if (id && id !== "") { newDialog.id = id; } const dialogTitle = document.createElement("span"); dialogTitle.classList.add("dialog-title"); dialogTitle.innerText = title; newDialog.appendChild(dialogTitle); const dialogContent = document.createElement("div"); dialogContent.classList.add("center-dialog-content"); dialogContent.appendChild(contentNode); newDialog.appendChild(dialogContent); if (buttonBar !== null && buttonBar !== undefined) { newDialog.appendChild(buttonBar); } newDialog.style.visibility = "visible"; centerDialogs.appendChild(newDialog); } // Shows an information dialog with a button that closes the dialog and // removes it from the DOM. function showInfoDialog(title, message, buttonText) { const dialogId = "info_dialog"; closeDialog(dialogId); const closeButton = createDialogButton(buttonText); closeButton.addEventListener("click", () => { closeDialog(dialogId); }); const messageNode = document.createElement("span"); messageNode.innerText = message; showDialog( dialogId, title, messageNode, createDialogButtonBar(closeButton), ); } function createDialogButton(text) { const button = document.createElement("button"); button.innerText = text; button.classList.add("dialog-button"); return button; } function createDialogButtonBar(...buttons) { const buttonBar = document.createElement("div"); buttonBar.classList.add("button-bar"); buttons.forEach(buttonBar.appendChild); return buttonBar; } function closeDialog(id) { const dialog = document.getElementById(id); if (dialog !== undefined && dialog !== null) { const parent = dialog.parentElement; if (parent !== undefined && parent !== null) { parent.removeChild(dialog); } } } const helpDialogId = "help-dialog"; function showHelpDialog() { closeDialog(helpDialogId); const controlsLabel = document.createElement("b"); controlsLabel.innerText = '{{.Translation.Get "controls"}}'; const controlsTextOne = document.createElement("p"); controlsTextOne.innerText = '{{.Translation.Get "switch-tools-intro"}}:'; const controlsTextTwo = document.createElement("p"); controlsTextTwo.innerHTML = '{{.Translation.Get "pencil"}}: Q
' + '{{.Translation.Get "fill-bucket"}}: W
' + '{{.Translation.Get "eraser"}}: E
'; const controlsTextThree = document.createElement("p"); controlsTextThree.innerHTML = '{{printf (.Translation.Get "switch-pencil-sizes") "1" "4"}}'; const closeButton = createDialogButton('{{.Translation.Get "close"}}'); closeButton.addEventListener("click", () => { closeDialog(helpDialogId); }); const footer = document.createElement("div"); footer.className = "help-footer"; footer.innerHTML = `{{template "footer" . }}`; const buttonBar = createDialogButtonBar(closeButton); const dialogContent = document.createElement("div"); dialogContent.appendChild(controlsLabel); dialogContent.appendChild(controlsTextOne); dialogContent.appendChild(controlsTextTwo); dialogContent.appendChild(controlsTextThree); dialogContent.appendChild(footer); showDialog( helpDialogId, '{{.Translation.Get "help"}}', dialogContent, buttonBar, ); } document .getElementById("help-button") .addEventListener("click", showHelpDialog); function showKickDialog() { hideMenu(); if (cachedPlayers && cachedPlayers) { kickDialogPlayers.innerHTML = ""; cachedPlayers.forEach((player) => { //Don't wanna allow kicking ourselves. if (player.id !== ownID && player.connected) { const playerKickEntry = document.createElement("button"); playerKickEntry.classList.add("kick-player-button"); playerKickEntry.classList.add("dialog-button"); playerKickEntry.onclick = () => onVotekickPlayer(player.id); playerKickEntry.innerText = player.name; kickDialogPlayers.appendChild(playerKickEntry); } }); kickDialog.style.visibility = "visible"; } } document .getElementById("kick-button") .addEventListener("click", showKickDialog); function hideKickDialog() { kickDialog.style.visibility = "hidden"; } document .getElementById("kick-close-button") .addEventListener("click", hideKickDialog); function showNameChangeDialog() { hideMenu(); namechangeDialog.style.visibility = "visible"; namechangeField.focus(); } document .getElementById("name-change-button") .addEventListener("click", showNameChangeDialog); function hideNameChangeDialog() { namechangeDialog.style.visibility = "hidden"; } document .getElementById("namechange-close-button") .addEventListener("click", hideNameChangeDialog); function changeName(name) { //Avoid unnecessary traffic. if (name !== ownName) { socket.send( JSON.stringify({ type: "name-change", data: name, }), ); } } document .getElementById("namechange-button-start-dialog") .addEventListener("click", () => { changeName( document.getElementById("namechange-field-start-dialog").value, ); }); document.getElementById("namechange-button").addEventListener("click", () => { changeName(document.getElementById("namechange-field").value); hideNameChangeDialog(); }); function setUsernameLocally(name) { ownName = name; namechangeFieldStartDialog.value = name; namechangeField.value = name; } function toggleFullscreen() { if (document.fullscreenElement !== null) { document.exitFullscreen(); } else { document.body.requestFullscreen(); } } document .getElementById("toggle-fullscreen-button") .addEventListener("click", toggleFullscreen); function showLobbySettingsDialog() { hideMenu(); lobbySettingsDialog.style.visibility = "visible"; } lobbySettingsButton.addEventListener("click", showLobbySettingsDialog); function hideLobbySettingsDialog() { lobbySettingsDialog.style.visibility = "hidden"; } document .getElementById("lobby-settings-close-button") .addEventListener("click", hideLobbySettingsDialog); function saveLobbySettings() { fetch( `${rootPath}/v1/lobby?` + new URLSearchParams({ drawing_time: document.getElementById( "lobby-settings-drawing-time", ).value, rounds: document.getElementById("lobby-settings-max-rounds") .value, public: document.getElementById("lobby-settings-public") .checked, max_players: document.getElementById( "lobby-settings-max-players", ).value, clients_per_ip_limit: document.getElementById( "lobby-settings-clients-per-ip-limit", ).value, custom_words_per_turn: document.getElementById( "lobby-settings-custom-words-per-turn", ).value, words_per_turn: document.getElementById( "lobby-settings-words-per-turn", ).value, }), { method: "PATCH", }, ).then((result) => { if (result.status === 200) { hideLobbySettingsDialog(); } else { result.text().then((bodyText) => { alert( "Error saving lobby settings: \n\n - " + bodyText.replace(";", "\n - "), ); }); } }); } document .getElementById("lobby-settings-save-button") .addEventListener("click", saveLobbySettings); function toggleSound() { sound = !sound; localStorage.setItem("sound", sound.toString()); updateSoundIcon(); } document .getElementById("toggle-sound-button") .addEventListener("click", toggleSound); function updateSoundIcon() { if (sound) { soundToggleLabel.src = `{{.RootPath}}/resources/{{.WithCacheBust "sound.svg"}}`; } else { soundToggleLabel.src = `{{.RootPath}}/resources/{{.WithCacheBust "no-sound.svg"}}`; } } function togglePenPressure() { penPressure = !penPressure; localStorage.setItem("penPressure", penPressure.toString()); updateTogglePenIcon(); } document .getElementById("toggle-pen-pressure-button") .addEventListener("click", togglePenPressure); function updateTogglePenIcon() { if (penPressure) { penToggleLabel.src = `{{.RootPath}}/resources/{{.WithCacheBust "pen.svg"}}`; } else { penToggleLabel.src = `{{.RootPath}}/resources/{{.WithCacheBust "no-pen.svg"}}`; } } //The drawing board has a base size. This base size results in a certain ratio //that the actual canvas has to be resized accordingly too. This is needed //since not every client has the same screensize. const baseWidth = 1600; const baseHeight = 900; const boardRatio = baseWidth / baseHeight; // Moving this here to extract the context after resizing const context = drawingBoard.getContext("2d", { alpha: false }); // One might one wonder what the fuck is going here. I'll enlighten you! // The data you put into a canvas, might not necessarily be what comes out // of it again. Some browser (*cough* firefox *cough*) seem to put little // off by one / two errors into the data, when reading it back out. // Apparently this helps against some type of fingerprinting. In order to // combat this, we do not use the canvas as a source of truth, but // permanently hold a virtual canvas buffer that we can operate on when // filling or drawing. let imageData; function scaleUpFactor() { return baseWidth / drawingBoard.clientWidth; } // Will convert the value to the server coordinate space. // The canvas locally can be bigger or smaller. Depending on the base // values and the local values, we'll either have a value slightly // higher or lower than 1.0. Since we draw on a virtual canvas, we have // to use the server coordinate space, which then gets scaled by the // canvas API of the browser, as we have a different clientWidth than // width and clientHeight than height. function convertToServerCoordinate(value) { return Math.round(parseFloat(scaleUpFactor() * value)); } const pen = 0; const rubber = 1; const fillBucket = 2; let allowDrawing = false; let spectating = false; let spectateRequested = false; //Initially, we require some values to avoid running into nullpointers //or undefined errors. The specific values don't really matter. let localTool = pen; let localLineWidth = 8; //Those are not scaled for now, as the whole toolbar would then have to incorrectly size up and down. const sizeButton8 = document.getElementById("size-8-button"); const sizeButton16 = document.getElementById("size-16-button"); const sizeButton24 = document.getElementById("size-24-button"); const sizeButton32 = document.getElementById("size-32-button"); const sizeButtons = document.getElementById("size-buttons"); const toolButtonPen = document.getElementById("tool-type-pencil"); const toolButtonRubber = document.getElementById("tool-type-rubber"); const toolButtonFill = document.getElementById("tool-type-fill"); if (sizeButton8.checked) { setLineWidthNoUpdate(8); } else if (sizeButton16.checked) { setLineWidthNoUpdate(16); } else if (sizeButton24.checked) { setLineWidthNoUpdate(24); } else if (sizeButton32.checked) { setLineWidthNoUpdate(32); } if (toolButtonPen.checked) { chooseToolNoUpdate(pen); } else if (toolButtonFill.checked) { chooseToolNoUpdate(fillBucket); } else if (toolButtonRubber.checked) { chooseToolNoUpdate(rubber); } let localColor, localColorIndex; function setColor(index) { setColorNoUpdate(index); // If we select a new color, we assume we don't want to use the // rubber anymore and automatically switch to the pen. if (localTool === rubber) { // Clicking the button programmatically won't trigger its toolButtonPen.click(); // updateDrawingStateUI is implicit chooseTool(pen); } else { updateDrawingStateUI(); } } const firstColorButtonRow = document.getElementById("first-color-button-row"); const secondColorButtonRow = document.getElementById("second-color-button-row"); for (let i = 0; i < firstColorButtonRow.children.length; i++) { const _setColor = () => setColor(i); firstColorButtonRow.children[i].addEventListener("mousedown", _setColor); firstColorButtonRow.children[i].addEventListener("click", _setColor); } for (let i = 0; i < secondColorButtonRow.children.length; i++) { const _setColor = () => setColor(i + 13); secondColorButtonRow.children[i].addEventListener("mousedown", _setColor); secondColorButtonRow.children[i].addEventListener("click", _setColor); } function setColorNoUpdate(index) { localColorIndex = index; localColor = indexToRgbColor(index); sessionStorage.setItem("local_color", JSON.stringify(index)); } setColorNoUpdate( JSON.parse(sessionStorage.getItem("local_color")) ?? 13 /* black*/, ); updateDrawingStateUI(); function setLineWidth(value) { setLineWidthNoUpdate(value); updateDrawingStateUI(); } sizeButton8.addEventListener("change", () => setLineWidth(8)); document .getElementById("size-8-button-wrapper") .addEventListener("mouseup", sizeButton8.click); document .getElementById("size-8-button-wrapper") .addEventListener("mousedown", sizeButton8.click); sizeButton16.addEventListener("change", () => setLineWidth(16)); document .getElementById("size-16-button-wrapper") .addEventListener("mouseup", sizeButton16.click); document .getElementById("size-16-button-wrapper") .addEventListener("mousedown", sizeButton16.click); sizeButton24.addEventListener("change", () => setLineWidth(24)); document .getElementById("size-24-button-wrapper") .addEventListener("mouseup", sizeButton24.click); document .getElementById("size-24-button-wrapper") .addEventListener("mousedown", sizeButton24.click); sizeButton32.addEventListener("change", () => setLineWidth(32)); document .getElementById("size-32-button-wrapper") .addEventListener("mouseup", sizeButton32.click); document .getElementById("size-32-button-wrapper") .addEventListener("mousedown", sizeButton32.click); function setLineWidthNoUpdate(value) { localLineWidth = value; } function chooseTool(value) { chooseToolNoUpdate(value); updateDrawingStateUI(); } toolButtonFill.addEventListener("change", () => chooseTool(fillBucket)); toolButtonPen.addEventListener("change", () => chooseTool(pen)); toolButtonRubber.addEventListener("change", () => chooseTool(rubber)); document .getElementById("tool-type-fill-wrapper") .addEventListener("mouseup", toolButtonFill.click); document .getElementById("tool-type-pencil-wrapper") .addEventListener("mouseup", toolButtonPen.click); document .getElementById("tool-type-rubber-wrapper") .addEventListener("mouseup", toolButtonRubber.click); document .getElementById("tool-type-fill-wrapper") .addEventListener("mousedown", toolButtonFill.click); document .getElementById("tool-type-pencil-wrapper") .addEventListener("mousedown", toolButtonPen.click); document .getElementById("tool-type-rubber-wrapper") .addEventListener("mousedown", toolButtonRubber.click); function chooseToolNoUpdate(value) { if (value === pen || value === rubber || value === fillBucket) { localTool = value; } else { //If this ends up with an invalid value, we use the pencil. localTool = pen; } } function rgbColorObjectToHexString(color) { return ( "#" + numberTo16BitHexadecimal(color.r) + numberTo16BitHexadecimal(color.g) + numberTo16BitHexadecimal(color.b) ); } function numberTo16BitHexadecimal(number) { return Number(number).toString(16).padStart(2, "0"); } const rubberColor = { r: 255, g: 255, b: 255 }; function updateDrawingStateUI() { // Color all buttons, so the player always has a hint as to what the // active color is, since the cursor might not always be visible. sizeButtons.style.setProperty( "--dot-color", rgbColorObjectToHexString(localColor), ); updateCursor(); } function updateCursor() { if (allowDrawing) { if (localTool === rubber) { setCircleCursor(rubberColor, localLineWidth); } else if (localTool === fillBucket) { const outerColor = getComplementaryCursorColor(localColor); drawingBoard.style.cursor = `url('data:image/svg+xml;utf8,` + encodeURIComponent( `` + generateSVGCircle(8, localColor, outerColor) + //This has been taken from fill.svg ` `, ) + `') 4 4, auto`; } else { setCircleCursor(localColor, localLineWidth); } } else { drawingBoard.style.cursor = "not-allowed"; } } function getComplementaryCursorColor(innerColor) { const hsp = Math.sqrt( 0.299 * (innerColor.r * innerColor.r) + 0.587 * (innerColor.g * innerColor.g) + 0.114 * (innerColor.b * innerColor.b), ); if (hsp > 127.5) { return { r: 0, g: 0, b: 0 }; } return { r: 255, g: 255, b: 255 }; } function setCircleCursor(innerColor, size) { const outerColor = getComplementaryCursorColor(innerColor); const circleSize = size; drawingBoard.style.cursor = `url('data:image/svg+xml;utf8,` + encodeURIComponent( `` + generateSVGCircle(circleSize, innerColor, outerColor) + `')`, ) + ` ` + circleSize / 2 + ` ` + circleSize / 2 + `, auto`; } function generateSVGCircle(circleSize, innerColor, outerColor) { const circleRadius = circleSize / 2; const innerColorCSS = "rgb(" + innerColor.r + "," + innerColor.g + "," + innerColor.b + ")"; const outerColorCSS = "rgb(" + outerColor.r + "," + outerColor.g + "," + outerColor.b + ")"; return ( `` ); } function toggleSpectate() { socket.send( JSON.stringify({ type: "toggle-spectate", }), ); } document .getElementById("toggle-spectate-button") .addEventListener("click", toggleSpectate); function setSpectateMode(requestedValue, spectatingValue) { const modeUnchanged = spectatingValue === spectating; const requestUnchanged = requestedValue === spectateRequested; if (modeUnchanged && requestUnchanged) { return; } if (spectateRequested && !requestedValue && modeUnchanged) { showInfoDialog( `{{.Translation.Get "spectation-request-cancelled-title"}}`, `{{.Translation.Get "spectation-request-cancelled-text"}}`, `{{.Translation.Get "confirm"}}`, ); } else if (spectateRequested && !requestedValue && modeUnchanged) { showInfoDialog( `{{.Translation.Get "participation-request-cancelled-title"}}`, `{{.Translation.Get "participation-request-cancelled-text"}}`, `{{.Translation.Get "confirm"}}`, ); } else if (!spectateRequested && requestedValue && !spectatingValue) { showInfoDialog( `{{.Translation.Get "spectation-requested-title"}}`, `{{.Translation.Get "spectation-requested-text"}}`, `{{.Translation.Get "confirm"}}`, ); } else if (!spectateRequested && requestedValue && spectatingValue) { showInfoDialog( `{{.Translation.Get "participation-requested-title"}}`, `{{.Translation.Get "participation-requested-text"}}`, `{{.Translation.Get "confirm"}}`, ); } else if (spectatingValue && !spectating) { showInfoDialog( `{{.Translation.Get "now-spectating-title"}}`, `{{.Translation.Get "now-spectating-text"}}`, `{{.Translation.Get "confirm"}}`, ); } else if (!spectatingValue && spectating) { showInfoDialog( `{{.Translation.Get "now-participating-title"}}`, `{{.Translation.Get "now-participating-text"}}`, `{{.Translation.Get "confirm"}}`, ); } spectateRequested = requestedValue; spectating = spectatingValue; } function toggleReadiness() { socket.send( JSON.stringify({ type: "toggle-readiness", }), ); } document .getElementById("ready-state-start") .addEventListener("change", toggleReadiness); document .getElementById("ready-state-game-over") .addEventListener("change", toggleReadiness); function forceStartGame() { socket.send( JSON.stringify({ type: "start", }), ); } forceStartButton.addEventListener("click", forceStartGame); forceRestartButton.addEventListener("click", forceStartGame); function clearCanvasAndSendEvent() { if (allowDrawing) { //Avoid unnecessary traffic back to us and handle the clear directly. clear(context); socket.send( JSON.stringify({ type: "clear-drawing-board", }), ); } } document .getElementById("clear-canvas-button") .addEventListener("click", clearCanvasAndSendEvent); function undoAndSendEvent() { if (allowDrawing) { socket.send( JSON.stringify({ type: "undo", }), ); } } document .getElementById("undo-button") .addEventListener("click", undoAndSendEvent); //Used to restore the last message on arrow up. let lastMessage = ""; const encoder = new TextEncoder(); function sendMessage(event) { if (event.key !== "Enter") { return; } if (!messageInput.value) { return; } // While the backend already checks for message length, we want to // prevent the loss of input and omit the event / clear here. if (encoder.encode(messageInput.value).length > 10000) { appendMessage( "system-message", '{{.Translation.Get "system"}}', '{{.Translation.Get "message-too-long"}}', ); //We keep the messageInput content, since it could've been //something important and we don't want the user having to //rewrite it. Instead they can send it via some other means //or shorten it a bit. return; } socket.send( JSON.stringify({ type: "message", data: messageInput.value, }), ); lastMessage = messageInput.value; messageInput.value = ""; } messageInput.addEventListener("keypress", sendMessage); messageInput.addEventListener("keydown", function (event) { if (event.key === "ArrowUp" && messageInput.value.length === 0) { messageInput.value = lastMessage; const length = lastMessage.length; // Postpone selection change onto next event queue loop iteration, as // nothing will happen otherwise. setTimeout(() => { // length+1 is necessary, as the selection wont change if start and // end are the same, messageInput.setSelectionRange(length + 1, length); }, 0); } }); function setAllowDrawing(value) { allowDrawing = value; updateDrawingStateUI(); if (allowDrawing) { document.getElementById("toolbox").style.display = "flex"; } else { document.getElementById("toolbox").style.display = "none"; } } function chooseWord(index) { socket.send( JSON.stringify({ type: "choose-word", data: index, }), ); setAllowDrawing(true); wordDialog.style.visibility = "hidden"; } function onVotekickPlayer(playerId) { socket.send( JSON.stringify({ type: "kick-vote", data: playerId, }), ); hideKickDialog(); } //This automatically scrolls down the chat on arrivals of new messages new MutationObserver( () => (messageContainer.scrollTop = messageContainer.scrollHeight), ).observe(messageContainer, { attributes: false, childList: true, subtree: false, }); let ownID, ownerID, ownName, drawerID, drawerName; let round = 0; let rounds = 0; let roundEndTime = 0; let gameState = "unstarted"; let drawingTimeSetting = "∞"; const handleEvent = (parsed) => { if (parsed.type === "ready") { handleReadyEvent(parsed.data); } else if (parsed.type === "game-over") { let ready = parsed.data; if (parsed.data.roundEndReason === "drawer_disconnected") { appendMessage( "system-message", null, `{{.Translation.Get "drawer-disconnected"}}`, ); } else if (parsed.data.roundEndReason === "guessers_disconnected") { appendMessage( "system-message", null, `{{.Translation.Get "guessers-disconnected"}}`, ); } else { showRoundEndMessage(ready.previousWord); } handleReadyEvent(ready); } else if (parsed.type === "update-players") { applyPlayers(parsed.data); } else if (parsed.type === "name-change") { const player = getCachedPlayer(parsed.data.playerId); if (player !== null) { player.name = parsed.data.playerName; } const playernameSpan = document.getElementById( "playername-" + parsed.data.playerId, ); if (playernameSpan !== null) { playernameSpan.innerText = parsed.data.playerName; } if (parsed.data.playerId === ownID) { setUsernameLocally(parsed.data.playerName); } if (parsed.data.playerId === drawerID) { waitChooseDrawerSpan.innerText = parsed.data.playerName; } } else if (parsed.type === "correct-guess") { playWav('{{.RootPath}}/resources/{{.WithCacheBust "plop.wav"}}'); if (parsed.data === ownID) { appendMessage( "correct-guess-message", null, `{{.Translation.Get "correct-guess"}}`, ); } else { const player = getCachedPlayer(parsed.data); if (player !== null) { appendMessage( "correct-guess-message-other-player", null, `{{.Translation.Get "correct-guess-other-player"}}`.format( player.name, ), ); } } } else if (parsed.type === "close-guess") { appendMessage( "close-guess-message", null, `{{.Translation.Get "close-guess"}}`.format(parsed.data), ); } else if (parsed.type === "update-wordhint") { wordDialog.style.visibility = "hidden"; waitChooseDialog.style.visibility = "hidden"; applyWordHints(parsed.data); // We don't do this in applyWordHints because that's called in all kinds of places if (parsed.data.some((hint) => hint.character)) { var hints = parsed.data .map((hint) => { if (hint.character) { var char = String.fromCharCode(hint.character); if (char === " " || hint.revealed) { return char; } } return "_"; }) .join(" "); appendMessage( ["system-message", "hint-chat-message"], '{{.Translation.Get "system"}}', '{{.Translation.Get "word-hint-revealed"}}\n' + hints, { dir: wordContainer.getAttribute("dir") }, ); } } else if (parsed.type === "message") { appendMessage(null, parsed.data.author, parsed.data.content); } else if (parsed.type === "system-message") { appendMessage( "system-message", '{{.Translation.Get "system"}}', parsed.data, ); } else if (parsed.type === "non-guessing-player-message") { appendMessage( "non-guessing-player-message", parsed.data.author, parsed.data.content, ); } else if (parsed.type === "line") { drawLine( context, imageData, parsed.data.x, parsed.data.y, parsed.data.x2, parsed.data.y2, indexToRgbColor(parsed.data.color), parsed.data.width, ); } else if (parsed.type === "fill") { if ( floodfillUint8ClampedArray( imageData.data, parsed.data.x, parsed.data.y, indexToRgbColor(parsed.data.color), imageData.width, imageData.height, ) ) { context.putImageData(imageData, 0, 0); } } else if (parsed.type === "clear-drawing-board") { clear(context); } else if (parsed.type === "word-chosen") { wordDialog.style.visibility = "hidden"; waitChooseDialog.style.visibility = "hidden"; setRoundTimeLeft(parsed.data.timeLeft); applyWordHints(parsed.data.hints); setAllowDrawing(drawerID === ownID); } else if (parsed.type === "next-turn") { if (gameState === "ongoing") { if (parsed.data.roundEndReason === "drawer_disconnected") { appendMessage( "system-message", null, `{{.Translation.Get "drawer-disconnected"}}`, ); } else if (parsed.data.roundEndReason === "guessers_disconnected") { appendMessage( "system-message", null, `{{.Translation.Get "guessers-disconnected"}}`, ); } else { showRoundEndMessage(parsed.data.previousWord); } } else { //First turn, the game starts gameState = "ongoing"; } //As soon as a turn starts, the round should be ongoing, so we make //sure that all types of dialogs, that indicate the game isn't //ongoing, are not visible anymore. startDialog.style.visibility = "hidden"; forceRestartButton.style.display = "none"; gameOverDialog.style.visibility = "hidden"; //If a player doesn't choose, the dialog will still be up. wordDialog.style.visibility = "hidden"; playWav('{{.RootPath}}/resources/{{.WithCacheBust "end-turn.wav"}}'); clear(context); round = parsed.data.round; updateRoundsDisplay(); setRoundTimeLeft(parsed.data.choiceTimeLeft); applyPlayers(parsed.data.players); set_dummy_word_hints(); //Even though we always hide the dialog in the "your-turn" //event handling, it will be shortly visible if we it here. if (drawerID !== ownID) { //Show additional dialog, that another user (drawer) is choosing a word waitChooseDrawerSpan.innerText = drawerName; waitChooseDialog.style.visibility = "visible"; } setAllowDrawing(false); } else if (parsed.type === "your-turn") { playWav('{{.RootPath}}/resources/{{.WithCacheBust "your-turn.wav"}}'); //This dialog could potentially stay visible from last //turn, in case nobody has chosen a word. waitChooseDialog.style.visibility = "hidden"; promptWords(parsed.data); } else if (parsed.type === "drawing") { applyDrawData(parsed.data); } else if (parsed.type === "kick-vote") { if ( parsed.data.playerId === ownID && parsed.data.voteCount >= parsed.data.requiredVoteCount ) { alert('{{.Translation.Get "self-kicked"}}'); document.location.href = "{{.RootPath}}/"; } else { let kickMessage = '{{.Translation.Get "kick-vote"}}'.format( parsed.data.voteCount, parsed.data.requiredVoteCount, parsed.data.playerName, ); if (parsed.data.voteCount >= parsed.data.requiredVoteCount) { kickMessage += ' {{.Translation.Get "player-kicked"}}'; } appendMessage( "system-message", '{{.Translation.Get "system"}}', kickMessage, ); } } else if (parsed.type === "owner-change") { ownerID = parsed.data.playerId; updateButtonVisibilities(); appendMessage( "system-message", '{{.Translation.Get "system"}}', '{{.Translation.Get "owner-change"}}'.format( parsed.data.playerName, ), ); } else if (parsed.type === "drawer-kicked") { appendMessage( "system-message", '{{.Translation.Get "system"}}', '{{.Translation.Get "drawer-kicked"}}', ); } else if (parsed.type === "lobby-settings-changed") { rounds = parsed.data.rounds; updateRoundsDisplay(); updateButtonVisibilities(); appendMessage( "system-message", '{{.Translation.Get "system"}}', '{{.Translation.Get "lobby-settings-changed"}}\n\n' + '{{.Translation.Get "drawing-time-setting"}}: ' + parsed.data.drawingTime + "\n" + '{{.Translation.Get "rounds-setting"}}: ' + parsed.data.rounds + "\n" + '{{.Translation.Get "public-lobby-setting"}}: ' + parsed.data.public + "\n" + '{{.Translation.Get "max-players-setting"}}: ' + parsed.data.maxPlayers + "\n" + '{{.Translation.Get "custom-words-per-turn-setting"}}: ' + parsed.data.customWordsPerTurn + "\n" + '{{.Translation.Get "players-per-ip-limit-setting"}}: ' + parsed.data.clientsPerIpLimit + "\n" + '{{.Translation.Get "words-per-turn-setting"}}: ' + parsed.data.wordsPerTurn, ); } else if (parsed.type === "shutdown") { socket.onclose = null; socket.close(); showDialog( "shutdown-info", '{{.Translation.Get "server-shutting-down-title"}}', document.createTextNode( '{{.Translation.Get "server-shutting-down-text"}}', ), ); } }; function showRoundEndMessage(previousWord) { if (previousWord === "") { appendMessage( "system-message", null, `{{.Translation.Get "round-over"}}`, ); } else { appendMessage( "system-message", null, `{{.Translation.Get "round-over-no-word"}}`.format(previousWord), ); } } function getCachedPlayer(playerID) { if (!cachedPlayers) { return null; } for (let i = 0; i < cachedPlayers.length; i++) { const player = cachedPlayers[i]; if (player.id === playerID) { return player; } } return null; } //In the initial implementation we used a timestamp to know when //the round will end. The problem with that approach was that the //clock on client and server was often not in sync. The second //approach was to instead send milliseconds left and keep counting //them down each 500 milliseconds. The problem with this approach, was //that there could potentially be timing mistakes while counting down. //What we do instead is use our local date, add the timeLeft to it and //repeatdly recaculate the timeLeft using the roundEndTime and the //current time. This way we won't have any calculation errors. // //FIXME The only leftover issue is that ping isn't taken into //account, however, that's no biggie for now. function setRoundTimeLeft(timeLeftMs) { roundEndTime = Date.now() + timeLeftMs; } const handleReadyEvent = (ready) => { ownerID = ready.ownerId; ownID = ready.playerId; setRoundTimeLeft(ready.timeLeft); setUsernameLocally(ready.playerName); setAllowDrawing(ready.allowDrawing); round = ready.round; rounds = ready.rounds; gameState = ready.gameState; drawingTimeSetting = ready.drawingTimeSetting; updateRoundsDisplay(); updateButtonVisibilities(); if (ready.players && ready.players.length) { applyPlayers(ready.players); } if (ready.currentDrawing && ready.currentDrawing.length) { applyDrawData(ready.currentDrawing); } if (ready.wordHints && ready.wordHints.length) { applyWordHints(ready.wordHints); } else { set_dummy_word_hints(); } if (ready.gameState === "unstarted") { startDialog.style.visibility = "visible"; if (ownerID === ownID) { forceStartButton.style.display = "block"; } else { forceStartButton.style.display = "none"; } } else if (ready.gameState === "gameOver") { gameOverDialog.style.visibility = "visible"; if (ownerID === ownID) { forceRestartButton.style.display = "block"; } gameOverScoreboard.innerHTML = ""; //Copying array so we can sort. const players = cachedPlayers.slice(); players.sort((a, b) => { return a.rank - b.rank; }); //These two are required for displaying the "game over / win / tie" message. let countOfRankOnePlayers = 0; let selfPlayer; for (let i = 0; i < players.length; i++) { const player = players[i]; if (!player.connected || player.state === "spectating") { continue; } if (player.rank === 1) { countOfRankOnePlayers++; } if (player.id === ownID) { selfPlayer = player; } // We only display the first 5 players on the scoreboard. if (player.rank <= 5) { const newScoreboardEntry = document.createElement("div"); newScoreboardEntry.classList.add("gameover-scoreboard-entry"); if (player.id === ownID) { newScoreboardEntry.classList.add( "gameover-scoreboard-entry-self", ); } const scoreboardRankDiv = document.createElement("div"); scoreboardRankDiv.classList.add("gameover-scoreboard-rank"); scoreboardRankDiv.innerText = player.rank; newScoreboardEntry.appendChild(scoreboardRankDiv); const scoreboardNameDiv = document.createElement("div"); scoreboardNameDiv.classList.add("gameover-scoreboard-name"); scoreboardNameDiv.innerText = player.name; newScoreboardEntry.appendChild(scoreboardNameDiv); const scoreboardScoreSpan = document.createElement("span"); scoreboardScoreSpan.classList.add("gameover-scoreboard-score"); scoreboardScoreSpan.innerText = player.score; newScoreboardEntry.appendChild(scoreboardScoreSpan); gameOverScoreboard.appendChild(newScoreboardEntry); } } if (selfPlayer.rank === 1) { if (countOfRankOnePlayers >= 2) { gameOverDialogTitle.innerText = `{{.Translation.Get "game-over-tie"}}`; } else { gameOverDialogTitle.innerText = `{{.Translation.Get "game-over-win"}}`; } } else { gameOverDialogTitle.innerText = `{{.Translation.Get "game-over"}}`.format( selfPlayer.rank, selfPlayer.score, ); } } else if (ready.gameState === "ongoing") { // Lack of wordHints implies that word has been chosen yet. if (!ready.wordHints && drawerID !== ownID) { waitChooseDrawerSpan.innerText = drawerName; waitChooseDialog.style.visibility = "visible"; } } }; function updateButtonVisibilities() { if (ownerID === ownID) { lobbySettingsButton.style.display = "flex"; } else { lobbySettingsButton.style.display = "none"; } } function promptWords(data) { wordPreSelected.textContent = data.words[data.preSelectedWord]; wordButtonContainer.replaceChildren( ...data.words.map((word, index) => { const button = createDialogButton(word); button.onclick = () => { chooseWord(index); }; return button; }), ); wordDialog.style.visibility = "visible"; } function playWav(file) { if (sound) { const audio = new Audio(file); audio.type = "audio/wav"; audio.play(); } } window.setInterval(() => { if (gameState === "ongoing") { const msLeft = roundEndTime - Date.now(); const secondsLeft = Math.max(0, Math.floor(msLeft / 1000)); timeLeftValue.innerText = "" + secondsLeft; } else { timeLeftValue.innerText = "∞"; } }, 500); //appendMessage adds a new message to the message container. If the //message amount is too high, we cut off a part of the messages to //prevent lagging and useless memory usage. function appendMessage(styleClass, author, message, attrs) { if (messageContainer.childElementCount >= 100) { messageContainer.removeChild(messageContainer.firstChild); } const newMessageDiv = document.createElement("div"); newMessageDiv.classList.add("message"); if (isString(styleClass)) { styleClass = [styleClass]; } for (const cls of styleClass) { newMessageDiv.classList.add(cls); } if (author !== null && author !== "") { const authorNameSpan = document.createElement("span"); authorNameSpan.classList.add("chat-name"); authorNameSpan.innerText = author; newMessageDiv.appendChild(authorNameSpan); } const messageSpan = document.createElement("span"); messageSpan.classList.add("message-content"); messageSpan.innerText = message; newMessageDiv.appendChild(messageSpan); if (attrs !== null && attrs !== "") { if (isObject(attrs)) { for (const [attrKey, attrValue] of Object.entries(attrs)) { messageSpan.setAttribute(attrKey, attrValue); } } } messageContainer.appendChild(newMessageDiv); } let cachedPlayers; //applyPlayers takes the players passed, assigns them to cachedPlayers, //refreshes the scoreboard and updates the drawerID and drawerName variables. function applyPlayers(players) { const matchOngoing = gameState === "ongoing"; if (!matchOngoing) { let readyPlayers = 0; let readyPlayersRequired = 0; players.forEach((player) => { if (!player.connected || player.state === "spectating") { return; } readyPlayersRequired = readyPlayersRequired + 1; if (player.state === "ready") { readyPlayers = readyPlayers + 1; } if (player.id === ownID) { document.getElementById("ready-state-start").checked = player.state === "ready"; document.getElementById("ready-state-game-over").checked = player.state === "ready"; } }); const readyCounts = document.getElementsByClassName("ready-count"); const reaadyNeededs = document.getElementsByClassName("ready-needed"); Array.from(readyCounts).forEach((element) => { element.innerText = readyPlayers.toString(); }); Array.from(reaadyNeededs).forEach((element) => { element.innerText = readyPlayersRequired.toString(); }); } playerContainer.innerHTML = ""; players.forEach((player) => { // Makes sure that the "is choosing" a word dialog doesn't show // "undefined" as the player name. Can happen, if the player // disconnects after being assigned the drawer. if (matchOngoing && player.state === "drawing") { drawerID = player.id; drawerName = player.name; } //We don't wanna show the disconnected players. if (!player.connected) { return; } if (player.id === ownID) { setSpectateMode( player.spectateToggleRequested, player.state === "spectating", ); } const oldPlayer = getCachedPlayer(player.id); if ( oldPlayer && oldPlayer.state === "spectating" && player.state !== "spectating" ) { appendMessage( "system-message", '{{.Translation.Get "system"}}', `${player.name} is now participating`, ); } else if ( oldPlayer && oldPlayer.state !== "spectating" && player.state === "spectating" ) { appendMessage( "system-message", '{{.Translation.Get "system"}}', `${player.name} is now spectating`, ); } if (player.state === "spectating") { return; } const playerDiv = document.createElement("div"); playerDiv.classList.add("player"); const scoreAndStatusDiv = document.createElement("div"); scoreAndStatusDiv.classList.add("score-and-status"); playerDiv.appendChild(scoreAndStatusDiv); const playerscoreDiv = document.createElement("div"); playerscoreDiv.classList.add("playerscore-group"); scoreAndStatusDiv.appendChild(playerscoreDiv); if (matchOngoing) { if (player.state === "standby") { playerDiv.classList.add("player-done"); } else if (player.state === "drawing") { const playerStateImage = createPlayerStateImageNode( `{{.RootPath}}/resources/{{.WithCacheBust "pencil.svg"}}`, ); playerStateImage.style.transform = "scaleX(-1)"; scoreAndStatusDiv.appendChild(playerStateImage); } else if (player.state === "standby") { const playerStateImage = createPlayerStateImageNode( `{{.RootPath}}/resources/{{.WithCacheBust "checkmark.svg"}}`, ); scoreAndStatusDiv.appendChild(playerStateImage); } } else { if (player.state === "ready") { playerDiv.classList.add("player-ready"); } } const rankSpan = document.createElement("span"); rankSpan.classList.add("rank"); rankSpan.innerText = player.rank; playerDiv.appendChild(rankSpan); const playernameSpan = document.createElement("span"); playernameSpan.classList.add("playername"); playernameSpan.innerText = player.name; playernameSpan.id = "playername-" + player.id; if (player.id === ownID) { playernameSpan.classList.add("playername-self"); } playerDiv.appendChild(playernameSpan); const playerscoreSpan = document.createElement("span"); playerscoreSpan.classList.add("playerscore"); playerscoreSpan.innerText = player.score; playerscoreDiv.appendChild(playerscoreSpan); const lastPlayerscoreSpan = document.createElement("span"); lastPlayerscoreSpan.classList.add("last-turn-score"); lastPlayerscoreSpan.innerText = '{{.Translation.Get "last-turn"}}'.format(player.lastScore); playerscoreDiv.appendChild(lastPlayerscoreSpan); playerContainer.appendChild(playerDiv); }); // We do this at the end, so we can access the old values while // iterating over the new ones cachedPlayers = players; } function createPlayerStateImageNode(path) { const playerStateImage = document.createElement("img"); playerStateImage.style.width = "1rem"; playerStateImage.style.height = "1rem"; playerStateImage.src = path; return playerStateImage; } function updateRoundsDisplay() { roundSpan.innerText = round; maxRoundSpan.innerText = rounds; } const applyWordHints = (wordHints, dummy) => { const isDrawer = drawerID === ownID; let wordLengths = []; let count = 0; wordContainer.replaceChildren( ...wordHints.map((hint, index) => { const hintSpan = document.createElement("span"); hintSpan.classList.add("hint"); if (dummy) { hintSpan.style.visibility = "hidden"; } if (hint.character === 0) { hintSpan.classList.add("hint-underline"); hintSpan.innerHTML = " "; } else { if (hint.underline) { hintSpan.classList.add("hint-underline"); } hintSpan.innerText = String.fromCharCode(hint.character); } // space if (hint.character === 32) { wordLengths.push(count); count = 0; } else if (index === wordHints.length - 1) { count += 1; wordLengths.push(count); } else { count += 1; } if (hint.revealed && isDrawer) { hintSpan.classList.add("hint-revealed"); } return hintSpan; }), ); const lengthHint = document.createElement("sub"); lengthHint.classList.add("word-length-hint"); if (dummy) { lengthHint.style.visibility = "hidden"; } lengthHint.setAttribute("dir", wordContainer.getAttribute("dir")); lengthHint.innerText = `(${wordLengths.join(", ")})`; wordContainer.appendChild(lengthHint); }; const set_dummy_word_hints = () => { // Dummy wordhint to prevent layout changes. applyWordHints( [ { character: "D", underline: true, }, ], true, ); }; set_dummy_word_hints(); const applyDrawData = (drawElements) => { clear(context); drawElements.forEach((drawElement) => { const drawData = drawElement.data; if (drawElement.type === "fill") { floodfillUint8ClampedArray( imageData.data, drawData.x, drawData.y, indexToRgbColor(drawData.color), imageData.width, imageData.height, ); } else if (drawElement.type === "line") { drawLineNoPut( context, imageData, drawData.x, drawData.y, drawData.x2, drawData.y2, indexToRgbColor(drawData.color), drawData.width, ); } else { console.log("Unknown draw element type: " + drawData.type); } }); context.putImageData(imageData, 0, 0); }; let lastX = 0; let lastY = 0; let touchID = null; function onTouchStart(event) { //We only allow a single touch if (allowDrawing && touchID == null && localTool !== fillBucket) { const touch = event.touches[0]; touchID = touch.identifier; // calculate the offset coordinates based on client touch position and drawing board client origin const clientRect = drawingBoard.getBoundingClientRect(); lastX = touch.clientX - clientRect.left; lastY = touch.clientY - clientRect.top; } } function onTouchMove(event) { // Prevent moving, scrolling or zooming the page event.preventDefault(); if (allowDrawing) { for (let i = event.changedTouches.length - 1; i >= 0; i--) { if (event.changedTouches[i].identifier === touchID) { const touch = event.changedTouches[i]; // calculate the offset coordinates based on client touch position and drawing board client origin const clientRect = drawingBoard.getBoundingClientRect(); const offsetX = touch.clientX - clientRect.left; const offsetY = touch.clientY - clientRect.top; // drawing functions must check for context boundaries drawLineAndSendEvent(context, lastX, lastY, offsetX, offsetY); lastX = offsetX; lastY = offsetY; return; } } } } function onTouchEnd(event) { for (let i = event.changedTouches.length - 1; i >= 0; i--) { if (event.changedTouches[i].identifier === touchID) { touchID = null; return; } } } drawingBoard.addEventListener("touchend", onTouchEnd); drawingBoard.addEventListener("touchcancel", onTouchEnd); drawingBoard.addEventListener("touchstart", onTouchStart); drawingBoard.addEventListener("touchmove", onTouchMove); function onMouseDown(event) { if ( allowDrawing && event.pointerType !== "touch" && event.buttons === 1 && localTool !== fillBucket ) { const clientRect = drawingBoard.getBoundingClientRect(); lastX = event.clientX - clientRect.left; lastY = event.clientY - clientRect.top; } } function pressureToLineWidth(event) { //event.button === 0 could be wrong, as it can also be the uninitialized state. //Therefore we use event.buttons, which works differently. if ( event.buttons !== 1 || event.pressure === 0 || event.pointerType === "touch" ) { return 0; } if (!penPressure || event.pressure === 0.5 || !event.pressure) { return localLineWidth; } return Math.ceil(event.pressure * 32); } // Previously the onMouseMove handled leave, but we do this separately now for // proper pen support. Otherwise leave leads to a loss of the pen pressure, as // we are handling that with mouseleave instead of pointerleave. pointerlave // is not triggered until the pen is let go. function onMouseLeave(event) { if (allowDrawing && lastLineWidth && localTool !== fillBucket) { // calculate the offset coordinates based on client mouse position and drawing board client origin const clientRect = drawingBoard.getBoundingClientRect(); const offsetX = event.clientX - clientRect.left; const offsetY = event.clientY - clientRect.top; // drawing functions must check for context boundaries drawLineAndSendEvent( context, lastX, lastY, offsetX, offsetY, lastLineWidth, ); lastX = offsetX; lastY = offsetY; } } let lastLineWidth; function onMouseMove(event) { const pressureLineWidth = pressureToLineWidth(event); lastLineWidth = pressureLineWidth; if (allowDrawing && pressureLineWidth && localTool !== fillBucket) { // calculate the offset coordinates based on client mouse position and drawing board client origin const clientRect = drawingBoard.getBoundingClientRect(); const offsetX = event.clientX - clientRect.left; const offsetY = event.clientY - clientRect.top; // drawing functions must check for context boundaries drawLineAndSendEvent( context, lastX, lastY, offsetX, offsetY, pressureLineWidth, ); lastX = offsetX; lastY = offsetY; } } function onMouseClick(event) { //event.buttons won't work here, since it's always 0. Since we //have a click event, we can be sure that we actually had a button //clicked and 0 won't be the uninitialized state. if (allowDrawing && event.button === 0) { if (localTool === fillBucket) { fillAndSendEvent( context, event.offsetX, event.offsetY, localColorIndex, ); } else { drawLineAndSendEvent( context, event.offsetX, event.offsetY, event.offsetX, event.offsetY, ); } } } drawingBoard.addEventListener("pointerdown", onMouseDown); drawingBoard.addEventListener("pointermove", onMouseMove); drawingBoard.addEventListener("mouseleave", onMouseLeave); drawingBoard.addEventListener("click", onMouseClick); function onGlobalMouseMove(event) { const clientRect = drawingBoard.getBoundingClientRect(); lastX = Math.min( clientRect.width - 1, Math.max(0, event.clientX - clientRect.left), ); lastY = Math.min( clientRect.height - 1, Math.max(0, event.clientY - clientRect.top), ); } //necessary for mousemove to not use the previous exit coordinates. //If this is done via mouseleave and mouseenter of the //drawingBoard, the lines will end too early on leave and start //too late on exit. window.addEventListener("mousemove", onGlobalMouseMove); function isAnyDialogVisible() { for (let i = 0; i < centerDialogs.children.length; i++) { if (centerDialogs.children[i].style.visibility === "visible") { return true; } } return false; } function onKeyDown(event) { //Avoid firing actions if the user is in the chat. if (document.activeElement instanceof HTMLInputElement) { return; } //If dialogs are open, it doesn't really make sense to be able to //change tools. As this is like being in the pause menu of a game. if (isAnyDialogVisible()) { return; } //They key choice was made like this, since it's easy to remember //and easy to reach. This is how many MOBAs do it and I personally //find it better than having to find specific keys on your //keyboard. Especially for people that aren't used to typing //without looking at their keyboard, this might help. if (event.key === "q") { toolButtonPen.click(); chooseTool(pen); } else if (event.key === "w") { toolButtonFill.click(); chooseTool(fillBucket); } else if (event.key === "e") { toolButtonRubber.click(); chooseTool(rubber); } else if (event.key === "1") { sizeButton8.click(); setLineWidth(8); } else if (event.key === "2") { sizeButton16.click(); setLineWidth(16); } else if (event.key === "3") { sizeButton24.click(); setLineWidth(24); } else if (event.key === "4") { sizeButton32.click(); setLineWidth(32); } else if (event.key === "z" && event.ctrlKey) { undoAndSendEvent(); } } //Handling events on the canvas directly isn't possible, since the user //must've clicked it at least once in order for that to work. window.addEventListener("keydown", onKeyDown); function debounce(func, timeout) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; } function clear(context) { context.fillStyle = "#FFFFFF"; context.fillRect(0, 0, drawingBoard.width, drawingBoard.height); // Refetch, as we don't manually fill here. imageData = context.getImageData( 0, 0, context.canvas.width, context.canvas.height, ); } // Clear initially, as it will be black otherwise. clear(context); function fillAndSendEvent(context, x, y, colorIndex) { const xScaled = convertToServerCoordinate(x); const yScaled = convertToServerCoordinate(y); const color = indexToRgbColor(colorIndex); if ( floodfillUint8ClampedArray( imageData.data, xScaled, yScaled, color, imageData.width, imageData.height, ) ) { context.putImageData(imageData, 0, 0); const fillInstruction = { type: "fill", data: { x: xScaled, y: yScaled, color: colorIndex, }, }; socket.send(JSON.stringify(fillInstruction)); } } function drawLineAndSendEvent( context, x1, y1, x2, y2, lineWidth = localLineWidth, ) { const color = localTool === rubber ? rubberColor : localColor; const colorIndex = localTool === rubber ? 0 /* white */ : localColorIndex; const x1Scaled = convertToServerCoordinate(x1); const y1Scaled = convertToServerCoordinate(y1); const x2Scaled = convertToServerCoordinate(x2); const y2Scaled = convertToServerCoordinate(y2); drawLine( context, imageData, x1Scaled, y1Scaled, x2Scaled, y2Scaled, color, lineWidth, ); const drawInstruction = { type: "line", data: { x: x1Scaled, y: y1Scaled, x2: x2Scaled, y2: y2Scaled, color: colorIndex, width: lineWidth, }, }; socket.send(JSON.stringify(drawInstruction)); } function getCookie(name) { let cookie = {}; document.cookie.split(";").forEach(function (el) { let split = el.split("="); cookie[split[0].trim()] = split.slice(1).join("="); }); return cookie[name]; } function isString(obj) { return typeof obj === "string"; } function isObject(obj) { return ( typeof obj === "object" && obj !== null && !Array.isArray(obj) && Object.prototype.toString.call(obj) === "[object Object]" ); } const connectToWebsocket = () => { if (socketIsConnecting === true) { return; } socketIsConnecting = true; socket = new WebSocket(`${rootPath}/v1/lobby/ws`); socket.onerror = (error) => { //Is not connected and we haven't yet said that we are done trying to //connect, this means that we could never even establish a connection. if (socket.readyState != 1 && !hasSocketEverConnected) { socketIsConnecting = false; showTextDialog( "connection-error-dialog", '{{.Translation.Get "error-connecting"}}', `{{.Translation.Get "error-connecting-text"}}`, ); console.log("Error establishing connection: ", error); } else { console.log("Socket error: ", error); } }; socket.onopen = () => { closeDialog(reconnectDialogId); hasSocketEverConnected = true; socketIsConnecting = false; socket.onclose = (event) => { //We want to avoid handling the error multiple times and showing the incorrect dialogs. socket.onerror = null; console.log("Socket Closed Connection: ", event); if (event.code === 4000) { showTextDialog( reconnectDialogId, "Kicked", `You have been kicked from the lobby.`, ); } else { console.log("Attempting to reestablish socket connection."); showReconnectDialogIfNotShown(); connectToWebsocket(); } }; socket.onmessage = (jsonMessage) => { handleEvent(JSON.parse(jsonMessage.data)); }; console.log("Successfully Connected"); }; }; connectToWebsocket(); //In order to avoid automatically canceling the socket connection, we keep //sending dummy events every 5 seconds. This was a problem on Heroku. If //a player took a very long time to choose a word, the connection of all //players could be killed and even cause the lobby being closed. Since //that's very frustrating, we want to avoid that. window.setInterval(() => { if (socket) { socket.send(JSON.stringify({ type: "keep-alive" })); } }, 5000); ================================================ FILE: internal/frontend/lobby_test.go ================================================ package frontend import ( "testing" "github.com/scribble-rs/scribble.rs/internal/api" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" ) func TestCreateLobby(t *testing.T) { t.Parallel() data := api.CreateLobbyData( &config.Default, &game.Lobby{ LobbyID: "TEST", }) var previousSize uint8 for _, suggestedSize := range data.SuggestedBrushSizes { if suggestedSize < previousSize { t.Error("Sorting in SuggestedBrushSizes is incorrect") } } for _, suggestedSize := range data.SuggestedBrushSizes { if suggestedSize < game.MinBrushSize { t.Errorf("suggested brushsize %d is below MinBrushSize %d", suggestedSize, game.MinBrushSize) } if suggestedSize > game.MaxBrushSize { t.Errorf("suggested brushsize %d is above MaxBrushSize %d", suggestedSize, game.MaxBrushSize) } } } ================================================ FILE: internal/frontend/resources/draw.js ================================================ //Notice for core code of the floodfill, which has since then been heavily //changed. //Copyright(c) Max Irwin - 2011, 2015, 2016 //Repo: https://github.com/binarymax/floodfill.js //MIT License function floodfillData(data, x, y, fillcolor, width, height) { const length = data.length; let i = (x + y * width) * 4; //Fill coordinates are out of bounds if (i < 0 || i >= length) { return false; } //We check whether the target pixel is already the desired color, since //filling wouldn't change any of the pixels in this case. const targetcolor = [data[i], data[i + 1], data[i + 2]]; if ( targetcolor[0] === fillcolor.r && targetcolor[1] === fillcolor.g && targetcolor[2] === fillcolor.b) { return false; } let e = i, w = i, me, mw, w2 = width * 4; let j; //Previously we used Array.push and Array.pop here, with which the method //took between 70ms and 80ms on a rather strong machine with a FULL HD monitor. //Since Q can never be required to be bigger than the amount of maximum //pixels (width*height), we preallocate Q with that size. While not all of //the space might be needed, this is cheaper than reallocating multiple times. //This improved the time from 70ms-80ms to 50ms-60ms. const Q = new Array(width * height); let nextQIndex = 0; Q[nextQIndex++] = i; while (nextQIndex > 0) { i = Q[--nextQIndex]; if (pixelCompareAndSet(i, targetcolor, fillcolor, data)) { e = i; w = i; mw = Math.floor(i / w2) * w2; //left bound me = mw + w2; //right bound while (mw < w && mw <= (w -= 4) && pixelCompareAndSet(w, targetcolor, fillcolor, data)); //go left until edge hit while (me > e && me > (e += 4) && pixelCompareAndSet(e, targetcolor, fillcolor, data)); //go right until edge hit for (j = w + 4; j < e; j += 4) { if (j - w2 >= 0 && pixelCompare(j - w2, targetcolor, data)) Q[nextQIndex++] = j - w2; //queue y-1 if (j + w2 < length && pixelCompare(j + w2, targetcolor, data)) Q[nextQIndex++] = j + w2; //queue y+1 } } } return data; }; function pixelCompare(i, targetcolor, data) { return ( targetcolor[0] === data[i] && targetcolor[1] === data[i + 1] && targetcolor[2] === data[i + 2] ); }; function pixelCompareAndSet(i, targetcolor, fillcolor, data) { if (pixelCompare(i, targetcolor, data)) { data[i] = fillcolor.r; data[i + 1] = fillcolor.g; data[i + 2] = fillcolor.b; return true; } return false; }; function floodfillUint8ClampedArray(data, x, y, color, width, height) { if (isNaN(width) || width < 1) throw new Error("argument 'width' must be a positive integer"); if (isNaN(height) || height < 1) throw new Error("argument 'height' must be a positive integer"); if (isNaN(x) || x < 0) throw new Error("argument 'x' must be a positive integer"); if (isNaN(y) || y < 0) throw new Error("argument 'y' must be a positive integer"); if (width * height * 4 !== data.length) throw new Error("width and height do not fit Uint8ClampedArray dimensions"); const xi = Math.floor(x); const yi = Math.floor(y); return floodfillData(data, xi, yi, color, width, height); }; // Code for line drawing, not related to the floodfill repo. // Hence it's all BSD licensed. function drawLine(context, imageData, x1, y1, x2, y2, color, width) { const coords = prepareDrawLineCoords(context, x1, y1, x2, y2, width); _drawLineNoPut(imageData, coords, color, width); context.putImageData(imageData, 0, 0, 0, 0, coords.right, coords.bottom); }; // This implementation directly access the canvas data and does not // put it back into the canvas context directly. This saved us not // only from calling put, which is relatively cheap, but also from // calling getImageData all the time. function drawLineNoPut(context, imageData, x1, y1, x2, y2, color, width) { _drawLineNoPut(imageData, prepareDrawLineCoords(context, x1, y1, x2, y2, width), color, width); }; function _drawLineNoPut(imageData, coords, color, width) { const { x1, y1, x2, y2, left, top, right, bottom } = coords; // off canvas, so don't draw anything if (right - left === 0 || bottom - top === 0) { return; } const circleMap = generateCircleMap(Math.floor(width / 2)); const offset = Math.floor(circleMap.length / 2); for (let ix = 0; ix < circleMap.length; ix++) { for (let iy = 0; iy < circleMap[ix].length; iy++) { if (circleMap[ix][iy] === 1 || (x1 === x2 && y1 === y2 && circleMap[ix][iy] === 2)) { const newX1 = x1 + ix - offset; const newY1 = y1 + iy - offset; const newX2 = x2 + ix - offset; const newY2 = y2 + iy - offset; drawBresenhamLine(imageData, newX1, newY1, newX2, newY2, color); } } } } function prepareDrawLineCoords(context, x1, y1, x2, y2, width) { // the coordinates must be whole numbers to improve performance. // also, decimals as coordinates is not making sense. x1 = Math.floor(x1); y1 = Math.floor(y1); x2 = Math.floor(x2); y2 = Math.floor(y2); // calculate bounding box const left = Math.max(0, Math.min(context.canvas.width, Math.min(x1, x2) - width)); const top = Math.max(0, Math.min(context.canvas.height, Math.min(y1, y2) - width)); const right = Math.max(0, Math.min(context.canvas.width, Math.max(x1, x2) + width)); const bottom = Math.max(0, Math.min(context.canvas.height, Math.max(y1, y2) + width)); return { x1: x1, y1: y1, x2: x2, y2: y2, left: left, top: top, right: right, bottom: bottom, }; } function drawBresenhamLine(imageData, x1, y1, x2, y2, color) { const dx = Math.abs(x2 - x1); const dy = Math.abs(y2 - y1); const sx = (x1 < x2) ? 1 : -1; const sy = (y1 < y2) ? 1 : -1; let err = dx - dy; while (true) { //check if pixel is inside the canvas if (!(x1 < 0 || x1 >= imageData.width || y1 < 0 || y1 >= imageData.height)) { setPixel(imageData, x1, y1, color); } if ((x1 === x2) && (y1 === y2)) break; const e2 = 2 * err; if (e2 > -dy) { err -= dy; x1 += sx; } if (e2 < dx) { err += dx; y1 += sy; } } } // We cache them, as we need quite a lot of them, but the pencil size usually // doesn't change that often. There's also not many sizes, so we don't need to // worry about invalidating anything. let cachedCircleMaps = {}; function generateCircleMap(radius) { const cached = cachedCircleMaps[radius]; if (cached) { return cached; } const diameter = 2 * radius; const circleData = new Array(diameter); for (let x = 0; x < diameter; x++) { circleData[x] = new Array(diameter); for (let y = 0; y < diameter; y++) { const distanceToRadius = Math.sqrt(Math.pow(radius - x, 2) + Math.pow(radius - y, 2)); if (distanceToRadius > radius) { circleData[x][y] = 0; } else if (distanceToRadius < radius - 2) { circleData[x][y] = 2; } else { circleData[x][y] = 1; } } } cachedCircleMaps[radius] = circleData; return circleData; } function setPixel(imageData, x, y, color) { const offset = (y * imageData.width + x) * 4; imageData.data[offset] = color.r; imageData.data[offset + 1] = color.g; imageData.data[offset + 2] = color.b; } //We accept both #RRGGBB and RRGGBB. Both are treated case insensitive. function hexStringToRgbColorObject(hexString) { if (!hexString) { return { r: 0, g: 0, b: 0 }; } const hexColorsRegex = /#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})/i; const match = hexString.match(hexColorsRegex) return { r: parseInt(match[1], 16), g: parseInt(match[2], 16), b: parseInt(match[3], 16) }; } const colorMap = [ { hex: '#ffffff', rgb: hexStringToRgbColorObject('#ffffff') }, { hex: '#c1c1c1', rgb: hexStringToRgbColorObject('#c1c1c1') }, { hex: '#ef130b', rgb: hexStringToRgbColorObject('#ef130b') }, { hex: '#ff7100', rgb: hexStringToRgbColorObject('#ff7100') }, { hex: '#ffe400', rgb: hexStringToRgbColorObject('#ffe400') }, { hex: '#00cc00', rgb: hexStringToRgbColorObject('#00cc00') }, { hex: '#00b2ff', rgb: hexStringToRgbColorObject('#00b2ff') }, { hex: '#231fd3', rgb: hexStringToRgbColorObject('#231fd3') }, { hex: '#a300ba', rgb: hexStringToRgbColorObject('#a300ba') }, { hex: '#d37caa', rgb: hexStringToRgbColorObject('#d37caa') }, { hex: '#a0522d', rgb: hexStringToRgbColorObject('#a0522d') }, { hex: '#592f2a', rgb: hexStringToRgbColorObject('#592f2a') }, { hex: '#ecbcb4', rgb: hexStringToRgbColorObject('#ecbcb4') }, { hex: '#000000', rgb: hexStringToRgbColorObject('#000000') }, { hex: '#4c4c4c', rgb: hexStringToRgbColorObject('#4c4c4c') }, { hex: '#740b07', rgb: hexStringToRgbColorObject('#740b07') }, { hex: '#c23800', rgb: hexStringToRgbColorObject('#c23800') }, { hex: '#e8a200', rgb: hexStringToRgbColorObject('#e8a200') }, { hex: '#005510', rgb: hexStringToRgbColorObject('#005510') }, { hex: '#00569e', rgb: hexStringToRgbColorObject('#00569e') }, { hex: '#0e0865', rgb: hexStringToRgbColorObject('#0e0865') }, { hex: '#550069', rgb: hexStringToRgbColorObject('#550069') }, { hex: '#a75574', rgb: hexStringToRgbColorObject('#a75574') }, { hex: '#63300d', rgb: hexStringToRgbColorObject('#63300d') }, { hex: '#492f31', rgb: hexStringToRgbColorObject('#492f31') }, { hex: '#d1a3a4', rgb: hexStringToRgbColorObject('#d1a3a4') } ]; function indexToHexColor(index) { return colorMap[index].hex; } function indexToRgbColor(index) { return colorMap[index].rgb; } ================================================ FILE: internal/frontend/resources/error.css ================================================ .error-pane-wrapper { flex: 1; display: flex; flex-direction: column; } .error-pane { display: inline-block; margin: auto; background-color: white; padding: 1rem; border-radius: 1rem; } .error-title, .error-message { display: block; } .error-title { font-size: 6rem; } .error-message { font-size: 3rem; margin: 2vw; } .go-back, .go-back:link, .go-back:visited { display: block; font-size: 3rem; color: rgb(248, 148, 164); text-align: center; } ================================================ FILE: internal/frontend/resources/index.css ================================================ * { border: none; margin: 0; } /*root end*/ #logo { width: 50vw; margin-top: 1rem; margin-bottom: 1rem; margin-left: auto; margin-right: auto; } #home-choices { display: flex; flex-direction: row; gap: 1rem; justify-content: center; } .home-choice-header { display: flex; } .home-choice-title { font-size: 1.25rem; font-weight: bold; flex: 1; } .home-choice-inner { row-gap: 1rem; display: flex; flex-direction: column; height: 100%; } .home-choice { background-color: var(--pane-background); padding: 1.5rem; border-radius: 1.3rem; overflow: hidden; width: min(42.5vw, 35rem); height: 59vh; } .home { display: flex; flex-direction: column; align-items: center; flex: 1; } #lobby-list { display: flex; flex-direction: column; overflow-y: auto; gap: 0.75rem; padding: 0.25rem; min-height: 10rem; } .lobby-list-item { background-color: white; padding: 1rem; border-radius: 0.75rem; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1.25rem; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); transition: transform 0.15s ease, box-shadow 0.15s ease; border: 1px solid rgba(0, 0, 0, 0.05); } .lobby-list-item:hover { background-color: #fafafa; } .lobby-list-rows { display: flex; flex-direction: column; gap: 0.5rem; overflow: hidden; } .lobby-list-row { display: flex; flex-direction: row; gap: 0.75rem; align-items: center; flex-wrap: wrap; } .language-flag { font-size: 3rem; line-height: 1; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); margin-right: 0.25rem; } .lobby-list-item-info-pair { display: flex; flex-direction: row; gap: 0.35rem; align-items: center; background: #f8f9fa; padding: 0.25rem 0.5rem; border-radius: 0.5rem; font-size: 0.9rem; font-weight: 600; } .lobby-list-item-icon { width: 1.1rem; height: 1.1rem; } .lobby-list-icon-loading { border-radius: 0.75rem; background-color: black; animation: shimmer 2s infinite; } @keyframes shimmer { 0% { background-color: rgb(161, 160, 160); } 50% { background-color: rgb(228, 228, 228); } 100% { background-color: rgb(161, 160, 160); } } .lobby-list-placeholder { display: flex; width: 100%; flex: 1; } .lobby-list-placeholder > * { margin: auto; max-width: 80%; } .join-button { background-color: rgb(38, 187, 38); color: white; font-weight: 800; font-size: 1.1rem; padding: 0.75rem 1.5rem; border-radius: 0.6rem; cursor: pointer; text-transform: uppercase; letter-spacing: 0.05rem; transition: background-color 0.2s, transform 0.1s; height: unset; width: unset; align-self: stretch; display: flex; align-items: center; justify-content: center; border: none; } .join-button:hover { background-color: rgb(34, 167, 34); transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15); } .join-button:active { transform: scale(0.96); } .custom-tag { font-size: 0.8rem; font-weight: 700; text-transform: uppercase; background-color: #f0f0f0; color: #666; border-radius: 2rem; padding: 0.15rem 0.6rem; white-space: nowrap; } #lobby-create { display: grid; grid-template-columns: max-content 1fr; column-gap: 1rem; row-gap: 0.5rem; overflow-y: auto; scrollbar-gutter: stable; padding-right: 0.5rem; flex: 1; min-height: 0; grid-template-rows: min-content min-content min-content min-content min-content min-content min-content max-content; } .lobby-create-label { font-weight: 600; } .advanced-toggle-checkbox { display: none !important; } .advanced-section-label { display: none !important; } .advanced-section-content { display: contents !important; } #custom_words { min-height: 4rem; } .lobby-create-errors { display: flex; flex-direction: column; gap: 0.5rem; background-color: #ff6961; border-radius: 1rem; padding: 0.5rem; } .create-buttons { display: flex; flex-direction: row; gap: 0.5rem; } .create-button { height: 2rem; flex: 1; } .number-input { display: flex; flex-direction: row; padding: 0; border-radius: var(--component-border-radius); border: 2px hidden; min-width: 0; box-sizing: border-box; } .number-input > button { width: 1.5rem; background-color: color-mix(in srgb, var(--component-base-color), #000 5%); } .number-input > button:hover { background-color: var(--component-hover-background); } .number-input > button:focus { background-color: var(--component-focus-background); } .number-decrement { border-top-right-radius: 0; border-bottom-right-radius: 0; } .number-increment { border-top-left-radius: 0; border-bottom-left-radius: 0; } .number-input > input { flex: 1; border-radius: 0; -webkit-appearance: textfield; appearance: textfield; min-width: 0; } .number-input > input::-webkit-inner-spin-button, .number-input > input::-webkit-inner-spin-button { -webkit-appearance: none; } .reload-spinner { animation-name: spin; animation-duration: 1000ms; animation-iteration-count: infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @media (max-width: 1000px) or (orientation: portrait) { #lobby-create { grid-template-columns: 1fr minmax(0, 8.5rem) !important; column-gap: 0.5rem; scrollbar-gutter: auto; } textarea.input-item { height: 6rem; } #lobby-join-choice { flex: 1; } .home-choice { height: initial; } #logo { width: 95vw; max-height: 10vh; margin-left: 0; margin-right: 0; margin-top: 0; } #home-choices { flex-direction: column; flex: 1; gap: 1.5rem; width: 100%; box-sizing: border-box; padding-left: 1rem; padding-right: 1rem; padding-bottom: 1rem; } .home-choice { width: 100%; box-sizing: border-box; height: auto; min-height: 15rem; max-height: none; flex: none; overflow: visible; } #lobby-create { overflow-y: visible; flex: none; } .home-choice-inner { height: auto; min-height: 0; } #lobby-list { flex: 1; } .advanced-section-label { display: flex !important; grid-column: 1 / -1; border-top: 1px solid rgba(0, 0, 0, 0.1); padding-top: 0.5rem; margin-top: 0.5rem; cursor: pointer; user-select: none; font-weight: 600; justify-content: space-between; align-items: center; } .advanced-section-label .toggle-icon { transition: transform 0.2s; font-size: 0.8rem; } .advanced-toggle-checkbox:checked + .advanced-section-label .toggle-icon { transform: rotate(90deg); } .advanced-toggle-checkbox:checked ~ .advanced-section-content { display: initial !important; max-height: 0; opacity: 1; overflow: hidden; pointer-events: none; } .advanced-section-content label[for="custom_words"], .advanced-section-content #custom_words { grid-column: 1 / -1; } .lobby-list-item { grid-template-columns: auto 1fr auto !important; text-align: left !important; gap: 0.6rem !important; padding: 0.6rem 0.8rem !important; } .language-flag { font-size: 2.2rem !important; margin-right: 0 !important; } .lobby-list-rows { gap: 0.15rem !important; justify-content: center; display: flex; flex-direction: column; } .lobby-list-row { justify-content: flex-start !important; gap: 0.35rem !important; } .lobby-list-item-info-pair { padding: 0.15rem 0.4rem !important; font-size: 0.8rem !important; } .join-button { width: auto !important; margin-top: 0 !important; padding: 0.4rem 0.8rem !important; font-size: 0.9rem !important; align-self: center !important; } } ================================================ FILE: internal/frontend/resources/lobby.css ================================================ :root { --dot-color: black; } .noscript { display: flex; font-size: 2.5rem; font-weight: bold; justify-content: center; border-bottom: 1rem solid black; padding: 10px; } .custom-check-or-radio { /* Little hack in order to hide the original components of the check/radio button */ opacity: 0; position: absolute; } .input-container { justify-content: center; align-items: center; display: inline-grid; grid-template-columns: auto auto auto auto; column-gap: 20px; row-gap: 10px; } .input-container > b { align-self: baseline; } .input-container > input[type="checkbox"] { /* By default checkboxes seem to have a bigger margin on the left. */ margin-left: 0; margin-right: 0; } kbd { background-color: #eee; border-radius: 3px; border: 1px solid #b4b4b4; box-shadow: 0 1px 1px rgb(0 0 0 / 20%), 0 2px 0 0 rgb(255 255 255 / 70%) inset; color: #333; display: inline-block; font-size: 0.85em; font-weight: 700; line-height: 1; vertical-align: middle; padding: 2px 4px; white-space: nowrap; } @media only screen and (max-width: 812px), (orientation: portrait) or (max-aspect-ratio: 4/3) { h1 { font-size: 4rem; } h2 { font-size: 2rem; } .input-container { align-items: start; display: flex; flex-direction: column; width: 100%; row-gap: 5px; } .input-container > input[type="checkbox"] { width: initial; } .input-container > * { width: 100%; /* These two prevent blow-out of the input elements */ display: block; box-sizing: border-box; } } .ready-check-box-wrapper { display: flex; align-self: center; } .ready-check-box { padding: 0.5rem 1rem 0.5rem 1rem; background-color: var(--component-base-color); border-radius: var(--component-border-radius); } .ready-check-box:has(input[type="checkbox"]:checked) { background-color: rgb(255, 224, 66); } .ready-needed, .ready-count { font-family: monospace; font-size: 1rem; } #lobby-header { grid-column-start: 1; grid-column-end: 4; grid-row: 1; display: grid; grid-template-columns: 15rem auto 18rem; grid-gap: 5px; } #lobby-header > *, #menu-button-container { background-color: white; height: 100%; align-items: center; padding: 0.1rem 0.2rem; box-sizing: border-box; border-radius: var(--component-border-radius); } #lobby-header-center-element { display: flex; justify-content: center; /* Hack to remove extra space between buttons */ font-size: 0; } #round-container, #time-left { font-size: 1.5rem; align-self: center; display: flex; } #rounds { margin-left: 0.25rem; } #rounds::after { content: "/"; } #time-left-value { min-width: 3rem; width: 3rem; margin-left: 0.25rem; } #word-container { flex: 1; display: flex; justify-content: center; text-align: center; column-gap: 0.5rem; width: 0; overflow-x: hidden; } .word-length-hint { font-family: monospace; font-size: 0.8rem; padding-top: 0.4rem; } .hint-chat-message { white-space: pre; text-wrap-mode: wrap; } .hint-underline { border-bottom: 0.2rem black solid; padding-bottom: 0.1rem; } .hint-revealed { border-bottom: 0.2rem rgb(38, 187, 38) solid; padding-bottom: 0.1rem; } .hint { font-family: monospace; font-weight: bold; font-size: 1.5rem; line-height: 1.4rem; } #lobby { padding: 5px; display: grid; grid-template-columns: 15rem auto 18rem; grid-template-rows: min-content min-content auto; grid-gap: 5px; flex: 1 1; } /* * These two ensure that the drawing board has an aspect ratio of 16/9. * Technically we could make this configurable by setting the padding via JS. */ #drawing-board-wrapper { width: 100%; height: 0; padding-top: 56.25%; position: relative; grid-column: 2; grid-row: 2; } #drawing-board-inner-wrapper { position: absolute; top: 0; right: 0; bottom: 0; left: 0; } #drawing-board { position: absolute; background-color: white; width: 100%; height: 100%; user-select: none; border-radius: var(--component-border-radius); } #center-dialogs { /* Without these two, drawing is impossible, since this container catches all events. */ pointer-events: none; touch-action: none; position: absolute; width: 100%; height: 100%; z-index: 20; display: flex; justify-content: center; align-items: center; } .center-dialog { /* All dialogs are initially invisible. */ visibility: hidden; /* Since the parent ignores all of those events, we need to restore the handling, since our dialogs have buttons. */ pointer-events: all; touch-action: auto; /* Allows layering, since there can be more than one dialog. */ position: absolute; /* A dialog should never fully hide the canvas. */ max-width: 80%; max-height: 80%; background-color: rgb(225, 221, 221); padding: 1rem; display: flex; flex-direction: column; justify-content: center; align-items: center; overflow: hidden; border-radius: var(--component-border-radius); } .center-dialog-content { overflow: auto; flex: 1; width: 100%; justify-content: center; display: flex; } #chat { display: flex; flex-direction: column; grid-column: 3; grid-row-start: 2; grid-row-end: 3; height: 0; min-height: 100%; } #message-container { overflow-y: scroll; background-color: white; flex: 1; border-radius: var(--component-border-radius) var(--component-border-radius) 0 0; } .chat-name { font-weight: bold; padding-right: 0.2em; } .chat-name:after { content: ":"; } .correct-guess-message { font-weight: bold; color: rgb(38, 187, 38); } .correct-guess-message-other-player { font-weight: bold; color: rgb(231 198 32); } .non-guessing-player-message { color: rgb(38, 187, 38); } .close-guess-message { font-weight: bold; color: rgb(25, 166, 166); } #message-input { padding: 10px; margin-top: 5px; border: 0; border-radius: 0 0 var(--component-border-radius) var(--component-border-radius); } .dialog-title { margin-bottom: 1rem; font-size: 2.75rem; font-weight: bold; color: rgb(240, 105, 127); text-align: center; } #word-button-container { display: grid; grid-template-columns: repeat(3, 1fr); margin-left: 20px; margin-right: 20px; gap: 0.5rem; align-self: stretch; } @media only screen and (max-width: 600px) { #word-button-container { grid-template-columns: repeat(2, 1fr); } } .dialog-button { border: none; background-color: var(--component-base-color); padding: 0.5rem 1rem 0.5rem 1rem; } .button-bar { display: flex; align-items: stretch; justify-content: center; margin-top: 1em; gap: 0.25rem; } .line-width-button-content:hover { background-color: var(--component-hover-background); } .header-button { padding: 0.2rem; background-color: transparent; user-select: none; } .header-button-image { width: 1.7rem; height: 1.7rem; /** Without these two, the button has too much height. */ display: inline-block; vertical-align: middle; } .dot { background-color: var(--dot-color); border: 1px solid black; border-radius: 50%; } .line-width-button-content { width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; background-color: var(--component-base-color); } .line-width-button-content > *, .canvas-button > * { width: 40px; height: 40px; } .line-width-button:checked + .line-width-button-content { background-color: var(--component-active-background); } .canvas-button { height: 50px; width: 50px; border: 0; padding: 0; } .canvas-button > img { display: inline-block; vertical-align: middle; } .canvas-button::-moz-focus-inner { border: 0; } .color-button-container { border: 1px solid gray; display: flex; flex-direction: column; height: 48px; border-radius: var(--component-border-radius); overflow: hidden; } .color-button-row { display: flex; flex-direction: row; } .color-button { height: 24px; width: 24px; border: 0; border-radius: 0; } .color-button::-moz-focus-inner { border: 0; } .message { overflow-wrap: break-word; padding: 0.3em 0.2em 0.2em 0.3em; } .message:nth-child(2n) { background-color: rgb(240, 238, 238); } .system-message { font-weight: bold; color: red; } #toolbox { display: flex; flex-direction: row; flex-wrap: wrap; grid-row: 3; grid-column: 2 / 4; height: min-content; user-select: none; column-gap: 10px; row-gap: 5px; } .toolbox-group { align-self: flex-start; } .pencil-sizes-container { display: flex; gap: 2.5px; } .line-width-button-content { border-radius: var(--component-border-radius); } #player-container { display: flex; flex-direction: column; grid-column: 1; grid-row: 2; overflow-y: auto; height: 0; min-height: 100%; } .player { background-color: rgb(255, 255, 255); padding: 0.2rem; display: grid; grid-template-columns: fit-content(100%) auto; grid-template-rows: 1fr 1fr; border-radius: var(--component-border-radius); } .player + .player { margin-top: 5px; } .playername { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; flex: 1; } .playername-self { font-weight: bold; } .player-done { background-color: rgb(141, 224, 15); } .player-ready { background-color: rgb(255, 224, 66); } .rank { display: flex; grid-row-start: 1; grid-row-end: 3; justify-content: center; align-items: center; width: 2.5rem; font-size: 1.5rem; } .playerscore-group { display: flex; flex-direction: row; align-items: center; } .score-and-status { display: flex; flex-direction: row; justify-content: space-between; } .last-turn-score { font-size: 0.8rem; color: lightslategray; padding-left: 0.2rem; } #kick-dialog-players { flex: 1; } .kick-player-button { width: 100%; } .kick-player-button + .kick-player-button { margin-top: 0.5rem; } .gameover-scoreboard-entry { font-size: 1.3rem; padding: 0.3rem 1rem 0.3rem 1rem; display: flex; flex-direction: row; background-color: rgb(245, 245, 245); } .gameover-scoreboard-entry + .gameover-scoreboard-entry { margin-top: 0.5rem; } .gameover-scoreboard-entry-self { font-weight: bold; } .gameover-scoreboard-entry:last-child { margin-bottom: 1rem; } .gameover-scoreboard-rank { margin-right: 1rem; } .gameover-scoreboard-name { flex: 1; text-align: center; } .gameover-scoreboard-score { margin-left: 1rem; } #force-restart-button { display: none; } #reconnect-dialog { /* As this dialog is very important, it should always be on the top. */ z-index: 100; } .namechange-field { width: 100%; height: 100%; box-sizing: border-box; padding: 0.35rem; } #waitchoose-drawer { font-weight: bold; } @media only screen and (max-width: 812px) and (orientation: landscape) { html { font-size: 0.8rem; } #lobby-header, #lobby { grid-template-columns: 12rem auto 15rem; } } @media only screen and (max-width: 812px) { .center-dialog { padding: 0.5rem; } .button-bar { margin-top: 0.5em; } .dialog-title { font-size: 1.75rem; } .color-button-container { height: 38px; } .color-button { width: 19px; height: 19px; } .canvas-button, .line-width-button-content { width: 40px; height: 40px; } .line-width-button-content > *, .canvas-button > * { width: 32px; height: 32px; } } @media only screen and (max-width: 812px) and (not (orientation: landscape)) { #message-container { max-height: 5rem; } } @media only screen and (orientation: portrait), (max-aspect-ratio: 4/3) { #lobby { grid-template-columns: 2fr 3fr; grid-template-rows: min-content min-content min-content auto; } #lobby-header { background-color: transparent; display: grid; grid-column-end: 3; grid-column-start: 1; grid-gap: 5px; grid-row: 1; grid-template-columns: 1fr auto 1fr; grid-template-rows: auto auto; } #lobby-header-center-element { display: contents; } #menu-button-container { grid-column: 2; grid-row: 1; display: flex; justify-content: center; } #round-container { grid-column: 1; grid-row: 1; justify-content: flex-start; } #time-left { grid-column: 3; grid-row: 1; justify-content: flex-end; } #word-container { grid-column: 1 / 4; grid-row: 2; background-color: white; align-items: center; padding: 0.1rem 0.2rem; border-radius: var(--component-border-radius); column-gap: 0.2rem; width: auto; min-width: 0; overflow: visible; } #round-container, #time-left { font-size: 1.1rem; } #time-left-value { min-width: 2.4rem; width: 2.4rem; } .header-button-image { width: 1.2rem; height: 1.2rem; } .hint { font-size: 1.1rem; line-height: 1.1rem; } .hint-underline { border-bottom-width: 0.15rem; } #drawing-board-wrapper { grid-column-start: 1; grid-column-end: 3; grid-row: 2; } #toolbox { grid-row: 3; grid-column-start: 1; grid-column-end: 3; column-gap: 5px; } #player-container { grid-column: 1; grid-row: 4; height: auto; min-height: auto; } #chat { grid-column: 2; grid-row: 4; height: 0; min-height: 100%; } } #menu-button-container { position: relative; } #menu-button { anchor-name: menu-anchor; } #menu { position-anchor: menu-anchor; position-area: bottom span-right; position-try-fallbacks: flip-block, flip-inline; margin: 0; inset: auto; border: 1px solid gray; border-radius: var(--component-border-radius); } .menu-list { display: flex; flex-direction: column; gap: 5px; padding: 5px; } .menu-item { display: flex; align-items: center; flex-direction: row; gap: 10px; font-size: 1rem !important; } ================================================ FILE: internal/frontend/resources/root.css ================================================ :root { --pane-background: #eee5e9; --component-base-color: #ffffff; --component-hover-background: rgb(250, 211, 252) !important; --component-hover-lighter-background: rgb(252, 231, 253) !important; --component-focus-background: rgb(244, 183, 247); --component-active-background: rgb(192, 58, 200); --component-border-radius: 0.5rem; font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; color: #222; font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; } * { outline: none; } html, body { min-height: 100vh; } body, body::backdrop, body:fullscreen { margin: 0; background: linear-gradient( 90deg, rgba(46, 46, 175, 1) 0%, rgba(37, 79, 191, 1) 42%, rgba(0, 170, 255, 1) 100% ); } body::before { content: " "; position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; opacity: 0.5; background: var(--scribble-background) repeat; background-size: 400px 400px; background-repeat: repeat; z-index: -1; } footer, .help-footer { display: flex; justify-content: center; align-items: center; gap: 1rem; } footer { padding: 0.1rem; background-color: lightslategray; color: white; } .help-footer { flex-wrap: wrap; } a:link, a:visited { color: inherit; } a:hover { text-decoration: underline; } h1, h2 { margin: 0; text-align: center; color: rgb(248, 148, 164); } h1 { font-size: 6rem; } h2 { font-size: 4rem; } ul { margin: 0; } select, input, button, textarea { background-color: var(--component-base-color); color: inherit; border-radius: var(--component-border-radius); border: 2px hidden; } input:hover, button:hover, select:hover, textarea:hover { background-color: var(--component-hover-background); } input:focus, button:focus, select:focus, textarea:focus { background-color: var(--component-focus-background); } button:active { background-color: var(--component-active-background); } input, select { padding-left: 0.35rem; padding-right: 0.35rem; } textarea { padding-left: 0.4rem; padding-top: 0.2rem; min-width: 0; resize: none; } #app { display: flex; flex-direction: column; min-height: 100vh; } .noscript { display: flex; font-size: 2.5rem; font-weight: bold; justify-content: center; border-bottom: 1rem solid black; padding: 10px; } ================================================ FILE: internal/frontend/templates/error.html ================================================ {{define "error-page"}} Scribble.rs - Error {{template "non-static-css-decl" .}} {{template "favicon-decl" .}}

(◕︿◕✿)

{{.ErrorMessage}}

{{.Translation.Get "click-to-homepage"}}
{{template "footer" .}}
{{end}} ================================================ FILE: internal/frontend/templates/favicon.html ================================================ {{define "favicon-decl"}} {{end}} ================================================ FILE: internal/frontend/templates/footer.html ================================================ {{define "footer"}} {{if eq .Version "dev"}} {{.Version}} {{else if ne .Commit ""}} {{.Version}} {{else}} {{.Version}} {{end}} {{if ne .Translation nil}} {{.Translation.Get "source-code"}} {{.Translation.Get "help"}} {{.Translation.Get "submit-feedback"}} {{.Translation.Get "stats"}} {{end}} {{end}} ================================================ FILE: internal/frontend/templates/index.html ================================================ {{define "index"}} Scribble.rs {{if not .AllowIndexing}} {{end}} {{if ne "" .RootURL}} {{end}} {{template "non-static-css-decl" .}} {{template "favicon-decl" .}}
{{.Translation.Get "create-lobby"}}
{{if .Errors}}
{{range .Errors}}
{{.}}
{{end}}
{{end}}
{{.Translation.Get "join-lobby"}}
{{template "footer" .}}
{{end}} ================================================ FILE: internal/frontend/templates/lobby.html ================================================ {{define "lobby-page"}} Scribble.rs - Game {{template "non-static-css-decl" .}} {{template "favicon-decl" .}}
{{.Translation.Get
{{.Translation.Get "choose-a-word"}}
{{.Translation.Get "word-choice-warning"}}:
{{.Translation.Get "start-the-game"}}
{{.Translation.Get "change-your-name"}}:
{{.Translation.Get "waiting-for-word-selection"}}
 {{.Translation.Get "is-choosing-word"}}
{{.Translation.Get "change-your-name"}}
{{.Translation.Get "change-lobby-settings-title"}}
{{.Translation.Get "drawing-time-setting"}} {{.Translation.Get "rounds-setting"}} {{.Translation.Get "max-players-setting"}} {{.Translation.Get "public-lobby-setting"}} {{.Translation.Get "words-per-turn-setting"}} {{.Translation.Get "custom-words-per-turn-setting"}} {{.Translation.Get "players-per-ip-limit-setting"}}
Game over!
{{.Translation.Get "votekick-a-player"}}
{{end}} ================================================ FILE: internal/frontend/templates/non-static-css.html ================================================ {{/* A little hack so we need don't to have CSS templates and embed those directly. */}} {{/* The reason being that we need to be able to define the RootPath here. */}} {{define "non-static-css-decl"}} {{end}} ================================================ FILE: internal/frontend/templating_test.go ================================================ package frontend import ( "bytes" "testing" "github.com/scribble-rs/scribble.rs/internal/api" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/translations" "github.com/stretchr/testify/require" ) func Test_templateLobbyPage(t *testing.T) { t.Parallel() var buffer bytes.Buffer err := pageTemplates.ExecuteTemplate(&buffer, "lobby-page", &lobbyPageData{ BasePageConfig: &BasePageConfig{ checksums: make(map[string]string), }, LobbyData: &api.LobbyData{ SettingBounds: config.Default.LobbySettingBounds, GameConstants: api.GameConstantsData, }, Translation: translations.DefaultTranslation, }) if err != nil { t.Errorf("Error templating: %s", err) } } func Test_templateErrorPage(t *testing.T) { t.Parallel() var buffer bytes.Buffer err := pageTemplates.ExecuteTemplate(&buffer, "error-page", &errorPageData{ BasePageConfig: &BasePageConfig{}, ErrorMessage: "KEK", Translation: translations.DefaultTranslation, Locale: "en-US", }) if err != nil { t.Errorf("Error templating: %s", err) } } func Test_templateIndexPage(t *testing.T) { t.Parallel() handler, err := NewHandler(&config.Config{}) require.NoError(t, err) createPageData := handler.createDefaultIndexPageData() createPageData.Translation = translations.DefaultTranslation var buffer bytes.Buffer if err := pageTemplates.ExecuteTemplate(&buffer, "index", createPageData); err != nil { t.Errorf("Error templating: %s", err) } } ================================================ FILE: internal/game/data.go ================================================ package game import ( "strings" "sync" "time" discordemojimap "github.com/Bios-Marcel/discordemojimap/v2" "github.com/gofrs/uuid/v5" "github.com/lxzan/gws" "golang.org/x/text/cases" ) // slotReservationTime should give a player enough time to restart their browser // without losing their slost. const slotReservationTime = time.Minute * 1 type roundEndReason string const ( drawerDisconnected roundEndReason = "drawer_disconnected" guessersDisconnected roundEndReason = "guessers_disconnected" ) // Lobby represents a game session. It must not be sent via the API, as it // exposes gameplay relevant information. type Lobby struct { // ID uniquely identified the Lobby. LobbyID string EditableLobbySettings // DrawingTimeNew is the new value of the drawing time. If a round is // already ongoing, we can't simply change the drawing time, as it would // screw with the score calculation of the current turn. DrawingTimeNew int CustomWords []string // customWordIndex is used to keep track of the next word to be drawn from // the custom word stack. Only used if exclusive custom word mode is active. customWordIndex int words []string // players references all participants of the Lobby. players []*Player // Whether the game has started, is ongoing or already over. State State // OwnerID references the Player that currently owns the lobby. // Meaning this player has rights to restart or change certain settings. OwnerID uuid.UUID // ScoreCalculation decides how scores for both guessers and drawers are // determined. ScoreCalculation ScoreCalculation // CurrentWord represents the word that was last selected. If no word has // been selected yet or the round is already over, this should be empty. CurrentWord string // wordHints for the current word. wordHints []*WordHint // wordHintsShown are the same as wordHints with characters visible. wordHintsShown []*WordHint // hintsLeft is the amount of hints still available for revelation. hintsLeft int // hintCount is the amount of hints that were initially available // for revelation. hintCount int // Round is the round that the Lobby is currently in. This is a number // between 0 and Rounds. 0 indicates that it hasn't started yet. Round int wordChoiceEndTime time.Time preSelectedWord int // wordChoice represents the current choice of words present to the drawer. wordChoice []string Wordpack string // roundEndTime represents the time at which the current round will end. // This is a UTC unix-timestamp in milliseconds. roundEndTime int64 roundEndReason roundEndReason timeLeftTicker *time.Ticker // currentDrawing represents the state of the current canvas. The elements // consist of LineEvent and FillEvent. Please do not modify the contents // of this array an only move AppendLine and AppendFill on the respective // lobby object. currentDrawing []any // These variables are used to define the ranges of connected drawing events. // For example a line that has been drawn or a fill that has been executed. // Since we can't trust the client to tell us this, we use the time passed // between draw events as an indicator of which draw events make up one line. // An alternative approach could be using the coordinates and see if they are // connected, but that could technically undo a whole drawing. lastDrawEvent time.Time connectedDrawEventsIndexStack []int lowercaser cases.Caser // LastPlayerDisconnectTime is used to know since when a lobby is empty, in case // it is empty. LastPlayerDisconnectTime *time.Time mutex sync.Mutex IsWordpackRtl bool WriteObject func(*Player, any) error WritePreparedMessage func(*Player, *gws.Broadcaster) error } // MaxPlayerNameLength defines how long a string can be at max when used // as the playername. const MaxPlayerNameLength int = 30 // GetLastKnownAddress returns the last known IP-Address used for an HTTP request. func (player *Player) GetLastKnownAddress() string { return player.lastKnownAddress } // SetLastKnownAddress sets the last known IP-Address used for an HTTP request. // Can be retrieved via GetLastKnownAddress(). func (player *Player) SetLastKnownAddress(address string) { player.lastKnownAddress = address } // GetWebsocket simply returns the players websocket connection. This method // exists to encapsulate the websocket field and prevent accidental sending // the websocket data via the network. func (player *Player) GetWebsocket() *gws.Conn { return player.ws } // SetWebsocket sets the given connection as the players websocket connection. func (player *Player) SetWebsocket(socket *gws.Conn) { player.ws = socket } // GetUserSession returns the players current user session. func (player *Player) GetUserSession() uuid.UUID { return player.userSession } type PlayerState string const ( Guessing PlayerState = "guessing" Drawing PlayerState = "drawing" Standby PlayerState = "standby" Ready PlayerState = "ready" Spectating PlayerState = "spectating" ) func (lobby *Lobby) GetPlayerByID(id uuid.UUID) *Player { for _, player := range lobby.players { if player.ID == id { return player } } return nil } func (lobby *Lobby) GetPlayerBySession(userSession uuid.UUID) *Player { for _, player := range lobby.players { if player.userSession == userSession { return player } } return nil } func (lobby *Lobby) GetOwner() *Player { return lobby.GetPlayerByID(lobby.OwnerID) } func (lobby *Lobby) ClearDrawing() { lobby.currentDrawing = make([]any, 0) lobby.connectedDrawEventsIndexStack = nil } // AppendLine adds a line direction to the current drawing. This exists in order // to prevent adding arbitrary elements to the drawing, as the backing array is // an empty interface type. func (lobby *Lobby) AppendLine(line *LineEvent) { lobby.currentDrawing = append(lobby.currentDrawing, line) } // AppendFill adds a fill direction to the current drawing. This exists in order // to prevent adding arbitrary elements to the drawing, as the backing array is // an empty interface type. func (lobby *Lobby) AppendFill(fill *FillEvent) { lobby.currentDrawing = append(lobby.currentDrawing, fill) } // SanitizeName removes invalid characters from the players name, resolves // emoji codes, limits the name length and generates a new name if necessary. func SanitizeName(name string) string { // We trim and handle emojis beforehand to avoid taking this into account // when checking the name length, so we don't cut off too much of the name. newName := discordemojimap.Replace(strings.TrimSpace(name)) // We don't want super-long names if len(newName) > MaxPlayerNameLength { return newName[:MaxPlayerNameLength+1] } if newName != "" { return newName } return generatePlayerName() } // GetConnectedPlayerCount returns the amount of player that have currently // established a socket connection. func (lobby *Lobby) GetConnectedPlayerCount() int { var count int for _, player := range lobby.players { if player.Connected { count++ } } return count } func (lobby *Lobby) HasConnectedPlayers() bool { lobby.mutex.Lock() defer lobby.mutex.Unlock() for _, otherPlayer := range lobby.players { if otherPlayer.Connected { return true } } return false } // CanIPConnect checks whether the IP is still allowed regarding the lobbies // clients per IP address limit. This function should only be called for // players that aren't already in the lobby. func (lobby *Lobby) CanIPConnect(address string) bool { var clientsWithSameIP int for _, player := range lobby.GetPlayers() { if player.GetLastKnownAddress() == address { clientsWithSameIP++ if clientsWithSameIP >= lobby.ClientsPerIPLimit { return false } } } return true } func (lobby *Lobby) IsPublic() bool { return lobby.Public } func (lobby *Lobby) GetPlayers() []*Player { return lobby.players } // GetOccupiedPlayerSlots counts the available slots which can be taken by new // players. Whether a slot is available is determined by the player count and // whether a player is disconnect or furthermore how long they have been // disconnected for. Therefore the result of this function will differ from // Lobby.GetConnectedPlayerCount. func (lobby *Lobby) GetOccupiedPlayerSlots() int { var occupiedPlayerSlots int now := time.Now() for _, player := range lobby.players { if player.Connected { occupiedPlayerSlots++ } else { disconnectTime := player.disconnectTime // If a player hasn't been disconnected for a certain // timeframe, we will reserve the slot. This avoids frustration // in situations where a player has to restart their PC or so. if disconnectTime == nil || now.Sub(*disconnectTime) < slotReservationTime { occupiedPlayerSlots++ } } } return occupiedPlayerSlots } // HasFreePlayerSlot determines whether the lobby still has a slot for at // least one more player. If a player has disconnected recently, the slot // will be preserved for 5 minutes. This function should be used over // Lobby.GetOccupiedPlayerSlots, as it is potentially faster. func (lobby *Lobby) HasFreePlayerSlot() bool { if len(lobby.players) < lobby.MaxPlayers { return true } return lobby.GetOccupiedPlayerSlots() < lobby.MaxPlayers } // Synchronized allows running a function while keeping the lobby locked via // it's own mutex. This is useful in order to avoid having to relock a lobby // multiple times, which might cause unexpected inconsistencies. func (lobby *Lobby) Synchronized(logic func()) { lobby.mutex.Lock() defer lobby.mutex.Unlock() logic() } ================================================ FILE: internal/game/data_test.go ================================================ package game import ( "testing" "time" ) func TestOccupiedPlayerCount(t *testing.T) { t.Parallel() lobby := &Lobby{} if lobby.GetOccupiedPlayerSlots() != 0 { t.Errorf("Occupied player count expected to be 0, but was %d", lobby.GetOccupiedPlayerSlots()) } // While disconnect, there's no disconnect time, which we count as occupied. lobby.players = append(lobby.players, &Player{}) if lobby.GetOccupiedPlayerSlots() != 1 { t.Errorf("Occupied player count expected to be 1, but was %d", lobby.GetOccupiedPlayerSlots()) } lobby.players = append(lobby.players, &Player{ Connected: true, }) if lobby.GetOccupiedPlayerSlots() != 2 { t.Errorf("Occupied player count expected to be 2, but was %d", lobby.GetOccupiedPlayerSlots()) } disconnectedPlayer := &Player{ Connected: false, } lobby.players = append(lobby.players, disconnectedPlayer) if lobby.GetOccupiedPlayerSlots() != 3 { t.Errorf("Occupied player count expected to be 3, but was %d", lobby.GetOccupiedPlayerSlots()) } now := time.Now() disconnectedPlayer.disconnectTime = &now if lobby.GetOccupiedPlayerSlots() != 3 { t.Errorf("Occupied player count expected to be 3, but was %d", lobby.GetOccupiedPlayerSlots()) } past := time.Now().AddDate(-1, 0, 0) disconnectedPlayer.disconnectTime = &past if lobby.GetOccupiedPlayerSlots() != 2 { t.Errorf("Occupied player count expected to be 2, but was %d", lobby.GetOccupiedPlayerSlots()) } } ================================================ FILE: internal/game/lobby.go ================================================ package game import ( json "encoding/json" "errors" "fmt" "log" "math" "math/rand/v2" "sort" "strings" "time" "unicode/utf8" "github.com/lxzan/gws" "github.com/scribble-rs/scribble.rs/internal/sanitize" discordemojimap "github.com/Bios-Marcel/discordemojimap/v2" petname "github.com/Bios-Marcel/go-petname" "github.com/gofrs/uuid/v5" ) var SupportedScoreCalculations = []string{ "chill", "competitive", } var SupportedLanguages = map[string]string{ "custom": "Custom words only", "english_gb": "English (GB)", "english": "English (US)", "italian": "Italian", "german": "German", "french": "French", "dutch": "Dutch", "ukrainian": "Ukrainian", "russian": "Russian", "polish": "Polish", "arabic": "Arabic", "hebrew": "Hebrew", "persian": "Persian", } const ( DrawingBoardBaseWidth = 1600 DrawingBoardBaseHeight = 900 MinBrushSize = 8 MaxBrushSize = 32 ) // SettingBounds defines the lower and upper bounds for the user-specified // lobby creation input. type SettingBounds struct { MinDrawingTime int `json:"minDrawingTime" env:"MIN_DRAWING_TIME"` MaxDrawingTime int `json:"maxDrawingTime" env:"MAX_DRAWING_TIME"` MinRounds int `json:"minRounds" env:"MIN_ROUNDS"` MaxRounds int `json:"maxRounds" env:"MAX_ROUNDS"` MinMaxPlayers int `json:"minMaxPlayers" env:"MIN_MAX_PLAYERS"` MaxMaxPlayers int `json:"maxMaxPlayers" env:"MAX_MAX_PLAYERS"` MinClientsPerIPLimit int `json:"minClientsPerIpLimit" env:"MIN_CLIENTS_PER_IP_LIMIT"` MaxClientsPerIPLimit int `json:"maxClientsPerIpLimit" env:"MAX_CLIENTS_PER_IP_LIMIT"` MinCustomWordsPerTurn int `json:"minCustomWordsPerTurn" env:"MIN_CUSTOM_WORDS_PER_TURN"` // MaxWordsPerTurn is now used for max words in general, as both amount of words and custom // can be configured now. MaxWordsPerTurn int `json:"maxWordsPerTurn" env:"MAX_WORDS_PER_TURN"` MinWordsPerTurn int `json:"minWordsPerTurn" env:"MIN_WORDS_PER_TURN"` } func (lobby *Lobby) HandleEvent(eventType string, payload []byte, player *Player) error { if eventType == EventTypeKeepAlive { // This is a known dummy event in order to avoid accidental websocket // connection closure. However, no action is required on the server. // Either way, we needn't needlessly lock the lobby. return nil } lobby.mutex.Lock() defer lobby.mutex.Unlock() // For all followup unmarshalling of the already unmarshalled Event, we // use mapstructure instead. It's cheaper in terms of CPU usage and // memory usage. There are benchmarks to prove this in json_test.go. if eventType == EventTypeToggleSpectate { player.SpectateToggleRequested = !player.SpectateToggleRequested if player.SpectateToggleRequested && lobby.State != Ongoing { if player.State == Spectating { player.State = Standby } else { player.State = Spectating } // Since we apply the state instantly, we reset it instantly as // well. player.SpectateToggleRequested = false } lobby.Broadcast(&Event{Type: EventTypeUpdatePlayers, Data: lobby.players}) } else if eventType == EventTypeMessage { var message StringDataEvent if err := json.Unmarshal(payload, &message); err != nil { return fmt.Errorf("invalid data received: '%s'", string(payload)) } handleMessage(message.Data, player, lobby) } else if eventType == EventTypeLine { if lobby.canDraw(player) { var line LineEvent if err := json.Unmarshal(payload, &line); err != nil { return fmt.Errorf("error decoding data: %w", err) } // In case the line is too big, we overwrite the data of the event. // This will prevent clients from lagging due to too thick lines. if line.Data.Width > MaxBrushSize { line.Data.Width = MaxBrushSize } else if line.Data.Width < MinBrushSize { line.Data.Width = MinBrushSize } now := time.Now() if now.Sub(lobby.lastDrawEvent) > 150*time.Millisecond || lobby.wasLastDrawEventFill() { lobby.connectedDrawEventsIndexStack = append(lobby.connectedDrawEventsIndexStack, len(lobby.currentDrawing)) } lobby.lastDrawEvent = now lobby.AppendLine(&line) // We directly forward the event, as it seems to be valid. lobby.broadcastConditional(&line, ExcludePlayer(player)) } } else if eventType == EventTypeFill { if lobby.canDraw(player) { var fill FillEvent if err := json.Unmarshal(payload, &fill); err != nil { return fmt.Errorf("error decoding data: %w", err) } lobby.connectedDrawEventsIndexStack = append(lobby.connectedDrawEventsIndexStack, len(lobby.currentDrawing)) lobby.lastDrawEvent = time.Now() lobby.AppendFill(&fill) // We directly forward the event, as it seems to be valid. lobby.broadcastConditional(&fill, ExcludePlayer(player)) } } else if eventType == EventTypeClearDrawingBoard { if lobby.canDraw(player) && len(lobby.currentDrawing) > 0 { lobby.ClearDrawing() lobby.broadcastConditional( EventTypeOnly{Type: EventTypeClearDrawingBoard}, ExcludePlayer(player)) } } else if eventType == EventTypeUndo { if lobby.canDraw(player) && len(lobby.currentDrawing) > 0 && len(lobby.connectedDrawEventsIndexStack) > 0 { undoFrom := lobby.connectedDrawEventsIndexStack[len(lobby.connectedDrawEventsIndexStack)-1] lobby.connectedDrawEventsIndexStack = lobby.connectedDrawEventsIndexStack[:len(lobby.connectedDrawEventsIndexStack)-1] if undoFrom < len(lobby.currentDrawing) { lobby.currentDrawing = lobby.currentDrawing[:undoFrom] lobby.Broadcast(&Event{Type: EventTypeDrawing, Data: lobby.currentDrawing}) } } } else if eventType == EventTypeChooseWord { var wordChoice IntDataEvent if err := json.Unmarshal(payload, &wordChoice); err != nil { return fmt.Errorf("error decoding data: %w", err) } if player.State == Drawing { if err := lobby.selectWord(wordChoice.Data); err != nil { return err } } } else if eventType == EventTypeKickVote { var kickEvent StringDataEvent if err := json.Unmarshal(payload, &kickEvent); err != nil { return fmt.Errorf("invalid data received: '%s'", string(payload)) } toKickID, err := uuid.FromString(kickEvent.Data) if err != nil { return fmt.Errorf("invalid data in kick-vote event: %v", payload) } handleKickVoteEvent(lobby, player, toKickID) } else if eventType == EventTypeToggleReadiness { lobby.handleToggleReadinessEvent(player) } else if eventType == EventTypeStart { if lobby.State != Ongoing && player.ID == lobby.OwnerID { lobby.startGame() } } else if eventType == EventTypeNameChange { var message StringDataEvent if err := json.Unmarshal(payload, &message); err != nil { return fmt.Errorf("invalid data received: '%s'", string(payload)) } handleNameChangeEvent(player, lobby, message.Data) } else if eventType == EventTypeRequestDrawing { // Since the client shouldn't be blocking to wait for the drawing, it's // fine to emit the event if there's no drawing. if len(lobby.currentDrawing) != 0 { _ = lobby.WriteObject(player, Event{Type: EventTypeDrawing, Data: lobby.currentDrawing}) } } return nil } func (lobby *Lobby) handleToggleReadinessEvent(player *Player) { if lobby.State != Ongoing && player.State != Spectating { if player.State != Ready { player.State = Ready } else { player.State = Standby } if lobby.readyToStart() { lobby.startGame() } else { lobby.Broadcast(&Event{Type: EventTypeUpdatePlayers, Data: lobby.players}) } } } func (lobby *Lobby) readyToStart() bool { // Otherwise the game will start and gameover instantly. This can happen // if a lobby is created and the owner refreshes. var hasConnectedPlayers bool for _, otherPlayer := range lobby.players { if !otherPlayer.Connected { continue } if otherPlayer.State != Ready { return false } hasConnectedPlayers = true } return hasConnectedPlayers } func isRatelimited(sender *Player) bool { if sender.messageTimestamps.size < 5 { return false } oldest := sender.messageTimestamps.Oldest() latest := sender.messageTimestamps.Latest() if latest.Sub(oldest) >= time.Second*3 { return false } return true } func handleMessage(message string, sender *Player, lobby *Lobby) { // No matter whether the message is send, we'll make ratelimitting take place. sender.messageTimestamps.Push(time.Now()) // Very long message can cause lags and can therefore be easily abused. // While it is debatable whether a 10000 byte (not character) long // message makes sense, this is technically easy to manage and therefore // allowed for now. if len(message) > 10000 { return } trimmedMessage := strings.TrimSpace(message) // Empty message can neither be a correct guess nor are useful for // other players in the chat. if trimmedMessage == "" { return } // Rate limitting is silent, we will pretend the message was sent, but not show any other players. // Additionally, both close and correct guesses will be ignored. if isRatelimited(sender) { if sender.State != Guessing && lobby.CurrentWord != "" { _ = lobby.WriteObject(sender, newMessageEvent(EventTypeNonGuessingPlayerMessage, trimmedMessage, sender)) } else { _ = lobby.WriteObject(sender, newMessageEvent(EventTypeMessage, trimmedMessage, sender)) } return } // If no word is currently selected, all players can talk to each other // and we don't have to check for corrected guesses. if lobby.CurrentWord == "" { lobby.broadcastMessage(trimmedMessage, sender) return } if sender.State != Guessing { lobby.broadcastConditional( newMessageEvent(EventTypeNonGuessingPlayerMessage, trimmedMessage, sender), IsAllowedToSeeRevealedHints, ) return } normInput := sanitize.CleanText(lobby.lowercaser.String(trimmedMessage)) normSearched := sanitize.CleanText(lobby.CurrentWord) switch CheckGuess(normInput, normSearched) { case EqualGuess: { sender.LastScore = lobby.calculateGuesserScore() sender.Score += sender.LastScore sender.State = Standby lobby.Broadcast(&Event{Type: EventTypeCorrectGuess, Data: sender.ID}) if !lobby.isAnyoneStillGuessing() { advanceLobby(lobby) } else { // Since the word has been guessed correctly, we reveal it. _ = lobby.WriteObject(sender, Event{Type: EventTypeUpdateWordHint, Data: lobby.wordHintsShown}) recalculateRanks(lobby) lobby.Broadcast(&Event{Type: EventTypeUpdatePlayers, Data: lobby.players}) } } case CloseGuess: { // In cases of a close guess, we still send the message to everyone. // This allows other players to guess the word by watching what the // other players are misstyping. lobby.broadcastMessage(trimmedMessage, sender) _ = lobby.WriteObject(sender, Event{Type: EventTypeCloseGuess, Data: trimmedMessage}) } default: lobby.broadcastMessage(trimmedMessage, sender) } } func (lobby *Lobby) wasLastDrawEventFill() bool { if len(lobby.currentDrawing) == 0 { return false } _, isFillEvent := lobby.currentDrawing[len(lobby.currentDrawing)-1].(*FillEvent) return isFillEvent } func (lobby *Lobby) isAnyoneStillGuessing() bool { for _, otherPlayer := range lobby.players { if otherPlayer.State == Guessing && otherPlayer.Connected { return true } } return false } func ExcludePlayer(toExclude *Player) func(*Player) bool { return func(player *Player) bool { return player != toExclude } } func IsAllowedToSeeRevealedHints(player *Player) bool { return player.State == Standby || player.State == Drawing } func IsAllowedToSeeHints(player *Player) bool { return player.State == Guessing || player.State == Spectating } func newMessageEvent(messageType, message string, sender *Player) *Event { return &Event{Type: messageType, Data: OutgoingMessage{ Author: sender.Name, AuthorID: sender.ID, Content: discordemojimap.Replace(message), }} } func (lobby *Lobby) broadcastMessage(message string, sender *Player) { lobby.Broadcast(newMessageEvent(EventTypeMessage, message, sender)) } func (lobby *Lobby) Broadcast(data any) { bytes, err := json.Marshal(data) if err != nil { log.Println("error marshalling Broadcast message", err) return } message := gws.NewBroadcaster(gws.OpcodeText, bytes) for _, player := range lobby.GetPlayers() { lobby.WritePreparedMessage(player, message) } } func (lobby *Lobby) broadcastConditional(data any, condition func(*Player) bool) { var message *gws.Broadcaster for _, player := range lobby.players { if condition(player) { if message == nil { bytes, err := json.Marshal(data) if err != nil { log.Println("error marshalling broadcastConditional message", err) return } // Message is created lazily, since the conditional events could // potentially not be sent at all. The cost of the nil-check is // much lower than the cost of creating the message. message = gws.NewBroadcaster(gws.OpcodeText, bytes) } lobby.WritePreparedMessage(player, message) } } } func (lobby *Lobby) startGame() { // We are reseting each players score, since players could // technically be player a second game after the last one // has already ended. for _, otherPlayer := range lobby.players { otherPlayer.Score = 0 otherPlayer.LastScore = 0 // Everyone has the same score and therefore the same rank. otherPlayer.Rank = 1 } // Cause advanceLobby to start at round 1, starting the game anew. lobby.Round = 0 advanceLobby(lobby) } func handleKickVoteEvent(lobby *Lobby, player *Player, toKickID uuid.UUID) { // Kicking yourself isn't allowed if toKickID == player.ID { return } // A player can't vote twice to kick someone if player.votedForKick[toKickID] { return } playerToKickIndex := -1 for index, otherPlayer := range lobby.players { if otherPlayer.ID == toKickID { playerToKickIndex = index break } } // If we haven't found the player, we can't kick them. if playerToKickIndex == -1 { return } playerToKick := lobby.players[playerToKickIndex] player.votedForKick[toKickID] = true var voteKickCount int for _, otherPlayer := range lobby.players { if otherPlayer.Connected && otherPlayer.votedForKick[toKickID] { voteKickCount++ } } votesRequired := calculateVotesNeededToKick(lobby) // We send the kick event to all players, since it was a valid vote. lobby.Broadcast(&Event{ Type: EventTypeKickVote, Data: &KickVote{ PlayerID: playerToKick.ID, PlayerName: playerToKick.Name, VoteCount: voteKickCount, RequiredVoteCount: votesRequired, }, }) // If the valid vote also happens to be the last vote needed, we kick the player. // Since we send the events to all players beforehand, the target player is automatically // being noteified of his own kick. if voteKickCount >= votesRequired { kickPlayer(lobby, playerToKick, playerToKickIndex) } } // kickPlayer kicks the given player from the lobby, updating the lobby // state and sending all necessary events. func kickPlayer(lobby *Lobby, playerToKick *Player, playerToKickIndex int) { // Avoiding nilpointer in case playerToKick disconnects during this event unluckily. if playerToKickSocket := playerToKick.ws; playerToKickSocket != nil { // 4k-5k is codes not in the spec, they are free to use. playerToKickSocket.WriteClose(4000, nil) } // Since the player is already kicked, we first clean up the kicking information related to that player for _, otherPlayer := range lobby.players { delete(otherPlayer.votedForKick, playerToKick.ID) } // If the owner is kicked, we choose the next best person as the owner. if lobby.OwnerID == playerToKick.ID { for _, otherPlayer := range lobby.players { potentialOwner := otherPlayer if potentialOwner.Connected { lobby.OwnerID = potentialOwner.ID lobby.Broadcast(&Event{ Type: EventTypeOwnerChange, Data: &OwnerChangeEvent{ PlayerID: potentialOwner.ID, PlayerName: potentialOwner.Name, }, }) break } } } if playerToKick.State == Drawing { newDrawer, roundOver := determineNextDrawer(lobby) lobby.players = append(lobby.players[:playerToKickIndex], lobby.players[playerToKickIndex+1:]...) lobby.Broadcast(&EventTypeOnly{Type: EventTypeDrawerKicked}) // Since the drawer has been kicked, that probably means that they were // probably trolling, therefore we redact everyones last earned score. for _, otherPlayer := range lobby.players { otherPlayer.Score -= otherPlayer.LastScore otherPlayer.LastScore = 0 } advanceLobbyPredefineDrawer(lobby, roundOver, newDrawer) } else { lobby.players = append(lobby.players[:playerToKickIndex], lobby.players[playerToKickIndex+1:]...) if lobby.isAnyoneStillGuessing() { // This isn't necessary in case we need to advanced the lobby, as it has // to happen anyways and sending events twice would be wasteful. recalculateRanks(lobby) lobby.Broadcast(&Event{Type: EventTypeUpdatePlayers, Data: lobby.players}) } else { advanceLobby(lobby) } } } func (lobby *Lobby) Drawer() *Player { for _, player := range lobby.players { if player.State == Drawing { return player } } return nil } func calculateVotesNeededToKick(lobby *Lobby) int { connectedPlayerCount := lobby.GetConnectedPlayerCount() // If there are only two players, e.g. none of them should be able to // kick the other. if connectedPlayerCount <= 2 { return 2 } // If the amount of players equals an even number, such as 6, we will always // need half of that. If the amount is uneven, we'll get a floored result. // therefore we always add one to the amount. // examples: // (6+1)/2 = 3 // (5+1)/2 = 3 // Therefore it'll never be possible for a minority to kick a player. return (connectedPlayerCount + 1) / 2 } func handleNameChangeEvent(caller *Player, lobby *Lobby, name string) { oldName := caller.Name newName := SanitizeName(name) // We'll avoid sending the event in this case, as it's useless, but still log // the event, as it might be useful to know that this happened. if oldName != newName { caller.Name = newName lobby.Broadcast(&Event{ Type: EventTypeNameChange, Data: &NameChangeEvent{ PlayerID: caller.ID, PlayerName: newName, }, }) } } func (lobby *Lobby) calculateGuesserScore() int { return lobby.ScoreCalculation.CalculateGuesserScore(lobby) } func (lobby *Lobby) calculateDrawerScore() int { return lobby.ScoreCalculation.CalculateDrawerScore(lobby) } // advanceLobbyPredefineDrawer is required in cases where the drawer is removed // from the game. func advanceLobbyPredefineDrawer(lobby *Lobby, roundOver bool, newDrawer *Player) { if lobby.timeLeftTicker != nil { // We want to create a new ticker later on. By setting the current // ticker to nil, we'll cause the ticker routine to stop the ticker // and then stop itself. Later on we create a new routine. // This way we won't have race conditions or wrongly executed logic. lobby.timeLeftTicker = nil } // The drawer can potentially be null if kicked or the game just started. if drawer := lobby.Drawer(); drawer != nil { newDrawerScore := lobby.calculateDrawerScore() drawer.LastScore = newDrawerScore drawer.Score += newDrawerScore } // We need this for the next-turn / game-over event, in order to allow the // client to know which word was previously supposed to be guessed. previousWord := lobby.CurrentWord lobby.CurrentWord = "" lobby.wordHints = nil if lobby.DrawingTimeNew != 0 { lobby.DrawingTime = lobby.DrawingTimeNew } for _, otherPlayer := range lobby.players { // If the round ends and people are still guessing, that means the // "LastScore" value for the next turn has to be "no score earned". // We also reset spectating players, to prevent any score fuckups. if otherPlayer.State == Guessing || otherPlayer.State == Spectating { otherPlayer.LastScore = 0 } if otherPlayer.SpectateToggleRequested { otherPlayer.SpectateToggleRequested = false if otherPlayer.State != Spectating { otherPlayer.State = Spectating } else { otherPlayer.State = Guessing } continue } if otherPlayer.State == Spectating { continue } // Initially all players are in guessing state, as the drawer gets // defined further at the bottom. otherPlayer.State = Guessing } recalculateRanks(lobby) currentRoundEndReason := lobby.roundEndReason lobby.roundEndReason = "" if roundOver { // Game over, meaning all rounds have been played out. Alternatively // We can reach this state if all players are spectating and or are not // connected anymore. if lobby.Round == lobby.Rounds || newDrawer == nil { lobby.State = GameOver for _, player := range lobby.players { readyData := generateReadyData(lobby, player) // The drawing is always available on the client, as the // game-over event is only sent to already connected players. readyData.CurrentDrawing = nil lobby.WriteObject(player, Event{ Type: EventTypeGameOver, Data: &GameOverEvent{ PreviousWord: previousWord, ReadyEvent: readyData, RoundEndReason: currentRoundEndReason, }, }) } // Omit rest of events, since we don't need to advance. return } lobby.Round++ } lobby.ClearDrawing() newDrawer.State = Drawing lobby.State = Ongoing lobby.wordChoice = GetRandomWords(lobby.WordsPerTurn, lobby) lobby.preSelectedWord = rand.IntN(len(lobby.wordChoice)) wordChoiceDuration := 30 lobby.Broadcast(&Event{ Type: EventTypeNextTurn, Data: &NextTurn{ Round: lobby.Round, Players: lobby.players, ChoiceTimeLeft: wordChoiceDuration * 1000, PreviousWord: previousWord, RoundEndReason: currentRoundEndReason, }, }) lobby.wordChoiceEndTime = time.Now().Add(time.Duration(wordChoiceDuration) * time.Second) lobby.timeLeftTicker = time.NewTicker(1 * time.Second) go startTurnTimeTicker(lobby, lobby.timeLeftTicker) lobby.SendYourTurnEvent(newDrawer) } // advanceLobby will either start the game or jump over to the next turn. func advanceLobby(lobby *Lobby) { newDrawer, roundOver := determineNextDrawer(lobby) advanceLobbyPredefineDrawer(lobby, roundOver, newDrawer) } func (player *Player) desiresToDraw() bool { // If a player is in standby, it would break the gameloop. However, if the // player desired to change anyway, then it is fine. if player.State == Spectating { return player.SpectateToggleRequested } return !player.SpectateToggleRequested } // determineNextDrawer returns the next person that's supposed to be drawing, but // doesn't tell the lobby yet. The boolean signals whether the current round // is over. func determineNextDrawer(lobby *Lobby) (*Player, bool) { for index, player := range lobby.players { if player.State == Drawing { // If we have someone that's drawing, take the next one for i := index + 1; i < len(lobby.players); i++ { nextPlayer := lobby.players[i] if !nextPlayer.desiresToDraw() || !nextPlayer.Connected { continue } return nextPlayer, false } // No player below the current drawer has been found, therefore we // fallback to our default logic at the bottom. break } } // We prefer the first connected player and non-spectating. for _, player := range lobby.players { if !player.desiresToDraw() || !player.Connected { continue } return player, true } // If no player is available, we will simply end the game. return nil, true } // startTurnTimeTicker executes a loop that listens to the lobbies // timeLeftTicker and executes a tickLogic on each tick. This method // blocks until the turn ends. func startTurnTimeTicker(lobby *Lobby, ticker *time.Ticker) { for { <-ticker.C if !lobby.tickLogic(ticker) { ticker.Stop() break } } } const disconnectGrace = 8 * time.Second // tickLogic checks whether the lobby needs to proceed to the next round and // updates the available word hints if required. The return value indicates // whether additional ticks are necessary or not. The ticker is automatically // stopped if no additional ticks are required. func (lobby *Lobby) tickLogic(expectedTicker *time.Ticker) bool { lobby.mutex.Lock() defer lobby.mutex.Unlock() // Since we have a lock on the lobby, we can find out if the ticker we are // listening to is still valid. If not, we want to kill the outer routine. if lobby.timeLeftTicker != expectedTicker { return false } if lobby.shouldEndEarlyDueToDisconnectedDrawer() { lobby.roundEndReason = drawerDisconnected advanceLobby(lobby) return false } if lobby.shouldEndEarlyDueToDisconnectedGuessers() { lobby.roundEndReason = guessersDisconnected advanceLobby(lobby) return false } if lobby.CurrentWord == "" { if lobby.wordChoiceEndTime.Before(time.Now()) { lobby.selectWord(lobby.preSelectedWord) } // This timer previously was only started AFTER a word was chosen, so we'll early exit here. return true } currentTime := getTimeAsMillis() if currentTime >= lobby.roundEndTime { advanceLobby(lobby) return false } if lobby.hintsLeft > 0 && lobby.wordHints != nil { revealHintEveryXMilliseconds := int64(lobby.DrawingTime * 1000 / (lobby.hintCount + 1)) // If you have a drawingtime of 120 seconds and three hints, you // want to reveal a hint every 40 seconds, so that the two hints // are visible for at least a third of the time. //If the word // was chosen at 60 seconds, we'll still reveal one hint // instantly, as the time is already lower than 80. revealHintAtXOrLower := revealHintEveryXMilliseconds * int64(lobby.hintsLeft) timeLeft := lobby.roundEndTime - currentTime if timeLeft <= revealHintAtXOrLower { lobby.hintsLeft-- // We are trying til we find a yet unshown wordhint. Since we have // thread safety and have already checked that there's a hint // left, this loop can never spin forever. for { randomIndex := rand.Int() % len(lobby.wordHints) if lobby.wordHints[randomIndex].Character == 0 { lobby.wordHints[randomIndex].Character = []rune(lobby.CurrentWord)[randomIndex] lobby.wordHints[randomIndex].Revealed = true lobby.wordHintsShown[randomIndex].Revealed = true wordHintData := &Event{ Type: EventTypeUpdateWordHint, Data: lobby.wordHints, } lobby.broadcastConditional(wordHintData, IsAllowedToSeeHints) wordHintsShownData := &Event{ Type: EventTypeUpdateWordHint, Data: lobby.wordHintsShown, } lobby.broadcastConditional(wordHintsShownData, IsAllowedToSeeRevealedHints) break } } } } return true } func (lobby *Lobby) shouldEndEarlyDueToDisconnectedDrawer() bool { // If a word was already chosen, there might already be a drawing. So we only end // early if the drawing isn't empty. if lobby.CurrentWord != "" && len(lobby.currentDrawing) != 0 { return false } drawer := lobby.Drawer() if drawer != nil && !drawer.Connected && drawer.disconnectTime != nil && time.Since(*drawer.disconnectTime) >= disconnectGrace { return true } return false } func (lobby *Lobby) shouldEndEarlyDueToDisconnectedGuessers() bool { if lobby.CurrentWord == "" { return false } for _, p := range lobby.players { if p.State == Guessing { goto HAS_GUESSERS } } // No guessers anyway. return false HAS_GUESSERS: for _, p := range lobby.players { if p.State == Guessing && p.Connected { return false } } for _, p := range lobby.players { if p.State == Guessing && // Relevant, as we can otherwise early exit when someone joins in a bit // too late and there's a ticket between page load and socket connect. // Probably not a big issue in reality, but annoying when testing. p.hasConnectedOnce && !p.Connected && p.disconnectTime != nil && time.Since(*p.disconnectTime) <= disconnectGrace { return false } } return true } func getTimeAsMillis() int64 { return time.Now().UTC().UnixMilli() } // recalculateRanks will assign each player his respective rank in the lobby // according to everyones current score. This will not trigger any events. func recalculateRanks(lobby *Lobby) { // We don't directly sort the players, since the order determines in which // order the players will have to draw. sortedPlayers := make([]*Player, len(lobby.players)) copy(sortedPlayers, lobby.players) sort.Slice(sortedPlayers, func(a, b int) bool { return sortedPlayers[a].Score > sortedPlayers[b].Score }) // We start at maxint32, since we want the first player to cause an // increment of the score, which will always happen this way, as // no player can have a score this high. lastScore := math.MaxInt32 var lastRank int for _, player := range sortedPlayers { if !player.Connected && player.State != Spectating { continue } if player.Score < lastScore { lastRank++ lastScore = player.Score } player.Rank = lastRank } } func (lobby *Lobby) selectWord(index int) error { if lobby.State != Ongoing { return errors.New("word was chosen, even though the game wasn't ongoing") } if len(lobby.wordChoice) == 0 { return errors.New("word was chosen, even though no choice was available") } if index < 0 || index >= len(lobby.wordChoice) { return fmt.Errorf("word choice was %d, but should've been >= 0 and < %d", index, len(lobby.wordChoice)) } lobby.roundEndTime = getTimeAsMillis() + int64(lobby.DrawingTime)*1000 lobby.CurrentWord = lobby.wordChoice[index] lobby.wordChoice = nil // Depending on how long the word is, a fixed amount of hints // would be too easy or too hard. runeCount := utf8.RuneCountInString(lobby.CurrentWord) if runeCount <= 2 { lobby.hintCount = 0 } else if runeCount <= 4 { lobby.hintCount = 1 } else if runeCount <= 9 { lobby.hintCount = 2 } else { lobby.hintCount = 3 } lobby.hintsLeft = lobby.hintCount // We generate both the "empty" word hints and the hints for the // drawer. Since the length is the same, we do it in one run. lobby.wordHints = make([]*WordHint, 0, runeCount) lobby.wordHintsShown = make([]*WordHint, 0, runeCount) for _, char := range lobby.CurrentWord { // These characters are part of the word, but aren't relevant for the // guess. In order to make the word hints more useful to the // guesser, those are always shown. An example would be "Pac-Man". // Because these characters aren't relevant for the guess, they // aren't being underlined. isAlwaysVisibleCharacter := char == ' ' || char == '_' || char == '-' // The hints for the drawer are always visible, therefore they // don't require any handling of different cases. lobby.wordHintsShown = append(lobby.wordHintsShown, &WordHint{ Character: char, Underline: !isAlwaysVisibleCharacter, }) if isAlwaysVisibleCharacter { lobby.wordHints = append(lobby.wordHints, &WordHint{ Character: char, Underline: false, }) } else { lobby.wordHints = append(lobby.wordHints, &WordHint{ Underline: true, }) } } wordHintData := &Event{ Type: EventTypeWordChosen, Data: &WordChosen{ Hints: lobby.wordHints, TimeLeft: int(lobby.roundEndTime - getTimeAsMillis()), }, } lobby.broadcastConditional(wordHintData, IsAllowedToSeeHints) wordHintDataRevealed := &Event{ Type: EventTypeWordChosen, Data: &WordChosen{ Hints: lobby.wordHintsShown, TimeLeft: int(lobby.roundEndTime - getTimeAsMillis()), }, } lobby.broadcastConditional(wordHintDataRevealed, IsAllowedToSeeRevealedHints) return nil } // CreateLobby creates a new lobby including the initial player (owner) and // optionally returns an error, if any occurred during creation. func CreateLobby( desiredLobbyId string, playerName, chosenLanguage string, settings *EditableLobbySettings, customWords []string, scoringCalculation ScoreCalculation, ) (*Player, *Lobby, error) { if desiredLobbyId == "" { desiredLobbyId = uuid.Must(uuid.NewV4()).String() } lobby := &Lobby{ LobbyID: desiredLobbyId, EditableLobbySettings: *settings, CustomWords: customWords, currentDrawing: make([]any, 0), State: Unstarted, ScoreCalculation: scoringCalculation, } if len(customWords) > 1 { rand.Shuffle(len(lobby.CustomWords), func(i, j int) { lobby.CustomWords[i], lobby.CustomWords[j] = lobby.CustomWords[j], lobby.CustomWords[i] }) } lobby.Wordpack = chosenLanguage // Necessary to correctly treat words from player, however, custom words // might be treated incorrectly, as they might not be the same language as // the one specified for the lobby. If for example you chose 100 french // custom words, but keep english_us as the lobby language, the casing rules // will most likely be faulty. lobby.lowercaser = WordlistData[chosenLanguage].Lowercaser() lobby.IsWordpackRtl = WordlistData[chosenLanguage].IsRtl // customWords are lowercased afterwards, as they are direct user input. if len(customWords) > 0 { for customWordIndex, customWord := range customWords { customWords[customWordIndex] = lobby.lowercaser.String(customWord) } } player := lobby.JoinPlayer(playerName) lobby.OwnerID = player.ID return player, lobby, nil } // generatePlayerName creates a new playername. A so called petname. It consists // of an adverb, an adjective and a animal name. The result can generally be // trusted to be sane. func generatePlayerName() string { return petname.Generate(3, petname.Title, petname.None) } func generateReadyData(lobby *Lobby, player *Player) *ReadyEvent { ready := &ReadyEvent{ PlayerID: player.ID, AllowDrawing: player.State == Drawing, PlayerName: player.Name, GameState: lobby.State, OwnerID: lobby.OwnerID, Round: lobby.Round, Rounds: lobby.Rounds, DrawingTimeSetting: lobby.DrawingTime, WordHints: lobby.GetAvailableWordHints(player), Players: lobby.players, CurrentDrawing: lobby.currentDrawing, } if lobby.State != Ongoing { // Clients should interpret 0 as "time over", unless the gamestate isn't "ongoing" ready.TimeLeft = 0 } else { ready.TimeLeft = int(lobby.roundEndTime - getTimeAsMillis()) } return ready } func (lobby *Lobby) SendYourTurnEvent(player *Player) { lobby.WriteObject(player, &Event{ Type: EventTypeYourTurn, Data: &YourTurn{ TimeLeft: int(lobby.wordChoiceEndTime.UnixMilli() - getTimeAsMillis()), PreSelectedWord: lobby.preSelectedWord, Words: lobby.wordChoice, }, }) } func (lobby *Lobby) OnPlayerConnectUnsynchronized(player *Player) { player.Connected = true player.hasConnectedOnce = true recalculateRanks(lobby) lobby.WriteObject(player, Event{Type: EventTypeReady, Data: generateReadyData(lobby, player)}) // This state is reached if the player reconnects before having chosen a word. // This can happen if the player refreshes his browser page or the socket // loses connection and reconnects quickly. if player.State == Drawing && lobby.CurrentWord == "" { lobby.SendYourTurnEvent(player) } // The player that just joined already has the most up-to-date data due // to the ready event being sent. Therefeore it'd be wasteful to send // that player and update event for players. lobby.broadcastConditional(&Event{ Type: EventTypeUpdatePlayers, Data: lobby.players, }, ExcludePlayer(player)) } func (lobby *Lobby) OnPlayerDisconnect(player *Player) { // We want to avoid calling the handler twice. if player.ws == nil { return } disconnectTime := time.Now() // It is important to properly disconnect the player before aqcuiring the mutex // in order to avoid false assumptions about the players connection state // and avoid attempting to send events. player.Connected = false player.ws = nil lobby.mutex.Lock() defer lobby.mutex.Unlock() player.disconnectTime = &disconnectTime lobby.LastPlayerDisconnectTime = &disconnectTime // Reset from potentially ready to standby if lobby.State != Ongoing { // FIXME Should we not set spectators to standby? Currently there's no // indication you are spectating right now. player.State = Standby if lobby.readyToStart() { lobby.startGame() // Rank Calculation and sending out player updates happened anyway, // so there's no need to keep going. return } } // Necessary to prevent gaps in the ranking. While players preserve their // points when disconnecting, they shouldn't preserve their ranking. Upon // reconnecting, the ranking will be recalculated though. recalculateRanks(lobby) lobby.Broadcast(&Event{Type: EventTypeUpdatePlayers, Data: lobby.players}) } // GetAvailableWordHints returns a WordHint array depending on the players // game state, since people that are drawing or have already guessed correctly // can see all hints. func (lobby *Lobby) GetAvailableWordHints(player *Player) []*WordHint { // The draw simple gets every character as a word-hint. We basically abuse // the hints for displaying the word, instead of having yet another GUI // element that wastes space. if player.State != Guessing { return lobby.wordHintsShown } return lobby.wordHints } // JoinPlayer creates a new player object using the given name and adds it // to the lobbies playerlist. The new players is returned. func (lobby *Lobby) JoinPlayer(name string) *Player { player := &Player{ Name: SanitizeName(name), ID: uuid.Must(uuid.NewV4()), userSession: uuid.Must(uuid.NewV4()), votedForKick: make(map[uuid.UUID]bool), messageTimestamps: NewRing[time.Time](5), } if lobby.State == Ongoing { // Joining an existing game will mark you as a guesser, as someone is // always drawing, given there is no pause-state. player.State = Guessing } else { player.State = Standby } lobby.players = append(lobby.players, player) return player } func (lobby *Lobby) canDraw(player *Player) bool { return player.State == Drawing && lobby.CurrentWord != "" && lobby.State == Ongoing } // Shutdown sends all players an event, indicating that the lobby // will be shut down. The caller of this function should take care of not // allowing new connections. Clients should gracefully disconnect. func (lobby *Lobby) Shutdown() { lobby.mutex.Lock() defer lobby.mutex.Unlock() log.Println("Lobby Shutdown: Mutex acquired") lobby.Broadcast(&EventTypeOnly{Type: EventTypeShutdown}) } // ScoreCalculation allows having different scoring systems for a lobby. type ScoreCalculation interface { Identifier() string CalculateGuesserScore(lobby *Lobby) int CalculateDrawerScore(lobby *Lobby) int } var ChillScoring = &adjustableScoringAlgorithm{ identifier: "chill", baseScore: 100.0, maxBonusBaseScore: 100.0, bonusBaseScoreDeclineFactor: 2.0, maxHintBonusScore: 60.0, } var CompetitiveScoring = &adjustableScoringAlgorithm{ identifier: "competitive", baseScore: 10.0, maxBonusBaseScore: 290.0, bonusBaseScoreDeclineFactor: 3.0, maxHintBonusScore: 120.0, } type adjustableScoringAlgorithm struct { identifier string baseScore float64 maxBonusBaseScore float64 bonusBaseScoreDeclineFactor float64 maxHintBonusScore float64 } func (s *adjustableScoringAlgorithm) Identifier() string { return s.identifier } func (s *adjustableScoringAlgorithm) CalculateGuesserScore(lobby *Lobby) int { return s.CalculateGuesserScoreInternal(lobby.hintCount, lobby.hintsLeft, lobby.DrawingTime, lobby.roundEndTime) } func (s *adjustableScoringAlgorithm) MaxScore() int { return int(s.baseScore + s.maxBonusBaseScore + s.maxHintBonusScore) } func (s *adjustableScoringAlgorithm) CalculateGuesserScoreInternal( hintCount, hintsLeft, drawingTime int, roundEndTimeMillis int64, ) int { secondsLeft := int(roundEndTimeMillis/1000 - time.Now().UTC().Unix()) declineFactor := s.bonusBaseScoreDeclineFactor / float64(drawingTime) score := int( s.baseScore + s.maxBonusBaseScore*math.Pow(1.0-declineFactor, float64(drawingTime-secondsLeft))) // Prevent zero division panic. This could happen with two letter words. if hintCount > 0 { score += hintsLeft * (int(s.maxHintBonusScore) / hintCount) } return score } func (s *adjustableScoringAlgorithm) CalculateDrawerScore(lobby *Lobby) int { // The drawer can get points even if disconnected. But if they are // connected, we need to ignore them when calculating their score. var ( playerCount int scoreSum int ) for _, player := range lobby.GetPlayers() { if player.State != Drawing && // Switch to spectating is only possible after score calculation, so // this can't be used to manipulate score. player.State != Spectating && // If the player has guessed, we want to take them into account, // even if they aren't connected anymore. If the player is // connected, but hasn't guessed, it is still as well, as the // drawing must've not been good enough to be guessable. (player.Connected || player.LastScore > 0) { scoreSum += player.LastScore playerCount++ } } if playerCount > 0 { return scoreSum / playerCount } return 0 } ================================================ FILE: internal/game/lobby_test.go ================================================ package game import ( "encoding/json" "reflect" "testing" "time" "unsafe" "github.com/gofrs/uuid/v5" "github.com/lxzan/gws" "github.com/scribble-rs/scribble.rs/internal/sanitize" "github.com/stretchr/testify/require" ) func createLobbyWithDemoPlayers(playercount int) *Lobby { owner := &Player{} lobby := &Lobby{ OwnerID: owner.ID, } for range playercount { lobby.players = append(lobby.players, &Player{ Connected: true, }) } return lobby } func noOpWriteObject(_ *Player, _ any) error { return nil } func noOpWritePreparedMessage(_ *Player, _ *gws.Broadcaster) error { return nil } func Test_Locking(t *testing.T) { t.Parallel() lobby := &Lobby{} lobby.mutex.Lock() if lobby.mutex.TryLock() { t.Error("Mutex shouldn't be acquiredable at this point") } } func Test_CalculateVotesNeededToKick(t *testing.T) { t.Parallel() expectedResults := map[int]int{ // Kinda irrelevant since you can't kick yourself, but who cares. 1: 2, 2: 2, 3: 2, 4: 2, 5: 3, 6: 3, 7: 4, 8: 4, 9: 5, 10: 5, } for playerCount, expctedRequiredVotes := range expectedResults { lobby := createLobbyWithDemoPlayers(playerCount) result := calculateVotesNeededToKick(lobby) if result != expctedRequiredVotes { t.Errorf("Error. Necessary vote amount was %d, but should've been %d", result, expctedRequiredVotes) } } } func Test_RemoveAccents(t *testing.T) { t.Parallel() expectedResults := map[string]string{ "é": "e", "É": "E", "à": "a", "À": "A", "ç": "c", "Ç": "C", "ö": "oe", "Ö": "OE", "œ": "oe", "\n": "\n", "\t": "\t", "\r": "\r", "": "", "·": "·", "?:!": "?:!", "ac-ab": "acab", //nolint:gocritic "ac - _ab-- ": "acab", } for k, v := range expectedResults { result := sanitize.CleanText(k) if result != v { t.Errorf("Error. Char was %s, but should've been %s", result, v) } } } func Test_simplifyText(t *testing.T) { t.Parallel() // We only test the replacement we do ourselves. We won't test // the "sanitize", or furthermore our expectations of it for now. tests := []struct { name string input string want string }{ { name: "dash", input: "-", want: "", }, { name: "underscore", input: "_", want: "", }, { name: "space", input: " ", want: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() if got := sanitize.CleanText(tt.input); got != tt.want { t.Errorf("simplifyText() = %v, want %v", got, tt.want) } }) } } func Test_recalculateRanks(t *testing.T) { t.Parallel() lobby := &Lobby{} lobby.players = append(lobby.players, &Player{ ID: uuid.Must(uuid.NewV4()), Score: 1, Connected: true, }) lobby.players = append(lobby.players, &Player{ ID: uuid.Must(uuid.NewV4()), Score: 1, Connected: true, }) recalculateRanks(lobby) rankPlayerA := lobby.players[0].Rank rankPlayerB := lobby.players[1].Rank if rankPlayerA != 1 || rankPlayerB != 1 { t.Errorf("With equal score, ranks should be equal. (A: %d; B: %d)", rankPlayerA, rankPlayerB) } lobby.players = append(lobby.players, &Player{ ID: uuid.Must(uuid.NewV4()), Score: 0, Connected: true, }) recalculateRanks(lobby) rankPlayerA = lobby.players[0].Rank rankPlayerB = lobby.players[1].Rank if rankPlayerA != 1 || rankPlayerB != 1 { t.Errorf("With equal score, ranks should be equal. (A: %d; B: %d)", rankPlayerA, rankPlayerB) } rankPlayerC := lobby.players[2].Rank if rankPlayerC != 2 { t.Errorf("new player should be rank 2, since the previous two players had the same rank. (C: %d)", rankPlayerC) } } func Test_chillScoring_calculateGuesserScore(t *testing.T) { t.Parallel() score := ChillScoring.CalculateGuesserScoreInternal(0, 0, 120, time.Now().Add(115*time.Second).UnixMilli()) if score >= ChillScoring.MaxScore() { t.Errorf("Score should have declined, but was bigger than or "+ "equal to the max score. (LastScore: %d; MaxScore: %d)", score, ChillScoring.MaxScore()) } lastDecline := -1 for secondsLeft := 105; secondsLeft >= 5; secondsLeft -= 10 { roundEndTime := time.Now().Add(time.Duration(secondsLeft) * time.Second).UnixMilli() newScore := ChillScoring.CalculateGuesserScoreInternal(0, 0, 120, roundEndTime) if newScore > score { t.Errorf("Score with more time taken should be lower. (LastScore: %d; NewScore: %d)", score, newScore) } newDecline := score - newScore if lastDecline != -1 && newDecline > lastDecline { t.Errorf("Decline should get lower with time taken. (LastDecline: %d; NewDecline: %d)\n", lastDecline, newDecline) } score = newScore lastDecline = newDecline } } func Test_handleNameChangeEvent(t *testing.T) { t.Parallel() lobby := &Lobby{} lobby.WriteObject = noOpWriteObject lobby.WritePreparedMessage = noOpWritePreparedMessage player := lobby.JoinPlayer("Kevin") handleNameChangeEvent(player, lobby, "Jim") expectedName := "Jim" if player.Name != expectedName { t.Errorf("playername didn't change; Expected %s, but was %s", expectedName, player.Name) } } func getUnexportedField(field reflect.Value) any { return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface() } func Test_wordSelectionEvent(t *testing.T) { t.Parallel() lobby := &Lobby{ EditableLobbySettings: EditableLobbySettings{ DrawingTime: 10, Rounds: 10, WordsPerTurn: 3, }, words: []string{"abc", "def", "ghi"}, } wordHintEvents := make(map[uuid.UUID][]*WordHint) var wordChoice []string lobby.WriteObject = func(_ *Player, message any) error { event, ok := message.(*Event) if ok { if event.Type == EventTypeYourTurn { yourTurn := event.Data.(*YourTurn) wordChoice = yourTurn.Words } } return nil } lobby.WritePreparedMessage = func(player *Player, message *gws.Broadcaster) error { data := getUnexportedField(reflect.ValueOf(message).Elem().FieldByName("payload")).([]byte) type event struct { Type string `json:"type"` Data json.RawMessage `json:"data"` } var e event if err := json.Unmarshal(data, &e); err != nil { t.Fatal("error unmarshalling message", err) } t.Log(e.Type) if e.Type == "word-chosen" { var event WordChosen if err := json.Unmarshal(e.Data, &event); err != nil { t.Fatal("error unmarshalling word hints:", err) } wordHintEvents[player.ID] = event.Hints } return nil } drawer := lobby.JoinPlayer("Drawer") drawer.Connected = true lobby.OwnerID = drawer.ID if err := lobby.HandleEvent(EventTypeStart, nil, drawer); err != nil { t.Errorf("Couldn't start lobby: %s", err) } guesser := lobby.JoinPlayer("Guesser") guesser.Connected = true err := lobby.HandleEvent(EventTypeChooseWord, []byte(`{"data": 0}`), drawer) if err != nil { t.Errorf("Couldn't choose word: %s", err) } wordHintsForDrawer := wordHintEvents[drawer.ID] if len(wordHintsForDrawer) != 3 { t.Errorf("Word hints for drawer were of incorrect length; %d != %d", len(wordHintsForDrawer), 3) } for index, wordHint := range wordHintsForDrawer { if wordHint.Character == 0 { t.Error("Word hints for drawer contained invisible character") } if !wordHint.Underline { t.Error("Word hints for drawer contained not underlined character") } expectedRune := rune(wordChoice[0][index]) if wordHint.Character != expectedRune { t.Errorf("Character at index %d was %c instead of %c", index, wordHint.Character, expectedRune) } } wordHintsForGuesser := wordHintEvents[guesser.ID] if len(wordHintsForGuesser) != 3 { t.Errorf("Word hints for guesser were of incorrect length; %d != %d", len(wordHintsForGuesser), 3) } for _, wordHint := range wordHintsForGuesser { if wordHint.Character != 0 { t.Error("Word hints for guesser contained visible character") } if !wordHint.Underline { t.Error("Word hints for guesser contained not underlined character") } } } func Test_kickDrawer(t *testing.T) { t.Parallel() lobby := &Lobby{ EditableLobbySettings: EditableLobbySettings{ DrawingTime: 10, Rounds: 10, WordsPerTurn: 3, }, ScoreCalculation: ChillScoring, words: []string{"a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a"}, } lobby.WriteObject = noOpWriteObject lobby.WritePreparedMessage = noOpWritePreparedMessage marcel := lobby.JoinPlayer("marcel") marcel.Connected = true lobby.OwnerID = marcel.ID kevin := lobby.JoinPlayer("kevin") kevin.Connected = true chantal := lobby.JoinPlayer("chantal") chantal.Connected = true if err := lobby.HandleEvent(EventTypeStart, nil, marcel); err != nil { t.Errorf("Couldn't start lobby: %s", err) } if lobby.Drawer() == nil { t.Error("Drawer should've been a, but was nil") } if lobby.Drawer() != marcel { t.Errorf("Drawer should've been a, but was %s", lobby.Drawer().Name) } lobby.Synchronized(func() { advanceLobby(lobby) }) if lobby.Drawer() == nil { t.Error("Drawer should've been b, but was nil") } if lobby.Drawer() != kevin { t.Errorf("Drawer should've been b, but was %s", lobby.Drawer().Name) } lobby.Synchronized(func() { kickPlayer(lobby, kevin, 1) }) if lobby.Drawer() == nil { t.Error("Drawer should've been c, but was nil") } if lobby.Drawer() != chantal { t.Errorf("Drawer should've been c, but was %s", lobby.Drawer().Name) } } func Test_lobby_calculateDrawerScore(t *testing.T) { t.Parallel() t.Run("only disconnected players, with score", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: false, LastScore: 100, }, { Connected: false, LastScore: 200, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 150, lobby.calculateDrawerScore()) }) t.Run("only disconnected players, with no score", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: false, LastScore: 0, }, { Connected: false, LastScore: 0, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 0, lobby.calculateDrawerScore()) }) t.Run("connected players, but no score", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: true, LastScore: 0, }, { Connected: true, LastScore: 0, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 0, lobby.calculateDrawerScore()) }) t.Run("connected players", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: true, LastScore: 100, }, { Connected: true, LastScore: 200, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 150, lobby.calculateDrawerScore()) }) t.Run("some connected players, some disconnected, some without score", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: true, LastScore: 100, }, { Connected: false, LastScore: 200, }, { Connected: true, LastScore: 0, }, { Connected: false, LastScore: 0, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 100, lobby.calculateDrawerScore()) }) t.Run("some connected players, some disconnected", func(t *testing.T) { t.Parallel() drawer := &Player{State: Drawing} lobby := Lobby{ players: []*Player{ drawer, { Connected: true, LastScore: 100, }, { Connected: true, LastScore: 200, }, { Connected: false, LastScore: 300, }, { Connected: false, LastScore: 400, }, }, ScoreCalculation: ChillScoring, } require.Equal(t, 250, lobby.calculateDrawerScore()) }) } func Test_NoPrematureGameOver(t *testing.T) { t.Parallel() player, lobby, err := CreateLobby("", "test", "english", &EditableLobbySettings{ Public: false, DrawingTime: 120, Rounds: 4, MaxPlayers: 4, CustomWordsPerTurn: 3, ClientsPerIPLimit: 1, WordsPerTurn: 3, }, nil, ChillScoring) require.NoError(t, err) lobby.WriteObject = noOpWriteObject lobby.WritePreparedMessage = noOpWritePreparedMessage require.Equal(t, Unstarted, lobby.State) require.Equal(t, Standby, player.State) // The socket won't be called anyway, so its fine. player.ws = &gws.Conn{} player.Connected = true lobby.OnPlayerDisconnect(player) require.False(t, player.Connected) require.Equal(t, Standby, player.State) require.Equal(t, Unstarted, lobby.State) lobby.OnPlayerConnectUnsynchronized(player) require.True(t, player.Connected) require.Equal(t, Standby, player.State) require.Equal(t, Unstarted, lobby.State) } ================================================ FILE: internal/game/shared.go ================================================ package game import ( "time" "github.com/gofrs/uuid/v5" "github.com/lxzan/gws" ) // // This file contains all structs and constants that are shared with clients. // // Eevnts that are just incomming from the client. const ( EventTypeStart = "start" EventTypeToggleReadiness = "toggle-readiness" EventTypeToggleSpectate = "toggle-spectate" EventTypeRequestDrawing = "request-drawing" EventTypeChooseWord = "choose-word" EventTypeUndo = "undo" ) // Events that are outgoing only. const ( EventTypeUpdatePlayers = "update-players" EventTypeUpdateWordHint = "update-wordhint" EventTypeWordChosen = "word-chosen" EventTypeCorrectGuess = "correct-guess" EventTypeCloseGuess = "close-guess" EventTypeSystemMessage = "system-message" EventTypeNonGuessingPlayerMessage = "non-guessing-player-message" EventTypeReady = "ready" EventTypeGameOver = "game-over" EventTypeYourTurn = "your-turn" EventTypeNextTurn = "next-turn" EventTypeDrawing = "drawing" EventTypeDrawerKicked = "drawer-kicked" EventTypeOwnerChange = "owner-change" EventTypeLobbySettingsChanged = "lobby-settings-changed" EventTypeShutdown = "shutdown" EventTypeKeepAlive = "keep-alive" ) // Events that are bidirectional. var ( EventTypeKickVote = "kick-vote" EventTypeNameChange = "name-change" EventTypeMessage = "message" EventTypeLine = "line" EventTypeFill = "fill" EventTypeClearDrawingBoard = "clear-drawing-board" ) type State string const ( // Unstarted means the lobby has been opened but never started. Unstarted State = "unstarted" // Ongoing means the lobby has already been started. Ongoing State = "ongoing" // GameOver means that the lobby had been start, but the max round limit // has already been reached. GameOver State = "gameOver" ) // Event contains an eventtype and optionally any data. type Event struct { Data any `json:"data"` Type string `json:"type"` } type StringDataEvent struct { Data string `json:"data"` } type EventTypeOnly struct { Type string `json:"type"` } type IntDataEvent struct { Data int `json:"data"` } // WordHint describes a character of the word that is to be guessed, whether // the character should be shown and whether it should be underlined on the // UI. type WordHint struct { // The actual word character or 0 if not revealed. Note, that for shown hints, these are always set, even if not revealed. Character rune `json:"character"` // Underline is used to distinguish characters like spaces or dashes from guessable characters. Underline bool `json:"underline,omitempty"` // Revealed is used for non-guessing players to indicate that other players can see a character. Revealed bool `json:"revealed,omitempty"` } type LineEvent struct { Type string `json:"type"` // Data contains the coordinates, stroke width and color. The coors here // aren't uint16, as it allows us to easily allow implementing drawing on // the client, where the user drags the line over the canvas border. // If we were to not accept out of bounds values, the lines would be chopped // off before reaching the canvas border. Data struct { X int16 `json:"x"` Y int16 `json:"y"` X2 int16 `json:"x2"` Y2 int16 `json:"y2"` // Color is a color index. This was previously an rgb value, but since // the values are always the same, using an index saves bandwidth. Color uint8 `json:"color"` Width uint8 `json:"width"` } `json:"data"` } type FillEvent struct { Data *struct { X uint16 `json:"x"` Y uint16 `json:"y"` // Color is a color index. This was previously an rgb value, but since // the values are always the same, using an index saves bandwidth. Color uint8 `json:"color"` } `json:"data"` Type string `json:"type"` } // KickVote represents a players vote to kick another players. If the VoteCount // is as great or greater than the RequiredVoteCount, the event indicates a // successful kick vote. The voting is anonymous, meaning the voting player // won't be exposed. type KickVote struct { PlayerName string `json:"playerName"` PlayerID uuid.UUID `json:"playerId"` VoteCount int `json:"voteCount"` RequiredVoteCount int `json:"requiredVoteCount"` } type OwnerChangeEvent struct { PlayerName string `json:"playerName"` PlayerID uuid.UUID `json:"playerId"` } type NameChangeEvent struct { PlayerName string `json:"playerName"` PlayerID uuid.UUID `json:"playerId"` } // GameOverEvent is basically the ready event, but contains the last word. // This is required in order to show the last player the word, in case they // didn't manage to guess it in time. This is necessary since the last word // is usually part of the "next-turn" event, which we don't send, since the // game is over already. type GameOverEvent struct { *ReadyEvent PreviousWord string `json:"previousWord"` RoundEndReason roundEndReason `json:"roundEndReason"` } type WordChosen struct { TimeLeft int `json:"timeLeft"` Hints []*WordHint `json:"hints"` } type YourTurn struct { TimeLeft int `json:"timeLeft"` PreSelectedWord int `json:"preSelectedWord"` Words []string `json:"words"` } // NextTurn represents the data necessary for displaying the lobby state right // after a new turn started. Meaning that no word has been chosen yet and // therefore there are no wordhints and no current drawing instructions. type NextTurn struct { // PreviousWord signals the last chosen word. If empty, no word has been // chosen. The client can now themselves whether there has been a previous // turn, by looking at the current gamestate. PreviousWord string `json:"previousWord"` Players []*Player `json:"players"` ChoiceTimeLeft int `json:"choiceTimeLeft"` Round int `json:"round"` RoundEndReason roundEndReason `json:"roundEndReason"` } // OutgoingMessage represents a message in the chatroom. type OutgoingMessage struct { // Content is the actual message text. Content string `json:"content"` // Author is the player / thing that wrote the message Author string `json:"author"` // AuthorID is the unique identifier of the authors player object. AuthorID uuid.UUID `json:"authorId"` } // ReadyEvent represents the initial state that a user needs upon connection. // This includes all the necessary things for properly running a client // without receiving any more data. type ReadyEvent struct { WordHints []*WordHint `json:"wordHints"` PlayerName string `json:"playerName"` Players []*Player `json:"players"` GameState State `json:"gameState"` CurrentDrawing []any `json:"currentDrawing"` PlayerID uuid.UUID `json:"playerId"` OwnerID uuid.UUID `json:"ownerId"` Round int `json:"round"` Rounds int `json:"rounds"` TimeLeft int `json:"timeLeft"` DrawingTimeSetting int `json:"drawingTimeSetting"` AllowDrawing bool `json:"allowDrawing"` } type Ring[T any] struct { buf []T head int size int } func NewRing[T any](cap int) *Ring[T] { return &Ring[T]{buf: make([]T, cap /* slice len, not cap */)} } func (r *Ring[T]) Push(v T) { r.buf[r.head] = v r.head = (r.head + 1) % len(r.buf) if r.size < len(r.buf) { r.size++ } } func (r *Ring[T]) Oldest() T { if r.size == 0 { var zero T return zero } return r.buf[(r.head-r.size+len(r.buf))%len(r.buf)] } func (r *Ring[T]) Latest() T { if r.size == 0 { var zero T return zero } return r.buf[(r.head-1+len(r.buf))%len(r.buf)] } // Player represents a participant in a Lobby. type Player struct { // userSession uniquely identifies the player. userSession uuid.UUID ws *gws.Conn // disconnectTime is used to kick a player in case the lobby doesn't have // space for new players. The player with the oldest disconnect.Time will // get kicked. disconnectTime *time.Time votedForKick map[uuid.UUID]bool lastKnownAddress string // messageTimestamps are stored for ratelimiting reasons. See handleMessage. messageTimestamps *Ring[time.Time] // Name is the players displayed name Name string `json:"name"` State PlayerState `json:"state"` // SpectateToggleRequested is used for state changes between spectator and // player. We want to prevent people from switching in and out of the Player // state. While this will allow people to skip being the drawer, it will // also cause them to lose points for that round. SpectateToggleRequested bool `json:"spectateToggleRequested"` // Rank is the current ranking of the player in his Lobby // Score is the points that the player got in the current Lobby. Score int `json:"score"` LastScore int `json:"lastScore"` Rank int `json:"rank"` // Connected defines whether the players websocket connection is currently // established. This has previously been in state but has been moved out // in order to avoid losing the state on refreshing the page. // While checking the websocket against nil would be enough, we still need // this field for sending it via the APIs. Connected bool `json:"connected"` // hasConnectedOnce indicates whether a player has ever connected to the websocket. // This can be false between loading the HTML and connecting to the websocket. hasConnectedOnce bool // ID uniquely identified the Player. ID uuid.UUID `json:"id"` } // EditableLobbySettings represents all lobby settings that are editable by // the lobby owner after the lobby has already been opened. type EditableLobbySettings struct { // CustomWords are additional words that will be used in addition to the // predefined words. // Public defines whether the lobby is being broadcast to clients asking // for available lobbies. Public bool `json:"public"` // MaxPlayers defines the maximum amount of players in a single lobby. MaxPlayers int `json:"maxPlayers"` CustomWordsPerTurn int `json:"customWordsPerTurn"` // ClientsPerIPLimit helps preventing griefing by reducing each player // to one tab per IP address. ClientsPerIPLimit int `json:"clientsPerIpLimit"` // Rounds defines how many iterations a lobby does before the game ends. // One iteration means every participant does one drawing. Rounds int `json:"rounds"` // DrawingTime is the amount of seconds that each player has available to // finish their drawing. DrawingTime int `json:"drawingTime"` // WordsPerTurn defines how many words the drawer is able to choose from WordsPerTurn int `json:"wordsPerTurn"` } ================================================ FILE: internal/game/words/ar ================================================ آيس كريم أرز أرنب أسد أكل أناناس إبريق إسفنجة إطار الأهرامات البيت الأبيض باب باتمان باذنجان بازلاء ببغاء برتقال برج برج إيفل برجر برق بركان بسكويت بصل بطارية بطاطس بطاقة بطانية بطة بطيخ بقرة بوصلة بيانو بيتزا بيض تذكرة تزلج تسلق تصوير تعلم تفاحة تقويم تلسكوب تمر تمساح تنظيف تين ثلاجة ثلج ثوم جبل جبن جدار جرس جزر جسر جواز جورب حديقة حديقة الحيوان حذاء حزام حساء حصان حصان بحر حقيبة حليب حمص خاتم خبز خروف خريطة خزانة خس خوخ خوذة خيار خيمة دائرة دجاج دراجة درج دش دفتر دلو دولفين ديك ذئب ذرة رسالة رسم رسم بالقلم رقص ركض رمان رمح زبدة زجاجة زرافة زيت زيتون ساحة ساعة ساندويتش سباحة سباق سبايدرمان ستارة سجادة سرير سفر سفينة سقف سكر سكين سلة سلحفاة سلحفاة بحرية سلطة سلم سماعة سمك سمكة سندباد سهم سوار سوبرمان سوق سيارة سيف سينما شاحن شاشة شاطئ شاي شبكة شكولاتة شلال شمس شمعة شوربة شوكة صابون صافرة صحراء صخرة صندوق صيد ضفدع طائر طائرة طاولة طبخ طبق طبلة طرزان طماطم عجلة عدس عسل عصير علم عنب غابة غرفة غزال غناء غيتار غيمة فأرة فجل فراشة فراولة فرشاة فرشاة أسنان فرن فطر فطيرة فلافل فلفل فيل قارب قبعة قدر قراءة قرش قرنبيط قرية قصر قطار قطة قفاز قفز قلادة قلم قمح قمر قميص قناع قهوة قوس قيادة كابينة كاميرا كبسة كتاب كتابة كرة كرز كرسي كعبة كعكة كلب كماشة كمان كمبيوتر كمثرى كهف كوب كوسة كيس لافتة لحم لوحة لوحة مفاتيح ليمون مئذنة ماء ماعز متحف مثلث مجلد مجهر مدرسة مدينة مذكرة مرآب مرآة مربع مربى مرفأ مرمى مروحة مستشفى مسجد مسرح مسمار مشمش مصباح مصحف مطار مطبخ مطر مطرقة مطعم مظلة معجون معطف معكرونة مغسلة مفتاح مفتاح سيارة مفك مقص مقلاة مقود مكتبة مكنسة مكواة ملاهي ملح ملعب ملعقة ملعقة خشب ممحاة منبه منشار منشفة منظار موزة موقد ميزان ميكروفون نافذة نحلة نخلة نظارة نعامة نمر نملة نهر نوم هاتف وادي وسادة وشاح ولاعة ================================================ FILE: internal/game/words/de ================================================ abdeckung abend abendessen abenteuer abfahrt abfall abfliegen abflussrohr abgrund abhalten abheben abhilfe abhängen abhängig abhängigkeit ablassen ablehnen ablehnung abmessungen abnormal abonnement abraham lincoln absatz abschaffen abschleppwagen abschluss absicht absolut absolvent absorbieren absorption absperrband abspielen abstammung abstimmung abstrakt absturz abtei abteil abtreibung abwechslungsreich abweichung abwesend abwesenheit abzug ac/dc achse achsel achselhöhle achteck achterbahn achtung addition ader adidas adler administrator adoptieren adresse affe affinität affäre afrika afrofrisur agenda agent agentur aggressiv agil ahorn aids airbag akademie akademisch akkord akkordeon akkumulation akne aktion aktionär aktiv aktivität aktualisieren akut akzent akzeptabel akzeptieren aladdin alarm albatros albtraum album alkohol allee allergie allgemeines alligator allmählich alpaka alphabetisierung alphorn alt altar alter altglascontainer altweibersommer alufolie aluminium amateur ambition amboss ameise ameisenbär ameisenhaufen amerika amor ampel ampelmännchen amputieren amsel amsterdam amüsieren anakonda analogie analyse analytiker ananas andere anders android anerkennung anfang anforderung anfrage anfällig anfänger anfügen anführer angebot angegebenen angelegenheit angelina jolie angemessen angemessene angenehm angestellter angewendet anglerfisch angreifen angriff angry birds angst anhalter anhang anhänger anhängerkupplung animation anime anker anklage ankündigung anlagegut anlocken anmeldung anmerkung anmut annahme annehmen anonym anordnung anruf ansatz anschließend anschwellen ansporn anspruch anspruchsvoll ansteigen anstrengung antarktis anteil antilope antivirus antragsteller antwort antworten anubis anwalt anweisung anwendung anzahl anzahlung anzeige anzeigen anzug anzünden apathie apfel apfelbaum apfelkern apfelkuchen apfelsaft apokalypse apotheker appetit applaudieren apple aprikose aquarium arbeit arbeiten arbeiter arbeitgeber arbeitslos arbeitslosigkeit arbeitszimmer architekt architektur archiv archäologe archäologisch arena argentinien aristokrat arm armaturenbrett armband armbanduhr armbrust armleuchter arrogant artikel artikulieren artist arzt arztkoffer asche aschenbecher asien aspekt ass ast asterix asteroid astronaut asyl asymmetrisch atem atemberaubend athlet atlantis atmen atmosphäre atom atombombe atomuhr attacke attraktion attraktiv aubergine audi aufblasen aufführen aufgeregt aufgeräumt aufhänger aufkleber aufladen auflage auflösung aufnahme aufnehmen aufrechterhalten aufregend aufregung aufsatz aufteilung aufwachen aufwerten aufzeichnung aufzug auge augenbinde augenbraue augenlid ausbeuten ausbildung ausblenden ausblick ausbreitung ausdruck ausdrücken ausfahrt ausflug ausführen ausführung ausgabe ausgaben ausgestorben ausgewogen ausgrabung auslauf ausländer ausnahme auspuff ausrede ausreichend ausruhen ausrüstung ausschließen aussehen aussicht aussichtspunkt ausstellung ausstellungsstück austausch auster australien auswahl auto autobahn autofahrer autogramm automatisch autonomie autor autoradio autorisieren außergewöhnlich außerirdisch außerirdischer avocado axolotl axt baby backen backenzahn backofen backstein bad badeanzug badekappe bademantel badewanne badezimmer bagel bagger baguette bahn bahnhof bahnschiene bajonett baklava balance balkon ball ballaststoff ballett ballon bambi bambus banane band bandnudel bandscheibenvorfall banjo bank bankier banner bar barack obama barbar barbier barcode bargeld barkeeper barriere bart bart simpson base baseball baseballschläger basis basketball batman batterie bauarbeiter bauch bauchnabel bauchpinseln bauer bauernhof bauholz baum baumhaus baumkrone baumkuchen baumstumpf baumwolle bayern beachten beachtung beatbox becher becken bedauern bedeuten bedeutung bedienung bedingung beeindrucken beeindruckend beeinflussen beerdigung beere beethoven befehl befehlen befehlshaber beflecken befreiung befriedigung beförderung befürworten begeistert begeisterung begleiten begraben begradigen begreifen begrenzt begriff begrüßen begünstigter behalten behandeln behandlung beharren behauptung behindert behinderung behälter behörde beihilfe bein beine beispiel beitrag beizen beißen bekanntmachung bekanntschaft bekenntnis bekifft beklagte belagerung belastung beleben beleidigen beleidigend belgien beliebt belohnung benachrichtigung benutzen benzin benötigen beobachten beobachter bequemlichkeit berater beratung berauben berechnung berechtigt bereich bereit bereitstellung berg bergkette bergmann bergwerk bericht berlin bernstein beruf beruflich berüchtigt berühmt berühmtheit berühren besatzung bescheiden beschreiben beschränken beschränkt beschränkung beschwerde beschweren beschäftigt beschäftigung beschämt beseitigen besen besenstiel besetzen besetzung besitz besonders besorgnis bestatter bestechen bestehen bestellung bestrafen bestrafung bestreiten besuch besuchen besucher beten beton betonung betrachten betrachtung betriebsbereit betrug beträchtlich betrügen bett bettdecke bettwanze beule beurteilung beute bevorzugen bewachen bewegung beweis beweisen bewertung bewirken bewohner bewundern bewunderung bewusst bewusstsein bewältigen bezaubernd bezeugen beziehung bibel biber bibliothek bibliothekar biege biegen biene bienenkönigin bienenstich bienenstock bier big ben bikini bild bilden bildhauer bildschirm bildung bill gates billard billig binden bindung bingo biografie biologie biotonne birke birne bischof biss bissen bitcoin bitte bitten bitter black friday blase blasebalg blatt blau blaubeere blaue jeans bleibe bleiche bleichen bleistift blendung blick blind blinddarm blitz block blond blume blumenkohl blumenstrauß blumentopf blut blutegel bluten bluterguss blutig blutspende blutvergießen blöd blüte bmw bmx bob bob ross bock boden bodybuilding bogen bogenschütze bohne bohnenstange bohren bohrmaschine bolzen bombe bomber bomberman bommelmütze bonbon bongo boom boot boris becker botschaft bowling box boxer brasilien brathering bratsche bratwurst brauchen brauerei braun brause braut brecheisen brechen breite bremse brennen brennnessel brett bretzel brezel brief briefkasten briefmarke brieftaube briefträger briefumschlag brieföffner brille bringen brise brocken brokkoli bronze brot brownie bruce lee bruch bruder brunnen brust brusthaare brustkorb bräutigam brücke brüllen brünett buch buchhalter buchstabieren bucht budget buffet bugs bunny bullauge bulldozer bulle bumerang bummel bundes bungee jumping bunt buntstift burger burgruine burrito bus busch busfahrer bushaltestelle butter bäcker bäckerei bär bärenfalle böller bösartig bösewicht bücherei bücherregal bücherwurm bügeleisen bühne bündeln bürger bürgermeister bürgersteig büro büroklammer bürokratie bürokratisch bürste cafe camping cappuccino captain america cartoon cat woman catering cello cent cerberus champagner champagnersorbet champion chamäleon chance chaos chaotisch charakter charakteristisch charismatisch charlie chaplin charme charta chauvinist cheerleader cheeseburger chef chemie chemisch chewbacca chihuahua china chinatown chinchilla chinesische mauer chip chips chirurg chirurgie chor christbaumkugel chrome chronisch chuck norris clever clickbait clown clownfisch cluster co2 cockpit cocktail code coffeeshop cola comic comicbuch community compass computer computing cousin cowboy creeper creme croissant cupcake curry cyborg dach dachboden dachfenster dachs dachschaden daffy duck dalmatiner dame dampf dankbar danken darlehen darm darsteller darts darwin datei dattel datum dauer daumen daune dazugewinnen deadpool deal debatte debüt deck decke deckel deckenventilator definieren definition definitiv defizit degen dekade dekoration dekorativ delegieren delfin delle demokratie demokratisch demonstration demonstrator denken denker denkmal denunzieren deodorant depression depressiv design designer desoxyribonukleinsäure dessert detail detektiv detektor detonieren deutlich deutschland dexter diagnose diagonale diagramm dialekt dialog diamant dichte dick didgeridoo dieb diebstahl dienen diener dienstag differenzieren digital diktieren dilemma dinosaurier diplom diplomat diplomatisch direkte direktor dirigent dirndl discord diskette disko diskret diskriminierung diskurs diskutieren distanz distanziert disziplin diva dividende diät dns doktor dokumentieren dolch dollar dom dominant dominieren domino dompteur donald duck donald trump donner donnerstag donut doppelpunkt doppelt dora dorf dorfbewohner doritos dose dosenöffner dosis drache drachen dracula draht drama dramatisch drang draußen dreck dreckig drehen drehung dreieck dreirad dressing drift drillinge dringlichkeit drinnen droge drohen drohung druck drucken drucker drücken dschungel dudelsack duell duftend dumbo dumm dunkel durchdringen durchmesser durchschnittlich durchsetzungsfähig durst durstig dusche dutzend dynamisch dynamit dynamo dämon dänemark döner düne dünn dürr dürre düsternis e-gitarre eben eber echo echt ecke edel edelstein efeu effizient ego ehe ehefrau ehemann ehre ehrenwert ehrgeizig ehrlich ei eiche eichel eichhörnchen eidechse eierbecher eierschachtel eifersüchtig eiffelturm eifrig eigelb eigentum eilen eimer einbahnstraße einblick einbruch einfach einfachheit einflussreich einfrieren einfügen einführung eingabestift eingeben eingestehen einheimisch einheit einhorn einhornwal einkaufen einkaufswagen einkaufszentrum einkommen einladen einladung einlösen einrad einrasten einreichen einrichtung einsam einschiffen einschlag einschränkung einsiedler einstein einstellen einstellung einstimmig eintopf eintrag eintritt einwand einwanderung einweichen einwohner einzelhandel einzelhändler einzigartig eis eis am stiel eisberg eisbär eisen eisenbahn eiskaffee eistee eisverkäufer eiszapfen elch elefant elegant elektriker elektrisch elektrizität elektroauto elektron elektronik elektronisch element elend elfenbein elite ellbogen elmo elon musk elsa elster eltern elternteil embryo eminem emoji emotion emotional empfangshalle empfehlen empfehlung empfindlich empfindlichkeit empirisch emu ende energie eng engagement engel england enorm entbehrung entdecken entdeckung ente entensuppe entfernt entfernung entgegengesetzt enthalten enthaupten entlarven entlassen entlassung entlasten entmutigen entscheiden entscheidend entschuldigen entschuldigung entspannen entspannung entsprechen enttäuschen enttäuschung entwickeln entwicklung entwurf epilieren epoche erbe erben erbrechen erbsen erdbeben erdbeere erde erdkern erdkunde erdmännchen erdnuss erdnuss-flips erfahren erfahrung erfassung erfindung erfolg erfolgreich erfrieren erfrierung ergebnis ergreifen ergänzend erhalten erhaltung erhebt euch erholung erhöhen erinnern erinnerung erkenne erklären erklärung erkrankung erkundung erkältung erläuterung ermitteln ermittler ermittlung ermutigen ermutigend ermäßigung ermöglichen ernennen ernst ernte ernten erosion erpressung erreichen error erröten ersatz erscheinen erschrecken erschreckend ersetzen erstaunlich erstellen ersticken ertragen ertrinken erwachen erwachsene erwartet erwartung erweitern erweiterung erwerb erwägen erwägung erwähnen erziehen erzählen esel eselsbrücke eselsohr espresso essen essig essiggurke essstäbchen etabliert etagenbett ethik ethisch ethnisch etikette eule euro europa euter evolution ewig excalibur exekutive exil exklusiv exotisch expedition experiment experimental experte explizit explodieren explosion export exposition extern extrem fabelhaft fabrik facebook fachmann fackel fade faden fahnenstange fahrbahn fahren fahrer fahrkarte fahrlässigkeit fahrpreis fahrrad fahrt fahrwerk fahrzeug faktor fall falle fallen fallschirm falltür falsch falte falten familie familiär family guy fang fanta fantasie farbe farbenblind farbpalette farmer farn fass fassade fastfood faszinieren fata morgana faul faultier faust faustkampf fax fazit fechten feder federball federmäppchen fee fegen fehler fehlerhaft fehlgeburt feier feierabend feiern feige fein feind feindlich feindseligkeit feld feldstecher fell felsen feminin feminist fenster fensterbank ferien ferkel fernbedienung fernglas fernsehen fernseher fernsehturm ferrari ferse fertig fertigkeit fest feste festival festnahme festung fett fett gedruckt fettleibig feuer feueralarm feuerball feuerfest feuersalamander feuerwache feuerwehrauto feuerwehrmann feuerwerk feuerzeug fidget spinner fieber figur fiktion film filmemacher filmriss filter finale finanzen finanziell finden finger fingerhut fingernagel fingerpuppe fingerspitze finn finn und jake finnland fisch fischer fischernetz fischgräte fitness fitness trainer fix flach flagge flamingo flammenwerfer flammkuchen flasche flaschendrehen flaschenpost flaschenöffner fledermaus fleisch fleischbällchen fleischfressend flexibel fliege fliegen fliegendes schwein fliegenklatsche fliegenpilz fliese flipper floh flohmarkt florida florist flotte floß flucht flug flugblatt fluggesellschaft flughafen flugzeug fluktuation flur fluss flut flutlicht flöte flüchtling flügel flüssig flüssigkeit flüstern folge folgen folklore folter fonds form formal format formation formel formulieren forscher forschung forstwirtschaft fortdauern fortschritt fortsetzung forum fossil fotograf fotografie fotografieren fotokopie fracht frage fragebogen fragen fragment fraktion franchise frank frankenstein frankreich frau fred feuerstein freddie faulig frei freibad freiheit freiheitsstatue freisetzung freitag freiwillig freiwillige freizeit frequenz freude freund freundlich freundschaft frieden friedhof friedlich frisbee frisch friseur frist fritten froh frosch frost frucht frustration fräulein früh frühling frühlingsrolle frühstück fuchs funke funkeln funktion funktional furchtbar fussel fuß fußball fußballfeld fußboden fußende fußgänger fächer fähig fähigkeit fähre fällig fässchen föderation föhn föhnen fördern fühler führen führer führung füllen gabel galaxie galaxis galerie gallone gandalf gandhi gang gangster gans ganze garage garantie garfield garnele garten gas gasmaske gasse gast gastfreundschaft gasthaus gazelle geben gebet gebiss gebrauchtwagenhändler gebrochen gebrochenes herz geburtstag gebäck gebäude gebühr gedeihen gedicht geduld geduldig gefahr gefallen gefrierschrank gefroren gefährlich gefängnis gefühl gegend gegenseitig gegenstand gegenteil gegenwart gegner geheimnis gehen gehirn gehirnwäsche gehorchen gehäuse gehören geier geige geisel geist geizig gekritzel gelangweilt gelb geld geldbeutel gelee gelegenheit gelehrte gelähmt gemeinschaft gemüse gemütlich gen genau genehmigen genehmigung generation generator generieren genesen genetisch genie genius genossenschaft gentleman geografie geologe geologisch gepard gepäck gepäckträger gerade gerangel gerechtigkeit gericht geringer geruch gerät geröll gerücht gesamt geschehen geschenk geschichte geschirrschrank geschlecht geschlossen geschmack geschrieben geschwindigkeit geschwür geschäft geschäftsmann gesellig gesellschaft gesetz gesetzgebung gesicht gesichtsbemalung gespenst gesprächig gestalten geste gestell gestresst gesund gesundheit getriebe getränk gewahrsam gewalt gewebe gewehr gewicht gewinner gewissen gewitter gewohnheit gewähren gewöhnliche gewürz geysir gier gießen gießkanne gift giftig giftzwerg gipfel gipfelkreuz gips giraffe gitarre gitter gladiator glanz glas glatt glatze glauben glaubensbekenntnis glaubwürdigkeit gleich gleichgewicht gleichung gleiten gletscher gliederung gliedmaßen glitzer globus glocke glockenspiel glut glück glücklich glücksrad glücksspiel glühbirne glühen glühwürmchen gnade gnom goblin gold goldener apfel goldenes ei goldfisch goldkette goldtopf golf golfwagen gong goofy googeln google gorilla gott gottesanbeterin gourmet gouverneur grab graben grabmal grabstein grad graffiti grafik grafiktablett grammatik granatapfel granate grapefruit graph gras grashüpfer grat gratulieren grausam grausamkeit green lantern grenze griechenland griff grill grille grillen grimasse grinch grinsen grippe groschen grotte groß großartig großmutter großvater großzügig gru grube grubenarbeiter grund grundbesitzer grusel gruß größe grün gründe gründen grüßen guerilla guillotine gully gumball gummi gummibärchen gummiwürmchen gurke gurt gut gutschein gymnastik gähnen gänseblümchen gärtner götterspeise gültig günstig gürtel gürteltier haar haare haarfarbe haarig haarschnitt haarschuppen haarspange haarspray haben hackbraten hacke hacken hacker hafen hafenbecken haftung hagel hahn hai haken halb halbinsel halbkreis halbleiter halle hals halsband halskette halskrause halt halterung haltestelle hamburger hammer hammerhai hampelmann hamster hand handbuch handel handfläche handgelenk handlung handschlag handschuh handtuch handwerker handy hantelbank happy meal hardware harfe harmonie harpune harry potter hart hartnäckig harz hase haselnuss hashtag hass haufen haupt hauptquartier hauptstadt haus hausfrau hausmeister hausnummer haustier haustür haut hawaii hawaiihemd hecht hecke heckspoiler heer heftig heil heilen heilig heiligenschein heiligtum heinzelmännchen heiter heizungskessel heiß heiße schokolade held helikopter helium hello kitty helm hemd hemisphäre hemmung henne herausforderung herausgeber herbst herde herkules heroin herrlich herrschaft hersteller herstellung herunterladen herz herzlich willkommen herzog heu heuschrecke hexe hierarchie hieroglyphen high five high heels high score hilfe hilflos hilfreich himbeere himmel himmelbett hindernis hingeben hintergrund hinweis hinzufügen hip hop hippie hirsch historiker historisch hitze hobbit hoch hochhaus hochschule hochzeit hochzeitskutsche hocken hockey hoffen hollywood hologramm holz holzfäller holzscheit homer simpson honig honigwabe horizont horizontal horn horoskop hose hosenstall hosentasche hotdog hotel hubschrauber huf huhn hula hoop hulk hummer humor hund hundehütte hunger hungrig husten hut hydrant hypnotisieren hypothek hypothese hyäne häftling hähnchen hälfte händler hängebauchschwein hängebrücke hängematte hängen hässlich häufig häufigkeit höflich höflichkeit höhe höhle höhlenforscher höhlenmensch hölle hören hüfte hügel hühnchen hündin hüpfen hüpfkästchen hürdenlauf hütte ideal idee identifizieren identifizierung identität ideologie igel ignorant ignoranz ignorieren ikea illegal illusion illustration im ruhestand immigrant immun implikation implizit importieren impuls imstande index indianer indien indikation indirekt individuell industrie industriell infektion infizieren inflation information informell infrastruktur ingenieur inhaber inhalt initiale initiative injektion injizieren inkognito inlineskates inländisch innen innere innerhalb innovation insekt insel insgesamt insider insolvent inspektor inspiration inspirieren installieren instandhaltung instinkt institution instrument integration integriert integrität intel intellektuell intelligenz intensivieren interaktion interaktiv interessant interesse interferenz intern international internet interpretieren intervention interview inuit invasion investition ipad iphone irland irokesenfrisur iron man ironie irreführen irrelevant island isolation israel italien jacht jacke jackie chan jagd jagdziel jagen jaguar jahr jahrbuch jahrestag jahreszeit jahrhundert jalapeno james bond japan jay z jazz jeans jeep jenga jesus jesus christ jet jetski jimmy neutron jo-jo job jockey joghurt john cena john lennon johnny bravo joint jonglieren journalist jugend jung junge jungfrau junior junk food jupiter jury justiz juwel jäger jährlich kabel kabellos kabine kabinett kader kaffee kaffeetasse kahl kaiserliche kakao kakerlake kaktus kalb kalender kalorie kalt kaltwachsstreifen kamel kamera kameramann kamin kamm kampagne kampf kanada kanal kanalisation kanarienvogel kandidat kanister kanone kante kapitalismus kapitel kapitän kappe karaoke karate karneval karotte karte karteikasten karten kartenspiel kartoffel kartoffelbrei kartoffelpuffer karussell kasino kasse kassenbon kassette kastagnetten kastanie katalog katamaran katana katapult katastrophe kategorie kathedrale katy perry katze katzenklo kauen kaufen kaugummi kaugummikugel kaulquappe kaution kaviar kazoo kebab kegel kegelrobbe kehle keim keks keksdose keller kellner kendama kennt kennzeichen keramik kerl kermit kernkraftwerk kernspintomografie kerze kerzenleuchter kerzenständer kessel ketchup kette kettenkarussell kettensäge keuchen keyboard kfc kiefer kies kiffen killerwal kim jong-un kim kardashian kind kindergarten kinderwagen kindheit kindisch king kong kinn kino kirby kirche kirchturm kirschblüte kirsche kissen kissenschlacht kiste kit kitesurfen kitzeln kiwi klang klar klarinette klasse klassenzimmer klassifizieren klassisch klatschen klaue klavier klaviersaite klebeband kleben kleber klebestift klebrig kleeblatt kleid kleider kleiderbügel kleiderschrank klein kleinbus kleiner finger kleinlich klempner klettern klima klimaanlage klinge klingelton klingen klinik klippe klobrille klopfen kloster klumpen kläger klären knall knallfrosch knast kneipe kneten knie knien knoblauch knochen knopf knoten knöchel koala koalition kobra koch kochen koffer kofferraum kohle kohlenstoff kohlrübe kojote kokon kokosnuss kolibri kollege kolonie kolosseum koma kombination kombinieren komet komfort komfortabel komiker komisch komitee kommentar kommerziell kommission kommunale kommunikation kommunismus kommunistisch kompakt kompass kompatibel kompensieren kompetent kompetenz komplett komplex komplikation komponist kompromiss komödie kondenswasser konferenz konfetti konflikt konfrontation konfrontieren konglomerat kongress konkurrieren konkurs konsens konservativ konsistent konsole konsolidieren konstante konstellation konstitutionell konstruieren konstruktiv kontakt kontext kontinent kontinental kontinuierlich konto kontrabass kontraktion kontrast konvention konventionell konversation konvertieren konzentration konzentrieren konzept konzeption konzert konzession kooperieren kopf kopfende kopfhörer kopflaus kopfschmerzen kopftuch kopie kopieren koralle korallenriff koran korb korken korkenzieher korn kornflakes korrektur korrelation korrespondenz korruption kostüm krabbe krake krank krankenhaus krankenschwester krankenwagen krankheit kranz kratzen kraut krawatte krebs kredit kredithai kreditkarte kreide kreis kreuz kreuzfahrt kreuzotter kreuzung kricket kriechen krieg krieger kriegsschiff kriminell krise kristall kritik kritiker kritisch kroatien krokodil krone kronkorken kronleuchter krug kruste kräftig krähe kröte krücke krümelmonster kuba kuchen kuckuck kuckucksuhr kugel kugelfisch kuh kuhglocke kultur kulturell kunde kung fu kunst kupfer kuppel kurs kurve kurz kurze hose kurzschluss kuscheln kuss käfer käfig känguru käse käsekuchen kätzchen köcher köder könig könig der löwen königin königlich königreich körper küche küchentuch kühlschrank künstler künstlerisch künstlich kürbis kürbislaterne kürzen küssen küste küstenwache labor laboratorium labyrinth lachen lachs ladebalken ladegerät laden lady lady gaga lage lager lagerfeuer lagerhaus lakritz laktoseintoleranz lama lamm lampe lampenschirm land landschaft landwirtschaft landwirtschaftlich lange langsam lanze laptop las vegas lasagne laser lassen lasso lastwagen laterne laubhaufen laubsäge lauf laufen lauschen laut lautsprecher lautstärke lava lavalampe lavendel layout leben lebensfähig lebensmittel lebensraum lebensstil leber lebhaft lebkuchen lebkuchenhaus leck lecken lecker leder lederhose leer leeren legal legen legende legislative lego lehm lehnen lehrer lehrplan lehrreich leiche leichtsinn leiden leidenschaft leidenschaftlich leihen leine leinen leistung leiten leiter leiterbahn leiterwagen lektion lemur leonardo da vinci leonardo dicaprio lernen lesen leser lesezeichen letzte leuchtreklame leuchtstab leuchtturm leugnung lexikon liane libelle liberal licht lichtschalter lichtschwert lidschatten liebe liebhaber lieblings liechtenstein liefern lieferung lilie limbo limette limonade limousine linderung lineal linear linie link links linse lippe lippen lippenstift lisa simpson literarisch literatur litfaßsäule litschi lizenz lizenzgebühren lkw lkw-fahrer loben loch locher locken lockenwickler log logik logisch logo lohn lokalisieren london london eye looping lorbeeren lose lotterie loyalität luchs luft luftfahrt luftkissenboot luftmatratze luftschiff luftschloss luigi lunge lungenentzündung lupe lustig lutscher luxemburg lächeln ländlich länge lärm läufer löffel löschen lösen lösung löwe löwenzahn lüfter lüftung lüge machen machomäßig macht madagaskar mafia magazin magersüchtig magie magier magma magnet magnetisch mahlzeit maibaum maid maikäfer mail main mainstream mais maisfeld maki makkaroni maler malkasten mammut manager mandel manege mangel maniküre mann mannschaft mantel manuskript marathon margarine marge simpson marienkäfer marine mario marionette mark zuckerberg marke marketing markieren markt marmelade marmor mars marshmallow maschine maschinen maske maskottchen masse massieren material mathematik mathematisch matratze matrix matrjoschka matsch matze maulkorb maulwurf maurer maus mauseloch maut maximal mayonnaise maßstab mcdonalds mechaniker mechanisch mechanismus medaille medizin medusa meer meerenge meeresfrüchte meerjungfrau meerschweinchen megafon mehl mehrdeutig mehrdeutigkeit mehrere mehrheit meile meint meinung meister mel gibson melken melodie melone meme memorandum menge mensch menschen menschheit menschlicher körper mental mercedes merken merkmal merkur messe messen messer metall meteorit meteorologe methode methodik mexiko michael jackson micky maus miete mieten mieter migration mikrofon mikroskop mikrowelle milch milchmann milchshake milchstraße mild militär minderheit minecraft mineral mineralwasser miniclip minigolf minimieren minimum minion minister ministerium minotaurus minute minze mischen mischpult mischung miss piggy missbrauch mistgabel mitarbeiter mitfahrgelegenheit mitglied mitgliedschaft mitleid mittagessen mitte mittel mittelalterlich mittelklasse mitternacht mittlere mittwoch mixer mobiltelefon mode modedesigner model modell modern modisch modul mohn molekular molekül molkerei moment mona lisa monaco monarch monarchie monat monatlich mond monobraue monopol monster monströs mont blanc montag moos mopp moral mord morgan freeman morgen morse code morty mosaik moschee moskau moskito mother motherboard motiv motivation motor motorrad motte mottenkugel mount everest mount rushmore mozart mr. bean mr. meeseeks mtv muffin multimedia multiplizieren mumie mund mundharmonika murmeln murmeltier muschel museum musical musik musiker muskel muskelkater muskete muster mut mutation mutig mutter muttermal mwst mythos mächtig mädchen mähdrescher märz mäusefalle möbel mögen möglich möglichkeit möhre mönch mörder möwe mücke müde mühe mühle müll müllabfuhr mülleimer müller münze mürrisch müsli mütze nach vorne nachbar nachdenklich nachfrage nachlass nachmittag nachos nachricht nachrichten nacht nachtclub nachteil nachthemd nachtisch nachwuchs nacken nackt nadel nadelkissen nagel nagelfeile nagellack nagelpflege nagelschere nahrung name narbe narr narwal nasa nascar nase nasenbluten nasenhaar nasenlöcher nasenpiercing nasenring nashorn nass national nationalismus nationalist natrium natur nebel necken neffe negativ nehmen nemo neptun nerd nerv nervenzusammenbruch nervös nessie nest nett netz netzwerk neu neueste neugierig neuling neuseeland neutral new york nicht mögen nicht wie nichts nichtschwimmer nickel nicken nickerchen niederlage niederlande niedlich niedrig niedriger niere niesen nike nilpferd ninja nintendo niveau nominieren nominierung nonne norden nordkorea nordpol norm normal norwegen not notenschlüssel notfall notizblock notizbuch notwendig nudel nuklear null nummer nuss nussknacker nussschale nutella nutzer nutzlos nächstenliebe nähen nähmaschine nützlich oase obdachlos obelix oben ober oberarm oberfläche oberteil objekt oboe observatorium obskur obst odysseus ofen offen offensichtlich offiziell offizier ohnmacht ohr ohrenschmalz ohrhörer ohrring ohrwurm oktoberfest oktopus olaf olive olivenöl oma omelett onkel oper operation opernhaus sydney opfer opfern opposition optimismus optimistisch optional oral orang-utan orange orbit orca orchester orchidee ordnen ordner oreo organ organisation organisch organisieren orgel orientierung origami original orthodox oscar osten osterhase ostern otter outfit oval ozean paar pac-man pack paintball paket palast palme panda panel panflöte panik panther pantomime panzer panzerband panzerfaust papagei papageientaucher paparazzi papaya papier papiertüte pappe paprika papst parade paradox parallel paralleluniversum parameter pardon parfüm paris park parkplatz parkuhr parlament partikel partner partnerlook partnerschaft party passage passagier passen passiv passwort pasta pastell pastete patenonkel patent patrick star patriot patrone patronenhülse patrouillieren pauke pause pavian paypal pech pedal pegasus peinlich peitsche pelikan pelz pendel pension pensionierung peperoni peppa pig pepsi perfekt perforieren performance periskop perle permanent person personenschützer persönlich persönlichkeit perücke pest pfad pfadfinder pfanne pfannenwender pfannkuchen pfau pfeffer pfeffersalami pfeife pfeifen pfeil pferd pferdeschwanz pferdestall pfirsich pflanze pflaster pflaume pflege pflegen pflicht pflug pflügen pfote pfund pfütze phantasie philosoph philosophie philosophisch phineas und ferb photoshop photosynthese physalis physik physisch phänomen pi picasso pickel picknick pieksen pikachu pille pilot pilz pinguin pinienkerne pink pinocchio pinsel pinzette pionier pirat piratenschiff pistazie pistole pizza planen planet planke plastik platte plattenspieler plattform platz platzen playstation pluto plädieren plätzchen plötzlich pobacken poesie pogo stick pokemon poker polarlicht pole polieren politik politiker politisch polizei polizist polo pommes pony pop popcorn popeye population pornhub portal porter portion portrait porträt portugal posaune poseidon position positiv post postbote poster postkarte potenzial prahlen praktisch prallen predigen preis preisschild presslufthammer prestige priester primär pringles prinz prinzessin prinzip priorität prisma privat privatsphäre privileg privilegiert probe problem produkt produktion produktiv produzent produzieren professor profi profil profitieren prognose programm programmierer progressiv projekt projektion proklamieren prokrastinieren propaganda propeller proportional protein protest provinz provozieren prozent prozess präferenz prämie präsentation präsident präsidentschaft präsidentschaftswahl präzedenzfall präzise präzision prüfen prüfung psychologe psychologie pu der bär publikum pudding pudel puder pulver puma pumba pumpe punker punkt punkte punktestand puppe puppenhaus pups purzelbaum puzzle pyramide quadrat qual qualifikation qualifizieren qualifiziert qualität qualle quantitativ quarantäne quartal quelle querflöte quote rabatt rache raclette rad radar radiergummi radieschen radikale radio radioaktivität raffiniert rahmen rakete rallye rampe rand randalieren rang rapper rapunzel rasen rasenmäher rasensprenger rasieren rasierer rasierklinge rasiermesser rasierschaum rasse rasseln rassismus rassistisch rat ratatouille rational ratte rau raub rauben raubtier rauch rauchen raum raumanzug raumschiff raupe ravioli reaktion reaktor realisieren realismus realistisch realität rebell rebellion rechen rechnen rechnung recht rechteck rechter flügel rechtfertigen rechtfertigung rechts rechtsstreitigkeiten rechtswidrig recyceln recycling reddit rede redner redundanz referenz reflektieren reflexion reform regal regel regen regenbogen regenmantel regenschirm regentropfen regenwald regenwolke regierung region regional regisseur registrieren regulär reh rehabilitation reiben reich reichlich reichtum reifen reihe reihenfolge rein reinheit reinigen reinkarnation reis reise reisender reisepass reiten reizen reißverschluss reißverschlussverfahren rekrutieren relativ relevant relevanz religion religiös rennauto rennen rentier rentner reparieren reporter reproduktion reproduzieren reptil republik reservieren reservoir residenz resort respekt respektabel ressource restaurant reste rettich rettung rettungsring rettungsweste revolution revolutionär revolver rezension rezept rezeption rezeptionist rezession rhetorik rhythmus richter richtig richtlinie richtung rick riechen riese riesenrad rinde rindfleisch ring ringelblume ringelschwanz ringen rinne rippe risiko riss ritter ritual robbe robin hood roboter rochen rock rockstar roh rohr rolle rollen roller rollladen rollschuhe rolltreppe rom roman romantisch rosarote panther rose rosine rot rote beete roter teppich rotieren rotkehlchen route routine rubin rucksack ruder ruf rugby ruhe ruhig ruhm ruine rumänien runde runden rune russland rutsche rutschen rutschig räuber räucherstäbchen räumlich röntgen röntgenstrahlung röstaroma rübe rücken rückenschmerzen rückgrat rückgängig rückkehr rückseite rücksichtslos rückspiegel rücktritt rückzug rührei rühren rülpsen rüstung sabbern sachen sachverstand safari safe saft saftpresse sagen sahne saisonal salami salat salon salz salzstange salzwasser samen sammeln sammlung samstag samsung samt sand sandale sandalen sandbank sandburg sandkasten sandsturm sanduhr sandwich sanft sarg satellit sattel sattelschlepper saturn satz sau sauber sauer sauerstoff saufen saugglocke sauna saxofon scan schach schacht schaden schaf schaffung schal schale schallplatte schalter schaltknüppel schamesröte schande scharf scharfe soße scharfschütze schatten schatz schatzkiste schatzmeister schauen schauer schaufel schaufensterpuppe schaukel schaukelpferd schaukelstuhl schaumschläger schauspieler scheibe scheibenwelt scheibenwischer scheidung scheinen scheitern schemel schenkel schenken schere scherz scherzkeks scheune schicht schicksal schiedsrichter schiefer turm von pisa schielen schießen schiff schiffstaufe schiffswrack schild schilf schimmel schimpanse schinken schlacht schlachter schlachtfeld schlaf schlafanzug schlafen schlafend schlafenszeit schlafstörung schlafzimmer schlag schlaganfall schlagen schlagsahne schlagzeug schlamm schlange schlauch schlecht schleich schleichwerbung schleier schleife schleifen schleifpapier schleim schleppen schleppend schleuder schleudern schließen schlitten schlittschuh schloss schlucht schluck schluckauf schlucken schlumpf schläger schlüssel schlüsselanhänger schlüsselbund schmelzen schmerz schmerzen schmerzlich schmetterling schmied schmiede schminke schminken schmutzig schnabel schnabeltier schnappen schnauze schnecke schnee schneeball schneeballschlacht schneebesen schneeflocke schneemann schneesturm schneiden schnell schnellstraße schnitt schnittstelle schnitzen schnorchel schnorcheln schnuller schnurrbart schnäppchen schnüffeln schnürsenkel schock schokolade schonen schornstein schornsteinfeger schottenrock schotter schottland schoß schrank schranke schraube schraubenschlüssel schrei schreiben schreibfeder schreibschrift schreibtisch schreien schreiten schriftsteller schritt schrott schrumpfen schub schubkarre schublade schuh schuhkarton schuld schule schulter schuppen schuss schutz schutzhelm schwach schwalbe schwamm schwan schwanger schwanz schwarm schwarz schwarzes loch schwarzwald schweben schweden schwefel schweigen schwein schweinchen dick schweinestall schweiz schweiß schweißer schwelle schwenken schwer schwere schwerkraft schwert schwertfisch schwester schwierig schwierigkeit schwimmbad schwimmen schwindelig schwingen schwitzen schwung schwäche schwören schädel schädlich schätzen schön schüchtern schüler schüssel schütteln schützen scooby doo sechseck sechserpack see seebrücke seegurke seehund seeigel seekrank seekuh seele seelöwe seemann seepferdchen seerose seestern seetang seewolf segelboot segelflieger segeln segeltuch segnen segway sehen seide seife seifenblase seifenoper seil seilrutsche seilspringen seiltänzer seite sekretion sekretär sektion sektor sekunde sekundär selbst selbstmord selten seltsam seminar senden senf senior senke sensation serie server serviette sessel session seuche seufzer shampoo sherlock holmes shrek sichel sicher sicherheit sicherheitsdienst sicherheitsgurt sicherheitsnadel sichern sicherung sicht sichtbar siedlung sieg siegel sightseeing silbe silber silberbesteck silo silvester simon and garfunkel singapur singen single sinken sinn sinnvoll sitz sitzbank sitzen sitzsack skalpell skandal skateboard skateboardfahrer skelett ski skilift skispringen skittles skizzieren sklave skorpion skribbl.rs skrillex skript skull skulptur skydiving skyline skype slalom slinky slogan slot smaragd smash smell sneeze snoopy snowboard social media socke socken software sogar sohn solar soldat solidarität solide solo sombrero sommer sommersprosse sommersprossen songtext sonic sonne sonnenaufgang sonnenblume sonnenbrand sonnenbrille sonnenfinsternis sonnenschein sonnenschirm sonnensystem sonnenuntergang sonntag sopran sorge sozial sozialistisch soziologie soße spaghetti spaghettieis spaghettimonster spalt spanien spanne spannen spannung spargel sparschwein spartacus spaten spaß specht speck speer speichel speichern speisekarte speisen spektrum spekulieren spenden spender sperren spezialist spezies sphinx spiderman spiegel spiegelei spiel spielen spieler spielplatz spielraum spielzeug spieß spinat spinne spion spirale spitze spitzer spitzhacke spitzmaus spongebob spontan spore sport sprache sprecher sprengen springen spritze sprudel sprungturm sprühen sprühfarbe spucke spucken spule spur spät spülen spüllappen staatsangehörigkeit staatsbürgerlich stabil stachel stacheldraht stachelrochen stachelschwein stadion stadt staffelei stahl stall stamm stampfen stand standard stangenbrot star wars stark start starten startseite station statistiken statistisch stativ statue stau staub staudamm steak steam stechen steckdose stecker stecknadel stegosaurus stehen stehlampe steigen steigung steil stein steinbock steinzeit stelle stellen stellvertreter stempel stengel stephen hawking sterben stereo stern sternenhimmel sternfrucht sternhagelvoll stetig steuergerät steuerung steuerzahler steve jobs steward stewardess stich stichprobe stiefel stift stiftung stil stimme stimmung stimulation stinktier stipendium stirn stirnband stock stoff stolpern stolz stoppschild stoppuhr storch stornieren stoßen stoßstange strafe strafrechtlich verfolgen strahl strahlung strand strandkorb strategisch strauß straße straßenbahn straßensperre strecken streichholz streichholzschachtel streifen streik streit streng stress streuen stricken stroh strohhalm strom strudel struktur strukturell strumpfhose stubenhocker student studie studieren studio stuhl stuhlbein stumpf stunde stur sturm sturz städtisch stärke stöhnen stöpsel störung stück stürzen subjektiv substantiv substanz suche suchen sudoku suezkanal suite summe sumo sumpf superintendent superkraft superman supermarkt supervisor suppe suppenkelle surfbrett sushi sweatshirt symbol symmetrie sympathisch symphonie symptom syndrom system systematisch szenario szene säbel säge sänger säule säure süchtig süd südafrika süden südpol sünde süss süß süßholz raspeln t-shirt tabak tabelle tablet tablett tablette tacker taco tafel tag tagebuch tageslicht taille taktik tal talentiert talentshow tandem tank tannenbaum tannenzapfen tante tanzen tapete tarzan tasche taschenlampe taschentuch tasmanischer teufel tasse tastatur taste tatsache tattoo tau taub taube tauchen tauchgang tausendfüßer tausendfüßler taxi taxifahrer technik technisch technologie teddybär tee teekanne teelicht teelöffel teenager teich teig teil teilen teilnehmen teilnehmer teilt teilzeit telefon telefonbuch telefonkabel teleskop teletubby teller tempel temperatur tempo tempus tendenz tennis tennisschläger tentakel teppich terminal terminator terrarium terrasse terrorist tetra pak tetris teuer teufel text textmarker textur thaddäus tentakel the beatles theater thema theologie theoretiker theorie therapeut therapie thermometer these thor thron thunfisch tick tide tief tiefgreifend tiegel tier tierarzt tierfutter tierhandlung tierwelt tiger tintenfisch tintenpatrone tippen tiramisu tisch tischdecke tischkicker tischplatte tischtennisschläger titanic titel toast toaster tochter tod toilette tolerant tolerieren tomate ton tonhöhe tonleiter tonne topf topflappen tor tornado torpedo torte tortenheber torwart tot totem totenkopf toter winkel tourismus tourist tradition traditionell tragbar tragen tragfläche tragödie trainer trainieren trakt traktor trampolin transaktion transfer transparent transport trauben traubensaft trauer traum traumfänger traurig treffen treiber treibsand treibstoff trend trennen trennung treppe tresorraum trete treten tretmühle treu treuhänder triangel tribut trick triebwagen triebwerk trinken trinkgeld trittstufe trivial trocken trommel trompete tropfen trophäe tropisch trottel trotz truhe trupp truthahn träger träne träumen trüffel tschechien tuba tube tugend tukan tumor tunnel tunnelblick tupperdose turban turm turmalin turnier turnschuh tweety twitter tycoon typisch tyrannosaurus rex täglich täter töne töten tödlich tür türkei türklinke türschloss türsteher türstopper u-bahn u-boot ufer ufo uhr ukulele ultimativ umarmen umfang umfassen umfassend umfrage umgeben umgebung umhang umkehren umstand umstritten umwelt umweltverschmutzung unabhängig unangemessen unangenehm unbequem unbesetzt undicht uneinigkeit unendlich unerwartet unfair unfall unfähig unglaublich unglücklich uniform union universal universität universum unmöglich unpassend unruhe unruhig unschuldig unsicherheit unsichtbar unsinn unterbrechen unterdrücken untergewichtig untergraben untergrund unterhalten unterhaltung unterhose unterlassung unternehmen unterschied unterschrift unterseite untersetzer unterstreichen unterstützung untersuchung unvergesslich unvermeidlich unwahrscheinlich unzureichend uranus urheberrecht urin urknall urlaub ursache ursprung urteil usain bolt usb vage vakuum vampir van vanille variable variante variation vater vatikan vault boy veganer vegetarier vegetation vektor velociraptor vene ventilator venus venusfliegenfalle verachten verachtung veranda veranschaulichen verantwortlich verantwortung verbal verband verbessern verbesserung verbieten verbindung verblassen verbot verbrauch verbraucher verbrechen verbrecher verbreitet verbringen verbunden verbündete verdacht verdammt verdampfen verdanken verdienen verdünnen verein verfahren verfassung verfault verfolgen verfolgung verfolgungsjagd verfrüht verfügbar vergangenheit vergeben vergeblich vergehen vergessen vergiften vergleich vergleichbar vergleichen vergnügen vergrößern vergütung verhalten verhandlung verheiratet verhindern verhältnis verjährung verkauf verkaufen verkehr verkehrskontrolle verkleidung verknüpfung verkäufer verlangen verlassen verlegenheit verleihen verletzen verletzt verletzung verlieren verlierer verlies verlust verlängert vermeiden vermieter vermuten vermögen vernachlässigen verordnung verpackung verpflichten verpflichtung verraten verringern verrückt versagen versammlung versatz verschieben verschiebung verschlechtern verschmutzung verschwinden verschwörung verschütten versichern versicherung versicherungskaufmann versprechen verstand versteck verstehen versteigerung verstärken versuch versuchen versuchung versöhnen verteidigen verteilen verteiler vertikal vertikale vertrag vertrauen vertreten vertreter verurteilen verwalten verwaltung verwandeln verwandtschaft verwechslung verweigern verweilen verweisen verweisung verwenden verwirrt verwöhnen verzeichnis verzerren verzerrung verzichten verzweiflung verzögern veränderung verärgert veröffentlichen veröffentlichung veteran video videospiel vieh vielfalt viertel villa vin diesel violine virtual reality virus vision visuell vitamin vodka vogel vogelbad vogelbeere vogelhaus vogelnest vogelscheuche vogelspinne vogelstrauß volk volkszählung voll volleyball vollkornbrot vollmond vollständig vollzeit volumen voodoo voraus vorausgehen vorbereitung vorderseite vorfall vorgänger vorhang vorhersagbar vorlesung vorort vorrichtung vorschlag vorschlagen vorschlaghammer vorsichtig vorspulen vorstellen vorstellungskraft vorteil vorurteil vorübergehend vulkan vulkanologe vuvuzela w-lan wachs wachsen wachstum wackeln waffe waffel wagen wahl wahlkreis wahr wahrheit wahrnehmen wahrnehmung wahrscheinlich wahrscheinlichkeit wal wald waldbrand wall-e walnuss walross wand wandern wanderstock wanderung wange wanze warm warnen warnung warnweste wart warten warteschlange wartezimmer warze waschbecken waschbrettbauch waschbär waschen waschlappen waschmaschine waschstraße wasser wasserfall wasserfarbkasten wasserhahn wasserkreislauf wasserpfeife wasserpistole wasserschildkröte wattestäbchen weben webseite wecker weg weide weihnachten weihnachtsbaum weihnachtsmann wein weinen weinglas weinrebe weintrauben weise weit weizen weiß welle wellensittich welt weltlich weltraum wende wenige werbespot werbung werdegang werden werfen werkstatt werkzeug werkzeugkasten wert wertvoll werwolf wesen wesentlich wespe westen westlich wettbewerb wettbewerbsfähig wette wetter wetterfrosch wettervorhersage whatsapp whiskey wichtig wickeln widder widerspruch widerstand widerstehen widerwillen widmen wiederbelebung wiederherstellung wiederholen wiederholung wiegen wiese wiesel wild wildnis wildschwein wildwasserbahn willenskraft william shakespeare william wallace willkürlich wimper wind windbeutel windel windmühle windows windrad windsack windschutzscheibe windsurfer winkel winter winzer winzig wippe wirbel wirbelsäule wirklichkeit wirksam wirt wirtschaft wirtschaftlich wirtschaftsprüfer wischen wissen wissenschaft wissenschaftler wissenschaftlich witwe woche wochenende wohlergehen wohlstand wohn wohnung wohnzimmer wolf wolke wolkenkratzer wolle wollen wolverine wonder woman wort wortlaut wrack wrestler wrestling wunde wunder wunderlampe wunderland wunschliste wurm wurst wurzel wut wählen wähler wählerschaft währung wäsche wäschespinne wäscheständer wöchentlich wörterbuch wünschenswert würde würfel würfelqualle würstchen wüste wütend xbox xylofon yacht yeti yin yang yoda yoshi youtube youtuber zahl zahlen zahlung zahn zahnarzt zahnbürste zahnfee zahnlücke zahnpasta zahnseide zahnspange zahnstein zahnstocher zapfhahn zart zauberer zauberstab zaubertrank zaubertrick zaun zebra zebrastreifen zecke zeh zehe zehnagel zeichenfolge zeichnen zeichnung zeigen zeit zeitgenössisch zeitlupe zeitmaschine zeitplan zeitraum zeitschrift zeitung zelda zelle zelt zelten zement zensur zentaur zentral zeppelin zerbrechen zeremonie zerfallen zerreißen zerren zerstören zerstörung zertifikat zertrümmern zeuge zeus zickzack ziege ziegelstein ziegenbart ziehen ziel zielsetzung zigarette zikade zimmer zimmermann zimmerpflanze zinn zirkel zirkus zirkusdirektor zitat zitrone zitteraal zittern zivilisation zivilist zoll zombie zone zoo zoomen zoowärter zorn zorro zucchini zucken zucker zuckerguss zuckerstange zuckerwatte zuerst zufall zufrieden zufriedenstellend zufällig zug zugbrücke zugeben zugriff zugänglich zuhause zukunft zuma zunge zuordnung zupfen zur verfügung stellen zurück zurückhalten zurückhaltung zurückspulen zurücktreten zusammenarbeit zusammenbrechen zusammenbruch zusammenfassung zusammenstoß zusammenzucken zusatz zuschlagen zustand zustimmen zustimmung zuständigkeit zutat zuverlässig zuversichtlich zuweisung zwang zweck zweifel zweig zweite zwerg zwiebel zwilling zwillinge zwischendecke zyklop zyklus zylinder zypresse zäh zähler zärtlich zögern zügel zündschnur äffchen ägypten ähneln ähnlich ähnlichkeit älter änderung äquator ärger ärgern ärmel ästhetisch äußere äußern öffentlichkeit öffnen ökonom öl österreich überarbeiten überblick übereinstimmen überfall übergeben übergewichtig überleben überlebende überlebender überlegen überleitung überraschend überrascht überraschung überschreiten überschrift überschuss übersehen übersetzen übertragung übertreiben überwachung überwintern überwältigen überzeugen überzeugung üblich übung ================================================ FILE: internal/game/words/en_gb ================================================ abandon abbey ability able abnormal abolish abortion abraham lincoln abridge absence absent absolute absorb absorption abstract abundant abuse abyss academic academy accent accept acceptable acceptance access accessible accident accompany accordion account accountant accumulation accurate ac/dc ace achievement acid acne acorn acquaintance acquisition act action activate active activity actor acute add addicted addiction addition address adequate adidas adjust administration administrator admiration admire admission admit adopt adoption adorable adult advance advantage adventure advertisement advertising advice adviser advocate aesthetic affair affect affinity afford afraid africa afro afterlife afternoon age agency agenda agent aggressive agile agony agree agreement agricultural agriculture aid aids air airbag air conditioner aircraft airhostess airline airplane airport aisle aladdin alarm albatross album alcohol alert alien alive allergy alley alligator allocation allow allowance ally almond aloof alpaca altar aluminium amateur amber ambiguity ambiguous ambition ambitious ambulance amendment america ample amputate amsterdam amuse anaconda analogy analysis analyst anchor android angel angelina jolie anger angle anglerfish angry angry birds animal animation anime ankle anniversary announcement annual anonymous answer ant antarctica anteater antelope antenna anthill anticipation antivirus anubis anvil anxiety apartment apathy apocalypse apologise apology apparatus appeal appear appearance appendix appetite applaud applause apple apple pie apple seed applicant application applied appoint appointment appreciate approach appropriate approval approve apricot aquarium arbitrary arch archaeological archaeologist archer architect architecture archive area arena argentina argument aristocrat arm armadillo armchair armour armpit army arrange arrangement arrest arrogant arrow art article articulate artificial artist artistic ascertain ash ashamed asia ask asleep aspect assassin assault assembly assertion assertive assessment asset assignment association assume assumption assurance asterix asteroid astonishing astronaut asylum asymmetry athlete atlantis atmosphere atom attach attachment attack attention attic attitude attract attraction attractive aubergine auction audi audience auditor aunt australia authorise authority autograph automatic autonomy available avenue average aviation avocado avoid awake award aware awful awkward axe axis baboon baby back backbone backflip background backpack back pain bacon bad badger bag bagel bagpipes baguette bail bait bake bakery baklava balance balanced balcony bald ball ballerina ballet balloon ballot bambi bamboo ban banana band bandage bandana bang banjo bank banker bankruptcy banner bar barack obama barbarian barbecue barbed wire barber barcode bare bargain bark barn barrel barrier bartender bart simpson base baseball basement basic basin basis basket basketball bat bath bathroom bathtub batman battery battle battlefield battleship bay bayonet bazooka beach beak beam bean beanbag beanie beanstalk bear beard bear trap beat beatbox beautiful beaver become bed bed bug bedroom bed sheet bedtime bee beef beer beet beethoven beetle beg begin beginning behave behaviour behead belief bell bellow belly belly button belong below belt bench bend beneficiary benefit berry bet betray bible bicycle big ben bike bill bill gates billiards bin bind bingo binoculars biography biology birch bird bird bath birthday biscuit bishop bitch bitcoin bite bitter black blackberry black friday black hole blackmail blacksmith blade blame bland blank blanket blast bleach bleed blender bless blimp blind blindfold blizzard block blonde blood bloodshed bloody blow blowfish blue blueberry blue jean blush bmw bmx boar board boat bobsled body bodyguard boil bold bolt bomb bomber bomberman bond bone booger book bookmark bookshelf boom boomerang boot boots border borrow bother bottle bottle flip bottom bounce bouncer bow bowel bowl bowling box boy bracelet braces bracket brag brain brainwash brake branch brand brave brazil bread break breakdown breakfast breast breath breathe breed breeze brewery brick bricklayer bride bridge bring broadcast broccoli broken broken heart bronze broom broomstick brother brown brownie bruise brunette brush bubble bubble gum bucket budget buffet bugs bunny building bulb bulge bull bulldozer bullet bulletin bump bumper bundle bungee jumping bunk bed bunny bureaucracy bureaucratic burglar burial burn burp burrito burst bury bus bus driver bush business businessman bus stop busy butcher butler butt cheeks butter butterfly button buy cab driver cabin cabin crew cabinet cable cactus cafe cage cake calculation calendar calf call calm calorie camel camera camp campaign campfire camping can canada canary cancel cancer candidate candle candy floss cane canister cannon can opener canvas canyon cap capable cape capital capitalism cappuccino capricorn captain captain america captivate capture car carbon card cardboard care career careful carnival carnivore carpenter carpet carriage carrier carrot carry cart cartoon carve car wash case cash casino cassette cast castle casualty cat catalogue catapult catch category cater caterpillar catfish cathedral cattle cat woman cauldron cauliflower cause cautious cave caveman caviar ceiling ceiling fan celebrate celebration celebrity cell cellar cello cement cemetery censorship census centaur center centipede central century cerberus cereal ceremony certain certificate chain chainsaw chair chalk challenge chameleon champagne champion chance chandelier change channel chaos chap chapter character characteristic charge charger charismatic charity charlie chaplin charm chart charter chase chauvinist cheap check cheek cheeks cheerful cheerleader cheese cheeseburger cheesecake cheetah chef chemical chemistry cheque cherry cherry blossom chess chest chest hair chestnut chestplate chew chewbacca chicken chief chihuahua child childhood childish chime chimney chimpanzee chin china chinatown chinchilla chip chocolate choice choke choose chop chopsticks chord chorus christmas chrome chronic chuck norris church cicada cigarette cinema circle circulation circumstance circus citizen city civic civilian civilisation claim clap clarify clarinet clash class classical classify classroom claw clay clean clear clearance clerk clickbait cliff climate climb clinic cloak clock close closed cloth clothes cloud clover clown clownfish club clue cluster coach coal coalition coast coaster coast guard coat cobra cockroach cocktail coconut cocoon code coffee coffee shop coffin coin coincide coincidence cola cold collapse collar colleague collect collection college colon colony colosseum colour colour-blind colourful column coma comb combination combine comedian comedy comet comfort comfortable comic book command commander comment commerce commercial commission commitment committee common communication communism communist community compact company comparable compare comparison compartment compass compatible compensate compensation compete competence competent competition competitive complain complete complex compliance complication composer compound comprehensive compromise computer computing concede conceive concentrate concentration concept conception concern concert concession conclusion concrete condiment condition conductor cone conference confession confidence confident confine conflict confront confrontation confused confusion conglomerate congratulate congress connection conscience conscious consciousness consensus conservation conservative consider considerable consideration consistent console consolidate conspiracy constant constellation constituency constitution constitutional constraint construct constructive consultation consumer consumption contact contain contemporary contempt content contest context continent continental continuation continuous contract contraction contradiction contrary contrast contribution control controller controversial convenience convenient convention conventional conversation convert convict conviction convince cook cookie cookie jar cookie monster cool cooperate cooperation cooperative cope copper copy copyright coral coral reef cord core cork corkscrew corn corner cornfield corporate corpse correction correlation correspond correspondence corruption costume cottage cotton cough council count counter country countryside coup couple courage course court courtesy cousin cover coverage cow cowbell cowboy coyote crab crack craft craftsman crash crash bandicoot crate crayon cream create creation credibility credit credit card creed creep creeper crew cricket crime criminal cringe crisis critic critical criticism croatia crocodile croissant crop cross crossbow crossing crouch crow crowbar crowd crown crucible crude cruel cruelty cruise crust crutch cry crystal cuba cube cuckoo cucumber cultivate cultural culture cup cupboard cupcake cupid curious curl currency current curriculum curry curtain curve cushion custody customer cut cute cutting cyborg cycle cylinder cymbal daffy duck dagger daily dairy daisy dalmatian damage damn dance dandelion dandruff danger dangerous dare dark darts darwin darwin watterson dashboard date daughter day daylight dead deadline deadly deadpool deaf deal dealer death debate debt debut decade decay decide decisive deck declaration decline decoration decorative decrease dedicate deep deer default defeat defence defend defendant deficiency deficit define definite definition degree delay delegate delete delicate deliver delivery demand democracy democratic demolish demon demonstrate demonstration demonstrator denial denounce density dent dentist deny deodorant depart departure depend dependence dependent deposit depressed depression deprivation deprive deputy derp descent describe desert deserve design designer desirable desire desk despair desperate despise dessert destruction detail detective detector deter deteriorate detonate develop development deviation devote dew dexter diagnosis diagonal diagram dialect dialogue diameter diamond dice dictate dictionary die diet differ difference different difficult difficulty dig digital dignity dilemma dilute dimension dine dinner dinosaur dip diploma diplomat diplomatic direct direction director directory dirty disability disadvantage disagreement disappear disappoint disappointment disaster discipline disco discord discount discourage discourse discover discovery discreet discrimination discuss disease disguise dish dishrag disk dislike dismiss dismissal disorder dispenser display disposition dispute dissolve diss track distance distant distinct distort distortion distribute distributor district disturbance diva dive divide dividend division divorce dizzy dna dock doctor document dog doghouse doll dollar dollhouse dolphin dome domestic dominant dominate domination dominoes donald duck donald trump donate donkey donor door doorknob dora doritos dose dots double doubt dough download dozen dracula draft drag dragon dragonfly drain drama dramatic draw drawer drawing dream dress dressing drift drill drink drip drive driver drool drop droplet drought drown drug drum drum kit dry duck duct tape due duel duke dull dumbo dump duration dust duty dwarf dynamic dynamite eager eagle ear earbuds early earth earthquake earwax east easter easter bunny easy eat eavesdrop echo eclipse economic economics economist economy edge edition education educational eel effect effective efficient effort egg ego egypt eiffel tower einstein elbow elder elect election electorate electric car electric guitar electrician electricity electron electronic electronics elegant element elephant elevator eligible eliminate elite elmo elon musk eloquent elsa embark embarrassment embassy embers embryo emerald emergency eminem emoji emotion emotional emphasis empire empirical employ employee employer employment empty emu encourage encouraging end endure enemy energy engagement engine engineer england enhance enjoyable enlarge ensure enter entertain entertainment enthusiasm enthusiastic entitlement entry envelope environment environmental episode equal equation equator equilibrium equipment era erosion error escape eskimo espresso essay essence essential establish established estate estimate eternal ethical ethics ethnic europe evaporate even evening evolution exact exaggerate exam examination example excalibur excavation excavator exceed exception excess exchange excited excitement exciting exclude exclusive excuse execute execution executive exemption exercise exhibit exhibition exile exit exotic expand expansion expect expectation expected expedition expenditure expensive experience experienced experiment experimental expert expertise explain explanation explicit explode exploit exploration explosion export expose exposure express expression extend extension extent external extinct extraordinary extraterrestrial extreme eye eyebrow eyelash eyeshadow fabric fabulous facade face facebook face paint facility fact factor factory fade fail failure faint fair fairy faith faithful fake teeth fall false fame familiar family family guy fan fanta fantasy far fare farm farmer fascinate fashion fashionable fashion designer fast fast food fast forward fastidious fat father fault favour favour favourable favourite fax fear feast feather feature federal federation fee feedback feel feeling feminine feminist fence fencing fern ferrari ferry festival fever few fibre fiction fidget spinner field fig fight figure figurine file fill film filmmaker filter final finance financial find fine finger fingernail fingertip finish finished finn finn and jake fire fire alarm fireball firecracker fire engine firefighter firefly firehouse fire hydrant fireman fireplace fireproof fireside firework firm first firsthand fish fish bowl fisherman fist fist fight fit fitness fitness trainer fix fixture fizz flag flagpole flamethrower flamingo flash flashlight flask flat flavour flawed flea fleet flesh flexible flight fling flock flood floodlight floor floppy disk florida florist flour flourish flower flu fluctuation fluid flush flute fly flying pig fly swatter fog foil fold folder folk folklore follow food fool foolish foot football forbid force forecast forehead foreigner forest forest fire forestry forge forget fork form formal format formation formula formulate fort fortress fortune forum forward fossil foster foundation fountain fox fraction fragment fragrant frame france franchise frank frankenstein fraud freckle freckles fred flintstone free freedom freeze freezer freight frequency frequent fresh freshman fridge friend friendly friendship fries frighten frog front frostbite frosting frown frozen fruit frustration fuel full full moon full-time fun function functional fund funeral funny fur furniture fuss future gain galaxy gallery gallon game gandalf gandhi gang gangster gap garage garbage garden gardener garfield garlic gas gas mask gasoline gasp gate gaze gear gem gender gene general generate generation generator generous genetic genie genius gentle gentleman genuine geography geological germ germany gesture get geyser ghost giant gift giraffe girl give glacier glad gladiator glance glare glass glasses glide glimpse glitter globe gloom glorious glory gloss glove glow glowstick glue glue stick gnome go goal goalkeeper goat goatee goblin god godfather gold gold chain golden apple golden egg goldfish golf golf cart good goofy google goose gorilla government governor gown grace grade gradual graduate graduation graffiti grain grammar grand grandfather grandmother grant grapefruit grapes graph graphic graphics grass grasshopper grateful grave gravedigger gravel graveyard gravity great great wall greece greed green green lantern greet greeting gregarious grenade grid grief grill grimace grin grinch grind grip groan groom ground grounds grow growth gru grumpy guarantee guard guerrilla guess guest guide guideline guillotine guilt guinea pig guitar gumball gummy gummy bear gummy worm gun gutter habit habitat hacker hair hairbrush haircut hair roller hairspray hairy half hall hallway halo halt ham hamburger hammer hammock hamster hand handicap handle handshake handy hang hanger hanger happen happy happy meal harbour harbour hard hard hat hardship hardware harm harmful harmonica harmony harp harpoon harry potter harsh harvest hashtag hat hate haul haunt have hawaii hay hazard hazelnut head headache headband headboard heading headline headphones headquarters heal health healthy hear heart heat heaven heavy hedge hedgehog heel height heir heist helicopter hell hello kitty helmet help helpful helpless hemisphere hen herb hercules herd hermit hero heroin hesitate hexagon hibernate hiccup hide hierarchy hieroglyph high high five high heels highlight high score highway hike hilarious hill hip hip hop hippie hippo historian historical history hit hitchhiker hive hobbit hockey hold hole holiday hollywood holy home home alone homeless homer simpson honest honey honeycomb honour honourable hoof hook hop hope hopscotch horizon horizontal horn horoscope horror horse horsewhip hose hospital hospitality host hostage hostile hostility hot hot chocolate hot dog hotel hot sauce hour hourglass house houseplant housewife housing hover hovercraft hug huge hula hoop hulk human human body humanity hummingbird humour hunger hungry hunter hunting hurdle hurt husband hut hyena hypnotise hypothesis ice iceberg ice cream ice cream van icicle idea ideal identification identify identity ideology ignorance ignorant ignore ikea illegal illness illusion illustrate illustration image imagination imagine immigrant immigration immune impact imperial implication implicit import importance important impossible impress impressive improve improvement impulse inadequate inappropriate incapable incentive inch incident include incognito income incongruous increase incredible independent index india indication indigenous indirect individual indoor indulge industrial industry inevitable infect infection infinite inflate inflation influence influential informal information infrastructure ingredient inhabitant inherit inhibition initial initiative inject injection injure injury inn inner innocent innovation inquest insect insert inside insider insight insist insistence insomnia inspector inspiration inspire instal install instinct institution instruction instrument insufficient insurance insure integrated integration integrity intel intellectual intelligence intense intensify intention interaction interactive interest interesting interface interference intermediate internal international internet interpret interrupt intersection intervention interview introduce introduction invasion invention investigation investigator investment invisible invitation invite ipad iphone ireland iron iron giant iron man irony irrelevant island isolation israel issue italy item ivory ivy jacket jackhammer jackie chan jack-o-lantern jaguar jail jalapeno jam james bond janitor japan jar jaw jay-z jazz jealous jeans jeep jello jelly jellyfish jenga jerk jest jester jesus christ jet jet ski jewel jimmy neutron job jockey john cena johnny bravo joint joke joker journal journalist journey joy judge judgment judicial juggle juice jump jump rope junction jungle junior junk food jurisdiction jury just justice justification justify kangaroo karaoke karate katana katy perry kazoo kebab keep keg kendama kermit ketchup kettle key keyboard kfc kick kid kidney kill killer kim jong-un kind kindergarten king kingdom king kong kinship kirby kiss kit kitchen kite kitten kiwi knead knee kneel knife knight knit knock knot know knowledge knuckle koala koran kraken kung fu label laboratory labour labourer lace lack ladder lady ladybird lady gaga lake lamb lamp land landlord landowner landscape lane language lantern lap laptop large lasagna laser lasso last las vegas late latest laugh launch laundry lava lava lamp law lawn lawn mower lawyer lay layer layout lazy lead leader leadership leaf leaflet leak lean learn lease leash leather leave lecture leech left leftovers leg legal legend legislation legislative legislature lego legs leisure lemon lemonade lemur lend length lens leonardo da vinci leonardo dicaprio leprechaun lesson let letter lettuce level levitate liability liberal liberty librarian library licence license lick lid lie life lifestyle lift light lightbulb lighter lighthouse lightning lightsaber like likely lily lilypad limb limbo lime limit limitation limited limousine line linear linen linger link lion lion king lip lips lipstick liquid liquorice list listen literacy literary literature litigation litter box live lively liver lizard llama load loading loaf loan lobby lobster locate location lock lodge log logic logical logo lollipop lolly london london eye lonely long look loop loose loot lose loser loss lost lot lotion lottery loud lounge love lover low lower loyal loyalty luck lucky luggage luigi lumberjack lump lunch lung lynx lyrics macaroni machine machinery macho madagascar mafia magazine magic magician magic trick magic wand magma magnet magnetic magnifier magnitude maid mail mailbox mailman main mainstream maintenance major majority make makeup mall mammoth man manage management manager manatee manhole manicure mannequin manner mansion mantis manual manufacture manufacturer manuscript map maracas marathon marble march margarine margin marigold marine mario mark market marketing mark zuckerberg marmalade marmot marriage married mars marsh marshmallow mascot mask mass massage master match matchbox material mathematical mathematics matrix matter mattress mature maximum mayonnaise mayor maze mcdonalds meadow meal mean meaning meaningful means measure meat meatball meatloaf mechanic mechanical mechanism medal medicine medieval medium medusa meerkat meet meeting megaphone melon melt member membership meme memorable memorandum memorial memory mental mention menu mercedes merchant mercury mercy merit mermaid message messy metal meteorite method methodology mexico michael jackson mickey mouse microphone microscope microsoft microwave middle middle-class midnight migration mild mile military milk milkman milkshake milky way mill mime mind mine minecraft miner mineral miniclip minigolf minimise minimum minion minister ministry minivan minor minority minotaur mint minute miracle mirror miscarriage miserable misery mislead miss missile mist mix mixture mobile mobile phone model modern modest module mohawk mole molecular molecule moment momentum mona lisa monarch monarchy monastery monday money monk monkey monopoly monster monstrous mont blanc month monthly mood moon moose mop moral morale morgan freeman morning morse code morsel mortgage morty mosaic mosque mosquito moss moth mothball mother motherboard motif motivation motorbike motorcycle motorist motorway mould mould mountain mount everest mount rushmore mourning mouse mousetrap mouth move movement movie moving mozart mr bean mr. bean mr meeseeks mr. meeseeks mtv mud muffin mug multimedia multiple multiply mummy municipal murder murderer muscle museum mushroom music musical musician musket mustache mustard mutation mutter mutual myth nachos nail nail file nail polish name nap napkin nappy narrow narwhal nasa nascar national nationalism nationalist nationality native nature navy necessary neck need needle negative neglect negligence negotiation neighbour neighbour neighbourhood nemo nephew neptune nerd nerve nervous nest net netherlands network neutral new newcomer news newspaper new zealand nice nickel night nightclub nightmare nike ninja nintendo switch noble nod node noise noisy nominate nomination nonsense noob noodle norm normal north northern lights north korea norway nose nosebleed nose hair nose ring nostrils notch note notebook notepad nothing notice notification notion notorious noun novel nuclear nugget nuke number nun nurse nursery nut nutcracker nutella nutmeg nutshell oak oar obelix obese obey object objection objective obligation obscure observation observatory observer obstacle obtain obvious occasion occupation occupational occupy ocean octagon octopus odd offence offend offender offensive offer office officer official offset offspring oil olaf old omelette omission onion open opera operation operational opinion opponent oppose opposed opposite opposition optimism optimistic option optional oral orange orangutan orbit orca orchestra orchid order ordinary oreo organ organic organisation organise orientation origami origin original orthodox ostrich other otter outer outfit outlet outline outlook output outside oval oven overall overlook overview overweight overwhelm owe owl owner ownership oxygen oyster pace pack package packet pac-man paddle page pain painful paint paintball painter pair pajamas palace palette palm palm tree pan pancake panda panel panic panpipes panther pants papaya paper paper bag parachute parade paradox paragraph parakeet parallel paralysed parameter pardon parent parental parents paris park parking parliament parrot part participant participate particle particular partner partnership part-time party pass passage passenger passion passionate passive passport password past pasta pastel pastry pasture pat patch patent path patience patient patio patrick patriot patrol pattern pause pavement paw pay payment paypal peace peaceful peach peacock peak peanut pear peas peasant pedal pedestrian pelican pen penalty pencil pencil case pencil sharpener pendulum penetrate penguin peninsula penny pension pensioner people peppa pig pepper pepper pepperoni pepsi perceive percent perception perfect perforate perform performance performer perfume period periscope permanent permission persist persistent person personal personality persuade pest pet petal pet food pet shop petty pharmacist phenomenon philosopher philosophical philosophy phineas and ferb photocopy photo frame photograph photographer photography photoshop physical physics piano picasso pick pickaxe pickle picnic picture pie piece pier pig pigeon piggy bank pigsty pikachu pike pile pill pillar pillow pillow fight pilot pimple pin pinball pine pineapple pine cone pink pink panther pinky pinocchio pinwheel pioneer pipe pirate pirate ship pistachio pistol pit pitch pitchfork pity pizza place plague plain plaintiff plan plane planet plank plant plaster plaster plastic plate platform platypus play player playground playstation plead pleasant please pleasure pledge plot plough plug plumber plunger pluto pneumonia pocket poem poetry pogo stick point poison poisonous poke pokemon polar bear pole policeman policy polish polite political politician politics poll pollution polo pond pony ponytail poodle pool poop poor pop popcorn pope popeye poppy popular population porch porcupine porky pig portable portal porter portion portrait portugal poseidon position positive possession possibility possible post postcard poster postpone pot potato potential potion pot of gold pottery pound pour powder power powerful practical practice praise prawn pray prayer preach precede precedent precise precision predator predecessor predictable prefer preference pregnant prejudice premature premium preoccupation preparation prescription presence present presentation preservation presidency president presidential press pressure prestige pretzel prevalence prevent prey price price tag pride priest primary prince princess principle pringles print printer priority prism prison prisoner privacy private privilege privileged prize pro probability problem procedure process proclaim procrastination produce producer product production productive profession professional professor profile profit profound program programmer progress progressive project projection prolonged promise promotion proof propaganda proper property proportion proportional proposal proposition prosecute prosecution prospect prosperity protect protection protein protest proud prove provide provincial provision provoke prune psychologist psychology pub public publication publicity publish publisher pudding puddle puffin pull puma pumba pump pumpkin punch punish punishment punk pupil puppet pure purity purpose purse pursuit push put puzzle pyramid qualification qualified qualify quality quantitative quantity quarter queen quest question questionnaire queue quicksand quiet quill quilt quit quota quotation quote rabbit raccoon race racial racing car racism rack radar radiation radical radio radish raft rage raid rail railcar railway rain rainbow raincoat raindrop rainforest raise raisin rake rally ram ramp random range rank rapper rare raspberry rat rate ratio rational ravioli raw razor razorblade reach reaction reactor read reader ready real realise realism realistic reality rear reason reasonable rebel rebellion receipt reception receptionist recession reckless recognise recognition recommend recommendation record recording recover recovery recreation recruit rectangle recycle recycling red red carpet reddit redeem reduction redundancy reeds refer referee reference referral reflect reflection reform refugee refusal refuse regard region regional register registration regret regular regulation rehabilitation rehearsal reign reindeer reinforce reject rejection relate related relation relationship relative relax relaxation release relevance relevant reliable reliance relief relieve religion religious relinquish reluctance rely remain remark remedy remember remind remote rent repeat repetition replace replacement report reporter represent representative reproduce reproduction reptile republic reputation request require requirement rescue research researcher resemble resent reserve reservoir residence resident residential resign resignation resist resolution resort resource respect respectable response responsibility responsible rest restaurant restless restoration restrain restraint restricted restriction result retail retailer retain retire retired retirement retreat return reveal revenge reverse review revise revival revive revolution revolutionary revolver reward rewind rhetoric rhinoceros rhythm rib ribbon rice rich rick ride rider ridge rifle right right wing ring ringtone riot rise risk ritual river road roadblock roar rob robber robbery robbie rotten robin robin hood robot rock rocket rockstar role roll romania romantic rome roof room rooster root rope rose rotation rotten rough round route routine row royal royalty rub rubber rubber rubbish rubbish bin ruby rug rugby ruin rule ruler rumour run rune runner rural rush russia sacred sacrifice sad saddle safari safe safety sail sailboat sailor salad sale saliva salmon salon salt saltwater salvation sample samsung sanctuary sand sandal sandbox sand castle sandstorm sandwich santa satellite satisfaction satisfactory satisfied saturn sauce sauna sausage save saxophone say scale scan scandal scar scarecrow scarf scary scatter scenario scene scent schedule scheme scholar scholarship school science scientific scientist scissors scooby doo scoop score scotland scramble scrap scrape scratch scream screen screw scribble script scuba sculpture scythe sea seafood seagull seahorse seal sea lion search seashell seasick season seasonal seat seat belt seaweed second secondary secret secretary secretion section sector secular secure security see seed seek seem seesaw segway seize selection self sell seller semicircle seminar send senior sensation sense sensei sensitive sensitivity sentence sentiment separate separation sequence series serious servant serve server service session set settle settlement sew sewing machine shade shadow shaft shake shallow shame shampoo shape share shareholder shark sharp shatter shave shaving cream shed sheep sheet shelf shell shelter sherlock holmes shield shift shine shipwreck shirt shiver shock shoe shoebox shoelace shoot shop shopping shopping trolley short shortage shorts shot shotgun shoulder shout shovel show shower shrek shrew shrink shrub shrug shy sick sickness side siege sigh sight sightsee sign signature silence silk silo silver silverware similar similarity simplicity sin sing singapore singer single sink sip sister sit site situation six pack size skate skateboard skateboarder skates skeleton sketch ski ski jump skill skilled skin skinny skirt skittles skribbl.rs skrillex skull skunk sky skydiving skyline skype skyscraper slab slam slap slave sledge sledgehammer sleep sleeve slice slide slime slingshot slinky slip slippery slogan slope slot sloth slow slump small smart smash smell smile smoke smooth snail snake snap snatch sneeze sniff sniper snow snowball snowball fight snowboard snowflake snowman snuggle soak soap soar soccer social socialist social media society sociology sock socket socks soda sodium soft software soil solar solar system soldier solid solidarity solo solution solve sombrero son sonic sophisticated soprano soul sound soup sour source south sow space spaceship space suit spade spaghetti spain spare spark sparkles spartacus spatial spatula speaker spear specialist species specified specimen spectrum speculate speech speed spell spelunker spend sphere sphinx spider spiderman spill spin spinach spine spiral spirit spit spite split spoil spoiler spokesman sponge spongebob spontaneous spool spoon spore sport sports spot spray spray paint spread spring sprinkler spy squad square squeeze squid squidward squirrel stab stable stadium staff stage stain staircase stake stall stamp stand standard stapler star starfish starfruit start star wars state statement station statistical statistics statue statue of liberty stay steady steak steam steel steep stegosaurus stem step stereo steve jobs steward stick sticky still stimulation sting stingray stir stitch stock stomach stone stone age stoned stool stop stop sign storage store stork storm story stove straight straighten strain strange strap strategic straw strawberry stream streamer street strength stress stretch strict stride strike string strip stroke stroll strong structural structure struggle stubborn student studio study stuff stumble stunning stupid style stylus subject subjective submarine submit subsequent substance substitute suburb subway success successful sudden sudoku suez canal suffer suffering sufficient sugar suggest suggestion suicide suit suitcase suite sulphur sum summary summer summit sun sunburn sunflower sunglasses sunrise sunshade sunshine superintendent superior superman supermarket superpower supervisor supplementary supply support suppose suppress surface surfboard surgeon surgery surprise surprised surprising surround survey survival survivor susan wojcicki sushi suspect suspicion sustain swag swallow swamp swan swarm swear sweat sweater sweep sweet swell swim swimming pool swimsuit swing swipe switch sword swordfish sydney opera house syllable symbol symmetry sympathetic symphony symptom syndrome system systematic table tablecloth tablet table tennis tabletop taco tactic tadpole tail tailor tails take take off talented talent show talk talkative tall tampon tangerine tank tap tap tape tarantula target tarzan taser taste tasty tattoo tax taxi taxi driver taxpayer tea teacher team teapot tear tease teaspoon technical technique technology teddy bear teenager telephone telescope teletubby television tell temperature temple temporary tempt temptation tenant tendency tender tennis tennis racket tense tension tent tentacle term terminal terminator terrace terrify terrorist test testify tetris text texture thank thanks theatre the beatles theft theme theology theorist theory therapist therapy thermometer thesis thick thief thigh thin think thinker thirst thirsty thor thought thoughtful thread threat threaten threshold throat throne throw thrust thug thumb thunder thunderstorm tick ticket tickle tide tidy tie tiger tight tile timber time time machine timetable timpani tin tiny tip tiramisu tire tired tissue tissue box titanic title toad toast toaster toe toenail toilet tolerant tolerate toll tomato tomb tombstone ton tone tongue tool toolbox tooth toothbrush tooth fairy toothpaste toothpick top top hat torch tornado torpedo tortoise torture toss total totem toucan touch tough tourism tourist tournament towel tower tower bridge tower of pisa town tow truck toxic toy trace track tract tractor trade tradition traditional traffic traffic light tragedy trailer train trainer training trait transaction transfer transform transition translate transmission transparent transport trap trapdoor traveler tray tread treadmill treasure treasurer treat treatment treaty tree treehouse tremble trench trend t-rex trial triangle tribe tribute trick trick shot tricycle trigger trip triplets tripod trivial trolley trombone troop trophy tropical trouble trouser truck truck driver true trumpet trunk trust trustee truth try t-shirt tuba tube tug tumble tumour tumour tuna tune tunnel turd turkey turn turnip turtle tuxedo tweety twig twin twist twitter tycoon type typical tyre udder ufo ugly ukulele ulcer ultimate umbrella unanimous unaware uncertainty uncle uncomfortable underground underline undermine understand understanding undertake underweight undo uneasy unemployed unemployment unexpected unfair unfortunate unibrow unicorn unicycle uniform union unique unit unity universal universe university unlawful unlike unlikely unpleasant unrest update upgrade upset uranus urban urge urgency urine usain bolt usb use useful useless user usual utter vacant vacation vaccine vacuum vague vain valid valley valuable value vampire van vanilla vanish variable variant variation varied variety vat vatican vault vault boy vector vegetable vegetarian vegetation vehicle veil vein velociraptor velvet vent venture venus verbal verdict version vertical vessel veteran veterinarian viable vicious victim victory video video game view vigorous villa village villager villain vin diesel vine vinegar viola violation violence violent violin virgin virtual reality virtue virus vise visible vision visit visitor visual vitamin vlogger vocational vodka voice volcano volleyball volume voluntary volunteer vomit voodoo vortex vote voter voucher voyage vulnerable vulture vuvuzela waffle wage wagon waist wait waiter wake wake up walk wall wall-e wallpaper walnut walrus wander want war ward wardrobe warehouse warm warn warning warrant warrior wart wash wasp waste watch water water cycle waterfall water gun wave wax way weak weakness wealth weapon wear weasel weather weave web website wedding weed week weekend weekly weigh weight welcome welder welfare well werewolf west western wet whale whatsapp wheat wheel wheelbarrow whip whisk whisky whisper whistle white whole widen widow width wife wig wiggle wild wilderness wildlife will william shakespeare william wallace willow willpower win wind windmill window windscreen wine wine glass wing wingnut winner winnie the pooh winter wipe wire wireless wise witch withdraw withdrawal witness wizard w-lan wolf wolverine woman wonder wonderland wonder woman wood woodpecker wool word wording work worker work out workplace workshop world worm worry worth wound wrap wrapping wreath wreck wrench wrestle wrestler wrestling wrinkle wrist write writer written wrong xbox xerox x-ray xylophone yacht yard yardstick yawn year yearbook yellow yeti yin and yang yoda yogurt yolk yoshi young youth youtube youtuber yo-yo zebra zelda zeppelin zero zeus zigzag zipline zipper zombie zone zoo zoom zorro zuma ================================================ FILE: internal/game/words/en_us ================================================ abandon abbey ability able abnormal abolish abortion abraham lincoln abridge absence absent absolute absorb absorption abstract abundant abuse abyss ac/dc academic academy accent accept acceptable acceptance access accessible accident accompany accordion account accountant accumulation accurate ace achievement acid acne acorn acquaintance acquisition act action activate active activity actor acute add addicted addiction addition address adequate adidas adjust administration administrator admiration admire admission admit adopt adoption adorable adult advance advantage adventure advertisement advertising advice adviser advocate aesthetic affair affect affinity afford afraid africa afro afterlife afternoon age agency agenda agent aggressive agile agony agree agreement agricultural agriculture aid aids air air conditioner airbag aircraft airline airplane airport aisle aladdin alarm albatross album alcohol alert alien alive allergy alley alligator allocation allow allowance ally almond aloof alpaca altar aluminium amateur amber ambiguity ambiguous ambition ambitious ambulance amendment america ample amputate amsterdam amuse anaconda analogy analysis analyst anchor android angel angelina jolie anger angle anglerfish angry angry birds animal animation anime ankle anniversary announcement annual anonymous answer ant antarctica anteater antelope antenna anthill anticipation antivirus anubis anvil anxiety apartment apathy apocalypse apologise apology apparatus appeal appear appearance appendix appetite applaud applause apple apple pie apple seed applicant application applied appoint appointment appreciate approach appropriate approval approve apricot aquarium arbitrary arch archaeological archaeologist archer architect architecture archive area arena argentina argument aristocrat arm armadillo armchair armor armpit army arrange arrangement arrest arrogant arrow art article articulate artificial artist artistic ascertain ash ashamed asia ask asleep aspect assassin assault assembly assertion assertive assessment asset assignment association assume assumption assurance asterix asteroid astonishing astronaut asylum asymmetry athlete atlantis atmosphere atom attach attachment attack attention attic attitude attract attraction attractive auction audi audience auditor aunt australia authorise authority autograph automatic autonomy available avenue average aviation avocado avoid awake award aware awful awkward axe axis baboon baby back back pain backbone backflip background backpack bacon bad badger bag bagel bagpipes baguette bail bait bake bakery baklava balance balanced balcony bald ball ballerina ballet balloon ballot bambi bamboo ban banana band band-aid bandage bandana bang banjo bank banker bankruptcy banner bar barack obama barbarian barbecue barbed wire barber barcode bare bargain bark barn barrel barrier bart simpson bartender base baseball basement basic basin basis basket basketball bat bath bathroom bathtub batman battery battle battlefield battleship bay bayonet bazooka beach beak beam bean bean bag beanie beanstalk bear bear trap beard beat beatbox beautiful beaver become bed bed bug bed sheet bedroom bedtime bee beef beer beet beethoven beetle beg begin beginning behave behaviour behead belief bell bell pepper bellow belly belly button belong below belt bench bend beneficiary benefit berry bet betray bible bicycle big ben bike bill bill gates billiards bin bind bingo binoculars biography biology birch bird bird bath birthday biscuit bishop bitch bitcoin bite bitter black black friday black hole blackberry blackmail blacksmith blade blame bland blank blanket blast bleach bleed blender bless blimp blind blindfold blizzard block blonde blood bloodshed bloody blow blowfish blue blue jean blueberry blush bmw bmx boar board boat bobsled body bodyguard boil bold bolt bomb bomber bomberman bond bone booger book bookmark bookshelf boom boomerang boot boots border borrow bother bottle bottle flip bottom bounce bouncer bow bowel bowl bowling box boy bracelet braces bracket brag brain brainwash brake branch brand brave brazil bread break breakdown breakfast breast breath breathe breed breeze brewery brick bricklayer bride bridge bring broadcast broccoli broken broken heart bronze broom broomstick brother brown brownie bruise brunette brush bubble bubble gum bucket budget buffet bugs bunny building bulb bulge bull bulldozer bullet bulletin bump bumper bundle bungee jumping bunk bed bunny bureaucracy bureaucratic burglar burial burn burp burrito burst bury bus bus driver bus stop bush business businessman busy butcher butler butt cheeks butter butterfly button buy cab driver cabin cabinet cable cactus cafe cage cake calculation calendar calf call calm calorie camel camera camp campaign campfire camping can can opener canada canary cancel cancer candidate candle cane canister cannon canvas canyon cap capable cape capital capitalism cappuccino capricorn captain captain america captivate capture car car wash carbon card cardboard care career careful carnival carnivore carpenter carpet carriage carrier carrot carry cart cartoon carve case cash casino cassette cast castle casualty cat cat woman catalog catalogue catapult catch category cater caterpillar catfish cathedral cattle cauldron cauliflower cause cautious cave caveman caviar ceiling ceiling fan celebrate celebration celebrity cell cell phone cellar cello cement cemetery censorship census centaur center centipede central century cerberus cereal ceremony certain certificate chain chainsaw chair chalk challenge chameleon champagne champion chance chandelier change channel chaos chap chapter character characteristic charge charger charismatic charity charlie chaplin charm chart charter chase chauvinist cheap check cheek cheeks cheerful cheerleader cheese cheeseburger cheesecake cheetah chef chemical chemistry cheque cherry cherry blossom chess chest chest hair chestnut chestplate chew chewbacca chicken chief chihuahua child childhood childish chime chimney chimpanzee chin china chinatown chinchilla chip chocolate choice choke choose chop chopsticks chord chorus christmas chrome chronic chuck norris church cicada cigarette cinema circle circulation circumstance circus citizen city civic civilian civilization claim clap clarify clarinet clash class classical classify classroom claw clay clean clear clearance clerk clickbait cliff climate climb clinic cloak clock close closed cloth clothes clothes hanger cloud clover clown clownfish club clue cluster coach coal coalition coast coast guard coaster coat cobra cockroach cocktail coconut cocoon code coffee coffee shop coffin coin coincide coincidence cola cold collapse collar colleague collect collection college colon colony color-blind colosseum colour colourful column coma comb combination combine comedian comedy comet comfort comfortable comic book command commander comment commerce commercial commission commitment committee common communication communism communist community compact company comparable compare comparison compartment compass compatible compensate compensation compete competence competent competition competitive complain complete complex compliance complication composer compound comprehensive compromise computer computing concede conceive concentrate concentration concept conception concern concert concession conclusion concrete condiment condition conductor cone conference confession confidence confident confine conflict confront confrontation confused confusion conglomerate congratulate congress connection conscience conscious consciousness consensus conservation conservative consider considerable consideration consistent console consolidate conspiracy constant constellation constituency constitution constitutional constraint construct constructive consultation consumer consumption contact contain contemporary contempt content contest context continent continental continuation continuous contract contraction contradiction contrary contrast contribution control controller controversial convenience convenient convention conventional conversation convert convict conviction convince cook cookie cookie jar cookie monster cool cooperate cooperation cooperative cope copper copy copyright coral coral reef cord core cork corkscrew corn corn dog corner cornfield corporate corpse correction correlation correspond correspondence corruption costume cottage cotton cotton candy cough council count counter country countryside coup couple courage course court courtesy cousin cover coverage cow cowbell cowboy coyote crab crack craft craftsman crash crash bandicoot crate crawl space crayon cream create creation credibility credit credit card creed creep creeper crew cricket crime criminal cringe crisis critic critical criticism croatia crocodile croissant crop cross crossbow crossing crouch crow crowbar crowd crown crucible crude cruel cruelty cruise crust crutch cry crystal cuba cube cuckoo cucumber cultivate cultural culture cup cupboard cupcake cupid curious curl currency current curriculum curry curtain curve cushion custody customer cut cute cutting cyborg cycle cylinder cymbal daffy duck dagger daily dairy daisy dalmatian damage damn dance dandelion dandruff danger dangerous dare dark darts darwin darwin watterson dashboard date daughter day daylight dead deadline deadly deadpool deaf deal dealer death debate debt debut decade decay decide decisive deck declaration decline decoration decorative decrease dedicate deep deer default defeat defend defendant defense deficiency deficit define definite definition degree delay delegate delete delicate deliver delivery demand democracy democratic demolish demon demonstrate demonstration demonstrator denial denounce density dent dentist deny deodorant depart departure depend dependence dependent deposit depressed depression deprivation deprive deputy derp descent describe desert deserve design designer desirable desire desk despair desperate despise dessert destruction detail detective detector deter deteriorate detonate develop development deviation devote dew dexter diagnosis diagonal diagram dialect dialogue diameter diamond diaper dice dictate dictionary die diet differ difference different difficult difficulty dig digital dignity dilemma dilute dimension dine dinner dinosaur dip diploma diplomat diplomatic direct direction director directory dirty disability disadvantage disagreement disappear disappoint disappointment disaster discipline disco discord discount discourage discourse discover discovery discreet discrimination discuss disease disguise dish dishrag disk dislike dismiss dismissal disorder dispenser display disposition dispute diss track dissolve distance distant distinct distort distortion distribute distributor district disturbance diva dive divide dividend division divorce dizzy dna dock doctor document dog doghouse doll dollar dollhouse dolphin dome domestic dominant dominate domination dominoes donald duck donald trump donate donkey donor door doorknob dora doritos dose dots double doubt dough download dozen dracula draft drag dragon dragonfly drain drama dramatic draw drawer drawing dream dress dressing drift drill drink drip drive driver drool drop droplet drought drown drug drum drum kit dry duck duct tape due duel duke dull dumbo dump duration dust duty dwarf dynamic dynamite eager eagle ear earbuds early earth earthquake earwax east easter easter bunny easy eat eavesdrop echo eclipse economic economics economist economy edge edition education educational eel effect effective efficient effort egg eggplant ego egypt eiffel tower einstein elbow elder elect election electorate electric car electric guitar electrician electricity electron electronic electronics elegant element elephant elevator eligible eliminate elite elmo elon musk eloquent elsa embark embarrassment embassy embers embryo emerald emergency eminem emoji emotion emotional emphasis empire empirical employ employee employer employment empty emu encourage encouraging end endure enemy energy engagement engine engineer england enhance enjoyable enlarge ensure enter entertain entertainment enthusiasm enthusiastic entitlement entry envelope environment environmental episode equal equation equator equilibrium equipment era eraser erosion error escape eskimo espresso essay essence essential establish established estate estimate eternal ethical ethics ethnic europe evaporate even evening evolution exact exaggerate exam examination example excalibur excavation excavator exceed exception excess exchange excited excitement exciting exclude exclusive excuse execute execution executive exemption exercise exhibit exhibition exile exit exotic expand expansion expect expectation expected expedition expenditure expensive experience experienced experiment experimental expert expertise explain explanation explicit explode exploit exploration explosion export expose exposure express expression extend extension extent external extinct extraordinary extraterrestrial extreme eye eyebrow eyelash eyeshadow fabric fabulous facade face face paint facebook facility fact factor factory fade fail failure faint fair fairy faith faithful fake teeth fall false fame familiar family family guy fan fanta fantasy far fare farm farmer fascinate fashion fashion designer fashionable fast fast food fast forward fastidious fat father faucet fault favor favorable favour favourite fax fear feast feather feature federal federation fee feedback feel feeling feminine feminist fence fencing fern ferrari ferry festival fever few fibre fiction fidget spinner field fig fight figure figurine file fill film filmmaker filter final finance financial find fine finger fingernail fingertip finish finished finn finn and jake fire fire alarm fire hydrant fire truck fireball firecracker firefighter firefly firehouse fireman fireplace fireproof fireside firework firm first firsthand fish fish bowl fisherman fist fist fight fit fitness fitness trainer fix fixture fizz flag flagpole flamethrower flamingo flash flashlight flask flat flavour flawed flea fleet flesh flexible flight flight attendant fling flock flood floodlight floor floppy disk florida florist flour flourish flower flu fluctuation fluid flush flute fly fly swatter flying pig fog foil fold folder folk folklore follow food fool foolish foot football forbid force forecast forehead foreigner forest forest fire forestry forge forget fork form formal format formation formula formulate fort fortress fortune forum forward fossil foster foundation fountain fox fraction fragment fragrant frame france franchise frank frankenstein fraud freckle freckles fred flintstone free freedom freeze freezer freight frequency frequent fresh freshman fridge friend friendly friendship fries frighten frog front frostbite frosting frown frozen fruit frustration fuel full full moon full-time fun function functional fund funeral funny fur furniture fuss future gain galaxy gallery gallon game gandalf gandhi gang gangster gap garage garbage garden gardener garfield garlic gas gas mask gasoline gasp gate gaze gear gem gender gene general generate generation generator generous genetic genie genius gentle gentleman genuine geography geological germ germany gesture get geyser ghost giant gift giraffe girl give glacier glad gladiator glance glare glass glasses glide glimpse glitter globe gloom glorious glory gloss glove glow glowstick glue glue stick gnome go goal goalkeeper goat goatee goblin god godfather gold gold chain golden apple golden egg goldfish golf golf cart good goofy google goose gorilla government governor gown grace grade gradual graduate graduation graffiti grain grammar grand grandfather grandmother grant grapefruit grapes graph graphic graphics grass grasshopper grateful grave gravedigger gravel graveyard gravity great great wall greece greed green green lantern greet greeting gregarious grenade grid grief grill grimace grin grinch grind grip groan groom ground grounds grow growth gru grumpy guarantee guard guerrilla guess guest guide guideline guillotine guilt guinea pig guitar gumball gummy gummy bear gummy worm gun gutter habit habitat hacker hair hair roller hairbrush haircut hairspray hairy half hall hallway halo halt ham hamburger hammer hammock hamster hand handicap handle handshake handy hang hanger happen happy happy meal harbor harbour hard hard hat hardship hardware harm harmful harmonica harmony harp harpoon harry potter harsh harvest hashtag hat hate haul haunt have hawaii hay hazard hazelnut head headache headband headboard heading headline headphones headquarters heal health healthy hear heart heat heaven heavy hedge hedgehog heel height heir heist helicopter hell hello kitty helmet help helpful helpless hemisphere hen herb hercules herd hermit hero heroin hesitate hexagon hibernate hiccup hide hierarchy hieroglyph high high five high heels high score highlight highway hike hilarious hill hip hip hop hippie hippo historian historical history hit hitchhiker hive hobbit hockey hold hole holiday hollywood holy home home alone homeless homer simpson honest honey honeycomb honorable honour hoof hook hop hope hopscotch horizon horizontal horn horoscope horror horse horsewhip hose hospital hospitality host hostage hostile hostility hot hot chocolate hot dog hot sauce hotel hour hourglass house houseplant housewife housing hover hovercraft hug huge hula hoop hulk human human body humanity hummingbird humour hunger hungry hunter hunting hurdle hurt husband hut hyena hypnotize hypothesis ice ice cream ice cream truck iceberg icicle idea ideal identification identify identity ideology ignorance ignorant ignore ikea illegal illness illusion illustrate illustration image imagination imagine immigrant immigration immune impact imperial implication implicit import importance important impossible impress impressive improve improvement impulse inadequate inappropriate incapable incentive inch incident include incognito income incongruous increase incredible independent index india indication indigenous indirect individual indoor indulge industrial industry inevitable infect infection infinite inflate inflation influence influential informal information infrastructure ingredient inhabitant inherit inhibition initial initiative inject injection injure injury inn inner innocent innovation inquest insect insert inside insider insight insist insistence insomnia inspector inspiration inspire instal install instinct institution instruction instrument insufficient insurance insure integrated integration integrity intel intellectual intelligence intense intensify intention interaction interactive interest interesting interface interference intermediate internal international internet interpret interrupt intersection intervention interview introduce introduction invasion invention investigation investigator investment invisible invitation invite ipad iphone ireland iron iron giant iron man irony irrelevant island isolation israel issue italy item ivory ivy jack-o-lantern jacket jackhammer jackie chan jaguar jail jalapeno jam james bond janitor japan jar jaw jayz jazz jealous jeans jeep jello jelly jellyfish jenga jerk jest jester jesus christ jet jet ski jewel jimmy neutron job jockey john cena johnny bravo joint joke joker journal journalist journey joy judge judgment judicial juggle juice jump jump rope junction jungle junior junk food jurisdiction jury just justice justification justify kangaroo karaoke karate katana katy perry kazoo kebab keep keg kendama kermit ketchup kettle key keyboard kfc kick kid kidney kill killer kim jong-un kind kindergarten king king kong kingdom kinship kirby kiss kit kitchen kite kitten kiwi knead knee kneel knife knight knit knock knot know knowledge knuckle koala koran kraken kung fu label laboratory labour labourer lace lack ladder lady lady gaga ladybug lake lamb lamp land landlord landowner landscape lane language lantern lap laptop large las vegas lasagna laser lasso last late latest laugh launch laundry lava lava lamp law lawn lawn mower lawyer lay layer layout lazy lead leader leadership leaf leaflet leak lean learn lease leash leather leave lecture leech left leftovers leg legal legend legislation legislative legislature lego legs leisure lemon lemonade lemur lend length lens leonardo da vinci leonardo dicaprio leprechaun lesson let letter lettuce level levitate liability liberal liberty librarian library licence license lick licorice lid lie life lifestyle lift light lightbulb lighter lighthouse lightning lightsaber like likely lily lilypad limb limbo lime limit limitation limited limousine line linear linen linger link lion lion king lip lips lipstick liquid list listen literacy literary literature litigation litter box live lively liver lizard llama load loading loaf loan lobby lobster locate location lock lodge log logic logical logo lollipop london london eye lonely long look loop loose loot lose loser loss lost lot lotion lottery loud lounge love lover low lower loyal loyalty luck lucky luggage luigi lumberjack lump lunch lung lynx lyrics macaroni machine machinery macho madagascar mafia magazine magic magic trick magic wand magician magma magnet magnetic magnifier magnitude maid mail mailbox mailman main mainstream maintenance major majority make makeup mall mammoth man manage management manager manatee manhole manicure mannequin manner mansion mantis manual manufacture manufacturer manuscript map maracas marathon marble march margarine margin marigold marine mario mark mark zuckerberg market marketing marmalade marmot marriage married mars marsh marshmallow mascot mask mass massage master match matchbox material mathematical mathematics matrix matter mattress mature maximum mayonnaise mayor maze mcdonalds meadow meal mean meaning meaningful means measure meat meatball meatloaf mechanic mechanical mechanism medal medicine medieval medium medusa meerkat meet meeting megaphone melon melt member membership meme memorable memorandum memorial memory mental mention menu mercedes merchant mercury mercy merit mermaid message messy metal meteorite method methodology mexico michael jackson mickey mouse microphone microscope microsoft microwave middle middle-class midnight migration mild mile military milk milkman milkshake milky way mill mime mind mine minecraft miner mineral miniclip minigolf minimise minimum minion minister ministry minivan minor minority minotaur mint minute miracle mirror miscarriage miserable misery mislead miss missile mist mix mixture mobile model modern modest module mohawk mold mole molecular molecule moment momentum mona lisa monarch monarchy monastery monday money monk monkey monopoly monster monstrous mont blanc month monthly mood moon moose mop moral morale morgan freeman morning morse code morsel mortgage morty mosaic mosque mosquito moss moth mothball mother motherboard motif motivation motorbike motorcycle motorist motorway mould mount everest mount rushmore mountain mourning mouse mousetrap mouth move movement movie moving mozart mr bean mr meeseeks mr. bean mr. meeseeks mtv mud muffin mug multimedia multiple multiply mummy municipal murder murderer muscle museum mushroom music musical musician musket mustache mustard mutation mutter mutual myth nachos nail nail file nail polish name nap napkin narrow narwhal nasa nascar national nationalism nationalist nationality native nature navy necessary neck need needle negative neglect negligence negotiation neighbor neighborhood neighbour neighbourhood nemo nephew neptune nerd nerve nervous nest net netherlands network neutral new new zealand newcomer news newspaper nice nickel night nightclub nightmare nike ninja nintendo switch noble nod node noise noisy nominate nomination nonsense noob noodle norm normal north north korea northern lights norway nose nose hair nose ring nosebleed nostrils notch note notebook notepad nothing notice notification notion notorious noun novel nuclear nugget nuke number nun nurse nursery nut nutcracker nutella nutmeg nutshell oak oar obelix obese obey object objection objective obligation obscure observation observatory observer obstacle obtain obvious occasion occupation occupational occupy ocean octagon octopus odd offence offend offender offensive offer office officer official offset offspring oil olaf old omelet omission onion open opera operation operational opinion opponent oppose opposed opposite opposition optimism optimistic option optional oral orange orangutan orbit orca orchestra orchid order ordinary oreo organ organic organisation organise orientation origami origin original orthodox ostrich other otter outer outfit outlet outline outlook output outside oval oven overall overlook overview overweight overwhelm owe owl owner ownership oxygen oyster pac-man pace pack package packet paddle page pain painful paint paintball painter pair pajamas palace palette palm palm tree pan pancake panda panel panic panpipes panther pants papaya paper paper bag parachute parade paradox paragraph parakeet parallel paralyzed parameter pardon parent parental parents paris park parking parliament parrot part part-time participant participate particle particular partner partnership party pass passage passenger passion passionate passive passport password past pasta pastel pastry pasture pat patch patent path patience patient patio patrick patriot patrol pattern pause pavement paw pay payment paypal peace peaceful peach peacock peak peanut pear peas peasant pedal pedestrian pelican pen penalty pencil pencil case pencil sharpener pendulum penetrate penguin peninsula penny pension pensioner people peppa pig pepper pepperoni pepsi perceive percent perception perfect perforate perform performance performer perfume period periscope permanent permission persist persistent person personal personality persuade pest pet pet food pet shop petal petty pharmacist phenomenon philosopher philosophical philosophy phineas and ferb photo frame photocopy photograph photographer photography photoshop physical physics piano picasso pick pickaxe pickle picnic picture pie piece pier pig pigeon piggy bank pigsty pikachu pike pile pill pillar pillow pillow fight pilot pimple pin pinball pine pine cone pineapple pink pink panther pinky pinocchio pinwheel pioneer pipe pirate pirate ship pistachio pistol pit pitch pitchfork pity pizza place plague plain plaintiff plan plane planet plank plant plaster plastic plate platform platypus play player playground playstation plead pleasant please pleasure pledge plot plow plug plumber plunger pluto pneumonia pocket poem poetry pogo stick point poison poisonous poke pokemon polar bear pole policeman policy polish polite political politician politics poll pollution polo pond pony ponytail poodle pool poop poor pop popcorn pope popeye poppy popsicle popular population porch porcupine porky pig portable portal porter portion portrait portugal poseidon position positive possession possibility possible post postcard poster postpone pot pot of gold potato potential potion pottery pound pour powder power powerful practical practice praise prawn pray prayer preach precede precedent precise precision predator predecessor predictable prefer preference pregnant prejudice premature premium preoccupation preparation prescription presence present presentation preservation presidency president presidential press pressure prestige pretzel prevalence prevent prey price price tag pride priest primary prince princess principle pringles print printer priority prism prison prisoner privacy private privilege privileged prize pro probability problem procedure process proclaim procrastination produce producer product production productive profession professional professor profile profit profound program programmer progress progressive project projection prolonged promise promotion proof propaganda proper property proportion proportional proposal proposition prosecute prosecution prospect prosperity protect protection protein protest proud prove provide provincial provision provoke prune psychologist psychology pub public publication publicity publish publisher pudding puddle puffin pull puma pumba pump pumpkin punch punish punishment punk pupil puppet pure purity purpose purse pursuit push put puzzle pyramid qualification qualified qualify quality quantitative quantity quarter queen quest question questionnaire queue quicksand quiet quill quilt quit quota quotation quote rabbit raccoon race racecar racial racism rack radar radiation radical radio radish raft rage raid rail railcar railway rain rainbow raincoat raindrop rainforest raise raisin rake rally ram ramp random range rank rapper rare raspberry rat rate ratio rational ravioli raw razor razorblade reach reaction reactor read reader ready real realise realism realistic reality rear reason reasonable rebel rebellion receipt reception receptionist recession reckless recognise recognition recommend recommendation record recording recover recovery recreation recruit rectangle recycle recycling red red carpet reddit redeem reduction redundancy reeds refer referee reference referral reflect reflection reform refugee refusal refuse regard region regional register registration regret regular regulation rehabilitation rehearsal reign reindeer reinforce reject rejection relate related relation relationship relative relax relaxation release relevance relevant reliable reliance relief relieve religion religious relinquish reluctance rely remain remark remedy remember remind remote rent repeat repetition replace replacement report reporter represent representative reproduce reproduction reptile republic reputation request require requirement rescue research researcher resemble resent reserve reservoir residence resident residential resign resignation resist resolution resort resource respect respectable response responsibility responsible rest restaurant restless restoration restrain restraint restricted restriction result retail retailer retain retire retired retirement retreat return reveal revenge reverse review revise revival revive revolution revolutionary revolver reward rewind rhetoric rhinoceros rhythm rib ribbon rice rich rick ride rider ridge rifle right right wing ring ringtone riot rise risk ritual river road roadblock roar rob robber robbery robbie rotten robin robin hood robot rock rocket rockstar role roll romania romantic rome roof room rooster root rope rose rotation rotten rough round route routine row royal royalty rub rubber rubbish ruby rug rugby ruin rule ruler rumour run rune runner rural rush russia sacred sacrifice sad saddle safari safe safety sail sailboat sailor salad sale saliva salmon salon salt saltwater salvation sample samsung sanctuary sand sand castle sandal sandbox sandstorm sandwich santa satellite satisfaction satisfactory satisfied saturn sauce sauna sausage save saxophone say scale scan scandal scar scarecrow scarf scary scatter scenario scene scent schedule scheme scholar scholarship school science scientific scientist scissors scooby doo scoop score scotland scramble scrap scrape scratch scream screen screw scribble script scuba sculpture scythe sea sea lion seafood seagull seahorse seal search seashell seasick season seasonal seat seat belt seaweed second secondary secret secretary secretion section sector secular secure security see seed seek seem seesaw segway seize selection self sell seller semicircle seminar send senior sensation sense sensei sensitive sensitivity sentence sentiment separate separation sequence series serious servant serve server service session set settle settlement sew sewing machine shade shadow shaft shake shallow shame shampoo shape share shareholder shark sharp shatter shave shaving cream shed sheep sheet shelf shell shelter sherlock holmes shield shift shine shipwreck shirt shiver shock shoe shoebox shoelace shoot shop shopping shopping cart short shortage shorts shot shotgun shoulder shout shovel show shower shrek shrew shrink shrub shrug shy sick sickness side siege sigh sight sightsee sign signature silence silk silo silver silverware similar similarity simplicity sin sing singapore singer single sink sip sister sit site situation six pack size skate skateboard skateboarder skates skeleton sketch ski ski jump skill skilled skin skinny skirt skittles skribbl.rs skrillex skull skunk sky skydiving skyline skype skyscraper slab slam slap slave sledge sledgehammer sleep sleeve slice slide slime slingshot slinky slip slippery slogan slope slot sloth slow slump small smart smash smell smile smoke smooth snail snake snap snatch sneeze sniff sniper snow snowball snowball fight snowboard snowflake snowman snuggle soak soap soar soccer social social media socialist society sociology sock socket socks soda sodium soft software soil solar solar system soldier solid solidarity solo solution solve sombrero son sonic sophisticated soprano soul sound soup sour source south sow space space suit spaceship spade spaghetti spain spare spark sparkles spartacus spatial spatula speaker spear specialist species specified specimen spectrum speculate speech speed spell spelunker spend sphere sphinx spider spiderman spill spin spinach spine spiral spirit spit spite split spoil spoiler spokesman sponge spongebob spontaneous spool spoon spore sport sports spot spray spray paint spread spring sprinkler spy squad square squeeze squid squidward squirrel stab stable stadium staff stage stain staircase stake stall stamp stand standard stapler star star wars starfish starfruit start state statement station statistical statistics statue statue of liberty stay steady steak steam steel steep stegosaurus stem step stereo steve jobs steward stick sticky still stimulation sting stingray stir stitch stock stomach stone stone age stoned stool stop stop sign storage store stork storm story stove straight straighten strain strange strap strategic straw strawberry stream streamer street strength stress stretch strict stride strike string strip stroke stroll strong structural structure struggle stubborn student studio study stuff stumble stunning stupid style stylus subject subjective submarine submit subsequent substance substitute suburb subway success successful sudden sudoku suez canal suffer suffering sufficient sugar suggest suggestion suicide suit suitcase suite sulphur sum summary summer summit sun sunburn sunflower sunglasses sunrise sunshade sunshine superintendent superior superman supermarket superpower supervisor supplementary supply support suppose suppress surface surfboard surgeon surgery surprise surprised surprising surround survey survival survivor susan wojcicki sushi suspect suspicion sustain swag swallow swamp swan swarm swear sweat sweater sweep sweet swell swim swimming pool swimsuit swing swipe switch sword swordfish sydney opera house syllable symbol symmetry sympathetic symphony symptom syndrome system systematic t-rex t-shirt table table tennis tablecloth tablet tabletop taco tactic tadpole tail tailor tails take take off talent show talented talk talkative tall tampon tangerine tank tap tape tarantula target tarzan taser taste tasty tattoo tax taxi taxi driver taxpayer tea teacher team teapot tear tease teaspoon technical technique technology teddy bear teenager telephone telescope teletubby television tell temperature temple temporary tempt temptation tenant tendency tender tennis tennis racket tense tension tent tentacle term terminal terminator terrace terrify terrorist test testify tetris text texture thank thanks the beatles theatre theft theme theology theorist theory therapist therapy thermometer thesis thick thief thigh thin think thinker thirst thirsty thor thought thoughtful thread threat threaten threshold throat throne throw thrust thug thumb thunder thunderstorm tick ticket tickle tide tidy tie tiger tight tile timber time time machine timetable timpani tin tiny tip tiramisu tire tired tissue tissue box titanic title toad toast toaster toe toenail toilet tolerant tolerate toll tomato tomb tombstone ton tone tongue tool toolbox tooth tooth fairy toothbrush toothpaste toothpick top top hat torch tornado torpedo tortoise torture toss total totem toucan touch tough tourism tourist tournament tow truck towel tower tower bridge tower of pisa town toxic toy trace track tract tractor trade tradition traditional traffic traffic light tragedy trailer train trainer training trait transaction transfer transform transition translate transmission transparent transport trap trapdoor trash can traveler tray tread treadmill treasure treasurer treat treatment treaty tree treehouse tremble trench trend trial triangle tribe tribute trick trick shot tricycle trigger trip triplets tripod trivial trolley trombone troop trophy tropical trouble trouser truck truck driver true trumpet trunk trust trustee truth try tuba tube tug tumble tumor tumour tuna tune tunnel turd turkey turn turnip turtle tuxedo tweety twig twin twist twitter tycoon type typical tyre udder ufo ugly ukulele ulcer ultimate umbrella unanimous unaware uncertainty uncle uncomfortable underground underline undermine understand understanding undertake underweight undo uneasy unemployed unemployment unexpected unfair unfortunate unibrow unicorn unicycle uniform union unique unit unity universal universe university unlawful unlike unlikely unpleasant unrest update upgrade upset uranus urban urge urgency urine usain bolt usb use useful useless user usual utter vacant vacation vaccine vacuum vague vain valid valley valuable value vampire van vanilla vanish variable variant variation varied variety vat vatican vault vault boy vector vegetable vegetarian vegetation vehicle veil vein velociraptor velvet vent venture venus verbal verdict version vertical vessel veteran veterinarian viable vicious victim victory video video game view vigorous villa village villager villain vin diesel vine vinegar viola violation violence violent violin virgin virtual reality virtue virus vise visible vision visit visitor visual vitamin vlogger vocational vodka voice volcano volleyball volume voluntary volunteer vomit voodoo vortex vote voter voucher voyage vulnerable vulture vuvuzela w-lan waffle wage wagon waist wait waiter wake wake up walk wall wall-e wallpaper walnut walrus wander want war ward wardrobe warehouse warm warn warning warrant warrior wart wash wasp waste watch water water cycle water gun waterfall wave wax way weak weakness wealth weapon wear weasel weather weave web website wedding weed week weekend weekly weigh weight welcome welder welfare well werewolf west western wet whale whatsapp wheat wheel wheelbarrow whip whisk whisky whisper whistle white whole widen widow width wife wig wiggle wild wilderness wildlife will william shakespeare william wallace willow willpower win wind windmill window windshield wine wine glass wing wingnut winner winnie the pooh winter wipe wire wireless wise witch withdraw withdrawal witness wizard wolf wolverine woman wonder wonder woman wonderland wood woodpecker wool word wording work work out worker workplace workshop world worm worry worth wound wrap wrapping wreath wreck wrench wrestle wrestler wrestling wrinkle wrist write writer written wrong x-ray xbox xerox xylophone yacht yard yardstick yawn year yearbook yellow yeti yin and yang yo-yo yoda yogurt yolk yoshi young youth youtube youtuber zebra zelda zeppelin zero zeus zigzag zipline zipper zombie zone zoo zoom zorro zuma ================================================ FILE: internal/game/words/fa ================================================ آئودی آب آب دهان آب شدن آب شور آب‌پاش آبجو آب‌خوری پرنده آبراهام لینکلن آبشار آب‌فشان آبمیوه آب‌نبات چوبی آبی آپارتمان آتش آتش کمپ آتش‌بازی آتش‌سوزی جنگل آتشفشان آتش‌نشان آتش‌نشان آتلانتیس آجر آجیل آچار آخر هفته آخرالزمان آخرین آخوندک آدامس آدامس آدرس آدم پررو آدم شرور آدم‌برفی آدمکش آدیداس آرام آرام آرام آرام شدن آرامش آرایش آرایشگاه آرایشگر آرد آرژانتین آرشیو آرمادیلو آرنج آروغ آروم آزاد آزاد کردن آزادی آزادی آزمایش آزمایشگاه آزمایشی آزمون آژانس آژیر آتش‌سوزی آس آسان آسانسور آسانسور آستانه آستریکس آستین آسمان‌خراش آسمون آسیا آسیاب آسیاب بادی آسیاب بادی کوچک آسیاب کردن آسیب آسیب زدن آسیب زدن آسیب زدن آسیب‌پذیر آشپزخونه آشغال آشکار کردن آشکارساز آشنا آشنا آفت آفتاب‌پرست آفتاب‌سوختگی آفتابگردان آفریقا آفرینش آقای بین آقای بین آقای می‌سیکس آقای می‌سیکس آکادمی آکاردئون آکواریوم آکورد آگاه آگاه آگاهی آلارم آلباتروس آلبوم آلپاکا آلپاکا آلمان آلودگی آلومینیوم آماده آماده‌سازی آمار آماری آمبولانس آمپول آمریکا آمستردام آموزش آموزشی آناکوندا آناناس آنتن آنتی‌ویروس آنجلینا جولی آنفلوآنزا آنوبیس آه کشیدن آهن آهن‌ربا آهنگ آهنگر آهنگری آهنگساز آهو آوردن آونگ آووکادو آویز یخی آویزون کردن آیپد آیرون من آیفون آینده آینه آیین ائتلاف ابتکار ابدی ابر ابرو ابرو تک ابریشم ابزار ابهام ابوالهول اپرا اپرای سیدنی اتاق اتاق خواب اتحادیه اتفاق افتادن اتکا اتکا کردن اتم اتواستاپ‌زن اتوبان اتوبوس اثبات اثبات کردن اثر اجاره کردن اجاره کردن اجازه اجازه دادن اجازه دادن اجاق اجتماعی اجتماعی اجتناب‌ناپذیر اجرا اجرا کردن اجرا کردن اجراکننده اجرایی اجماع احترام احترام احتمال احتمال احتمالا احراز هویت احساس احساس احساس احساس کردن احساسی احمق احمق احمقانه احیاء احیاء کردن اخاذی اختراع اختراع اختلاف اختلاف اختلال اختیار اختیاری اخراج اخراج کردن اخگر اخلاق اخلاقی اخلاقی اخم اخمو ادامه ادای احترام ادب ادبی ادبیات ادرار ادراک ادعا ادعا ارائه اراده اراده قوی ارتباط ارتباط ارتدوکس ارتش ارتفاع ارتقا دادن ارتودنسی ارث بردن ارجاع ارجاع دادن اردک ارز ارزان ارزش ارزش ارزشمند ارزیابی ارسال کردن ارکستر ارکیده ارگانیک اره‌برقی اروپا از دست دادن ازدحام ازدواج اژدها اسب اسب آبی اسب دریایی اسب کوچک اسباب‌بازی اسپارتاکوس اسپاگتی اسپانیا اسپایدرمن اسپرسو اسپری رنگ اسپری کردن اسپری مو اسپور اسپویلر استاد استاد استاندار استاندارد استانی استثنا استحقاق داشتن استخدام کردن استخدام کردن استخر استخر شنا استخوان استرئو استراتژیک استراحت استرالیا استرس استریمر استعفا استعفا دادن استفاده کردن استفراغ استگوسوروس استودیو استیک استیو جابز اسرائیل اسطوره اسفناج اسفنج اسفنج‌باب اسقف اسکاتلند اسکایپ اسکریبل اسکریلکس اسکلت اسکله اسکله اسکن کردن اسکوبی دو اسکوییدوارد اسکی اسکیت اسکیت کردن اسکیت‌بورد اسکیت‌بوردسوار اسکیتلز اسکیمو اسلینکی اسم اسم اسنوبورد اسید اشاره اشتباه اشتراک گذاشتن اشتغال اشتها اشتیاق اشراف‌زاده اشعه ایکس اشغال کردن اشک اصرار کردن اصرار کردن اصطلاح اصل اصلاح اصلاح اصلاحیه اصلی اصلی اصلی اصیل اضافه اضافه اضافه کردن اضافه وزن اضافه‌کاری اضطراب اضطراری اطاعت کردن اطلاعات اطمینان اطمینان دادن اظهارنظر اعتبار اعتبار اعتبار مالی اعتراض اعتراض کردن اعتراف اعتراف کردن اعتصاب اعتماد اعتمادبه‌نفس اعتیاد اعدام اعطا کردن اعلام کردن اعلامیه اعلامیه اعلان اعوجاج اغراق کردن افتادن افتادن افتادن افتخار افتضاح افزایش افزونه افسانه افسانه عامیانه افسر افسردگی افسرده افق افقی افول اقامتگاه اقتصاد اقتصاد اقتصاددان اقتصادی اقدام اقلیت اقلیم اقیانوس اکتشاف اکثریت اکسپدیشن اکسکالیبور اکسیژن الاغ الاکلنگ التماس کردن التماس کردن السا الکترون الکترونیک الکترونیکی الکل الگو الماس المو الهام الهام دادن الهیات امانت‌دار امپراتوری امپراتوری امتحان امتناع امتناع کردن امتیاز امتیاز امتیاز امتیاز تجاری امتیاز دادن ام‌تی‌وی امضا امکانات املت امن امنیت امید امینم انبار انبار انبار انباشت انتخاب انتخاب انتخاب کردن انتخاب کردن انتخاب کردن انتخابات انتزاعی انتشار انتظار انتظار انتظار داشتن انتقاد انتقال انتقال انتقام انجمن انجمن انجیر انجیل انحراف انحصاری انداختن اندازه اندازه گرفتن اندام اندام اندروید اندوه انرژی انزوا انسان انسان انسانیت انضباط انطباق انعام انعطاف‌پذیر انعکاس انفجار انفجار انقباض انقلاب انقلابی انکار انکار کردن انگری بردز انگشت انگشت پا انگشت کوچک انگلستان انگور انگیزه انگیزه انیمه انیمیشن اهدا کردن اهداکننده اهمیت اوبلیکس اوج گرفتن اورانگوتان اورانوس اوریگامی اوریو اول اولاف اولویت اولین حضور اولیه اولیه ایالت ایتالیا ایدئولوژی ایدز ایده ایده ایده‌آل ایربادز ایربگ ایرلند ایستادن ایستگاه ایستگاه آتش‌نشانی ایستگاه اتوبوس ایکس‌باکس ایکیا ایگو ایلان ماسک ایمان ایمن ایمنی ایموجی اینترنت اینتل اینچ اینشتین ایوان با نفوذ بااستعداد بااعتماد باب‌اسلد بابون باتجربه باتری باتلاق باتلاق باحال باختن باد باد کردن بادام بادام‌زمینی بادبادک بادکنک بادمجان بادیگارد بار بار بار باراک اوباما باران بارانی باربر بارت سیمپسون باردار بارکد باریک باز باز کردن بازار بازاریابی بازبینی کردن بازپرس بازتوانی بازجویی بازخرید کردن بازخورد بازدارندگی بازداری بازدید کردن بازدیدکننده بازرس بازسازی بازمانده بازنده بازنشستگی بازنشسته بازنشسته بازنشسته شدن بازو بازو بازوکا بازی بازی با توپ و توپ‌بازی بازی کردن بازی ویدیویی بازیافت بازیافت کردن بازیکن بازیگر باستان‌شناس باستان‌شناسی باسن باسن باشکوه باشگاه باغ باغبان باغ‌وحش بافت بافت بافتن بافندگی باقلوا باقی ماندن باکره باگت باگز بانی بال بالا بالا بردن بالا رفتن بالا رفتن بالرین بالش بالغ بالقوه بالکن بالن باله بامبرمن بامبو بامبی بامزه بانجو بانجی جامپینگ باند باند باندان بانک بانک کوکی بانکدار باهوش باور باورنکردنی ببخشید ببر بتمن بتن بتهوون بچگانه بچه بچه‌گربه بحث بحث کردن بحث‌برانگیز بحران بحرانی بخار بخش بخش بخش بد بدبخت بدبختی بدجنس بدشانس بدن بدن انسان بدنام بدهکار بودن بدهی برآمدگی برآورد برابر برادر برادرزاده براق براکت براونی بربر برتر برج برج ایفل برج پیزا برج جدی برچسب برچسب قیمت برخلاف برخلاف بردن برده بررسی بررسی اجمالی برزیل برس برش برش زدن برف برق برق برق زدن برق‌کار برکت دادن برکه برگ برگشتن برگه برنامه برنامه درسی برنامه زمانی برنامه‌نویس برنج برند برنده برنز بره برهنه بروکلی بریدن بز بزاق بزرگ بزرگ بزرگ کردن بزرگراه بزرگسال بزرگی بسامد بستن بستن بستنی بستنی یخی بستنی‌ماشین بسته بسته بسته بسته‌بندی بسکتبال بشقاب بشقاب بشکه بشکه آبجو بصری بطری بعد بعدازظهر بعدی بعید بغل کردن بغل کردن گرم بقا بلاغت بلعیدن بلند بلند بلند بلند شدن بلندگو بلوبری بلوط بلوط بلوک بلوند بلیت بمب بمب اتمی بمب‌افکن بنا بند بند انگشت بند کفش بندر بنر بنزین بنیاد به تعویق انداختن به دست آوردن به فرزندی گرفتن به نظر آمدن بهار بهانه بهبود بهبود دادن بهبودی بهبودی پیدا کردن به‌دست آوردن بهره‌برداری به‌روزرسانی بهشت به‌یادماندنی بو بو بو کشیدن بوته بوته بوته آزمایش بودجه بورس تحصیلی بوریتو بوسیدن بوفه بوقلمون بولتن بولدوزر بولینگ بوم بومرنگ بومی بومی بیابان بیابان بی‌ام‌و بیان بیان کردن بیانیه بی‌پروا بیت‌باکس بیت‌کوین بیتلز بی‌توجهی کردن بیچاره بی‌حسی بی‌خانمان بی‌خبر بی‌خوابی بید مجنون بیدار بیدار شدن بیدار کردن بی‌ربط بی‌رحم بی‌رحمی بیرون بیسبال بیسکویت بی‌سیم بیضی بی‌فایده بی‌قرار بی‌قرار بیکار بیکاری بیکن بیگ بن بیگل بی‌گناه بیگودی بیل بیل گیتس بیل مکانیکی بیلچه بیلیارد بیمار بیمارستان بیماری بیماری بیماری بی‌مزه بیمه بیمه کردن بی‌میلی بین‌المللی بینایی بین‌بگ بینش بی‌نظمی بینگو بی‌نهایت بینی بیوه پا پا پاپ پاپ پاپ‌آی پاپایا پاپ‌کورن پاتریک پاداش پادشاه پادشاه پادشاهی پادشاهی پارادوکس پاراگراف پارامتر پارچه پارچه پارک پارکینگ پارلمان پاره‌وقت پارو پارو زدن پاریس پاسپورت پاستا پاستلی پاستیلی پاستیلی خرسی پاستیلی کرمی پاسخ پاشنه پافشاری پافشاری کردن پاک کردن پاکت پاکت پاک‌کن پاکی پالت پالتو پاندا پانک پاها پای پای سیب پایان پایان‌نامه پایتخت پایدار پایدار پایدار پایه پایین پایین پایین پایین‌تر کردن پپا پیگ پپرونی پپسی پتو پختن پختن پخش پدال پدر پدربزرگ پدرخوانده پدیده پذیرایی پذیرایی کردن پذیرش پذیرش پر پر پر انرژی پر سر و صدا پر قلم پر کردن پراکنی کردن پرت کردن پرتاب پرتاب کردن پرتاب کردن پرتره پرتزل پرتغال پرتقال پرتگاه پرتو پرچم پرچین پرخاشگر پرداخت پرداخت کردن پرده پررنگ پرستار پرسشنامه پرسه زدن پرسیدن پرش اسکی پرشور پرمو پرنده پرواز پرواز کردن پروانه پروانه شب‌پره پروتئین پروجکشن پرورش دادن پرورش دادن پروژه پروفایل پری پری دریایی پریدن پریدن پریز پریسکوپ پرینتر پرینگلز پژواک پست پست پستان گاو پستچی پسته پسر پسر پسرعمو پس‌زمینه پشت پشتک پشته پشم پشمک پشه پشیمانی پک‌من پل پل تاور پلاتیپوس پلاستیک پلنگ پلنگ سیاه پلنگ سیاه پله پلوتو پلی‌استیشن پلیس پلیکان پمپ پناهگاه پناهگاه پناهنده پنبه پنجره پنجه پنکه سقفی پنکیک پنگوئن پنل پنی پنیر پودر پودل پودینگ پورکی پیگ پوزخند پوزیدون پوست پوست درخت پوستر پوسته پوسته پوسیدگی پوشاندن پوشش پوشک پوشه پوشیدن پوکمون پول پول نقد پولو پولیش کردن پومبا پوند پویا پیاده‌رو پیاز پیام پیامد پیانو پی‌پال پیتزا پیچ پیچ پیچ بال پیچاندن پیچک پیچک پیچیدگی پیچیدن پیچیده پیچیده پیدا کردن پیدا کردن پیر پیراهن پیروزی پیژامه پیشانی پیش‌بینی پیش‌پاافتاده پیشخدمت پیشخوان پیش‌ذهن پیشرفت پیشرفت پیشرو پیش‌فرض پیشگام پیشنهاد پیشنهاد پیشنهاد پیشنهاد دادن پیشنهاد کردن پیش‌نویس پیشینی پیکاچو پیکاسو پیک‌نیک پیله پیمانه پین‌بال پینت‌بال پینک پنتر پینوکیو پیوست پیوسته پیوند تأثیر گذاشتن تأسیس کردن تأسیس‌شده تأیید تأیید کردن تئاتر تا کردن تاب خوردن تابستان تابلو ایست تابه تابوت تاثیر تاثیر گذاشتن تاثیرگذار تاج تاج گل تاجر تاجر تاخیر تار تارزان تاریخ تاریخ‌دان تاریخی تاریک تازه تازه‌کار تازه‌کار تازه‌وارد تاس تاکتیک تاکسی تاکو تاکید تالار تامپون تامین تانک تایتانیک تب تبخیر شدن تبدیل کردن تبر تبریک گفتن تبعید تبعیض تبلت تبلیغ تبلیغات تبلیغات تبلیغات تبلیغاتی تپانچه تپانچه تپه تتریس تجارت تجارت تجربه تجربی تجمع تجهیزات تحت تاثیر قرار دادن تحریک تحریک کردن تحسین تحسین کردن تحقیر تحقیق تحقیق تحلیل تحلیل‌گر تحمل کردن تحمل کردن تحمل‌کننده تحویل تحویل دادن تخت تخت پادشاهی تخت دوطبقه تخته تخته تخته سنگ تخته موج‌سواری تخریب کردن تخصص تخصیص تخفیف تخلیه تخم‌مرغ تخم‌مرغ طلایی تخیل تدارکات تدریجی تراژدی تراس تراش مداد تراشیدن ترافیک تراکتور تراکنش تراموا تربچه ترتیب دادن ترجمه کردن ترجیح ترجیح دادن ترحم ترخیص تردمیل تردید کردن ترس ترساندن ترساندن ترساندن ترسناک ترسناک ترسیده ترش ترشح ترفیع ترقه ترک ترک ترک کردن ترکیب ترکیب ترکیب کردن ترکیدن ترمز ترمیناتور ترمینال تروریست ترومبون ترومپت تریلر تزئین تزئینی تزریق کردن تست تسکین تسکین دادن تشبیه تشخیص تشدید کردن تشعشع تشک تشکر کردن تشکیل تشنگی تشنه تشویق تشویق کردن تشویق‌کننده تصاحب کردن تصادف تصادف تصادف تصادفی تصمیم تصمیم گرفتن تصور تصور کردن تصور کردن تصویر تصویر تصویرسازی تضعیف کردن تظاهرات تظاهرکننده تعادل تعادل تعامل تعاملی تعاونی تعبیر کردن تعجب تعجب تعجب‌آور تعریف تعریف کردن تعصب تعطیلات تعطیلات تعقیب تعقیب تعقیب قضایی تعلق داشتن تعمیر کردن تعهد تعهد تعویق انداختن تغییر تغییر تغییر شیفت تغییر قیافه تف کردن تفاوت تفاوت داشتن تفریح تفریح تفریحگاه تفنگ تفنگ تفنگ آب‌پاش تفنگ قدیمی تقارن تقاضا تقاطع تقسیم تقسیم کردن تقصیر تقویت کردن تقویت کردن تقویم تکامل تکان دادن تکان دادن تک‌تیرانداز تک‌چرخه تکرار تکرار کردن تکلیف تکنولوژی تکنیک تکه تکه تکه تکه کوچک تکه‌پاره تکی تکی تلاش تلاش کردن تلتبی تلخ تلسکوپ تلفات تلفن تله تله خرس تله موش تلویزیون تم تماس تماس گرفتن تماشاگر تمام کردن تمام‌شده تمام‌وقت تمبر تمدن تمرکز تمرکز کردن تمرین تمرین تمرین تمساح تمساح تمشک تمشک تمیز تمیز کردن تن تن ماهی تناسب اندام تناقض تنبل تنبل تنبیه تنبیه کردن تند تنش تنظیم کردن تنگ تنگ ماهی تنه تنه درخت تنها تنها در خانه تنوع تنیس تنیس روی میز تهاجم تهدید تهدید کردن تهویه توافق توالت توالی توان مالی داشتن توانایی توانستن توانمند توانمند توپ توپ برفی توپ جنگی توپا توت توت‌فرنگی توتم توجه توجه کردن توجیه توجیه کردن توده توده تور تور تورپدو تورم تورنمنت توزیع کردن توزیع‌کننده توستر توسعه توسعه دادن توصیف کردن توصیه توصیه کردن توضیح توضیح دادن توضیح دادن با تصویر توطئه توقف کردن توقف کردن توکان تولد تولید تولید کردن تولید کردن تولید کردن تولید مثل تولید مثل کردن تولیدکننده تولیدکننده تولیدمثل تومور تومور تونل توهم توهین‌آمیز تویتی توییتر تی دستی تیتر تیر تی‌رекс تیرامیسو تیراندازی کردن تیز تیزر تی‌شرت تیغ تیغ اصلاح تیغه تیک تیم تیمپانی ثابت ثابت ثانیه ثبت کردن ثبت‌نام ثروت ثروت ثروتمند ثور جاده جادو جادوگر جادوگر جاذبه جارو جارو کردن جاروبرقی جاری جاسوس جالب جام جامد جامدادی جامع جامعه جامعه جامعه‌شناسی جاه‌طلب جاه‌طلبی جای زخم جایزه جایزه جایگزین جایگزین جایگزین کردن جبران جبران خسارت جبران کردن جدا کردن جدایی جدول زمانی جدی جدید جدیدترین جذاب جذابیت جذابیت جذب جذب کردن جذب کردن جرئت جراح جراحت جرعه جرعه خوردن جرقه جرم جرم جرم جرم گوش جریان جریان اصلی جریان برق متناوب جریمه جز جزئیات جزر و مد جزیره جستجو جستجو کردن جستجو کردن جسد جسمانی جشن جشن گرفتن جشنواره جعبه جعبه جعبه ابزار جعبه خاک گربه جعبه دستمال جعبه شنی جعبه کبریت جعبه کفش جغد جغرافیا جفت جک‌همری جکی چان جگر جلبک دریایی جلسه جلسه جلو جلو جلو بردن سریع جلوگیری کردن جمجمه جمع جمع‌آوری جمعه سیاه جمعیت جمعیت جمله جمهوری جن کوتوله ایرلندی جن گا جنایتکار جنبه جنتلمن جنسیت جنگ جنگ بالشی جنگ توپ برفی جنگ ستارگان جنگجو جنگل جنگل جنگل بارانی جنگلداری جنوب جنین جهان جهان جهانی جهت جهت جهت‌گیری جهش جهنم جهیدن جو جواب جوان جوانی جوجه‌تیغی جوجه‌تیغی جوراب جوراب‌ها جوز هندی جوش جوش جوشکار جوشیدن جونیور جویدن جیب جیپ جیرجیرک جی‌زی جیغ زدن جیمز باند جین آبی جیوه چابک چاپ کردن چادر چارلی چاپلین چاشنی چاق چاق چاقو چاک نوریس چالش چانه چاه چای چپ چتر چتر نجات چتربازی چراغ چراغ راهنمایی چراغاه چراغ‌قوه چرت زدن چرخ چرخ خیاطی چرخاندن بطری چرخ‌دستی چرخ‌دنده چرخش چرخه چرخه آب چرخیدن چرخیدن چرم چرند چریکی چسب چسب زخم چسب ماتیکی چسب نواری چسبناک چشم چشم لندن چشم‌انداز چشم‌انداز چشم‌بند چغندر چک چک چکش چکش بزرگ چکمه چکمه‌ها چکه چگالی چمباتمه چمدان چمدون چمن چمن چمنزار چمن‌زن چندرسانه‌ای چندگانه چنگ چنگال چنگال چنگک چنگک چهارپایه چهارراه چوب چوب چوب چوب شب‌تاب چوب غذا چوباکا چوب‌بر چوب‌پران چوب‌پنبه چوب‌پنبه‌بازکن چوب‌لباسی چوب‌لباسی چیپس چیدمان چیدمان چیزبرگر چیزکیک چیزها چین چین و چروک چینچیلا چیواوا حاد حادثه حاشیه حاضر حافظه حال‌به‌هم‌زن حال‌به‌هم‌زن حالت حامل حامی حباب حجم حد حداقل حداکثر حدس زدن حذف حذف کردن حذف کردن حذف کردن حرف زدن حرف‌زن حرفه حرفه‌ای حرفه‌ای حرفه‌ای حرکت حرکت حرکت کردن حرکت کردن حریف حریم خصوصی حس حس حساب حسابدار حساس حساسیت حساسیت حسود حشره حصار حضانت حضور حفاظت حفاظت حفاظت حفاظت کردن حق حق نشر حق‌السهم حقه حقیقت حکاکی حکم حکم حکومت حکیم حل شدن حل کردن حل و فصل کردن حلزون حلقه حلقه حلقه بینی حمام حمایت کردن حمایت کردن حمل کردن حمل و نقل حمله حمله حوزه انتخابیه حوزه قضایی حوله حومه حومه حیات وحش حیاط حیاط حیوان حیوان خانگی خار دادن خاراندن خارجی خارجی خارجی خاص خاک خاک رس خاکستر خاکستری خال خالص خالکوبی خاله خالی خالی خالی خام خام خامه خانگی خانم خانم خونه‌دار خانه عروسکی خانواده خاویار خبر خبرنگار خبرنگار خجالت خجالت‌زده خجالتی خدا خدمت خدمتکار خدمتکار خدمه خراب کردن خراشیدن خربزه خرت خرج کردن خرچنگ خرد کردن خردسال خردل خرده‌فروش خرده‌فروشی خرس خرس قطبی خرگوش خرگوش خرگوش عید پاک خروج خروجی خروس خرید خریدن خز خزانه‌دار خزنده خزه خسته خشخاش خشک خشکسالی خشم خشم خشن خشن خشن خشونت خصوصی خط خط استوا خط افق شهر خط هوایی خطا خط‌خطی کردن خطر خطر خطرناک خط‌کش خط‌کش یارد خطی خفاش خفه شدن خلاصه خلاصه خلاصه کردن خلال دندان خلبان خلق کردن خلیج خم شدن خمیازه خمیر خمیر دندان خنثی خنجر خنجر زدن خندق خنده‌دار خندیدن خواب خواب زمستونی خوابیدن خواستن خواندن خواننده خواننده خواهر خوب خوب خود خودجوش خودکار خودکار خودکشی خودگردان خوردن خورشید خورشیدگرفتگی خورشیدی خوره خوش‌آمدگویی خوشبو خوش‌بین خوش‌بینی خوشحال خوشحال خوش‌شانس خوشگل خوشمزه خوشه خوک خوک پرنده خوکچه هندی خوک‌دانی خون خون‌آشام خون‌دماغ خوندن خونریزی خونریزی خونه خونه خونی خویشاوندی خیابان خیار خیارشور خیاط خیانت کردن خیره شدن خیره شدن خیریه خیس خیس کردن خیلی خیلی بامزه دائمی داخل داخلی داخلی داخلی دادستانی دادگاه دادن دارایی دارت دارکوب دارو داروساز داروین داروین واترسون داس داستان داستان داستانی داشبورد داشتن داغ دافی داک دالماسی داماد دامبو دامپزشک دامن دامن دانستن دانش دانش‌آموز دانشجو دانشجو دانشگاه دانشگاه دانشگاهی دانشمند دانلود دانه دانه دانه برف دانه سیب داور داوطلب داوطلبانه دایره دایناسور دبیر دخالت دختر دختر دخترعمو ددپول ددلاین در در بر گرفتن در تله در حال بارگذاری در حال حرکت در دسترس در دسترس در زدن در ظرف در معرض بودن در معرض گذاشتن در نظر گرفتن در نظر گرفتن درآمد دراز کشیدن دراز کشیدن دراکولا درام دراماتیک دربازکن درپ درخت درخت توس درخت‌خانه درخشش درخشیدن درخشیدن درخواست درخواست درد دردناک درس درست درشکه درصد درک درک کردن درگیری درگیری درمان درمان درمان درمانگر دره دره درهم ریختن درهم شکستن درو دروازه دروازه دروازه‌بان دریا دریاچه دریازده دریایی دریچه فاضلاب دریل دزد دزد دزد دزد دریایی دزدی دزدی دزدی کردن دژ دست دست دادن دست زدن دست زدن دست کشیدن دستاورد دست‌اول دستبند دسترسی دستشویی دستکش دستگاه دستگاه پخش دستگیره دستگیره در دستگیری دستمال دستمال سفره دستمال کاغذی دستمزد دست‌نوشته دسته جارو دسته‌بندی دسته‌بندی دست‌ودل‌باز دستور دستور دستور زبان دستور کار دستورالعمل دستورالعمل دستی دسر دشمن دشمن‌وار دشمنی دعا دعا کردن دعوا دعوا با مشت دعوای حقوقی دعوت کردن دعوت‌نامه دفاع دفاع کردن دفتر دفترچه دفن دفن کردن دقت دقیق دقیق دقیق دقیقه دکتر دکستر دکمه دگرگون کردن دلار دلال دل‌بخواهی دلپذیر دلتنگی کردن دلسرد کردن دل‌شکستگی دلفین دلقک دلقک دربار دلگرم‌کننده دلیل دم دم اسبی دما دماسنج دم‌ها دموکراتیک دموکراسی دمیدن دنبال کردن دنباله‌دار دندان دندان مصنوعی دندانپزشک دنده دندون‌پری دهان دهانی دهقان دهکده دهه دو برابر دوئل دوجین دوچرخه دوچرخه دوچرخه بی‌ام‌ایکس دوختن دوختن دود دودکش دور دور دور دور ریختن دورا دوراهی دوربین دوربین دوچشمی دوره دوره دوره دوری کردن دوریتوس دوز دوزیست کوچک دوست دوست داشتن دوست نداشتن دوستانه دوستی دوش دوشاخه دوشنبه دوقلو دوک دولت دومینو دونالد ترامپ دونالد داک دوندہ دویدن دی‌ان‌ای دیپلمات دیپلماتیک دیجیتال دیدن دیدن دیر دیس ترک دیسک دیسک فلاپی دیسکو دیسکورد دیکته کردن دیگ دیگ طلا دیگر دیلم دین دینامیت دیو دیوا دیوار دیوار چین دیوان‌سالارانه دیوان‌سالاری ذات ذات‌الریه ذخیره کردن ذخیره کردن ذرت ذره ذره‌بین ذکر کردن ذهن ذهنی ذهنی ذی‌نفع رأی دادن رأی‌دهندگان رأی‌دهنده رأی‌گیری رئالیسم رئیس رئیس‌جمهور رابط رابطه رابطه رابی روتن رابین‌هود راحت راحت راحتی راحتی رادار رادیکال رادیو راز راست راست راست کردن راست‌گرا راست‌گو راسوی بدبو راسوی کوچک راضی راک‌استار راکت تنیس راکتور راکن راگبی ران رانش رانندگی راننده راننده راننده اتوبوس راننده تاکسی راننده تاکسی راننده کامیون راه راه رفتن راه‌آهن راهب راهبه راهپیمایی راهپیمایی راه‌حل راهرو راهرو راهنما راویولی ربات ربط داشتن ربع رپر رتبه رحم رد شدن رد کردن ردیابی ردیت ردیف رژ لب رژیم رستگاری رستوران رسمی رسمی رسوایی رسید رسیدن رشته رشد رشد کردن رصدخانه رضایت رضایت‌بخش رعد رفاه رفاه رفتار رفتار رفتار کردن رفتن رفتن رقابت رقابت کردن رقابتی رقص رقیق کردن رک رکود رکورد رکورد بالا رگ رم رمان رمانتیک رمپ رمز عبور رنج رنج بردن رنجاندن رنجیدن رنگ رنگ کردن رنگارنگ رنگین‌کمان رهبر رهبر ارکستر رهبری رهبری کردن روانشناس روانشناسی روبان روباه روبند روبه‌رو شدن روتین روح روح روح روحیه رودخانه روده روده بزرگ روز روزانه روزنامه روستایی روستایی روسیه روش روش‌شناسی روشویی روغن روکش کیک رومانی رومیزی رون روند روند رونق روی میز رویا رویارویی رویکرد ریاست‌جمهوری ریاست‌جمهوری ریاضی ریاضیات ریتم ریختن ریختن ریختن ریسک ریش ریش بزی ریشه ریشه ریک ریل ریه زئوس زالو زامبی زانو زانو زدن زاویه زایلافون زباله زبان زبان زپلین زحل زخم زخم معده زدن زدن زرافه زرد زردآلو زرده زره زره سینه زشت زغال زگیل زلدا زلزله زمان زمرد زمزمه کردن زمستان زمین زمین زمین زمین بازی زمین بازی زمین‌شناسی زن زنانه زنبور زنبور زنجره زنجیر زنجیر طلا زندان زندان زندانی زندگی زندگی پس از مرگ زندگی‌نامه زنده زنده بودن زنگ زنگ زنگ موبایل زنگوله گاو زهره زوج زوج زود زور زورو زوم زوما زیبایی‌شناسانه زیپ زیپ‌لاین زیر بغل زیرخط کشیدن زیردریایی زیرزمین زیرزمینی زیرساخت زیرلب گفتن زیرلیوانی زیروکس زیست‌شناسی زیست‌محیطی زیگزاگ زین ژاپن ژاکت ژامبون ژله ژله ژن ژنتیکی ژنراتور سابقه ساحل ساحل ساختار ساختمان ساختن ساختن سادگی ساده ساده ساز سازدهنی سازگار سازگار سازمان سازماندهی کردن سازنده سازه‌ای ساس ساعت ساعت ساعت ساعت شنی سافاری ساق پا ساقه ساقه لوبیا ساکسیفون ساکن ساکن سال سالاد سالانه سال‌اولی سالگرد سالم سالمند سالمند سالمون سالن استراحت سالنامه سامسونگ سانتا ساندویچ سانسور سایبان سایبورگ سایه سایه سایه چشم سبد سبد خرید سبز سبزیجات سبک سبک زندگی سبیل سپر سپر سپرده ست درام ست کردن ستاره ستاره دریایی ستاره میوه‌ای ستایش کردن ستون ستون ستون فقرات ستون فقرات سخت سخت سخت سخت‌افزار سخت‌گیر سختی سختی سخنرانی سخنرانی سخنگو سدیم سر سر تکان دادن سر خوردن سر خوردن سرآشپز سرایدار سرباز سربروس سرپرست سرپناه سرپوشیده سرتاپا گرفتار سرتخت سرخ شدن سرخس سرد سرداب سردرد سردرگمی سرزمین عجایب سرزنده سرزنش سرشماری سرطان سرعت سرعت سرفه سرقت سرقت مسلحانه سرکه سرکوب کردن سرگرم کردن سرگرم کردن سرگرمی سرگیجه سرمازدگی سرمایه‌داری سرمایه‌گذاری سرنخ سرنیزه سرو کردن سرور سروصدا سری سریع سس سس تند سس سالاد سطح سطح سطل سطل سطل آشغال سفارت سفالگری سفر سفر سفر دریایی سفید سقط جنین سقط جنین سقف سقف سکته سکسکه سکه سکو سکوت سکولار سکونتگاه سگ سگ آبی سگ‌وی سلاح سلام سلام کردن سلامت سلبریتی سلسله‌مراتب سلطنت سلطنتی سلطه سلول سم سم اسب سمفونی سمور آبی سمی سمی سمینار سن سناریو سنت سنتی سنج سنجاب سنجاق سنجاقک سند سندان سندرم سنسی سنگ سنگ سنگ قبر سنگ قیمتی سنگاپور سنگین سهام سهام‌دار سه‌پایه سه‌چرخه سه‌قلو سهل‌انگاری سهم سهمیه سوءاستفاده سواد سوار سوار شدن سوال سوایپ کردن سوپ سوپرانو سوپرمارکت سوپرمن سوت سوخت سوختن سود سود تقسیمی سودوکو سوراخ سوراخ کردن سوراخ‌های بینی سورتمه سوزان وجیکی سوزن سوسک سوسک سوسیالیست سوسیس سوشی سوکت سوگ سوگواری سومبررو سونا سونیک سوهان ناخن سوییت سوییچ سیارک سیاره سیاست سیاست سیاستمدار سیاسی سیال سیاه سیاه‌چاله سیب سیب طلایی سیب‌زمینی سیب‌زمینی سرخ‌کرده سیر سیرک سیستم سیستماتیک سیفون سیکس پک سیگار سیل سیلندر سیلو سیلی زدن سیم سیم خاردار سیمان سینک سینما سینه سینه سینه‌سرخ سینی شات شات حقه‌ای شاتگان شاخ شاخه شاخه نازک شاد شادی شارژ شارژر شاکی شال‌گردن شام شام خوردن شامپانزه شامپاین شامپو شامل شدن شانس شانس شانه شانه عسل شاه‌بلوط شاهد شاهزاده شاهزاده خانم شایستگی شایعه شب شباهت شب‌تاب شبدر شبکه شبکه شبکه اجتماعی شبنم شبه‌جزیره شبیه شبیه بودن شتاب شتر شترمرغ شترمرغ شجاع شجاعت شخص شخصی شخصیت شخصیت شخم زدن شدن شدید شدید شراب شراکت شرایط شرایط شرط شرق شرک شرکت شرکت کردن شرکت‌کننده شرکتی شرلوک هولمز شرم شرور شرور شروع شروع کردن شروع کردن شروع کردن شریف شریک شست دست شستن شست‌وشوی مغزی شش‌ضلعی شطرنج شعار شعبده‌باز شعبده‌بازی شعر شعر شعله‌افکن شغل شغلی شفا دادن شفاف شفاف شفاف‌سازی شفت شفق قطبی شک شک شکار شکار کردن شکارچی شکارچی شکاف شکاف شکاف شکافتن شکایت کردن شکر شکست شکست خوردن شکست دادن شکستن شکسته شکل شکل شکل شکلات شکم شکنجه شکوفا شدن شکوفه گیلاس شگفت‌انگیز شگفت‌انگیز شل شلاق شلاق اسب شلغم شلنگ شلوار شلوار شلوار جین شمال شمردن شمرده حرف زدن شمشیر شمشیر سامورایی شمشیر نوری شمشیربازی شمشیرماهی شمع شن شن شن روان شنا کردن شناخت شناختن شناختن شناسایی شناور شدن شناور شدن شنل شنل شنیدن شهاب‌سنگ شهر شهر شهرت شهرت شهردار شهرداری شهروند شهری شوالیه شوخی شوخی کردن شور و اشتیاق شورا شورت شورش شورش شورشی شوره سر شوک شومینه شونه شونه شونه بالا انداختن شوهر شیء شیب شیر شیر شیر آب شیر آب شیر آتش‌نشانی شیر دریایی شیرجه شیرشاه شیرفروش شیروانی شیرین شیرین‌بیان شیرینی شیشه شیشه شیشه جلو شیک شیمی شیمیایی شیوع صابون صاحب‌خونه صادرات صاف صاف صبح صبحانه صبر صحنه صحنه صخره صخره مرجانی صدا صدا صداقت صدای انفجار صدف صدف دریایی صریح صف صف صفحه صفحه نمایش صفر صلاحیت صلاحیت صلح صلیب صندل صندلی صندلی صندوق صندوق پستی صنعت صنعتگر صنعتی صورت صورت فلکی صورت‌بندی صورتحساب صورتی صومعه صومعه ضبط ضخیم ضدحریق ضرب کردن ضربه ضروری ضعف ضعیف ضمانت ضمنی ضمیمه ضیافت طاعون طاق طاق طاووس طبقه طبقه متوسط طبل طبیعت طراح طراح مد طراحی طرح طرح زدن طرح کلی طرفدار طعم طعمه طعمه کلیک طعنه طلا طلاق طلسم کردن طلوع آفتاب طمع طناب طناب طناب‌اندازی طناب‌بازی طوطی طوطی دریایی طوطی کوچک طوفان طوفان رعد و برق طوفان شنی طول طولانی طولانی طیف ظاهر ظاهر شدن ظرف بزرگ ظروف نقره ظریف عابر پیاده عاج عادت عادلانه عادی عاشق عالی عالی عامل عبارتبندی عجله کردن عجیب عجیب‌وغریب عدالت عدد عدم تقارن عدم قطعیت عذاب عذرخواهی عذرخواهی کردن عرشه عرض عرق کردن عروس عروس دریایی عروسک عروسک تدی عروسک خیمه‌شب‌بازی عروسی عسل عشق عصا عصا عصای جادویی عصب عصبانی عصبی عصر عصر حجر عضله عضو عضویت عطر عطسه کردن عفونت عفونت دادن عقاب عقب عقب بردن عقب‌نشینی عکاس عکاسی عکاسی ماشین عکس علاءالدین علاقه علاقه علامت علامت علت علف هرز علم علمی عمارت عمل عمل جراحی عمل جراحی عملی عملیاتی عمه عمو عمودی عمومی عمومی عمیق عمیق عنصر عنکبوت عنکبوت تارانتولا عنوان عهد عوارض عید پاک عینک عینک آفتابی غار غارنشین غارنورد غاز غالب غایب غذا غذای حیوان خانگی غذای دریایی غذای مونده غرب غربی غرش کردن غرفه غرق شدن غرق شدن کشتی غرق کردن غرور غریدن غریزه غش غفلت غلات غلبه کردن غلتیدن غلتیدن غلغلک دادن غم غمگین غواصی غول غول آهنی غول تجارت غول چراغ غول‌پیکر غیبت غیررسمی غیرعادی غیرقانونی غیرقانونی غیرمستقیم غیرممکن غیرمنتظره غیرنظامی فاجعه فاخته فارغ‌التحصیل شدن فارغ‌التحصیلی فاسد فاصله فال روزانه فانتا فانتزی فانوس فانوس دریایی فایده فایل فتوشاپ فتوکپی فحش فدراسیون فدرال فر فر کردن فراتر رفتن فرار فراری فرازمینی فراغت فراموش کردن فرانسه فرانکنشتاین فراهم کردن فراوان فراوان فرایند فرد فرد فرد فلینتستون فرزند فرزندخواندگی فرسایش فرستادن فرش فرش قرمز فرش کوچک فرشته فرض فرض کردن فرض کردن فرضیه فرغون فرمانده فرمت فرمول فرهنگ فرهنگ لغت فرهنگی فرو بردن فروپاشی فروپاشی فروختن فرودگاه فرورفتگی فروش فروشگاه فروشگاه حیوان خانگی فروشنده فریاد زدن فریزر فساد فست‌فود فست‌فود فسیل فشار فشار آوردن فشار دادن فشار دادن فشردن فشرده فصل فصل فصلی فصیح فضا فضاپیما فضانورد فضای خزیدن فضایی فضیلت فعال فعال کردن فعالیت فقیر فک فکر فکر کردن فکری فکس فلاخن فلاسک فلامینگو فلج فلز فلسفه فلسفی فلش فلفل فلفل جلابینو فلفل دلمه‌ای فلوت فلوت پان فلوریدا فمیلی گای فمینیست فنجان فندق فندق‌شکن فندک فنی فهرست فهرست فهرست فهمیدن فواره فوتبال فوتبال فوریت فوق‌العاده فوک فولاد فویل فیبر فیجت اسپینر فیزیک فیس‌بوک فیگور فیل فیلتر فیلسوف فیلم فیلم فیلم‌ساز فیلمنامه فین فین و جیک فینیاس و فرب قاب قاب عکس قابل اجرا قابل اعتماد قابل پیش‌بینی قابل توجه قابل حمل قابل دیدن قابل قبول قابل مقایسه قاپیدن قاتل قاتل قادر قارچ قاره قاره‌ای قاشق قاشق چای‌خوری قاصدک قاضی قاطع قاطع قانع کردن قانون قانون قانون قانون اساسی قانون‌گذاری قانونی قانونی قایق قایق بادبانی قایق بادی قایق تفریحی قایقرانی قایم شدن قبر قبرستان قبرکن قبول کردن قبیله قتل قدرت قدرت قدرت فوق‌العاده قدرتمند قدردان قدردانی کردن قرآن قرار قرار ملاقات قرارداد قربانی قربانی قرص قرص نون قرض دادن قرض گرفتن قرقره قرمز قرن قرون وسطی قسم خوردن قسمت قسمت قشنگ قصاب قصد قضاوت قضایی قطار قطب قطب جنوب قطب‌نما قطر قطره قطره باران قطری قطع عضو قطع کردن قطعه زمین قطعی قطعی قفس قفسه قفسه قفسه کتاب قفل قلاب قلاده قلب قلع قلعه قلعه قلعه شنی قلک قلم نوری قله قله قله اورست قناری قنطورس قهرمان قهرمان قهوه قهوه‌ای قهوه‌خانه قو قوچ قورباغه قوری چای قوطی قول دادن قومیتی قوی قیچی قیمت کابل کابوس کابوی کابینت کابینت کاپشن کاپ‌کیک کاپوچینو کاپیتان کاپیتان آمریکا کاتالوگ کاج کاخ کادوپیچی کار کار کار راه بنداز کارآگاه کارآمد کارائوکه کاراته کاربر کاربردی کاربردی کارت کارت اعتباری کارت پستال کارتون کارخانه کارخانه آبجوسازی کاردک کارزار کارشناس کارفرما کارکرد کارکنان کارگاه کارگر کارگر کارگردان کارمند کارمند کارناوال کارواش کاری کاریزماتیک کازو کازینو کاست کاسه کاشتن کاشی کاغذ کاغذ دیواری کافه کافی کافی کاکتوس کالری کامپیوتر کامل کامل کامل کامیون کامیون یدک‌کش کانادا کانال کانال سوئز کانگورو کاهش کاهش کاهو کاوش کایوت کباب کباب کبرا کبریت کبوتر کبودی کپک کپک کپی کت رسمی کت و شلوار کتاب کتاب کمیک کتابخونه کتابدار کتان کتری کت‌وومن کتی پری کثیف کثیف کج کردن کچاپ کچل کد کد مورس کدو تنبل کدو تنبل نورانی کراکن کرامت کراوات کرایه کربن کربی کرش بندیکوت کرکس کرگدن کرم کرم ابریشم کرم اصلاح کرمیت کره کره کره کره شمالی کرواسی کروز کروسان کروم کریپر کریستال کریسمس کسب کسب‌وکار کسر کسری کسل‌کننده کش آمدن کشاورز کشاورزی کشاورزی کشتن کشتی کشتی کشتی دزدان دریایی کشتی‌گیر کشتی‌گیری کشتی‌گیری کردن کشف کشف کردن کشمش کشنده کشو کشور کشیدن کشیدن کشیدن کشیدن کشیش کف دست کفتار کفش کفش پاشنه‌بلند کفشدوزک کک کک‌ومک کک‌ومک‌ها کل کل کلاب شبانه کلارینت کلاس کلاس درس کلاسیک کلاغ کلامی کلاه کلاه کلاه استوانه‌ای کلاه ایمنی کلاه ایمنی کلاه بافتنی کلاهبرداری کلاه‌گیس کلبه کلبه کلبه کلمه کلنگ کلوسئوم کلی کلید کلیسا کلیسا کلیک کردن کلینیک کلیه کم کم کردن کما کمان کمان پولادی کماندار کمبود کمبود کمبود کمپ کمپینگ کمد لباس کمدی کمدین کمر کمربند کمربند ایمنی کمردرد کم‌عمق کمک کمک کردن کم‌وزن کمونیست کمونیسم کمی کمیته کمیسیون کنار کنار آتش کنار آمدن کنار کشیدن کنتراست کنترل کنترل‌کننده کنجکاو کنداما کندن کندو کنسرت کنسول کنفرانس کنگره کنگلومرا کنوانسیون کهربا کهکشان کهکشان راه شیری کهنه‌سرباز کوآلا کوبا کوبیدن کوپن کوتاه کوتاهی مو کوتوله کوتوله کوچک کوچک شدن کوچه کوچه کوچولو کوچیک کودتا کودک کودکی کور کوررنگ کوسن کوسه کوفته گوشت کوکتل کوکی کوکی مانستر کولاک کولر کوله‌پشتی کونگ‌فو کوه کوه راشمور کوه یخ کوه‌پیمایی کی‌اف‌سی کیبورد کیت کیسه کاغذی کیف کیف دستی کیفیت کیک کیم جونگ اون کینگ‌کنگ کیوپید کیوی گابلین گاراژ گارد ساحلی گارسون گارفیلد گاز گاز گرفتن گازدار گالری گالن گام گام بلند گاندی گانگستر گاو گاو دریایی گاو نر گچ گچ گدازه گذار گذاشتن گذاشتن گذرگاه گذرگاه گذشته گراز گراز دریایی گرافیتی گرافیک گرافیکی گران گرانش گرایش گرایش گربه گربه‌سان وحشی گرد گرد و خاک گرداب گردباد گردش گردش دیدنی گردشگر گردشگری گردن گردن زدن گردو گرسنگی گرسنه گرفتن گرفتن گرفتن گرفتن گرفتن گرفتن گرگ گرگینه گرم گرما گرمسیری گره گره گرو گروگان گروه گروه گروه گروه کر گریپ‌فروت گریل گرین لنترن گرینچ گریه گزارش گزینه گسترش گسترش دادن گسترش دادن گسترش دادن گشاد کردن گشت‌زنی گشت‌وگذار گفتمان گفتن گفتن گفت‌وگو گفت‌وگو گل گل رز گل سوسن گل مینا گل همیشه‌بهار گل‌آلود گلابی گلادیاتور گلبرگ گلدان گلدون خونه گلف گل‌فروش گل‌کلم گله گله گله گاو گلو گلوله گلوله آتش گمانه‌زنی کردن گمراه کردن گم‌شده گناه گناه گنبد گنج گندالف گندم گواهی گواهی دادن گواهینامه گوجه‌فرنگی گودال گودال آب گورخر گورستان گورکن گوریل گوزن گوزن شمالی گوزن شمالی گوسفند گوش گوش دادن گوشت گوشت گوشت چرخ‌کرده پخته گوشت گاو گوشت‌خوار گوشه گوشه‌گیر گوشه‌گیر گوفی گوگرد گوگل گونه گونه گونه‌ها گویش گیاه گیاه دارویی گیاهان گیاه‌خوار گیتار گیتار برقی گیج گیره گیلاس گیوتین لئوناردو دا وینچی لئوناردو دی‌کاپریو لابستر لابی لابیرنت لاتاری لازانیا لازم لاستیک لاستیک لاستیک لاستیک لاس‌وگاس لاغر لاغر شدن لاف زدن لاک ناخن لاک‌پشت لاک‌پشت لاما لامپ لامپ لامپ لاوا لانه لانه سگ لانه مورچه لایه لب لباس لباس لباس لباس رسمی لباس فضایی لباس مبدل لباسشویی لبخند لبخند لبنیات لبه لب‌ها لپ‌تاپ لجباز لجبازی لجن لحاف لحظه لحظه‌ای دیدن لحن لذت لذت بردن لذت‌بخش لرزیدن لرزیدن لطف لطف لطفا لطیف لعنت لغزنده لغزیدن لغو کردن لغو کردن لک‌لک لکه لکه لگد زدن لگو لمس کردن لمور لندن لنز لنگ زدن لنگر له کردن لهجه لوئیجی لوبیا لوستر لوسیون لوگو لوله لوله لوله‌بازکن لوله‌کش لیبرال لیدی گاگا لیزر لیس زدن لیست لیمبو لیمو لیموترش لیموزین لیموناد لینک لیوان بزرگ لیوان شراب ماتریکس ماجرا ماجراجویی ماجراجویی ماداگاسکار مادر مادربزرگ مادربورد ماده ماده ماده مار ماراتن ماراکاس مارپیچ مارشملو مارک زاکربرگ مارگارین مارماهی مارمولک ماریو ماژول ماساژ ماست ماسک ماسک گاز ماشه ماشین ماشین ماشین آتش‌نشانی ماشین برقی ماشین زمان ماشین گلف ماشین مسابقه ماشین‌آلات مافیا مافین ماکارونی ماگما مالک مالک زمین مالکیت مالکیت مالی مالی مالیات مالیات‌دهنده مالیدن مام ماموت ماندن مانع مانع مانع پرش مانع جاده مانکن مانیکور ماه ماه ماه کامل ماهر ماهواره ماهی ماهی بادکنکی ماهی دلقک ماهی قرمز ماهی قلاب‌دار ماهی گربه‌ای ماهیانه ماهیگیر مایع مایکروسافت مایکروویو مایکل جکسون مایل ماینکرفت مایو مایونز مبادله مبارزه مبل مبلمان مبنا مبهم مبهم مبهم متأهل متحد متخصص متداول مترسک مترو متصدی بار متعادل متعجب متعهد شدن متغیر متفاوت متفق‌القول متفکر متقاضی متقاعد کردن متکبر متمایز متن متن آهنگ متناسب متنفر بودن متنفر بودن متنوع متهم متواضع متوجه شدن متورم شدن متوسط متوسط متوسطه مثال مثبت مثلث مجذوب کردن مجذوب کردن مجرم مجسمه مجسمه آزادی مجسمه‌سازی مجلس قانون‌گذاری مجله مجمع مجموعه مجوز مچ پا مچ دست محاسبات محاسبه محاصره محاصره کردن محافظه‌کار محاکمه محبوب محتاط محتاط محتاط محترم محتوا محدود محدود محدود کردن محدوده محدودیت محدودیت محدودیت محدودیت محراب محروم کردن محرومیت محصول محصول محفظه محقق محکم محکوم محکوم کردن محکومیت محل محل سکونت محل کار محله محله محله چینی‌ها محو شدن محور محوطه محیط زندگی محیط زیست مخالف مخالفت مخالفت کردن مخروط مخروط کاج مخزن مخلوط مخلوط کردن مخلوط‌کن مخمل مد مد روز مداخله مداد مدادشمعی مدار مدال مدت مدرسه مدرک مدرک مدرن مدفوع مدفوع مدل مدنی مدوسا مدیر مدیر مدیریت مدیریت مدیریت کردن مذاکره مذهبی مراسم مراسم تدفین مراقبت مرام مربا مربع مربی مربی مربی تناسب اندام مرتبط مرتبط مرتبط کردن مرجان مرجع مردانه مردسالار مردم مردم مردن مرده مرز مرسدس مرغ مرغ مرغ دریایی مرغ مگس‌خوار مرکب مرکز مرکز خرید مرکزی مرگ مرمالاد مرمر مرموت مریخ مریض مزاحم شدن مزایده مزرعه مزرعه ذرت مزمن مزه مزیت مژه مس مسئله مسئول مسئولیت مسئولیت قانونی مسابقه مسابقه مسافر مسافر مسافرخونه مست مستاجر مستطیل مستعمره مستقل مستقیم مستمری مسجد مسخره کردن مسکن مسکونی مسواک مسیر مسیر مسیر مسیر شغلی مشارکت مشاهده مشاور مشاوره مشت مشت مشتاق مشتاق مشترک مشتری مشخص‌شده مشعل مشکل مشکل مصاحبه مصالحه مصر مصرف مصرف‌کننده مصنوعی مضر مضطرب مطالعه کردن مطلق مطلوب مطلوب مظنون معادله معاصر معافیت معامله معامله خوب معاهده معاون معبد معتاد معتبر معجزه معجون معدن معدنچی معدنی معده معذب معرفی معرفی کردن معطل شدن معکوس معلم معلول بودن معما معمار معماری معمول معمولی معمولی معمولی معنادار معنی معیوب مغازه مغرور مغرور مغز مغناطیسی مفهوم مفید مفید مقابل مقاله مقاله مقاوم مقاومت کردن مقایسه مقایسه مقبره مقدار مقدس مقدس مقدم بودن مقر اصلی مقررات مقوا مقیاس مکاتبات مکاتبه داشتن مکان مکان مکانی مکانیزم مکانیک مکانیکی مکث مک‌دونالد مکرر مکزیک مکعب مکمل مگافون مگس‌کش ملاحظه ملایم ملایم ملحفه ملخ ملک ملک ملکه ملوان ملی ملیت ممتاز ممتاز ممکن ممنوع کردن ممنوع کردن ممنون مناسب مناسب مناسبت مناظره منبع منبع منتشر کردن منتظر ماندن منتقد منجنیق منحصربه‌فرد منحنی منشور منشور منشی پذیرش منصفانه منصوب کردن منطق منطقه منطقه منطقه منطقه منطقه‌ای منطقی منطقی منطقی منظره منظره منظم منظومه شمسی منعکس کردن منفجر شدن منفجر کردن منفعل منفی منقار منقرض منگنه منو مه مه مهاجر مهاجرت مهاجرت مهار مهار کردن مهارت مهارت مهدکودک مهدکودک مهربان مهربون مهم مهمان مهمان کردن مهماندار مهماندار مهمان‌نوازی مهمانی مهندس مو مو قهوه‌ای مواد اولیه مواد مخدر موازی موافق بودن موبایل موبایل موتزارت موتور موتورسیکلت موتورسیکلت موثر موج مودب مورتی مورچه مورچه‌خوار مورد مورد انتظار مورد علاقه مورگان فریمن موز موزاییک موزه موزیکال موسیقی موسیقی‌دان موش موش موش کور موشک موشک موضوع موعد موعظه کردن موفق موفقیت موقت موقعیت مولد مولکول مولکولی موم مومیایی مونالیزا مون‌بلان مونوپولی موهاک موی آفرو موی بینی موی سینه میانگین میخ میخ میخونه میدان میدان میدان نبرد میرکت میز میز میزبان میکروب میکروسکوپ میکروفون میکی ماوس میگو میل میلک‌شیک میله پرچم میم میم میمون مینوتور مینی‌کلیپ مینی‌گلف مینیون مینی‌ون میهن‌پرست میوه ناآرام ناآرامی ناامید کردن ناامیدی ناامیدی نابغه ناپدید شدن ناپدید شدن ناتوان ناتوانی ناچو ناخن ناخن پا ناخوشایند نادان نادانی نادر نادرست نادیده گرفتن ناراحت ناراحت نارس نارگیل نارنجک نارنگی ناروال ناز نازک ناسا ناسکار ناسیونالیست ناسیونالیسم ناشر ناشناس ناشناس ناشنوا ناظر ناظر ناظر ناعادلانه ناف ناکافی ناکافی ناکامی ناگت ناگهانی ناله نامرئی نامزد نامزد کردن نامزدی نامزدی نامناسب نامه نان نان تست نانوایی ناهار ناهماهنگ ناو جنگی ناودان ناوگان نایکی نبرد نپتون نتیجه نتیجه‌گیری نجات دادن نجار نجیب نخ نخبه نخل نخودفرنگی نرخ نردبان نرم نرم‌افزار نروژ نزول نژادپرستی نژادی نسبت نسبت نسبی نسبی نسخه نسخه نسل نسیم نشان دادن نشانک نشانه نشتی نشستن نصب کردن نصف نصیحت نظامی نظر نظر نظرسنجی نظرسنجی نظریه نظریه‌پرداز نعناع نفتالین نفس نفس کشیدن نفس‌نفس زدن نفوذ کردن نقاش نقاشی نقاشی صورت نقره نقش نقش نقشه نقشه نقص نقض نقطه نقطه‌ها نقل قول نقل کردن نگاه کردن نگاه کوتاه نگرانی نگرانی نگرش نگه داشتن نگه داشتن نگهبان نگهبان در نگهداری نما نما نماد نماد نمایش نمایش استعداد نمایش دادن نمایشگاه نمایشگاه نمایندگی کردن نماینده نماینده نماینده نمره نمره نمک نمو نمودار نمودار نمودار نمونه نمونه ننو نهاد نهایی نهایی نهنگ نهنگ قاتل نوآوری نوار نوار چسب نوار سر نوازش کردن نوت‌پد نوتلا نوجوان نودل نور نور خورشید نور روز نورافکن نوزاد نوسان نوشابه نوشابه نوشتن نوشته‌شده نوشیدن نوع نوک انگشت نویسنده نی نیاز نیاز داشتن نیاز داشتن نی‌انبان نیروی دریایی نیزار نیزه نیزه ماهیگیری نیزه‌ماهی نیش زدن نیکل نیلوفر آبی نیم‌دایره نیمکت نیم‌کره نیمه‌شب نینتندو سوییچ نینجا نیوزیلند هابیت هات‌چاکلت هات‌داگ هات‌داگ ذرتی هاکی هالک هاله هالیوود هاوایی هاورکرافت های‌فایو هایلایت کردن هپی‌میل هتل هجا هدر دادن هدف هدف هدف هدف هدفون هدیه هرج‌ومرج هرس کردن هرکول هرم هروئین هری پاتر هزارپا هزینه هزینه هسته هسته‌ای هشت‌پا هشت‌ضلعی هشتگ هشدار هشدار هشدار دادن هفتگی هفته هکر هل دادن هلند هلو هلو کیتی هلیکوپتر هم زدن هماهنگی همبرگر همبستگی همبستگی همدرد همراهی کردن همزمان شدن هم‌زن همسایه همسایه همستر همسر همکار همکاری همکاری کردن هنجار هند هنر هنرمند هنری هنوز هوا هوا هواپیما هواپیما هواپیما هوانوردی هوپ‌اسکاچ هوس یهویی هوش هولا‌هوپ هومر سیمپسون هویت هویج هیئت منصفه هیاهو هیپنوتیزم کردن هیپ‌هاپ هیپی هیجان هیجان‌انگیز هیجان‌زده هیچی هیروگلیف هیولا هیولاوار و لاگر وابستگی وابسته وابسته بودن واتس‌اپ واتیکان واجد شرایط واجد شرایط واجد شرایط شدن واحد وارث وارد شدن وارد کردن وارد کردن واریانت واضح وافل واقع‌گرایانه واقعی واقعیت واقعیت واقعیت مجازی واکسن واکنش واگن واگن قطار وال-ای والد والدین والدینی والیبال وام وام مسکن وان واندر وومن وانیل وایتکس وای‌فای وبسایت وثیقه وجدان وحدت وحشت وحشی وخیم شدن ودکا ورز دادن ورزش ورزش ورزش کردن ورزشکار ورزشگاه ورزش‌ها ورشکستگی ورق ورودی وزارتخانه وزغ وزن وزن کردن وزیر وسط وسواسی وسوسه وسوسه کردن وسیله وسیله وسیله نقلیه وصل کردن وضعیت وظیفه وعده غذا وفادار وفادار وفاداری وقار وقت خواب وقف کردن وقف کردن وکتور وکیل ول کردن ولت بوی ولورین ولوسیراپتور ون وودو ووووزلا ویتامین ویدیو ویران کردن ویران کردن ویرانی ویرایش ویروس ویژگی ویژگی ویژگی ویسکی ویلا ویلیام شکسپیر ویلیام والاس وین دیزل وینی پو ویولا ویولن ویولنسل یاد گرفتن یادآوری کردن یادآوری کردن یادبود یادداشت یادداشت رسمی یارو یاقوت کبود یتیم یخ یخ زدن یخچال یخچال طبیعی یخ‌زده یدکی یقه یکپارچگی یکپارچه یکپارچه کردن یو‌اس‌بی یواشکی گوش دادن یوتیوب یوتیوبر یودا یورش یوزپلنگ یوسین بولت یوشی یوفو یوکولله یونان یونجه یونیفرم یونیکورن یو‌یو یین و یانگ ================================================ FILE: internal/game/words/fr ================================================ capacité avortement abus académie accident comptable acide acte ajouter accro ajout adresse administrateur adulte publicité liaison effrayé après-midi âge agence agent accord aérer aéronef compagnie aérienne aéroport allée alarme album alcool allocation allié autel ambre ambulance amputer analyse ange colère angle fâché animal cheville annonce annuel anonyme fourmi anticipation anxiété apparaître appétit applaudir pomme application nomination approuver aquarium arche archiver arène bras fauteuil armée arrestation flèche art article artificiel artiste artistique cendre endormi aspect assaut atout affectation asile athlète atome attaque grenier attirer enchères auditoire automatique moyenne aviation éveillé prix axe bébé dos arrière-plan lardon sac caution cuire équilibre balcon chauve balle ballet ballon banane bande détonation banque bannière bar écorce baril barrière base baseball bassin panier basket-ball batte bain batterie bataille champ de bataille baie plage faisceau haricot ours barbe battre lit chambre abeille bœuf bière supplier décapiter cloche ventre ceinture banc virage pari bible vélo poubelle biographie biologie oiseau anniversaire biscuit évêque chienne morsure amer noir lame vierge explosion saigner bénir aveugle bloc blonde sang carnage sanglante souffler bleu planche bateau corps bouillir boulon bombe bombardier lien os livre boom botte frontière déranger bouteille bas rebondir arc entrailles bol boîte garçon cerveau frein succursale marque courageux pain pause poitrine respirer race brise brasserie brique mariée pont apporter diffuser brocoli cassé bronze frère brun brosse bulle seau buffet bâtiment bulbe inhumation brûler enterrer bus brousse entreprise beurre papillon bouton acheter cabine cabinet câble café cage gâteau calcul calendrier veau appeler caméra camp annuler cancer candidat bougie canne toile bouchon capital capitaine capture voiture carte carrière tapis carrosse carotte porter chariot tailler cas espèces cassette château chat attraper cathédrale cause grotte plafond célébration cellule cave cimetière censure centre céréale cérémonie certificat chaîne chaise craie champagne champion changement chaos chapitre caractère charge charité charme graphe radin vérifier joue fromage chimique chimie cerise mâcher poulet chef enfant enfance cheminée menton croustille chocolat étouffer hacher chronique église cigarette cinéma cercle circulation citoyen ville civil réclamation classe classique salle de classe argile nettoyer grimper clinique horloge fermer fermé vêtements nuage club indice autocar charbon côte manteau code cercueil pièce froid effondrement collègue recueillir collection collège colonie couleur coloré colonne coma combinaison combiner comédie comète commande commentaire communication communauté compagnie comparer rivaliser se plaindre complète ordinateur concentrer concert béton conducteur conférence confiant conflit confusion connexion conscience consensus envisager conspiration constellation contrainte construire contact concours contrat contradiction convention conversation convertir bagnard cuivre copie corde noyau cor coin correction costume cottage coton toux compter compteur pays couple cours couvrir vache crack métier artisan crash crème création carte de crédit crédit ramper équipage cricket crime criminel croix croisement accroupis foule couronne pleurer cristal concombre tasse placard boucle monnaie actuel cursus rideau courbe coussin client couper mignon découpage cycle cylindre laitière dommage danse danger sombre date fille jour morts mortel sourd traiter dealer mort dette diminuer profond cerf défaite défendre degré livrer livraison démolir démonstration dentiste quitter départ dépôt dépression descente désert conception bureau destruction détective détecteur diagnostic diagramme diamètre diamant dicter dictionnaire mourir différer différence creuser numérique dîner tremper direction directeur répertoire sale invalidité disparaître discothèque rabais découverte discret discuter maladie plat antipathie afficher dissoudre distance lointain plongée diviser division divorce médecin document chien poupée dollar dauphin dôme domination donner porte dose double pâte traîner dragon drain dessiner tiroir dessin rêve robe perceuse boire lecteur goutte noyer drogue tambour sec canard due terne larguer durée aigle oreille précoce séisme orient manger écho bord éducation oeuf coude élection électricité électron électronique élément éléphant éliminer urgence émotion empire vide fin ennemi énergie moteur ingénieur agrandir entrer enthousiasme entrée enveloppe environnement épisode égal équation équipement erreur échapper europe même soir évolution dépasser excité exécution sortie expansion coûteux expérimenter exploser exploration exporter expression extension éteint extraterrestre œil sourcil façade visage installation usine échouer échec faible équitable fée chute gloire famille ventilateur fantasme loin ferme agriculteur rapide graisse père télécopieur crainte festin plume honoraires clôture ferry festival fièvre fibre fiction champ lutte fichier remplir pellicule filtre financer financier trouver doigt finir licencier pompier premier poissons pêcheur poing apte aptitude fixer drapeau éclair flotte chair vol passade inondation plancher farine fleur grippe fluide voler plier nourriture imbécile pied football interdire front étranger forêt fourche formel formule fortune avancer fossile fondation fontaine renard fragment franchise fraude tache de rousseur libre geler fret fréquence fraîche frigo ami amitié grenouille devant congelé fruit carburant amusant funérailles drôle fourrure mobilier galaxie galerie gallon jeu écart garage ordures jardin ail gaz génie gentilhomme géographie géologique geste fantôme géant cadeau glacier verre lunettes glisser morosité gant lueur colle aller objectif gardien chèvre dieu or golf bonne gouvernement progressive diplômé grain grand-père grand-mère graphique graphisme herbe grave graviers gravité vert saluer salutation grimace sourire poignée sol croître croissance garde invité culpabilité guitare pistolet caniveau habitat cheveux coupe moitié salle couloir marteau main handicap accrocher heureux port dur matériel harmonie récolte chapeau détester hanter foin tête manchette quartier général santé sain entendre cœur chaleur ciel lourd haie hauteur hélicoptère enfer casque hémisphère poule troupeau héros héroïne cacher élevé souligner randonnée colline hanche historique frapper tenir trou vacances foyer miel crochet horizon horizontal corne horreur cheval hôpital otage chaud hôtel heure abriter femme au foyer planer énorme homme humanité chasseur chasse blesser mari hutte hypnotiser crème glacée glace idée identification identifier identité illégal image imagination imaginer immigrant immigration importer impulsion incident revenu individuel intérieur industrielle industrie infecter infection infini gonfler informations ingrédient habitant injecter injection blessure innocent insecte insérer inspecteur instruction instrument intégration intelligence international entrevue invasion enquêteur invitation inviter fer île isolement point veste prison confiture bocal mâchoire jazz gelée secousse jet joyau emploi jockey articulation blague joie juge jugement jus sauter jungle junior jury justice bouilloire clé botter gamin rein tuer tueur genre roi royaume baiser cuisine cerf-volant genou agenouiller couteau nœud étiquette laboratoire dentelle échelle dame lac agneau lampe terre propriétaire paysage langue genoux grand laser dernier rire lancement blanchisserie gazon avocat pondre disposition leadership feuille dépliant fuite maigre apprendre cuir congé gauche restes jambe légende citron longueur leçon lettre niveau bibliothèque licence lécher couvercle mensonge ascenseur lumière lys membre limite ligne lion lèvre liquide liste écouter littérature vivre foie lobby localiser emplacement verrouiller loge bûche seul long regarder lâche perdre lot bruyant salon amour abaisser chanceux bosse déjeuner poumon machine magazine magnétique servante courrier commercial entretien majeur maquillage mec gestion manuel fabriquer marathon marbre marche marin marketing mariage marié mars marais masque masse maître match matériau mathématique mathématiques maximum maire dédale repas mesurer viande mécanique médaille médecine médiéval moyen rencontrer réunion adhésion mémorial mémoire menu marchand message métal microphone milieu minuit mille lait esprit mineur minéral minimiser minimum minute miroir fausse couche manquer missile mobile modèle taupe moléculaire argent moine singe monopole monstre monstrueux mois lune matin mosquée moustique mère autoroute montagne souris bouche déplacer émouvant boue mug multimédia multiple multiplier meurtre muscle musée champignon musique musicien mutuel mythe ongle nom sieste étroit nature marine cou aiguille voisin quartier neveu nid net réseau nouvelles nuit cauchemar hochement bruit nord nez note cahier roman nucléaire nombre nonne infirmière pépinière écrou chêne obèse obéir observation observateur obstacle obtenir océan impair offrir officier progéniture huile vieux omission oignon ouvrir opéra opération adversaire opposé option oral orange orbite orchestre organe original tenue exutoire esquisse vue extérieur four hibou propriété oxygène paquet page douleur peinture peintre paire palais paume poêle papier parade paragraphe parallèle parent parc parking particule partenaire partenariat partie passage passager passeport mot de passe passé tapoter brevet chemin chaussée payer paiement paisible arachide piétonne stylo crayon penny gens poivre pourcent perforé interprète période personne animal de compagnie philosophe photocopie photo photographe photographie physique piano tarte jetée cochon pigeon pile pilule oreiller pilote épingle pionnier tuyau fosse plan avion planète plante plastique plate-forme jouer agréable gage brancher poche poème poésie perche politique sondage pollution poney piscine pauvre portrait positif poste carte postale pot pomme de terre poterie verser poudre puissance prier prière précis prédécesseur prévisible enceinte présent présentation présidence président presse pression proie prince princesse impression imprimante prisonnier privilège produire producteur produit production productives professeur profil programme projection preuve propagande proportion proportionnelle protéger protection protéines protestation psychologue pub publier pudding tirer pompe citrouille coup de poing élève pousser puzzle pyramide qualifié qualité quart reine question questionnaire file d'attente arrêter citation lapin course racisme rack rayonnement radio fureur raid wagon chemin de fer pluie arc-en-ciel rassemblement aléatoire rang rat taux ratio cru atteindre réaction réacteur lire arrière rebelle reçu réception enregistrement récupération recycler rouge réduction redondance réfléchir réflexion région réadaptation répétition règne liés relation relâche religieux réticence remarque loyer répéter remplacer remplacement rapport reporter reproduction reptile recherche chercheur résident station ressource restaurant restriction résultat vengeance inverse renouveau revivre ruban riz riche cavalier fusil droite sonnerie émeute élévation rituel rivière route rugissement cambriolage robot rocher fusée rôle rouler romantique toit rose royauté bêtises rugby courir coureur sacré sacrifice voile salade vente saumon sel salut sable sandale satellite satisfaisant sauce saucisse sauvegarder scanner disperser scène école science scientifique score gratter écran script sculpture mer sceller saison saisonnière siège seconde secondaire secrétaire sécurisé voir semence vendre vendeur séminaire senior séparation séquence série serviteur servir service règlement ombre forme partager requin pointu brousiller moutons étagère coquille bouclier déplacement briller chemise choc chaussure boutique shopping court pénurie short tir épaule montrer douche rétrécir hausser les épaules timide malade signe signature silence soie similaire similitude péché chanteur évier sœur site taille patins croquis ski crâne dalle slam gifle esclave dormir manche tranche glissante fente doucement intelligent frappe odeur fumer escargot serpent renifler neige savon foot chaussette doux logiciel solaire soldat solide solo solution résoudre âme son soupe sud espace orateur spécimen discours vitesse épeler sphère araignée répandre tourner épinards colonne vertébrale split cuillère sport spot pulvérisation propagation printemps espionne escouade carré presser poignarder personnel tache escalier décrochage timbre étoile statue steak vapeur tige pas collante piqûre stock estomac pierre tabouret stockage magasin tempête droit paille fraise rue force étirer grève avc fort étudiant studio style subjective substance banlieue réussi sucre suicide suite somme résumé été soleil lever du soleil supérieur supermarché superviseur soutien supprimer surface chirurgien chirurgie surprise entourer enquête suspect sueur pull balayage goule nager balançoire balayer interrupteur épée symétrie système t-shirt table tablette queue réservoir toucher cible savoureux taxi thé équipe déchirure technique technologie adolescent téléphone télévision température temple locataire tendre tennis tente terminal terrasse terroriste test texte théâtre thérapeute thérapie épais mince pensée menace menacer gorge trône lancer pouce billet marée cravate tigre serré tuile temps étain pourboire fatigué tissu titre toast orteil tomate tonne outil dent haut torche torture jetons total tourisme tournoi serviette tour toxique jouet trace piste commerce trafic train formateur formation transfert transparent transport piège trésor traitement arbre tendance procès triangle tribu hommage voyage troupe tropicale pantalon camion coffre tube tumeur tunnel dinde jumeau tordre magnat pneu parapluie mal à l'aise uniforme unique unité université mise à jour contrarié urbain urine utilisateur vallée précieux camionnette variante légume végétation véhicule vénus verbale version verticale vaisseau vétéran victime victoire vidéo villa village violent vision vitamine voix volcan volume bon d'achat marcher mur guerre garde-robe avertissement guerrier laver gaspillage eau cascade vague faiblesse richesse arme météo tissage semaine week-end hebdomadaire poids ouest mouillé baleine blé roue fouet whisky murmure blanc entières veuve largeur femme sauvage faune gagner vent fenêtre vin aile gagnant hiver essuyer fil sorcière témoin loup bois laine mot monde ver emballage épave lutter poignet écrire écrivain écrit radiographie yacht bâiller année jeune jeunesse ================================================ FILE: internal/game/words/he ================================================ לנטוש מנזר יכולת מסוגל לא שגרתי לבטל הפלה אברהם לינקולן לקצר היעדרות נעדר מוחלט לספוג ספיגה מופשט שופע לנצל תהום זרם ישר וזרם חילופין אקדמי אקדמיה מבטא לקבל קביל קבלה גישה נגיש תאונה ללוות אקורדיון חשבון רואה חשבון צבירה מדויק אס הישג חומצה אקנה בלוט היכרות רכישה לפעול פעולה להפעיל פעיל פעילות שחקן חריף להוסיף מכור התמכרות הוספה כתובת הולם אדידס להתאים מנהל אדמיניסטרטור הערצה להעריץ קבלה להודות לאמץ אימוץ חמוד מבוגר להתקדם יתרון הרפתקה פרסומת פרסום עצה יועץ פרקליט אסתטיקה רומן להשפיע זיקה להרשות לעצמו מפוחד אפריקה אפרו חיים לאחר המוות אחר הצהריים גיל סוכנות סדר יום סוכן תוקפני זריז ייסורים להסכים הסכם חקלאי חקלאות סיוע איידס אוויר מזגן כרית אוויר מטוס חברת תעופה מטוס שדה תעופה מעבר אלאדין אזעקה אלבטרוס אלבום אלכוהול התראה חייזר חי אלרגיה סמטה אליגטור הקצאה להרשות קצבה בן ברית שקד מרוחק אלפקה מזבח אלומיניום חובבן ענבר דו-משמעות דו-משמעי שאיפה שאפתני אמבולנס תיקון אמריקה שופע לקטוע אמסטרדם לשעשע אנקונדה אנלוגיה ניתוח אנליסט עוגן אנדרואיד מלאך אנג׳לינה ג׳ולי כעס זווית דג חכאי כועס אנגרי בירדס בעל חיים אנימציה אנימה עקב יום נישואין הודעה שנתי אנונימי תשובה נמלה אנטרקטיקה אוכל נמלים אנטילופה אנטנה קן נמלים ציפייה אנטיוירוס אנוביס סדן חרדה דירה אדישות אפוקליפסה להתנצל התנצלות מנגנון לערער להופיע הופעה תוספתן תיאבון להריע מחיאות כפיים תפוח פאי תפוחים זרעי תפוח מועמד אפליקציה מיושם למנות פגישה להעריך גישה מתאים אישור לאשר משמש אקווריום שרירותי קשת ארכיאולוגי ארכאלוג קשת אדריכל ארכיטקטורה ארכיון שטח ארינה ארגנטינה מריבה אריסטוקרטי זרוע ארמדילו כורסה שיריון בית שחי צבא לסדר סידור לעצור יהיר חץ אומנות מאמר רהוט מלאכותי אומן אומנותי לוודא אפר מבוייש אסיה לשאול ישן היבט מתנקש תקיפה אסיפה טענה אסרטיבי הערכה נכס משימה איגוד לשער השערה ביטחון כוכבית אסטרואיד מדהים אסטרונאוט מקלט מדיני אסימטרי אתלט אטלנטיס אטמוספירה אטום לצרף קובץ מצורף לתקוף תשומת לב עליית גג יחס למשוך משיכה אטרקטיבי מכירה פומבית אאודי קהל מבקר דודה אוסטרליה לאשר סמכות חתימה אוטומטי אוטונומיה זמין שדרה ממוצע תעופה אבוקדו להימנע ער פרס מודע נוראי מוזר גרזן ציר בבון תינוק גב כאב גב עמוד שדרה סלטה לאחור רקע תיק גב בייקון רע גירית שקית בייגל חמת חלילים באגט ערבות פיתיון לאפות מאפייה בקלאווה איזון מאוזן מרפסת קירח כדור בלרינה בלט בלון פתק הצבעה במבי במבוק לאסור בננה להקה תחבושת תחבושת בנדנה לחבוט בנגו בנק בנקאי פשיטת רגל באנר בר ברק אובמה ברברי ברביקיו גדר תייל ספר ברקוד חשוף מיקוח לנבוח אסם חבית מחסום בארט סימפסון ברמן בסיס בייסבול מרתף בסיסי אגן בסיס סל כדורסל עטלף אמבט חדר אמבטיה גקוזי באטמן סוללה קרב שדה קרב ספינת קרב מפרץ כידון בזוקה חוף מקור קרן שעועית פוף כובע גרב שעועית דוב מלכודת דובים זקן קצב ביטבוקס יפייפה בונה להפוך ל מיטה פשפש מיטה סדין חדר שינה זמן שינה דבורה בקר בירה סלק בטהובן חיפושית לבקש להתחיל התחלה להתנהג התנהגות עריפת ראש אמונה פעמון גמבה שאגה בטן פופיק שייך מתחת חגורה ספסל עיקול מוטב תועלת פירות יער להתערב לבגוד תנך אופניים ביג בן אופניים חשבון ביל גייטס ביליארד פח לקשור בינגו משקפת ביוגרפיה ביולוגיה עץ שדר ציפור מקלחת ציפורים יום הולדת ביסקוויט בישופ כלבה ביטקוין לנשוך מר שחור בלאק פריידי חור שחור אוכמנית סחיטה נפח להב להאשים תפל ריק שמיכה פיצוץ אקונומיקה לדמם בלנדר לברך ספינת אוויר עיוור כיסוי עיניים סופה לחסום בלונד דם שפיכות דמים מדמם מכה דג אבו נפחא כחול גינס אוכמנית להסמיק במוו אופניים חזיר בר לוח סירה מזחלת שלג גוף שומר ראש להרתיח מודגש בריח פצצה מפציץ מחבל קשר עצם נזלת ספר סימניה מדף בום בומרנג מגף מגפיים גבול להלוות אח בקבוק הקפצת בקבוק תחתית להקפיץ מאבטח קשת קיבה קערה באולינג קופסה ילד צמיד גשר לשיניים סוגריים להתרברב מוח שטיפת מוח בלמים ענף מותג אמיץ ברזיל לחם לשבור התמוטטת ארוחת בוקר חזה נשימה לנשום גזע בריזה מבשלה לבנה לבנים כלה גשר להביא שידור ברוקולי שבור לב שבור ברונזה מטאטא מקל מטאטא אח חום בראוני חבורה ברונט מברשת בועה מסטיק דלי תקציב מזנון באגס באני בניין נורה בליטה שור בולדוזר קליע לוח מודעות מכה פגוש צרור קפיצת באנג׳י מיטת קומותיים ארנבון בירוקרטיה ביורוקרטי פורץ לקבור לשרוף לגהק בוריטו להתפוצץ לקבור אוטובוס נהג אוטובוס תחנת אוטובוס שיח עסק איש עסקים עסוק קצב משרת לחי של טוסיק חמאה פרפר כפתור לקנות נהג מונית תא ארון כבל קקטוס בית קפה כלוב עוגה חישוב לוח שנה עגל להתקשר רגוע קלוריה גמל מצלמה מחנה קמפיין מדורה קמפינג פחית פותחן קנדה כנרית לבטל סרטן מועמד נר מקל הליכה קופסה תותח בד קניון כובע מסוגל גלימה בירה קפיטליזם קפוצ׳ינו מזל גדי קפטן קפטן אמריקה שובה לב ללכוד מכונית שטיפת מכוניות פחמן כרטיס ארון לדאוג קריירה זהיר קרנבל קרניבור נגר שטיח כרכרה מנשא גזר לשאת עגלה סרט מצוייר לגלף כיסוי מזומן קזינו קלטת לצקת טירה קורבן חתול אשת חתול קטלוג קטלוג קטפולטה לתפוס קטגוריה לספק זחל שפמנון קתדרלה בקר קלחת כרובית גורם זהיר מערה איש מערה קוויאר תקרה מאוורר תקרה לחגוג חגיגה סלבריטי תא טלפון סלולרי מרתף צלו מלט בית קברות צנזורה מפקד אוכלוסין סנטאור מרכז מרבה רגליים מרכזי מאה קרברוס דגני בוקר טקס מסויים תעודה שרשרת מסור שרשרת כסא גיר אתגר זיקית שמפניה אלוף הזדמנות נברשת לשנות ערוץ בלאגן בחור פרק דמות אופייני להטעין מטען כריזמטי צדקה צ׳ארלי צ׳פלין חן טבלה צארטר מרדף שוביניסט זול לבדוק לחי לחיים עליז מעודדת גבינה ציזבורגר עוגת גבינה ציטה שף כימיקל כימיה צק דובדבן פריחת דובדבן שחמט חזה שיער חזה ערמון חזה ללעוס צובקה תרנגולת ציף ציוואוואה ילד ילדות ילדותי צלצול ארובה שימפנזה סנטר סין ציינה טאון צינצילה שבב שוקולד בחירה לחנוק לבחור לחתוך צופסטיקס מיתר פזמון קריסמס כרום כרוני צאק נוריס כנסייה ציקדה סיגריה קולנוע עיגול מחזור נסיבות קרקס תושב עיר אזרחי אזרחות ציוויליזציה טענה מחיאות כפיים להבהיר קלרינט התנגשות מחלקה קלאסי סיווג כיתה טופר חימר נקי ניקוי פינוי פקיד קליקבייט צוק אקלים טיפוס מרפאה גלימה שעון לסגור סגור בגד בגים מתלה בגדים ענן תלתן ליצן דג ליצן מועדון רמז אשכול מאמן פחם קואליציה חוף משמר החופים תחתית לכוס מעיל קוברה תיקן קוקטייל קוקוס גולם קוד קפה בית קפה ארון קבורה מטבע לחפוף צירוף מקרים קולה קר התמוטטות קולר קולגה לאסוף אוסף מכללה נקודותיים קולוניה עיוור צבעים קולוסיאום צבע צבעוני עמודה תרדמת מסרק שילוב לשלב קומיקאי קומדיה כוכב שביט נוחות נוח קומיקס פקודה מפקד הערה מסחר מסחרי ועדה מחויבות ועדה תקשורת משותף קומיוניזם קומוניסט קהילה קומפקטי חברה דומה להשוות השוואה תא מצפן תואם לפצות פיצוי להתחרות יכולת מוכשר תחרות תחרותי להתלונן שלם מורכב תאימות סיבוך מלחין מורכב מקיף להתפשר מחשב מחשוב להודות להגות להתרכז ריכוז רעיון תפיסה דאגה קונצרט ויתור מסקנה בטון תבלין מצב מנצח קונוס וועידה ווידוי ביטחון בטוח בעצמו להגביל סכסוך להתעמת עימות מבולבל בלבול תאגיד לברך קונגרס חיבור מצפון מודע תודעה קונצנזוס שימור שמרני לשקול משמעותי התחשבות עקבי קונסולה לאחד קונספירציה קבוע קונסטלציה מחוז בחירה חוקה חוקתי אילוץ לבנות בונה התייעצות צרכן צריכה קשר מכיל עכשווי זלזול תוכן תחרות הקשר יבשה יבשתי המשכיות המשכי חוזה התכווצות סתירה מנוגד להשוות תרומה שליטה שלט שנוי במחלוקת נוחות נוח כנס מוסכם שיחה להמיר להרשיע הרשעה לשכנע טבח עוגייה צנצנת עוגיות מפלצת עוגיות קריר לשתף פעולה שיתוף פעולה שיתופי להתמודד נחושת להעתיק זכויות יוצרים אלמוג ריף אלמוגים חוט ליבה פקק שעם פותחן תירס קורן דוג פינה שדה תירס תאגיד גופה תיקון קורלציה להתכתב התכתבות שחיתות תחפושת קוטג כותנה שיערות סבתא שיעול מועצה לספור דלפק מדינה כפר הפיכה זוג אומץ קורס בית משפט אדיבות בן דוד לכסות כיסוי פרה פעמון פרה קאובוי קויוטי סרטן סדק מלאכה אומן התרסקות קראש בנדיקוט ארגז חלל זחילה צבע פנדה קרם ליצור יצירה אמינות קרדיט כרטיס אשראי אמונה לזחול זוחל צוות קריקט פשע פושע מוזר משבר מבקר קריטי ביקורת קרואטיה קרוקודיל קוראסון ייבול לחצות חץ וקשת מעבר לכרוע ברך עורב מוט ברזל קהל כתר כור היתוך גס רשע רשעות שייט קרום קב לבכות קריסטל קובה קוביה קוקיה מלפפון עיבוד אדמה תרבותי תרבות גביע ארון קאפקייק קופיד סקרן סלסול מטבע נוכחי תוכנית לימודים קארי וילון עקומה כרית משמורת לקוח לחתוך חמוד גזירה סייבורג עיגול גליל מצילתיים דאפי דאק פגיון יומי מוצרי חלב חרצית דלמטי נזק לעזאזל לרקוד שן הארי קשקשים סכנה מסוכן להעז חושך חיצים דארווין דארווין ווטרסן לוח מחוונים דייט בת יום אור יום מת תאריך יעד מסוכן דדפול חרש עסקה סוחר מוות דיון חוב בכורה עשור רקבון להחליט מכריע סיפון הצהרה לסרב קישוט דקורטיבי להוריד להקדיש עמוק צבי ברירת מחדל להביס להגן נאשם הגנה מחסור חוסר להגדיר מוגדר הגדרה מעלה עיכוב נציג למחוק עדין לשלוח משלוח דרישה דמוקרטיה דמוקרטי להרוס שד להפגין הפגנה מפגין הכחשה להוקיע צפיפות שקע רופא שיניים להכחיש דאודורנט לעזוב עזיבה לסמוך תלות תלוי להפקיד מדוכא דיכאון שלילה לשלול סגן טיפש לנחות לתאר מדבר ראוי לעצב מעצב רצוי תשוקה שולחן יאוש נואש לסלוד קינוח הרס פרט בלש גלאי להרתיע להתדרדר לפוצץ לפתח פיתוח חריגה להקדיש טל דקסטר אבחנה אלכסון תרשים מבטא דיאלוג קוטר יהלום חיתול קוביית משחק להכתיב מילון למות דיאטה שונה שוני שונה קשה קושי לחפור דיגיטלי כבוד דילמה לדלל מימד לסעוד ארוחת ערב דינוזאור לטבול תעודה דיפלומט דיפלומטי ישיר כיוון במאי תיקייה מלוכלך נכות חיסרון חוסר הסכמה להיעלם לאכזב אכזבה אסון משמעת דיסקו מחלוקת הנחה להרתיע שיח לגלות תגלית דיסקרטי אפלייה לדון מחלה הסוואה מנה מטלית דיסק לא אוהב לפטר הדחה הפרעה דיספנסר תצוגה הלך רוח מחלוקת שיר העלבה להמיס מרחק רחוק ייחודי לעוות עיוות להפיץ מפיץ רובע הפרעה דיווה לצלול לחלק מחולק חלוקה להתגרש מסוחרר די אן איי מעגן רופא מסמך כלב מלונה בובה דולר בית בובות דולפין כיפה מקומי דומיננטי לשלוט שליטה דומינו דונלד דאק דונלד טראמפ לתרום חמור תורם דלת ידית דורה דוריטוס מנה נקודות כפול ספק בצק להוריד תריסר דרקולה טיוטה לגרור דרקון שפירית ביוב דרמה דרמטי לצייר מגירה ציור חלום שמלה רוטב להיסחף לקדוח משקה לטפטף לנהוג נהג לרייר להפיל טיפה בצורת לטבוע סם תוף מערכת תופים יבש ברווז סלוטייפ תאריך יעד דו קרב דוכס משעמם דמבו מזבלה פרק זמן אבק תפקיד גמד דינמי דינמיט להוט נשר אוזן אוזניות מוקדם כדור הארץ רעידת אדמה שעוות אוזניים מזרח פסחא ארנב של פסחא קל לאכול להאזין הד ליקוי כלכלי כלכלה כלכלן כלכלה קצה מהדורה חינוך חינוכי צלופח השפעה יעיל חסכוני מאמץ ביצה חציל אגו מצריים מגדל אייפל איינשטיין מרפק קשיש לבחור בחירות ציבור בוחרים מכונית חשמלית גיטרה חשמלית חשמלאי חשמל אלקטרון אלקטרוני אלקטרוניקה אלגנטי אלמנט פיל מעלית זכאי לחסל עלית אלמו אילון מסק רהוט אלזה לצאת לדרך מבוכה שגרירות גחלים עובר ברקת מקרה חירום אמינם אמוגי רגש רגשי דגש אימפריה אמפירי להעסיק עובד מעסיק תעסוקה ריק אמו לעודד מעודד סוף לסבול אוייב אנרגיה אירוסין מנוע מהנדס אנגליה לשפר מהנה להגדיל לוודא להיכנס לבדר בידור נלהבות נלהב זכות כניסה מעטפה סביבה סביבתי פרק שווה משווה קו המשווה שיווי משקל ציוד תקופה מחק שחיקה טעות לברוח אסקימו אספרסו מאמר מהות חיוני לבסס להקים אחוזה להעריך נצחי אתי אתיקה אתני אירופה התאדות זוגי ער אבולוציה מדוייק להגזים מבחן בחינה דוגמה אקסקליבר חפירה מחפר חורג חריג עודף החלפה נרגש התרגשות מרגש לא לכלול בלעדי תירוץ לבצע הוצאה להורג מנהל פטור תרגיל להציג תערוכה גלות יציאה אקזוטי להרחיב הרחבה לצפות ציפייה צפוי משלחת הוצאה יקר ניסיון מנוסה ניסוי ניסיוני מומחה מומחיות להסביר הסבר מפורש להתפוצץ לנצל גישוש פיצוץ לייצא לחשוף חשיפה מהיר ביטוי להאריך הרחבה מידה חיצוני נכחד יוצא מהכלל חוצן אקסטרים עין גבה ריס צללית בד נפלא חזית פנים איפור פייסבוק מתקן עובדה גורם מפעל לדעוך להיכשל כשלון להתעלף הוגן פייה אמונה נאמן שן זהב סתיו שלילי תהילה מוכר משפחה איש משפחה מאוורר פאנטה פנטזיה רחוק דמי נסיעה חווה חוואי להקסים אופנה מעצב אופנה אופנתי מהיר מזון מהיר להריץ קדימה בררני שמן אבא כיור אשמה טובה מועדף טובה מועדף פקס פחד סעודה נוצה תכונה פדרלי פדרציה עמלה משוב להרגיש הרגשה נשי פמיניסטי גדר סייף שרך פרארי מעבורת פסטיבל חום מעט סיב בידיוני ספינר שדה תאנה קרב דמות בובה תיקייה למלא סרט במאי פילטר סופי לממן פיננסי למצוא קנס אצבע ציפורן קצה אצבע לסיים סיים פיני הרפתקאות פין וגייק אש אזעקת אש ברז כיבוי אש כבאית כדור אש קפצון כבאי גחלילית תחנת כיבוי כבאי אח חסין אש מדורה זיקוק קשיח ראשון מקור ראשון דג קערת דגים דייג אגרוף קרב אגרופים בכושר כושר מאמן כושר לתקן מתקן קצף דגל מוט דגל להביור פלמינגו הבזק פנס בקבוק שטוח טעם פגום לברוח צי בשר גמיש טיסה דיילת לזרוק עדר שיטפון זרקור רצפה דיסקט פלורידה מוכר פרחים קמח שגשוג פרח שפעת תנודה נוזל לשטוף חליל זבוב חובט זבובים חזיר מעופף ערפל נייר כסף לקפל תיקייה עם פולקלור לעקוב אוכל טיפש טיפשי רגל כדורגל לאסור כח תחזית מצח זר יער שריפת יער יערנות חישול לשכוח מזלג טופס רשמי תבנית מבנה נוסחה לנסח מבצר טירה עושר פורום קדימה מאובן חורג יסודות מזרקה שועל חלק רסיס ריחני מסגרת צרפת מותג כן פרנקישטיין הונאה נמש נמשים פרד פלינסטון חופשי חופש להקפיא מקפיא מטען תדר תדיר טרי סטודנט שנה א מקפיא חבר ידידותי חברות ציפס מפוחד צפרדע חזית כוויית קור ציפוי מבט כועס קפוא פרי תסכול דלק מלא ירח מלא משרה מלאה כיף פונקציה פונקציונלי קרן הלוויה מצחיק פרווה ריהוט רעשני עתיד תועלת גלקסיה גלריה גלון משחק גנדלף גנדי כנופיה גנגסטר מרווח מוסך זבל גינה גנן גרפילד שום גז מסיכת גז דלק אנחה שער מבט גלגל אבן חן מגדר גן כללי ליצור דור גנרטור נדיב גנטי גיני גאון עדין גנטלמן אמיתי גאוגרפיה גאולוגי חיידק גרמניה מחווה לקבל גייזר רוח רפאים ענק מתנה גירפה ילדה לתת קרחון שמח גלדיאטור מבט לבהות זכוכית משפיים לדאות הצצה נצנוץ גלובוס חשיכה מפואר תהילה ברק כפפה זוהר סטיקלייט דבק דבק סטיק גמד ללכת מטרה שוער עז זקן תיש גובלין אלוהים סנדק זהב שרשרת זהב התפוח הזהוב ביצת זהב דג זהב גולף עגלת גולף טוב גופי גוגל אווז גורילה ממשלה מושל גלימה חן ציון הדרגתי בוגר אוניברסיטה טקס סיום גרפיטי דגן דקדוק גדול סבא סבתא מענק אשכולית ענבים גרף גרפי גרפיקה דשא צרצר אסיר תודה קבר קברן חצץ קבר כוח המשיכה גדול החומה הגדולה של סין יוון חמדנות ירוק גרין לנטרן לברך ברכה חברותי רימון רשת צער גריל גרימייס חיוך גרינץ לטחון ידית אנקה חתן קרקע שטחים לגדול גדילה גרו זועף התחייבות שומר גורילה לנחש אורח מדריך הנחיות גיליוטינה אשמה שרקן גיטרה מסטיק גומי דובי גומי תולעת גומי אקדח מרזב הרגל בית גידול האקר שיער רולר שיער מברשת שיער תספורת ספריי שיער שעיר חצי אולם מסדרון הילה לעצור חזיר המבורגר פטיש ערסל אוגר יד נכה ידית לחיצת יד שימושי לתלות קולב לקרות שמח ארוחת ילדים נמל נמל קשה קסדה קושי חומרה לפגוע פוגעני מפוחית הרמוניה נבל צלצל הארי פוטר קשה קציר סולמית כובע שנאה לגרור לרדוף יש הוואי חציר מפגע אגוז לוז ראש כאב ראש סרט ראש ראש מיטה כיוון כותרת אוזניות מפקדה לרפא בריאות בריא לשמוע לב חום גן עדן כבד גדר חיה קיפוד עקב גובה יורש שוד מסוק גיהנום הלו קיטי קסדה עזרה עוזר חסר ישע חצי כדור תרנגולת עשבי תיבול הרקולס עדר נזיר גיבור הרואין להסס משושה שנת חורף שיהוק להתחבא היררכיה הירוגליף גבוה כיף נעלי עקב שיא שיא כביש מהיר טיול מצחיק גבעה ירך היפ הופ היפי היפופוטם היסטוריון היסטורי היסטוריה להכות טרמפיסט כוורת הוביט הוקי להחזיק חור חג הוליוד קדוש בית לבד בבית הומלס הומר סימפסון כן דבש חלת דבש מכובד כבוד פרסה וו דילוג תקווה קלאס אופק אופקי קרן הורוסקופ אימה סוס שוט צינור בית חולים הכנסת אורחים מארח שבוי עוין עוינות חם שוקו נקניקיה רוטב חריף בית מלון שעה שעון חול בית צמח בית עקרת בית מגורים לרחף רחפת חיבוק ענק חישוק הענק הירוק אדם גוף האדם אנושות יונק הדבש הומור רעב רעב צייד ציד מכשול פגוע בעל בקתה צבוע להפנט השערה קרח גלידה אוטו גלידה קרחון נטיף רעיון אידאלי הזדהות לזהות לזהות אידיאולוגיה בורות בור להתעלם איקאה לא חוקי חולי אשלייה לאייר איור תמונה דימיון לדמיין מהגר הגירה חסין פגיעה אימפריאלי השלכה משתמע לייבא חשיבות חשוב בלתי אפשרי להרשים מרשים לשפר שיפור דחף לקוי בלתי הולם לא מסוגל תמריץ אינץ אירוע כולל בסתר הכנסה לא הולם להגדיל מדהים עצמאי מדד הודו סימן יליד עקיף אישי מקורה לפנק תעשייתי תעשייה בלתי נמנע לזהם זיהום אינסופי לנפח אינפלציה השפעה משפיען לא פורמלי מידע תשתית רכיב תושב לרשת עכבה התחלתי יוזמה להזריק זריקה לפצוע פציעה פונדק פנימי תמים חדשנות חקירה חרק להכניס בפנים פנימי תובנה להתעקש התעקשות נדודי שינה מפקח השראה לתת השראה להתקין להתקין אינסטינקט מוסד הוראה כלי נגינה לא מספיק ביטוח לבטח משולב אינטגרציה יושרה מידע אינטלקטואלי אינטליגנציה אינטנסיבי להגביר כוונה אינטרקציה אינטרקטיבי ריבית מעניין ממשק הפרעה בינוני פנימי בינלאומי אינטרנט לפרש להפריע צומת התערבות ראיון להכיר היכרות פלישה המצאה חקירה חוקר השקעה בלתי נראה הזמנה להזמין אייפד אייפון אירלנד ברזל ענק הברזל איירונמן אירוניה לא רלוונטי אי בידוד ישראל להנפיק איטליה חפץ שנהב קיסוס מנורת דלעת גאקט פטיש אוויר גקי צאן יגואר כלא חלפיניו ריבה גיימס בונד מנקה יפן צנצנת לסת גיי זי גאז קנאי גינס גיפ ריבה גלי מדוזה גנגה לנדנד הלצה ליצן ישו סילון אופנוע ים תכשיט גימי ניוטרון עבודה רוכב גון סנה גוני בראבו מפרק בדיחה גוקר יומן עיתונאי מסע שמחה שופט שיפוט משפטי ללהטט מיץ לקפוץ חבל קפיצה צומת גונגל זוטר מזון מהיר סמכות שיפוט חבר מושפעים רק צדק הצדקה להצדיק קנגורו קריוקי קרטה קטנה קטי פרי קאזו קבב לשמור חבית קנדמה קרמיט קטשופ קומקום מפתח מקלדת קיי אף סי לבעוט ילד כלייה להרוג רוצח קים גונג און סוג גן ילדים מלך קינג קונג ממלכה קרבה קירבי נשיקה ערכה מטבח עפיפון חתלתול קיווי ללוש ברך לכרוע ברך סכין אביר לסרוג לדפוק קשר לדעת ידע מפרק קואלה קוראן קראקן קונג פו תווית מעבדה עבודה מעביד שרוך חוסר סולם ליידי ליידי גאגה פרת משה רבינו אגם טלה מנורה אדמה בעל דירה בעל קרקע נוף מסלול שפה עששית הקפה לפטופ גדול לאס וגאס לזנייה לייזר לאסו אחרון מאוחר אחרון צחוק ארוחת צהריים כביסה לבה מנורת לבה חוק מדשאה מכסחת דשא עורך דין להניח שכבה פריסה עצלן להוביל מוביל הנהגה עלה עלון נזילה להישען ללמוד לחכור רצועה עור לעזוב הרצאה עלוקה שמאל שאריות רגל חוקי אגדה חקיקה חקיקה בית מחוקקים לגו רגליים פנאי לימון לימונדה למור להלוות אורך עדשה לאונרדו דה וינצי לאונרדו די קפריו לפרקון שיעור לתת מכתב חדה שלב לרחף אחריות ליברלי חירות ספרנית ספרייה רישיון רישיון ללקק ליקריץ מכסה לשקר חיים סגנון חיים מעלית אור נורה קל יותר מגדלור ברק חרב אור כמו סביר שושן נופר גף לימבו ליים להגביל הגבלה מוגבל לימוזינה קו לינארי פשתן להתעכב קשר אריה מלך האריות שפה שפתיים שפתון נוזל רשימה להקשיב ידיעת קרוא וכתוב באופן מילולי ספרות התדיינות קופסת חול חי תוסס כבד לטאה לאמה מטען נטען לחם הלוואה לובי לובסטר למצוא מיקום לנעול אכסניה בול עץ הגיון הגיוני לוגו סוכרייה על מקל לונדון גלגל ענק בודד ארוך להסתכל לופ רופף לבזוז להפסיד מפסידן הפסד הפסיד מגרש קרם לחות לוטו רועש טרקלין אהבה מאהב נמוך נמוך יותר נאמן נאמנות מזל בר מזל מטען לואיגי חוטב עצים גוש ארוחת צהריים ריאה לינקס מילות שיר מקרוני מכונה מכונות מאצו מדגסקר מאפיה מגזין קסם קסם שרביט קסמים קוסם מגמה מגנט מגנטי זכוכית מגדלת עוצמה עוזרת בית דואר תיבת דואר דוור ראשי מיינסטרים תחזוקה ראשי רוב לעשות איפור קניון ממוטה איש לנהל הנהלה מנהל תחש נהרות בור בכביש מניקור בובת ראווה מידה אחוזה גמל שלמה ידני לייצר יצרן כתב יד מפה מאראקס מרתון שייש לצעוד מרגרינה שוליים ציפורני חתול ימי מאריו ציון מארק זוקרברג שוק שיווק ריבה מרמיטה נישואין נשוי מאדים ביצה מרשמלו קמע מסיכה מסה מסג ראשי גפרור קופסת גפרורים חומר מתמטיקאי מתמטיקאי מטריצה חומר מזרון בוגר מקסימום מיונז ראש עיר מבוך מקדונלדס אחו ארוחה ממוצע משמעות בעל משמעות אמצעים למדוד בשר קציצה קציץ מכונאי מכני מנגנון מדליה תרופה ימי הביניים בינוני מדוזה סוריקטה לפגוש פגישה מגפון מלון נמס חבר חברות מם זכור תזכיר אנדרטה זיכרון מנטלי לציין תפריט מרצדס סוחר כספית רחמים ערך בת ים הודעה מבולגן מתחת מטאור שיטה מתודולוגיה מקסיקו מיכאל גקסון מיקי מאוס מיקרופון מיקרוסקופ מיקרוסופט מיקרוגל אמצע מעמד הביניים חצות הגירה מתון מייל צבא חלב חלבן מילקשייק שביל החלב טחנה פנטומימה מוח שלי מיינקרפט כורה מינרל מיניקליפ מיני גולף לצמצם מינימום מיניון שר משרד מיני ואן מינורי מיעוט מינוטאור מנטה דקה נס מראה הפלה אומלל אומללות להטעות להתגעגע טיל ערפל תערובת תערובת נייד דגם מודרני צנוע מודול מוהוק עובש חפרפרת מולקולרי מולקולה רגע מומנטום מונה ליזה מונרך מלוכה מנזר יום שני כסף נזיר קוף מונופול מפלצת מפלצתי מון בלאן חודש חודשי מצב רוח ירח אייל מגב מוסרי מורל מורגן פרימן בוקר קוד מורס פת משכנתא מורטי פסיפס מסגד יתוש טחב עש רעל עש אמא לוח אם מוטיב מוטיבציה אופנוע אופנוע נהג כביש מהיר עובש הר אוורסט הר רושמור הר התאבלות עכבר מלכודת עכברים פה לזוז תזוזה סרט זז מוצארט מיסטר בין מיסטר מיסיקס מיסטר בין מיסטר מיסיקס אמ טי וי בוץ מאפין ספל מולטימדיה הרבה להכפיל אמא עירוני רצח רוצח שריר מוזיאון פטרייה מוזיקה מוזיקלי מוזיקאי מוסקט שפם חרדל מוטציה מלמול הדדי מיתוס נאצוס ציפורן פצירה לק שם תנומה מפית צר חד שן נאסא נאסקאר לאומי לאומיות לאומני אזרחות יליד טבע חיל הים חיוני צוואר צורך מחט שלילי להתעלם רשלנות משא ומתן שכן שכונה שכן שכונה נימו אחיין נפטון חנון עצב לחוץ קן רשת הולנד רשת ניטרלי חדש ניו זילנד עולה חדש חדשות עיתון נחמד ניקל לילה מועדון לילה סיוט נייק נינגה נינטנדו סוויטץ אצילי הנהון צומת רעש רעשני למנות מועמדות שטויות טירון נודל נורמה נורמלי צפון צפון קוריאה הזוהר הצפוני נורווגיה אף שיער אף נזם אף מדמם נחיריים חריץ הערה מחברת פנקס כלום הודעה נוטיפיקציה רעיון ידוע לשמצה שם עצם רומן גרעיני נאגט אטום מספר נזירה אחות משתלה אגוז מפצח אגוזים נוטלה מוסקט קצה המזלג אלון משוט אובליקס משקל עודף לציית אובייקט התנגדות מטרה חובה מעורפל תצפית מצפה כוכבים צופה מכשול להשיג ברור הזדמנות עיסוק מקצועי להעסיק אוקיינוס מתומן תמנון מוזר עבירה להעליב עבריין מעליב הצעה משרד קצין רשמי לקזז צאצא שמן אולף ישן אומלט השמטה בצל פתוח אופרה מבצע מבצעי דעה מתחרה התנגדות מתנגד ההפך אופוזיציה אופטימיות אופטימי אפשרות אופציונלי אוראלי תפוז אורנגוטן מסלול אורקה תזמורת סחלב הזמנה רגיל אוראו איבר אורגני אירגון לארגן התמצאות אוריגמי מקור מקורי אורתודוקסי יען אחר לוטרה חיצוני תלבושת מוצא תמצית השקפה פלט בחוץ אליפטי תנור בסך הכל להתעלם תצפית משקל חורג הצפה חייב ינשוף בעל בעלות חמצן צדפה פקמן קצב לארוז חבילה חפיסה שלולית עמוד כאב כואב צבע פיינטבול צייר זוג פיגמה ארמון פלטה כף יד עץ דקל מחבת פנקייק פנדה פאנל פניקה חליל פאן פנתר מכנסיים פפאיה נייר שקית נייר מצנח מצעד פרדוקס פסקה תוכי מקביל משותק פרמטר חנינה הורה הורי הורים פריז פארק חנייה פרלמנט תוכי חלק משרה חלקית משתתף להשתתף חלקיק מסוים שותף שותפות מסיבה למסור מעבר נוסע תשוקה תשוקתי פסיבי דרכון סיסמה עבר פסטה פסטל מאפה מראה ללטף טלאי פטנט דרך סבלנות פציינט פטיו פטריק פטריוט פטרול תבנית לעצור מדרכה כף רגל לשלם תשלום פייפאל שלום שקט אפרסק טווס פסגה בוטן אגס אפונים איכר דוושה הולך רגל שקנאי עט עונשין עיפרון קלמר מחדד מטוטלת לחדור פינגווין חצי אי פני פנסיה פנסיונר אנשים החזירה פפה פלפל פפרוני פפסי לתפוס אחוז תפיסה מושלם לנקב לבצע ביצוע מבצע בושם תקופה פריסקופ קבוע אישור להתמיד מתמיד איש אישי אישיות לשכנע מזיק חיית מחמד אוכל של חיות חנות חיות עלה כותרת רחמים רוקח תופעה פילוסוף פילוסופי פילוסופיה פיניאס ופרב מסגרת תמונה צילום מסמך תמונה צלם צילום פוטושופ פיזי פיזיקה פסנתר פיקאסו לבחור גרזן מלפפון חמוץ פיקניק תמונה פאי חתיכה מזח חזיר יונה קופת חזיר דיר חזירים פיקאצו כידון ערימה גלולה עמוד כרית מלחמת כריות טייס חצקון סיכה פינבול אורן אצטרובל אננס ורוד הפנתר הורוד זרת פינוקיו שבשבת חלוץ צינור פיראט ספינת פיראטים פיסטוק אקדח בור נאום קלשון רחמים פיצה מקום מגיפה מישור תובע תוכנית מטוס כוכב לכת קרש צמח פלסטר פלסטיק צלחת פלטפורמה ברווזן לשחק שחקן גן משחקים פלייסטיישן להפציר נעים בבקשה עונג ערובה מגרש לחרוש שסתום אינסטלטור פומפה פלוטו דלקת ריאות כיס שיר שירה מקל פוגו נקודה רעל רעיל לדקור פוקימון דוב קוטב עמוד שוטר מדיניות להבריק מנומס פוליטי פוליטיקאי פוליטיקה סקר זיהום פולו אגם פוני קוקו פודל בריכה קקי עני לפוצץ פופקורן אפיפיור פופאי פרג קרטיב פופולרי אוכלוסייה מרפסת דורבן פורקי פיג נייד פורטל סבל חלק פורטרט פורטוגל פסואידון עמדה חיובי רשות אפשרות אפשרי דואר גלוייה פוסטר לדחות סיר סיר זהב תפוח אדמה פוטנציאל שיקוי קדרות לחבוט למזוג אבקה כח כוחני פרקטי אימון להלל חסילון להתפלל תפילה להטיף להקדים תקדים מדויק דיוק טורף קודם צפוי להעדיף העדפה הריון דעה קדומה מוקדם מידי פרימיום עיסוק הכנה מרשם נוכחות מתנה הצגה שמירה נשיאות נשיא נשיאותי ללחוץ לחץ יוקרה פרטצל שכיחות למנוע טרף מחיר תג מחיר גאווה כומר ראשי נסיך נסיכה עיקרון פרינגלס להדפיס מדפסת עדיפות פריזמה בית כלא אסיר פרטיות פרטי זכות מיוחס פרס בעד הסתברות בעיה נוהל תהליך להכריז דחיינות לייצר מפיק מוצר ייצור פרודוקטיבי מקצוע מקצועי פרופסור פרופיל רווח עמוק תוכנית מתכנת התקדמות פרוגרסיבי פרויקט השלכה ממושך הבטחה קידום הוכחה תעמולה תקין רכוש פרופורציה פרופורציונלית הצעה הצעה להעמיד לדין תביעה סיכוי שגשוג להגן הגנה חלבון מחאה גאה להוכיח לספק מחוזי הוראה לעורר שזיף מיובש פסיכולוג פסיכולוגיה פאב ציבורי פרסום פרסום לפרסם מוציא לאור פודינג שלולית פאפין משיכה פומה פומבה משאבה דלעת אגרוף להעניש ענישה פאנק תלמיד מריונטה טהור טוהר מטרה ארנק מרדף לדחוף לשים פאזל פירמידה הסמכה מוסמך להעפיל איכות כמותי כמות רבע מלכה מסע שאלה שאלון תור חול טובעני שקט עט נוצה שמיכה להפסיק מכסת ציטוט ציטוט ארנב רקון מירוץ מכונית מירוץ גיזעי גזענות מתלה ראדאר קרינה קיצוני רדיו צנון רפסודה זעם פשיטה מסילה קרון מסילת ברזל גשם קשת בענן מעיל גשם טיפה יער גשם להרים צימוקים לגרף להרים ראלי רמפה שרירותי מטווח דירוג ראפר נדיר פטל חולדה קצב יחס רציונלי רביולי נא להב סכין גילוח להושיט יד תגובה כור לקרוא קורא מוכן אמיתי להבין מציאותיות מציאותי מציאות אחורי סיבה סביר מורד מרד קבלה קבלה פקיד קבלה מיתון פזיז זהה הכרה ממליץ המלצה הקלטה הקלטה לשחזר החלמה בילוי גיוס מלבן למחזר מיחזור אדום שטיח אדום רדיט לגאול הפחתה יתירות קנים להפנות שופט הפניה הפניה להרהר השתקפות רפורמה פליט סירוב לסרב להתייחס אזור אזורי לרשום רישום חרטה רגיל רגולציה שיקום חזרה שלטון אייל לחזק לדחות דחייה להתייחס קשור קשר מערכת יחסים יחסי להירגע הרפיה שחרור רלוונטיות רלוונטי אמין הסתמכות הקלה להקל דת דתי לוותר להיסחף להסתמך להישאר להעיר תרופה לזכור להזכיר מרחוק להשכיר לחזור חזרה להחליף החלפה דווח מדווח לייצג נציג לשכפל רבייה זוחל רפובליקה מוניטין בקשה לדרוש דרישה הצלה מחקר חוקר דומה להביע כעס שמורה מאגר מגורים תושב מגורים להתפטר התפטרות להתנגד פתרון אתר נופש משאב לכבד מכובד תגובה אחריות אחראי מנוחה מסעדה חסר מנוחה שיקום לרסן ריסון מוגבל הגבלה תוצאה קמעונאות קמעונאי לשמור לפרוש פריש פרישה נסיגה להחזיר לחשוף נקמה להפוך לסקור לתקן החייה להחיות מהפכה מהפכנית אקדח גמול להריץ אחורה רטוריקה קרנף קצב צלע סרט אורז עשיר לנקוע לרכב רוכב רכס רובה ימין ימני לצלצל צלצול להפגין להרים סיכון טקס נהר כביש מחסום שאגה לשדוד שודד שוד רובי רוטן ציפור אדום החזה רובין הוד רובוט אבן רקטה כוכב רוק תפקיד לגלגל רומניה רומנטי רומא גג חדר תרנגול שורש חדר ורד סיבוב רקוב מחוספס עגול מסלול שגרה שורה מלכותי תמלוג לשפשף גומי זבל אודם שטיח רוגבי הריסה כלל סרגל שמועה לרוץ אלפאבית רוני אצן כפרי למהר רוסיה קדוש להקריב עצוב אוכף ספארי בטוח בטיחות להפליג ספינת מפרש מלח סלט למכור רוק סלמון סלון מלח מי ים ישועה דוגמית סמסונג מקלט חול טירת חול סנדל ארגז חול סופת חול סנדוויץ סנטה לווין שביעות רצון משביע רצון מרוצה שבתאי רוטב סאונה נקניק לשמור סקסופון לומר משקל לסרוק שערוריה צלקת דחליל צעיף מפחיד פיזור תסריט סצנה ריח לוח זמנים תבנית מלומד מלגה בית ספר מדע מדעי מדען מספריים סקובי דו לגרוף ניקוד סקוטלנד לטרוף לזרוק לגרד לגרד צעקה מסך בורג לשרבט תסריט צלילה פסל חרמש ים אריה ים מאכלי ים שחף סוס ים כלב ים לחפש צדף מחלת ים עונה עונתי מושב חגורת בטיחות אצה שני משני סוד מזכירה הפרשה סעיף מגזר חילוני מאובטח אבטחה לראות זרע לחפש נראה נדנדה סגווי לתפוס בחירה עצמי למכור מוכר חצי עיגול סמינר לשלוח ותיק תחושה להרגיש סנסאיי רגיש רגישות משפט רגש נפרד הפרדה רצף סדרה רציני משרת לשרת שרת שירות ישיבה סט להתיישב ישוב לתפור מכונת תפירה צל צל מוט לנהר רדוד בושה שמפו צורה לחלוק בעל מניות כריש חד לנפץ להתגלח קצף גילוח מחסן כבשה דף מדף פגז מקלט שרלוק הולמס מגן משמרת לזהור ספינה טרופה חולצה לרעוד שוק נעל קופסת נעליים שרוך לירות חנות ופינג עגלת קניות נמוך מחסור מכנסיים בעיטה רובה צייד כתף לצעוק יעה הצגה מקלחת שרק חדף להקטין שיח למשוך כתפיים ביישן חולה מחלה צד מצור אנחה מראה סיור סימן חתימה שקט משי סילו כסף כלי כסף דומה דמיון פשטות חטא לשיר סינגפור זמר יחיד כיור ללגום אחות לשבת אתר מצב שישייה מידה להחליק סקייטבורד רוכב סקייטבורד גלגליות שלד סקיצה סקי מקפצת סקי מיומנות מיומן עור רזה חצאית סקיטלס סקריבל סקרילקס גולגולת בואש שמיים צניחה חופשית קו רקיע סקייפ גורד שחקים לוח לטרוק סתירה עבד מזחלת פטיש לישון שרוול חתיכה לגלוש סליים קלע קפיץ להחליק חלקלק סיסמה מדרון חריץ עצלן לאט ליפול קטן חכם לרסק ריח חיוך עשן חלק חילזון נחש לצלם לחטוף להתעטש לרחרח צלף שלג כדור שלג מלחמת כדורי שלג סנובורד פתית שלג איש שלג להתכרבל להשרות סבון לדאות כדורגל חברתי מדיה חברתית סוציאליסט חברה סוציולוגיה גרב כיס גרביים סודה נתרן רך תוכנה אדמה סולרי מערכת השמש חייל מוצק סולידריות סולו פיתרון לפתור סומבררו בן קולי מתוחכם סופרנו נשמה צליל מרק חמוץ מקור דרום לזרוע חלל חליפת חלל ספינת חלל את חפירה ספגטי ספרד רזרבה ניצוץ ניצוצות ספרטקוס מרחבי מרית רמקול חנית מומחה זן נקוב דוגמה ספקטרום לשער דיבור מהירות לאיית חוקר מערות לבזבז כדור ספינקס עכביש ספיידרמן לשפוך לסובב תרד עמוד השדרה ספירלי רוח לירוק להכעיס לפצל לפנק ספוילר דובר ספוג ספונג בוב ספונטני סליל כף נבג ספורט ספורט נקודה תרסיס ספריי צבע ממרח אביב ממטרה מרגל חוליה ריבוע למעוך דיונון סקווידוויד סנאי לדקור חווה אצטדיון צוות במה כתם גרם מדרגות יתד דוכן חותמת לעמוד סטנדרטי שדכן כוכב מלחמת הכוכבים כוכב ים קרמבולה התחלה מצב הצהרה תחנה סטטיסטי סטטיסטיקה פסל פסל החירות להישאר יציב סטייק קיטור פלדה תלול סטגוזאורוס גזע צעד סטריאו סטיב גובס דייל להדביק דביק שקט גירוי עוקץ טריגון לערבב תפר מלאי קיבה אבן עידן האבן מסטול שרפרף לעצור תמרור עצור אחסון חנות חסידה סופה סיפור תנור ישר ליישר למתוח מוזר רצועה אסטרטגי קש תות נחל סטרימר רחוב כוח לחץ למתוח קפדן צעד מכה שרשרת רצועה שבץ הליכה חזק מבני מבנה מאבק עקשן תלמיד סטודיו ללמוד חפצים למעוד מדהים טיפש סגנון עט נושא סובייקטיבי צוללת להגיש לאחר מכן חומר להחליף פרבר רכבת תחתית הצלחה מוצלח פתאומי סודוקו תעלת סואץ לסבול סבל מספיק סוכר להציע הצעה להתאבד חליפה מזוודה חליפה גופרית סכום סיכום קיץ פסגה שמש כוויה חמנייה משקפי שמש זריחה שמשיה אור שמש מפקח טוב יותר סופרמן סופרמרקט כח על מנהל כלול אספקה תמיכה להניח לדכא שטח גלשן מנתח ניתוח הפתעה מופתע מפתיע להקיף סקר השרדות שורד סוזן ווציצקי סושי חשוד חשד לתמוך סוואג לבלוע ביצה ברבור נחיל להישבע זיעה סוודר לטאטא מתוק נפוח לשחות בריכת שחייה בגד ים לנדנד להחליק מפסק חרב דג חרב בית האופרה בסידני הברה סמל סימטריה סימפטי סימפוניה סימפטום סינדרום מערכת שיטתי טי רקס טי שירט שולחן טניס שולחן מפת שולחן טאבלט שולחן טאקו טקטיקה ראשן זנב חייט זנבות לקחת המראה מופע כשרונות כשרוני לדבר פטפטן גבוה טמפון מנדרינה טנק ברז סרט טרנטולה מטרה טרזן טייזר טעם טעים קעקוע מס מונית נהג מונית משלם מיסים תה מורה קבוצה קנקן תה דמעה להקניט כפית טכני טכניקה טכנולוגיה בובת דובי נוער טלפון טלסקופ טלטאבי טלוויזיה לספר טמפרטורה מקדש זמני לפתות פיתוי דייר מגמה מכרז טניס מחבט טניס מתוח מתח אוהל זרוע מונח טרמינל מחסל מרפסת מפחיד מחבל מבחן להעיד טטריס טקסט טקסטורה להודות תודה החיפושיות תאטרון גניבה נושא תאולוגיה תאורטיקן תאוריה תרפיסט תרפיה מד חום תזה עבה גנב ירך דק לחשוב הוגה צמא צמא טור מחשבה מתחשב שרוך איום לאיים סף גרון כס מלכות לזרוק דחף בריון אגודל ברק סופת ברקים קרציה כרטיס לדגדג גאות לנקות עניבה טייגר צמוד מרצפת עץ זמן מכונת זמן לוח זמנים טימפני פח קטנטן טיפ טירמיסו צמיג עייף טישו קופסת טישו טיטאניק כותרת קרפדה טוסט מצנם בוהן ציפורן בית שימוש סובלני לסבול אגרה עגבניה קבר מצבה טון טון לשון כלי ארגז כלים שן פיית שיניים מברשת שיניים משחת שיניים קיסם שיניים ראש מגבעת לפיד טורנדו טורפדו צב עינוי לזרוק סך הכל טוטם טוקאן לגעת קשוח תיירות תייר טורניר משאית גרר מגבת מגדל גשר לונדון מגדל פיזה עיר רעיל צעצוע זכר מסלול מסלול טרקטור מסחר מסורת מסורתי תנועה רמזור טרגדיה נגרר רכבת מאמן אימון תכונה טרנזקציה להעביר לשנות מעבר לתרגם תמסורת שקוף תחבורה מלכודת מלכודת פח אשפה נוסע מגש לדרוך הליכון אוצר גזבר לטפל טיפול אמנה עץ בית עץ לרעוד חפירה טרנד משפט משולש שבט הוקרה טריק טריקשוט תלת אופן הדק טיול שלישיות חצובה טריוויאלי עגלה טרומבון גדוד גביע טרופי צרה מכנס משאית נהג משאית אמת חצוצרה גזע אמון נאמן אמת לנסות טובה צינור למשוך להתגלגל גידול גידול טונה מנגינה מנהרה צואה תרנגול הודו פנייה לפת צב טוקסידו טוויטי מקל תאום להתפתל טוויטר טייקון סוג טיפוסי צמיג עטין חייזר מכוער יוקלילי כיב סופי מטרייה פה אחד לא מודע אי וודאות דוד לא נוח תת קרקעי למתוח קו מתחת לחתור להבין הבנה לוקח על עצמו תת משקל לבטל לא נוח מובטל אבטלה לא צפוי לא הוגן חסר מזל חד גבה חד קרן חד אופן מדים איגוד ייחודי יחידה אחדות אוניברסלי ייקום אוניברסיטה לא חוקי שונה בלתי סביר לא נעים אי שקט לעדכן שדרוג לשבש אורנוס אורבני דחף דחוף שטן יוסיין בולט יו אס בי להשתמש שימושי חסר שימוש משתמש רגיל מוחלט פנוי חופשה חיסון ואקום מעורפל יהיר תקף עמק יקר ערך ערך ערפד ואן וניל נעלם משתנה סוג וריאציה מגוון גיוון מעמ ותיקן כספת נער הכספת וקטור ירק צמחוני צמחייה כלי רכב צעיף וריד ולוסירפטור קטיפה פתח איוורור להעז נוגה מילולי גזר דין גרסה אנכי כלי שיט ותיק וטרינר אפשרי מרושע קורבן ניצלון וידאו משחק וידאו נוף נמרץ וילה כפר תושב כפר רשע וין דיזל גפן חומץ כונרת הפרה אלימות אלים כינור בתול מציאות מדומה מעלה וירוס מלחציים נראה ראייה ביקור מבקר ויזואלי ויטמין ולוגר מקצועי וודקה קול הר געש כדורעף ווליום רצוני מתנדב להקיא וודוו מערבולת להצביע מצביע שובר מסע פגיע נשר וווזלה רשת אלחוטית וופל שכר עגלה מותן לחכות מלצר ער להעיר ללכת קיר וול-אי טפט אגוז מלך סוס ים לשוטט רוצה מלחמה מחלקה מלתחה מחסן חמים להזהיר אזהרה צו לוחם יבלת לשטוף צרעה זבל שעון מים מחזור המים רובה מים מפל גל שעווה דרך חלש חולשה עושר כלי נשק ללבוש סמור מזג אוויר לארוג רשת אתר חתונה עשב שבוע סוף שבועי שבועי לשקול משקל ברוך הבא רתך רווחה באר איש זאב מערב מערבי רטוב ליוויתן וואטסאפ חיטה גלגל מריצה שוט להקציף וויסקי לחישה שריקה לבן שלם להרחיב אלמנה רוחב אישה פאה להתפתל פראי מדבר חיות בר רצון וויליאם שייקספיר וויליאם וולאס עץ ערבה כח רצון ניצחון רוח טחנת רוח חלון שמשה יין כוס יין כנף אום כנפיים מנצח פו הדוב חורף למחוק כבל אלחוטי חכם מכשפה לסגת נסיגה עד ראייה מכשף זאב גרגרן אישה פלא וונדר וומן ארץ הפלאות עץ נקר צמר מילה ניסוח לעבוד אימון עובד מקום עבודה סדנה עולם תולעת לדאוג שווי פצע לעטוף עטיפה זר הריסות מפתח ברגים להתאבק מתאבק האבקות קמט זרוע לכתוב כותב כתוב טעות רנטגן אקסבוקס מכונת צילום קסילופון יאכטה חצר סרט מדידה לפהק שנה ספר מחזור צהוב יטי יין-יאנג יו יו יודה יוגורט חלבון ביצה יושי צעיר נוער יוטיוב יוטיובר זברה זלדה צפלין אפס זאוס זיגזג אומגה רוכסן זומבי איזור גן חיות זום זורו זומה ================================================ FILE: internal/game/words/it ================================================ capacità aborto abuso accademia incidente contabile acido atto inserisci dipendente aggiunta indirizzo amministratore adulto pubblicità affare impaurito pomeriggio età agenzia agente accordo aria aereo linea aerea aeroporto corridoio allarme album alcool indennità alleato altare ambra ambulanza amputare analisi angelo rabbia angolo arrabbiato animale caviglia annuncio annuale anonimo formica anticipati ansia scusarsi apparire appetito applaudire mela applicazione appuntamento approvare acquario arco archivio arena braccio poltrona esercito arresto freccia arte articolo artificiale artista artistico cenere addormentato aspetto assalto risorsa incarico asilo atleta atomo attacco attico attirare sala delle aste pubblico automatico media aviazione sveglio premio asse bambino indietro sfondo bacon borsa cauzione infornare equilibrio balcone calvo palla balletto palloncino banana gruppo musicale scoppio banca bandiera bar abbaiare barile barriera base baseball bacino cestino pallacanestro pipistrello bagno batteria battaglia campo di battaglia baia spiaggia fascio fagiolo orso barba battere letto camera da letto ape manzo birra elemosinare decapitare campana pancia cintura panchina piegare bacca scommessa bibbia bicicletta bidone biografia biologia uccello compleanno biscotto vescovo cagna mordere amaro nero lama vuoto esplosione sanguinare benedire cieco bloccare bionda sangue massacro sanguinoso soffio blu tavola barca corpo bollire bullone bomba bombardiere legame osso libro esplosione stivale confine preoccuparsi bottiglia sotto rimbalzo arco intestino ciotola scatola ragazzo cervello freno ramo marca coraggioso pane rompere seno respirare razza brezza fabbrica di birra mattone sposa ponte portare trasmissione broccoli rotto bronzo fratello marrone spazzola bolla secchio buffet edificio lampadina proiettile fascio sepoltura bruciare seppellire autobus cespuglio attività commerciale uomo d'affari burro farfalla pulsante acquistare cabina consiglio dei ministri cavo bar gabbia torta calcolo calendario vitello chiamata telecamera campo annulla cancro candidato candela canna tela berretto capitale capitano catturare auto carta carriera tappeto carrozza carota trasportare carrello intagliare astuccio denaro cassetta castello gatto catturare cattedrale causa grotta soffitto celebrazione cellula cantina cimitero censura centro cereale cerimonia certificato catena sedia gesso champagne campione modificare canale caos capitolo personaggio caricare beneficenza fascino grafico svalutare controllare guancia formaggio chimico chimica ciliegia petto masticare pollo capo bambino infanzia camino mento patatine fritte cioccolato soffocare tritare cronico chiesa sigaretta cinema cerchio circolazione cittadino città civile richiesta classe classico aula argilla pulito scalata clinica orologio vicino chiuso abiti nube club traccia allenatore carbone costa cappotto codice caffè bara moneta freddo crollo collega raccogliere collezione università colonia colore colorato colonna coma combinazione combinare commedia cometa comando commento comunicazione comunità azienda confrontare competere lamentarsi completare computer concentrato concerto calcestruzzo conduttore conferenza fiducioso conflitto confusione connessione coscienza consenso ritenere cospirazione costellazione costrizione costruire contatto concorso contrarre contraddizione convenzione conversazione convertire galeotto cucinare rame copia cordone nucleo mais angolo correzione costume villetta cotone tosse contare contatore nazione coppia corso copertina mucca crepa mestiere artigiano schianto crema creazione carta di credito credito strisciamento equipaggio cricket crimine penale attraversare attraversamento accovacciarsi folla corona piangere cristallo cetriolo tazza credenza arricciare moneta attuale programma scolastico tenda curva cuscino cliente tagliare carino taglio ciclo cilindro latteria danno danza pericolo buio data figlia giorno luce del giorno morto mortale sordo affare commerciante morte debito diminuire profondità cervo sconfitta difendere grado consegnare consegna demolire dimostrazione dentista allontanarsi partenza depositare depressione discesa deserto design scrivania distruzione investigatore rivelatore diagnosi diagramma diametro diamante dettare dizionario morire differire differenza scavare digitale cena tuffo direzione direttore elenco sporco invalidità scomparire discoteca sconto scoperta discreto discutere malattia piatto antipatia schermo sciogliere distanza lontano tuffo dividere divisione divorzio medico documento cane bambola dollaro delfino cupola dominio donare porta dose doppio impasto trascinare drago drain disegnare cassetto disegno sognare vestito trapano bevanda guidare autista goccia annegare droga tamburo asciutto anatra dovuto noioso discarica durata aquila orecchio presto terremoto est mangiare origliare eco bordo educazione uovo gomito elezione elettricità elettrone elettronico elettronica elemento elefante eliminare emergenza emozione impero vuoto fine nemico energia motore ingegnere ingrandire accedere entusiasmo iscrizione busta ambiente episodio pari equazione attrezzatura errore fuga Europa anche sera evoluzione superare eccitato esecuzione uscita espandere espansione costoso sperimentare esplodere esplorazione esplosione esportare espressione ampliare estinto extraterrestre occhio sopracciglio facciata viso agevolazione fabbrica fallire fallimento svenire giusto fata autunno fama famiglia fan fantasia lontano azienda agricola contadino veloce grasso padre fax paura festa piuma tassa recinto traghetto festival febbre fibra finzione campo combattimento file riempire film filtro finanza finanziario trova dito finire fuoco pompiere primo pesce pescatore cazzotto adattarsi fitness aggiustare bandiera veloce flotta carne volo scagliare alluvione pavimento farina fiore influenza flui sciacquone volare piegare cibo scemo piede calcio vietare fronte straniero foresta forchetta formale formula fortuna inoltrare fossile fondazione fontana volpe frammento franchigia frode lentiggine gratuito congelare nolo frequenza fresco frigo amico amicizia rana davanti congelato frutta carburante divertimento funerale divertente pelliccia mobilia galassia galleria gallone gioco divario box auto spazzatura giardino aglio gas cancello genio signore geografia geologica gesto fantasma gigante regalo ragazza dare ghiacciaio bicchiere bicchieri planata oscurità guanto splendore colla partire obbiettivo portiere capra dio oro golf bene governo graduale diplomato grano nonno nonna grafo grafica erba tomba ghiaia gravità verde salutare saluto smorfia sorriso presa terra crescere crescita guardia ospite colpa chitarra pistola grondaia habitat capelli tagliare i capelli metà sala corridoio martello mano handicap appendere contento porto difficile hardware danno armonia raccogliere cappello odiare ritrovo fieno testa titolo sede centrale salute salutare sentire cuore calore paradiso pesante siepe altezza elicottero inferno casco emisfero gallina mandria eroe eroina nascondere alto evidenziare escursione collina anca storico colpire stretta buco vacanza casa miele gancio orizzonte orizzontale corno orrore cavallo ospedale ostaggio caldo hotel ora casa pianta della casa casalinga librarsi enorme umano umanità cacciatore cacciare male marito capanna ipnotizzare gelato ghiaccio idea identificazione identificare identità illegale malattia immagine immaginazione immaginare immigrante immigrazione importare impulso incidente reddito individuale interno industriale industria infettare infezione infinito gonfiare informazione ingrediente abitante iniettare iniezione infortunio innocente insetto inserire dentro ispettore impiantare istruzione strumento integrazione intelligenza internazionale colloquio invasione investigatore invito invitare ferro isola solitudine articolo giacca prigione marmellata vaso mascella jazz gelatina cretino jet gioiello lavoro fantino comune scherzo gioia giudice giudizio succo saltare giungla junior giuria giustizia bollitore chiave calcio ragazzo rene uccidere uccisore genere re regno bacio cucina aquilone ginocchio inginocchiarsi coltello bussare nodo etichetta laboratorio pizzo scala signora lago agnello lampada terra proprietario proprietario terriero paesaggio linguaggio giro grande laser ultimo ultimo ridere lanciare lavanderia prato avvocato posare disposizione comando foglia volantino perdita magro imparare pelle partire conferenza sinistra avanzi gamba leggenda limone lunghezza lezione lettera livello biblioteca licenza leccare coperchio menzogna sollevamento leggero giglio arto limite linea collegamento leone labbro liquido elenco ascolta letteratura vivere fegato atrio individuare posizione serratura casetta log solitario lungo guarda cappio largo perdere lotto forte sala amore inferiore fortunato grumo pranzo polmone macchina rivista magnetico domestica posta corrente principale manutenzione maggiore trucco uomo gestione manuale produzione carta geografica maratona marmo marzo marino marketing matrimonio sposato Marte palude maschera massa maestro incontro materiale matematico matematica massimo sindaco labirinto pasto misurare carne meccanico medaglia medicina medievale medio incontrare incontro membro membri memoriale memoria menù mercante messaggio metallo microfono mezzo mezzanotte miglio militare latte mente minatore minerale minimizzare minimo minore minuto specchio aborto spontaneo perdere missile mobile modello talpa molecolare soldi monaco scimmia monopolio mostro mostruoso mese luna mattina moschea zanzara madre autostrada montagna topo bocca mossa muovere fango boccale multimedia multiplo moltiplicare omicidio muscolo museo fungo musica musicista reciproco mito chiodo nome pisolino stretto natura marina militare collo ago vicino quartiere nipote nido netto rete notizia notte incubo cenno rumore nord naso nota taccuino romanzo nucleare numero suora infermiera asilo noce quercia obeso obbedire osservazione osservatore ostacolo ottenere oceano dispari offrire ufficio ufficiale prole olio vecchio omissione cipolla aperto musica lirica operazione avversario opporsi frontale opzione orale arancia orbita orchestra organo originale attrezzatura presa schema prospettiva esternamente forno gufo proprietà ossigeno pacco pacchetto pagina dolore dipingere pittore paio palazzo palma padella carta parata paragrafo parallelo genitore parco parcheggio particella compagno associazione festa passaggio passeggeri passaporto password passato colpetto brevetto sentiero modello pausa marciapiede pagare pagamento tranquillo arachide pedone penna matita centesimo persone pepe per cento perforare esecutore periodo persona animale domestico filosofo fotocopia fotografia fotografo fotografia fisica pianoforte raccogliere immagine torta pezzo molo maiale piccione mucchio pillola cuscino pilota perno pioniere seme fossa piano aereo pianeta pianta plastica piattaforma giocare piacevole impegno spina tasca poema poesia punto veleno polo politica sondaggio inquinamento pony piscina povero ritratto positivo inviare cartolina pentola patata ceramica versare polvere energia pregare preghiera preciso predecessore prevedibile incinta presente presentazione presidenza presidente stampa pressione preda prezzo principe principessa stampa stampante prigione prigioniero vita privata privilegio premio produrre produttore prodotto produzione produttivo professoressa profilo programma proiezione prova propaganda proprietà proporzione proporzionale proteggere protezione proteina protesta psicologo pub pubblicare budino tirare pompa zucca pugno allievo spingere puzzle piramide qualificato qualità trimestre regina domanda questionario coda smettere quotazione citazione coniglio gara razzismo cremagliera radiazione radio rabbia incursione automotrice ferrovia pioggia arcobaleno rally casuale rango ratto vota rapporto crudo raggiungere reazione reattore leggere lettore posteriore ribelle ricevuta ricezione disco registrazione recupero riciclare rosso riduzione ridondanza riflettere riflessione regione registrati reinserimento prova regno relazionato relazione rilassare pubblicazione religioso riluttanza rimanere osservazione ricordare affitto ripetere ripetizione sostituire sostituzione rapporto reporter riproduzione rettile ricerca ricercatore residente ricorrere risorsa riposo ristorante restrizione risultato vendetta inverso rinascita rivivere costola nastro riso ricco ciclista fucile giusto squillare rivolta salire rituale fiume strada ruggito rapinare rapina robot roccia razzo ruolo rotolo romantico tetto camera corda rosa riga reali sciocchezze rugby correre corridore sacro sacrificio sicuro vela marinaio insalata vendita salmone sale salvezza sabbia sandalo satellitare soddisfacente salsa salsiccia salva dire scansione spargimento scena programma scuola scienza scienziato punto graffiare urlare schermo copione scultura mare foca ricerca stagione stagionale posto a sedere secondo secondario segretario sicuro vedere seme vendere venditore seminario anziano separazione sequenza serie servitore servire servizio insediamento sfumatura ombra superficiale vergogna forma condividere squalo acuto frantumarsi radersi pecora foglio mensola conchiglia scudo cambio brillare camicia shock scarpa sparare negozio shopping corto carenza pantaloncini tiro spalla grido mostrare doccia contrarsi alzare le spalle timido malato malattia vista giro turistico cartello firma silenzio seta argento simile somiglianza peccato cantare cantante singolo lavello sorella sedersi luogo taglia pattinare schizzo sciare cranio cielo lastra sbattere schiaffo schiavo dormire manica fetta limo scivolare scivoloso fessura lento intelligente distruggere odore sorridi fumo lumaca serpente annusare neve rannicchiarsi sapone calcio calzino morbido software suolo solare soldato solido assolo soluzione risolvere anima suono minestra sud spazio altoparlante campione discorso velocità sillabare sfera ragno versare rotazione spinaci colonna vertebrale spirito sputare diviso cucchiaio sport individuare spray diffusione primavera spiare squadra piazza spremere pugnalata personale palcoscenico macchia scala stalla francobollo stare in piedi stella stazione statua bistecca vapore stelo passo bastone appiccicoso puntura punto azione stomaco pietra sgabello conservazione memorizzare tempesta dritto cannuccia fragola strada forza allungare sciopero corda ictus forte alunno studio stupido stile soggettivo sostanza sobborgo riuscito zucchero suicidio completo da uomo appartamento somma sommario estate sole alba luce del sole superiore supermercato supervisore supporto sopprimere superficie chirurgo chirurgia sorpresa circondare sondaggio sospettare giurare sudore maglione spazzare dolce gonfiarsi nuotare swing rubare interruttore spada simmetria sistema maglietta tavolo tavoletta coda alto serbatoio rubinetto nastro bersaglio gustoso taxi tè insegnante squadra lacrima tecnico tecnica tecnologia adolescente telefono televisione temperatura tempio inquilino tenero tennis tenda terminale terrazza terrorista test testo teatro furto terapista terapia spesso magro pensare pensato minaccia minacciare gola trono gettare pollice zecca biglietto marea cravatta tigre stretto piastrella tempo orario lattina mancia stanco fazzoletto di carta titolo crostini dito del piede pomodoro tonnellata lingua attrezzo dente superiore torcia tortura scossa totale toccare turismo torneo asciugamano torre cittadina tossico giocattolo tracciare traccia commercio traffico treno allenatore formazione trasferimento trasparente trasporto trappola tesoro trattamento albero tendenza prova triangolo tribù omaggio trucco viaggio carrello truppe tropicale pantaloni camion tronco tubo caduta tumore tunnel tacchino girare gemello torcere magnate pneumatico brutto ombrello scomodo sottolineare uniforme unico unità unità università aggiornare irritato urbano urina utente vuoto valle prezioso furgone variante verdura vegetazione veicolo velo venere verbale versione verticale nave veterano vittima vittoria video visualizza villa villaggio violento vergine visione vitamina voce vulcano volume voucher viaggio carro vita scia camminare parete guerra armadio caldo avvertimento guerriero lavare rifiuto orologio acqua cascata onda modo debolezza ricchezza arma indossare tempo metereologico tessere nozze erba settimana fine settimana settimanalmente peso bene ovest bagnato balena grano ruota frusta whisky sussurro bianca totale vedova larghezza moglie selvaggio natura selvaggia natura vincere vento finestra vino ala vincitore inverno pulire filo strega testimone lupo donna legna lana parola mondo verme preoccupazione ferita avvolgere relitto lottare polso scrivi scrittore scritto sbagliato raggi X yacht cortile sbadiglio anno giovane gioventù zero zona ================================================ FILE: internal/game/words/nl ================================================ aanbieding aandrijving aangename aankondiging aantrekken aanval aanwezig aanwijzing aap aardappel aardbei aardbeving aardewerk abortus academie accountant achter achtergrond achteruit achtervolgen adelaar ademen adres advocaat afbeelding afbeeldingen afdaling affaire afgelopen afgestudeerde aflevering afluisteren afname afspraak afstand afval afvoer agent alarm AlbertHeijn album alcohol altaar ambacht amber ambulance amputeren analyse angst annuleer anoniem anticipatie appel applaudisseren aquarium archief arena arm arrest art artikel artistiek as asiel aspect atleet atoom automatisch avond award baan baard baby bad bak bal balkon ballet ballon banaan band bang bank banner barrière basis basketbal batterij bean bed bedreig bedreiging bedrijf bedrijfstak been beer begraaf begraafplaats begrafenis begroet behandeling beheerder beker bekijk bekken bel belofte bemanning beperking bereik berekening berg bericht berijder beroerte bes bescherm bescherming bespaar bespreek bestand bestrating bestuurder betaal betaling beton bevredigend bevriezen bevroren bewaker bewijs bezienswaardigheden bibliotheek bid bier bij bijbel bijt bin binding binnen biografie biologie bioscoop bisschop bitter blad blanco blauw blijven blind bloed bloeden bloedvergieten bloem blok blonde bocht boek boem boer boerderij bol bom bommenwerper bondgenoot boog boom boor boos boot bord borgtocht borst borstel bos bot boter bout branden brandstof brandweerman breedte breng briefkaart bril broccoli broek broer brok bron brons brood brouwerij brug bruid bruiloft bruin brullen bubbel buffet buigen buik buis buiten buitenaards buitenlander buitenwijk bundel bureau burgemeester burger bus buur buurt café cake camera canvas cap carrière carve cassette cat cel censuur ceremonie certificaat champagne chaos charme chemie chemische chip chirurg chocolade chronische cilinder circulatie cirkel citaat citeer citroen claim club coach code collectie collega college coma combinatie combineren commando commentaar communicatie computer concentraat concert concurreren conferentie conflict consensus construct contact contant contract controleer conventie correctie crack crash creatie creditcard crème cricket crimineel curriculum cursus curve cyclus dacht dag daglicht dak daling dame dans dappere darm datum deal dealer deeg deel deeltje deining dekking deksel demonstratie denk depressie detective detector deur diagnose diagram diamant diameter dicteer diefstal dienaar diep dier digitale dik diner dip directory dirigent disco discrete divisie dochter document dodelijke doel doelman dokter dolfijn dollar doneer donker dood doof doolhof dorp dosis douche draad draag draai draak dragen driehoek drink droog droom drug druk drum dubbel duif duik duivin dump dun dutje duur dwaas echo echtgenoot echtscheiding eenheid eenzaam eerbetoon eerlijke eerste eet eetlust ei eigendom eikel eiken eiland einde elektriciteit elektron elektronica elektronische element elimineren elleboog emmer emotie energie engel enkel enkele enorme enthousiasme envelop Europa evenredig evolutie excuses exemplaar experiment explosie export extensie fabricage fabriek faciliteit falen familie fantasie fase fauteuil fax fee feest festival fictie fiets film filosoof filter financiële financiën finish fitness fix fles flits fluisteren flush folder fontein formele formule fortuin fossiel foto fotograaf fotografie fotokopie fout fragment franchise fraude frequentie fruit ga Galaxy galerij gallon gang gangpad garage gast gat gazon gebaar gebed gebouw gebroken gebruiker gedenkteken gedicht geest geeuw gegijzeld geheugen gehoorzamen geit gekwalificeerd gekwetst geld gelei geleidelijke gelijkspel geluid geluk gelukkig gemalen gemeenschap gemiddeld geneeskunde genie geografie geologische gereedschap gerelateerde geschenk geschreven geslacht gesloten gesprek getrouwd getuige geur gevaar gevangene gevangenis gevel geweer gewelddadige geweten gewicht gezamenlijke gezicht gezond gezondheid giet giftig gitaar gladde glans glas gletsjer glijden glimlach gloed god goed goedkoop golf gooi goot gordijn goud graad graaf graan graf grafiek grap grappig gras gratis grens griep grijns grimas grind grip groeien groen groente groet grond grootmoeder grootvader grot grote haai haak haar haat habitat hak hal halfrond hamer hand handdoek handel handelaar handelen handicap handleiding handschoen handtekening hang hard hardware harmonie hart haven hedge heersen heet heilige hek heks hel held hele helikopter helm hemel herhaal herhaling herinneren herleven heroïne heropleving hersenen herstel hert heup heuvel historisch hoek hoest hond honkbal hoofd hoofdkantoor hoofdletter hoofdstuk hoog hoogte hooi hoor hoorn horizon horizontaal horror hotel houd hout huidige huilen huis huisdier huisje huisvrouw hurken hut huur huurder huwelijk hypnotiseren idee identificatie identificeer identiteit ijs ijzer illegaal immigrant immigratie importeer impuls incident indeling individuele industrieel infecteren infectie informatie ingenieur ingrediënt injecteer injectie inkomen inschrijving insect inspecteur instal instorten instructie instrument integratie intelligentie internationaal interview invasie inwoner inzet isolatie item jaar jaarlijks jacht jager jam jammer jas jazz jet jeugd jockey jonge jongen juist jungle junior jurk jury juweel kaak kaal kaars kaart kaas kabel kalender kalf kalkoen kamer kamerplant kamp kampioen kanaal kandidaat kanker kant kantoor kapitein kapsel karakter kast kasteel kathedraal katoen kauw keel kelder kerk kern kers ketting keuken kick kies kijk kikker kin kind kindertijd kip kist klagen klant klap klaslokaal klasse klassiek kleerkast klei kleren kleur kleurrijk kleverige klim kliniek klok kloof klop knal knie kniel knijp knik knoflook knoop knop koe koekje koelkast koepel koffie kolen kolom kolonie kom komedie komeet komkommer konijn koning koningin koninkrijk kooi kook koop koorts kop koper kopieer koppel korte korting kostuum koud kraam kras krijger krijt krimpen kristal kroon kruip kruis kruising kruk krul kudde kunstenaar kunstmatige kussen kust kwaliteit kwart kwekerij laat laatste label laboratorium lach ladder lade lading lagere lam lamp land landeigenaar landschap lang lange langzaam laser last ledemaat leef leeftijd leeg leer leerling lees leeuw leg legende leger leiderschap lek lekker lelie lelijk lengte lente lepel leraar les letsel letter leugen leuk lever leveren levering lezer lezing licentie lichaam licht lid lidmaatschap liefdadigheid liefde lift lijm lijn lijst lik limiet link links lint lip literatuur lobby locatie lodge log long lopen loper losse lounge lucht luchthaven luchtvaart luchtvaartmaatschappij luid luister lunch lus maag maagd maaltijd maan maand maart maat machine magere magnetische mail mainstream maïs make-up management mand manier marathon marine markeer marketing marmer mars marteling masker massa materiaal matroos mechanisch medaille meer meerdere meester meid meisje melk meneer menigte mens mensen mensheid menu merk mes metaal meubels microfoon middag middeleeuws midden middernacht mier mijl mijnwerker militaire mineraal minimaal minimaliseren minor minuut misbruik misdaad mislukking mobiel modder model moe moeder moer moeras mok mol moleculair mond monnik monopolie monster monsterlijke moord moordenaar morsen moskee motor motorwagen mouw mug muis multimedia munt museum muur muziek muzikant mythe naald naam nacht nachtmerrie nagel nakomelingen nat natuur natuurkunde nauwkeurige nederlaag neef nek nest netto netwerk neus nier nieuws niveau non nood noord notitieboek nucleair nul nummer observatie obstakel oceaan ochtend offer officier olie olifant omgeving omissie onderdrukken onderhoud onderkant ondersteuning onderstreep onderwijs onderzoek onderzoeker ondiep oneindig oneven ongemakkelijk ongeval onschuldige ontbijtgranen ontbinden ontdekking onthoof ontmoet ontploffen ontploffing ontsnappen ontvangst ontwerp onzin oog oogst oor oordeel oorlog oorzaak oost opdracht open opera operatie opgewonden oplossing opmerking opname opperhoofd oppervlakte opslag opsommingsteken optie oraal oranje orgel origineel orkest oude ouder outfit oven overdracht overeenkomst overheersing overheid overstroming overstuur overval overweeg overwinning overzicht paar paard pad paddenstoel pagina pak pakket paleis palm pan papier parade paragraaf parallel paraplu park parkeren partij partner partnerschap paspoort passage passagier past patent patroon pauze pen penny peper perforeer periode personeel persoon piano pier pijl pijn pijp pil piloot pinda pionier piramide pistool plaat plaats plafond plak plan planeet plank plant plastic platform plek ploeg plug poeder poëzie politiek poll pols pomp pompoen pony pool poort pop portret positieve post pot potlood presentatie president prijs prins prinses print printer privacy privilege procent producent produceren product productie productieve proef professor profiel programma projectie prooi propaganda proteïne protest psycholoog pub publiceer publiek pudding punch punt put puzzel race racisme radio raid raket rally rand rangschikking rapport ras rat reactie reactor rebel receptie rechte rechter rechtvaardigheid reclame record recycle redding reductie redundantie reeks reflectie regen regenboog regio regisseur register rehabilitatie reis rek rel relatie relax religieuze rem ren repetitie reproductie reptiel restaurant restjes resultaat reus rib richting riem rij rijk rijkdom rijst ring ritueel rivier rob robot rock roem rol roman romantisch rood rook royalty rug rugby ruimte rundvlees rust ruwe saaie salade saldo samenvatting samenzwering sandaal sap satelliet saus scan scène schade schaduw schakelaar schapen schat schattig schedel scheiding schema scheren scherm scherpe schets scheur schiet schikking schild schilder schip schoen schok schommel school schoon schoorsteen schoot schors schot schotel schouder schouderophalen schreeuw schrijf schrijver schuld score script sculptuur secretaris secundair seizoen seizoensgebonden seminar senior serie serveren service shell shift shirt sigaret sin site skate ski skribbl.rs slaaf slaap slaapkamer slachtoffer slagveld slak slam slang slechte sleep sleutel slijm slimme slip slopen slot sluier sluiten smakelijke smal smash smeken sneeuw snel snelheid snelweg snijd snijden snoer snuif soep software sok soldaat solide solo som somberheid soort soortgelijke speel speelgoed spek spel spell spiegel spier spin spinazie spion split spoorweg sport spray spreiding spreker sproet sprong spuug staan​​ staart stad staking stam standbeeld stap stapel start station steak steeg steek steen stem stempel sterk sterkte sterrenbeeld sterven stichting stick stijgen stijl stikken stilte stoel stof stok stom stoom stop storm storting straal straat strak straling strand stretch strijd string stro struik student studio stuiteren stuk subjectief succesvol suiker suite superieur supermarkt supervisor surround symmetrie systeem t-shirt taal taart tablet tafel taille tand tandarts tank tape tapijt tarief tarwe taxi team techniek technische technologie teef teen tegel tegen tegenover tegenstander tegenstrijdigheid tegenzin tegoed tegoedbon teken tekening tekort tekst tel telefoon televisie teller tempel temperatuur tennis tent terminal terras terrorist terug test theater therapeut therapie thumb tick ticket tiener tij tijd tijdschema tijdschrift tijger tin tip titel toast toepassing toerisme toernooi toespraak toevoeging tomaat ton tong toon top toren totaal touw trace track trainer training transparant trap trein trek trend trip troep trolley troon tropische truc trui tuimelen tuin tumor tunnel tweede twin tycoon ui uil uitbreiden uitbreiding uitdrukking uitgang uitgestorven uitlaat uitnodigen uitnodiging uitrusting uitvoerder uitvoering uitzending uniek uniform universiteit update urban urine uur vacht vacuüm vader vak vakantie vakman vallei vallen valuta van vang variant varken vat vechten veeg veel veer veerboot vegetatie veilig veilige veiling veld venster Venus ver verander verbaal verbeelding verbergen verbied verbinding verbrijzelen verdachte verdedig verdeel verdieping verdomde verdrinken verdwijnen verf vergadering vergelijk vergelijking vergif vergoeding vergroten verhouding verhuurder verjaardag verkeer verkeerd verkenning verkiezing verkoop verkoper verkrijg verlegen verliezen vermenigvuldig vermogen vernietiging veroordeelde verplaatsen verpleegster verrassing verre verschijnen verschil verschillen verschuldigd verse versie verslaafd verslaan verslaggever verspreid verticaal vertrek vervang vervanging vervoer vervuiling verwarring verzamel vestiging veteraan vezel video viering vierkant vijand villa vind vinger vis visie visser vitamine vlag vleermuis vlees vlek vleugel vlieg vlieger vliegtuig vliegtuigen vlinder vloeistof vloot vlucht voedsel voertuig voet voetbal voetgangers vogel voltooi volume volwassen voor voorganger voorhoofd voorraad voorspelbare vooruit vooruitzichten voorzitterschap vork vorm vos vouw vraag vracht vrachtwagen vragenlijst vreedzaam vreugde vriend vriendschap vroege vrouw vuile vuilnis vuist vul vulkaan vuur waardevolle waarnemer waarschuwing wachtrij wachtwoord wagen wakker walvis wandeling wang wapen warm warmte was water waterkoker waterval wederzijdse wedstrijd weduwe weefsel week weekend weer weergeven weerspiegelen weg wekelijks wenkbrauw wereld west wetenschap wetenschapper weven whisky wiel wiet wijn wilde wildernis willekeurige win wind winkel winkelen winkelwagen winnaar winter wiskunde wiskundig wit woede woestijn wol wolf wolk wond woord woordenboek worm worst worstelen wortel wraak wrak wrap x-ray yard zaad zaak zachte zak zakenman zaklamp zalm zanger zee zeep zeg zegel zegen zeil zelfmoord zelfs zelfverzekerd zet zicht ziek ziekenhuis ziekte ziel zijde zilver zing zinken zit zoek zoete zolder zomer zon zone zonne zonneschijn zonsopgang zorgen zout zuid zuivel zus zuur zuurstof zwaar zwaard zwaarlijvig zwaartekracht zwak zwakte zwanger zwart zweep zweer zweet zwembad zwemmen ================================================ FILE: internal/game/words/pl ================================================ Abraham Lincoln absolutny absolwent abstrakcyjny ac/dc adidas administracja administrator adopcja adoptować adres Afryka agencja agent agonia agresywny akademia akapit akcent akceptacja akcjonariusz akord akordeon aksamit aktor aktualizacja aktywność aktywny aktywo aktywować akumulacja akwarium alarm alarm przeciwpożarowy albatros album aleja alergia aligator alkohol Alladyn alpaka altówka aluminium amator ambasada ambicja ambitny ambulans Ameryka amputować Amsterdam anakonda analiza analogia ananas android Anglia animacja anime anioł ankieta anonimowy Antarktyka antylopa antywirus anubis anuluj aparat aparat fotograficzny apartament apatia apel apetyt aplikant apokalipsa arbitralny archeolog archeologiczny architekt architektura archiwum arena aresztowanie Argentyna argument arkusz armata armia arogancki artykuł artysta artystyczny arystokrata as asertywny aspekt Asterix asteroida astronauta asymetria atak Atlantyda atmosfera atom atomowy atrakcyjny audi audytor aukcja aureola Australia autobus autograf automatyczny autonomia autostopowicz autostrada awans awaria awokado Azja azyl babcia babeczka badacz badania bagaż bagażnik bagietka bagnet bagno bajgiel baklawa bakłażan balet baletnica balkon balon balsam bambi bambus banan bandana bandaż baner banjo bank bankier bar baran barbarzyńca bariera barman baseball basen bateria batman bawełna bazgroły bazooka bałagan bałwan bańka beatbox beczka Beethoven bekon belka beneficjent benzyna bezdomny bezpieczeństwo bezpieczny bezpośredni bezprzewodowy bezradny bezrobocie bezrobotny bezsenność bezużyteczny białko biały Biblia biblioteka bibliotekarz bicz biedny biedronka bieg biegacz bieżnia bieżący Big Ben bilard bilet bingo biografia biologia biskup bitcoin bitwa biuletyn biurko biuro biurokracja biurokratyczny biznes biznesmen bić blask blat stołu blizna bliźniak blokada drogi blokować blondynka bluszcz bmw bmx bobslej bochenek bocian bogactwo bogaty bohater boisko bolesny bomba borsuk borówka Boże Narodzenie brak brama bramkarz bransoletka brat bratanek Brazylia brać broda brodawka brokuły bronić browar brownie broń brudny brunetka brwi bryza bryła brzoskwinia brzoza brzuch brzydki brzytwa bródka brąz brązowy buda budzić się budżet bufet bum bumerang bunt buntownik burak burmistrz burrito bursztyn bury burza burza piaskowa but butelka buty bydło byk bzdury bóbr bóg ból ból pleców bęben błagać błahy błazen błogosławić błoto błysk błyskawica błąd cappuccino całkowity cały cebula cecha cegła cel celebracja celebryta cement cena cenny centaur centralny centrum centrum handlowe cenzura ceramika cerber ceremonia certyfikat chaos charakter charakterystyczny Charlie Chaplin charyzmatyczny chata chcieć chciwość cheerleaderka cheeseburger chemia chemiczny Chewbacca chihuahua chirurg chirurgia chleb chlew chmura chodnik cholera chomik choroba choroba morska Chorwacja chory chrom chronić chudy chusteczka chwast chwała chwyt chętny chłop chłopak chłopiec ciasny ciasteczko ciastko ciasto ciało ciekawy cielę ciemny cienki ciepło ciepły cierpienie cierpieć cierpliwość cień cień do powiek cios ciotka cisza ciągnik ciągnąć ciągły ciąża cięcie ciężarówka ciężki cmentarz cnota codziennie creeper cud cudzoziemiec cukier curry cyborg cyfrowy cykada cykl cylinder cyrk cytat cytryna cywilizacja czajnik czapka czarna dziura czarny czarny piątek czarodziej czas czasopismo czaszka czek czekać czekolada czerwony czerwony dywan czkawka czosnek czoło czubek czuć czułka czynnik czystość czysty czytać czytelnik cząsteczka cząstka częstotliwość częstość częsty część członek członkostwo człowiek córka dach daleki dalmatyńczyk daltonista dama danie darczyńca darmowy darowizna data dawać dawka dać debata debiut decydować decydujący deficyt definicja dekada deklaracja dekoracja dekoracyjny delegować delfin delikatny demokracja demon demonstracja demonstrować dentysta depozyt depresja deser deska deska surfingowa deskorolka deskorolkarz deszcz detaliczny detalista detektor detektyw detonować dezodorant diagnoza dialekt dialog diament dieta dinozaur dmuchać dno dobrobyt dobroczynność dobrowolny dobry dobrze doceniać dochód dodatek dodawać dojrzały dokument dokładny dolar dolina dom domek domek dla lalek domek na drzewie dominacja domino dominować dominujący domyślny dopasowanie dopasować dopuszczalny doradca dorosły doskonały dostarczać dostawa dostać dostęp dostępny dotyk dowód dowódca dozownik doświadczony drabina dracula dramat dramatyczny drapacz chmur drapać drapieżnik drażnić drewno drobiazg droga droga mleczna drogi drugi drukarka drukować drut kolczasty drwal dryf drzemka drzewo drzwi drżenie duch dudy duma dumny dusić dusza duży dwuznaczność dwuznaczny dwór dyktować dylemat dym dynamiczny dynamit dynia dyplom dyplomata dyplomatyczny dyrektor dyrygent dyscyplina dysk dyskoteka dyskretny dyskryminacja dyskryminacja utwór dyskurs dyspozycja dystrybuować dystrybutor dywan dywidenda dziadek dziadek do orzechów działanie dzicz dzieciak dziecinny dzieciństwo dziecko dziedzic dziedziczyć dzielić dzielnica dziennikarz dzierżawa dziewczyna dzień dzik dziki dziobak dziura dziwny dziób dzięcioł dzięki dziękować dzwon dzwonek dół dąb dług długi długopis długość dźgnąć dźwięk dźwiękowy dżem dżentelmen dżin dżinsy dżokej dżungla echo edukacja edukacyjny efekt efektywny Egipt ego egzamin egzotyczny Einstein ekonomia ekonomiczny ekonomista ekran ekscytujący Ekskalibur ekspert ekspertyza eksperyment eksperymentalny eksplozja eksport ekspozycja ekstremalny elastyczny elegancki elektorat elektron elektroniczny elektronika elektryczność elektryk element eliminować elitarny emerytowany emerytura emocja emocjonalny emoji empiryczny emu energia entuzjastyczny entuzjazm epoka kamienia era erozja esej esencja eskimos espresso estetyczny etniczny etyczny etyka etykieta Europa ewolucja fabryka fabuła facebook fajerwerk fajka fajny faks fakt fala fan fanta fantazja farba farmaceuta fasada fascynować fasola fałszywy federacja federalny feministka ferrari festiwal figurka fikcja Filar film filmowiec filozof filozofia filozoficzny filtr finanse finansowy firma fizyczny fizyka flaga flaming flet Floryda flota foka folder folia folklor fontanna forma formacja formalny format formuła formułować fort fortepian forum fotel fotograf fotografia fracht fragment Francja frustracja frytki fryzjer fundacja fundusz funkcja funkcjonalny funt futro gabinet gad gadatliwy galaktyka Gandalf ganek gang gangster garaż garderoba gardło garnek garnitur gatunek gaz gazeta gałązka gałąź gejzer gen generacja generator generować genetyczny geniusz geografia geologiczny gepard gest gigant gilotyna gitara gitara elektryczna gladiator gleba glina glut gniazdo gniew gnom goblin godność godzina golf golf wózek golić się Google goryl gorzki gorąca czekolada gorący gorączka gospoda gospodarka gospodarstwo gospodarz gospodyni domowa gotowanie gotować gotowy gotówka gołąb gościnność gość gra gra wideo grabarz grabie gracz graffiti gramatyka granat granica grant grawitacja Grecja grejpfrut grill grobowiec grosz groszek grotołaz gruby grupa gruszka grymas grypa grzbiet grzebień grzech grzeczność grzeczny grzmot grzyb grób gubernator guma guma balonowa guz gwarancja gwiazda gwiazda rocka gwiezdne wojny gwizdek gwóźdź góra lodowa górnik gówno gąbka gąsienica gęstość gęś gładki głodny głos głosić głosowanie głosować głowa głośność głośny głuchy głupek głupi głupiec głód główny głęboki hak haker hamak hamburger hamowanie handel harfa harmonia harmonijka harmonogram harpun hashtag hasło hawaje hałas hałaśliwy helikopter Hello Kitty herbata Herkules heroina hibernować hiena hierarchia hieroglif hipis hipnotyzować hipopotam hipoteza historia historyczny historyk hiszpania hobbit hokej hol Holandia Hollywood holownik homar honor honorowy hop horoskop horror horyzont hot dog hotel hołd hula hop humor huśtawka huśtać się hydrant hydraulik ideał identyfikacja identyfikować ideologia ignorancja ignorant ignorować igła Ikea ilościowy ilość ilustracja ilustrować imadło imigracja imigrant imperialny imperium implikacja imponować imponujący import impreza impuls incognito incydent indeks Indie indyk indywidualny inflacja informacja infrastruktura inicjatywa innowacja inny inspektor inspiracja inspirować instalować instrukcja instrument instynkt instytucja integracja integralność intelektualny inteligentny intencja intensyfikować intensywny interakcja interaktywny interfejs internet interpretować interwencja inwazja inwestycja inżynier ipad iphone Irlandia irokez ironia iskra iskry istotność istotny izolacja iść jabłko jacht jagnięcina jagoda jaguar jajko jak jakość jalapeno japonia jaskinia jaskiniowiec jaszczurka jazda jazz jednokołowiec jednomyślny jednorożec jednostka jedność jedwab jedzenie Jeep jeleń jelito jenga jezioro jeść jeździec jeździć jeż jeżozwierz jeżyna jo-jo jogurt jurysdykcja jądrowy jęk język kabel kabina kaczka Kaczor Donald kaktus kalafior kalendarz kalmar kalorie kameleon kamerdyner kamień kampania kanapka kanał kandydat kangur kanion kapać kapelusz kapitalizm kapitan kapitał kapłan kara karabin karaluch karaoke karate karać kariera karnawał karta karzeł kaseta kask kasyno kaszel kasztan katalog katana katapulta katastrofa katedra kategoria kaucja kawa kawałek kawiarnia kawior kazoo kałuża kciuk kebab kelner kemping ketchup kichnąć kieliszek do wina kierowca kierowca autobusu kierowca taksówki kierunek kieszeń kiełbasa kij kij od miotły kijanka kilof King Kong kino kiwi klamka klapnięcie klasa klasyka klasztor klatka klatka piersiowa klatka schodowa klaun klawiatura klej klej w sztyfcie klejnot klepsydra klient klimat klinika klopsik klub klucz klęczeć knykieć koala koalicja kobiecy kobieta kobra koc kod kod kreskowy kod morsea kogut kojot kokon kokos koktajl kolano kolba kolega kolej kolejka kolekcja koliber kolonia kolor kolorowy koloseum kolumna komar kombinacja komedia komentarz komercyjny kometa komfort komik komiks komin kominek komitet kompaktowy kompas kompensacja kompensować kompetencja kompetentny kompleksowy kompletny komplikacja kompozytor kompromis komputer komunikacja komunizm komórka koncentracja koncepcja koncept koncert koncesja konferencja konflikt konfrontacja kongres koniczyna koniec konik morski konik polny konkret konkurencja konkurs konsensus konserwacja konserwatywny konsolidować konspiracja konstelacja konstrukcja konstruktywny konstytucja konstytucyjny konsultacja konsument konsumpcja kontakt kontekst konto kontrakt kontrast kontrola kontroler kontrowersyjny kontynent kontynuacja konwencja konwencjonalny konwertować kooperacja kooperatywny kopalina kopalnia koparka kopać koperta kopiować kopnąć kopuła kopyto kora koral korek korek korekta korelacja korespondencja korkociąg korona koronka korporacyjny korupcja korytarz korzeń korzyść kosa kosiarka do trawy kostium kostium kąpielowy kostka kosz kosz na śmieci koszmar koszula koszulka koszyk koszykówka kot kotek kotły kowadło kowal kowboj koza koziorożec kołdra kołnierz koło koń kończyna końcówka kościół kość kość słoniowa krab kradzież kraj krajobraz krajowy krawat krawiec krawędź kreda kredyt kredyt hipoteczny krem krem do golenia kreskówka kret krew krewetka krok krokodyl kropki kropla kropla deszczu krowa krowa dzwonek krwawić krwawy krwotok z nosa krykiet kryształ krytyczny krytyk krytyka kryzys krzesło krzew krzyczeć krzyk krzywa Krzywa wieża w Pizie krzyż król Król Lew królestwo królewski królewskość króliczek królik królowa krótki krąg kręcić się kręgle kręgosłup kserokopia książka książę księgowy księżniczka księżyc ksylofon kształt kuba kubek Kubuś Puchatek kucanie kuchnia kucyk kucyk kukurydza kukułka kula kula ognia kultura kulturalny kung fu kupa kupidyn kupiec kura kurczak kurczyć się kurs kurtka kurz kusza kuweta kuzyn kuźnia kwadrat kwalifikacja kwalifikowany kwalifikować kwas kwaśny kwiaciarz kwiat kwota kąpiel kąsek kąt kłamać kłopot kłucie labirynt laboratorium lakier do włosów lalka lama lampa laptop las las deszczowy laser lasso latarka latarnia latarnia morska latawiec lato lawa laweta leczenie leczyć legenda lego lekarz lekcja lekkomyślny lemoniada lemur len lenistwo leniwy lepki lew lew morski lewy leśnictwo leżeć liberalny licencja liczba licznik lider lilia limonka limuzyna lina linia liniowy lis list lista listonosz literacki literatura lizać liść lodowiec lody lodówka logiczny logika logo lojalność lojalny lok lokalizacja lokator Londyn lornetka los losowy lot loteria lotnictwo lotnisko lud ludzie ludzkość lukier lupa lustro luźny lód lęk macierz macka Madagaskar mafia magazyn magia magiczna różdżka magik magma magnes magnetyczny majonez majątek mak makaron makijaż malarz malina malutki mamut manat mandarynka manekin manicure mapa marakas maraton marchewka margaryna margines marionetka marka marketing marmolada marmur mars marszczenie brwi martwy marynarka wojenna marynarz marzec masa masaż maska maska ​​gazowa maskotka maszt maszyna maszyna do szycia masło matematyczny matematyka materac materia materiał matka małpa mały małżeństwo McDonalds mdły meble mech mechaniczny mechanik mechanizm meczet medal meduza medycyna megafon melodia melon mem memorandum menedżer mentalny menu Mercedes metal meteoryt metoda metodologia metro mewa mgła miara miasto Microsoft miecz miecz świetlny miecznik miedź miejsce pracy miejscowość miejski miesiąc miesięczny mieszanka mieszać mieszkanie mieszkaniec mieć migdał migracja mikrofalówka mikrofon mikroskop mikser mikstura Minecraft minerał miniclip minigolf minimalizować minimum minister ministerstwo minivan minotaur minuta miotacz ognia miotła miska mistrz mit miód międzynarodowy mięsień mięso mięsożerca mięta miłosierdzie miłość miś pluszowy mleczarz mleczny mleko mnich mniejszość mniszek lekarski mobilny moc mocny mocz moda model modliszka modlitwa modlić się modny moduł mokry molo moment Mona Lisa monarcha monarchia moneta monopol mop morale moralny morderca morderstwo morela mors morski morze most motocykl motyl motyw motywacja Mount Everest mowa mozaika Mozart mrok mrowisko mrówka mrówkojad mucha muffinka multimedia mumia mundur murarz musical muszkiet muszla musztarda mutacja muzeum muzyk muzyka mydło myjnia samochodowa mysz Myszka Miki myć myśl myśleć myśliciel myśliwy mówca mówić mózg mądry mąka mąż mężczyzna młody młodzież młotek młyn nachos nachylenie nacisk nacjonalizm naczynie nadgarstek nadmiar nadużycie nadwaga nadzieja nadzorca nadzwyczajny naftalina nagi nagietek nagrobek nagroda nagrywanie nagrywać nagły nagłówek najnowszy nakaz naleganie nalegać naleśnik należeć należny nalot namiot namoczyć napad napaść napierśnik napisane napisać napięcie napompować naprawić naprężyć napój narodowość narodowy narty naruszenie narwal narzędzie NASA nasionko nastawienie nastolatek nastrój następny natura nauczyciel nauczyć się nauka naukowiec naukowy nawyk nazwa negatywny negocjacje Neptun nerka nerw nerwowy neutralny niebezpieczeństwo niebezpieczny niebieski niebo niedobór niedowaga niedźwiedź niedźwiedź polarny nieformalny niefortunny nieistotne niejasny nielegalny nieletni niemcy niemożliwy nienawidzić nienormalny nieobecność nieobecny nieoczekiwany niepewność niepełnosprawność niepełnosprawny nieporządek niepowodzenie nieprawdopodobny nieprzyjemny niesamowity niespodzianka niespokojny niespójny nieunikniony niewidzialny niewinny niewolnik niewygodny niewystarczający niezależny niezawodny niezbędny niezdolny niezgoda niezręczny nieśmiały nieświadomy nieść ninja niski niższy noc noga nogi nominacja nominować norma normalny nos nosorożec notatka notatnik Nowa Zelandia nowicjusz nowoczesny nowy nozdrza nożyczki nudny nurkowanie nurkować nuta nutella nóż nędza nędzny obcas obcy obecność obecny obejmować Obelix obfity obiad obieg obiekt obiektyw obiektywny obietnica objaw obliczanie obliczenia oblężenie obowiązek obraz obraźliwy obrażenie obrona obrus obrót obserwacja obserwator obszar obudzić się obwiniać obywatel obóz ocalały ocean ocena ocet ochrona ochroniarz oczekiwanie oczekiwać odbicie odbiór odbić się odchylenie odcień odcinek odczucie oddech oddychać oddział oddzielny odejść odkrycie odkryć odległość odległy odlew odmiana odmowa odmrożenie odmówić odpady odporny odpowiadać odpowiedź odpływ odrodzenie odrzucenie odrzucić odrzutowiec odstraszać odwaga odważny odwrócić odłożyć oferta ofiara oficer oficjalny ogień oglądać ognioodporny ognisko ogon ograniczenie ograniczony ograniczony ograniczyć ogrodnik ogrodzenie ogromny ogród ogólny ogórek ojciec okaz okazja oklaski okno oko okoliczność okop okres określony okropny okrągły okulary okulary przeciwsłoneczne okładka olej omlet opactwo opakowanie oparzenie oparzenie słoneczne opaska opaska na głowę opaska na oczy opera operacja opieka opinia opona opowieść oprogramowanie optymizm opuszczony opór opóźnienie opłacać opłata orangutan orbita orchidea organ organizacja organizować orientacja origami orka orkiestra orzech orzech laskowy orzech ziemny orzeł osa osioł osiągnięcie oskarżać oskarżenie osoba osobowość ostateczny ostatni ostrożny ostry ostry sos ostryga ostrze ostrzegać ostrzeżenie oszustwo osąd osłabiać otchłań otoczyć otwarty otwieracz do puszek otyły owad owalny owca owinąć owoc owoce morza ołtarz ołówek oś ośmiokąt ośmiornica ośrodek oświadczenie pacha pachnący pacjent paintball pająk pakiet pal palec palec u nogi paleta paliwo palma pamiętać pamięć pan młody pancernik panda panel panika panna młoda panowanie pantera papaja papier papieros papierowa torba papież paproć papuga papużka para parada paradoks paralizator parasol park parking parlament partner partnerstwo partyzant Paryż pas pasażer pasek pasek pasja pasta do zębów pastel pastwisko paszport pat patelnia patent patio patrol patrz patyk pauza paw pawian paznokieć paznokieć u nogi pałac pałeczki pchać pchnięcie pchła pedał peleryna pelikan pepperoni pepsi percepcja perforować perfumy personel perspektywy peruka peryskop petarda pewność pewny pełnia piasek piaskownica Picasso piec pieczęć pieg piegi piekarnia piekarnik piekło pieluszka pielęgniarka pieniądze pieprz pierwszy pierś pierścień pies pieszy pijawka piknik pilnik do paznokci pilność pilot pinball pingwin pinokio pionowy piramida pirat pisarz pistacja pistolet piwnica piwo pizza piórnik pióro piękny pięść piła łańcuchowa piłka piłka nożna piżama plac zabaw plakat plama plan planeta plaster miodu plastik platforma plaża plecak plecy plemię plik plon plotka pluskwa pluton pluć pocałunek pochodnia pochwała pochówek pocierać pocisk pociąg poczta pocztówka początek podatek podejrzany podekscytowany podnieść podnoszenie podobny podpis podróż podróżnik podstawa podstawowy podsumowanie podsłuchiwać poduszka poduszkowiec podwójny podwórko podział podziemny podziw podziwiać podłoga poezja pogarda pogardzać pogoda pogrzeb pojawiać się pojazd pojedynczy pojedynek pojemnik pokaz pokojówka pokrewieństwo pokrywka pokusa pokój pokój pole pole bitwy pole kukurydzy polegać policjant policzek policzki polityczny polityk polityka polowanie polski pomarańczowy pomidor pomnik pomoc pomocny pomocy pompa pomysł poniedziałek poniżej popcorn popiół popołudnie poprawa poprawiać poprawka poprzednik poprzedzać populacja popularny popyt pora snu porada porażka porcja port portal portret poruszanie się porzucić porządek porównanie poręczny Posejdon posiłek postęp poszerzyć posłuszny pot potknięcie się potomstwo potworny potwór poważny powiadomienie powiedz powiedzieć powiernik powierzchnia powietrze powieść powitanie powiązane powiązać powiększać powolny powrót powstrzymać powtórzenie powtórzyć powód powódź powóz pozaziemski poziom poziomy pozostać pozwolenie pozwól pozycja pozytywny połknąć połowa południe połysk połączenie połączyć pościg pośladki poślizg poświęcać pożyczka pożyczyć pożądany praca pracodawca pracownik pragnienie praktyczny praktyka pralnia prawda prawdopodobieństwo prawdziwy prawnik prawo precedens precel precyzja precyzyjny premia presja prezent prezentacja prezydent priorytet problem proca procedura procent proces proces sądowy producent produkcja produkować produkt profesjonalny profesor profil prognoza program programista projekcja projekt projektant projektant mody prom promieniowanie proporcja propozycja prospekt prostokąt prostota prosty proszek proszę protest prowadzić prowokować prośba pryszcz prysznic prywatność prywatny pryzmat przebranie przebudzony przeciek przeciwnik przeciwny przeciwstawić się przecięcie przeciętny przedmieście przedmiot przedstawiciel przedszkole przedwczesny przedłużony przegląd przegrany przegrać przejście przekaz przekonać przekonywać przekraczać przekształcenie przekątna przemoc przemysł przemyślany przenikać przenośny przeoczyć przepis przepraszam przeprosiny przepustka przerażać przerwa przerwać przestraszyć przestraszyć się przestrzeń przestępca przestępstwo przesunięcie przesuwać przeszkadzać przeszkoda przeszłość przetrwanie przewidywalny przewinąć przewlekły przewoźnik przewrót przewód przezroczysty przełożony przełącznik prześcieradło prześwit przybij piątkę przychylność przycinać przycisk przyciąganie przyciągnąć przyczepa przyczyna przydatny przydział przygnębiony przygoda przygotowanie przyjaciel przyjazny przyjaźń przyjemność przyjemny przyjąć przyjęcie przykład przynieść przypadek przypisanie przypomnieć przyprawa przypływ przyroda przysięgać przystanek autobusowy przyszłość przytulać przytulać się przytłoczyć przywilej przywiązanie przywrócenie przywództwo przyznać przyłączyć przód próba próbka próg próżnia próżny psycholog psychologia pszczoła pszenica ptak publiczność publiczny publikacja publikować pudel pudełko pudełko zapałek pukać puma punkt pustelnik pusty pustynia puszka puzon pułapka pułapka na myszy pytanie półka półkole półkula północ półwysep późny pęcznieć pęd pędzel pęknięcie pępek pętla płaca płacz płaski płaszcz płaszcz przeciwdeszczowy płaszczka płatek płatek śniegu płatki kukurydziane płatność płać płuco pług płyn płyn płyta płytka płytki pływać płótno rabat rabować rabunek rachunek racjonalny rada radar radio radość radykalny rafa koralowa rafika rajd rak rakieta rakieta tenisowa ramię ramka ramka na zdjęcia rampa rana ranga rano raport ratunek rdzeń reakcja reaktor realistyczny realizm recepcjonista recesja recykling redukcja reflektor reforma refren region regionalny regulacja regularny rehabilitacja rejestracja rejs rekin reklama relacja relaksacja religia religijny remiza strażacka renifer rentgenowski reporter republika reputacja restauracja reszta resztki retoryka rewolucja rewolucyjny rewolwer rezerwa rezydent rezygnacja robak robin Robin Hood robot robotnik rocznica rocznik rodzaj rodzic rodzice rodzina rodzynka rogalik rok rola rolnictwo rolniczy rolnik romans romantyczny ropucha rosa Rosja rosomak rotacja rower rozbić rozcieńczyć rozciągać rozczarowanie rozczarować rozdymka rozdział rozdzielić rozgwiazda rozkwitać rozkład rozkład jazdy rozlewać rozmiar rozmnażanie rozmnożyć rozmowa rozpacz rozpoznanie rozpoznać rozprzestrzeniać się rozpuścić rozrzucenie rozszerzenie rozszerzyć rozsądny rozum rozumienie rozumieć rozważanie rozważać rozwijać rozwiązanie rozwiązać rozwód rozwój roślina roślina doniczkowa roślinność rtęć rubin ruch ruina rumieniec rura rutyna ryba ryba błazenek rybak rycerz ryk rynek rynna rysik rysować rysownik rysunek rytm rytuał ryś ryż rzadki rzeczy rzeczywistość rzeka rzemieślnik rzepa rzeźba rzeźbić rzodkiewka rzut Rzym rząd rzęsy róg rój równanie równik równoległy równowaga równy róża różnica różnić się różowy ręcznik ręka rękaw rękawica rękodzieło rękopis safari saksofon salon samochód samodzielny samolot samorodek samotny sandał sanki sanktuarium satelita Saturn sauna sałata sałatka scena scena scenariusz schemat schludny schronienie sekcja sekretarz sektor sekwencja seminarium sen sens separacja ser serce seria sernik serwer serwetka sesja sezon Sfinks Sherlock Holmes Shrek siano siarka siatka siatkówka siać siedlisko siedzenie siedzieć siekać siekiera sieć silnik silny silos siniak siodło siostra siła siła woli skakanka skala skarb skarbnik skarbonka skarpetka skarpetki skała skierowanie sklep sklep zoologiczny skok skok na bungee skok w tył skoki ze spadochronem skorupa skończony skromny skrypt skrzat skrzydło skrzynia skrzynka pocztowa skrzynka z narzędziami skrzypce skrzyżowanie skrócić skręt skunks skupić skurcz skuteczny skuter wodny skóra składnik smaczny smak smok smoking smutek smutny smycz snajper snowboard sojusznik sok solidarność solidny sombrero sondaż sopel lodu sopran sos sosna sowa spacer spadek spadochron spaghetti sparaliżowany spawacz specjalista Spiderman spirala spisek spodnie spojrzenie spojrzenie spokojny spokój spontaniczny sport sportowiec spostrzeżenie sposób spotkanie społeczeństwo społeczność spragniony sprawiedliwość sprawność spray sprzeciw sprzeczność sprzeczny sprzedaj sprzedawca sprzedaż sprzyjający sprzęt sprężysty spychacz spódnica spójny spór spłukiwanie srebro stabilny stacja stadion stado stal standard starszy start stary statek kosmiczny statek piracki statua Statua Wolności statystyczny statyw staw stać stały stegozaur stek stereo sterowiec steward stewardesa stodoła stoisko stojak stokrotka stolarz stonoga stop stopa stopień stopniowy stos stowarzyszenie stołek stożek strach strach na wróble straszny strata strategiczny strażak strażnik strefa stres stromy strona strona internetowa struktura strumień struś strych strzał strzałka strzelać strzelba strzyżenie strój student studia studio stuknięcie stymulacja stypendium stół substancja suchy sudoku sufit sugerować sugestia sukces sukienka suknia sum suma sumienie Superman supermarket supermoc surowy surykatka sushi susza sweter syczenie sylaba symbol symetria symfonia sympatyczny sypialnia syrena system szachy szacować szacunek szafka szalik szampan szampon szansa szantaż szarlotka szczególny szczegół szczelina szczepionka szczoteczka do zębów szczotka do włosów szczupak szczupły szczur szczyt szczyt szczęka szczęście szczęśliwy szef kuchni szelki szept szerokość sześciokąt sześciopak szkic szkielet Szkocja szkoda szkodliwy szkodnik szkoła szkło szlachetny szmaragd szminka sznur sznurek sznurowadło szop szopa szorstki szorty szpatułka szpieg szpilka szpinak szpital szpon szpula sztuczka sztuczka magiczna sztuczne zęby sztuka sztylet szufelka szukaj szyba przednia szybki szybkość szybować szyja szympans szynka szynszyla szyszka szyć sól sąd sądowy sąsiad sąsiedztwo sędzia sęp słabnąć słabość słaby sława sławny słodki słoik słoma słonecznik słoneczny słownik słowo słoń słońce słuchawki słuchawki douszne słuchać sługa słup służyć słyszeć t-rex tablet tabletka taca taczka tajny taksówka taksówkarz talerz talia tani taniec tapeta tarantula taras tarcza Tarzan tatuaż taśma taśma klejąca teatr techniczny technika technologia tekst tekstura teksty tektura telefon telefon komórkowy teleskop telewizja temat temperatura temperówka tempo tenis tenis stołowy teoria terapeuta terapia teren termin termometr terrorysta test tetris teza tiramisu titanic tkanina tkać tlen toaleta toast toczyć toksyczny tona topienie torba tornado torpeda toster totem towarzyski towarzyszyć tożsamość tradycja tradycyjny tragedia trakt traktat transakcja transfer transmisja transport trasa tratwa trawa trawnik trend trener trening treść trofeum trojaczki tron tropikalny trucizna trudności trudność trudny trujący trumna trup truskawka trzask trzcina trzepaczka trzymanie trzęsienie ziemi trójkołowiec trójkąt trąbka tuba tubylczy tukan tunel turniej turysta turystyka tuzin twardy twarz twierdza twierdzenie tworzenie tworzyć tydzień tygiel tygodniowy tygrys tykać tynk typ typowy tyrolka tytuł tył tęcza tło tłok tłum tłumaczyć tłumić ubezpieczenie ubezpieczyć ubieranie się ubrania ucho uchwyt ucieczka uczciwy uczestniczyć uczestnik uczeń uczony uczta uczucie udany uderzenie udo udowodnić udział ufo ugniatać ugoda ugryźć ujawnić ukryć ukulele układ układ słoneczny ul ulepszenie ulga ulica ulotka ulubiony ulżyć umiejętność umowa umrzeć umysł unikalny unikać uniwersalny uniwersytet unosić się upadek upadłość uparty upierać się uporczywy upoważnić uprawnienie uprawniony uprzedzenie uprzywilejowany uroczy urodziny urok uruchomienie urzekać urządzenie urzędnik USB usprawiedliwić usta ustalenie ustalić ustanowiony ustanowić ustawodawca ustawodawczy ustawodawstwo ustny usunąć uszkodzenie usługa utalentowany utopić utrzymać uwaga uwolnić uzależnienie uzależniony uzasadnienie uzupełniający uzyskać ułamek uścisk dłoni uśmiech użytkownik używać van voucher wada wadliwy wafel waga wagon wahadło wahać się wakacje walizka walka walka na pięści walka na poduszki walka na śnieżki waluta wampir wanilia wanna warga wariacja wariant warstwa warsztat wartość warunek warzywo wata cukrowa wał wałek do włosów ważka ważny wchodzić wchłonąć wczesny wdowa wdzięczny weekend wegetarianin wektor welon wentylacja wentylator sufitowy werdykt wersja wesoły weteran weterynarz wewnątrz wewnętrzny wełna wiadomości wiadomość wiadro wiara wiarygodność wiatr wiatrak widelec wideo widmo widoczny widok widły wieczny wieczór wiedza wiedzieć wiedźma wiejski wiek wielbłąd wielkanoc wielki wielkość wieloryb wieniec wierny wiersz wiertło wierzba wieszak wiewiórka wieś wieża Wieża Eiffla wilk wilkołak willa wina winda wino winogrona winorośl wiolonczela wiosna wiosło wir wirus witamina wizja wizyta wiązać większość więzienie więzień wiśnia wkład wniosek woda wodorosty wodospad wojna wojownik wojskowy wola wolność wolontariusz wosk woskowina wołowina woźny wpis wprowadzenie wprowadzić wpływ wpływać wrak wrażliwość wrażliwy wrażliwy wrogi wrogość wrona wrzód wróg wróżka wschód słońca wsiadać wskazówka wskaźnik wspaniały wsparcie wspierać wspinać się wspornik wspólny współczesny współpracować wstawić wstrzyknięcie wstrzyknąć wstrząs wstyd wstążka wszechświat wtórny wujek wulkan wybaczyć wybielacz wybierać wyborca wybory wybredny wybrzeże wybrzuszenie wybuch wybór wycierać wycięcie wycofanie wycofać wycofać się wydanie wydatek wydawać wydawać się wydawca wydawnictwo wydra wydzielina wygląd wygnanie wygoda wygodny wygrać wyjaśnienie wyjaśnić wyjątek wyjście wykałaczka wykluczać wykop wykres wykwalifikowany wykład wylewać wylot wymaganie wymagać wymarły wymiana wymiar wymiotować wymię wymowny wynajem wynalazek wynik wyobraźnia wypadek wyparować wypełnij wyprawa wyprostować wyrazić wyraźny wyrwać wyróżnienie wysiłek wysoki wysokie obcasy wysokość wyspa wystawa występ wytrzymywać wytyczne wywiad wyznaczać wyznaczenie wyznanie wyzwalacz wyzwanie wyłączny wyślij wyświetlać wzajemny wzdychanie względny wzgórze wzmacniać wzmianka wzmocnić wzrok wzrost wzruszenie ramion wzór wódz wóz wóz strażacki wóz z lodami wózek wózek sklepowy wąchać wąski wąsy wątek wątpliwość wątroba wąż wędrować wędrówka węgiel węgorz węzeł władca władza włamywacz własność właz właściciel właściwy włochaty Włochy włosy włosy w nosie włożyć włócznia włókno wściekłość Yeti Yoda youtube zaakceptować zaangażowanie zabawa zabawka zabawny zabić zabójca zachodni zachowanie zachować zachowywać się zachwyć zachód zachęcający zachęcać zachęta zaczynać zadanie zadowalający zadowolenie zadowolony zadziwiający zadzwoń zagrozić zagrożenie zagubiony zagłówek zainteresowanie zajmować zajęcie zajęty zakaz zakazać zakażenie zaklęcie zakonnica zakończ zakres zakupy zakładać zakładka zakładnik zakłopotanie zakłócenie zalecenie zaleganie zalegać zaleta zależeć zależność zależny zamek zamek błyskawiczny zamek z piasku zamiatać zamieszanie zamieszki zamieć zamknięty zamknąć zamrażanie zamrażarka zamrożony zaniechanie zanieczyszczenie zaniedbanie zanurzyć zaopatrywać zapach zapadnia zapalenie płuc zapalniczka zapas zapasowy zapasy zapałka zapaśnik zapaść zapewniać zapewnienie zapewnić zapisz zapobiegać zapomnieć zapowiedź zaprosić zaproszenie zaprzeczenie zaprzeczyć zapytać zaraza zarażać zarejestrować zarodek zarodnik zarys zarządzanie zasada zasięg zaskakujący zaskoczony zastąpić zastępca zastępczy zasób zasłona zasługa zasługiwać zatoka zatrudniać zatrudnienie zatrzymanie zatrzymać zatwierdzać zatwierdzenie zaufanie zawierać zawiesić zawodowy zawroty głowy zawstydzony zawód zazdrosny zaćmienie założenie zbawienie zbieg okoliczności zbierać zbiornik zbroja zdalny zdanie zdarzyć się zdefiniować zdenerwowany zderzak zdesperowany zdjąć zdobyć zdolność zdolny zdradzić zdrowie zdrowy zebra zegar zejście zemsta zepsuć zespół zestaw zestaw perkusyjny Zeus zewnętrzny zgadnij zgiąć zgniły zgoda zgodny zgodzić się zgromadzenie ziarno zielony Ziemia ziemia ziemniak ziewnięcie zima zimno zintegrowany zioło zjawisko zlew zlokalizować zmarszczka zmartwienie zmiana zmienna zmniejszenie zmęczony znaczenie znaczny znaczący znajdź znajomość znajomy znak znak stopu zniechęcać zniekształcać zniekształcenie znieść znikać zniszczenie zniszczyć zombie zoo zorza polarna zostawić zraniony zranić zraszacz zrelaksować się zrezygnować zrozumieć zrzut zrzędliwy zrównoważony zróżnicowany zręczność zszywacz zupa zwiedzać zwierzę zwierzę domowe zwinny związek zwlekanie zwolnienie zwycięstwo zwycięzca zwykły zygzak zysk zyski ząb złamane serce złamany złoczyńca złodziej złom złota rybka złote jabłko złote jajko złoto złoty łańcuch złośliwość złośliwy złośnica złożony złożyć złudzenie zły ćma ćwiartka ćwiczyć łabędź ładny ładowanie ładowarka ładować łagodny łamigłówka łapa łapać łasica łaska łaskotać łatka łatwy ławka łazienka łańcuch łobuz łodyga łodyga fasoli łokieć łom łopata łosoś łoś łucznik łuk łup łuska orzecha łyk łysy łyżeczka do herbaty łyżka łyżwa łyżwy łza łódź łódź podwodna łóżko łóżko piętrowe łąka Święty Mikołaj ściana ścieżka ścisk ścisły ściąć ślad śledzić śledztwo ślepy ślimak ślina ślinić się śliski ślizg ślizgać się ślub śluz śmiały śmiech śmieci śmiertelny śmierć śmieszny śniadanie śnieg śnieżka śpiewak śpiewać śpiący śpiączka średni średnica średniowieczny środki środowisko środowiskowy śruba świadczyć świadek świadomość świadomy świat światło światło dzienne światło słoneczne świeca świecić świecki świetlik świeży świnia świstak świątynia święto świętować święty źle źródło żaba żabka żagiel żaglówka żart żartowniś żarówka żałoba żałować żebro żelazo żniwo żona żonaty żonglowanie żołnierz żołądek żołądź żuk żuć żwir życie żyrafa żyrandol żywopłot żywotny żywy żyć żyła żółtko żółty żółw żądło żłobek ================================================ FILE: internal/game/words/ru ================================================ абзац абонент авария авиакомпания авиация автобус автограф автомат автомашина авторитет агент агентство агрегат агрессия ад адаптация адвокат администратор адмирал азарт академик академия актив активность актриса акцент акционер алгоритм алкоголь аллея алмаз альбом альтернатива алюминий амбиция американец аналитик аналог аналогия ангел англичанин анекдот анкета ансамбль антитело аплодисменты апостол аппаратура аппетит аптека араб аргумент арена аренда арест арка армянин аромат арсенал артиллерия артистка архив архиепископ архитектор архитектура аспект ассортимент ассоциация асфальт атака атмосфера атом атрибут аудитория аукцион афиша аэродром аэропорт бабка бабочка багаж багажник базар бак бал баланс балет балкон балл банда бандит банка банкет банкир банкротство баня бар барабан барак барон барышня барьер бас бассейн батальон батарея батюшка башка башня бег бегство беда бедность бедро бедствие беженец бездна безобразие безработица безумие белка белок белье бензин береза беременность бес бесконечность беспокойство беспорядок бетон бешенство библиотека библия бизнесмен билет бинокль биография биология биржа битва благо благодарность благодать благополучие благословение бланк блеск близкие близнец близость блин блок блокнот блондинка блюдо богатство богатырь богослужение боевик боеприпас боец бок бокал бокс болельщик болото большевик бомба бомж бор борец борода борт босс ботинок бочка боярин брак братец братство бревно бред бремя бригада бригадир бровь брюки брюхо будка буква букет бульвар бульон бумажка бунт буря бутерброд буфет бухгалтер бык быт бытие бюллетень бюро вагон важность ваза вакцина вал валенок валюта ванна ванная варенье вахта введение ввод вдова вдохновение ведение ведомство ведро ведущий ведьма веко вектор величество величие величина велосипед вена веранда верблюд веревка верность вероятность версия верста вертикаль вертолет верующий верх верхушка вершина вес веселье вестибюль весть весы ветвь ветеран ветерок ветка вечеринка вечность вещество взаимодействие взаимоотношения взаимосвязь взвод вздох взлет взнос взор взрослый взрыв взыскание взятка видение видимость виза визг визит вилка вилла вина виноград винтовка виски висок витамин витрина вице-президент вице-премьер вклад включение вкус влага владелец владение владыка вложение вмешательство внедрение внесение внешность внук внучка водитель водоем военнослужащий военный вождь возбуждение возврат возвращение воздействие возмещение возмущение вознаграждение возникновение возражение возрождение воин вой вокзал волк волнение волокно воображение вооружение воплощение вопль вор воробей ворона ворот ворота воротник воскресение воскресенье воспитание восприятие воспроизводство восстание восстановление восток восторг восхищение вращение вред всадник вселенная всплеск вспышка вступление вторжение вторник вуз вход выброс вывеска выгода выдача выделение выдержка выдумка выезд выживание вызов выигрыш выпивка выплата выполнение выпуск выпускник выработка вырост выручка высказывание выстрел выступ выступление выходной вышка выявление гад гадость газон галактика галерея галстук гамма гараж гарантия гармония гастроли гвардия гвоздь гектар ген гений геном генштаб география гепатит героиня гибель гигант гимн гимназия гимнастерка гипотеза гитара глагол глазок глина глоток глупость гнев гнездо го гол головка голод голосование голубь гонка гонорар гонщик гордость горе горечь горизонт горка горло городок горожанин горшок госпиталь господь госпожа гостиная гостиница государь готовность град градус гражданство грамм грамота граната грань граф график гребень грек грех гриб грипп гроб гроза гром грохот груда груз грузин грузовик грунт группировка грусть груша грязь губернатор губерния гудок гул гусеница гусь давление давность даль дальнейшее дальность дар дата дверца двигатель дворец дворник дева девица девка девчонка дедушка дежурный дежурство действительность декларация декорация делегация деление демократ демократия демон демонстрация департамент депрессия держава дерьмо десятилетие десятка деталь детектив дефект дефицит деяние деятель джаз джинсы джип диагноз диагностика диалог диаметр диапазон диван дивизион дивизия дизайн дизайнер дилер динамика динамо диплом дипломат дирекция дирижер диск дискуссия диссертация дистанция дисциплина дитя длина дневник дно добавка добро доброта добыча доверие довод догадка договоренность доза доказательство доклад доктрина документация должник должное долина домик дон донос дополнение допрос дорожка досада доска доставка достижение достоверность достоинство достояние доступ доцент дочка драка дракон драма драматург древесина древность дрова дрожь дружба дружка дружок дрянь дуб дуга дура дурак духи душ дым дыра дырка дыхание дьявол дядька евангелие евро европеец еда единица единство ежик езда елка ель емкость епархия епископ ерунда жажда жалоба жалость жанр жар жара желающий железа железо желудок жених жертва жест жестокость живопись живот жидкость жилец жилище жилье жир жительство жук жюри забава заблуждение заболевание забор забота заведение завершение завет завещание зависть завтрак загадка заговор заготовка загрязнение зад задание задержка задница задолженность заем зажигалка заказ заказчик закат заклинание заключение заключенный законность законодатель закономерность законопроект закрытие закупка закуска залив залог заложник залп зам замена заметка замечание замок замысел занавес занавеска занятость запас записка запись заповедь запрет запрос запуск заработок заражение заросль зарплата заря заряд заслуга застолье застройка затея затрата затылок захват защитник заявитель заявка заяц звание звездочка звено зверь звон звонок звучание здравоохранение зелень землетрясение земляк землянка зеркало зерно зло злоба злость змей змея знакомство знакомый знаменитость знамя знаток значимость значок золото зонтик зоопарк зрелище зять игла игрок игрушка идеал идентификация идеология идиот иерархия изба избиратель избыток известность изготовление издание издатель издательство изделие издержки изложение излучение измена измерение изображение изобретатель изобретение изоляция изумление изучение изъятие икона икра ил иллюзия иллюстрация имидж иммунитет император империя импорт импульс инвалид инвестиция инвестор индеец индекс индивид индивидуальность индустрия инерция инженер инициатива инициатор иномарка иностранец инспектор инспекция инстанция инстинкт инструктор инструкция инструмент интеграция интеллект интеллигент интеллигенция интенсивность интервал интервью интернет интерпретация интерьер интонация интрига интуиция инфаркт инфекция инфляция инфраструктура инцидент ирония иск исключение ископаемое искра ислам исповедь исполнитель испуг испытание исследователь истерика истец истина исток историк истребитель исход исчезновение итальянец июль кабина каблук кавалер кадр казак казарма казино казнь календарь калитка камера камин кампания канал кандидат кандидатура каникулы канон канцелярия капитал капитализм капля капуста карандаш картинка картофель карточка картошка карьера касса кассета кастрюля каталог катание катастрофа категория катер кафе кафедра каша каюта квадрат квалификация квартал квота кепка килограмм километр кинематограф кинотеатр киоск кипяток кирпич кислород кислота кисть кит китаец кишка кладбище клапан классик классика классификация клей климат клиника кличка клок клоун клочок ключ клятва книжка кнопка княгиня ковер код коза козел койка колбаса колебание коленка колесо коллегия колледж коллектив коллекция колодец колокол колония колонка колонна колхоз колхозник кольцо коляска ком командировка командование командующий комар комбайн комбинат комбинация комедия комендант комиссар комментарий коммерсант коммунизм коммуникация коммунист комнатка компенсация компетенция комплект комплимент композитор композиция компонент компромисс компьютер комсомол комсомолец комфорт конвейер конвенция конверт конгресс конек конкурент конкурентоспособность конкуренция конкурс консерватория консервы конституция конструктор конструкция консультант консультация контакт контейнер контекст континент контора контракт контур конференция конфета конфликт концентрация концепция концерн кончик кончина конь коньяк конюшня кооператив координата координация копейка копия копыто кора корень корзина корм коробка коробочка корова королева король корпорация корпус корреспондент коррупция корточки коса косметика космонавт космос костер косточка кость кот котел котелок котенок котлета кофе кошелек кошка кошмар коэффициент крайность кран красавец красавица краска крах кредит кредитование кредитор крем крепость крест крестьянин кривая кризис крик кристалл критерий критик критика крокодил кролик крона крошка кружка кружок крыло крыльцо крыса крышка крючок кубок кузов кукла кулак кулиса культ кумир купе купец купол купюра курица курорт курсант куртка кусок кусочек куст кустарник куча кучка лаборатория лавка лавочка лад лак лампа лампочка ландшафт лапа лапка ларек ласка лауреат лебедь лев легенда легкое легкость лед леди лезвие лейтенант лекарство лекция лен лента летчик лечение лига лик ликвидация лимон липа листва листок листочек литератор литр литургия лифт лихорадка лицензия лишение лоб ловушка логика логистика лодка ложа ложка ложь лозунг локомотив локоть лопасть лопата лопатка лорд луг лужа лук луна луч лыжа льгота любитель любовник любовница любопытство люк лягушка маг магия магнитофон мадам майка майор максимум малыш мальчишка мамаша мамочка маневр манеж манера марка марш маршал маршрут маска масло массив мастерская мастерство масштаб мат математик математика материя матрица матрос матушка матч машинка мгновение мебель мед медаль медведь медик медицина медсестра медь мелодия мелочь мельница мемуары менеджер менеджмент мент меньшинство меню мерка мероприятие мерседес мертвый местечко местность месторождение месть металл металлургия метафора методика методология метро мех механик механика меч мечта мешок миг миграция микрофон милиционер миллиард милосердие милость мина минимум минус мировоззрение миска миссия мистер митинг митрополит миф младенец могила мода моделирование модернизация модификация модуль молекула молитва молния молодежь молодец молодость молоко молоток молчание монастырь монах монета мониторинг монография монолог монополия монтаж мораль морда мороженое мороз морщина моряк москвич мост мостик мостовая мотив мотивация мотор мотоцикл моча мощи мощность мощь мрак мудрость мужество муза музыкант мука мундир муравей мусор мусульманин муха мыло мыслитель мышка мышление мышца мышь мэр мэрия мясо мяч набережная наблюдатель наблюдение набор навык награда нагрузка надежность надзор надпись назначение наименование наказание накопление налет налогообложение налогоплательщик наложение намек намерение нападение напиток направленность напряжение напряженность нарком наркоман наркотик нары наряд насаждение насекомое насилие наслаждение наследие наследник наследство насмешка насос наставник настоящее наступление натура находка нахождение национальность нация начальство невеста невозможность негодяй негр недвижимость недоверие недовольство недостаток недоумение недра нежность независимость незнакомец ненависть неожиданность неопределенность неправда неприязнь неприятность нерв несправедливость несчастье нетерпение неудача нефть нехватка низ нитка нить ниша нищета нищий новинка новичок новое новость ноготь нож ножка ноздря ноль нора норматив носитель носок нота ноябрь нрав нравственность нужда нуль обаяние обвинение обвиняемый обед обезьяна обещание обзор обида обилие обитатель обитель обком обладатель облако облегчение облигация облик обложка обломок обман обмен обморок обнаружение обновление обобщение обозначение обои оболочка оборона оборот обоснование обочина обработка обращение обрыв обрывок обряд обследование обслуживание обстановка обсуждение обувь обучение обход общее общежитие общение общественность община общность объединение объявление объяснение объятие обыватель обыск обычай обязательство овощи овраг овца оговорка огонек огород ограда ограничение огурец одеяло одиночество одиночка одобрение ожидание озеро оказание океан оклад око окончание окоп окошко окраина окраска окрестность округ окружающее окружение окурок олень олигарх олимпиада опасение опасность опера оператор описание оплата опора оппозиция оппонент оправдание опрос оптимизация оптимизм орбита организатор орден орел орех оригинал ориентация ориентир оркестр орудие освещение освобождение освоение осколок оскорбление осмотр основатель основное особа особняк осознание остановка остаток осторожность острота осужденный осуществление ось отбор отверстие ответчик отвращение отдельность отдых отель отечество отзыв отказ отклик отклонение откровение открытие открытка отмена отметка отопление отпечаток отпуск отражение отрезок отрывок отряд отставка отступление оттенок отходы отчаяние отчество отчет отчетность отъезд офис официант оформление охота охотник охранник очаг очерк очертание очистка очки очко павильон падение пакет палата палатка палач палка палочка палуба пальма пальто пальчик памятник пан панель паника папироса папка пар парад парадокс параметр парк парламент паровоз пароход парочка парта партизан партнер партнерство парус паспорт пассаж пассажир пасть патриарх патриот патриотизм патрон пауза паутина пафос пацан пациент пачка певец певица педагог пейзаж пена пение пенсионер пенсия пепел первенство первое перевод переводчик перевозка переворот переговоры перегородка передвижение переезд переживание перекресток перелом перемена перемещение перенос переписка перепись переработка перерыв пересмотр перестройка переулок перец перечень перила перо перрон персона персонаж персонал перспектива перчатка пес песенка песнь песок петля петух пехота печаль печать печень печка печь пещера пиво пиджак пик пилот пионер пир пирамида пират пирог пирожок писание пистолет питание пища плавание плакат пламя планета планирование пласт пластинка плата платеж платок платформа платье плач плащ племя племянник плен пленка пленный пленум плита плитка плод плоскость плотность плоть площадка плюс пляж побег победитель побережье повар повествование повестка повесть поворот повреждение повторение погода погон погоня подарок подача подбор подбородок подвал подвеска подвиг поддержание подлец поднос подобие подозрение подоконник подошва подписание подпись подполковник подразделение подробность подросток подруга подружка подсудимый подсчет подтверждение подушка подчинение подчиненный подъезд подъем поединок поездка пожар пожелание поза поздравление познание позор показ показание покаяние поклон поклонник покой покойник покров покрытие покупатель покупка покушение полгода полдень полет полигон поликлиника политбюро политик полицейский полиция полк полка полномочие полнота полночь полоса полоска полость полотенце полотно полчаса польза пользование пользователь полюс поляк поляна помеха помидор помощник понедельник поп попадание поправка популярность популяция поражение порог порода порок поросенок порошок порт портрет портфель поручение поручик порция порыв посадка поселение поселок посетитель посещение послание последовательность последствие пособие посол посольство посредник поставка поставщик постановка постановление постель пострадавший построение постройка поступление поступок посуда посылка пот потенциал потерпевший потеря потолок потомок потребитель потребление потребность потрясение похвала поход походка похороны поцелуй почва почерк почка почта пошлина поэзия поэма пояс правильность правитель правление правонарушение правоотношение православие правосудие правота прапорщик прах пребывание превосходство превращение предание преданность предатель предательство предисловие предлог предок предоставление предположение предпосылка предпочтение предприниматель предпринимательство представительство предупреждение предчувствие предшественник презентация президиум презрение преимущество прекращение прелесть премия премьер премьера премьер-министр преобразование преодоление препарат преподаватель препятствие преследование пресса пресс-конференция пресс-служба престол преступник преступность претендент претензия приближение прибор прибыль прибытие приватизация привет приветствие привилегия привлечение привычка приглашение приговор приготовление приезд приемная приемник приз призвание признак признание призрак призыв приказ приключение прикосновение прикрытие прилавок приложение примета примечание принадлежность принц принцесса принятие приобретение приоритет прирост приспособление пристань пристрастие приступ присутствие приток притча приход прихожая прическа приятель проба пробка провал проверка провинция провод проводник провокация проволока прогноз прогресс прогулка продавец продавщица продвижение продолжение продолжительность продюсер проезд проектирование проем проживание проза прозвище производитель производительность произвол происхождение происшествие прокат прокуратура прокурор промежуток промысел промышленность проникновение пропаганда пропасть прописка проповедь пропуск пророк прорыв просвещение просмотр проспект проститутка простор простота простыня просьба протест противодействие противоречие противостояние протокол протяжение профессионал профессионализм профессия профилактика профиль профсоюз проход прохождение прохожий процедура прочность прощание прощение проявление пруд пружина прыжок психика психолог психология птичка публика публикация пуговица пузырь пулемет пульт пуля пуск пустота пустыня пустяк путевка путешественник путешествие пух пучок пушка пчела пшеница пыль пытка пьяница пьянство пятерка пятка пятница пятно раб работодатель рабочий равенство равновесие равнодушие радио радиостанция разбирательство разбойник разбор разборка развал развалина разведка разведчик развлечение развод разгар раздел разделение раздражение раздумье различие разлука размах размещение размышление разница разновидность разногласие разнообразие разочарование разработчик разрез разрешение разрушение разрыв разряд разум разъяснение рай райком рак ракета раковина рама рана ранг ранение раненый распад расписание расположение распоряжение распределение распространение рассвет расследование рассмотрение расстояние расстрел расстройство рассуждение раствор растерянность расширение реальность ребро ребятишки рев ревность револьвер регистрация регламент регулирование редактор редкость реестр резерв резиденция резолюция рейс рейтинг реклама рекомендация реконструкция рекорд ректор религия рельс ремень ремесло ремонт реорганизация репертуар репетиция реплика репрессия репутация ресница респондент ресторан референдум реформирование рецензия рецепт речка решетка риск ритм ритуал рог родные родня родственник рожа рождество роза розыск ролик романс роскошь россиянин рота роща рояль рубаха рубашка рубеж рубка рубрика руда ружье рукав рукопись рукоятка руль русло русский ручей ручка рыбак рыбка рывок рыцарь рычаг рюкзак рюмка садик сайт салат сало салон салфетка самец самка самовар самостоятельность самоубийство самоуправление санаторий сани санитар санкция сантиметр сапог сарай сахар сближение сбор сборка сборная сборник сбыт свадьба свалка свекровь сверстник свеча свидание свидетель свидетельство свинья свист свитер свод сволочь связка святитель святой священник сдача сдвиг сделка сеанс себестоимость север сегмент седло сезон сейф секрет секретарша секретарь секс сектор секция село семейство семинар семя сенатор сено сенсация сервис серебро сержант сериал серия сертификат сессия сетка сигарета сигнал сиденье силуэт символ симпатия симптом симфония синтез синяк сирота сияние сказка скала скамейка скамья скандал скатерть скважина сквер скелет скидка склад складка склон склонность скорбь скот скотина скрип скрипка скука скула скульптор скульптура слабость славянин следователь следствие слияние словарь сложность слой слон слуга служащий служение слух случайность слушатель слюна смелость смена смесь смех снабжение снаряд снижение снимок снятие собачка собеседник соблазн соблюдение собор собственник совершение совершенство совершенствование совесть советник совещание совокупность совпадение современник современность совхоз согласие согласование соглашение содействие содержимое соединение создатель сок сокращение сокровище солнышко соль соображение сообщение сообщество сооружение соотечественник соотношение соперник сопоставление сопровождение сопротивление соратник соревнование сорт соседка соседство сосна составление составляющая сострадание сосуд сотрудничество соус сохранение социализм социология сочетание сочинение сочувствие союзник спальня спасение спасибо спаситель спектр специальность специфика спецслужба спинка спирт спичка сплав спокойствие спонсор спор спорт спортсмен справедливость справка справочник спрос спуск спутник сражение средневековье среднее ссора ссылка стабильность ставка стадион стадия стадо стаж стакан сталь стан стандарт становление станок старец старина старичок старость старт старуха старушка старший старшина статистика статус статуя стать стая ствол стебель стенд стенка степь стереотип стимул стих стихия стихотворение стойка столб столетие столик столкновение столовая стон стопа стопка сторож сторонник стоянка страдание стража страсть стратегия страхование страховщик стрела стрелка стрельба стремление стресс строение строитель строй стройка строка строчка струна струя студентка студия стук ступень ступенька стыд суббота сугроб судно судопроизводство суета суждение сука сумерки сумка сумочка сундук суп супруг супруга сустав сущность схватка сходство сценарий съезд съемка сыворотка сынок сыр сырье сэр сюжет сюрприз табак таблетка табличка табуретка таз таинство тайга такси такт тактика талант талия танец танк таракан тарелка тариф татарин тварь творение творец творчество тезис телевидение телевизор телега телеграмма тележка тематика темнота темп темперамент температура тенденция теннис теоретик тепло теракт термин терпение терраса террор терроризм террорист тест тесто тетка тетрадка тетрадь тетя теща тигр тираж титр титул тишина ткань товарищество ток толк толкование толчок толщина том тон тонкость тонна топливо топор торг торговец торговля торжество тормоз торт тоска тост точность травма трагедия траектория трактовка трактор трамвай транслит транспорт транспортировка трансформация трасса тревога тренер тренировка треск треть треугольник трещина трибуна троица тройка троллейбус тропа тропинка тротуар трубопровод трудность трудящийся труп труппа трусы трюк тряпка туалет туман тумбочка тупик тур турист турнир турок туфля туча тыл тысячелетие тьма тюрьма тяга тяжесть убеждение убийство убийца убитый уборка уборная убыток уважение увеличение уверенность увлечение увольнение уголок уголь угроза удаление удача удивление удобство удовлетворение удостоверение ужин узел узор указ указание укол украшение укрепление улучшение умение уменьшение умница унижение уничтожение упаковка уплата упоминание упор употребление управляющий упражнение упрек уравнение урегулирование урожай урок ус усадьба усиление ускорение усмешка уста устав усталость установление устойчивость устранение устройство уступка утверждение утешение утка уточнение утрата уход участковый участь учащийся учеба учебник учение училище учительница учреждение ущелье ущерб фабрика фаза факс факультет фантазия фара фасад фашизм фашист февраль феномен ферма фестиваль фигурка физик физика физиономия филиал философ философия фильтр финал финансирование финансы флаг флот фокус фон фонарь фонтан формат формула формулировка форум фото фотограф фрагмент фракция француз фрукт фундамент функционирование фунт фуражка футбол футболист фюрер халат хаос характеристика хата хвост химия хирург хитрость хлопоты ходатайство хозяйка хоккей холдинг холл холм холод холодильник хор хохот хранение хребет хрен христианин христианство хроника хулиган хутор царица царство царь целостность цензура цепочка цепь церемония цех цивилизация цикл цилиндр цирк цитата цифра цыган чайка чайник часовой частица частота часы чаша чашка чекист человечек человечество челюсть чемодан чемпион чемпионат чепуха чердак череп чернила черта чертеж четверг четверть чеченец чин чиновник численность чистка чистота чтение чувствительность чудовище чулок чушь шампанское шанс шапка шапочка шар шарик шахматы шахта шедевр шепот шерсть шеф шина шинель ширина широта шкала шкаф школьник шкура шлем шляпа шов шок шоколад шорох шоссе шоу шофер шпион шрам штаб штамм штамп штаны штат штора штраф штука штурм штык шуба шум шут шутка щека щель щенок щит эвакуация эволюция экзамен экземпляр экипаж экология экономист экономия экран экскурсия экспедиция эксперимент эксперт экспертиза эксплуатация экспозиция экспорт электричество электричка электрон электроэнергия элита эмигрант эмиграция эмоция энергетика энтузиазм энциклопедия эпидемия эпизод эра эстетика эстрада этика эфир эффект эффективность эхо эшелон юбилей юбка юг юмор юность юноша юрисдикция юрист юстиция яблоко ягода яд ядро яйцо якорь яма японец ярмарка ярость ясность ять ячейка ящик ================================================ FILE: internal/game/words/ua ================================================ абрикос автобус автомобіль адвокат аеропорт актор ананас апельсин аптека багаж багажник баклажан балкон банан банк батарейка безлад бензин блокнот блузка блюдце боби борода брову будинок булочка буряк бутерброд бухгалтер білка ваза ванна варення ведмідь велосипед весна весілля вечірка взуття вибір вилка вино виноград випадок висота вишня вовк вогонь водій вождь вокзал волосся вправа вулиця вуса вухо відпустка відро відстань вікно вітер газета гаманець гарбуз глибина годинник гора горло горох горіх готель гребінець гриб грип гроші груди груша губи гусак гість дах двері двір дерево джинси дзеркало диван диво диня дитина довжина дозвіл дорога досвід доставка досягнення дощ друг дріт думка духовка душ душа дівчинка жаба жираф життя журнал журналіст жінка завдання завод запис запрошення звичка здатність здоров’я земля зима знання знижка зошит зуб зупинка зустріч іграшка інженер їжак їдальня йогурт кабачок кава кавун календар камінь капелюх капуста капюшон карта картина картопля каструля кафе качка каша квиток квітка кермо килим клавіатура клей ключ книга ковбаса ковдру колготки колега колесо коліно конверт корабель коридор коробка корова костюм котлета кофта краватка кран кролик кросівки крісло кукурудза кухня кіно кінотеатр кінь кістка кішка лампа лимон лисиця листок лоб ложка лопата люди ліжко лікар лікарня лікоть лінійка ліс літак літера література літо ліхтар мавпа магазин малина мандарин масло масло мед медсестра межа мило мистецтво митниця миша молоко молоток море морква мотузка музика музикант мука мікрохвильовка міст місто місяць м’ясо м’яч наука небезпека небо нога ножиці носовичок носок ноутбук ніж ніс обличчя овочі огірок одяг озеро океан окуляри олівець острів осінь офіс офіціант оцінка очей палець палиця пальто пам’ять папір парк паркан пензлик перевага переговори перехрестя перець персик печиво пиріжок плаття плече площа пляж пляшка поведінка повітря погода подарунок подушка покупка поле полку поліція помилка помідор посилка потяг почуття пошта поїздка проблема продавець простирадло прянощі птах підборіддя піджак пісня пісок радіо радість рахунок реклама ремінь ресторан риба ринок рис робочий розетка розмір розповідь рослина рот рукавиця ручка рушник рюкзак річка сад салат светр свиня світ село серветка серце сила синяк сир слива словник слово слон сміття сніг собака сонце сорочка соус спальня спідниця стакан сторінка страх студент стілець сумка суп сусід сік сіль тарілка тварина театр телевізор температура торт трава трамвай тротуар туалет туман угода удача узбережжя університет урок учитель фото фотоапарат фрукт хлопець хлопчик хліб хмара холодильник художник цвях церква цибуля ціна чай чайник чайові часник чашка чемодан черевик чоловік шапка шарф шафа швидкість шия школа школяр шоколад шорти штани щастя щур яблуко ягода яйце ================================================ FILE: internal/game/words.go ================================================ package game import ( "embed" "errors" "fmt" "log" "math/rand/v2" "strings" "unicode/utf8" "golang.org/x/text/cases" "golang.org/x/text/language" ) type LanguageData struct { Lowercaser func() cases.Caser LanguageCode string IsRtl bool } var ( ErrUnknownWordList = errors.New("wordlist unknown") WordlistData = map[string]LanguageData{ "custom": { LanguageCode: "en_gb", Lowercaser: func() cases.Caser { return cases.Lower(language.BritishEnglish) }, }, "english_gb": { LanguageCode: "en_gb", Lowercaser: func() cases.Caser { return cases.Lower(language.BritishEnglish) }, }, "english": { LanguageCode: "en_us", Lowercaser: func() cases.Caser { return cases.Lower(language.AmericanEnglish) }, }, "italian": { LanguageCode: "it", Lowercaser: func() cases.Caser { return cases.Lower(language.Italian) }, }, "german": { LanguageCode: "de", Lowercaser: func() cases.Caser { return cases.Lower(language.German) }, }, "french": { LanguageCode: "fr", Lowercaser: func() cases.Caser { return cases.Lower(language.French) }, }, "dutch": { LanguageCode: "nl", Lowercaser: func() cases.Caser { return cases.Lower(language.Dutch) }, }, "ukrainian": { LanguageCode: "ua", Lowercaser: func() cases.Caser { return cases.Lower(language.Ukrainian) }, }, "russian": { LanguageCode: "ru", Lowercaser: func() cases.Caser { return cases.Lower(language.Russian) }, }, "polish": { LanguageCode: "pl", Lowercaser: func() cases.Caser { return cases.Lower(language.Polish) }, }, "arabic": { IsRtl: true, LanguageCode: "ar", Lowercaser: func() cases.Caser { return cases.Lower(language.Arabic) }, }, "hebrew": { IsRtl: true, LanguageCode: "he", Lowercaser: func() cases.Caser { return cases.Lower(language.Hebrew) }, }, "persian": { IsRtl: true, LanguageCode: "fa", Lowercaser: func() cases.Caser { return cases.Lower(language.Persian) }, }, } //go:embed words/* wordFS embed.FS ) func getLanguageIdentifier(language string) string { return WordlistData[language].LanguageCode } // readWordListInternal exists for testing purposes, it allows passing a custom // wordListSupplier, in order to avoid having to write tests aggainst the // default language lists. func readWordListInternal( lowercaser cases.Caser, chosenLanguage string, wordlistSupplier func(string) (string, error), ) ([]string, error) { languageIdentifier := getLanguageIdentifier(chosenLanguage) if languageIdentifier == "" { return nil, ErrUnknownWordList } wordListFile, err := wordlistSupplier(languageIdentifier) if err != nil { return nil, fmt.Errorf("error invoking wordlistSupplier: %w", err) } // Wordlists are guaranteed not to contain any carriage returns (\r). words := strings.Split(lowercaser.String(wordListFile), "\n") shuffleWordList(words) return words, nil } // readDefaultWordList reads the wordlist for the given language from the filesystem. // If found, the list is cached and will be read from the cache upon next // request. The returned slice is a safe copy and can be mutated. If the // specified has no corresponding wordlist, an error is returned. This has been // a panic before, however, this could enable a user to forcefully crash the // whole application. func readDefaultWordList(lowercaser cases.Caser, chosenLanguage string) ([]string, error) { log.Printf("Loading wordlist '%s'\n", chosenLanguage) defer log.Printf("Wordlist loaded '%s'\n", chosenLanguage) return readWordListInternal(lowercaser, chosenLanguage, func(key string) (string, error) { wordBytes, err := wordFS.ReadFile("words/" + key) if err != nil { return "", fmt.Errorf("error reading wordfile: %w", err) } return strings.ReplaceAll(string(wordBytes), "\r", ""), nil }) } func reloadLobbyWords(lobby *Lobby) ([]string, error) { return readDefaultWordList(lobby.lowercaser, lobby.Wordpack) } // GetRandomWords gets a custom amount of random words for the passed Lobby. // The words will be chosen from the custom words and the default // dictionary, depending on the settings specified by the lobbies creator. func GetRandomWords(wordCount int, lobby *Lobby) []string { return getRandomWords(wordCount, lobby, reloadLobbyWords) } // getRandomWords exists for test purposes, allowing to define a custom // reloader, allowing us to specify custom wordlists in the tests without // running into a panic on reload. func getRandomWords(wordCount int, lobby *Lobby, reloadWords func(lobby *Lobby) ([]string, error)) []string { words := make([]string, wordCount) // If we have custom words only, we don't want to pop them off the stack. // We want to keep going in circles, worstcase returning the same word 3 times. if lobby.Wordpack == "custom" && len(lobby.CustomWords) > 0 { for i := range wordCount { if lobby.customWordIndex >= len(lobby.CustomWords) { lobby.customWordIndex = 0 } words[i] = lobby.CustomWords[lobby.customWordIndex] lobby.customWordIndex++ } return words } for customWordsLeft, i := lobby.CustomWordsPerTurn, 0; i < wordCount; i++ { if customWordsLeft > 0 && len(lobby.CustomWords) > 0 { customWordsLeft-- words[i] = popCustomWord(lobby) } else { words[i] = popWordpackWord(lobby, reloadWords) } } return words } func popCustomWord(lobby *Lobby) string { lastIndex := len(lobby.CustomWords) - 1 lastWord := lobby.CustomWords[lastIndex] lobby.CustomWords = lobby.CustomWords[:lastIndex] return lastWord } // popWordpackWord gets X words from the wordpack. The major difference to // popCustomWords is, that the wordlist gets reset and reshuffeled once every // item has been popped. func popWordpackWord(lobby *Lobby, reloadWords func(lobby *Lobby) ([]string, error)) string { if len(lobby.words) == 0 { var err error lobby.words, err = reloadWords(lobby) if err != nil { // Since this list should've been successfully read once before, we // can "safely" panic if this happens, assuming that there's a // deeper problem. panic(err) } } lastIndex := len(lobby.words) - 1 lastWord := lobby.words[lastIndex] lobby.words = lobby.words[:lastIndex] return lastWord } func shuffleWordList(wordlist []string) { rand.Shuffle(len(wordlist), func(a, b int) { wordlist[a], wordlist[b] = wordlist[b], wordlist[a] }) } const ( EqualGuess = 0 CloseGuess = 1 DistantGuess = 2 ) // CheckGuess compares the strings with eachother. Possible results: // - EqualGuess (0) // - CloseGuess (1) // - DistantGuess (2) // // This works mostly like levensthein distance, but doesn't check further than // to a distance of 2 and also handles transpositions where the runes are // directly next to eachother. func CheckGuess(a, b string) int { // We only want to indicate a close guess if: // * 1 additional character is found (abc ~ abcd) // * 1 character is missing (abc ~ ab) // * 1 character is wrong (abc ~ adc) // * 2 characters are swapped (abc ~ acb) // If the longer string can't be on both sides, the follow-up logic can // be simpler, so we switch them here. if len(a) < len(b) { a, b = b, a } // A maximum of 4 bytes is used for one unicode code point. So if there is a definitive character // count difference of 2 or more characters, we can clearly indicate a distant guess.\ // This prevents having to count all runes in b. if len(a)-len(b) >= 8 { return DistantGuess } if a == b { return EqualGuess } var distance int aBytes := []byte(a) bBytes := []byte(b) for { aRune, aSize := utf8.DecodeRune(aBytes) // If a eaches the end, then so does b, as we make sure a is longer at // the top, therefore we can be sure no additional conflict diff occurs. if aRune == utf8.RuneError { // If a is longer in terms of bytes, but contains for example an emoji that takes up 4 bytes, this CAN happen. distance += utf8.RuneCount(bBytes) if distance >= 2 { return DistantGuess } return distance } bRune, bSize := utf8.DecodeRune(bBytes) // Either different runes, or b is empty, returning RuneError (65533). if aRune != bRune { // Check for transposition (abc ~ acb) nextARune, nextASize := utf8.DecodeRune(aBytes[aSize:]) if nextARune == bRune { if nextARune != utf8.RuneError { nextBRune, nextBSize := utf8.DecodeRune(bBytes[bSize:]) if nextBRune == aRune { distance++ aBytes = aBytes[aSize+nextASize:] bBytes = bBytes[bSize+nextBSize:] continue } } // Make sure to not pop from b, so we can compare the rest, in // case we are only missing one character for cases such as: // abc ~ bc // abcde ~ abde bSize = 0 } else if distance == 1 { // We'd reach a diff of 2 now. Needs to happen after transposition // though, as transposition could still prove us wrong. return DistantGuess } distance++ } aBytes = aBytes[aSize:] bBytes = bBytes[bSize:] } } ================================================ FILE: internal/game/words_test.go ================================================ package game import ( "bytes" "fmt" "slices" "strings" "testing" "github.com/stretchr/testify/assert" "golang.org/x/text/cases" "golang.org/x/text/language" ) func Test_wordListsContainNoCarriageReturns(t *testing.T) { t.Parallel() for _, entry := range WordlistData { fileName := entry.LanguageCode fileBytes, err := wordFS.ReadFile("words/" + fileName) if err != nil { t.Errorf("language file '%s' could not be read: %s", fileName, err) } else if bytes.ContainsRune(fileBytes, '\r') { t.Errorf("language file '%s' contains a carriage return", fileName) } } } func Test_readWordList(t *testing.T) { t.Parallel() t.Run("test invalid language file", func(t *testing.T) { t.Parallel() words, err := readDefaultWordList(cases.Lower(language.English), "nonexistent") assert.ErrorIs(t, err, ErrUnknownWordList) assert.Empty(t, words) }) for language := range WordlistData { t.Run(language, func(t *testing.T) { t.Parallel() testWordList(t, language) testWordList(t, language) }) } } func testWordList(t *testing.T, chosenLanguage string) { t.Helper() lowercaser := WordlistData[chosenLanguage].Lowercaser() words, err := readDefaultWordList(lowercaser, chosenLanguage) if err != nil { t.Errorf("Error reading language %s: %s", chosenLanguage, err) } if len(words) == 0 { t.Errorf("Wordlist for language %s was empty.", chosenLanguage) } for _, word := range words { if word == "" { // We can't print the faulty line, since we are shuffling // the words in order to avoid predictability. t.Errorf("Wordlist for language %s contained empty word", chosenLanguage) } if strings.TrimSpace(word) != word { t.Errorf("Word has surrounding whitespace characters: '%s'", word) } if lowercaser.String(word) != word { t.Errorf("Word hasn't been lowercased: '%s'", word) } } } func Test_getRandomWords(t *testing.T) { t.Parallel() t.Run("Test getRandomWords with 3 words in list", func(t *testing.T) { t.Parallel() lobby := &Lobby{ CurrentWord: "", EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 0, }, words: []string{"a", "b", "c"}, } randomWords := GetRandomWords(3, lobby) for _, lobbyWord := range lobby.words { if !slices.Contains(randomWords, lobbyWord) { t.Errorf("Random words %s, didn't contain lobbyWord %s", randomWords, lobbyWord) } } }) t.Run("Test getRandomWords with 3 words in list and 3 more in custom word list, but with 0 chance", func(t *testing.T) { t.Parallel() lobby := &Lobby{ CurrentWord: "", words: []string{"a", "b", "c"}, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 0, }, CustomWords: []string{"d", "e", "f"}, } randomWords := GetRandomWords(3, lobby) for _, lobbyWord := range lobby.words { if !slices.Contains(randomWords, lobbyWord) { t.Errorf("Random words %s, didn't contain lobbyWord %s", randomWords, lobbyWord) } } }) t.Run("Test getRandomWords with 3 words in list and 100% custom word chance, but without custom words", func(t *testing.T) { t.Parallel() lobby := &Lobby{ CurrentWord: "", words: []string{"a", "b", "c"}, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 3, }, CustomWords: nil, } randomWords := GetRandomWords(3, lobby) for _, lobbyWord := range lobby.words { if !slices.Contains(randomWords, lobbyWord) { t.Errorf("Random words %s, didn't contain lobbyWord %s", randomWords, lobbyWord) } } }) t.Run("Test getRandomWords with 3 words in list and 100% custom word chance, with 3 custom words", func(t *testing.T) { t.Parallel() lobby := &Lobby{ CurrentWord: "", words: []string{"a", "b", "c"}, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 3, }, CustomWords: []string{"d", "e", "f"}, } randomWords := GetRandomWords(3, lobby) for _, customWord := range lobby.CustomWords { if !slices.Contains(randomWords, customWord) { t.Errorf("Random words %s, didn't contain customWord %s", randomWords, customWord) } } }) } func Test_getRandomWordsReloading(t *testing.T) { t.Parallel() loadWordList := func() []string { return []string{"a", "b", "c"} } reloadWordList := func(_ *Lobby) ([]string, error) { return loadWordList(), nil } wordList := loadWordList() t.Run("test reload with 3 words and 0 custom words and 0 chance", func(t *testing.T) { t.Parallel() lobby := &Lobby{ words: wordList, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 0, }, CustomWords: nil, } // Running this 10 times, expecting it to get 3 words each time, even // though our pool has only got a size of 3. for range 10 { words := getRandomWords(3, lobby, reloadWordList) if len(words) != 3 { t.Errorf("Test failed, incorrect wordcount: %d", len(words)) } } }) t.Run("test reload with 3 words and 0 custom words and 100 chance", func(t *testing.T) { t.Parallel() lobby := &Lobby{ words: wordList, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 3, }, CustomWords: nil, } // Running this 10 times, expecting it to get 3 words each time, even // though our pool has only got a size of 3. for range 10 { words := getRandomWords(3, lobby, reloadWordList) if len(words) != 3 { t.Errorf("Test failed, incorrect wordcount: %d", len(words)) } } }) t.Run("test reload with 3 words and 1 custom words and 0 chance", func(t *testing.T) { t.Parallel() lobby := &Lobby{ words: wordList, EditableLobbySettings: EditableLobbySettings{ CustomWordsPerTurn: 3, }, CustomWords: []string{"a"}, } // Running this 10 times, expecting it to get 3 words each time, even // though our pool has only got a size of 3. for range 10 { words := getRandomWords(3, lobby, reloadWordList) if len(words) != 3 { t.Errorf("Test failed, incorrect wordcount: %d", len(words)) } } }) } var poximityBenchCases = [][]string{ {"", ""}, {"a", "a"}, {"ab", "ab"}, {"abc", "abc"}, {"abc", "abcde"}, {"cde", "abcde"}, {"a", "abcdefghijklmnop"}, {"cde", "abcde"}, {"cheese", "wheel"}, {"abcdefg", "bcdefgh"}, } func Benchmark_proximity_custom(b *testing.B) { for _, benchCase := range poximityBenchCases { b.Run(fmt.Sprint(benchCase[0], " ", benchCase[1]), func(b *testing.B) { var sink int for i := 0; i < b.N; i++ { sink = CheckGuess(benchCase[0], benchCase[1]) } _ = sink }) } } // We've replaced levensthein with the implementation from proximity_custom // func Benchmark_proximity_levensthein(b *testing.B) { // for _, benchCase := range poximityBenchCases { // b.Run(fmt.Sprint(benchCase[0], " ", benchCase[1]), func(b *testing.B) { // var sink int // for i := 0; i < b.N; i++ { // sink = levenshtein.ComputeDistance(benchCase[0], benchCase[1]) // } // _ = sink // }) // } // } func Test_CheckGuess_Negative(t *testing.T) { t.Parallel() type testCase struct { name string a, b string } cases := []testCase{ { a: "abc", b: "abcde", }, { a: "abc", b: "01abc", }, { a: "abc", b: "a", }, { a: "c", b: "abc", }, { a: "abc", b: "c", }, { a: "hallo", b: "welt", }, { a: "abcd", b: "badc", }, { name: "emoji_a", a: "😲", b: "abc", }, { name: "emoji_a_same_byte_count", a: "abcda", b: "😲", }, { name: "emoji_a_higher_byte_count", a: "abcda", b: "😲", }, { name: "emoji_b", a: "abc", b: "😲", }, { a: "cheese", b: "wheel", }, { a: "a", b: "bcdefg", }, } for _, c := range cases { name := fmt.Sprintf("%s ~ %s", c.a, c.b) if c.name != "" { name = c.name } t.Run(name, func(t *testing.T) { t.Parallel() assert.Equal(t, 2, CheckGuess(c.a, c.b)) }) } } func Test_CheckGuess_Positive(t *testing.T) { t.Parallel() type testCase struct { a, b string dist int } cases := []testCase{ { a: "abc", b: "abc", dist: EqualGuess, }, { a: "abc", b: "abcd", dist: CloseGuess, }, { a: "abc", b: "ab", dist: CloseGuess, }, { a: "abc", b: "bc", dist: CloseGuess, }, { a: "abcde", b: "abde", dist: CloseGuess, }, { a: "abc", b: "adc", dist: CloseGuess, }, { a: "abc", b: "acb", dist: CloseGuess, }, { a: "abcd", b: "acbd", dist: CloseGuess, }, { a: "äbcd", b: "abcd", dist: CloseGuess, }, { a: "abcd", b: "bacd", dist: CloseGuess, }, } for _, c := range cases { t.Run(fmt.Sprintf("%s ~ %s", c.a, c.b), func(t *testing.T) { t.Parallel() assert.Equal(t, c.dist, CheckGuess(c.a, c.b)) }) } } ================================================ FILE: internal/metrics/metrics.go ================================================ package metrics import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( registry *prometheus.Registry connectedPlayers prometheus.Gauge ) func init() { registry = prometheus.NewRegistry() connectedPlayers = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "scribblers", Name: "connected_players", Help: "The amount of connected players (active websocket connections)", }) registry.MustRegister(connectedPlayers) } func TrackPlayerConnect() { connectedPlayers.Inc() } func TrackPlayerDisconnect() { connectedPlayers.Dec() } func SetupRoute(registerFunc func(http.HandlerFunc)) { registerFunc(promhttp.HandlerFor(registry, promhttp.HandlerOpts{}).ServeHTTP) } ================================================ FILE: internal/sanitize/sanitize.go ================================================ // Package sanitize is used for cleaning up text. package sanitize import ( "unicode/utf8" ) // FIXME Improve transliteration set or document why the current state // is acceptableb. These transliterations originally come from // github.com/kennygrant/sanitize. var transliterations = map[rune]string{ 'À': "A", 'Á': "A", 'Â': "A", 'Ã': "A", 'Ä': "A", 'Å': "AA", 'Æ': "AE", 'Ç': "C", 'È': "E", 'É': "E", 'Ê': "E", 'Ë': "E", 'Ì': "I", 'Í': "I", 'Î': "I", 'Ï': "I", 'Ð': "D", 'Ł': "L", 'Ñ': "N", 'Ò': "O", 'Ó': "O", 'Ô': "O", 'Õ': "O", 'Ö': "OE", 'Ø': "OE", 'Œ': "OE", 'Ù': "U", 'Ú': "U", 'Ü': "UE", 'Û': "U", 'Ý': "Y", 'Þ': "TH", 'ẞ': "SS", 'à': "a", 'á': "a", 'â': "a", 'ã': "a", 'ä': "ae", 'å': "aa", 'æ': "ae", 'ç': "c", 'è': "e", 'é': "e", 'ê': "e", 'ë': "e", 'ì': "i", 'í': "i", 'î': "i", 'ï': "i", 'ð': "d", 'ł': "l", 'ñ': "n", 'ń': "n", 'ò': "o", 'ó': "o", 'ô': "o", 'õ': "o", 'ō': "o", 'ö': "oe", 'ø': "oe", 'œ': "oe", 'ś': "s", 'ù': "u", 'ú': "u", 'û': "u", 'ū': "u", 'ü': "ue", 'ý': "y", 'ÿ': "y", 'ż': "z", 'þ': "th", 'ß': "ss", } // CleanText removes all kinds of characters that could disturb the algorithm // checking words for similarity. func CleanText(str string) string { var buffer []byte // We try to stack allocate, but also make // space for the worst case scenario. if len(str) <= 32 { buffer = make([]byte, 0, 64) } else { buffer = make([]byte, 0, len(str)*2) } var changed bool for _, character := range str { if character < utf8.RuneSelf { switch character { case ' ', '-', '_': changed = true default: buffer = append(buffer, byte(character)) } continue } if val, contains := transliterations[character]; contains { buffer = append(buffer, val...) changed = true } else { buffer = utf8.AppendRune(buffer, character) } } if !changed { return str } return string(buffer) } ================================================ FILE: internal/state/doc.go ================================================ // Package state provides the application state. Currently this is only the // open lobbies. However, the lobby state itself is managed in the game // package. On top of this, we automatically clean up deserted lobbies // in this package, as it is much easier in a centralized places and also // protects us from flooding the server with goroutines. package state ================================================ FILE: internal/state/lobbies.go ================================================ package state import ( "log" "sync" "time" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" ) var ( globalStateMutex = &sync.RWMutex{} lobbies []*game.Lobby ) // LaunchCleanupRoutine starts a task to clean up empty lobbies. An empty // lobby is a lobby where all players have been disconnected for a certain // timeframe. This avoids deleting lobbies when the creator of a lobby // accidentally reconnects or needs to refresh. Another scenario might be // where the server loses it's connection to all players temporarily. While // unlikely, we'll be able to preserve lobbies this way. // This method shouldn't be called more than once. Initially this was part of // this packages init method, however, in order to avoid side effects in // tests, this has been moved into a public function that has to be called // manually. func LaunchCleanupRoutine(cfg config.LobbyCleanup) { log.Println("Lobby Cleanup Routine started.") go func() { lobbyCleanupTicker := time.NewTicker(cfg.Interval) for { <-lobbyCleanupTicker.C cleanupRoutineLogic(&cfg) } }() } // cleanupRoutineLogic is an extra function in order to prevent deadlocks by // being able to use defer mutex.Unlock(). func cleanupRoutineLogic(cfg *config.LobbyCleanup) { globalStateMutex.Lock() defer globalStateMutex.Unlock() initalLobbyCount := len(lobbies) for index := len(lobbies) - 1; index >= 0; index-- { lobby := lobbies[index] if lobby.HasConnectedPlayers() { continue } disconnectTime := lobby.LastPlayerDisconnectTime if disconnectTime == nil || time.Since(*disconnectTime) >= cfg.PlayerInactivityThreshold { removeLobbyByIndex(index) } } if lobbiesClosed := initalLobbyCount - len(lobbies); lobbiesClosed > 0 { log.Printf("Closing %d lobbies. Remaining lobbies: %d\n", lobbiesClosed, len(lobbies)) } } // AddLobby adds a lobby to the instance, making it visible for GetLobby calls. func AddLobby(lobby *game.Lobby) { globalStateMutex.Lock() defer globalStateMutex.Unlock() lobbies = append(lobbies, lobby) } // GetLobby returns a Lobby that has a matching ID or no Lobby if none could // be found. func GetLobby(id string) *game.Lobby { globalStateMutex.RLock() defer globalStateMutex.RUnlock() for _, lobby := range lobbies { if lobby.LobbyID == id { return lobby } } return nil } // ShutdownLobbiesGracefully shuts down all lobbies and removes them from the // state, preventing reconnects to existing lobbies. New lobbies can // technically still be added. func ShutdownLobbiesGracefully() { globalStateMutex.Lock() defer globalStateMutex.Unlock() log.Println("Shutdown: Mutex acquired") for _, lobby := range lobbies { // Since a reconnect requires a lookup to the state, all attempts to // reconnect will end up running into the global statelock. Therefore, // reconnecting wouldn't be possible. lobby.Shutdown() } // Instead of removing one by one, we nil the array, since that's faster. lobbies = nil } // GetActiveLobbyCount indicates how many activate lobby there are. This includes // both private and public lobbies and it doesn't matter whether the game is // already over, hasn't even started or is still ongoing. func GetActiveLobbyCount() int { globalStateMutex.RLock() defer globalStateMutex.RUnlock() return len(lobbies) } // GetPublicLobbies returns all lobbies with their public flag set to true. // This implies that the lobbies can be found in the lobby browser ob the // homepage. func GetPublicLobbies() []*game.Lobby { globalStateMutex.RLock() defer globalStateMutex.RUnlock() var publicLobbies []*game.Lobby for _, lobby := range lobbies { if lobby.IsPublic() { publicLobbies = append(publicLobbies, lobby) } } return publicLobbies } // RemoveLobby deletes a lobby, not allowing anyone to connect to it again. func RemoveLobby(id string) { globalStateMutex.Lock() defer globalStateMutex.Unlock() removeLobby(id) } func removeLobby(id string) { for index, lobby := range lobbies { if lobby.LobbyID == id { removeLobbyByIndex(index) return } } } func removeLobbyByIndex(index int) { // We delete the lobby without maintaining order, since the lobby order // is irrelevant. This holds true as long as there's no paging for // requesting lobbies via the API. lobbies[index] = lobbies[len(lobbies)-1] // Remove reference to moved lobby, as we'd multiple references to // the same lobby in memory, potentially leaking memory if the // lobby is removed later on. lobbies[len(lobbies)-1] = nil lobbies = lobbies[:len(lobbies)-1] } // PageStats represents dynamic information about the website. type PageStats struct { ActiveLobbyCount int `json:"activeLobbyCount"` PlayersCount uint64 `json:"playersCount"` OccupiedPlayerSlotCount uint64 `json:"occupiedPlayerSlotCount"` ConnectedPlayersCount uint64 `json:"connectedPlayersCount"` } // Stats delivers information about the state of the service. Currently this // is lobby and player counts. func Stats() *PageStats { globalStateMutex.RLock() defer globalStateMutex.RUnlock() var playerCount, occupiedPlayerSlotCount, connectedPlayerCount uint64 // While one would expect locking the lobby here, it's not very // important to get 100% consistent results here. for _, lobby := range lobbies { playerCount += uint64(len(lobby.GetPlayers())) occupiedPlayerSlotCount += uint64(lobby.GetOccupiedPlayerSlots()) connectedPlayerCount += uint64(lobby.GetConnectedPlayerCount()) } return &PageStats{ ActiveLobbyCount: len(lobbies), PlayersCount: playerCount, OccupiedPlayerSlotCount: occupiedPlayerSlotCount, ConnectedPlayersCount: connectedPlayerCount, } } ================================================ FILE: internal/state/lobbies_test.go ================================================ package state import ( "testing" "github.com/scribble-rs/scribble.rs/internal/config" "github.com/scribble-rs/scribble.rs/internal/game" "github.com/stretchr/testify/require" ) //nolint:paralleltest //this test is very stateful func TestAddAndRemove(t *testing.T) { require.Empty(t, lobbies, "Lobbies should be empty when test starts") createLobby := func() *game.Lobby { player, lobby, err := game.CreateLobby("", "player", "dutch", &game.EditableLobbySettings{ Public: true, DrawingTime: 100, Rounds: 10, MaxPlayers: 10, CustomWordsPerTurn: 3, ClientsPerIPLimit: 1, WordsPerTurn: 3, }, nil, game.ChillScoring) require.NoError(t, err) lobby.OnPlayerDisconnect(player) return lobby } lobbyA := createLobby() lobbyB := createLobby() lobbyC := createLobby() AddLobby(lobbyA) AddLobby(lobbyB) AddLobby(lobbyC) require.NotNil(t, GetLobby(lobbyA.LobbyID)) require.NotNil(t, GetLobby(lobbyB.LobbyID)) require.NotNil(t, GetLobby(lobbyC.LobbyID)) RemoveLobby(lobbyB.LobbyID) require.Nil(t, GetLobby(lobbyB.LobbyID), "Lobby B should have been deleted.") require.NotNil(t, GetLobby(lobbyA.LobbyID), "Lobby A shouldn't have been deleted.") require.NotNil(t, GetLobby(lobbyC.LobbyID), "Lobby C shouldn't have been deleted.") require.Len(t, lobbies, 2) cleanupRoutineLogic(&config.LobbyCleanup{}) require.Empty(t, lobbies) } ================================================ FILE: internal/translations/ar.go ================================================ package translations func initArabicTranslation() *Translation { translation := createTranslation() translation.IsRtl = true translation.put("requires-js", "يحتاج هذا الموقع لصلاحيات جافاسكريبت ليعمل.") translation.put("start-the-game", "إستعدوا!") translation.put("force-start", "البدء الإجباري") translation.put("force-restart", "الإعادة الإجبارية") translation.put("game-not-started-title", "لم تبدإ اللعبة بعد") translation.put("waiting-for-host-to-start", "الرجاء إنتظار المنظم لبدإ اللعبة") translation.put("now-spectating-title", "أنت الآن متفرج") translation.put("now-spectating-text", "يمكنك الخروج من وضع المتفرج بالضغط على زر العين أعلاه") translation.put("now-participating-title", "أنت الآن مشارك") translation.put("now-participating-text", "يمكنك دخول وضع المتفرج بالضغط على زر العين أعلاه") translation.put("spectation-requested-title", "تم طلب وضع المتفرج") translation.put("spectation-requested-text", "ستكون متفرجا بعد هذه الجولة.") translation.put("participation-requested-title", "تم طلب المشاركة") translation.put("participation-requested-text", "ستكون مشاركا بعد هذه الجولة.") translation.put("spectation-request-cancelled-title", "تم إلغاء طلب وضع المتفرج") translation.put("spectation-request-cancelled-text", "تم إلغاء وضع المتفرج, ستبقى مشاركا.") translation.put("participation-request-cancelled-title", "تم إلغاء طلب المشاركة") translation.put("participation-request-cancelled-text", "تم إلغاء طلب المشاركة ستبقى متفرجا.") translation.put("round", "الجولة") translation.put("toggle-soundeffects", "تشغيل/إيقاف مؤثرات الصوتية") translation.put("toggle-pen-pressure", "تشغيل/إيقاف ضغط القلم") translation.put("change-your-name", "إسم الشهرة") translation.put("randomize", "إختيار عشوائي") translation.put("apply", "تطبيق") translation.put("save", "حفظ") translation.put("toggle-fullscreen", "وضع ملء الشاشة") translation.put("toggle-spectate", "تشغيل/إيقاف وضع المتفرج") translation.put("show-help", "عرض المساعدة") translation.put("votekick-a-player", "تصويت لطرد اللاعب") translation.put("last-turn", "(آخر دور %s)") translation.put("drawer-kicked", "بما أن اللاعب المطرود كان يرسم, لن يأخذ أي منكم نقاط") translation.put("self-kicked", "تم طردك") translation.put("kick-vote", "(%s/%s) اللاعبين الذين صوتو لطرد %s.") translation.put("player-kicked", "اللاعب تم طرده.") translation.put("owner-change", "%s هو الآن مالك الردهة") translation.put("change-lobby-settings-tooltip", "تغيير إعدادات الردهة") translation.put("change-lobby-settings-title", "إعدادات الردهة") translation.put("lobby-settings-changed", "تم تغيير إعدادات الردهة") translation.put("advanced-settings", "إعدادات متقدمة") translation.put("chill", "هادئة") translation.put("competitive", "تنافسية") translation.put("chill-alt", "مع أن السرعة تكافأ, إلا أنه لا بأس إن كنت أبطأ قليلا.\nالنقاط الأساسية مرتفعة نسبيا, ركز على الإستمتاع!") translation.put("competitive-alt", "كلما كنت أسرع, حصلت على نقاط أكثر.\nالنقاط الأساسية أقل بكثير, و الإنخفاض أسرع.") translation.put("score-calculation", "النقاط") translation.put("word-language", "اللغة") translation.put("drawing-time-setting", "وقت الرسم") translation.put("rounds-setting", "الجولات") translation.put("max-players-setting", "الحد الأقصى للاعبين") translation.put("public-lobby-setting", "ردهة عامة") translation.put("custom-words", "كلمات مخصصة") translation.put("custom-words-info", "أضف كلماتك الخاصة, فرق بينها بالفاصلة") translation.put("custom-words-per-turn-setting", "كلمات مخصصة لكل دور") translation.put("players-per-ip-limit-setting", "حد اللاعبين في كل IP") translation.put("save-settings", "Save settings") translation.put("input-contains-invalid-data", "مدخلاتك تحتوي على معلومات خاطئة") translation.put("please-fix-invalid-input", "صحح المدخل الخاطئ و أعد المحاولة") translation.put("create-lobby", "إنشاء ردهة") translation.put("create-public-lobby", "إنشاء ردهة عامة") translation.put("create-private-lobby", "إنشاء ردهة خاصة") translation.put("refresh", "إعادة تحميل") translation.put("join-lobby", "دخول الردهة") translation.put("message-input-placeholder", "أدخل تخميناتك و رسائلك هنا!") translation.put("word-choice-warning", "كلمة إذا لم تختر في الوقت") translation.put("choose-a-word", "إختر كلمة") translation.put("waiting-for-word-selection", "في إنتظار إختيار كلمة") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "يختار كلمة.") translation.put("close-guess", "'%s' قريب جدا") translation.put("correct-guess", "لقد أصبت في تخمينك للكلمة.") translation.put("correct-guess-other-player", "'%s' اصاب في تخمين الكلمة") translation.put("round-over", "إنتهى دورك, لم يتم إختيار أي كلمة.") translation.put("round-over-no-word", "إنتهى دورك, الكلمة كانت '%s'") translation.put("game-over-win", "مبارك, لقد فزت!") translation.put("game-over-tie", "إنه تعادل") translation.put("game-over", "لقد وضعت %s. برصيد %s نقطة.") translation.put("change-active-color", "غير لونك الحالي") translation.put("use-pencil", "إستخدم القلم") translation.put("use-eraser", "إستخدم الممحاة") translation.put("use-fill-bucket", "إستعمل الملء بالدلو (يقوم بملء مساحة معينة باللون المعين)") translation.put("change-pencil-size-to", "غير حجم القلم/الممحاة %s") translation.put("clear-canvas", "مسح مساحة الرسم") translation.put("undo", "التراجع عن آخر تغيير قمت به ( لا تعمل بعد \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "فقدت الإشارة") translation.put("connection-lost-text", "محاولة الإتصال مجددا"+ " ...\n\nتأكد من إتصالك بالإنترنت\nإذا "+ "بقي المشكل على حاله, تواصل مع المالك") translation.put("error-connecting", "خطأ في الإتصال بالخادم") translation.put("error-connecting-text", "Scribble.rs لا يمكنه الإتصال بالخادم\n\nبما أن إتصالك "+ "بالأنترنت يبدو أنه يعمل, فإن\nالخادم أو الجدار الناري لم "+ "يتم ضبطه بشكل صحيح\n\nلإعادة المحاولة, قم بإعادة تحميل الصفحة.") translation.put("message-too-long", "رسالتك طويلة جدا!") // Help dialog translation.put("controls", "التحكم") translation.put("pencil", "القلم") translation.put("eraser", "الممحاة") translation.put("fill-bucket", "الملء بالدلو") translation.put("switch-tools-intro", "يمكنك التحويل بين الأدوات بواسطة الاختصارات") translation.put("switch-pencil-sizes", "يمكنك التغيير بين احجام القلم من %s إلى %s.") // Generic words // "close" as in "closing the window" translation.put("close", "إغلاق") translation.put("no", "لا") translation.put("yes", "نعم") translation.put("system", "النظام") translation.put("source-code", "مصدر الكود") translation.put("help", "المساعدة") translation.put("submit-feedback", "الآراء") translation.put("stats", "الحالة") RegisterTranslation("ar", translation) return translation } ================================================ FILE: internal/translations/de_DE.go ================================================ package translations func initGermanTranslation() { translation := createTranslation() translation.put("requires-js", "Diese Website benötigt JavaScript um korrekt zu funktionieren.") translation.put("start-the-game", "Mach dich bereit!") translation.put("force-start", "Start erzwingen") translation.put("force-restart", "Neustart erzwingen") translation.put("game-not-started-title", "Warte auf Spielstart") translation.put("waiting-for-host-to-start", "Bitte warte bis der Lobby Besitzer das Spiel startet.") translation.put("now-spectating-title", "Du schaust nun zu") translation.put("now-spectating-text", "Du kannst den Zuschauermodus verlassen, indem du das Auge oben betätigst.") translation.put("now-participating-title", "Du nimmst nun teil") translation.put("now-participating-text", "Du kannst den Zuschauermodus betreten, indem du das Auge oben betätigst.") translation.put("spectation-requested-title", "Zuschauermodus angefragt") translation.put("spectation-requested-text", "Nach diesem Zug wirst du zum Zuschauer.") translation.put("participation-requested-title", "Teilnahme angefragt") translation.put("participation-requested-text", "Nach diesem Zug wirst du wieder teilnehmen.") translation.put("spectation-request-cancelled-title", "Zuschauermodusanfrage zurückgezogen") translation.put("spectation-request-cancelled-text", "Deine Zuschauermodusanfrage wurde zurückgezogen, du nimmst weiterhin teil.") translation.put("participation-request-cancelled-title", "Teilnahmeanfrage zurückgezogen") translation.put("participation-request-cancelled-text", "Deine Teilnahmeanfrage wurde zurückgezogen, du schaust weiterhin zu.") translation.put("last-turn", "(Letzter Zug: %s)") translation.put("round", "Runde") translation.put("toggle-soundeffects", "Sound ein- / ausschalten") translation.put("toggle-pen-pressure", "Tablet-Stiftdruck ein- / ausschalten") translation.put("change-your-name", "Anzeigename") translation.put("randomize", "Zufälliger Name") translation.put("apply", "Anwenden") translation.put("save", "Speichern") translation.put("toggle-fullscreen", "Vollbild aktivieren / deaktivieren") translation.put("toggle-spectate", "Zuschauermodus aktivieren / deaktivieren") translation.put("show-help", "Hilfe anzeigen") translation.put("votekick-a-player", "Stimme dafür ab, einen Spieler rauszuwerfen") translation.put("change-lobby-settings-tooltip", "Lobby-Einstellungen ändern") translation.put("change-lobby-settings-title", "Lobby-Einstellungen") translation.put("lobby-settings-changed", "Lobby-Einstelungen verändert") translation.put("advanced-settings", "Erweiterte Einstellungen") translation.put("chill", "Gemütlich") translation.put("competitive", "Wettkampf") translation.put("chill-alt", "Zwar wird schnell sein belohnt, aber der Fokus liegt hier eher auf Spaß.") translation.put("competitive-alt", "Je schneller du bist, desto mehr Punkte bekommst du. Schnell sein lohnt sich also!") translation.put("score-calculation", "Punktsystem") translation.put("word-language", "Sprache") translation.put("drawing-time-setting", "Zeichenzeit") translation.put("rounds-setting", "Runden") translation.put("max-players-setting", "Maximale Spieler") translation.put("public-lobby-setting", "Öffentliche Lobby") translation.put("custom-words", "Extrawörter") translation.put("custom-words-info", "Gib hier deine Extrawörter ein und trenne einzelne Wörter mit einem Komma") translation.put("custom-words-per-turn-setting", "Extrawörter pro Zug") translation.put("players-per-ip-limit-setting", "Maximale Spieler pro IP") translation.put("save-settings", "Einstellungen Speichern") translation.put("input-contains-invalid-data", "Deine Eingaben enthalten invalide Daten:") translation.put("please-fix-invalid-input", "Bitte korrigiere deine Eingaben und versuche es erneut.") translation.put("create-lobby", "Lobby erstellen") translation.put("create-public-lobby", "Public Lobby erstellen") translation.put("create-private-lobby", "Private Lobby erstellen") translation.put("refresh", "Aktualisieren") translation.put("join-lobby", "Lobby beitreten") translation.put("message-input-placeholder", "Antworten und Nachrichten hier eingeben") translation.put("word-choice-warning", "Wort, wenn du nicht zeitig wählst") translation.put("choose-a-word", "Wähle ein Wort") translation.put("waiting-for-word-selection", "Warte auf Wort-Auswahl") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "wählt gerade ein Wort.") translation.put("close-guess", "'%s' ist nah dran.") translation.put("correct-guess", "Du hast das Wort korrekt erraten.") translation.put("correct-guess-other-player", "'%s' hat das Wort korrekt erraten.") translation.put("round-over", "Zug vorbei, es wurde kein Wort gewählt.") translation.put("round-over-no-word", "Zug vorbei, das gewählte Wort war '%s'.") translation.put("game-over-win", "Glückwunsch, du hast gewonnen!") translation.put("game-over-tie", "Unentschieden!") translation.put("game-over", "Du bist %s. mit %s Punkten") translation.put("change-active-color", "Ändere die aktive Farbe") translation.put("use-pencil", "Stift bentuzen") translation.put("use-eraser", "Radiergummi benutzen") translation.put("use-fill-bucket", "Fülleimer benutzen (Füllt den Zielbereich mit der gewählten Farbe)") translation.put("change-pencil-size-to", "Ändere die Stift / Radiergummi Größe auf %s") translation.put("clear-canvas", "Leere die Zeichenfläche") translation.put("undo", "Mache deine letzte Änderung ungeschehen (Funktioniert nicht nach \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "Verbindung verloren!") translation.put("connection-lost-text", "Versuche Verbindung wiederherzustellen"+ " ...\n\nStelle sicher, dass deine Internetverbindung funktioniert.\nFalls das "+ "Problem weiterhin besteht, kontaktiere den Webmaster.") translation.put("error-connecting", "Fehler beim Verbindungsaufbau") translation.put("error-connecting-text", "Scribble.rs war nicht in der Lage eine Socket-Verbindung aufzubauen.\n\nZwar scheint dein "+ "Internet zu funktionieren, aber entweder wurden der Server oder \ndeine Firewall falsch konfiguriert.\n\n"+ "Versuche die Seite neu zu laden.") translation.put("message-too-long", "Deine Nachricht ist zu lang.") // Help dialog translation.put("controls", "Steuerung") translation.put("pencil", "Stift") translation.put("eraser", "Radiergummi") translation.put("fill-bucket", "Fülleimer") translation.put("switch-tools-intro", "Zwischen den Werkzeugen kannst du mit Tastaturkürzel wechseln") translation.put("switch-pencil-sizes", "Die Stiftgröße kannst du mit den Tasten %s bis %s verändern.") // Generic words // "close" as in "closing the window" translation.put("close", "Schließen") translation.put("no", "Nein") translation.put("yes", "Ja") translation.put("system", "System") // Footer translation.put("source-code", "Source Code") translation.put("help", "Hilfe") translation.put("submit-feedback", "Feedback") translation.put("stats", "Status") RegisterTranslation("de", translation) } ================================================ FILE: internal/translations/doc.go ================================================ /* Package translations introduces a simple localization layer that can be used by a templating engine. Upon retrieving a localization package, values can be retrieved in both Go code and the .html files via Get(key string). If a given key hasn't been translated, the default localization pack will be accessed. If the templating engine accesses non existent values, the server will panic. This makes sure that we can't oversee the use of non-existent values. Values must be plain text and not contain any HTML or CSS. If values are to be inserted dynamically, placeholders can be placed with "%s". */ package translations ================================================ FILE: internal/translations/en_us.go ================================================ package translations func initEnglishTranslation() *Translation { translation := createTranslation() translation.put("requires-js", "This website requires JavaScript to run properly.") translation.put("start-the-game", "Ready up!") translation.put("force-start", "Force Start") translation.put("force-restart", "Force Restart") translation.put("game-not-started-title", "Game hasn't started") translation.put("waiting-for-host-to-start", "Please wait for your lobby host to start the game.") translation.put("click-to-homepage", "Click here to get back to the Homepage") translation.put("now-spectating-title", "You are now spectating") translation.put("now-spectating-text", "You can leave the spectator mode by pressing the eye button at the top.") translation.put("now-participating-title", "You are now participating") translation.put("now-participating-text", "You can enter the spectator mode by pressing the eye button at the top.") translation.put("spectation-requested-title", "Spectator mode requested") translation.put("spectation-requested-text", "You'll be a spectator after this turn.") translation.put("participation-requested-title", "Participation requested") translation.put("participation-requested-text", "You'll be participating after this turn.") translation.put("spectation-request-cancelled-title", "Spectator mode requested cancelled") translation.put("spectation-request-cancelled-text", "Your spectation request has been cancelled, you will keep participating.") translation.put("participation-request-cancelled-title", "Participation requested cancelled") translation.put("participation-request-cancelled-text", "Your partiticpation request has been cancelled, you will keep spectating.") translation.put("round", "Round") translation.put("toggle-soundeffects", "Toggle soundeffects") translation.put("toggle-pen-pressure", "Toggle pen pressure") translation.put("change-your-name", "Nickname") translation.put("randomize", "Randomize") translation.put("apply", "Apply") translation.put("save", "Save") translation.put("toggle-fullscreen", "Toggle fullscreen") translation.put("toggle-spectate", "Toggle spectator mode") translation.put("show-help", "Show help") translation.put("votekick-a-player", "Vote to kick a player") translation.put("last-turn", "(Last turn: %s)") translation.put("drawer-kicked", "Since the kicked player has been drawing, none of you will get any points this round.") translation.put("self-kicked", "You have been kicked") translation.put("kick-vote", "(%s/%s) players voted to kick %s.") translation.put("player-kicked", "Player has been kicked.") translation.put("owner-change", "%s is the new lobby owner.") translation.put("change-lobby-settings-tooltip", "Change the lobby settings") translation.put("change-lobby-settings-title", "Lobby settings") translation.put("lobby-settings-changed", "Lobby settings changed") translation.put("advanced-settings", "Advanced Settings") translation.put("chill", "Chill") translation.put("competitive", "Competitive") translation.put("chill-alt", "While being fast is rewarded, it's not too bad if you are little slower.\nThe base score is rather high, focus on having fun!") translation.put("competitive-alt", "The faster you are, the more points you will get.\nThe base score is a lot lower and the decline is faster.") translation.put("score-calculation", "Scoring") translation.put("word-language", "Language") translation.put("drawing-time-setting", "Drawing Time") translation.put("rounds-setting", "Rounds") translation.put("max-players-setting", "Maximum Players") translation.put("public-lobby-setting", "Public Lobby") translation.put("custom-words", "Custom Words") translation.put("custom-words-info", "Enter your additional words, separating them by commas") translation.put("custom-words-placeholder", "Comma, separated, word, list, here") translation.put("custom-words-per-turn-setting", "Custom Words Per Turn") translation.put("players-per-ip-limit-setting", "Players per IP Limit") translation.put("words-per-turn-setting", "Words Per Turn") translation.put("save-settings", "Save settings") translation.put("input-contains-invalid-data", "Your input contains invalid data:") translation.put("please-fix-invalid-input", "Correct the invalid input and try again.") translation.put("create-lobby", "Create Lobby") translation.put("create-public-lobby", "Create Public Lobby") translation.put("create-private-lobby", "Create Private Lobby") translation.put("no-lobbies-yet", "There are no lobbies yet.") translation.put("lobby-full", "Sorry, but the lobby is full.") translation.put("lobby-ip-limit-excceeded", "Sorry, but you have exceeded the maximum number of clients per IP.") translation.put("lobby-open-tab-exists", "It appears you already have an open tab for this lobby.") translation.put("lobby-doesnt-exist", "The requested lobby doesn't exist") translation.put("refresh", "Refresh") translation.put("join-lobby", "Join Lobby") translation.put("message-input-placeholder", "Type your guesses and messages here") translation.put("word-choice-warning", "Word if you don't choose in time") translation.put("choose-a-word", "Choose a word") translation.put("waiting-for-word-selection", "Waiting for word selection") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "is choosing a word.") translation.put("close-guess", "'%s' is very close.") translation.put("correct-guess", "You have correctly guessed the word.") translation.put("correct-guess-other-player", "'%s' correctly guessed the word.") translation.put("round-over", "Turn over, no word was chosen.") translation.put("round-over-no-word", "Turn over, the word was '%s'.") translation.put("game-over-win", "Congratulations, you've won!") translation.put("game-over-tie", "It's a tie!") translation.put("game-over", "You placed %s. with %s points") translation.put("drawer-disconnected", "Turn ended early, drawer disconnected.") translation.put("guessers-disconnected", "Turn ended early, guessers disconnected.") translation.put("word-hint-revealed", "A word hint was revealed!") translation.put("change-active-color", "Change your active color") translation.put("use-pencil", "Use pencil") translation.put("use-eraser", "Use eraser") translation.put("use-fill-bucket", "Use fill bucket (Fills the target area with the selected color)") translation.put("change-pencil-size-to", "Change the pencil / eraser size to %s") translation.put("clear-canvas", "Clear the canvas") translation.put("undo", "Revert the last change you made (Doesn't work after \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "Connection lost!") translation.put("connection-lost-text", "Attempting to reconnect"+ " ...\n\nMake sure your internet connection works.\nIf the "+ "problem persists, contact the webmaster.") translation.put("error-connecting", "Error connecting to server") translation.put("error-connecting-text", "Scribble.rs couldn't establish a socket connection.\n\nWhile your internet "+ "connection seems to be working, either the\nserver or your firewall hasn't "+ "been configured correctly.\n\nTo retry, reload the page.") translation.put("message-too-long", "Your message is too long.") translation.put("server-shutting-down-title", "Server shutting down") translation.put("server-shutting-down-text", "Sorry, but the server is about to shut down. Please come back at a later time.") // Help dialog translation.put("controls", "Controls") translation.put("pencil", "Pencil") translation.put("eraser", "Eraser") translation.put("fill-bucket", "Fill bucket") translation.put("switch-tools-intro", "You can switch between tools using shortcuts") translation.put("switch-pencil-sizes", "You can also switch between pencil sizes using keys %s to %s.") // Generic words // "close" as in "closing the window" translation.put("close", "Close") translation.put("no", "No") translation.put("yes", "Yes") translation.put("system", "System") translation.put("confirm", "Okay") translation.put("ready", "Ready") translation.put("join", "Join") translation.put("ongoing", "Ongoing") translation.put("game-over-lobby", "Game Over") translation.put("source-code", "Source Code") translation.put("help", "Help") translation.put("submit-feedback", "Feedback") translation.put("stats", "Status") translation.put("forbidden", "Forbidden") RegisterTranslation("en", translation) return translation } ================================================ FILE: internal/translations/es_ES.go ================================================ package translations func initSpainTranslation() { translation := createTranslation() translation.put("requires-js", "Este sitio web requiere JavaScript para funcionar correctamente..") translation.put("start-the-game", "Prepárate!") translation.put("force-start", "Inicio forzado") translation.put("force-restart", "Force RestartReinicio forzado") translation.put("game-not-started-title", "El juego no ha comenzado") translation.put("waiting-for-host-to-start", "Por favor, espere a que el anfitrión de su lobby inicie el juego..") translation.put("now-spectating-title", "Ahora estás observando") translation.put("now-spectating-text", "Puedes salir del modo espectador presionando el botón del ojo en la parte superior.") translation.put("now-participating-title", "Ahora estás participando") translation.put("now-participating-text", "Puedes ingresar al modo espectador presionando el botón del ojo en la parte superior.") translation.put("spectation-requested-title", "Se solicita modo espectador") translation.put("spectation-requested-text", "Serás espectador después de este turno.") translation.put("participation-requested-title", "Se solicita participación") translation.put("participation-requested-text", "Participarás después de este turno..") translation.put("spectation-request-cancelled-title", "Se solicitó el modo espectador cancelado") translation.put("spectation-request-cancelled-text", "Tu solicitud de espectación ha sido cancelada, seguirás participando..") translation.put("participation-request-cancelled-title", "Participación solicitada cancelada") translation.put("participation-request-cancelled-text", "Tu solicitud de participación ha sido cancelada, continuarás viendo..") translation.put("round", "Redondo") translation.put("toggle-soundeffects", "Activar o desactivar efectos de sonido") translation.put("toggle-pen-pressure", "Alternar la presión del lápiz") translation.put("change-your-name", "Apodo") translation.put("randomize", "Aleatorizar") translation.put("apply", "Aplicar") translation.put("save", "Ahorrar") translation.put("toggle-fullscreen", "Cambiar a pantalla completa") translation.put("toggle-spectate", "Activar o desactivar el modo espectador") translation.put("show-help", "Mostrar ayuda") translation.put("votekick-a-player", "Votar para patear a un jugador") translation.put("last-turn", "(Último turno: %s)") translation.put("drawer-kicked", "Dado que el jugador expulsado ha estado robando, ninguno de ustedes obtendrá puntos en esta ronda.") translation.put("self-kicked", "Te han pateado") translation.put("kick-vote", "(%s/%s) Los jugadores votaron para patear %s.") translation.put("player-kicked", "El jugador ha sido expulsado.") translation.put("owner-change", "%s es el nuevo dueño del lobby.") translation.put("change-lobby-settings-tooltip", "Cambiar la configuración del lobby") translation.put("change-lobby-settings-title", "Configuración del lobby") translation.put("lobby-settings-changed", "Se cambiaron las configuraciones del lobby") translation.put("advanced-settings", "Configuración avanzada") translation.put("chill", "Enfriar") translation.put("competitive", "Competitivo") translation.put("chill-alt", "Aunque ser rápido tiene recompensa, no es tan malo si eres un poco más lento..\nLa puntuación base es bastante alta, concéntrate en divertirte.!") translation.put("competitive-alt", "Cuanto más rápido seas, más puntos obtendrás..\nLa puntuación base es mucho más baja y el descenso es más rápido..") translation.put("score-calculation", "Tanteo") translation.put("word-language", "Idioma") translation.put("drawing-time-setting", "Tiempo de dibujo") translation.put("rounds-setting", "Rondas") translation.put("max-players-setting", "Máximo de jugadores") translation.put("public-lobby-setting", "Vestíbulo público") translation.put("custom-words", "Palabras personalizadas") translation.put("custom-words-info", "Ingrese sus palabras adicionales, separándolas por comas") translation.put("custom-words-per-turn-setting", "Palabras personalizadas por turno") translation.put("players-per-ip-limit-setting", "Jugadores por límite de IP") translation.put("save-settings", "Guardar configuración") translation.put("input-contains-invalid-data", "Su entrada contiene datos no válidos:") translation.put("please-fix-invalid-input", "Corrija la entrada no válida y vuelva a intentarlo.") translation.put("create-lobby", "Crear lobby") translation.put("create-public-lobby", "Crear un lobby público") translation.put("create-private-lobby", "Crear un lobby privado") translation.put("refresh", "Refrescar") translation.put("join-lobby", "Únase al lobby") translation.put("message-input-placeholder", "Escribe tus conjeturas y mensajes aquí") translation.put("word-choice-warning", "Palabra si no eliges a tiempo") translation.put("choose-a-word", "Elige una palabra") translation.put("waiting-for-word-selection", "Esperando la selección de palabras") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "está eligiendo una palabra.") translation.put("close-guess", "'%s' está muy cerca.") translation.put("correct-guess", "Has adivinado correctamente la palabra..") translation.put("correct-guess-other-player", "'%s' adivinó correctamente la palabra.") translation.put("round-over", "Dé la vuelta, no se eligió ninguna palabra.") translation.put("round-over-no-word", "Al dar la vuelta, la palabra era '%s'.") translation.put("game-over-win", "¡Enhorabuena, has ganado!") translation.put("game-over-tie", "Es un empate!") translation.put("game-over", "Quedaste en %s lugar. Con %s puntos") translation.put("change-active-color", "Cambia tu color activo") translation.put("use-pencil", "Usa lápiz") translation.put("use-eraser", "Usar borrador") translation.put("use-fill-bucket", "UUtilice el cubo de llenado (Rellena el área objetivo con el color seleccionado)") translation.put("change-pencil-size-to", "Cambia el lápiz / tamaño del borrador a %s") translation.put("clear-canvas", "Limpiar el lienzo") translation.put("undo", "Revertir el último cambio realizado (No funciona después \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "Conexión perdida!") translation.put("connection-lost-text", "Intentando reconectarse"+ " ...\n\nAsegúrese de que su conexión a Internet funcione.\n"+ "Si el problema persiste, contacte con el webmaster..") translation.put("error-connecting", "Error al conectar con el servidor") translation.put("error-connecting-text", "Scribble.rs no se pudo establecer una conexión de socket.\n\nAunque su conexión "+ "a Internet parece funcionar, es posible que el servidor\no su firewall no se hayan "+ "configurado correctamente.\n\nPara volver a intentarlo, recarga la página.") translation.put("message-too-long", "Tu mensaje es demasiado largo.") // Help dialog translation.put("controls", "Controles") translation.put("pencil", "Lápiz") translation.put("eraser", "Borrador") translation.put("fill-bucket", "Llenar el cubo") translation.put("switch-tools-intro", "Puede cambiar entre herramientas mediante atajos") translation.put("switch-pencil-sizes", "También puedes cambiar entre tamaños de lápiz usando teclas %s para %s.") // Generic words // "close" as in "closing the window" translation.put("close", "Cerca") translation.put("no", "No") translation.put("yes", "Sí") translation.put("system", "Sistema") translation.put("source-code", "Código fuente") translation.put("help", "Ayuda") translation.put("submit-feedback", "Comentario") translation.put("stats", "Estado") RegisterTranslation("es", translation) } ================================================ FILE: internal/translations/fa.go ================================================ package translations func initPersianTranslation() *Translation { translation := createTranslation() translation.IsRtl = true translation.put("requires-js", "این وبسایت برای درست اجرا شدن نیاز به جاوااسکریپت داره.") translation.put("start-the-game", "بزن بریم!") translation.put("force-start", "شروع فوری") translation.put("force-restart", "راه‌اندازی دوباره فوری") translation.put("game-not-started-title", "بازی هنوز شروع نشده") translation.put("waiting-for-host-to-start", "لطفا منتظر میزبان لابی باشید تا بازی رو شروع کنه.") translation.put("click-to-homepage", "برای بازگشت به خونه اینجا رو کلیک کنید") translation.put("now-spectating-title", "الان شما تماشاچی هستید") translation.put("now-spectating-text", "برای خروج از حالت تماشاچی می‌تونید روی دکمه چشم بالای صفحه بزنید.") translation.put("now-participating-title", "الان شما شرکت‌کننده هستید") translation.put("now-participating-text", "برای ورود به حالت تماشاچی روی دکمه چشم بالای صفحه بزنید.") translation.put("spectation-requested-title", "حالت تماشاچی درخواست شد") translation.put("spectation-requested-text", "بعد از این دور بازی شما تماشاچی می‌شید.") translation.put("participation-requested-title", "درخواست شرکت تو بازی داده شد") translation.put("participation-requested-text", "بعد از این دور بازی شما هم می‌تونید بازی کنید.") translation.put("spectation-request-cancelled-title", "درخواست حالت تماشاچی لغو شد") translation.put("spectation-request-cancelled-text", "درخواست حالت تماشاچی لغو شد، می‌تونید به بازی ادامه بدید.") translation.put("participation-request-cancelled-title", "درخواست شرکت تو بازی لغو شد") translation.put("participation-request-cancelled-text", "درخواست شرکت تو بازی لغو شد، می‌تونید به تماشای بازی ادامه بدید.") translation.put("round", "دور") translation.put("toggle-soundeffects", "روشن/خاموش کردن افکت‌های صدا") translation.put("toggle-pen-pressure", "روشن/خاموش کردن فشار قلم") translation.put("change-your-name", "لقب") translation.put("randomize", "انتخاب تصادفی") translation.put("apply", "ثبت") translation.put("save", "ذخیره") translation.put("toggle-fullscreen", "روشن/خاموش کردن حالت تمام صفحه") translation.put("toggle-spectate", "روشن/خاموش کردن حالت تماشاچی") translation.put("show-help", "نمایش راهنما") translation.put("votekick-a-player", "رای به بیرون انداختن یه بازیکن") translation.put("last-turn", "(دور آخر: %s)") translation.put("drawer-kicked", "چون کسی که بیرون انداخته شد نقاش بود، هیچ کدوم از شما این دست امتیازی نمی‌گیرید.") translation.put("self-kicked", "شما بیرون انداخته شدید") translation.put("kick-vote", "(%s/%s) بازیکن رای به بیرون انداختن %s دادن.") translation.put("player-kicked", "بازیکن بیرون انداخته شد.") translation.put("owner-change", "%s میزبان جدید لابیه.") translation.put("change-lobby-settings-tooltip", "تغییر تنظیمات لابی") translation.put("change-lobby-settings-title", "تنظیمات لابی") translation.put("lobby-settings-changed", "تنظیمات لابی تغییر کرد") translation.put("advanced-settings", "تنظیمات پیشرفته") translation.put("chill", "دوستانه") translation.put("competitive", "رقابتی") translation.put("chill-alt", "درسته که سریع بودن جایزه داره، اما حالا یه کم یواش‌ترم باشی خیلی بد نیست.\nامتیاز پایه نسبتا بالاتره، روی عشق و حال تمرکز کن!") translation.put("competitive-alt", "هر چی سریع‌تر باشی، امتیاز بیشتری می‌گیری.\nامتیاز پایه خیلی پایین‌تره و سقوط سریع‌تره.") translation.put("score-calculation", "امتیازدهی") translation.put("word-language", "زبان واژه‌ها") translation.put("drawing-time-setting", "زمان نقاشی") translation.put("rounds-setting", "دورها") translation.put("max-players-setting", "بیشترین تعداد بازیکنان") translation.put("public-lobby-setting", "لابی همگانی") translation.put("custom-words", "واژه‌های سفارشی") translation.put("custom-words-info", "واژه‌های اضافی‌تونو وارد کنید،با کاما از هم جداشون کنید") translation.put("custom-words-placeholder", "فهرست, واژه‌های, جدا, شده, با, کاما") translation.put("custom-words-per-turn-setting", "واژه‌های سفارشی در هر نوبت") translation.put("players-per-ip-limit-setting", "حداکثر تعداد بازیکنن با یک IP") translation.put("save-settings", "ذخیره تنظیمات") translation.put("input-contains-invalid-data", "ورودی شامل داده اشتباهه:") translation.put("please-fix-invalid-input", "ورودی اشتباهو درست کنید و دوباره امتحان کنید.") translation.put("create-lobby", "ساخت لابی") translation.put("create-public-lobby", "ساخت لابی همگانی") translation.put("create-private-lobby", "ساخت لابی خصوصی") translation.put("no-lobbies-yet", "هنوز لابی همگانی نداریم.") translation.put("lobby-full", "ببخشید، ولی لابی پره.") translation.put("lobby-ip-limit-excceeded", "ببخشید، ولی شما تعداد دستگاه‌های مجاز با همین IP رو رد کردید.") translation.put("lobby-open-tab-exists", "به نظر میاد یه تب باز دیگه برای این لابی دارید.") translation.put("lobby-doesnt-exist", "لابی درخواستی وجود نداره") translation.put("refresh", "تازه کردن") translation.put("join-lobby", "ورود به لابی") translation.put("message-input-placeholder", "حدس‌ها و پیاماتو اینجا تایپ کن") translation.put("word-choice-warning", "اگه به موقع انتخاب نکنی این واژه انتخاب میشه") translation.put("choose-a-word", "یه واژه انتخاب کن") translation.put("waiting-for-word-selection", "در انتظار انتخاب واژه") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "داره واژه انتخاب می‌کنه.") translation.put("close-guess", "'%s' خیلی نزدیکه") translation.put("correct-guess", "شما واژه رو درست حدس زدید.") translation.put("correct-guess-other-player", "'%s' واژه رو درست حدس زد.") translation.put("round-over", "نوبت تموم شد، واژه‌ای انتخاب نشد.") translation.put("round-over-no-word", "نوبت تموم شد، واژه '%s' بود.") translation.put("game-over-win", "آفرین، تو بردی!") translation.put("game-over-tie", "بازی مساوی شد!") translation.put("game-over", "رتبه شما %s. با %s امتیاز") translation.put("drawer-disconnected", "دست زود‌تر تموم شد، ارتباط نقاش قطع شد.") translation.put("guessers-disconnected", "دست زودتر تموم شد، ارتباط بازیکنا قطع شد.") translation.put("change-active-color", "تغییر رنگ") translation.put("use-pencil", "استفاده از قلم") translation.put("use-eraser", "استفاده از پاک‌کن") translation.put("use-fill-bucket", "استفاده از سطل رنگ (ناحیه هدف رو با رنگ انتخاب شده رنگ می‌کنه)") translation.put("change-pencil-size-to", "تغییر اندازه قلم / پاک‌کن به %s") translation.put("clear-canvas", "پاک کردن بوم نقاشی") translation.put("undo", "برگردوندن آخرین تغییری که دادید (بعد از \""+translation.Get("clear-canvas")+"\" کار نمی‌کنه)") translation.put("connection-lost", "ارتباط قطع شد!") translation.put("connection-lost-text", "در تلاش برای برقراری ارتباط"+ " ...\n\nمطمئن شید که اینترنتتون وصله.\nاگر "+ "مشکل برقرار بود، با ادمین تماس بگیرید") translation.put("error-connecting", "خطا در برقراری ارتباط با سرور") translation.put("error-connecting-text", "Scribble.rs نتونست ارتباط رو برقرار کنه\n\nدر حالی که اینترنتتون "+ "به نظر میاد که کار می‌کنه، یا شاید\nسرور یا دیواره‌آتشتون "+ "درست تنظیم نشده.\n\nبرای تلاش دوباره، صفحه رو دوباره باز کنید.") translation.put("message-too-long", "پیام خیلی طولانیه.") translation.put("server-shutting-down-title", "سرور در حال خاموش شدنه") translation.put("server-shutting-down-text", "ببخشید، اما سرور در حال خاموش شدنه. لطفا چند لحظه دیگه برگردید.") // Help dialog translation.put("controls", "کلیدا") translation.put("pencil", "قلم") translation.put("eraser", "پاک‌کن") translation.put("fill-bucket", "سطل رنگ") translation.put("switch-tools-intro", "شما می‌تونید ابزارها رو با استفاده از کلیدای میانبر عوض کنید") translation.put("switch-pencil-sizes", "همچنین می‌تونید اندازه قلم رو با کلیدای %s تا %s عوض کنید.") // Generic words // "close" as in "closing the window" translation.put("close", "بستن") translation.put("no", "نه") translation.put("yes", "بله") translation.put("system", "سامانه") translation.put("confirm", "باشه") translation.put("ready", "آماده") translation.put("join", "ورود") translation.put("ongoing", "در حال برگزاری") translation.put("game-over-lobby", "بازی تموم شده") translation.put("source-code", "کد منبع") translation.put("help", "راهنمایی") translation.put("submit-feedback", "بازخورد") translation.put("stats", "وضعیت") translation.put("forbidden", "ممنوع") RegisterTranslation("fa", translation) return translation } ================================================ FILE: internal/translations/fr_FR.go ================================================ package translations func initFrenchTranslation() *Translation { translation := createTranslation() translation.put("requires-js", "Ce site nécessite JavaScript pour fonctionner correctement.") translation.put("start-the-game", "Prêt !") translation.put("force-start", "Forcer le démarrage") translation.put("force-restart", "Forcer le redémarrage") translation.put("game-not-started-title", "La partie n'a pas commencé") translation.put("waiting-for-host-to-start", "Veuillez attendre que l'hôte du salon démarre la partie.") translation.put("click-to-homepage", "Cliquez ici pour revenir à la page d'accueil") translation.put("now-spectating-title", "Vous êtes maintenant spectateur") translation.put("now-spectating-text", "Vous pouvez quitter le mode spectateur en appuyant sur le bouton œil en haut.") translation.put("now-participating-title", "Vous participez maintenant") translation.put("now-participating-text", "Vous pouvez activer le mode spectateur en appuyant sur le bouton œil en haut.") translation.put("spectation-requested-title", "Mode spectateur demandé") translation.put("spectation-requested-text", "Vous serez spectateur après ce tour.") translation.put("participation-requested-title", "Participation demandée") translation.put("participation-requested-text", "Vous participerez après ce tour.") translation.put("spectation-request-cancelled-title", "Demande de mode spectateur annulée") translation.put("spectation-request-cancelled-text", "Votre demande de spectateur a été annulée, vous resterez participant.") translation.put("participation-request-cancelled-title", "Demande de participation annulée") translation.put("participation-request-cancelled-text", "Votre demande de participation a été annulée, vous resterez spectateur.") translation.put("round", "Manche") translation.put("toggle-soundeffects", "Activer/désactiver les effets sonores") translation.put("toggle-pen-pressure", "Activer/désactiver la pression du stylet") translation.put("change-your-name", "Pseudo") translation.put("randomize", "Aléatoire") translation.put("apply", "Appliquer") translation.put("save", "Enregistrer") translation.put("toggle-fullscreen", "Activer/désactiver le plein écran") translation.put("toggle-spectate", "Activer/désactiver le mode spectateur") translation.put("show-help", "Afficher l'aide") translation.put("votekick-a-player", "Voter pour expulser un joueur") translation.put("last-turn", "(Dernier tour : %s)") translation.put("drawer-kicked", "Comme le joueur expulsé dessinait, personne ne gagnera de points ce tour.") translation.put("self-kicked", "Vous avez été expulsé") translation.put("kick-vote", "(%s/%s) joueurs ont voté pour expulser %s.") translation.put("player-kicked", "Le joueur a été expulsé.") translation.put("owner-change", "%s est le nouveau propriétaire du salon.") translation.put("change-lobby-settings-tooltip", "Modifier les paramètres du salon") translation.put("change-lobby-settings-title", "Paramètres du salon") translation.put("lobby-settings-changed", "Paramètres du salon modifiés") translation.put("advanced-settings", "Paramètres avancés") translation.put("chill", "Détente") translation.put("competitive", "Compétitif") translation.put("chill-alt", "La rapidité est récompensée, mais ce n'est pas grave si vous êtes un peu plus lent.\nLe score de base est assez élevé, l'essentiel est de s'amuser !") translation.put("competitive-alt", "Plus vous êtes rapide, plus vous gagnerez de points.\nLe score de base est bien plus bas et la baisse est plus rapide.") translation.put("score-calculation", "Score") translation.put("word-language", "Langue") translation.put("drawing-time-setting", "Temps de dessin") translation.put("rounds-setting", "Manches") translation.put("max-players-setting", "Joueurs maximum") translation.put("public-lobby-setting", "Salon public") translation.put("custom-words", "Mots personnalisés") translation.put("custom-words-info", "Saisissez vos mots supplémentaires en les séparant par des virgules") translation.put("custom-words-placeholder", "Liste, de, mots, séparés, par, des, virgules") translation.put("custom-words-per-turn-setting", "Mots personnalisés par tour") translation.put("players-per-ip-limit-setting", "Limite de joueurs par IP") translation.put("words-per-turn-setting", "Mots par tour") translation.put("save-settings", "Enregistrer les paramètres") translation.put("input-contains-invalid-data", "Votre saisie contient des données invalides :") translation.put("please-fix-invalid-input", "Corrigez la saisie invalide et réessayez.") translation.put("create-lobby", "Créer un salon") translation.put("create-public-lobby", "Créer un salon public") translation.put("create-private-lobby", "Créer un salon privé") translation.put("no-lobbies-yet", "Il n'y a encore aucun salon.") translation.put("lobby-full", "Désolé, le salon est complet.") translation.put("lobby-ip-limit-excceeded", "Désolé, vous avez dépassé le nombre maximal de clients par IP.") translation.put("lobby-open-tab-exists", "Il semble qu'un onglet pour ce salon soit déjà ouvert.") translation.put("lobby-doesnt-exist", "Le salon demandé n'existe pas") translation.put("refresh", "Actualiser") translation.put("join-lobby", "Rejoindre le salon") translation.put("message-input-placeholder", "Tapez ici vos propositions et messages") translation.put("word-choice-warning", "Mot choisi si vous ne décidez pas à temps") translation.put("choose-a-word", "Choisissez un mot") translation.put("waiting-for-word-selection", "En attente du choix du mot") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "choisit un mot.") translation.put("close-guess", "'%s' est très proche.") translation.put("correct-guess", "Vous avez correctement deviné le mot.") translation.put("correct-guess-other-player", "'%s' a correctement deviné le mot.") translation.put("round-over", "Tour terminé, aucun mot n'a été choisi.") translation.put("round-over-no-word", "Tour terminé, le mot était '%s'.") translation.put("game-over-win", "Félicitations, vous avez gagné !") translation.put("game-over-tie", "Égalité !") translation.put("game-over", "Vous avez terminé %s. avec %s points") translation.put("drawer-disconnected", "Tour terminé prématurément, le dessinateur s'est déconnecté.") translation.put("guessers-disconnected", "Tour terminé prématurément, les devineurs se sont déconnectés.") translation.put("word-hint-revealed", "Un indice du mot a été révélé !") translation.put("change-active-color", "Changer votre couleur active") translation.put("use-pencil", "Utiliser le crayon") translation.put("use-eraser", "Utiliser la gomme") translation.put("use-fill-bucket", "Utiliser le pot de peinture (Remplit la zone ciblée avec la couleur sélectionnée)") translation.put("change-pencil-size-to", "Changer la taille du crayon / de la gomme à %s") translation.put("clear-canvas", "Effacer le canevas") translation.put("undo", "Annuler la dernière modification effectuée (Ne fonctionne pas après \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "Connexion perdue !") translation.put("connection-lost-text", "Tentative de reconnexion"+ " ...\n\nAssurez-vous que votre connexion internet fonctionne.\nSi le "+ "problème persiste, contactez le webmaster.") translation.put("error-connecting", "Erreur de connexion au serveur") translation.put("error-connecting-text", "Scribble.rs n'a pas pu établir une connexion socket.\n\nBien que votre connexion internet "+ "semble fonctionner, soit le\nserveur, soit votre pare-feu n'a pas "+ "été configuré correctement.\n\nPour réessayer, rechargez la page.") translation.put("message-too-long", "Votre message est trop long.") translation.put("server-shutting-down-title", "Arrêt du serveur") translation.put("server-shutting-down-text", "Désolé, le serveur va s'arrêter. Merci de revenir plus tard.") // Help dialog translation.put("controls", "Contrôles") translation.put("pencil", "Crayon") translation.put("eraser", "Gomme") translation.put("fill-bucket", "Pot de peinture") translation.put("switch-tools-intro", "Vous pouvez changer d'outil à l'aide des raccourcis") translation.put("switch-pencil-sizes", "Vous pouvez aussi changer la taille du crayon avec les touches %s à %s.") // Generic words // "close" as in "closing the window" translation.put("close", "Fermer") translation.put("no", "Non") translation.put("yes", "Oui") translation.put("system", "Système") translation.put("confirm", "OK") translation.put("ready", "Prêt") translation.put("join", "Rejoindre") translation.put("ongoing", "En cours") translation.put("game-over-lobby", "Partie terminée") translation.put("source-code", "Code source") translation.put("help", "Aide") translation.put("submit-feedback", "Retour") translation.put("stats", "Statut") translation.put("forbidden", "Interdit") RegisterTranslation("fr", translation) return translation } ================================================ FILE: internal/translations/he.go ================================================ package translations func initHebrewTranslation() { translation := createTranslation() translation.IsRtl = true translation.put("requires-js", "אתר זה דורש JavaScript על מנת לעבוד בצורה תקינה") translation.put("start-the-game", "התכונן!") translation.put("force-start", "התחל בלי לחכות לכל השחקנים") translation.put("force-restart", "התחל מחדש") translation.put("game-not-started-title", "המשחק לא התחיל עדיין") translation.put("waiting-for-host-to-start", "המתן להתחלת המשחק על-ידי המארח") translation.put("click-to-homepage", "חזור לדף הבית") translation.put("now-spectating-title", "הינך במצב צפייה") translation.put("now-spectating-text", "ניתן לעזוב את מצב הצפייה על-ידי לחיצה על כפתור העין למעלה") translation.put("now-participating-title", "הינך משתתף במשחק") translation.put("now-participating-text", "ניתן לעבור למצב צפייה על-ידי לחיצה על כפתור העין למעלה") translation.put("spectation-requested-title", "ביקשת לעבור למצב צפייה") translation.put("spectation-requested-text", "תעבור למצב צפייה לאחר תור זה") translation.put("participation-requested-title", "ביקשת להשתתף במשחק") translation.put("participation-requested-text", "תצורף למשחק לאחר תור זה") translation.put("spectation-request-cancelled-title", "בקשת מצב צפייה בוטלה") translation.put("spectation-request-cancelled-text", "בקשתך לעבור למצב צפייה בוטלה, תמשיך להיות משתתף במשחק") translation.put("participation-request-cancelled-title", "בקשת השתתפות במשחק בוטלה") translation.put("participation-request-cancelled-text", "בקשתך להשתתף במשחק בוטלה, תמשיך להיות צופה במשחק") translation.put("round", "סיבוב") translation.put("toggle-soundeffects", "הפעלת/כיבוי סאונד") translation.put("toggle-pen-pressure", "הפעלת/כיבוי שליטה בלחץ העט") translation.put("change-your-name", "כינוי") translation.put("randomize", "אקראי") translation.put("apply", "החל") translation.put("save", "שמור") translation.put("toggle-fullscreen", "מסך מלא") translation.put("toggle-spectate", "הפעלת/כיבוי מצב צפייה") translation.put("show-help", "הצג עזרה") translation.put("votekick-a-player", "הצבע להרחקת שחקן") translation.put("last-turn", "(תור אחרון: %s)") translation.put("drawer-kicked", "השחקן שהורחק צייר, לכן אף שחקן לא ייקבל ניקוד בסיבוב זה") translation.put("self-kicked", "הורחקת מהמשחק") translation.put("kick-vote", "שחקנים הצביעו להרחיק את %s (%s/%s)") translation.put("player-kicked", "שחקן הורחק מהמשחק") translation.put("owner-change", "הוא המנהל החדש של הלובי %s") translation.put("change-lobby-settings-tooltip", "שינוי הגדרות לובי") translation.put("change-lobby-settings-title", "הגדרות לובי") translation.put("lobby-settings-changed", "הגדרות לובי שונו") translation.put("advanced-settings", "הגדרות מתקדמות") translation.put("chill", "רגוע") translation.put("competitive", "תחרותי") translation.put("chill-alt", "למרות שמהירות מתוגמלת בניקוד גבוה יותר, זה לא נורא אם אתם קצת יותר איטיים.\nהציון הבסיסי גבוה יחסית, אז התמקדו בליהנות!") translation.put("competitive-alt", "ככל שתהיו מהירים יותר, כך תקבלו יותר נקודות.\nהציון הבסיסי נמוך") translation.put("score-calculation", "שיטת ניקוד") translation.put("word-language", "שפה") translation.put("drawing-time-setting", "זמן ציור") translation.put("rounds-setting", "סיבובים") translation.put("max-players-setting", "מספר שחקנים מקסימלי") translation.put("public-lobby-setting", "לובי ציבורי") translation.put("custom-words", "מילים נוספות") translation.put("custom-words-info", "מילים נוספות מופרדות בפסיק") translation.put("custom-words-placeholder", "מילים, מופרדות, בפסיק, כאן") translation.put("custom-words-per-turn-setting", "מילים נוספות בכל תור") translation.put("players-per-ip-limit-setting", "הגבלת שחקנים לכתובת IP") translation.put("words-per-turn-setting", "מילים בכל תור") translation.put("save-settings", "שמור הגדרות") translation.put("input-contains-invalid-data", "הזנת תוכן לא חוקי") translation.put("please-fix-invalid-input", "תקן את התוכן ונסה שנית") translation.put("create-lobby", "יצירת לובי") translation.put("create-public-lobby", "לובי ציבורי") translation.put("create-private-lobby", "לובי פרטי") translation.put("no-lobbies-yet", "אין לובים") translation.put("lobby-full", "הלובי מלא") translation.put("lobby-ip-limit-excceeded", "עברת את מקבלת החיבורים עבור כתובת IP") translation.put("lobby-open-tab-exists", "נראה שכבר פתחת את לובי זה בלשונית אחרת") translation.put("lobby-doesnt-exist", "הלובי המבוקש אינו קיים") translation.put("refresh", "רענון") translation.put("join-lobby", "הצטרף ללובי") translation.put("message-input-placeholder", "כתוב כאן את הניחוש שלך") translation.put("word-choice-warning", "המילה אם לא תבחר בזמן") translation.put("choose-a-word", "בחר מילה") translation.put("waiting-for-word-selection", "המתן לבחירת מילה") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "בוחר מילה") translation.put("close-guess", "הניחוש '%s' קרוב לתשובה!") translation.put("correct-guess", "ניחשת נכון") translation.put("correct-guess-other-player", "'%s' ניחש נכון") translation.put("round-over", "התור נגמר, לא נבחרה מילה") translation.put("round-over-no-word", "התור נגמר. המילה הייתה '%s'") translation.put("game-over-win", "כל הכבוד, ניצחת!") translation.put("game-over-tie", "תיקו!") translation.put("game-over", "סיימת במקום ה %s עם %s נקודות") translation.put("drawer-disconnected", "התור הסתיים, השחקן שצייר התנתק") translation.put("guessers-disconnected", "התור הסתיים, כל השחקנים המנחשים התנתקו") translation.put("word-hint-revealed", "נחשף רמז") translation.put("change-active-color", "שינוי צבע") translation.put("use-pencil", "עיפרון") translation.put("use-eraser", "מחק") translation.put("use-fill-bucket", "דלי") translation.put("change-pencil-size-to", "שינוי גודל העיפרון/מחק ל %s") translation.put("clear-canvas", "ניקוי קאנבס") translation.put("undo", "ביטול שינוי אחרון (לא ניתן לבטל \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "החיבור עם השרת התנתק") translation.put("connection-lost-text", "מנסה להתחבר מחדש"+ " ...\n\nוודא שהחיבור לאינטרנט תקין") translation.put("error-connecting", "שגיאה בהתחברות לשרת") translation.put("error-connecting-text", "Scribble.rs לא הצליח ליצור חיבור Socket.\n\nלמרות שנראה שחיבור האינטרנט שלך עובד, או שה\nהשרת או חומת האש שלך לא הוגדרו כראוי.\n\nכדי לנסות שוב, טען מחדש את הדף.") translation.put("message-too-long", "ההודעה ארוכה מידי") translation.put("server-shutting-down-title", "השרת בתהליך כיבוי") translation.put("server-shutting-down-text", "מתנצלים אך השרת בתהליך כיבוי. נסו שוב מאוחר יותר") // Help dialog translation.put("controls", "כלים") translation.put("pencil", "עיפרון") translation.put("eraser", "מחק") translation.put("fill-bucket", "דלי") translation.put("switch-tools-intro", "ניתן להחליך בין הכלים השונים על-ידי שימוש בקיצורים") translation.put("switch-pencil-sizes", "ניתן לעבור בין גדלי העיפרון/מחק השונים על-ידי שימוש בכפתורים %s עד %s") // Generic words // "close" as in "closing the window" translation.put("close", "סגור") translation.put("no", "לא") translation.put("yes", "כן") translation.put("system", "מערכת") translation.put("confirm", "אישור") translation.put("ready", "מוכן") translation.put("join", "הצטרף") translation.put("ongoing", "פעיל") translation.put("game-over-lobby", "נגמר") translation.put("source-code", "קוד מקור") translation.put("help", "עזרה") translation.put("submit-feedback", "משוב") translation.put("stats", "סטטוס") translation.put("forbidden", "לא ניתן להציג דף זה") RegisterTranslation("he", translation) } ================================================ FILE: internal/translations/pl.go ================================================ package translations func initPolishTranslation() { translation := createTranslation() translation.put("requires-js", "Ta strona wymaga włączonej obsługi JavaScript aby działć poprawnie.") translation.put("start-the-game", "Gotowi!") translation.put("force-start", "Wymuś Start") translation.put("force-restart", "Wymuś Restart") translation.put("game-not-started-title", "Gra się nie zaczęła") translation.put("waiting-for-host-to-start", "Poczekaj aż gospodarz rozpocznie grę.") translation.put("now-spectating-title", "Jesteś teraz widzem") translation.put("now-spectating-text", "Możesz wyjść z trybu widza naciskając przycisk oka u góry ekranu.") translation.put("now-participating-title", "Jesteś teraz uczestnikiem") translation.put("now-participating-text", "Możesz wejść w tryb widza naciskając przycisk oka u góry ekranu.") translation.put("spectation-requested-title", "Zażądany tryb widza") translation.put("spectation-requested-text", "Staniesz się widzem po tej turze.") translation.put("participation-requested-title", "Zażądano uczestnictwa") translation.put("participation-requested-text", "Staniesz się uczestnikiem po tej turze.") translation.put("spectation-request-cancelled-title", "Anulowano żądanie trybu widza") translation.put("spectation-request-cancelled-text", "Anulowano twoje żądanie trybu widza, będziesz dalej uczestnikiem.") translation.put("participation-request-cancelled-title", "Anulowano żądanie uczestnictwa") translation.put("participation-request-cancelled-text", "Anulowano twoje żądanie uczestnictwa, będziesz dalej widzem.") translation.put("round", "Runda") translation.put("toggle-soundeffects", "Przełącz dźwięki") translation.put("change-your-name", "Ksywka") translation.put("randomize", "Losowo") translation.put("apply", "Zastosuj") translation.put("save", "Zapisz") translation.put("toggle-fullscreen", "Przełącz pełny ekran") translation.put("toggle-spectate", "Przełącz tryb widza") translation.put("show-help", "Pokaż pomoc") translation.put("votekick-a-player", "Głosuj za wykopaniem gracza") translation.put("last-turn", "(Ostatnia tura: %s)") translation.put("drawer-kicked", "Ponieważ wykopany gracz rysował, nikt z was nie dostanie punktów w tej rundzie.") translation.put("self-kicked", "Zostałeś wykopany") translation.put("kick-vote", "(%s/%s) gracze zagłosowali za wykopaniem %s.") translation.put("player-kicked", "Gracz został wykopany.") translation.put("owner-change", "%s jest nowym gospodarzem.") translation.put("change-lobby-settings-tooltip", "Zmień ustawienia lobby") translation.put("change-lobby-settings-title", "Ustawienia lobby") translation.put("lobby-settings-changed", "Ustawienia lobby zostały zmienione") translation.put("advanced-settings", "Ustawienia zaawansowane") translation.put("word-language", "Język") translation.put("drawing-time-setting", "Czas rysowania") translation.put("rounds-setting", "Rundy") translation.put("max-players-setting", "Maksymalna ilośc graczy") translation.put("public-lobby-setting", "Publiczne Lobby") translation.put("custom-words", "Własne słowa") translation.put("custom-words-info", "Wporowadź swoje dodatkowe słowa, rozdzielone przecinkami.") translation.put("custom-words-per-turn-setting", "Własne słowa na turę") translation.put("players-per-ip-limit-setting", "Limit graczy na adres IP") translation.put("save-settings", "Zapisz ustawienia") translation.put("input-contains-invalid-data", "Twoje wprowadzone dane są nieprawidłowe:") translation.put("please-fix-invalid-input", "Popraw błędy i sprobuj ponownie.") translation.put("create-lobby", "Stwórz Lobby") translation.put("create-public-lobby", "Stwórz Publiczne Lobby") translation.put("create-private-lobby", "Stwórz Prywatne Lobby") translation.put("refresh", "Odśwież") translation.put("join-lobby", "Wejdź do Lobby") translation.put("message-input-placeholder", "Tutaj wpisz swoje odpowiedzi i wiadomości") translation.put("choose-a-word", "Wybierz słowo") translation.put("waiting-for-word-selection", "Czekamy na wybranie słowa") // This one doesn't use %s, since we want to make one part bold. translation.put("is-choosing-word", "wybiera słowo.") translation.put("close-guess", "'%s' jest bardzo blisko.") translation.put("correct-guess", "Poprawnie zgadłeś(-aś) słowo.") translation.put("correct-guess-other-player", "'%s' poprawnie zgadł(a) słowo.") translation.put("round-over", "Koniec tury, nie wybrano żadnego słowa.") translation.put("round-over-no-word", "Koniec tury, słowo to '%s'.") translation.put("game-over-win", "Gratulacje, wygrałeś(-aś)!") translation.put("game-over-tie", "Remis!") translation.put("game-over", "Zająłeś %s. miejsce z %s punktami") translation.put("change-active-color", "Zmień swój aktywny kolor") translation.put("use-pencil", "Użyj ołówka") translation.put("use-eraser", "Użyj gumki") translation.put("use-fill-bucket", "Użyj wiadra (wypełnia obszar zaznaczonym kolorem)") translation.put("change-pencil-size-to", "Zmień rozmiar ołówka / gumki na %s") translation.put("clear-canvas", "Wyczyść kanwę") translation.put("undo", "Cofnij ostatnią zmianę (Nie działa po \""+translation.Get("clear-canvas")+"\")") translation.put("connection-lost", "Utracono połączenie!") translation.put("connection-lost-text", "Próbuję pnownie połączyć"+ " ...\n\nUpewnij się, że twoje połączenie internetowe działa.\nJeśli "+ "problem się utrzymuje, skontaktuj się z administratorem.") translation.put("error-connecting", "Błąd połączenia z serwerem") translation.put("error-connecting-text", "Scribble.rs nie może połączyć się z socketem.\n\nTwoje połączenie z internetem "+ "wydaje się działać, ale \nserver lub twoja zapora sieciowa nie "+ "zostały poprawnie skonfigurowane.\n\nOdśwież stronę aby spróbować ponownie.") translation.put("message-too-long", "Twoja wiadomość jest za długa.") // Help dialog translation.put("controls", "Sterowanie") translation.put("pencil", "Ołówek") translation.put("eraser", "Gumka") translation.put("fill-bucket", "Wiadro") translation.put("switch-tools-intro", "Możesz przełączać się pomiędzy narzędziami za pomocą skrótów") translation.put("switch-pencil-sizes", "Możesz też zmieniać rozmiary ołówka używają klawiszy %s do %s.") // Generic words // "close" as in "closing the window" translation.put("close", "Zamknij") translation.put("no", "Nie") translation.put("yes", "Tak") translation.put("system", "System") translation.put("source-code", "Kod Żródłowy") translation.put("help", "Pomoc") translation.put("submit-feedback", "Opinia") translation.put("stats", "Stan") RegisterTranslation("pl", translation) } ================================================ FILE: internal/translations/translations.go ================================================ package translations import ( "fmt" "strings" "golang.org/x/text/language" ) // init initializes all localization packs. Each new package has to be added // to this function. func init() { // We are making sure to add english first, since it's the default. DefaultTranslation = initEnglishTranslation() initGermanTranslation() initPolishTranslation() initSpainTranslation() initArabicTranslation() initHebrewTranslation() initPersianTranslation() initFrenchTranslation() } var translationRegistry = make(map[string]*Translation) // DefaultTranslation is the fallback translation for cases where the users // preferred language can't be found. This value is never returned by Get, but // has to be retrieved manually if desired. Currently, this is en-US. var DefaultTranslation *Translation // Translation represents key - value pairs of translated user interface // strings. type Translation struct { Dictionary map[string]string IsRtl bool } // Get retrieves a translated string or the default string if none could // be found. func (translation Translation) Get(key string) string { value, avail := translation.Dictionary[key] if avail { return value } fallbackValue, fallbackAvail := DefaultTranslation.Dictionary[key] if fallbackAvail { return fallbackValue } panic(fmt.Sprintf("no translation value available for key '%s'", key)) } // put adds a new key to the translation. If the key already exists, the // server panics. This happens on startup, therefore it's safe. func (translation Translation) put(key, value string) { _, avail := translation.Dictionary[key] if avail { panic(fmt.Sprintf("Duplicate key '%s'", key)) } if len(strings.TrimSpace(key)) != len(key) { panic(fmt.Sprintf("Language key '%s' contains leading or trailing whitespace", key)) } if len(strings.TrimSpace(value)) != len(value) { panic(fmt.Sprintf("Language key '%s' value contains leading or trailing whitespace", value)) } translation.Dictionary[key] = value } // GetLanguage retrieves a translation pack or nil if the desired package // couldn't be found. func GetLanguage(locale string) *Translation { return translationRegistry[locale] } // RegisterTranslation makes adds a language to the registry and makes // it available via Get. If the language is already registered, the server // panics. This happens on startup, therefore it's safe. func RegisterTranslation(locale string, translation *Translation) { // Make sure the locale is valid. language.MustParse(locale) localeLowercased := strings.ToLower(locale) _, avail := translationRegistry[localeLowercased] if avail { panic(fmt.Sprintf("Language '%s' has been registered multiple times", locale)) } if DefaultTranslation != nil { for key := range translation.Dictionary { _, fallbackValueAvail := DefaultTranslation.Dictionary[key] if !fallbackValueAvail { panic(fmt.Sprintf("Language key '%s' in language '%s' has no default translation value in 'en_US'", key, locale)) } } } translationRegistry[localeLowercased] = translation } func createTranslation() *Translation { return &Translation{ Dictionary: make(map[string]string), } } ================================================ FILE: internal/translations/translations_test.go ================================================ package translations import ( "fmt" "testing" "github.com/stretchr/testify/assert" ) func Test_noObsoleteKeys(t *testing.T) { for language, translationMap := range translationRegistry { t.Run(fmt.Sprintf("obsolete_keys_check_%s", language), func(t *testing.T) { for key := range translationMap.Dictionary { _, englishContainsKey := DefaultTranslation.Dictionary[key] assert.True(t, englishContainsKey, "key %s is obsolete", key) } }) } } ================================================ FILE: internal/version/version.go ================================================ // version holds the git that this version was built from. In development // scearios, it will default to "dev". package version import ( "regexp" ) // Version of the application. var ( Version = "dev" Commit = "" ) func init() { // We expect to get a "dirt git tag" when deploying a test version that // we did not yet finalize. We'll take it apart to allow the frontend // to put the correct link to the repository. if Version != "dev" { // version-commit_count_after_version-hash hashRegex := regexp.MustCompile(`v.+?(?:-\d+?-g(.+?)(?:$|-))`) match := hashRegex.FindStringSubmatch(Version) if len(match) == 2 { Commit = match[1] } } } ================================================ FILE: linux.Dockerfile ================================================ # # Builder for Golang # # We explicitly use a certain major version of go, to make sure we don't build # with a newer verison than we are using for CI tests, as we don't directly # test the produced binary but from source code directly. FROM docker.io/golang:1.25.5 AS builder WORKDIR /app # This causes caching of the downloaded go modules and makes repeated local # builds much faster. We must not copy the code first though, as a change in # the code causes a redownload. COPY go.mod go.sum ./ RUN go mod download -x # Import that this comes after mod download, as it breaks caching. ARG VERSION="dev" # Copy actual codebase, since we only have the go.mod and go.sum so far. COPY . /app/ ENV CGO_ENABLED=0 RUN go build -trimpath -ldflags "-w -s -X 'github.com/scribble-rs/scribble.rs/internal/version.Version=${VERSION}'" -tags timetzdata -o ./scribblers ./cmd/scribblers # # Runner # FROM scratch COPY --from=builder /app/scribblers /scribblers # The scratch image doesn't contain any certificates, therefore we use # the builders certificate, so that we can send HTTP requests. COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ ENTRYPOINT ["/scribblers"] # Random uid to avoid having root privileges. Linux doesn't care that there's no user for it. USER 248:248 ================================================ FILE: tools/compare_en_words.sh ================================================ #!/usr/bin/env bash US_DICT="../game/words/en_us" # For example on install british dict # apt-get install wbritish-large SYSTEM_GB_DICT='/usr/share/dict/british-english-large' OUTPUT_GB_DICT="../game/words/en_gb" FIXLIST="./fixlist" rm -f ${FIXLIST} ${OUTPUT_GB_DICT} while IFS= read -r line do grep -x ${line} ${SYSTEM_GB_DICT} # Check it exists in GB list if [[ $? == 0 ]]; then echo ${line} >> ${OUTPUT_GB_DICT} # Write to en_gb else echo ${line} >> ${FIXLIST} # Finally write to fixlist if no matches fi done < "${US_DICT}" ================================================ FILE: tools/sanitizer/README.md ================================================ # Sanitizer This tool lowercases, deduplicates, sorts and cleans the word lists. First argument is expected to be the wordlist and second argument the language shortcut, for example `en` for english. Don't pipe into the same file that you are reading from ;) ================================================ FILE: tools/sanitizer/main.go ================================================ package main import ( "bufio" "fmt" "io" "os" "sort" "strings" "golang.org/x/text/cases" "golang.org/x/text/language" ) func main() { languageFile, err := os.Open(os.Args[len(os.Args)-2]) if err != nil { panic(err) } lowercaser := cases.Lower(language.Make(os.Args[len(os.Args)-1])) reader := bufio.NewReader(languageFile) var words []string for { line, _, err := reader.ReadLine() if err != nil { if err == io.EOF { break } panic(err) } lineAsString := string(line) // Remove previously edited difficulty indicators, we don't really need it anymore. difficultyIndicatorIndex := strings.IndexRune(lineAsString, '#') if difficultyIndicatorIndex != -1 { lineAsString = lineAsString[:difficultyIndicatorIndex] } // Lowercase and trim, to make sure we can compare them without errors words = append(words, strings.TrimSpace(lowercaser.String(lineAsString))) } var filteredWords []string WORDS: for _, word := range words { for _, filteredWord := range filteredWords { if filteredWord == word { continue WORDS } } filteredWords = append(filteredWords, word) } // Filter for niceness sort.Strings(filteredWords) for _, word := range filteredWords { fmt.Println(word) } } ================================================ FILE: tools/simulate/main.go ================================================ package main import ( "encoding/json" "errors" "fmt" "io" "log" "math/rand/v2" "net/http" "strings" "time" "github.com/gofrs/uuid/v5" "github.com/lxzan/gws" "github.com/scribble-rs/scribble.rs/internal/api" ) type body struct { contentType string data io.Reader } func request(method, url string, body *body, queryParameters map[string]any) (*http.Response, error) { var data io.Reader if body != nil { data = body.data } request, err := http.NewRequest(method, url, data) if err != nil { return nil, fmt.Errorf("error perparing request: %w", err) } if body != nil { request.Header.Set("Content-Type", body.contentType) } query := request.URL.Query() for k, v := range queryParameters { query.Set(k, fmt.Sprint(v)) } request.URL.RawQuery = query.Encode() response, err := http.DefaultClient.Do(request) if err != nil { return nil, fmt.Errorf("error during http call: %w", err) } return response, nil } func PostLobby() (*api.LobbyData, error) { response, err := request(http.MethodPost, "http://localhost:8080/v1/lobby", nil, map[string]any{ "language": "english", "drawing_time": 120, "rounds": 4, "max_players": 12, "clients_per_ip_limit": 12, "custom_words_per_turn": 3, "public": true, }) if err != nil { return nil, fmt.Errorf("error sending request: %w", err) } if response.StatusCode != http.StatusOK { bytes, err := io.ReadAll(response.Body) if err != nil { return nil, err } fmt.Println(string(bytes)) } var lobby api.LobbyData if err := json.NewDecoder(response.Body).Decode(&lobby); err != nil { return nil, fmt.Errorf("error decoding response: %w", err) } return &lobby, err } type SimPlayer struct { Id string Name string Usersession string ws *gws.Conn } func (s *SimPlayer) WriteJSON(value any) error { bytes, err := json.Marshal(value) if err != nil { return err } return s.ws.WriteMessage(gws.OpcodeText, bytes) } func (s *SimPlayer) SendRandomStroke() { if err := s.WriteJSON(map[string]any{ "fromX": rand.Float64(), "fromY": rand.Float64(), "toX": rand.Float64(), "toY": rand.Float64(), "color": map[string]any{ "r": rand.Int32N(255), "g": rand.Int32N(255), "b": rand.Int32N(255), }, "lineWidth": 5, }); err != nil { log.Println("error writing:", err) } } func (s *SimPlayer) SendRandomMessage() { if err := s.WriteJSON(map[string]any{ "type": "message", "data": uuid.Must(uuid.NewV4()).String(), }); err != nil { log.Println("error writing:", err) } } func JoinPlayer(lobbyId string) (*SimPlayer, error) { lobbyUrl := "localhost:8080/v1/lobby/" + lobbyId response, err := request(http.MethodPost, "http://"+lobbyUrl+"/player", nil, map[string]any{ "username": uuid.Must(uuid.NewV4()).String(), }) if err != nil { return nil, fmt.Errorf("error sending request: %w", err) } if response.StatusCode != http.StatusOK { bytes, err := io.ReadAll(response.Body) if err != nil { return nil, err } return nil, errors.New(string(bytes)) } var session string for _, cookie := range response.Cookies() { if strings.EqualFold(cookie.Name, "Usersession") { session = cookie.Value break } } if session == "" { return nil, errors.New("no usersession") } headers := make(http.Header) headers.Set("usersession", session) wsConnection, response, err := gws.NewClient(gws.BuiltinEventHandler{}, &gws.ClientOption{ Addr: "ws://" + lobbyUrl + "/ws", RequestHeader: headers, }) if response != nil && response.StatusCode != http.StatusSwitchingProtocols { bytes, err := io.ReadAll(response.Body) if err != nil { return nil, err } return nil, errors.New(string(bytes)) } if err != nil { return nil, fmt.Errorf("error establishing websocket connection: %w", err) } return &SimPlayer{ Usersession: session, ws: wsConnection, }, nil } func main() { // lobby, err := PostLobby() // if err != nil { // panic(err) // } // log.Println("Lobby:", lobby.LobbyID) player, err := JoinPlayer("4cf284ff-8e18-4dc7-86a9-d2c2ed14227f") if err != nil { panic(err) } start := time.Now() for range 1_000_000 { player.SendRandomStroke() player.SendRandomMessage() } log.Println(time.Since(start).Seconds()) } ================================================ FILE: tools/skribbliohintsconverter/README.md ================================================ # Skribblio Hints Converter Converts lists from https://github.com/skribbliohints/skribbliohints.github.io into plain newline separated list. The list has to be passed as first argument. ================================================ FILE: tools/skribbliohintsconverter/english.json ================================================ {"bear":{"count":227,"lastSeenTime":1577025649999,"publicGameCount":5,"difficulty":0.4492753623188406,"difficultyWeight":138},"archaeologist":{"count":203,"lastSeenTime":1577035850371,"publicGameCount":3,"difficulty":0.7619047619047619,"difficultyWeight":21},"sunflower":{"count":417,"lastSeenTime":1577034315724,"publicGameCount":59,"difficulty":0.44967880085653106,"difficultyWeight":467},"hair":{"count":454,"lastSeenTime":1577025391428,"publicGameCount":30,"difficulty":0.42729970326409494,"difficultyWeight":337},"Vin Diesel":{"count":488,"lastSeenTime":1577037483079,"publicGameCount":13,"difficulty":0.7547169811320755,"difficultyWeight":106},"Daffy Duck":{"count":432,"lastSeenTime":1577032873667,"publicGameCount":20,"difficulty":0.7432432432432432,"difficultyWeight":148},"broomstick":{"count":215,"lastSeenTime":1577032648652,"difficulty":0.7317073170731707,"difficultyWeight":123,"publicGameCount":12},"unibrow":{"count":473,"lastSeenTime":1577035664302,"publicGameCount":45,"difficulty":0.6717171717171717,"difficultyWeight":396},"accident":{"count":237,"lastSeenTime":1577004853990,"publicGameCount":7,"difficulty":0.5849056603773585,"difficultyWeight":53},"saliva":{"count":429,"lastSeenTime":1576994904212,"publicGameCount":27,"difficulty":0.6136363636363636,"difficultyWeight":220},"Batman":{"count":430,"lastSeenTime":1577025104122,"difficulty":0.5263157894736845,"difficultyWeight":323,"publicGameCount":35},"radiation":{"count":240,"lastSeenTime":1577032236778,"publicGameCount":13,"difficulty":0.6545454545454545,"difficultyWeight":110},"boots":{"count":229,"lastSeenTime":1576967221649,"difficulty":0.581081081081081,"difficultyWeight":222,"publicGameCount":6},"tornado":{"count":436,"lastSeenTime":1577011796049,"publicGameCount":67,"difficulty":0.4551971326164874,"difficultyWeight":558},"skyscraper":{"count":434,"lastSeenTime":1577035483877,"publicGameCount":25,"difficulty":0.622549019607843,"difficultyWeight":204},"knife":{"count":421,"lastSeenTime":1577025391428,"publicGameCount":45,"difficulty":0.45208333333333334,"difficultyWeight":480},"witch":{"count":225,"lastSeenTime":1577024344558,"difficulty":0.5061728395061729,"difficultyWeight":162,"publicGameCount":17},"glass":{"count":422,"lastSeenTime":1577033178896,"publicGameCount":21,"difficulty":0.5797665369649806,"difficultyWeight":257},"Patrick":{"count":421,"lastSeenTime":1577037341722,"publicGameCount":61,"difficulty":0.44587155963302755,"difficultyWeight":545},"tank":{"count":425,"lastSeenTime":1577032857353,"difficulty":0.4811320754716981,"difficultyWeight":318,"publicGameCount":22},"type":{"count":226,"lastSeenTime":1577010004276,"publicGameCount":10,"difficulty":0.5,"difficultyWeight":78},"shampoo":{"count":223,"lastSeenTime":1577012059559,"publicGameCount":9,"difficulty":0.7380952380952381,"difficultyWeight":126},"emerald":{"count":233,"lastSeenTime":1577013669125,"publicGameCount":14,"difficulty":0.6546391752577319,"difficultyWeight":194},"factory":{"count":437,"lastSeenTime":1577035607642,"difficulty":0.602803738317757,"difficultyWeight":214,"publicGameCount":24},"apartment":{"count":434,"lastSeenTime":1577033358892,"publicGameCount":23,"difficulty":0.691860465116279,"difficultyWeight":172},"Darwin":{"count":209,"lastSeenTime":1576988845736,"difficulty":0.7307692307692307,"difficultyWeight":52,"publicGameCount":4},"pig":{"count":201,"lastSeenTime":1576984695357,"difficulty":0.43322475570032576,"difficultyWeight":307,"publicGameCount":4},"underweight":{"count":334,"lastSeenTime":1577025726927,"publicGameCount":20,"difficulty":0.7985611510791367,"difficultyWeight":139},"grandmother":{"count":224,"lastSeenTime":1577032873667,"publicGameCount":19,"difficulty":0.6344827586206897,"difficultyWeight":145},"bar":{"count":604,"lastSeenTime":1577037678090,"publicGameCount":48,"difficulty":0.719387755102041,"difficultyWeight":392},"short":{"count":435,"lastSeenTime":1577015139924,"publicGameCount":47,"difficulty":0.5896805896805896,"difficultyWeight":407},"iron":{"count":475,"lastSeenTime":1577035761130,"publicGameCount":33,"difficulty":0.602996254681648,"difficultyWeight":267},"cloth":{"count":240,"lastSeenTime":1577021075120,"publicGameCount":7,"difficulty":0.5148514851485149,"difficultyWeight":101},"William Wallace":{"count":414,"lastSeenTime":1577030272907,"publicGameCount":10,"difficulty":0.8208955223880597,"difficultyWeight":67},"skydiving":{"count":240,"lastSeenTime":1577024430436,"difficulty":0.5238095238095238,"difficultyWeight":84,"publicGameCount":11},"chopsticks":{"count":215,"lastSeenTime":1577024485059,"publicGameCount":14,"difficulty":0.6528925619834711,"difficultyWeight":121},"cord":{"count":235,"lastSeenTime":1577033383363,"difficulty":0.6417910447761194,"difficultyWeight":134,"publicGameCount":8},"rug":{"count":240,"lastSeenTime":1577031521720,"publicGameCount":4,"difficulty":0.6238532110091743,"difficultyWeight":109},"spaceship":{"count":239,"lastSeenTime":1577029674779,"publicGameCount":26,"difficulty":0.5866666666666667,"difficultyWeight":225},"moss":{"count":419,"lastSeenTime":1577037627992,"publicGameCount":13,"difficulty":0.5952380952380952,"difficultyWeight":168},"ponytail":{"count":219,"lastSeenTime":1577037472968,"publicGameCount":13,"difficulty":0.6524822695035462,"difficultyWeight":141},"elbow":{"count":435,"lastSeenTime":1577024181667,"publicGameCount":45,"difficulty":0.4511494252873563,"difficultyWeight":348},"path":{"count":426,"lastSeenTime":1577035263186,"difficulty":0.6653225806451614,"difficultyWeight":248,"publicGameCount":21},"Barack Obama":{"count":433,"lastSeenTime":1577036907083,"difficulty":0.7366666666666666,"difficultyWeight":300,"publicGameCount":39},"centaur":{"count":228,"lastSeenTime":1577007798107,"publicGameCount":9,"difficulty":0.7142857142857143,"difficultyWeight":91},"wave":{"count":435,"lastSeenTime":1577016460052,"difficulty":0.49999999999999983,"difficultyWeight":384,"publicGameCount":26},"cello":{"count":446,"lastSeenTime":1577025115050,"publicGameCount":20,"difficulty":0.6234567901234568,"difficultyWeight":162},"Mark Zuckerberg":{"count":452,"lastSeenTime":1577024267715,"publicGameCount":34,"difficulty":0.7542372881355932,"difficultyWeight":236},"sailboat":{"count":225,"lastSeenTime":1576995804799,"difficulty":0.6610878661087868,"difficultyWeight":239,"publicGameCount":20},"JayZ":{"count":428,"lastSeenTime":1577031444488,"publicGameCount":12,"difficulty":0.6782608695652174,"difficultyWeight":115},"cheeks":{"count":447,"lastSeenTime":1577034290492,"publicGameCount":35,"difficulty":0.6128048780487805,"difficultyWeight":328},"Dora":{"count":420,"lastSeenTime":1577031245121,"publicGameCount":33,"difficulty":0.6272727272727272,"difficultyWeight":330},"Ferrari":{"count":207,"lastSeenTime":1577030712255,"publicGameCount":11,"difficulty":0.6120689655172413,"difficultyWeight":116},"meatloaf":{"count":231,"lastSeenTime":1577011596369,"publicGameCount":9,"difficulty":0.6101694915254238,"difficultyWeight":59},"burglar":{"count":232,"lastSeenTime":1577033983037,"publicGameCount":15,"difficulty":0.7652173913043478,"difficultyWeight":115},"dog":{"count":216,"lastSeenTime":1577035914736,"difficulty":0.39880952380952384,"difficultyWeight":168},"double":{"count":245,"lastSeenTime":1576991022450,"difficulty":0.5909090909090909,"difficultyWeight":88,"publicGameCount":5},"sneeze":{"count":231,"lastSeenTime":1576981150242,"publicGameCount":10,"difficulty":0.6595744680851063,"difficultyWeight":141},"Tweety":{"count":422,"lastSeenTime":1577029664662,"publicGameCount":16,"difficulty":0.7423312883435583,"difficultyWeight":163},"Donald Duck":{"count":428,"lastSeenTime":1577015070109,"publicGameCount":38,"difficulty":0.6825396825396827,"difficultyWeight":252},"Pumba":{"count":403,"lastSeenTime":1577036549571,"publicGameCount":13,"difficulty":0.6952380952380952,"difficultyWeight":105},"messy":{"count":389,"lastSeenTime":1577037483079,"publicGameCount":21,"difficulty":0.6275510204081632,"difficultyWeight":196},"melt":{"count":229,"lastSeenTime":1577008913721,"publicGameCount":8,"difficulty":0.5607476635514019,"difficultyWeight":107},"graduation":{"count":224,"lastSeenTime":1577034742470,"publicGameCount":14,"difficulty":0.5789473684210527,"difficultyWeight":95},"wart":{"count":413,"lastSeenTime":1577020612196,"publicGameCount":11,"difficulty":0.5588235294117646,"difficultyWeight":102},"moose":{"count":231,"lastSeenTime":1577009754970,"difficulty":0.5,"difficultyWeight":86,"publicGameCount":2},"Zeus":{"count":464,"lastSeenTime":1577017445912,"publicGameCount":33,"difficulty":0.631578947368421,"difficultyWeight":266},"school":{"count":473,"lastSeenTime":1577033920831,"publicGameCount":49,"difficulty":0.6448598130841121,"difficultyWeight":428},"kiss":{"count":257,"lastSeenTime":1577011710244,"difficulty":0.6141304347826086,"difficultyWeight":184,"publicGameCount":11},"dream":{"count":427,"lastSeenTime":1577031013002,"publicGameCount":33,"difficulty":0.5730994152046782,"difficultyWeight":342},"Shrek":{"count":465,"lastSeenTime":1577016219244,"publicGameCount":46,"difficulty":0.536340852130326,"difficultyWeight":399},"snow":{"count":413,"lastSeenTime":1577029910813,"publicGameCount":41,"difficulty":0.5456919060052219,"difficultyWeight":383},"Steve Jobs":{"count":444,"lastSeenTime":1577003773529,"publicGameCount":11,"difficulty":0.8076923076923077,"difficultyWeight":78},"Hollywood":{"count":436,"lastSeenTime":1577033383363,"publicGameCount":24,"difficulty":0.5144230769230769,"difficultyWeight":208},"eclipse":{"count":209,"lastSeenTime":1577020326031,"difficulty":0.6145833333333333,"difficultyWeight":96,"publicGameCount":10},"record":{"count":624,"lastSeenTime":1577012339365,"difficulty":0.7423312883435582,"difficultyWeight":326,"publicGameCount":37},"sale":{"count":236,"lastSeenTime":1577032786045,"difficulty":0.5862068965517241,"difficultyWeight":116,"publicGameCount":5},"lottery":{"count":205,"lastSeenTime":1577030712255,"publicGameCount":13,"difficulty":0.6770186335403726,"difficultyWeight":161},"field":{"count":427,"lastSeenTime":1577031982423,"publicGameCount":22,"difficulty":0.6294117647058822,"difficultyWeight":170},"ring":{"count":208,"lastSeenTime":1577035607642,"difficulty":0.5165289256198347,"difficultyWeight":242,"publicGameCount":3},"pet shop":{"count":459,"lastSeenTime":1577031910884,"publicGameCount":36,"difficulty":0.6964285714285714,"difficultyWeight":280},"symphony":{"count":424,"lastSeenTime":1577025451893,"publicGameCount":5,"difficulty":0.5526315789473685,"difficultyWeight":38},"portal":{"count":229,"lastSeenTime":1577017407009,"difficulty":0.6845238095238095,"difficultyWeight":168,"publicGameCount":12},"ear":{"count":407,"lastSeenTime":1577037557962,"difficulty":0.46116504854368934,"difficultyWeight":412,"publicGameCount":13},"Elsa":{"count":426,"lastSeenTime":1577021143400,"publicGameCount":30,"difficulty":0.5142857142857139,"difficultyWeight":315},"basement":{"count":209,"lastSeenTime":1577034632349,"publicGameCount":7,"difficulty":0.7131782945736435,"difficultyWeight":129},"emoji":{"count":214,"lastSeenTime":1577010223357,"publicGameCount":27,"difficulty":0.5732217573221757,"difficultyWeight":239},"Elon Musk":{"count":429,"lastSeenTime":1577031296608,"publicGameCount":22,"difficulty":0.7659574468085106,"difficultyWeight":188},"Robbie Rotten":{"count":423,"lastSeenTime":1577035455493,"publicGameCount":12,"difficulty":0.8,"difficultyWeight":90},"security":{"count":224,"lastSeenTime":1577019859074,"publicGameCount":8,"difficulty":0.6666666666666666,"difficultyWeight":108},"Flash":{"count":441,"lastSeenTime":1577033129254,"publicGameCount":26,"difficulty":0.5311203319502076,"difficultyWeight":241},"Grinch":{"count":430,"lastSeenTime":1577036846155,"publicGameCount":40,"difficulty":0.5558823529411763,"difficultyWeight":340},"spy":{"count":217,"lastSeenTime":1577025952720,"publicGameCount":13,"difficulty":0.6666666666666666,"difficultyWeight":138},"finger":{"count":434,"lastSeenTime":1577025863283,"publicGameCount":37,"difficulty":0.4628099173553719,"difficultyWeight":363},"Ikea":{"count":422,"lastSeenTime":1577036211618,"difficulty":0.5130434782608696,"difficultyWeight":230,"publicGameCount":23},"loot":{"count":234,"lastSeenTime":1577036588307,"publicGameCount":9,"difficulty":0.6090909090909091,"difficultyWeight":110},"seahorse":{"count":216,"lastSeenTime":1577001950046,"publicGameCount":13,"difficulty":0.5197368421052632,"difficultyWeight":152},"bird bath":{"count":218,"lastSeenTime":1576994786459,"publicGameCount":13,"difficulty":0.7171717171717171,"difficultyWeight":99},"fabulous":{"count":437,"lastSeenTime":1577017839436,"publicGameCount":11,"difficulty":0.7176470588235294,"difficultyWeight":85},"Donald Trump":{"count":437,"lastSeenTime":1577025426672,"publicGameCount":62,"difficulty":0.6716738197424893,"difficultyWeight":466},"library":{"count":441,"lastSeenTime":1577021253681,"difficulty":0.576666666666667,"difficultyWeight":300,"publicGameCount":36},"panther":{"count":211,"lastSeenTime":1577037345324,"difficulty":0.675,"difficultyWeight":80,"publicGameCount":5},"birthday":{"count":247,"lastSeenTime":1577035568579,"publicGameCount":13,"difficulty":0.5416666666666665,"difficultyWeight":144},"nachos":{"count":232,"lastSeenTime":1577029749666,"difficulty":0.6206896551724138,"difficultyWeight":145,"publicGameCount":5},"dough":{"count":205,"lastSeenTime":1577035216186,"publicGameCount":7,"difficulty":0.574468085106383,"difficultyWeight":47},"Terminator":{"count":478,"lastSeenTime":1576995845059,"publicGameCount":17,"difficulty":0.7890625,"difficultyWeight":128},"Sydney Opera House":{"count":448,"lastSeenTime":1577037402133,"publicGameCount":15,"difficulty":0.7981651376146789,"difficultyWeight":109},"anthill":{"count":235,"lastSeenTime":1577035263186,"publicGameCount":6,"difficulty":0.6212121212121212,"difficultyWeight":66},"scar":{"count":454,"lastSeenTime":1577015610581,"publicGameCount":24,"difficulty":0.6103896103896104,"difficultyWeight":231},"quokka":{"count":222,"lastSeenTime":1576995830173,"publicGameCount":3,"difficulty":0.875,"difficultyWeight":40},"Angry Birds":{"count":443,"lastSeenTime":1577020626476,"publicGameCount":53,"difficulty":0.6882494004796164,"difficultyWeight":417},"happy":{"count":222,"lastSeenTime":1577036882731,"difficulty":0.5364238410596026,"difficultyWeight":151,"publicGameCount":10},"BMW":{"count":420,"lastSeenTime":1577017466404,"publicGameCount":20,"difficulty":0.5211267605633803,"difficultyWeight":213},"luggage":{"count":232,"lastSeenTime":1577034340467,"publicGameCount":9,"difficulty":0.7924528301886793,"difficultyWeight":106},"bacon":{"count":257,"lastSeenTime":1577037263306,"difficulty":0.5359477124183005,"difficultyWeight":153,"publicGameCount":14},"maze":{"count":217,"lastSeenTime":1577035554960,"difficulty":0.5670731707317073,"difficultyWeight":164,"publicGameCount":8},"brush":{"count":426,"lastSeenTime":1577013899075,"difficulty":0.5657492354740062,"difficultyWeight":327,"publicGameCount":37},"sand castle":{"count":243,"lastSeenTime":1577035338348,"publicGameCount":21,"difficulty":0.6226415094339622,"difficultyWeight":159},"tiny":{"count":434,"lastSeenTime":1577034376972,"publicGameCount":27,"difficulty":0.654761904761905,"difficultyWeight":252},"Minion":{"count":411,"lastSeenTime":1577035508304,"publicGameCount":49,"difficulty":0.49330357142857145,"difficultyWeight":448},"James Bond":{"count":443,"lastSeenTime":1577018880730,"publicGameCount":22,"difficulty":0.7696969696969697,"difficultyWeight":165},"beach":{"count":449,"lastSeenTime":1577034081969,"publicGameCount":47,"difficulty":0.5065616797900262,"difficultyWeight":381},"fork":{"count":435,"lastSeenTime":1577035656351,"publicGameCount":36,"difficulty":0.4231578947368421,"difficultyWeight":475},"sandwich":{"count":216,"lastSeenTime":1577006998548,"difficulty":0.6496815286624205,"difficultyWeight":157,"publicGameCount":13},"Australia":{"count":447,"lastSeenTime":1577034713991,"difficulty":0.6589861751152074,"difficultyWeight":217,"publicGameCount":25},"casino":{"count":424,"lastSeenTime":1577013957831,"difficulty":0.676056338028169,"difficultyWeight":142,"publicGameCount":13},"stoned":{"count":420,"lastSeenTime":1577032849365,"difficulty":0.7444444444444445,"difficultyWeight":180,"publicGameCount":19},"Antarctica":{"count":481,"lastSeenTime":1577037031237,"difficulty":0.7928994082840237,"difficultyWeight":169,"publicGameCount":23},"AC/DC":{"count":430,"lastSeenTime":1577024663216,"difficulty":0.7034482758620689,"difficultyWeight":145,"publicGameCount":8},"Jackie Chan":{"count":423,"lastSeenTime":1577037331094,"publicGameCount":25,"difficulty":0.6931818181818182,"difficultyWeight":176},"reeds":{"count":412,"lastSeenTime":1577037236956,"publicGameCount":4,"difficulty":0.8125,"difficultyWeight":32},"oval":{"count":217,"lastSeenTime":1577024968702,"publicGameCount":17,"difficulty":0.4642857142857143,"difficultyWeight":168},"scoop":{"count":246,"lastSeenTime":1577007933571,"difficulty":0.5913978494623657,"difficultyWeight":93,"publicGameCount":9},"gnome":{"count":197,"lastSeenTime":1577034340467,"difficulty":0.509090909090909,"difficultyWeight":110,"publicGameCount":5},"taser":{"count":230,"lastSeenTime":1576995770863,"publicGameCount":15,"difficulty":0.675,"difficultyWeight":160},"bingo":{"count":218,"lastSeenTime":1577025852952,"difficulty":0.5909090909090909,"difficultyWeight":110,"publicGameCount":8},"arrow":{"count":412,"lastSeenTime":1577024485059,"publicGameCount":49,"difficulty":0.3867403314917127,"difficultyWeight":543},"blender":{"count":207,"lastSeenTime":1577036121146,"publicGameCount":8,"difficulty":0.6,"difficultyWeight":70},"America":{"count":456,"lastSeenTime":1577033393491,"publicGameCount":53,"difficulty":0.5124378109452735,"difficultyWeight":402},"bakery":{"count":439,"lastSeenTime":1577019302199,"publicGameCount":17,"difficulty":0.6375,"difficultyWeight":160},"point":{"count":447,"lastSeenTime":1577016293273,"publicGameCount":28,"difficulty":0.5714285714285714,"difficultyWeight":294},"fly swatter":{"count":249,"lastSeenTime":1577034329984,"publicGameCount":18,"difficulty":0.6615384615384615,"difficultyWeight":130},"ski":{"count":255,"lastSeenTime":1577016713300,"difficulty":0.45454545454545453,"difficultyWeight":110,"publicGameCount":6},"condiment":{"count":247,"lastSeenTime":1577032752804,"publicGameCount":4,"difficulty":0.7678571428571429,"difficultyWeight":56},"knee":{"count":445,"lastSeenTime":1577032051558,"publicGameCount":39,"difficulty":0.44984802431610943,"difficultyWeight":329},"dandruff":{"count":454,"lastSeenTime":1577037638341,"publicGameCount":16,"difficulty":0.7711864406779662,"difficultyWeight":118},"yearbook":{"count":240,"lastSeenTime":1577032444866,"difficulty":0.6309523809523809,"difficultyWeight":84,"publicGameCount":8},"mouth":{"count":463,"lastSeenTime":1577035287582,"difficulty":0.5626740947075206,"difficultyWeight":359,"publicGameCount":42},"cabinet":{"count":224,"lastSeenTime":1577036588307,"difficulty":0.7222222222222222,"difficultyWeight":54,"publicGameCount":5},"cold":{"count":428,"lastSeenTime":1577037131444,"publicGameCount":40,"difficulty":0.5800604229607251,"difficultyWeight":331},"Mercury":{"count":227,"lastSeenTime":1577021133236,"publicGameCount":12,"difficulty":0.7567567567567568,"difficultyWeight":148},"ice":{"count":434,"lastSeenTime":1577036791454,"publicGameCount":42,"difficulty":0.5347721822541969,"difficultyWeight":417},"skull":{"count":466,"lastSeenTime":1577034440167,"publicGameCount":53,"difficulty":0.48739495798319316,"difficultyWeight":476},"tire":{"count":199,"lastSeenTime":1577019660052,"publicGameCount":5,"difficulty":0.6164383561643836,"difficultyWeight":146},"barbecue":{"count":223,"lastSeenTime":1577037688224,"publicGameCount":18,"difficulty":0.7928994082840237,"difficultyWeight":169},"Mercedes":{"count":456,"lastSeenTime":1577030922860,"publicGameCount":33,"difficulty":0.6395348837209303,"difficultyWeight":258},"icicle":{"count":424,"lastSeenTime":1577035469679,"publicGameCount":27,"difficulty":0.676,"difficultyWeight":250},"muscle":{"count":432,"lastSeenTime":1577012030780,"difficulty":0.5077881619937695,"difficultyWeight":321,"publicGameCount":42},"wedding":{"count":218,"lastSeenTime":1577033841722,"difficulty":0.6538461538461539,"difficultyWeight":130,"publicGameCount":14},"librarian":{"count":210,"lastSeenTime":1577020860567,"publicGameCount":5,"difficulty":0.7954545454545454,"difficultyWeight":44},"Amsterdam":{"count":436,"lastSeenTime":1577030033309,"publicGameCount":13,"difficulty":0.6065573770491803,"difficultyWeight":122},"hotel":{"count":411,"lastSeenTime":1577015814834,"publicGameCount":21,"difficulty":0.5327868852459018,"difficultyWeight":244},"plow":{"count":441,"lastSeenTime":1577015335750,"publicGameCount":11,"difficulty":0.6274509803921567,"difficultyWeight":102},"weak":{"count":437,"lastSeenTime":1577017556724,"publicGameCount":17,"difficulty":0.6052631578947368,"difficultyWeight":152},"nail":{"count":627,"lastSeenTime":1577034214987,"difficulty":0.5587349397590361,"difficultyWeight":664,"publicGameCount":80},"Peppa Pig":{"count":443,"lastSeenTime":1577029699092,"difficulty":0.631578947368421,"difficultyWeight":475,"publicGameCount":58},"target":{"count":230,"lastSeenTime":1577020058754,"publicGameCount":6,"difficulty":0.5586854460093895,"difficultyWeight":213},"bagpipes":{"count":467,"lastSeenTime":1577020250301,"difficulty":0.883495145631068,"difficultyWeight":103,"publicGameCount":9},"carnival":{"count":242,"lastSeenTime":1577000681812,"difficulty":0.7582417582417582,"difficultyWeight":91,"publicGameCount":10},"storm":{"count":456,"lastSeenTime":1577035961642,"publicGameCount":43,"difficulty":0.4766355140186916,"difficultyWeight":321},"cookie jar":{"count":241,"lastSeenTime":1576981874066,"publicGameCount":18,"difficulty":0.6824324324324323,"difficultyWeight":148},"florist":{"count":244,"lastSeenTime":1577033102907,"publicGameCount":6,"difficulty":0.7540983606557377,"difficultyWeight":61},"hop":{"count":218,"lastSeenTime":1576980767661,"publicGameCount":10,"difficulty":0.6976744186046512,"difficultyWeight":129},"keg":{"count":224,"lastSeenTime":1577001275584,"publicGameCount":5,"difficulty":0.7101449275362319,"difficultyWeight":69},"spaghetti":{"count":252,"lastSeenTime":1577033670196,"publicGameCount":34,"difficulty":0.6130268199233716,"difficultyWeight":261},"hive":{"count":216,"lastSeenTime":1576998831960,"publicGameCount":7,"difficulty":0.48,"difficultyWeight":75},"compass":{"count":427,"lastSeenTime":1577035947488,"publicGameCount":51,"difficulty":0.4618834080717489,"difficultyWeight":446},"air conditioner":{"count":211,"lastSeenTime":1577033129254,"publicGameCount":7,"difficulty":0.7619047619047619,"difficultyWeight":42},"golf cart":{"count":228,"lastSeenTime":1577007159755,"publicGameCount":15,"difficulty":0.6910569105691057,"difficultyWeight":123},"bus stop":{"count":476,"lastSeenTime":1577036377269,"publicGameCount":36,"difficulty":0.6796536796536796,"difficultyWeight":231},"pants":{"count":233,"lastSeenTime":1577004312386,"publicGameCount":5,"difficulty":0.46195652173913043,"difficultyWeight":184},"forehead":{"count":483,"lastSeenTime":1577035358654,"publicGameCount":33,"difficulty":0.5758620689655174,"difficultyWeight":290},"basket":{"count":229,"lastSeenTime":1577004751157,"difficulty":0.5579710144927537,"difficultyWeight":138,"publicGameCount":11},"mechanic":{"count":233,"lastSeenTime":1576986317705,"publicGameCount":6,"difficulty":0.6382978723404256,"difficultyWeight":47},"zoo":{"count":440,"lastSeenTime":1577034546199,"publicGameCount":31,"difficulty":0.5714285714285716,"difficultyWeight":287},"ladybug":{"count":207,"lastSeenTime":1577004792479,"publicGameCount":18,"difficulty":0.45754716981132076,"difficultyWeight":212},"mothball":{"count":255,"lastSeenTime":1577037092671,"publicGameCount":4,"difficulty":0.8857142857142857,"difficultyWeight":35},"Nemo":{"count":426,"lastSeenTime":1577024576475,"publicGameCount":39,"difficulty":0.4492753623188406,"difficultyWeight":345},"cute":{"count":455,"lastSeenTime":1577020425587,"publicGameCount":35,"difficulty":0.660377358490566,"difficultyWeight":265},"printer":{"count":217,"lastSeenTime":1577018843554,"difficulty":0.75,"difficultyWeight":68,"publicGameCount":2},"palette":{"count":230,"lastSeenTime":1577016110707,"publicGameCount":8,"difficulty":0.7192982456140351,"difficultyWeight":57},"royal":{"count":473,"lastSeenTime":1577035975818,"publicGameCount":32,"difficulty":0.6964285714285714,"difficultyWeight":280},"border":{"count":425,"lastSeenTime":1577032076358,"publicGameCount":23,"difficulty":0.59375,"difficultyWeight":224},"London Eye":{"count":447,"lastSeenTime":1577019695028,"publicGameCount":19,"difficulty":0.8059701492537313,"difficultyWeight":134},"picnic":{"count":217,"lastSeenTime":1577031433614,"publicGameCount":5,"difficulty":0.66,"difficultyWeight":50},"Christmas":{"count":231,"lastSeenTime":1577014939690,"publicGameCount":18,"difficulty":0.5155279503105592,"difficultyWeight":161},"nurse":{"count":213,"lastSeenTime":1577015139924,"publicGameCount":6,"difficulty":0.4896551724137931,"difficultyWeight":145},"dwarf":{"count":200,"lastSeenTime":1577033494000,"difficulty":0.6932515337423313,"difficultyWeight":163,"publicGameCount":17},"alpaca":{"count":206,"lastSeenTime":1577036070954,"publicGameCount":4,"difficulty":0.6551724137931034,"difficultyWeight":58},"hopscotch":{"count":200,"lastSeenTime":1577024805982,"difficulty":0.59375,"difficultyWeight":128,"publicGameCount":10},"garage":{"count":214,"lastSeenTime":1576989156663,"difficulty":0.5746268656716418,"difficultyWeight":134,"publicGameCount":9},"eggplant":{"count":216,"lastSeenTime":1577032066062,"publicGameCount":12,"difficulty":0.5437788018433181,"difficultyWeight":217},"strong":{"count":450,"lastSeenTime":1577029593108,"publicGameCount":27,"difficulty":0.5201793721973095,"difficultyWeight":223},"rocket":{"count":243,"lastSeenTime":1576985426678,"publicGameCount":15,"difficulty":0.5061224489795918,"difficultyWeight":245},"scientist":{"count":206,"lastSeenTime":1577013370658,"publicGameCount":8,"difficulty":0.49999999999999994,"difficultyWeight":100},"bow":{"count":644,"lastSeenTime":1577035579255,"publicGameCount":89,"difficulty":0.5365126676602088,"difficultyWeight":671},"landscape":{"count":430,"lastSeenTime":1577002755949,"publicGameCount":29,"difficulty":0.7449392712550608,"difficultyWeight":247},"fingernail":{"count":451,"lastSeenTime":1577008836893,"publicGameCount":46,"difficulty":0.6307692307692305,"difficultyWeight":325},"pound":{"count":450,"lastSeenTime":1577032516007,"publicGameCount":17,"difficulty":0.5352941176470588,"difficultyWeight":170},"pumpkin":{"count":248,"lastSeenTime":1577035813853,"difficulty":0.5115207373271888,"difficultyWeight":217,"publicGameCount":22},"bait":{"count":236,"lastSeenTime":1576978397196,"publicGameCount":4,"difficulty":0.6438356164383562,"difficultyWeight":73},"lyrics":{"count":443,"lastSeenTime":1577020474773,"publicGameCount":15,"difficulty":0.7837837837837838,"difficultyWeight":148},"wrinkle":{"count":443,"lastSeenTime":1577009521220,"publicGameCount":19,"difficulty":0.6408450704225352,"difficultyWeight":142},"palm tree":{"count":450,"lastSeenTime":1577032701751,"publicGameCount":53,"difficulty":0.5245901639344265,"difficultyWeight":427},"Ireland":{"count":434,"lastSeenTime":1577037678090,"difficulty":0.6615384615384615,"difficultyWeight":130,"publicGameCount":16},"sombrero":{"count":215,"lastSeenTime":1577018482673,"publicGameCount":11,"difficulty":0.6821705426356589,"difficultyWeight":129},"stapler":{"count":223,"lastSeenTime":1576991677127,"publicGameCount":11,"difficulty":0.54014598540146,"difficultyWeight":137},"Apple":{"count":435,"lastSeenTime":1577037070414,"publicGameCount":85,"difficulty":0.3912248628884826,"difficultyWeight":547},"Israel":{"count":445,"lastSeenTime":1577025104883,"publicGameCount":19,"difficulty":0.676923076923077,"difficultyWeight":130},"birch":{"count":457,"lastSeenTime":1577020225357,"publicGameCount":11,"difficulty":0.6909090909090909,"difficultyWeight":110},"western":{"count":421,"lastSeenTime":1577032763018,"publicGameCount":18,"difficulty":0.776536312849162,"difficultyWeight":179},"Hulk":{"count":410,"lastSeenTime":1577033369181,"publicGameCount":40,"difficulty":0.5592286501377411,"difficultyWeight":363},"helmet":{"count":239,"lastSeenTime":1577024499507,"difficulty":0.5886524822695034,"difficultyWeight":141,"publicGameCount":13},"Africa":{"count":447,"lastSeenTime":1577024296338,"publicGameCount":30,"difficulty":0.64,"difficultyWeight":250},"vlogger":{"count":222,"lastSeenTime":1577036183989,"publicGameCount":7,"difficulty":0.6440677966101694,"difficultyWeight":59},"Kermit":{"count":442,"lastSeenTime":1576981253418,"publicGameCount":23,"difficulty":0.6391752577319587,"difficultyWeight":194},"clean":{"count":647,"lastSeenTime":1577035855162,"difficulty":0.6486486486486487,"difficultyWeight":259,"publicGameCount":30},"patio":{"count":218,"lastSeenTime":1576949627341,"difficulty":0.8,"difficultyWeight":25,"publicGameCount":1},"windmill":{"count":434,"lastSeenTime":1577032716307,"publicGameCount":43,"difficulty":0.43042071197411,"difficultyWeight":309},"skeleton":{"count":425,"lastSeenTime":1577035664302,"publicGameCount":50,"difficulty":0.48756218905472637,"difficultyWeight":402},"backbone":{"count":461,"lastSeenTime":1577036791454,"publicGameCount":13,"difficulty":0.6759259259259259,"difficultyWeight":108},"feather":{"count":212,"lastSeenTime":1577036598485,"difficulty":0.710691823899371,"difficultyWeight":159,"publicGameCount":10},"submarine":{"count":227,"lastSeenTime":1577034613528,"difficulty":0.5486111111111112,"difficultyWeight":144,"publicGameCount":13},"beef":{"count":204,"lastSeenTime":1577035775298,"publicGameCount":12,"difficulty":0.6294117647058824,"difficultyWeight":170},"rib":{"count":458,"lastSeenTime":1577037016878,"publicGameCount":25,"difficulty":0.6130653266331657,"difficultyWeight":199},"day":{"count":228,"lastSeenTime":1577024514106,"publicGameCount":3,"difficulty":0.72,"difficultyWeight":75},"quill":{"count":201,"lastSeenTime":1576964925367,"publicGameCount":9,"difficulty":0.7155172413793104,"difficultyWeight":116},"spore":{"count":420,"lastSeenTime":1577024282018,"publicGameCount":6,"difficulty":0.7413793103448276,"difficultyWeight":58},"skribbl.io":{"count":214,"lastSeenTime":1577004022286,"difficulty":0.7004608294930875,"difficultyWeight":217,"publicGameCount":5},"yellow":{"count":425,"lastSeenTime":1577013370658,"difficulty":0.44611528822055135,"difficultyWeight":399,"publicGameCount":44},"legs":{"count":427,"lastSeenTime":1577031113164,"publicGameCount":42,"difficulty":0.43781094527363185,"difficultyWeight":402},"black":{"count":454,"lastSeenTime":1576991548923,"publicGameCount":45,"difficulty":0.4342105263157895,"difficultyWeight":380},"nightclub":{"count":410,"lastSeenTime":1577034135613,"publicGameCount":15,"difficulty":0.7163120567375887,"difficultyWeight":141},"Italy":{"count":460,"lastSeenTime":1577012120756,"publicGameCount":37,"difficulty":0.6181318681318682,"difficultyWeight":364},"anchor":{"count":233,"lastSeenTime":1577025889721,"publicGameCount":8,"difficulty":0.5126050420168068,"difficultyWeight":119},"mask":{"count":245,"lastSeenTime":1576978131498,"publicGameCount":12,"difficulty":0.4866666666666667,"difficultyWeight":150},"fabric":{"count":240,"lastSeenTime":1577019533344,"publicGameCount":3,"difficulty":0.8108108108108109,"difficultyWeight":37},"kindergarten":{"count":412,"lastSeenTime":1577031943447,"publicGameCount":20,"difficulty":0.7377049180327869,"difficultyWeight":122},"diss track":{"count":455,"lastSeenTime":1577033007248,"publicGameCount":9,"difficulty":0.8378378378378378,"difficultyWeight":74},"pencil":{"count":215,"lastSeenTime":1577008446028,"publicGameCount":10,"difficulty":0.48258706467661694,"difficultyWeight":201},"spit":{"count":221,"lastSeenTime":1577033454373,"publicGameCount":6,"difficulty":0.5048543689320388,"difficultyWeight":103},"Medusa":{"count":461,"lastSeenTime":1577034253534,"difficulty":0.6017316017316018,"difficultyWeight":231,"publicGameCount":24},"glue stick":{"count":229,"lastSeenTime":1576997743182,"publicGameCount":26,"difficulty":0.6481481481481481,"difficultyWeight":216},"Suez Canal":{"count":420,"lastSeenTime":1577020200660,"publicGameCount":11,"difficulty":0.8020833333333334,"difficultyWeight":96},"tooth":{"count":449,"lastSeenTime":1577029925040,"difficulty":0.5183150183150184,"difficultyWeight":546,"publicGameCount":59},"stop sign":{"count":451,"lastSeenTime":1577029554508,"publicGameCount":60,"difficulty":0.5022123893805309,"difficultyWeight":452},"prawn":{"count":424,"lastSeenTime":1577035937353,"publicGameCount":17,"difficulty":0.6808510638297873,"difficultyWeight":141},"peas":{"count":215,"lastSeenTime":1576971627380,"publicGameCount":4,"difficulty":0.574468085106383,"difficultyWeight":188},"clownfish":{"count":220,"lastSeenTime":1576964515718,"publicGameCount":10,"difficulty":0.5528455284552846,"difficultyWeight":123},"Frankenstein":{"count":416,"lastSeenTime":1577037002742,"publicGameCount":29,"difficulty":0.6794258373205742,"difficultyWeight":209},"viola":{"count":435,"lastSeenTime":1577016549321,"publicGameCount":11,"difficulty":0.625,"difficultyWeight":112},"Fanta":{"count":449,"lastSeenTime":1577035277440,"publicGameCount":42,"difficulty":0.530791788856305,"difficultyWeight":341},"jungle":{"count":400,"lastSeenTime":1577032662789,"publicGameCount":23,"difficulty":0.5978835978835979,"difficultyWeight":189},"pistol":{"count":217,"lastSeenTime":1577035813853,"difficulty":0.5869565217391305,"difficultyWeight":230,"publicGameCount":1},"claw":{"count":215,"lastSeenTime":1576974780290,"publicGameCount":8,"difficulty":0.5686274509803921,"difficultyWeight":153},"priest":{"count":221,"lastSeenTime":1577035607642,"difficulty":0.6165413533834586,"difficultyWeight":133,"publicGameCount":10},"vuvuzela":{"count":448,"lastSeenTime":1577010808769,"publicGameCount":14,"difficulty":0.7567567567567568,"difficultyWeight":111},"alley":{"count":448,"lastSeenTime":1577037392013,"publicGameCount":22,"difficulty":0.6173469387755103,"difficultyWeight":196},"lighthouse":{"count":448,"lastSeenTime":1577035387934,"publicGameCount":49,"difficulty":0.6531165311653118,"difficultyWeight":369},"diva":{"count":233,"lastSeenTime":1577035252998,"difficulty":0.7407407407407407,"difficultyWeight":27,"publicGameCount":1},"meal":{"count":238,"lastSeenTime":1577019494384,"publicGameCount":5,"difficulty":0.7333333333333333,"difficultyWeight":105},"Tails":{"count":447,"lastSeenTime":1577035161889,"publicGameCount":25,"difficulty":0.5666666666666665,"difficultyWeight":210},"cola":{"count":208,"lastSeenTime":1577032997046,"publicGameCount":15,"difficulty":0.48201438848920863,"difficultyWeight":278},"catapult":{"count":221,"lastSeenTime":1577025326713,"difficulty":0.6410256410256411,"difficultyWeight":78,"publicGameCount":10},"tourist":{"count":226,"lastSeenTime":1577000472369,"difficulty":0.6976744186046512,"difficultyWeight":43,"publicGameCount":1},"intersection":{"count":403,"lastSeenTime":1577031754107,"publicGameCount":15,"difficulty":0.7476635514018691,"difficultyWeight":107},"stingray":{"count":233,"lastSeenTime":1577019550440,"publicGameCount":11,"difficulty":0.6,"difficultyWeight":90},"base":{"count":441,"lastSeenTime":1577021204269,"difficulty":0.6064516129032258,"difficultyWeight":155,"publicGameCount":16},"copy":{"count":438,"lastSeenTime":1577029982333,"publicGameCount":26,"difficulty":0.5681818181818182,"difficultyWeight":220},"groom":{"count":434,"lastSeenTime":1577025753070,"publicGameCount":10,"difficulty":0.625,"difficultyWeight":88},"orbit":{"count":233,"lastSeenTime":1577001324409,"publicGameCount":8,"difficulty":0.71875,"difficultyWeight":96},"Morgan Freeman":{"count":462,"lastSeenTime":1577024220453,"publicGameCount":21,"difficulty":0.7590361445783133,"difficultyWeight":166},"spoiler":{"count":234,"lastSeenTime":1577033444243,"publicGameCount":4,"difficulty":0.7560975609756098,"difficultyWeight":41},"juggle":{"count":223,"lastSeenTime":1577025287762,"publicGameCount":5,"difficulty":0.7906976744186046,"difficultyWeight":86},"Iron Man":{"count":429,"lastSeenTime":1577014278060,"publicGameCount":49,"difficulty":0.6646884272997033,"difficultyWeight":337},"Discord":{"count":437,"lastSeenTime":1577018696562,"difficulty":0.6245733788395904,"difficultyWeight":293,"publicGameCount":33},"patriot":{"count":223,"lastSeenTime":1577016460052,"publicGameCount":3,"difficulty":0.8409090909090909,"difficultyWeight":44},"harmonica":{"count":408,"lastSeenTime":1577025478336,"publicGameCount":18,"difficulty":0.728,"difficultyWeight":125},"Cookie Monster":{"count":455,"lastSeenTime":1577035238778,"publicGameCount":49,"difficulty":0.749271137026239,"difficultyWeight":343},"popcorn":{"count":219,"lastSeenTime":1577019117926,"publicGameCount":15,"difficulty":0.5103448275862068,"difficultyWeight":290},"hunger":{"count":457,"lastSeenTime":1577036441110,"publicGameCount":18,"difficulty":0.7189542483660131,"difficultyWeight":153},"invasion":{"count":239,"lastSeenTime":1577020597928,"publicGameCount":7,"difficulty":0.7611940298507462,"difficultyWeight":67},"salt":{"count":227,"lastSeenTime":1577036730175,"publicGameCount":10,"difficulty":0.5148148148148151,"difficultyWeight":270},"snake":{"count":242,"lastSeenTime":1576984207434,"difficulty":0.44723618090452255,"difficultyWeight":199,"publicGameCount":10},"avocado":{"count":245,"lastSeenTime":1577011492557,"publicGameCount":24,"difficulty":0.5203252032520326,"difficultyWeight":246},"opera":{"count":422,"lastSeenTime":1577019921307,"publicGameCount":18,"difficulty":0.7044025157232705,"difficultyWeight":159},"pimple":{"count":436,"lastSeenTime":1577036463485,"publicGameCount":51,"difficulty":0.5472636815920395,"difficultyWeight":402},"socks":{"count":218,"lastSeenTime":1577032398028,"publicGameCount":11,"difficulty":0.4810126582278481,"difficultyWeight":158},"spray paint":{"count":221,"lastSeenTime":1577032738629,"publicGameCount":23,"difficulty":0.6369426751592357,"difficultyWeight":157},"Happy Meal":{"count":225,"lastSeenTime":1576996528089,"publicGameCount":18,"difficulty":0.5902777777777778,"difficultyWeight":144},"Rick":{"count":415,"lastSeenTime":1577036121146,"publicGameCount":19,"difficulty":0.5999999999999999,"difficultyWeight":180},"seasick":{"count":211,"lastSeenTime":1577032420483,"publicGameCount":6,"difficulty":0.6470588235294118,"difficultyWeight":68},"curry":{"count":219,"lastSeenTime":1577021290587,"publicGameCount":6,"difficulty":0.7647058823529411,"difficultyWeight":51},"uniform":{"count":219,"lastSeenTime":1577008148913,"difficulty":0.6704545454545455,"difficultyWeight":88,"publicGameCount":9},"deer":{"count":244,"lastSeenTime":1577004115371,"difficulty":0.5735294117647058,"difficultyWeight":136,"publicGameCount":10},"tuna":{"count":438,"lastSeenTime":1577007159755,"publicGameCount":28,"difficulty":0.5045454545454547,"difficultyWeight":220},"soap":{"count":225,"lastSeenTime":1577034268153,"difficulty":0.5318181818181819,"difficultyWeight":220,"publicGameCount":11},"thin":{"count":411,"lastSeenTime":1577034603831,"publicGameCount":34,"difficulty":0.5559701492537313,"difficultyWeight":268},"Tooth Fairy":{"count":436,"lastSeenTime":1577034425936,"publicGameCount":36,"difficulty":0.7051792828685259,"difficultyWeight":251},"Popsicle":{"count":191,"lastSeenTime":1576993893742,"publicGameCount":8,"difficulty":0.6613756613756613,"difficultyWeight":189},"rain":{"count":430,"lastSeenTime":1577035324132,"publicGameCount":35,"difficulty":0.389413988657845,"difficultyWeight":529},"mayonnaise":{"count":203,"lastSeenTime":1576985476162,"publicGameCount":20,"difficulty":0.7142857142857143,"difficultyWeight":147},"hobbit":{"count":223,"lastSeenTime":1577032648652,"publicGameCount":8,"difficulty":0.7164179104477612,"difficultyWeight":67},"laser":{"count":226,"lastSeenTime":1577010883037,"difficulty":0.5521739130434783,"difficultyWeight":230,"publicGameCount":19},"Bill Gates":{"count":420,"lastSeenTime":1577036715889,"publicGameCount":26,"difficulty":0.7272727272727273,"difficultyWeight":198},"swing":{"count":410,"lastSeenTime":1577019031436,"publicGameCount":28,"difficulty":0.5179640718562875,"difficultyWeight":334},"pepperoni":{"count":229,"lastSeenTime":1576972958215,"publicGameCount":12,"difficulty":0.6202531645569621,"difficultyWeight":158},"Scooby Doo":{"count":457,"lastSeenTime":1577006987948,"publicGameCount":27,"difficulty":0.7391304347826086,"difficultyWeight":184},"elder":{"count":236,"lastSeenTime":1577003867547,"publicGameCount":11,"difficulty":0.7070707070707071,"difficultyWeight":99},"socket":{"count":223,"lastSeenTime":1577033794297,"publicGameCount":4,"difficulty":0.5737704918032787,"difficultyWeight":61},"lips":{"count":428,"lastSeenTime":1577035177226,"publicGameCount":51,"difficulty":0.43951612903225806,"difficultyWeight":496},"jeans":{"count":231,"lastSeenTime":1577031885678,"difficulty":0.5909090909090909,"difficultyWeight":154,"publicGameCount":9},"Aladdin":{"count":449,"lastSeenTime":1577019945970,"publicGameCount":30,"difficulty":0.6622222222222223,"difficultyWeight":225},"love":{"count":260,"lastSeenTime":1577037365574,"difficulty":0.4507042253521127,"difficultyWeight":213,"publicGameCount":14},"disaster":{"count":249,"lastSeenTime":1576992981171,"difficulty":0.7129629629629629,"difficultyWeight":108,"publicGameCount":13},"sushi":{"count":204,"lastSeenTime":1577031781371,"publicGameCount":17,"difficulty":0.5099337748344371,"difficultyWeight":151},"table":{"count":229,"lastSeenTime":1577036811707,"publicGameCount":14,"difficulty":0.46226415094339623,"difficultyWeight":212},"toothpick":{"count":208,"lastSeenTime":1577032544510,"difficulty":0.641860465116279,"difficultyWeight":215,"publicGameCount":20},"good":{"count":440,"lastSeenTime":1577019660052,"publicGameCount":22,"difficulty":0.5248618784530387,"difficultyWeight":181},"dots":{"count":215,"lastSeenTime":1576971290931,"difficulty":0.5446808510638299,"difficultyWeight":235,"publicGameCount":13},"gentle":{"count":419,"lastSeenTime":1577037535729,"difficulty":0.5888888888888889,"difficultyWeight":90,"publicGameCount":11},"Facebook":{"count":416,"lastSeenTime":1577030691919,"publicGameCount":58,"difficulty":0.3927893738140417,"difficultyWeight":527},"flamingo":{"count":207,"lastSeenTime":1577019910867,"difficulty":0.5857988165680472,"difficultyWeight":169,"publicGameCount":11},"mud":{"count":409,"lastSeenTime":1577033336640,"publicGameCount":20,"difficulty":0.6137931034482759,"difficultyWeight":290},"cell phone":{"count":231,"lastSeenTime":1577014924115,"publicGameCount":25,"difficulty":0.6278026905829597,"difficultyWeight":223},"nut":{"count":222,"lastSeenTime":1577037472968,"difficulty":0.5324675324675324,"difficultyWeight":154,"publicGameCount":3},"wingnut":{"count":230,"lastSeenTime":1577009049641,"publicGameCount":5,"difficulty":0.7090909090909091,"difficultyWeight":55},"Dexter":{"count":439,"lastSeenTime":1577036258761,"publicGameCount":21,"difficulty":0.7127659574468084,"difficultyWeight":188},"dalmatian":{"count":228,"lastSeenTime":1577033946337,"publicGameCount":4,"difficulty":0.6851851851851852,"difficultyWeight":54},"poke":{"count":218,"lastSeenTime":1577037355436,"publicGameCount":8,"difficulty":0.5487804878048781,"difficultyWeight":82},"Bambi":{"count":469,"lastSeenTime":1577033946337,"publicGameCount":16,"difficulty":0.7954545454545454,"difficultyWeight":132},"plate":{"count":233,"lastSeenTime":1577032420483,"publicGameCount":7,"difficulty":0.6541353383458647,"difficultyWeight":133},"shovel":{"count":235,"lastSeenTime":1577029886480,"publicGameCount":23,"difficulty":0.5075187969924813,"difficultyWeight":266},"roll":{"count":241,"lastSeenTime":1576999530628,"difficulty":0.6020408163265306,"difficultyWeight":98,"publicGameCount":6},"ambulance":{"count":221,"lastSeenTime":1576972446223,"publicGameCount":18,"difficulty":0.4659090909090909,"difficultyWeight":176},"voodoo":{"count":220,"lastSeenTime":1577019921307,"publicGameCount":14,"difficulty":0.6698113207547168,"difficultyWeight":106},"wax":{"count":274,"lastSeenTime":1576993408685,"difficulty":0.5671641791044776,"difficultyWeight":67,"publicGameCount":5},"sit":{"count":257,"lastSeenTime":1576995855674,"difficulty":0.566137566137566,"difficultyWeight":189,"publicGameCount":9},"navy":{"count":223,"lastSeenTime":1577036303309,"publicGameCount":8,"difficulty":0.5842696629213483,"difficultyWeight":89},"Xbox":{"count":211,"lastSeenTime":1576999174479,"difficulty":0.5,"difficultyWeight":264,"publicGameCount":27},"observatory":{"count":448,"lastSeenTime":1577004605706,"publicGameCount":15,"difficulty":0.6590909090909091,"difficultyWeight":88},"Pokemon":{"count":240,"lastSeenTime":1577006876607,"publicGameCount":24,"difficulty":0.5223214285714283,"difficultyWeight":224},"white":{"count":460,"lastSeenTime":1577018507060,"publicGameCount":32,"difficulty":0.48494983277591974,"difficultyWeight":299},"manatee":{"count":208,"lastSeenTime":1577036377269,"publicGameCount":5,"difficulty":0.7435897435897436,"difficultyWeight":39},"Skype":{"count":428,"lastSeenTime":1577032373261,"publicGameCount":29,"difficulty":0.5524193548387096,"difficultyWeight":248},"Google":{"count":415,"lastSeenTime":1577037402133,"publicGameCount":45,"difficulty":0.45436507936507936,"difficultyWeight":504},"filter":{"count":214,"lastSeenTime":1577025781863,"publicGameCount":4,"difficulty":0.6379310344827587,"difficultyWeight":58},"bark":{"count":451,"lastSeenTime":1577032801953,"publicGameCount":18,"difficulty":0.5365853658536585,"difficultyWeight":164},"bathroom":{"count":217,"lastSeenTime":1576971715224,"difficulty":0.5877862595419848,"difficultyWeight":131,"publicGameCount":9},"blood":{"count":434,"lastSeenTime":1577030301299,"publicGameCount":48,"difficulty":0.4859154929577464,"difficultyWeight":426},"fortress":{"count":408,"lastSeenTime":1577017825119,"publicGameCount":14,"difficulty":0.7244094488188977,"difficultyWeight":127},"twig":{"count":439,"lastSeenTime":1577037216675,"publicGameCount":34,"difficulty":0.5762711864406778,"difficultyWeight":236},"head":{"count":393,"lastSeenTime":1577036825894,"publicGameCount":30,"difficulty":0.5481171548117157,"difficultyWeight":478},"fisherman":{"count":235,"lastSeenTime":1577037056234,"publicGameCount":18,"difficulty":0.5714285714285715,"difficultyWeight":182},"notification":{"count":221,"lastSeenTime":1577024196032,"publicGameCount":17,"difficulty":0.7165354330708661,"difficultyWeight":127},"wake up":{"count":228,"lastSeenTime":1577014002026,"publicGameCount":10,"difficulty":0.6623376623376623,"difficultyWeight":77},"Germany":{"count":443,"lastSeenTime":1577013359587,"publicGameCount":44,"difficulty":0.5652173913043478,"difficultyWeight":391},"island":{"count":439,"lastSeenTime":1577019695028,"publicGameCount":59,"difficulty":0.460352422907489,"difficultyWeight":454},"drum":{"count":425,"lastSeenTime":1577036765048,"difficulty":0.5430463576158941,"difficultyWeight":302,"publicGameCount":32},"lamp":{"count":186,"lastSeenTime":1577037042051,"difficulty":0.5,"difficultyWeight":174,"publicGameCount":6},"apricot":{"count":189,"lastSeenTime":1577011310637,"difficulty":0.7391304347826086,"difficultyWeight":23,"publicGameCount":1},"penguin":{"count":203,"lastSeenTime":1576995550228,"difficulty":0.5635593220338985,"difficultyWeight":236,"publicGameCount":7},"face":{"count":429,"lastSeenTime":1577024267715,"publicGameCount":35,"difficulty":0.48509485094850946,"difficultyWeight":369},"Garfield":{"count":435,"lastSeenTime":1577009133675,"publicGameCount":26,"difficulty":0.6226415094339621,"difficultyWeight":212},"alcohol":{"count":211,"lastSeenTime":1577014187810,"difficulty":0.655367231638418,"difficultyWeight":177,"publicGameCount":17},"lilypad":{"count":449,"lastSeenTime":1577037483079,"publicGameCount":37,"difficulty":0.6151515151515151,"difficultyWeight":330},"New Zealand":{"count":439,"lastSeenTime":1577037306624,"publicGameCount":18,"difficulty":0.7258064516129032,"difficultyWeight":124},"Twitter":{"count":465,"lastSeenTime":1577033216553,"publicGameCount":55,"difficulty":0.4934210526315789,"difficultyWeight":456},"speaker":{"count":428,"lastSeenTime":1577015484814,"publicGameCount":35,"difficulty":0.5503144654088049,"difficultyWeight":318},"orca":{"count":206,"lastSeenTime":1577025251101,"publicGameCount":7,"difficulty":0.76,"difficultyWeight":100},"tablecloth":{"count":237,"lastSeenTime":1577033583113,"publicGameCount":9,"difficulty":0.6470588235294118,"difficultyWeight":68},"Great Wall":{"count":439,"lastSeenTime":1577036917213,"publicGameCount":31,"difficulty":0.7542372881355932,"difficultyWeight":236},"restaurant":{"count":416,"lastSeenTime":1577032137321,"publicGameCount":26,"difficulty":0.7285067873303167,"difficultyWeight":221},"bleach":{"count":232,"lastSeenTime":1577037151662,"publicGameCount":16,"difficulty":0.5555555555555555,"difficultyWeight":144},"lion":{"count":251,"lastSeenTime":1576975875210,"difficulty":0.4564102564102564,"difficultyWeight":195,"publicGameCount":13},"price tag":{"count":246,"lastSeenTime":1577035644067,"publicGameCount":36,"difficulty":0.6431372549019606,"difficultyWeight":255},"pike":{"count":396,"lastSeenTime":1576996771285,"publicGameCount":10,"difficulty":0.5588235294117648,"difficultyWeight":102},"eyelash":{"count":437,"lastSeenTime":1577031469464,"difficulty":0.5037406483790523,"difficultyWeight":401,"publicGameCount":46},"battery":{"count":219,"lastSeenTime":1577013947672,"publicGameCount":17,"difficulty":0.5684647302904564,"difficultyWeight":241},"forest fire":{"count":227,"lastSeenTime":1577012247604,"publicGameCount":21,"difficulty":0.6792452830188679,"difficultyWeight":159},"hedgehog":{"count":218,"lastSeenTime":1577018853704,"publicGameCount":18,"difficulty":0.593939393939394,"difficultyWeight":165},"Kirby":{"count":415,"lastSeenTime":1577015274772,"publicGameCount":37,"difficulty":0.5608108108108109,"difficultyWeight":296},"drum kit":{"count":426,"lastSeenTime":1577024698445,"publicGameCount":36,"difficulty":0.7584905660377359,"difficultyWeight":265},"earthquake":{"count":442,"lastSeenTime":1577034044177,"publicGameCount":33,"difficulty":0.7392857142857143,"difficultyWeight":280},"hexagon":{"count":220,"lastSeenTime":1577037002742,"publicGameCount":11,"difficulty":0.6324786324786325,"difficultyWeight":117},"Easter Bunny":{"count":447,"lastSeenTime":1577036872583,"publicGameCount":51,"difficulty":0.7135678391959799,"difficultyWeight":398},"abstract":{"count":458,"lastSeenTime":1577036645866,"difficulty":0.8130081300813008,"difficultyWeight":123,"publicGameCount":13},"oxygen":{"count":233,"lastSeenTime":1577017517304,"publicGameCount":14,"difficulty":0.5620437956204379,"difficultyWeight":137},"tropical":{"count":395,"lastSeenTime":1577032246891,"publicGameCount":23,"difficulty":0.7192118226600985,"difficultyWeight":203},"skinny":{"count":444,"lastSeenTime":1577035202003,"publicGameCount":35,"difficulty":0.5780141843971628,"difficultyWeight":282},"accordion":{"count":426,"lastSeenTime":1577024931941,"publicGameCount":8,"difficulty":0.7567567567567568,"difficultyWeight":74},"cookie":{"count":246,"lastSeenTime":1577032123143,"difficulty":0.5941558441558442,"difficultyWeight":308,"publicGameCount":17},"Nutella":{"count":429,"lastSeenTime":1577032676999,"publicGameCount":40,"difficulty":0.5402985074626866,"difficultyWeight":335},"seagull":{"count":248,"lastSeenTime":1577030226184,"publicGameCount":14,"difficulty":0.689922480620155,"difficultyWeight":129},"revolver":{"count":236,"lastSeenTime":1577015335750,"difficulty":0.6691176470588235,"difficultyWeight":136,"publicGameCount":12},"vision":{"count":236,"lastSeenTime":1577015710329,"difficulty":0.5686274509803921,"difficultyWeight":51,"publicGameCount":5},"knuckle":{"count":426,"lastSeenTime":1577024897004,"publicGameCount":24,"difficulty":0.572972972972973,"difficultyWeight":185},"Superman":{"count":416,"lastSeenTime":1577020636784,"publicGameCount":59,"difficulty":0.4416058394160583,"difficultyWeight":548},"fencing":{"count":233,"lastSeenTime":1577019408573,"publicGameCount":7,"difficulty":0.5671641791044776,"difficultyWeight":67},"coral reef":{"count":474,"lastSeenTime":1577034200815,"publicGameCount":27,"difficulty":0.7587939698492462,"difficultyWeight":199},"stamp":{"count":445,"lastSeenTime":1577035947488,"publicGameCount":30,"difficulty":0.5179282868525894,"difficultyWeight":251},"leader":{"count":221,"lastSeenTime":1577014187810,"difficulty":0.7314814814814815,"difficultyWeight":108,"publicGameCount":8},"cone":{"count":222,"lastSeenTime":1577036110764,"difficulty":0.4692737430167598,"difficultyWeight":179,"publicGameCount":1},"palace":{"count":398,"lastSeenTime":1577035544830,"publicGameCount":15,"difficulty":0.588785046728972,"difficultyWeight":107},"dead":{"count":433,"lastSeenTime":1577035554960,"difficulty":0.42827868852459017,"difficultyWeight":488,"publicGameCount":45},"Yoda":{"count":450,"lastSeenTime":1577032958355,"publicGameCount":30,"difficulty":0.5253731343283581,"difficultyWeight":335},"infinite":{"count":224,"lastSeenTime":1576999428424,"publicGameCount":20,"difficulty":0.6011235955056179,"difficultyWeight":178},"bill":{"count":239,"lastSeenTime":1576991232857,"difficulty":0.6260869565217392,"difficultyWeight":115,"publicGameCount":6},"receptionist":{"count":240,"lastSeenTime":1576934377323,"publicGameCount":4,"difficulty":0.8387096774193549,"difficultyWeight":31},"guinea pig":{"count":231,"lastSeenTime":1577024212837,"publicGameCount":10,"difficulty":0.7727272727272727,"difficultyWeight":66},"potato":{"count":227,"lastSeenTime":1577032459097,"difficulty":0.5584415584415585,"difficultyWeight":154,"publicGameCount":6},"fluid":{"count":233,"lastSeenTime":1577001273789,"publicGameCount":9,"difficulty":0.6,"difficultyWeight":85},"cheeseburger":{"count":216,"lastSeenTime":1577006913223,"publicGameCount":23,"difficulty":0.6235955056179775,"difficultyWeight":178},"punk":{"count":208,"lastSeenTime":1577016914668,"publicGameCount":3,"difficulty":0.7777777777777778,"difficultyWeight":54},"prune":{"count":233,"lastSeenTime":1577032066062,"publicGameCount":2,"difficulty":0.8636363636363636,"difficultyWeight":22},"crate":{"count":211,"lastSeenTime":1577001496952,"publicGameCount":9,"difficulty":0.5,"difficultyWeight":118},"west":{"count":446,"lastSeenTime":1577019122862,"publicGameCount":31,"difficulty":0.5,"difficultyWeight":286},"Zelda":{"count":252,"lastSeenTime":1577036387422,"difficulty":0.6666666666666666,"difficultyWeight":57,"publicGameCount":4},"India":{"count":464,"lastSeenTime":1577014609359,"publicGameCount":19,"difficulty":0.5818181818181818,"difficultyWeight":165},"Scotland":{"count":523,"lastSeenTime":1577034300607,"publicGameCount":16,"difficulty":0.7327586206896551,"difficultyWeight":116},"Zuma":{"count":240,"lastSeenTime":1577025899880,"publicGameCount":3,"difficulty":0.84,"difficultyWeight":25},"forest":{"count":440,"lastSeenTime":1577036917213,"publicGameCount":38,"difficulty":0.5382165605095539,"difficultyWeight":314},"defense":{"count":211,"lastSeenTime":1577031496440,"difficulty":0.6296296296296297,"difficultyWeight":54,"publicGameCount":7},"iPad":{"count":227,"lastSeenTime":1577030626411,"publicGameCount":29,"difficulty":0.5206896551724138,"difficultyWeight":290},"cave":{"count":444,"lastSeenTime":1577030888377,"publicGameCount":28,"difficulty":0.6072727272727274,"difficultyWeight":275},"thermometer":{"count":200,"lastSeenTime":1577004049189,"publicGameCount":15,"difficulty":0.608,"difficultyWeight":125},"Popeye":{"count":448,"lastSeenTime":1577035656351,"difficulty":0.6792452830188679,"difficultyWeight":159,"publicGameCount":19},"pensioner":{"count":217,"lastSeenTime":1577031023734,"difficulty":0.9166666666666666,"difficultyWeight":36,"publicGameCount":2},"postcard":{"count":225,"lastSeenTime":1577017319731,"difficulty":0.5573770491803278,"difficultyWeight":122,"publicGameCount":15},"desert":{"count":475,"lastSeenTime":1577036846155,"difficulty":0.6461538461538461,"difficultyWeight":260,"publicGameCount":28},"remote":{"count":219,"lastSeenTime":1577025190112,"publicGameCount":9,"difficulty":0.6708860759493671,"difficultyWeight":158},"sculpture":{"count":208,"lastSeenTime":1576979673605,"publicGameCount":5,"difficulty":0.8181818181818182,"difficultyWeight":66},"cream":{"count":233,"lastSeenTime":1577000966420,"difficulty":0.7131782945736435,"difficultyWeight":129,"publicGameCount":11},"Xerox":{"count":383,"lastSeenTime":1577036836029,"publicGameCount":7,"difficulty":0.5319148936170213,"difficultyWeight":47},"cardboard":{"count":221,"lastSeenTime":1577015910800,"difficulty":0.6231884057971014,"difficultyWeight":69,"publicGameCount":6},"flashlight":{"count":197,"lastSeenTime":1577018276584,"publicGameCount":27,"difficulty":0.46987951807228917,"difficultyWeight":249},"butcher":{"count":222,"lastSeenTime":1576983612198,"publicGameCount":8,"difficulty":0.7386363636363636,"difficultyWeight":88},"McDonalds":{"count":456,"lastSeenTime":1577005058058,"publicGameCount":62,"difficulty":0.46296296296296297,"difficultyWeight":486},"rest":{"count":263,"lastSeenTime":1577011349311,"publicGameCount":6,"difficulty":0.6282051282051282,"difficultyWeight":78},"Eminem":{"count":434,"lastSeenTime":1577037392013,"publicGameCount":25,"difficulty":0.6443298969072165,"difficultyWeight":194},"bathtub":{"count":248,"lastSeenTime":1577036608773,"publicGameCount":25,"difficulty":0.5530973451327434,"difficultyWeight":226},"beatbox":{"count":437,"lastSeenTime":1577035409514,"publicGameCount":14,"difficulty":0.6413043478260869,"difficultyWeight":92},"hot":{"count":439,"lastSeenTime":1577025852952,"publicGameCount":39,"difficulty":0.5833333333333331,"difficultyWeight":384},"clown":{"count":223,"lastSeenTime":1577019595041,"difficulty":0.5720338983050848,"difficultyWeight":236,"publicGameCount":16},"apocalypse":{"count":219,"lastSeenTime":1576990388712,"publicGameCount":10,"difficulty":0.7777777777777778,"difficultyWeight":90},"antivirus":{"count":221,"lastSeenTime":1577011071361,"publicGameCount":8,"difficulty":0.7777777777777778,"difficultyWeight":72},"unicycle":{"count":232,"lastSeenTime":1577014443779,"publicGameCount":11,"difficulty":0.5923076923076923,"difficultyWeight":130},"frame":{"count":242,"lastSeenTime":1577037355436,"difficulty":0.553030303030303,"difficultyWeight":132,"publicGameCount":11},"taxi":{"count":239,"lastSeenTime":1577035803681,"publicGameCount":11,"difficulty":0.41843971631205673,"difficultyWeight":141},"tip":{"count":238,"lastSeenTime":1577014053725,"publicGameCount":6,"difficulty":0.6231884057971014,"difficultyWeight":69},"chinchilla":{"count":224,"lastSeenTime":1577033694684,"publicGameCount":3,"difficulty":0.8636363636363636,"difficultyWeight":22},"hard":{"count":426,"lastSeenTime":1577020128841,"difficulty":0.6172839506172839,"difficultyWeight":162,"publicGameCount":11},"saltwater":{"count":421,"lastSeenTime":1577032344586,"publicGameCount":23,"difficulty":0.5576923076923077,"difficultyWeight":156},"detective":{"count":235,"lastSeenTime":1577036158826,"publicGameCount":13,"difficulty":0.6910569105691057,"difficultyWeight":123},"open":{"count":424,"lastSeenTime":1577037216675,"publicGameCount":25,"difficulty":0.581081081081081,"difficultyWeight":222},"armpit":{"count":392,"lastSeenTime":1577036137207,"difficulty":0.48220064724919093,"difficultyWeight":309,"publicGameCount":34},"darts":{"count":225,"lastSeenTime":1577035469679,"publicGameCount":9,"difficulty":0.7189542483660128,"difficultyWeight":153},"thumb":{"count":450,"lastSeenTime":1577036283076,"publicGameCount":47,"difficulty":0.49489795918367346,"difficultyWeight":392},"canary":{"count":217,"lastSeenTime":1577032554634,"difficulty":0.8055555555555556,"difficultyWeight":72,"publicGameCount":6},"action":{"count":208,"lastSeenTime":1576994505129,"publicGameCount":8,"difficulty":0.6031746031746031,"difficultyWeight":63},"plug":{"count":221,"lastSeenTime":1577024368956,"publicGameCount":11,"difficulty":0.4056603773584906,"difficultyWeight":106},"purity":{"count":238,"lastSeenTime":1576999487961,"publicGameCount":2,"difficulty":0.9333333333333333,"difficultyWeight":30},"switch":{"count":225,"lastSeenTime":1577024344558,"publicGameCount":11,"difficulty":0.49714285714285716,"difficultyWeight":175},"globe":{"count":437,"lastSeenTime":1577014443779,"difficulty":0.5,"difficultyWeight":294,"publicGameCount":31},"Wonder Woman":{"count":441,"lastSeenTime":1577036645866,"publicGameCount":34,"difficulty":0.6546184738955824,"difficultyWeight":249},"pajamas":{"count":237,"lastSeenTime":1577011157534,"publicGameCount":10,"difficulty":0.6597938144329895,"difficultyWeight":97},"tea":{"count":193,"lastSeenTime":1577025899880,"difficulty":0.5287958115183246,"difficultyWeight":191,"publicGameCount":5},"mouse":{"count":246,"lastSeenTime":1577018362555,"difficulty":0.5351351351351353,"difficultyWeight":185,"publicGameCount":3},"butter":{"count":219,"lastSeenTime":1577026025625,"difficulty":0.583756345177665,"difficultyWeight":197,"publicGameCount":9},"turkey":{"count":454,"lastSeenTime":1577035985945,"publicGameCount":30,"difficulty":0.6236162361623615,"difficultyWeight":271},"The Beatles":{"count":412,"lastSeenTime":1577021339910,"publicGameCount":22,"difficulty":0.8,"difficultyWeight":165},"armor":{"count":257,"lastSeenTime":1577037557962,"publicGameCount":14,"difficulty":0.6347305389221555,"difficultyWeight":167},"chimney":{"count":216,"lastSeenTime":1577034679025,"publicGameCount":13,"difficulty":0.5819672131147541,"difficultyWeight":122},"fish":{"count":450,"lastSeenTime":1577037521580,"publicGameCount":55,"difficulty":0.3680851063829787,"difficultyWeight":470},"William Shakespeare":{"count":434,"lastSeenTime":1577016407755,"publicGameCount":21,"difficulty":0.7692307692307693,"difficultyWeight":156},"Dumbo":{"count":430,"lastSeenTime":1577037178254,"publicGameCount":24,"difficulty":0.5953488372093022,"difficultyWeight":215},"king":{"count":243,"lastSeenTime":1577029763817,"publicGameCount":5,"difficulty":0.49214659685863876,"difficultyWeight":191},"radio":{"count":251,"lastSeenTime":1577017671934,"publicGameCount":10,"difficulty":0.5672514619883041,"difficultyWeight":171},"volcano":{"count":420,"lastSeenTime":1577034290492,"publicGameCount":49,"difficulty":0.4449244060475162,"difficultyWeight":463},"fairy":{"count":240,"lastSeenTime":1577037632002,"difficulty":0.5481927710843374,"difficultyWeight":166,"publicGameCount":4},"ruler":{"count":407,"lastSeenTime":1577015824965,"publicGameCount":43,"difficulty":0.49453551912568305,"difficultyWeight":366},"towel":{"count":222,"lastSeenTime":1577018710756,"difficulty":0.5268817204301075,"difficultyWeight":93,"publicGameCount":8},"ticket":{"count":251,"lastSeenTime":1576990850601,"difficulty":0.4943181818181818,"difficultyWeight":176,"publicGameCount":19},"pan":{"count":471,"lastSeenTime":1577003097778,"publicGameCount":55,"difficulty":0.6223776223776225,"difficultyWeight":429},"snail":{"count":245,"lastSeenTime":1577012059559,"difficulty":0.4820512820512821,"difficultyWeight":195,"publicGameCount":12},"tortoise":{"count":227,"lastSeenTime":1576922942486,"difficulty":0.7345132743362832,"difficultyWeight":113,"publicGameCount":6},"panda":{"count":229,"lastSeenTime":1577013825828,"publicGameCount":23,"difficulty":0.5071090047393365,"difficultyWeight":211},"sphinx":{"count":224,"lastSeenTime":1577004504580,"difficulty":0.8208955223880597,"difficultyWeight":67,"publicGameCount":7},"festival":{"count":238,"lastSeenTime":1577035947488,"publicGameCount":3,"difficulty":0.6851851851851852,"difficultyWeight":54},"injection":{"count":218,"lastSeenTime":1577025893054,"publicGameCount":15,"difficulty":0.6453900709219859,"difficultyWeight":141},"airbag":{"count":230,"lastSeenTime":1577034391339,"publicGameCount":9,"difficulty":0.6000000000000001,"difficultyWeight":60},"jazz":{"count":414,"lastSeenTime":1577037497263,"publicGameCount":18,"difficulty":0.5301204819277109,"difficultyWeight":166},"Playstation":{"count":212,"lastSeenTime":1577032505816,"publicGameCount":22,"difficulty":0.6195652173913043,"difficultyWeight":184},"Photoshop":{"count":471,"lastSeenTime":1577034728271,"publicGameCount":20,"difficulty":0.7314285714285714,"difficultyWeight":175},"shy":{"count":208,"lastSeenTime":1577036765048,"difficulty":0.5571428571428572,"difficultyWeight":70,"publicGameCount":3},"pavement":{"count":427,"lastSeenTime":1577008811101,"difficulty":0.7156862745098039,"difficultyWeight":102,"publicGameCount":11},"Bitcoin":{"count":439,"lastSeenTime":1577002076413,"difficulty":0.5582329317269076,"difficultyWeight":249,"publicGameCount":32},"Star Wars":{"count":212,"lastSeenTime":1577017097804,"publicGameCount":21,"difficulty":0.5906040268456377,"difficultyWeight":149},"punishment":{"count":240,"lastSeenTime":1577037002742,"publicGameCount":14,"difficulty":0.6990291262135923,"difficultyWeight":103},"flute":{"count":444,"lastSeenTime":1577035238778,"difficulty":0.5426356589147286,"difficultyWeight":258,"publicGameCount":25},"ringtone":{"count":242,"lastSeenTime":1577024168827,"difficulty":0.6688741721854303,"difficultyWeight":151,"publicGameCount":15},"thunder":{"count":437,"lastSeenTime":1577020011949,"publicGameCount":37,"difficulty":0.48125,"difficultyWeight":320},"vitamin":{"count":218,"lastSeenTime":1577030567444,"publicGameCount":10,"difficulty":0.6111111111111112,"difficultyWeight":90},"cocktail":{"count":215,"lastSeenTime":1576985193733,"publicGameCount":19,"difficulty":0.6144578313253012,"difficultyWeight":166},"levitate":{"count":229,"lastSeenTime":1577024791794,"publicGameCount":15,"difficulty":0.7133333333333334,"difficultyWeight":150},"lightning":{"count":447,"lastSeenTime":1577029603248,"publicGameCount":64,"difficulty":0.5078740157480314,"difficultyWeight":508},"homeless":{"count":437,"lastSeenTime":1577035803681,"publicGameCount":42,"difficulty":0.6513761467889908,"difficultyWeight":327},"dishrag":{"count":234,"lastSeenTime":1577014128670,"difficulty":0.6904761904761905,"difficultyWeight":42,"publicGameCount":5},"glitter":{"count":225,"lastSeenTime":1577030813017,"difficulty":0.7307692307692307,"difficultyWeight":104,"publicGameCount":6},"Rome":{"count":449,"lastSeenTime":1577025200410,"publicGameCount":14,"difficulty":0.6530612244897959,"difficultyWeight":98},"failure":{"count":234,"lastSeenTime":1577024317066,"publicGameCount":9,"difficulty":0.6170212765957447,"difficultyWeight":94},"Morse code":{"count":222,"lastSeenTime":1577037331094,"publicGameCount":12,"difficulty":0.5256410256410257,"difficultyWeight":78},"lap":{"count":415,"lastSeenTime":1577037627992,"publicGameCount":15,"difficulty":0.5968992248062015,"difficultyWeight":129},"wiggle":{"count":238,"lastSeenTime":1577030392582,"publicGameCount":6,"difficulty":0.5544554455445545,"difficultyWeight":101},"shaving cream":{"count":243,"lastSeenTime":1577036608773,"publicGameCount":19,"difficulty":0.8309859154929577,"difficultyWeight":142},"keyboard":{"count":404,"lastSeenTime":1577018894925,"publicGameCount":59,"difficulty":0.5943600867678959,"difficultyWeight":461},"Nike":{"count":413,"lastSeenTime":1577014994472,"publicGameCount":46,"difficulty":0.47692307692307695,"difficultyWeight":520},"eskimo":{"count":219,"lastSeenTime":1577000783813,"publicGameCount":4,"difficulty":0.7692307692307693,"difficultyWeight":39},"newspaper":{"count":242,"lastSeenTime":1577009484512,"publicGameCount":20,"difficulty":0.5031847133757962,"difficultyWeight":157},"barbarian":{"count":222,"lastSeenTime":1577033190137,"difficulty":0.9333333333333333,"difficultyWeight":15,"publicGameCount":1},"vault":{"count":220,"lastSeenTime":1577019621093,"difficulty":0.6371681415929203,"difficultyWeight":113,"publicGameCount":11},"wall":{"count":214,"lastSeenTime":1577017203993,"publicGameCount":12,"difficulty":0.5,"difficultyWeight":148},"virus":{"count":218,"lastSeenTime":1577033699738,"publicGameCount":12,"difficulty":0.5809523809523809,"difficultyWeight":105},"lobster":{"count":437,"lastSeenTime":1577033153784,"publicGameCount":31,"difficulty":0.6090225563909776,"difficultyWeight":266},"fire hydrant":{"count":425,"lastSeenTime":1577019435052,"publicGameCount":37,"difficulty":0.7711267605633803,"difficultyWeight":284},"circus":{"count":245,"lastSeenTime":1577017380155,"publicGameCount":12,"difficulty":0.5785714285714286,"difficultyWeight":140},"Sherlock Holmes":{"count":456,"lastSeenTime":1577025028815,"publicGameCount":13,"difficulty":0.7021276595744681,"difficultyWeight":94},"Egypt":{"count":425,"lastSeenTime":1577035409514,"publicGameCount":41,"difficulty":0.5552050473186119,"difficultyWeight":317},"can":{"count":213,"lastSeenTime":1577016914668,"difficulty":0.5325443786982249,"difficultyWeight":169,"publicGameCount":4},"Singapore":{"count":458,"lastSeenTime":1577035900512,"difficulty":0.7310924369747899,"difficultyWeight":119,"publicGameCount":13},"ramp":{"count":427,"lastSeenTime":1577035692632,"publicGameCount":21,"difficulty":0.5707964601769911,"difficultyWeight":226},"thug":{"count":187,"lastSeenTime":1577011310637,"publicGameCount":11,"difficulty":0.6666666666666666,"difficultyWeight":87},"ice cream":{"count":243,"lastSeenTime":1577035886295,"publicGameCount":46,"difficulty":0.44299674267100975,"difficultyWeight":307},"bottle flip":{"count":220,"lastSeenTime":1577008687049,"publicGameCount":32,"difficulty":0.7818181818181819,"difficultyWeight":220},"cash":{"count":223,"lastSeenTime":1577020788547,"publicGameCount":9,"difficulty":0.5568862275449104,"difficultyWeight":167},"raccoon":{"count":222,"lastSeenTime":1577005002910,"publicGameCount":14,"difficulty":0.7025316455696202,"difficultyWeight":158},"Gru":{"count":443,"lastSeenTime":1577003426912,"publicGameCount":26,"difficulty":0.777292576419214,"difficultyWeight":229},"Bart Simpson":{"count":452,"lastSeenTime":1577034107033,"publicGameCount":44,"difficulty":0.6993670886075949,"difficultyWeight":316},"pharmacist":{"count":232,"lastSeenTime":1577034764802,"publicGameCount":7,"difficulty":0.75,"difficultyWeight":48},"thunderstorm":{"count":424,"lastSeenTime":1577025008306,"difficulty":0.648293963254593,"difficultyWeight":381,"publicGameCount":54},"cork":{"count":226,"lastSeenTime":1577015499271,"difficulty":0.6370967741935484,"difficultyWeight":124,"publicGameCount":7},"rock":{"count":454,"lastSeenTime":1577019177354,"publicGameCount":32,"difficulty":0.5164473684210527,"difficultyWeight":304},"Gumball":{"count":440,"lastSeenTime":1577024549622,"publicGameCount":48,"difficulty":0.65814696485623,"difficultyWeight":313},"lasso":{"count":196,"lastSeenTime":1577010360204,"publicGameCount":14,"difficulty":0.6503496503496502,"difficultyWeight":143},"son":{"count":241,"lastSeenTime":1577025627579,"difficulty":0.6883116883116883,"difficultyWeight":154,"publicGameCount":12},"acorn":{"count":230,"lastSeenTime":1577003071375,"publicGameCount":7,"difficulty":0.6037735849056604,"difficultyWeight":106},"Pinocchio":{"count":404,"lastSeenTime":1577037446644,"publicGameCount":42,"difficulty":0.6156351791530945,"difficultyWeight":307},"airport":{"count":419,"lastSeenTime":1577024968702,"publicGameCount":28,"difficulty":0.6270491803278688,"difficultyWeight":244},"caterpillar":{"count":211,"lastSeenTime":1577017369949,"publicGameCount":27,"difficulty":0.5412371134020618,"difficultyWeight":194},"diagram":{"count":236,"lastSeenTime":1577034689603,"publicGameCount":7,"difficulty":0.7846153846153846,"difficultyWeight":65},"biology":{"count":215,"lastSeenTime":1576993475178,"difficulty":0.7058823529411765,"difficultyWeight":68,"publicGameCount":5},"slam":{"count":186,"lastSeenTime":1577024615879,"difficulty":0.7272727272727273,"difficultyWeight":44,"publicGameCount":4},"iceberg":{"count":418,"lastSeenTime":1577029739555,"publicGameCount":46,"difficulty":0.5688073394495412,"difficultyWeight":327},"Netherlands":{"count":416,"lastSeenTime":1577019041654,"publicGameCount":22,"difficulty":0.6797385620915033,"difficultyWeight":153},"vacuum":{"count":218,"lastSeenTime":1577036225894,"publicGameCount":14,"difficulty":0.6,"difficultyWeight":120},"bandana":{"count":242,"lastSeenTime":1577000870046,"publicGameCount":24,"difficulty":0.6820083682008367,"difficultyWeight":239},"Picasso":{"count":456,"lastSeenTime":1577016640495,"publicGameCount":9,"difficulty":0.639344262295082,"difficultyWeight":61},"pause":{"count":231,"lastSeenTime":1577035985945,"difficulty":0.5628140703517587,"difficultyWeight":199,"publicGameCount":6},"grasshopper":{"count":218,"lastSeenTime":1577035975818,"publicGameCount":13,"difficulty":0.5514018691588785,"difficultyWeight":107},"pickaxe":{"count":286,"lastSeenTime":1577036559751,"difficulty":0.5,"difficultyWeight":248,"publicGameCount":26},"cup":{"count":212,"lastSeenTime":1576951270268,"difficulty":0.4854368932038835,"difficultyWeight":206,"publicGameCount":2},"litter box":{"count":241,"lastSeenTime":1577001584251,"publicGameCount":10,"difficulty":0.7209302325581395,"difficultyWeight":86},"Microsoft":{"count":431,"lastSeenTime":1577037192421,"publicGameCount":38,"difficulty":0.5568862275449101,"difficultyWeight":334},"burp":{"count":212,"lastSeenTime":1576996543336,"difficulty":0.5813953488372093,"difficultyWeight":86,"publicGameCount":7},"loaf":{"count":240,"lastSeenTime":1577035876160,"difficulty":0.5728155339805825,"difficultyWeight":103,"publicGameCount":9},"poor":{"count":458,"lastSeenTime":1577019287813,"publicGameCount":30,"difficulty":0.6166007905138341,"difficultyWeight":253},"smell":{"count":412,"lastSeenTime":1577017800715,"publicGameCount":28,"difficulty":0.5636363636363637,"difficultyWeight":275},"science":{"count":230,"lastSeenTime":1577026054361,"publicGameCount":10,"difficulty":0.6320754716981132,"difficultyWeight":106},"meteorite":{"count":222,"lastSeenTime":1577004853990,"difficulty":0.752,"difficultyWeight":125,"publicGameCount":5},"pastry":{"count":221,"lastSeenTime":1577024917709,"difficulty":0.78,"difficultyWeight":50,"publicGameCount":6},"bear trap":{"count":198,"lastSeenTime":1576990904851,"publicGameCount":17,"difficulty":0.5909090909090909,"difficultyWeight":110},"fast food":{"count":243,"lastSeenTime":1577018145182,"publicGameCount":26,"difficulty":0.6331658291457286,"difficultyWeight":199},"octopus":{"count":404,"lastSeenTime":1577014594710,"publicGameCount":57,"difficulty":0.41721854304635764,"difficultyWeight":453},"butterfly":{"count":240,"lastSeenTime":1577008698019,"difficulty":0.37710437710437716,"difficultyWeight":297,"publicGameCount":23},"geyser":{"count":487,"lastSeenTime":1577015860357,"publicGameCount":13,"difficulty":0.8113207547169812,"difficultyWeight":106},"spring":{"count":438,"lastSeenTime":1577034268153,"difficulty":0.5047619047619049,"difficultyWeight":210,"publicGameCount":27},"yardstick":{"count":225,"lastSeenTime":1577015732671,"difficulty":0.859375,"difficultyWeight":64,"publicGameCount":5},"sniper":{"count":234,"lastSeenTime":1577034253534,"publicGameCount":5,"difficulty":0.6068376068376068,"difficultyWeight":117},"tissue box":{"count":231,"lastSeenTime":1577011396963,"publicGameCount":30,"difficulty":0.6936936936936937,"difficultyWeight":222},"calendar":{"count":232,"lastSeenTime":1577009484512,"publicGameCount":7,"difficulty":0.6363636363636364,"difficultyWeight":110},"scissors":{"count":249,"lastSeenTime":1577036549571,"publicGameCount":27,"difficulty":0.5690376569037656,"difficultyWeight":239},"Creeper":{"count":403,"lastSeenTime":1577032261139,"publicGameCount":57,"difficulty":0.520408163265306,"difficultyWeight":490},"sledgehammer":{"count":226,"lastSeenTime":1577017628796,"publicGameCount":17,"difficulty":0.6486486486486487,"difficultyWeight":111},"cheerleader":{"count":223,"lastSeenTime":1577031166738,"publicGameCount":11,"difficulty":0.6547619047619048,"difficultyWeight":84},"red":{"count":451,"lastSeenTime":1577034411762,"publicGameCount":33,"difficulty":0.41350210970464135,"difficultyWeight":474},"Samsung":{"count":443,"lastSeenTime":1577036248643,"difficulty":0.556497175141243,"difficultyWeight":354,"publicGameCount":38},"graveyard":{"count":501,"lastSeenTime":1577008564587,"publicGameCount":45,"difficulty":0.5867768595041323,"difficultyWeight":363},"bell pepper":{"count":204,"lastSeenTime":1577025914163,"publicGameCount":15,"difficulty":0.768595041322314,"difficultyWeight":121},"interview":{"count":189,"lastSeenTime":1576996882509,"publicGameCount":5,"difficulty":0.8181818181818182,"difficultyWeight":44},"Las Vegas":{"count":448,"lastSeenTime":1577012374204,"publicGameCount":24,"difficulty":0.7267441860465116,"difficultyWeight":172},"wife":{"count":225,"lastSeenTime":1577018492804,"difficulty":0.5316455696202531,"difficultyWeight":158,"publicGameCount":13},"clay":{"count":234,"lastSeenTime":1576991873714,"publicGameCount":8,"difficulty":0.7333333333333333,"difficultyWeight":90},"score":{"count":212,"lastSeenTime":1577019809349,"publicGameCount":11,"difficulty":0.5970149253731343,"difficultyWeight":134},"mermaid":{"count":224,"lastSeenTime":1576973838261,"publicGameCount":7,"difficulty":0.5375,"difficultyWeight":80},"full moon":{"count":211,"lastSeenTime":1577036135826,"publicGameCount":38,"difficulty":0.6227758007117437,"difficultyWeight":281},"charger":{"count":243,"lastSeenTime":1577006689556,"publicGameCount":15,"difficulty":0.5454545454545454,"difficultyWeight":176},"provoke":{"count":237,"lastSeenTime":1577016935320,"publicGameCount":3,"difficulty":0.8,"difficultyWeight":35},"link":{"count":224,"lastSeenTime":1577010578881,"difficulty":0.6666666666666666,"difficultyWeight":120,"publicGameCount":4},"snowball":{"count":218,"lastSeenTime":1577031033935,"publicGameCount":14,"difficulty":0.5133333333333333,"difficultyWeight":150},"surface":{"count":204,"lastSeenTime":1577037345324,"publicGameCount":10,"difficulty":0.7171717171717171,"difficultyWeight":99},"rainforest":{"count":446,"lastSeenTime":1577033694684,"publicGameCount":40,"difficulty":0.6588628762541806,"difficultyWeight":299},"incognito":{"count":485,"lastSeenTime":1577009000428,"publicGameCount":28,"difficulty":0.825,"difficultyWeight":240},"read":{"count":234,"lastSeenTime":1577033454373,"difficulty":0.6571428571428571,"difficultyWeight":105,"publicGameCount":2},"Leonardo DiCaprio":{"count":421,"lastSeenTime":1577035593475,"publicGameCount":13,"difficulty":0.87,"difficultyWeight":100},"heat":{"count":202,"lastSeenTime":1576993155866,"publicGameCount":7,"difficulty":0.5714285714285714,"difficultyWeight":112},"puppet":{"count":252,"lastSeenTime":1577011633265,"difficulty":0.6524822695035462,"difficultyWeight":141,"publicGameCount":15},"torpedo":{"count":207,"lastSeenTime":1577001920799,"difficulty":0.7884615384615384,"difficultyWeight":52,"publicGameCount":4},"chameleon":{"count":217,"lastSeenTime":1576991519260,"publicGameCount":8,"difficulty":0.696969696969697,"difficultyWeight":66},"chime":{"count":444,"lastSeenTime":1577036426489,"publicGameCount":10,"difficulty":0.7623762376237624,"difficultyWeight":101},"electricity":{"count":213,"lastSeenTime":1577031556468,"publicGameCount":16,"difficulty":0.6444444444444445,"difficultyWeight":135},"prism":{"count":229,"lastSeenTime":1577030902569,"difficulty":0.6956521739130435,"difficultyWeight":92,"publicGameCount":7},"Mount Rushmore":{"count":447,"lastSeenTime":1577036329616,"publicGameCount":29,"difficulty":0.7692307692307693,"difficultyWeight":195},"insomnia":{"count":243,"lastSeenTime":1577016136003,"publicGameCount":9,"difficulty":0.7719298245614035,"difficultyWeight":57},"Mickey Mouse":{"count":442,"lastSeenTime":1577036211618,"publicGameCount":66,"difficulty":0.6284501061571125,"difficultyWeight":471},"Homer Simpson":{"count":466,"lastSeenTime":1577014491023,"publicGameCount":44,"difficulty":0.6909090909090909,"difficultyWeight":330},"anteater":{"count":213,"lastSeenTime":1577030738545,"difficulty":0.7297297297297297,"difficultyWeight":37,"publicGameCount":2},"warm":{"count":450,"lastSeenTime":1577032076358,"publicGameCount":29,"difficulty":0.7083333333333334,"difficultyWeight":264},"tiramisu":{"count":215,"lastSeenTime":1577017976509,"publicGameCount":4,"difficulty":0.875,"difficultyWeight":40},"orchestra":{"count":460,"lastSeenTime":1577019386006,"publicGameCount":10,"difficulty":0.7954545454545454,"difficultyWeight":88},"die":{"count":224,"lastSeenTime":1577015139924,"publicGameCount":6,"difficulty":0.6303317535545023,"difficultyWeight":211},"silo":{"count":443,"lastSeenTime":1577032334398,"difficulty":0.7161290322580646,"difficultyWeight":155,"publicGameCount":19},"shape":{"count":205,"lastSeenTime":1577036110764,"publicGameCount":5,"difficulty":0.5963302752293579,"difficultyWeight":109},"baboon":{"count":214,"lastSeenTime":1577020099794,"publicGameCount":6,"difficulty":0.6896551724137931,"difficultyWeight":87},"Abraham Lincoln":{"count":438,"lastSeenTime":1577021339910,"publicGameCount":25,"difficulty":0.7542857142857143,"difficultyWeight":175},"palm":{"count":438,"lastSeenTime":1577035775298,"publicGameCount":22,"difficulty":0.48214285714285715,"difficultyWeight":224},"invisible":{"count":449,"lastSeenTime":1577036754761,"publicGameCount":28,"difficulty":0.6222222222222222,"difficultyWeight":225},"gentleman":{"count":242,"lastSeenTime":1577024306506,"difficulty":0.7446808510638298,"difficultyWeight":47,"publicGameCount":7},"museum":{"count":448,"lastSeenTime":1577030272907,"publicGameCount":19,"difficulty":0.6845637583892618,"difficultyWeight":149},"spine":{"count":452,"lastSeenTime":1577018048472,"publicGameCount":25,"difficulty":0.6096491228070176,"difficultyWeight":228},"stage":{"count":258,"lastSeenTime":1577013531039,"difficulty":0.6384615384615384,"difficultyWeight":130,"publicGameCount":11},"emu":{"count":217,"lastSeenTime":1577033804412,"publicGameCount":4,"difficulty":0.6727272727272727,"difficultyWeight":55},"bullet":{"count":201,"lastSeenTime":1577032982788,"difficulty":0.5021097046413503,"difficultyWeight":237,"publicGameCount":5},"toothbrush":{"count":240,"lastSeenTime":1577012388447,"publicGameCount":32,"difficulty":0.6820276497695853,"difficultyWeight":217},"sand":{"count":440,"lastSeenTime":1577031322805,"publicGameCount":31,"difficulty":0.5208333333333333,"difficultyWeight":288},"mafia":{"count":214,"lastSeenTime":1576989412887,"difficulty":0.7560975609756098,"difficultyWeight":82,"publicGameCount":7},"starfruit":{"count":229,"lastSeenTime":1577029763817,"publicGameCount":11,"difficulty":0.753968253968254,"difficultyWeight":126},"honeycomb":{"count":235,"lastSeenTime":1577032997046,"difficulty":0.5700934579439253,"difficultyWeight":107,"publicGameCount":12},"warehouse":{"count":451,"lastSeenTime":1577034618043,"publicGameCount":18,"difficulty":0.6833333333333333,"difficultyWeight":120},"oar":{"count":227,"lastSeenTime":1577037192421,"difficulty":0.7413793103448276,"difficultyWeight":58,"publicGameCount":5},"zipline":{"count":215,"lastSeenTime":1577020215138,"difficulty":0.5743243243243243,"difficultyWeight":148,"publicGameCount":12},"apple pie":{"count":206,"lastSeenTime":1577034728271,"publicGameCount":18,"difficulty":0.5491803278688523,"difficultyWeight":122},"barbed wire":{"count":428,"lastSeenTime":1577030912743,"publicGameCount":26,"difficulty":0.7525252525252525,"difficultyWeight":198},"ace":{"count":205,"lastSeenTime":1577025008306,"difficulty":0.6593406593406593,"difficultyWeight":91,"publicGameCount":3},"coaster":{"count":209,"lastSeenTime":1577037436536,"publicGameCount":4,"difficulty":0.609375,"difficultyWeight":64},"adorable":{"count":437,"lastSeenTime":1577030738545,"publicGameCount":19,"difficulty":0.7482993197278911,"difficultyWeight":147},"gasoline":{"count":222,"lastSeenTime":1577019859074,"publicGameCount":7,"difficulty":0.7341772151898734,"difficultyWeight":79},"lock":{"count":210,"lastSeenTime":1577036377269,"difficulty":0.4912280701754387,"difficultyWeight":171,"publicGameCount":1},"car wash":{"count":417,"lastSeenTime":1577031510950,"publicGameCount":41,"difficulty":0.6698113207547169,"difficultyWeight":318},"tailor":{"count":242,"lastSeenTime":1577003420489,"difficulty":0.8275862068965517,"difficultyWeight":29,"publicGameCount":2},"traffic light":{"count":421,"lastSeenTime":1577032824600,"publicGameCount":64,"difficulty":0.6388308977035491,"difficultyWeight":479},"village":{"count":468,"lastSeenTime":1577009942735,"publicGameCount":26,"difficulty":0.7283950617283951,"difficultyWeight":243},"pelican":{"count":212,"lastSeenTime":1577031910884,"publicGameCount":5,"difficulty":0.6615384615384615,"difficultyWeight":65},"tape":{"count":229,"lastSeenTime":1577026078796,"publicGameCount":10,"difficulty":0.6666666666666666,"difficultyWeight":108},"lightsaber":{"count":253,"lastSeenTime":1577020933771,"publicGameCount":26,"difficulty":0.5842105263157895,"difficultyWeight":190},"fox":{"count":211,"lastSeenTime":1576998052312,"difficulty":0.5338983050847458,"difficultyWeight":118,"publicGameCount":4},"laptop":{"count":224,"lastSeenTime":1577033358892,"difficulty":0.5245098039215687,"difficultyWeight":204,"publicGameCount":9},"organ":{"count":627,"lastSeenTime":1577020363890,"difficulty":0.7638888888888888,"difficultyWeight":216,"publicGameCount":29},"Hello Kitty":{"count":459,"lastSeenTime":1577019066716,"difficulty":0.6830065359477123,"difficultyWeight":306,"publicGameCount":41},"community":{"count":207,"lastSeenTime":1576988578637,"publicGameCount":6,"difficulty":0.4909090909090909,"difficultyWeight":55},"insect":{"count":230,"lastSeenTime":1576905419869,"difficulty":0.5128205128205128,"difficultyWeight":156,"publicGameCount":18},"belly":{"count":457,"lastSeenTime":1577020760004,"publicGameCount":35,"difficulty":0.569811320754717,"difficultyWeight":265},"ant":{"count":254,"lastSeenTime":1577016233883,"difficulty":0.4857142857142858,"difficultyWeight":175,"publicGameCount":1},"massage":{"count":235,"lastSeenTime":1577033593279,"publicGameCount":15,"difficulty":0.751937984496124,"difficultyWeight":129},"Wolverine":{"count":417,"lastSeenTime":1577030433295,"publicGameCount":31,"difficulty":0.6064814814814815,"difficultyWeight":216},"Minecraft":{"count":232,"lastSeenTime":1577034391339,"publicGameCount":18,"difficulty":0.59,"difficultyWeight":200},"dent":{"count":251,"lastSeenTime":1576997406919,"publicGameCount":6,"difficulty":0.631578947368421,"difficultyWeight":76},"Romania":{"count":449,"lastSeenTime":1577033129254,"publicGameCount":11,"difficulty":0.6530612244897959,"difficultyWeight":98},"goblin":{"count":215,"lastSeenTime":1577035348501,"publicGameCount":6,"difficulty":0.6842105263157894,"difficultyWeight":76},"pink":{"count":410,"lastSeenTime":1577035937353,"publicGameCount":36,"difficulty":0.40497737556561086,"difficultyWeight":442},"broom":{"count":207,"lastSeenTime":1576998352706,"difficulty":0.5963636363636363,"difficultyWeight":275,"publicGameCount":8},"cowbell":{"count":470,"lastSeenTime":1577036135826,"publicGameCount":25,"difficulty":0.729064039408867,"difficultyWeight":203},"brick":{"count":212,"lastSeenTime":1577018145182,"difficulty":0.5930232558139537,"difficultyWeight":258,"publicGameCount":9},"Gandhi":{"count":448,"lastSeenTime":1577019580143,"difficulty":0.6698113207547169,"difficultyWeight":106,"publicGameCount":8},"barrel":{"count":214,"lastSeenTime":1577017306336,"publicGameCount":2,"difficulty":0.725925925925926,"difficultyWeight":135},"Cerberus":{"count":198,"lastSeenTime":1577017825119,"difficulty":0.71,"difficultyWeight":100,"publicGameCount":10},"drain":{"count":443,"lastSeenTime":1577034440167,"publicGameCount":27,"difficulty":0.5495049504950494,"difficultyWeight":202},"hat":{"count":228,"lastSeenTime":1576971026140,"difficulty":0.4770992366412214,"difficultyWeight":262,"publicGameCount":2},"fence":{"count":221,"lastSeenTime":1576986723653,"difficulty":0.5786802030456853,"difficultyWeight":197,"publicGameCount":8},"display":{"count":236,"lastSeenTime":1577020565262,"publicGameCount":3,"difficulty":0.9117647058823529,"difficultyWeight":34},"carnivore":{"count":203,"lastSeenTime":1577015681933,"publicGameCount":5,"difficulty":0.6607142857142857,"difficultyWeight":56},"electrician":{"count":230,"lastSeenTime":1577013975511,"publicGameCount":8,"difficulty":0.7857142857142857,"difficultyWeight":56},"excavator":{"count":227,"lastSeenTime":1577032676999,"publicGameCount":5,"difficulty":0.7647058823529411,"difficultyWeight":34},"lightbulb":{"count":224,"lastSeenTime":1576997976651,"difficulty":0.5223880597014927,"difficultyWeight":201,"publicGameCount":23},"wasp":{"count":235,"lastSeenTime":1577018027793,"publicGameCount":7,"difficulty":0.43243243243243246,"difficultyWeight":111},"pineapple":{"count":230,"lastSeenTime":1577017071398,"difficulty":0.4645669291338583,"difficultyWeight":254,"publicGameCount":14},"razor":{"count":224,"lastSeenTime":1577025889721,"publicGameCount":7,"difficulty":0.7291666666666666,"difficultyWeight":96},"Angelina Jolie":{"count":431,"lastSeenTime":1577017203993,"publicGameCount":12,"difficulty":0.8117647058823529,"difficultyWeight":85},"orchid":{"count":432,"lastSeenTime":1577030581728,"publicGameCount":4,"difficulty":0.7727272727272727,"difficultyWeight":44},"shirt":{"count":229,"lastSeenTime":1577019177354,"difficulty":0.5094339622641508,"difficultyWeight":212,"publicGameCount":5},"werewolf":{"count":241,"lastSeenTime":1577020909312,"publicGameCount":13,"difficulty":0.6421052631578947,"difficultyWeight":95},"taco":{"count":240,"lastSeenTime":1577029617419,"difficulty":0.5663265306122449,"difficultyWeight":196,"publicGameCount":17},"dentist":{"count":228,"lastSeenTime":1577025277614,"difficulty":0.578125,"difficultyWeight":64,"publicGameCount":6},"talent show":{"count":214,"lastSeenTime":1576963674203,"publicGameCount":9,"difficulty":0.7804878048780488,"difficultyWeight":82},"panpipes":{"count":406,"lastSeenTime":1577031807616,"publicGameCount":10,"difficulty":0.797979797979798,"difficultyWeight":99},"sunglasses":{"count":243,"lastSeenTime":1577035961642,"publicGameCount":23,"difficulty":0.5,"difficultyWeight":160},"shoelace":{"count":221,"lastSeenTime":1576992062315,"publicGameCount":9,"difficulty":0.514018691588785,"difficultyWeight":107},"Hawaii":{"count":455,"lastSeenTime":1577032544510,"publicGameCount":22,"difficulty":0.6574585635359116,"difficultyWeight":181},"noodle":{"count":213,"lastSeenTime":1576992913448,"difficulty":0.5747126436781609,"difficultyWeight":174,"publicGameCount":9},"horn":{"count":221,"lastSeenTime":1577035664302,"difficulty":0.5047619047619049,"difficultyWeight":105,"publicGameCount":4},"boar":{"count":224,"lastSeenTime":1577002663157,"difficulty":0.5777777777777778,"difficultyWeight":90,"publicGameCount":8},"addiction":{"count":205,"lastSeenTime":1576839994978,"publicGameCount":8,"difficulty":0.717391304347826,"difficultyWeight":92},"addition":{"count":229,"lastSeenTime":1577036811707,"difficulty":0.5164835164835165,"difficultyWeight":91,"publicGameCount":6},"afro":{"count":230,"lastSeenTime":1577037412232,"publicGameCount":15,"difficulty":0.47468354430379744,"difficultyWeight":158},"airplane":{"count":233,"lastSeenTime":1577030663428,"difficulty":0.5048076923076923,"difficultyWeight":208,"publicGameCount":6},"alarm":{"count":222,"lastSeenTime":1577024525038,"publicGameCount":11,"difficulty":0.5267489711934156,"difficultyWeight":243},"alien":{"count":225,"lastSeenTime":1577033680486,"difficulty":0.5228426395939086,"difficultyWeight":197,"publicGameCount":4},"almond":{"count":239,"lastSeenTime":1577035522572,"difficulty":0.6219512195121951,"difficultyWeight":82,"publicGameCount":7},"anaconda":{"count":271,"lastSeenTime":1577018291021,"publicGameCount":7,"difficulty":0.6176470588235294,"difficultyWeight":68},"angel":{"count":219,"lastSeenTime":1577001760080,"publicGameCount":8,"difficulty":0.48148148148148145,"difficultyWeight":162},"anglerfish":{"count":225,"lastSeenTime":1576976694803,"publicGameCount":13,"difficulty":0.7265625,"difficultyWeight":128},"angry":{"count":230,"lastSeenTime":1577019480194,"difficulty":0.4517766497461929,"difficultyWeight":197,"publicGameCount":17},"animation":{"count":242,"lastSeenTime":1577015031203,"publicGameCount":6,"difficulty":0.7936507936507936,"difficultyWeight":63},"anime":{"count":234,"lastSeenTime":1577032777377,"publicGameCount":6,"difficulty":0.532258064516129,"difficultyWeight":62},"apple":{"count":228,"lastSeenTime":1577013426420,"difficulty":0.33687943262411346,"difficultyWeight":282,"publicGameCount":2},"apple seed":{"count":381,"lastSeenTime":1577017228395,"publicGameCount":38,"difficulty":0.6317829457364341,"difficultyWeight":258},"aquarium":{"count":466,"lastSeenTime":1577032246891,"publicGameCount":32,"difficulty":0.5879999999999999,"difficultyWeight":250},"architect":{"count":209,"lastSeenTime":1577037056234,"publicGameCount":4,"difficulty":0.6206896551724138,"difficultyWeight":29},"ash":{"count":197,"lastSeenTime":1577015885827,"publicGameCount":8,"difficulty":0.5846153846153846,"difficultyWeight":130},"assassin":{"count":238,"lastSeenTime":1577010282547,"publicGameCount":13,"difficulty":0.7272727272727273,"difficultyWeight":110},"assault":{"count":190,"lastSeenTime":1576973403404,"publicGameCount":4,"difficulty":0.7692307692307693,"difficultyWeight":39},"asteroid":{"count":219,"lastSeenTime":1577011181933,"publicGameCount":10,"difficulty":0.7052631578947368,"difficultyWeight":95},"astronaut":{"count":249,"lastSeenTime":1577017417153,"difficulty":0.68125,"difficultyWeight":160,"publicGameCount":21},"athlete":{"count":220,"lastSeenTime":1577010076784,"publicGameCount":3,"difficulty":0.8536585365853658,"difficultyWeight":41},"atom":{"count":219,"lastSeenTime":1577033421787,"publicGameCount":14,"difficulty":0.5658914728682171,"difficultyWeight":129},"audience":{"count":255,"lastSeenTime":1576993372131,"publicGameCount":11,"difficulty":0.7402597402597403,"difficultyWeight":77},"axe":{"count":238,"lastSeenTime":1577019277416,"difficulty":0.49603174603174605,"difficultyWeight":252,"publicGameCount":4},"baby":{"count":232,"lastSeenTime":1577030998362,"difficulty":0.5183486238532109,"difficultyWeight":218,"publicGameCount":15},"bad":{"count":450,"lastSeenTime":1577033468984,"publicGameCount":31,"difficulty":0.6406926406926406,"difficultyWeight":231},"bag":{"count":233,"lastSeenTime":1577014454540,"difficulty":0.536082474226804,"difficultyWeight":194,"publicGameCount":9},"bagel":{"count":231,"lastSeenTime":1577024601158,"difficulty":0.5652173913043478,"difficultyWeight":115,"publicGameCount":7},"baguette":{"count":231,"lastSeenTime":1577032483552,"publicGameCount":13,"difficulty":0.698529411764706,"difficultyWeight":136},"balance":{"count":244,"lastSeenTime":1577016763081,"publicGameCount":11,"difficulty":0.717948717948718,"difficultyWeight":117},"balcony":{"count":227,"lastSeenTime":1577015211742,"difficulty":0.5802469135802469,"difficultyWeight":81,"publicGameCount":4},"bald":{"count":419,"lastSeenTime":1577017157118,"publicGameCount":34,"difficulty":0.5065616797900262,"difficultyWeight":381},"ball":{"count":212,"lastSeenTime":1577036872583,"difficulty":0.5294117647058824,"difficultyWeight":187,"publicGameCount":3},"ballerina":{"count":233,"lastSeenTime":1577033421787,"publicGameCount":10,"difficulty":0.6893203883495146,"difficultyWeight":103},"balloon":{"count":218,"lastSeenTime":1577031943447,"publicGameCount":10,"difficulty":0.5748502994011976,"difficultyWeight":167},"banana":{"count":218,"lastSeenTime":1577018781997,"difficulty":0.4641509433962264,"difficultyWeight":265,"publicGameCount":4},"bandage":{"count":213,"lastSeenTime":1577016293273,"publicGameCount":14,"difficulty":0.631578947368421,"difficultyWeight":133},"banjo":{"count":434,"lastSeenTime":1577033841722,"publicGameCount":22,"difficulty":0.5707317073170731,"difficultyWeight":205},"bank":{"count":426,"lastSeenTime":1577031234774,"difficulty":0.4463768115942029,"difficultyWeight":345,"publicGameCount":35},"barber":{"count":208,"lastSeenTime":1577031593360,"difficulty":0.6589147286821705,"difficultyWeight":129,"publicGameCount":2},"barn":{"count":462,"lastSeenTime":1577029603248,"publicGameCount":25,"difficulty":0.574585635359116,"difficultyWeight":181},"basketball":{"count":246,"lastSeenTime":1577018377436,"publicGameCount":27,"difficulty":0.39908256880733944,"difficultyWeight":218},"bat":{"count":429,"lastSeenTime":1577024539413,"publicGameCount":37,"difficulty":0.46534653465346537,"difficultyWeight":404},"battle":{"count":237,"lastSeenTime":1577008650446,"publicGameCount":11,"difficulty":0.71875,"difficultyWeight":128},"battleship":{"count":213,"lastSeenTime":1577031885678,"publicGameCount":13,"difficulty":0.6632653061224489,"difficultyWeight":98},"bayonet":{"count":236,"lastSeenTime":1577034401652,"difficulty":0.6739130434782609,"difficultyWeight":46,"publicGameCount":4},"bazooka":{"count":218,"lastSeenTime":1577017359795,"publicGameCount":17,"difficulty":0.635036496350365,"difficultyWeight":137},"beak":{"count":236,"lastSeenTime":1577019799055,"difficulty":0.5136986301369864,"difficultyWeight":146,"publicGameCount":4},"bean":{"count":213,"lastSeenTime":1577018262363,"publicGameCount":7,"difficulty":0.6736111111111112,"difficultyWeight":144},"beanie":{"count":240,"lastSeenTime":1577012030780,"publicGameCount":7,"difficulty":0.6551724137931034,"difficultyWeight":87},"beanstalk":{"count":227,"lastSeenTime":1577002854632,"difficulty":0.8225806451612904,"difficultyWeight":62,"publicGameCount":6},"beaver":{"count":228,"lastSeenTime":1577019859074,"publicGameCount":7,"difficulty":0.6666666666666666,"difficultyWeight":84},"bed":{"count":201,"lastSeenTime":1577007477517,"publicGameCount":8,"difficulty":0.5495049504950497,"difficultyWeight":202},"bedtime":{"count":235,"lastSeenTime":1577018058770,"publicGameCount":17,"difficulty":0.6923076923076923,"difficultyWeight":169},"bee":{"count":195,"lastSeenTime":1577032910599,"publicGameCount":3,"difficulty":0.5,"difficultyWeight":196},"beer":{"count":209,"lastSeenTime":1577018235828,"difficulty":0.5354838709677419,"difficultyWeight":155,"publicGameCount":5},"bell":{"count":226,"lastSeenTime":1577031409078,"difficulty":0.5120000000000002,"difficultyWeight":250,"publicGameCount":3},"belly button":{"count":397,"lastSeenTime":1577009158040,"publicGameCount":41,"difficulty":0.6363636363636364,"difficultyWeight":319},"below":{"count":224,"lastSeenTime":1577033699738,"publicGameCount":8,"difficulty":0.6421052631578947,"difficultyWeight":95},"belt":{"count":240,"lastSeenTime":1577018445128,"publicGameCount":7,"difficulty":0.5294117647058825,"difficultyWeight":204},"bench":{"count":425,"lastSeenTime":1577015610581,"publicGameCount":32,"difficulty":0.5870307167235495,"difficultyWeight":293},"bicycle":{"count":225,"lastSeenTime":1577006837634,"difficulty":0.5546875000000001,"difficultyWeight":256,"publicGameCount":14},"billiards":{"count":215,"lastSeenTime":1577002745783,"publicGameCount":8,"difficulty":0.8333333333333334,"difficultyWeight":72},"bird":{"count":229,"lastSeenTime":1577036070954,"difficulty":0.48314606741573035,"difficultyWeight":178,"publicGameCount":5},"biscuit":{"count":207,"lastSeenTime":1577019635326,"difficulty":0.7152317880794702,"difficultyWeight":151,"publicGameCount":16},"bite":{"count":235,"lastSeenTime":1577024882700,"difficulty":0.5460526315789473,"difficultyWeight":152,"publicGameCount":10},"black hole":{"count":211,"lastSeenTime":1577036487959,"publicGameCount":21,"difficulty":0.5272727272727272,"difficultyWeight":165},"blackberry":{"count":234,"lastSeenTime":1577030057610,"publicGameCount":20,"difficulty":0.6794871794871795,"difficultyWeight":156},"blacksmith":{"count":242,"lastSeenTime":1577034107033,"publicGameCount":7,"difficulty":0.6567164179104478,"difficultyWeight":67},"blimp":{"count":245,"lastSeenTime":1577011942293,"difficulty":0.7279411764705882,"difficultyWeight":136,"publicGameCount":7},"blind":{"count":239,"lastSeenTime":1577033407643,"publicGameCount":6,"difficulty":0.5483870967741935,"difficultyWeight":93},"blindfold":{"count":226,"lastSeenTime":1577014939690,"publicGameCount":28,"difficulty":0.669683257918552,"difficultyWeight":221},"blizzard":{"count":445,"lastSeenTime":1577035678469,"publicGameCount":26,"difficulty":0.6747572815533981,"difficultyWeight":206},"blowfish":{"count":234,"lastSeenTime":1577024663216,"publicGameCount":17,"difficulty":0.4857142857142857,"difficultyWeight":140},"blue":{"count":420,"lastSeenTime":1577036882731,"difficulty":0.4179431072210066,"difficultyWeight":457,"publicGameCount":39},"blueberry":{"count":206,"lastSeenTime":1577020870978,"publicGameCount":18,"difficulty":0.54,"difficultyWeight":150},"board":{"count":230,"lastSeenTime":1577002644652,"publicGameCount":6,"difficulty":0.671875,"difficultyWeight":128},"bodyguard":{"count":234,"lastSeenTime":1577024978893,"difficulty":0.6666666666666666,"difficultyWeight":111,"publicGameCount":13},"bomb":{"count":240,"lastSeenTime":1577025426672,"difficulty":0.44015444015444016,"difficultyWeight":259,"publicGameCount":20},"booger":{"count":424,"lastSeenTime":1577025391428,"publicGameCount":29,"difficulty":0.6085271317829457,"difficultyWeight":258},"book":{"count":238,"lastSeenTime":1577036765048,"difficulty":0.4896265560165975,"difficultyWeight":241,"publicGameCount":10},"boomerang":{"count":219,"lastSeenTime":1577037236956,"publicGameCount":10,"difficulty":0.6153846153846154,"difficultyWeight":130},"bottle":{"count":232,"lastSeenTime":1577033670196,"difficulty":0.5472972972972973,"difficultyWeight":148,"publicGameCount":8},"bounce":{"count":253,"lastSeenTime":1577029982333,"publicGameCount":11,"difficulty":0.6333333333333333,"difficultyWeight":120},"bowl":{"count":239,"lastSeenTime":1577035692632,"difficulty":0.5092592592592594,"difficultyWeight":216,"publicGameCount":16},"bowling":{"count":224,"lastSeenTime":1577010511117,"difficulty":0.6266666666666667,"difficultyWeight":150,"publicGameCount":11},"box":{"count":235,"lastSeenTime":1577034613528,"difficulty":0.5421686746987956,"difficultyWeight":249,"publicGameCount":2},"boy":{"count":234,"lastSeenTime":1577013899075,"difficulty":0.6115384615384616,"difficultyWeight":260,"publicGameCount":10},"bracelet":{"count":204,"lastSeenTime":1576947376959,"publicGameCount":7,"difficulty":0.7086614173228346,"difficultyWeight":127},"brain":{"count":432,"lastSeenTime":1577032037095,"publicGameCount":46,"difficulty":0.49865229110512127,"difficultyWeight":371},"branch":{"count":410,"lastSeenTime":1577034642507,"publicGameCount":24,"difficulty":0.6053811659192825,"difficultyWeight":223},"brand":{"count":235,"lastSeenTime":1577000571830,"publicGameCount":10,"difficulty":0.6021505376344086,"difficultyWeight":93},"bread":{"count":238,"lastSeenTime":1577030702095,"difficulty":0.50990099009901,"difficultyWeight":202,"publicGameCount":12},"breakfast":{"count":221,"lastSeenTime":1577031023734,"difficulty":0.6549295774647887,"difficultyWeight":142,"publicGameCount":14},"breath":{"count":430,"lastSeenTime":1577004292006,"publicGameCount":25,"difficulty":0.6171171171171174,"difficultyWeight":222},"bride":{"count":219,"lastSeenTime":1577032444866,"publicGameCount":8,"difficulty":0.5394736842105263,"difficultyWeight":76},"bridge":{"count":461,"lastSeenTime":1577017763955,"publicGameCount":47,"difficulty":0.607142857142857,"difficultyWeight":420},"broadcast":{"count":223,"lastSeenTime":1577029603248,"difficulty":0.7096774193548387,"difficultyWeight":62,"publicGameCount":5},"broccoli":{"count":214,"lastSeenTime":1577019041654,"publicGameCount":14,"difficulty":0.5820895522388059,"difficultyWeight":201},"broken heart":{"count":208,"lastSeenTime":1577015710329,"publicGameCount":34,"difficulty":0.5,"difficultyWeight":256},"bronze":{"count":228,"lastSeenTime":1576998388543,"publicGameCount":6,"difficulty":0.7283950617283951,"difficultyWeight":81},"brownie":{"count":217,"lastSeenTime":1577020516206,"publicGameCount":10,"difficulty":0.6904761904761905,"difficultyWeight":84},"bruise":{"count":232,"lastSeenTime":1577000981163,"publicGameCount":8,"difficulty":0.6395348837209303,"difficultyWeight":86},"bubble":{"count":203,"lastSeenTime":1577006766360,"publicGameCount":17,"difficulty":0.5795918367346938,"difficultyWeight":245},"bubble gum":{"count":203,"lastSeenTime":1577032530295,"publicGameCount":35,"difficulty":0.5719844357976653,"difficultyWeight":257},"bucket":{"count":236,"lastSeenTime":1576983054666,"difficulty":0.5703124999999998,"difficultyWeight":256,"publicGameCount":7},"bulge":{"count":201,"lastSeenTime":1577033719031,"difficulty":0.7605633802816901,"difficultyWeight":71,"publicGameCount":7},"bull":{"count":236,"lastSeenTime":1577036882731,"difficulty":0.5592105263157894,"difficultyWeight":152,"publicGameCount":14},"bulldozer":{"count":255,"lastSeenTime":1577011734748,"publicGameCount":10,"difficulty":0.6944444444444444,"difficultyWeight":72},"bungee jumping":{"count":222,"lastSeenTime":1577033780065,"publicGameCount":20,"difficulty":0.6929133858267716,"difficultyWeight":127},"bunny":{"count":228,"lastSeenTime":1577020774303,"difficulty":0.4864864864864865,"difficultyWeight":148,"publicGameCount":2},"bus driver":{"count":240,"lastSeenTime":1577033708898,"publicGameCount":20,"difficulty":0.6524390243902439,"difficultyWeight":164},"butler":{"count":256,"lastSeenTime":1577014769336,"publicGameCount":15,"difficulty":0.5964912280701754,"difficultyWeight":114},"button":{"count":221,"lastSeenTime":1577029763817,"publicGameCount":11,"difficulty":0.6467661691542289,"difficultyWeight":201},"cab driver":{"count":247,"lastSeenTime":1577019664821,"publicGameCount":12,"difficulty":0.8181818181818182,"difficultyWeight":88},"cabin":{"count":432,"lastSeenTime":1577013545590,"publicGameCount":16,"difficulty":0.5030674846625767,"difficultyWeight":163},"cactus":{"count":429,"lastSeenTime":1577032147462,"publicGameCount":47,"difficulty":0.4064665127020785,"difficultyWeight":433},"cage":{"count":229,"lastSeenTime":1576947664758,"publicGameCount":9,"difficulty":0.6037735849056604,"difficultyWeight":106},"cake":{"count":236,"lastSeenTime":1577036096380,"difficulty":0.49056603773584906,"difficultyWeight":265,"publicGameCount":15},"camel":{"count":233,"lastSeenTime":1576996756331,"difficulty":0.49693251533742333,"difficultyWeight":163,"publicGameCount":4},"campfire":{"count":256,"lastSeenTime":1577034121420,"difficulty":0.5394736842105263,"difficultyWeight":228,"publicGameCount":22},"can opener":{"count":218,"lastSeenTime":1577034603831,"publicGameCount":11,"difficulty":0.7444444444444445,"difficultyWeight":90},"cannon":{"count":213,"lastSeenTime":1577015776309,"difficulty":0.6,"difficultyWeight":60,"publicGameCount":4},"canyon":{"count":468,"lastSeenTime":1577036645866,"publicGameCount":18,"difficulty":0.7006802721088435,"difficultyWeight":147},"cape":{"count":231,"lastSeenTime":1577035644067,"publicGameCount":15,"difficulty":0.5518867924528303,"difficultyWeight":212},"cappuccino":{"count":227,"lastSeenTime":1577009296414,"publicGameCount":11,"difficulty":0.8235294117647058,"difficultyWeight":85},"captain":{"count":210,"lastSeenTime":1576990355848,"publicGameCount":9,"difficulty":0.7477477477477478,"difficultyWeight":111},"carpenter":{"count":212,"lastSeenTime":1577019945970,"publicGameCount":3,"difficulty":0.7407407407407407,"difficultyWeight":27},"carpet":{"count":266,"lastSeenTime":1577031546307,"difficulty":0.608433734939759,"difficultyWeight":166,"publicGameCount":15},"carrot":{"count":228,"lastSeenTime":1577020735420,"difficulty":0.46503496503496505,"difficultyWeight":286,"publicGameCount":6},"cast":{"count":208,"lastSeenTime":1577018733113,"publicGameCount":7,"difficulty":0.5844155844155844,"difficultyWeight":77},"cathedral":{"count":458,"lastSeenTime":1577029554508,"publicGameCount":13,"difficulty":0.7553191489361702,"difficultyWeight":94},"cauldron":{"count":251,"lastSeenTime":1577014754709,"publicGameCount":11,"difficulty":0.6375,"difficultyWeight":80},"cauliflower":{"count":219,"lastSeenTime":1577016651044,"difficulty":0.676056338028169,"difficultyWeight":71,"publicGameCount":8},"caveman":{"count":234,"lastSeenTime":1577037263306,"publicGameCount":14,"difficulty":0.5746268656716418,"difficultyWeight":134},"ceiling fan":{"count":246,"lastSeenTime":1577032701751,"publicGameCount":25,"difficulty":0.7244897959183672,"difficultyWeight":196},"celebrate":{"count":218,"lastSeenTime":1577016031951,"publicGameCount":6,"difficulty":0.776595744680851,"difficultyWeight":94},"cell":{"count":231,"lastSeenTime":1576982895854,"publicGameCount":10,"difficulty":0.7757009345794392,"difficultyWeight":107},"centipede":{"count":241,"lastSeenTime":1577005234169,"publicGameCount":13,"difficulty":0.6888888888888889,"difficultyWeight":135},"chain":{"count":213,"lastSeenTime":1577012145150,"difficulty":0.5384615384615385,"difficultyWeight":234,"publicGameCount":10},"chair":{"count":213,"lastSeenTime":1577019921307,"difficulty":0.5070422535211269,"difficultyWeight":213,"publicGameCount":3},"chalk":{"count":240,"lastSeenTime":1577037306624,"publicGameCount":11,"difficulty":0.6829268292682927,"difficultyWeight":123},"champagne":{"count":230,"lastSeenTime":1577033508319,"publicGameCount":11,"difficulty":0.6907216494845361,"difficultyWeight":97},"champion":{"count":226,"lastSeenTime":1577034556334,"publicGameCount":12,"difficulty":0.6148148148148149,"difficultyWeight":135},"chandelier":{"count":217,"lastSeenTime":1577029650059,"publicGameCount":15,"difficulty":0.6865671641791045,"difficultyWeight":134},"cheek":{"count":406,"lastSeenTime":1576986114754,"publicGameCount":25,"difficulty":0.5564853556485355,"difficultyWeight":239},"cheese":{"count":235,"lastSeenTime":1577037568133,"publicGameCount":16,"difficulty":0.38076923076923075,"difficultyWeight":260},"cheesecake":{"count":206,"lastSeenTime":1577015110298,"publicGameCount":12,"difficulty":0.5867768595041323,"difficultyWeight":121},"cheetah":{"count":267,"lastSeenTime":1577001547359,"publicGameCount":12,"difficulty":0.5047619047619047,"difficultyWeight":105},"chef":{"count":214,"lastSeenTime":1577024929912,"publicGameCount":15,"difficulty":0.5555555555555558,"difficultyWeight":180},"cherry":{"count":213,"lastSeenTime":1577034656692,"difficulty":0.5040983606557375,"difficultyWeight":244,"publicGameCount":6},"chess":{"count":247,"lastSeenTime":1577018073317,"publicGameCount":8,"difficulty":0.49382716049382713,"difficultyWeight":162},"chest":{"count":606,"lastSeenTime":1577037202536,"publicGameCount":82,"difficulty":0.6106983655274891,"difficultyWeight":673},"chest hair":{"count":438,"lastSeenTime":1577018733113,"publicGameCount":48,"difficulty":0.6304347826086958,"difficultyWeight":322},"chestplate":{"count":212,"lastSeenTime":1576976966651,"difficulty":0.746031746031746,"difficultyWeight":63,"publicGameCount":6},"chicken":{"count":441,"lastSeenTime":1577037497263,"publicGameCount":50,"difficulty":0.5815450643776826,"difficultyWeight":466},"chihuahua":{"count":221,"lastSeenTime":1576993284545,"difficulty":0.7333333333333333,"difficultyWeight":105,"publicGameCount":11},"child":{"count":222,"lastSeenTime":1577033593279,"difficulty":0.591160220994475,"difficultyWeight":181,"publicGameCount":6},"chin":{"count":472,"lastSeenTime":1577033699738,"publicGameCount":28,"difficulty":0.5660377358490566,"difficultyWeight":265},"chocolate":{"count":232,"lastSeenTime":1577007615650,"publicGameCount":18,"difficulty":0.5509259259259259,"difficultyWeight":216},"church":{"count":446,"lastSeenTime":1577032591482,"publicGameCount":57,"difficulty":0.4467120181405896,"difficultyWeight":441},"cigarette":{"count":218,"lastSeenTime":1577031155319,"publicGameCount":21,"difficulty":0.5323383084577114,"difficultyWeight":201},"cinema":{"count":438,"lastSeenTime":1577021253681,"difficulty":0.6470588235294118,"difficultyWeight":255,"publicGameCount":30},"circle":{"count":213,"lastSeenTime":1577025451893,"difficulty":0.6349206349206348,"difficultyWeight":252,"publicGameCount":14},"clap":{"count":232,"lastSeenTime":1577036401976,"publicGameCount":6,"difficulty":0.5242718446601943,"difficultyWeight":103},"clickbait":{"count":246,"lastSeenTime":1577015885827,"publicGameCount":12,"difficulty":0.631578947368421,"difficultyWeight":76},"cliff":{"count":390,"lastSeenTime":1577017714611,"difficulty":0.5888888888888889,"difficultyWeight":270,"publicGameCount":22},"climb":{"count":228,"lastSeenTime":1577016728346,"difficulty":0.5169491525423728,"difficultyWeight":118,"publicGameCount":6},"cloak":{"count":223,"lastSeenTime":1577000608344,"publicGameCount":6,"difficulty":0.6621621621621622,"difficultyWeight":74},"clock":{"count":231,"lastSeenTime":1577024586841,"difficulty":0.5,"difficultyWeight":288,"publicGameCount":6},"clothes hanger":{"count":224,"lastSeenTime":1577025028815,"publicGameCount":21,"difficulty":0.6917808219178082,"difficultyWeight":146},"cloud":{"count":443,"lastSeenTime":1577035383092,"publicGameCount":51,"difficulty":0.41735537190082644,"difficultyWeight":484},"clover":{"count":430,"lastSeenTime":1577018434581,"publicGameCount":34,"difficulty":0.5225225225225223,"difficultyWeight":333},"coach":{"count":220,"lastSeenTime":1577011865165,"publicGameCount":9,"difficulty":0.7070707070707071,"difficultyWeight":99},"coal":{"count":264,"lastSeenTime":1577033444243,"publicGameCount":10,"difficulty":0.5612244897959183,"difficultyWeight":98},"coast guard":{"count":218,"lastSeenTime":1577019435052,"publicGameCount":12,"difficulty":0.7865168539325843,"difficultyWeight":89},"coat":{"count":221,"lastSeenTime":1576998860918,"difficulty":0.5957446808510638,"difficultyWeight":47,"publicGameCount":1},"cockroach":{"count":230,"lastSeenTime":1577006776589,"publicGameCount":15,"difficulty":0.5695364238410596,"difficultyWeight":151},"coconut":{"count":215,"lastSeenTime":1577018038260,"publicGameCount":20,"difficulty":0.5756457564575643,"difficultyWeight":271},"cocoon":{"count":196,"lastSeenTime":1577036303309,"publicGameCount":8,"difficulty":0.7702702702702703,"difficultyWeight":74},"coffee":{"count":243,"lastSeenTime":1577010447702,"difficulty":0.4763779527559055,"difficultyWeight":254,"publicGameCount":18},"coffee shop":{"count":438,"lastSeenTime":1577035569138,"publicGameCount":43,"difficulty":0.7444794952681388,"difficultyWeight":317},"coffin":{"count":214,"lastSeenTime":1576996730066,"publicGameCount":13,"difficulty":0.5182926829268294,"difficultyWeight":164},"coin":{"count":240,"lastSeenTime":1577030372247,"publicGameCount":9,"difficulty":0.5096153846153848,"difficultyWeight":208},"collar":{"count":228,"lastSeenTime":1577030861848,"difficulty":0.5897435897435898,"difficultyWeight":117,"publicGameCount":8},"color-blind":{"count":244,"lastSeenTime":1577018410162,"publicGameCount":12,"difficulty":0.8695652173913043,"difficultyWeight":92},"comb":{"count":241,"lastSeenTime":1577035202003,"difficulty":0.5183486238532111,"difficultyWeight":218,"publicGameCount":14},"comedian":{"count":240,"lastSeenTime":1576988478150,"difficulty":0.6666666666666666,"difficultyWeight":60,"publicGameCount":5},"comic book":{"count":223,"lastSeenTime":1577024181667,"publicGameCount":16,"difficulty":0.6929824561403509,"difficultyWeight":114},"commercial":{"count":241,"lastSeenTime":1576994067476,"publicGameCount":7,"difficulty":0.8392857142857143,"difficultyWeight":56},"communism":{"count":244,"lastSeenTime":1576986940805,"publicGameCount":14,"difficulty":0.6444444444444445,"difficultyWeight":90},"complete":{"count":414,"lastSeenTime":1577031607937,"publicGameCount":17,"difficulty":0.6891891891891891,"difficultyWeight":148},"computer":{"count":241,"lastSeenTime":1577033983037,"publicGameCount":12,"difficulty":0.478494623655914,"difficultyWeight":186},"concert":{"count":261,"lastSeenTime":1577032883820,"publicGameCount":10,"difficulty":0.7066666666666667,"difficultyWeight":75},"confused":{"count":216,"lastSeenTime":1577035654185,"publicGameCount":8,"difficulty":0.5595238095238095,"difficultyWeight":84},"console":{"count":183,"lastSeenTime":1576986189390,"publicGameCount":6,"difficulty":0.675,"difficultyWeight":120},"corkscrew":{"count":217,"lastSeenTime":1577012020436,"publicGameCount":8,"difficulty":0.626865671641791,"difficultyWeight":67},"corn":{"count":231,"lastSeenTime":1577018661849,"difficulty":0.47058823529411764,"difficultyWeight":170,"publicGameCount":4},"corn dog":{"count":223,"lastSeenTime":1577036846155,"publicGameCount":22,"difficulty":0.574585635359116,"difficultyWeight":181},"corpse":{"count":234,"lastSeenTime":1577025711695,"difficulty":0.7214285714285714,"difficultyWeight":140,"publicGameCount":13},"cotton":{"count":256,"lastSeenTime":1576996517140,"publicGameCount":6,"difficulty":0.6527777777777778,"difficultyWeight":72},"cotton candy":{"count":214,"lastSeenTime":1577000929474,"publicGameCount":39,"difficulty":0.5841584158415841,"difficultyWeight":303},"crab":{"count":434,"lastSeenTime":1577036110764,"difficulty":0.4235294117647059,"difficultyWeight":340,"publicGameCount":39},"crack":{"count":276,"lastSeenTime":1577037568133,"difficulty":0.6436781609195402,"difficultyWeight":174,"publicGameCount":15},"crayon":{"count":229,"lastSeenTime":1577010680782,"difficulty":0.6181818181818183,"difficultyWeight":165,"publicGameCount":11},"credit":{"count":231,"lastSeenTime":1577029674779,"publicGameCount":7,"difficulty":0.6612903225806451,"difficultyWeight":62},"credit card":{"count":247,"lastSeenTime":1577034329984,"publicGameCount":31,"difficulty":0.6403508771929823,"difficultyWeight":228},"cricket":{"count":219,"lastSeenTime":1577032910599,"difficulty":0.6376811594202898,"difficultyWeight":138,"publicGameCount":5},"crocodile":{"count":217,"lastSeenTime":1577031583222,"difficulty":0.5662650602409639,"difficultyWeight":166,"publicGameCount":12},"crossbow":{"count":247,"lastSeenTime":1577016590802,"difficulty":0.5925925925925926,"difficultyWeight":189,"publicGameCount":22},"crow":{"count":211,"lastSeenTime":1577032222590,"publicGameCount":8,"difficulty":0.5217391304347826,"difficultyWeight":92},"cruise":{"count":212,"lastSeenTime":1577030372247,"publicGameCount":2,"difficulty":0.75,"difficultyWeight":48},"crust":{"count":210,"lastSeenTime":1576983512728,"difficulty":0.6644295302013422,"difficultyWeight":149,"publicGameCount":7},"crystal":{"count":225,"lastSeenTime":1577033920831,"publicGameCount":11,"difficulty":0.6794871794871795,"difficultyWeight":156},"cube":{"count":220,"lastSeenTime":1577032198145,"publicGameCount":14,"difficulty":0.5458715596330276,"difficultyWeight":218},"cuckoo":{"count":213,"lastSeenTime":1577017097804,"publicGameCount":4,"difficulty":0.65,"difficultyWeight":40},"cucumber":{"count":235,"lastSeenTime":1577036070954,"publicGameCount":18,"difficulty":0.5824175824175825,"difficultyWeight":182},"cupboard":{"count":238,"lastSeenTime":1577037446644,"publicGameCount":9,"difficulty":0.8309859154929577,"difficultyWeight":142},"cupcake":{"count":211,"lastSeenTime":1577033997203,"difficulty":0.5052631578947369,"difficultyWeight":190,"publicGameCount":13},"curtain":{"count":191,"lastSeenTime":1576977126292,"difficulty":0.5855263157894738,"difficultyWeight":152,"publicGameCount":5},"cut":{"count":216,"lastSeenTime":1577012130912,"publicGameCount":8,"difficulty":0.5955882352941176,"difficultyWeight":136},"cyborg":{"count":218,"lastSeenTime":1577015080639,"difficulty":0.5818181818181818,"difficultyWeight":55,"publicGameCount":7},"cylinder":{"count":237,"lastSeenTime":1577031248949,"publicGameCount":16,"difficulty":0.5982142857142859,"difficultyWeight":112},"dagger":{"count":198,"lastSeenTime":1576979491238,"difficulty":0.7465753424657534,"difficultyWeight":146,"publicGameCount":9},"daisy":{"count":435,"lastSeenTime":1577030311398,"difficulty":0.5906250000000002,"difficultyWeight":320,"publicGameCount":33},"dance":{"count":250,"lastSeenTime":1576966284603,"difficulty":0.6470588235294116,"difficultyWeight":170,"publicGameCount":16},"dandelion":{"count":471,"lastSeenTime":1577037103049,"publicGameCount":21,"difficulty":0.7294685990338164,"difficultyWeight":207},"deaf":{"count":211,"lastSeenTime":1577033619352,"publicGameCount":5,"difficulty":0.5833333333333334,"difficultyWeight":132},"demon":{"count":217,"lastSeenTime":1577024636673,"publicGameCount":8,"difficulty":0.6435643564356436,"difficultyWeight":202},"demonstration":{"count":207,"lastSeenTime":1577009779663,"publicGameCount":7,"difficulty":0.72,"difficultyWeight":50},"deodorant":{"count":222,"lastSeenTime":1577033017430,"publicGameCount":13,"difficulty":0.6418918918918919,"difficultyWeight":148},"depressed":{"count":237,"lastSeenTime":1576965662459,"publicGameCount":16,"difficulty":0.578125,"difficultyWeight":128},"derp":{"count":211,"lastSeenTime":1577014619671,"publicGameCount":8,"difficulty":0.5983606557377049,"difficultyWeight":122},"desk":{"count":239,"lastSeenTime":1577031102670,"difficulty":0.6745562130177515,"difficultyWeight":169,"publicGameCount":7},"dessert":{"count":232,"lastSeenTime":1577037412232,"publicGameCount":15,"difficulty":0.6566265060240963,"difficultyWeight":166},"detonate":{"count":220,"lastSeenTime":1576975314574,"publicGameCount":6,"difficulty":0.8493150684931506,"difficultyWeight":73},"diagonal":{"count":209,"lastSeenTime":1577036574064,"publicGameCount":10,"difficulty":0.794392523364486,"difficultyWeight":107},"diamond":{"count":237,"lastSeenTime":1577020464611,"difficulty":0.4671814671814672,"difficultyWeight":259,"publicGameCount":18},"diaper":{"count":252,"lastSeenTime":1577014779545,"publicGameCount":10,"difficulty":0.6176470588235294,"difficultyWeight":136},"dictionary":{"count":265,"lastSeenTime":1577033906184,"publicGameCount":20,"difficulty":0.6079545454545454,"difficultyWeight":176},"diet":{"count":243,"lastSeenTime":1577030057610,"publicGameCount":8,"difficulty":0.6521739130434784,"difficultyWeight":92},"dinosaur":{"count":230,"lastSeenTime":1577030567444,"publicGameCount":16,"difficulty":0.5608465608465608,"difficultyWeight":189},"dirty":{"count":428,"lastSeenTime":1577018625054,"difficulty":0.6593406593406592,"difficultyWeight":182,"publicGameCount":26},"dispenser":{"count":227,"lastSeenTime":1577017724852,"publicGameCount":4,"difficulty":0.8387096774193549,"difficultyWeight":31},"distance":{"count":224,"lastSeenTime":1576994305172,"difficulty":0.8064516129032258,"difficultyWeight":93,"publicGameCount":7},"divorce":{"count":216,"lastSeenTime":1577031943447,"publicGameCount":14,"difficulty":0.652542372881356,"difficultyWeight":118},"dizzy":{"count":418,"lastSeenTime":1577032910599,"publicGameCount":26,"difficulty":0.6170212765957447,"difficultyWeight":235},"doghouse":{"count":408,"lastSeenTime":1577010309027,"publicGameCount":39,"difficulty":0.5927051671732522,"difficultyWeight":329},"dollar":{"count":218,"lastSeenTime":1577032026722,"difficulty":0.46666666666666673,"difficultyWeight":255,"publicGameCount":10},"dollhouse":{"count":211,"lastSeenTime":1576973874742,"publicGameCount":7,"difficulty":0.5851063829787234,"difficultyWeight":94},"dolphin":{"count":211,"lastSeenTime":1577035900512,"difficulty":0.5603448275862067,"difficultyWeight":232,"publicGameCount":10},"dominoes":{"count":226,"lastSeenTime":1577032716307,"difficulty":0.6347305389221555,"difficultyWeight":167,"publicGameCount":10},"door":{"count":218,"lastSeenTime":1577016094689,"difficulty":0.5297029702970297,"difficultyWeight":202,"publicGameCount":3},"doorknob":{"count":225,"lastSeenTime":1576987429699,"publicGameCount":18,"difficulty":0.5317919075144507,"difficultyWeight":173},"download":{"count":235,"lastSeenTime":1577033407643,"publicGameCount":18,"difficulty":0.618421052631579,"difficultyWeight":152},"dragon":{"count":221,"lastSeenTime":1577003395215,"difficulty":0.5524861878453039,"difficultyWeight":181,"publicGameCount":7},"dragonfly":{"count":200,"lastSeenTime":1576990735116,"publicGameCount":12,"difficulty":0.5578231292517006,"difficultyWeight":147},"drawer":{"count":231,"lastSeenTime":1577032787613,"publicGameCount":7,"difficulty":0.7029702970297029,"difficultyWeight":101},"drink":{"count":391,"lastSeenTime":1577031510950,"publicGameCount":32,"difficulty":0.5630252100840337,"difficultyWeight":357},"drive":{"count":250,"lastSeenTime":1577024698445,"publicGameCount":14,"difficulty":0.6212121212121213,"difficultyWeight":198},"driver":{"count":249,"lastSeenTime":1577037412232,"difficulty":0.5925925925925927,"difficultyWeight":162,"publicGameCount":14},"drool":{"count":221,"lastSeenTime":1577018610787,"difficulty":0.6541353383458647,"difficultyWeight":133,"publicGameCount":7},"droplet":{"count":387,"lastSeenTime":1577001449472,"publicGameCount":30,"difficulty":0.6498054474708171,"difficultyWeight":257},"duct tape":{"count":207,"lastSeenTime":1577017859865,"publicGameCount":12,"difficulty":0.7346938775510204,"difficultyWeight":98},"dynamite":{"count":216,"lastSeenTime":1577034440167,"publicGameCount":19,"difficulty":0.597989949748744,"difficultyWeight":199},"eagle":{"count":208,"lastSeenTime":1576975499357,"difficulty":0.47368421052631576,"difficultyWeight":171,"publicGameCount":9},"earbuds":{"count":221,"lastSeenTime":1577012475718,"publicGameCount":22,"difficulty":0.5968586387434555,"difficultyWeight":191},"earwax":{"count":401,"lastSeenTime":1577013730906,"publicGameCount":37,"difficulty":0.6137566137566137,"difficultyWeight":378},"eat":{"count":404,"lastSeenTime":1577030358000,"difficulty":0.6607142857142857,"difficultyWeight":280,"publicGameCount":15},"egg":{"count":191,"lastSeenTime":1577017859865,"difficulty":0.5219123505976095,"difficultyWeight":251,"publicGameCount":9},"electric car":{"count":244,"lastSeenTime":1577035544830,"publicGameCount":16,"difficulty":0.7867647058823529,"difficultyWeight":136},"electric guitar":{"count":461,"lastSeenTime":1577014429167,"publicGameCount":35,"difficulty":0.7862318840579711,"difficultyWeight":276},"elephant":{"count":233,"lastSeenTime":1577014153105,"publicGameCount":22,"difficulty":0.4418604651162791,"difficultyWeight":215},"elevator":{"count":235,"lastSeenTime":1577033647739,"publicGameCount":13,"difficulty":0.48360655737704916,"difficultyWeight":122},"end":{"count":229,"lastSeenTime":1577031138755,"difficulty":0.6145833333333334,"difficultyWeight":96,"publicGameCount":7},"engine":{"count":242,"lastSeenTime":1577036158826,"publicGameCount":8,"difficulty":0.5975609756097561,"difficultyWeight":82},"equator":{"count":405,"lastSeenTime":1577025975223,"publicGameCount":26,"difficulty":0.5942028985507246,"difficultyWeight":207},"error":{"count":242,"lastSeenTime":1576973278025,"difficulty":0.5468750000000002,"difficultyWeight":128,"publicGameCount":11},"evaporate":{"count":242,"lastSeenTime":1576988895070,"publicGameCount":4,"difficulty":0.8,"difficultyWeight":35},"evening":{"count":231,"lastSeenTime":1576986689127,"publicGameCount":7,"difficulty":0.7402597402597403,"difficultyWeight":77},"evolution":{"count":220,"lastSeenTime":1577010384587,"difficulty":0.6417910447761194,"difficultyWeight":67,"publicGameCount":7},"exam":{"count":231,"lastSeenTime":1576979584203,"publicGameCount":19,"difficulty":0.5180722891566265,"difficultyWeight":166},"explosion":{"count":246,"lastSeenTime":1577029996661,"publicGameCount":20,"difficulty":0.6142131979695431,"difficultyWeight":197},"eye":{"count":413,"lastSeenTime":1577034239310,"difficulty":0.4728682170542636,"difficultyWeight":387,"publicGameCount":14},"eyebrow":{"count":445,"lastSeenTime":1577037511458,"publicGameCount":58,"difficulty":0.5087040618955514,"difficultyWeight":517},"eyeshadow":{"count":216,"lastSeenTime":1577007491736,"publicGameCount":12,"difficulty":0.6486486486486487,"difficultyWeight":111},"face paint":{"count":216,"lastSeenTime":1577010323756,"publicGameCount":11,"difficulty":0.7123287671232876,"difficultyWeight":73},"fall":{"count":461,"lastSeenTime":1577025129454,"publicGameCount":32,"difficulty":0.5156794425087107,"difficultyWeight":287},"family":{"count":232,"lastSeenTime":1576999137808,"difficulty":0.5700000000000001,"difficultyWeight":100,"publicGameCount":2},"farm":{"count":421,"lastSeenTime":1577030888377,"publicGameCount":29,"difficulty":0.5379939209726443,"difficultyWeight":329},"farmer":{"count":233,"lastSeenTime":1577019636661,"publicGameCount":14,"difficulty":0.5862068965517241,"difficultyWeight":145},"fashion designer":{"count":247,"lastSeenTime":1577016742708,"publicGameCount":8,"difficulty":0.7619047619047619,"difficultyWeight":42},"fast":{"count":445,"lastSeenTime":1577015786414,"publicGameCount":36,"difficulty":0.5367412140575079,"difficultyWeight":313},"fast forward":{"count":244,"lastSeenTime":1577020962581,"publicGameCount":19,"difficulty":0.7103448275862069,"difficultyWeight":145},"father":{"count":213,"lastSeenTime":1577020439934,"difficulty":0.7,"difficultyWeight":160,"publicGameCount":9},"faucet":{"count":214,"lastSeenTime":1577034546199,"difficulty":0.6721311475409836,"difficultyWeight":61,"publicGameCount":6},"fidget spinner":{"count":251,"lastSeenTime":1577029617419,"publicGameCount":43,"difficulty":0.6327868852459017,"difficultyWeight":305},"filmmaker":{"count":227,"lastSeenTime":1577001561609,"publicGameCount":9,"difficulty":0.6486486486486487,"difficultyWeight":74},"fingertip":{"count":444,"lastSeenTime":1577032358945,"publicGameCount":34,"difficulty":0.6431372549019608,"difficultyWeight":255},"fire truck":{"count":246,"lastSeenTime":1577011245370,"publicGameCount":30,"difficulty":0.5879629629629631,"difficultyWeight":216},"fireball":{"count":249,"lastSeenTime":1577010869992,"publicGameCount":25,"difficulty":0.6709956709956709,"difficultyWeight":231},"firehouse":{"count":440,"lastSeenTime":1577011662153,"publicGameCount":19,"difficulty":0.5999999999999999,"difficultyWeight":200},"fireman":{"count":214,"lastSeenTime":1577010262294,"publicGameCount":17,"difficulty":0.6211453744493389,"difficultyWeight":227},"fireplace":{"count":223,"lastSeenTime":1577032859509,"publicGameCount":14,"difficulty":0.5879396984924623,"difficultyWeight":199},"fireside":{"count":220,"lastSeenTime":1577033078485,"difficulty":0.7333333333333333,"difficultyWeight":60,"publicGameCount":4},"firework":{"count":237,"lastSeenTime":1577018586401,"publicGameCount":20,"difficulty":0.5208333333333335,"difficultyWeight":240},"fish bowl":{"count":220,"lastSeenTime":1577034656692,"publicGameCount":29,"difficulty":0.514018691588785,"difficultyWeight":214},"fist fight":{"count":227,"lastSeenTime":1577036293187,"difficulty":0.7345132743362832,"difficultyWeight":113,"publicGameCount":11},"fitness trainer":{"count":213,"lastSeenTime":1577025726927,"publicGameCount":8,"difficulty":0.7647058823529411,"difficultyWeight":51},"flag":{"count":426,"lastSeenTime":1577033997203,"publicGameCount":46,"difficulty":0.3579418344519016,"difficultyWeight":447},"flagpole":{"count":447,"lastSeenTime":1577018352358,"publicGameCount":40,"difficulty":0.6446540880503144,"difficultyWeight":318},"flamethrower":{"count":229,"lastSeenTime":1577019945970,"publicGameCount":26,"difficulty":0.7348066298342542,"difficultyWeight":181},"flea":{"count":221,"lastSeenTime":1577010774216,"difficulty":0.6630434782608695,"difficultyWeight":92,"publicGameCount":4},"flock":{"count":236,"lastSeenTime":1577021290587,"publicGameCount":6,"difficulty":0.5777777777777777,"difficultyWeight":90},"flower":{"count":447,"lastSeenTime":1577037345324,"publicGameCount":53,"difficulty":0.38228941684665224,"difficultyWeight":463},"flu":{"count":212,"lastSeenTime":1576974949148,"publicGameCount":8,"difficulty":0.44,"difficultyWeight":75},"fly":{"count":421,"lastSeenTime":1577031113164,"difficulty":0.566750629722922,"difficultyWeight":397,"publicGameCount":10},"fog":{"count":421,"lastSeenTime":1577020143058,"publicGameCount":12,"difficulty":0.6878980891719745,"difficultyWeight":157},"fortune":{"count":232,"lastSeenTime":1577016150699,"publicGameCount":5,"difficulty":0.8028169014084507,"difficultyWeight":71},"fossil":{"count":448,"lastSeenTime":1577034689603,"publicGameCount":20,"difficulty":0.7185929648241205,"difficultyWeight":199},"fountain":{"count":435,"lastSeenTime":1577025578748,"publicGameCount":49,"difficulty":0.5555555555555554,"difficultyWeight":369},"freezer":{"count":212,"lastSeenTime":1576999462046,"publicGameCount":13,"difficulty":0.5675675675675677,"difficultyWeight":111},"fridge":{"count":225,"lastSeenTime":1577018571006,"difficulty":0.5418994413407822,"difficultyWeight":179,"publicGameCount":11},"fries":{"count":213,"lastSeenTime":1577015197399,"difficulty":0.46443514644351463,"difficultyWeight":239,"publicGameCount":3},"frog":{"count":222,"lastSeenTime":1577015586196,"publicGameCount":7,"difficulty":0.46153846153846156,"difficultyWeight":130},"frown":{"count":223,"lastSeenTime":1577036283076,"publicGameCount":9,"difficulty":0.6083333333333333,"difficultyWeight":120},"fruit":{"count":233,"lastSeenTime":1577007767963,"difficulty":0.4015748031496063,"difficultyWeight":127,"publicGameCount":5},"full":{"count":475,"lastSeenTime":1577010615663,"publicGameCount":36,"difficulty":0.5847176079734219,"difficultyWeight":301},"funeral":{"count":231,"lastSeenTime":1577036754761,"publicGameCount":11,"difficulty":0.5454545454545454,"difficultyWeight":88},"funny":{"count":483,"lastSeenTime":1577035569138,"publicGameCount":34,"difficulty":0.6825396825396826,"difficultyWeight":252},"gang":{"count":238,"lastSeenTime":1577034096819,"publicGameCount":7,"difficulty":0.6639344262295082,"difficultyWeight":122},"garbage":{"count":221,"lastSeenTime":1577034556334,"publicGameCount":18,"difficulty":0.6103286384976526,"difficultyWeight":213},"gardener":{"count":227,"lastSeenTime":1577026040111,"publicGameCount":12,"difficulty":0.7431192660550459,"difficultyWeight":109},"garlic":{"count":231,"lastSeenTime":1577030520806,"publicGameCount":14,"difficulty":0.5583333333333333,"difficultyWeight":120},"gas mask":{"count":241,"lastSeenTime":1577002956642,"publicGameCount":23,"difficulty":0.7159090909090909,"difficultyWeight":176},"gate":{"count":233,"lastSeenTime":1577011781649,"difficulty":0.5586592178770949,"difficultyWeight":179,"publicGameCount":15},"gem":{"count":230,"lastSeenTime":1577018192097,"difficulty":0.5967741935483871,"difficultyWeight":186,"publicGameCount":4},"genie":{"count":247,"lastSeenTime":1576994586439,"publicGameCount":12,"difficulty":0.6626506024096386,"difficultyWeight":166},"germ":{"count":217,"lastSeenTime":1577014167357,"difficulty":0.5486725663716814,"difficultyWeight":113,"publicGameCount":10},"ghost":{"count":210,"lastSeenTime":1576992152678,"difficulty":0.4727272727272727,"difficultyWeight":330,"publicGameCount":4},"giant":{"count":235,"lastSeenTime":1577032982788,"publicGameCount":13,"difficulty":0.6944444444444444,"difficultyWeight":108},"gift":{"count":211,"lastSeenTime":1577025802876,"publicGameCount":8,"difficulty":0.4867724867724869,"difficultyWeight":189},"giraffe":{"count":223,"lastSeenTime":1577020114457,"difficulty":0.4594594594594595,"difficultyWeight":185,"publicGameCount":14},"gladiator":{"count":245,"lastSeenTime":1577032198145,"difficulty":0.68,"difficultyWeight":25,"publicGameCount":2},"glasses":{"count":241,"lastSeenTime":1577024306506,"difficulty":0.4945054945054945,"difficultyWeight":182,"publicGameCount":15},"gloss":{"count":245,"lastSeenTime":1577035714898,"publicGameCount":5,"difficulty":0.5970149253731343,"difficultyWeight":67},"glove":{"count":226,"lastSeenTime":1577018682226,"difficulty":0.555045871559633,"difficultyWeight":218,"publicGameCount":19},"glow":{"count":240,"lastSeenTime":1577007757536,"publicGameCount":10,"difficulty":0.5446428571428572,"difficultyWeight":112},"glowstick":{"count":255,"lastSeenTime":1577020336526,"publicGameCount":18,"difficulty":0.6220930232558141,"difficultyWeight":172},"goal":{"count":194,"lastSeenTime":1577015835147,"publicGameCount":8,"difficulty":0.5533333333333335,"difficultyWeight":150},"godfather":{"count":218,"lastSeenTime":1577018061246,"publicGameCount":8,"difficulty":0.7368421052631579,"difficultyWeight":76},"gold":{"count":218,"lastSeenTime":1576983733645,"difficulty":0.5560538116591929,"difficultyWeight":223,"publicGameCount":9},"gold chain":{"count":239,"lastSeenTime":1577032530295,"publicGameCount":16,"difficulty":0.6861313868613139,"difficultyWeight":137},"golden apple":{"count":220,"lastSeenTime":1577018743300,"publicGameCount":26,"difficulty":0.6188118811881187,"difficultyWeight":202},"golden egg":{"count":257,"lastSeenTime":1577034214987,"publicGameCount":45,"difficulty":0.7329376854599405,"difficultyWeight":337},"goldfish":{"count":216,"lastSeenTime":1577029961880,"publicGameCount":18,"difficulty":0.5367965367965368,"difficultyWeight":231},"golf":{"count":258,"lastSeenTime":1577033583113,"difficulty":0.5697674418604652,"difficultyWeight":172,"publicGameCount":9},"goose":{"count":233,"lastSeenTime":1576998176725,"difficulty":0.6982758620689655,"difficultyWeight":116,"publicGameCount":6},"gorilla":{"count":238,"lastSeenTime":1576975519093,"publicGameCount":13,"difficulty":0.725925925925926,"difficultyWeight":135},"graffiti":{"count":235,"lastSeenTime":1577025938533,"publicGameCount":15,"difficulty":0.6293103448275862,"difficultyWeight":116},"grapefruit":{"count":220,"lastSeenTime":1576954599059,"publicGameCount":8,"difficulty":0.7619047619047619,"difficultyWeight":63},"grapes":{"count":227,"lastSeenTime":1577032430625,"publicGameCount":4,"difficulty":0.45348837209302323,"difficultyWeight":172},"graph":{"count":199,"lastSeenTime":1576981282130,"publicGameCount":9,"difficulty":0.5578231292517006,"difficultyWeight":147},"grass":{"count":422,"lastSeenTime":1577029688943,"publicGameCount":26,"difficulty":0.5116959064327484,"difficultyWeight":342},"grave":{"count":228,"lastSeenTime":1577021218762,"publicGameCount":11,"difficulty":0.48633879781420764,"difficultyWeight":183},"gravedigger":{"count":208,"lastSeenTime":1577036892935,"difficulty":0.7608695652173914,"difficultyWeight":92,"publicGameCount":11},"grenade":{"count":243,"lastSeenTime":1577006677996,"publicGameCount":26,"difficulty":0.5836734693877551,"difficultyWeight":245},"grid":{"count":230,"lastSeenTime":1577029593108,"difficulty":0.6410256410256411,"difficultyWeight":117,"publicGameCount":10},"grill":{"count":240,"lastSeenTime":1577018165583,"difficulty":0.6607142857142857,"difficultyWeight":112,"publicGameCount":2},"grin":{"count":214,"lastSeenTime":1576976608765,"difficulty":0.6102941176470589,"difficultyWeight":136,"publicGameCount":13},"guillotine":{"count":243,"lastSeenTime":1577036953671,"difficulty":0.8548387096774194,"difficultyWeight":62,"publicGameCount":8},"gumball":{"count":227,"lastSeenTime":1577030902569,"difficulty":0.6568627450980391,"difficultyWeight":102,"publicGameCount":4},"gummy":{"count":431,"lastSeenTime":1577019972511,"publicGameCount":37,"difficulty":0.579124579124579,"difficultyWeight":297},"gummy worm":{"count":209,"lastSeenTime":1577002437912,"publicGameCount":20,"difficulty":0.678082191780822,"difficultyWeight":146},"hacker":{"count":248,"lastSeenTime":1577007782564,"publicGameCount":12,"difficulty":0.6935483870967742,"difficultyWeight":124},"hairbrush":{"count":236,"lastSeenTime":1577031895972,"publicGameCount":18,"difficulty":0.5533333333333333,"difficultyWeight":150},"haircut":{"count":214,"lastSeenTime":1576980501058,"difficulty":0.5688073394495413,"difficultyWeight":109,"publicGameCount":10},"hairspray":{"count":216,"lastSeenTime":1577035202003,"publicGameCount":11,"difficulty":0.6470588235294118,"difficultyWeight":119},"hairy":{"count":442,"lastSeenTime":1577030082147,"publicGameCount":28,"difficulty":0.5887445887445889,"difficultyWeight":231},"half":{"count":220,"lastSeenTime":1577021368947,"difficulty":0.5163043478260869,"difficultyWeight":184,"publicGameCount":9},"hamburger":{"count":223,"lastSeenTime":1577033017430,"publicGameCount":23,"difficulty":0.4900398406374502,"difficultyWeight":251},"hammer":{"count":230,"lastSeenTime":1577032786045,"difficulty":0.4740740740740741,"difficultyWeight":270,"publicGameCount":19},"hamster":{"count":218,"lastSeenTime":1577015971079,"difficulty":0.6587301587301586,"difficultyWeight":126,"publicGameCount":11},"hand":{"count":459,"lastSeenTime":1577029564602,"difficulty":0.38687782805429866,"difficultyWeight":442,"publicGameCount":34},"handicap":{"count":256,"lastSeenTime":1577037511458,"publicGameCount":7,"difficulty":0.8059701492537313,"difficultyWeight":67},"handshake":{"count":227,"lastSeenTime":1577007971712,"publicGameCount":12,"difficulty":0.6600000000000001,"difficultyWeight":100},"hanger":{"count":215,"lastSeenTime":1577037426426,"difficulty":0.49999999999999994,"difficultyWeight":110,"publicGameCount":1},"harbor":{"count":459,"lastSeenTime":1577037092671,"difficulty":0.8444444444444444,"difficultyWeight":90,"publicGameCount":9},"hard hat":{"count":234,"lastSeenTime":1577018781997,"publicGameCount":13,"difficulty":0.7777777777777778,"difficultyWeight":81},"harp":{"count":440,"lastSeenTime":1577036892935,"publicGameCount":17,"difficulty":0.5906735751295337,"difficultyWeight":193},"harpoon":{"count":212,"lastSeenTime":1576986413615,"difficulty":0.875,"difficultyWeight":88,"publicGameCount":6},"hashtag":{"count":227,"lastSeenTime":1577024212837,"difficulty":0.5597826086956522,"difficultyWeight":184,"publicGameCount":5},"hazard":{"count":227,"lastSeenTime":1577019684566,"publicGameCount":6,"difficulty":0.7115384615384616,"difficultyWeight":52},"hazelnut":{"count":246,"lastSeenTime":1576993732939,"publicGameCount":6,"difficulty":0.509090909090909,"difficultyWeight":55},"headboard":{"count":222,"lastSeenTime":1577031957749,"publicGameCount":9,"difficulty":0.6923076923076923,"difficultyWeight":65},"heading":{"count":207,"lastSeenTime":1577026078796,"difficulty":0.7058823529411765,"difficultyWeight":51,"publicGameCount":2},"heart":{"count":407,"lastSeenTime":1577032222590,"publicGameCount":35,"difficulty":0.3900226757369615,"difficultyWeight":441},"heel":{"count":446,"lastSeenTime":1577015110298,"publicGameCount":30,"difficulty":0.5167286245353159,"difficultyWeight":269},"heist":{"count":229,"lastSeenTime":1577037667912,"publicGameCount":4,"difficulty":0.8194444444444444,"difficultyWeight":72},"helicopter":{"count":211,"lastSeenTime":1577034096819,"difficulty":0.4226190476190476,"difficultyWeight":168,"publicGameCount":20},"hell":{"count":211,"lastSeenTime":1576972623220,"difficulty":0.5592105263157895,"difficultyWeight":152,"publicGameCount":8},"hen":{"count":228,"lastSeenTime":1577008396195,"difficulty":0.6666666666666666,"difficultyWeight":78,"publicGameCount":3},"hero":{"count":208,"lastSeenTime":1577025578748,"difficulty":0.5741626794258372,"difficultyWeight":209,"publicGameCount":12},"hibernate":{"count":214,"lastSeenTime":1577034096819,"publicGameCount":6,"difficulty":0.5813953488372093,"difficultyWeight":43},"hieroglyph":{"count":201,"lastSeenTime":1577037226802,"publicGameCount":7,"difficulty":0.7971014492753623,"difficultyWeight":69},"high five":{"count":254,"lastSeenTime":1577019799055,"difficulty":0.5734265734265734,"difficultyWeight":143,"publicGameCount":18},"high heels":{"count":211,"lastSeenTime":1577017330066,"publicGameCount":26,"difficulty":0.5027322404371585,"difficultyWeight":183},"highway":{"count":454,"lastSeenTime":1577037236956,"publicGameCount":23,"difficulty":0.5904761904761906,"difficultyWeight":210},"hippie":{"count":219,"lastSeenTime":1576945048708,"difficulty":0.6818181818181818,"difficultyWeight":66,"publicGameCount":6},"hippo":{"count":252,"lastSeenTime":1577037151662,"difficulty":0.7373737373737373,"difficultyWeight":99,"publicGameCount":8},"hitchhiker":{"count":244,"lastSeenTime":1577030311398,"publicGameCount":2,"difficulty":0.8,"difficultyWeight":20},"hockey":{"count":225,"lastSeenTime":1577025742812,"difficulty":0.6901408450704225,"difficultyWeight":142,"publicGameCount":7},"holiday":{"count":223,"lastSeenTime":1576972207002,"publicGameCount":11,"difficulty":0.7388059701492538,"difficultyWeight":134},"honey":{"count":214,"lastSeenTime":1577035177226,"publicGameCount":14,"difficulty":0.4880382775119617,"difficultyWeight":209},"hoof":{"count":228,"lastSeenTime":1577017431391,"publicGameCount":5,"difficulty":0.5609756097560975,"difficultyWeight":82},"hook":{"count":276,"lastSeenTime":1577020291134,"difficulty":0.4742268041237113,"difficultyWeight":194,"publicGameCount":16},"horizon":{"count":430,"lastSeenTime":1577029639639,"publicGameCount":17,"difficulty":0.723404255319149,"difficultyWeight":141},"horse":{"count":231,"lastSeenTime":1577036907083,"publicGameCount":6,"difficulty":0.4808743169398907,"difficultyWeight":183},"horsewhip":{"count":217,"lastSeenTime":1577031792602,"publicGameCount":6,"difficulty":0.8285714285714286,"difficultyWeight":70},"hose":{"count":218,"lastSeenTime":1577015378171,"publicGameCount":7,"difficulty":0.6513761467889908,"difficultyWeight":109},"hospital":{"count":443,"lastSeenTime":1577032873667,"difficulty":0.5020325203252033,"difficultyWeight":492,"publicGameCount":54},"hot chocolate":{"count":258,"lastSeenTime":1576994676492,"publicGameCount":39,"difficulty":0.702054794520548,"difficultyWeight":292},"hot dog":{"count":225,"lastSeenTime":1577018647384,"publicGameCount":37,"difficulty":0.525735294117647,"difficultyWeight":272},"hot sauce":{"count":209,"lastSeenTime":1577033960762,"publicGameCount":21,"difficulty":0.7531645569620253,"difficultyWeight":158},"hourglass":{"count":230,"lastSeenTime":1577014885145,"difficulty":0.6000000000000001,"difficultyWeight":275,"publicGameCount":21},"hug":{"count":252,"lastSeenTime":1577019371561,"difficulty":0.6630434782608695,"difficultyWeight":92,"publicGameCount":3},"hummingbird":{"count":217,"lastSeenTime":1577031754107,"publicGameCount":10,"difficulty":0.7108433734939759,"difficultyWeight":83},"hurdle":{"count":222,"lastSeenTime":1577030396800,"publicGameCount":7,"difficulty":0.6666666666666666,"difficultyWeight":99},"hurt":{"count":213,"lastSeenTime":1577011040351,"difficulty":0.5979381443298969,"difficultyWeight":97,"publicGameCount":5},"husband":{"count":226,"lastSeenTime":1577016590802,"difficulty":0.6309523809523809,"difficultyWeight":168,"publicGameCount":17},"hut":{"count":468,"lastSeenTime":1577018932714,"difficulty":0.5971223021582733,"difficultyWeight":278,"publicGameCount":23},"hypnotize":{"count":247,"lastSeenTime":1577037688224,"difficulty":0.7211538461538461,"difficultyWeight":104,"publicGameCount":13},"ice cream truck":{"count":229,"lastSeenTime":1577018964063,"publicGameCount":35,"difficulty":0.6770428015564203,"difficultyWeight":257},"idea":{"count":211,"lastSeenTime":1577021177893,"difficulty":0.5275590551181102,"difficultyWeight":127,"publicGameCount":7},"imagination":{"count":248,"lastSeenTime":1577037103049,"publicGameCount":18,"difficulty":0.746268656716418,"difficultyWeight":134},"industry":{"count":244,"lastSeenTime":1576973913856,"publicGameCount":5,"difficulty":0.75,"difficultyWeight":36},"inside":{"count":231,"lastSeenTime":1577012446133,"publicGameCount":11,"difficulty":0.6304347826086957,"difficultyWeight":92},"ivy":{"count":425,"lastSeenTime":1577030851645,"publicGameCount":14,"difficulty":0.576,"difficultyWeight":125},"jacket":{"count":243,"lastSeenTime":1577021204269,"difficulty":0.6271186440677966,"difficultyWeight":118,"publicGameCount":9},"jackhammer":{"count":214,"lastSeenTime":1577031781371,"publicGameCount":12,"difficulty":0.75,"difficultyWeight":108},"jaguar":{"count":234,"lastSeenTime":1577009531378,"difficulty":0.5757575757575758,"difficultyWeight":66,"publicGameCount":7},"jalapeno":{"count":220,"lastSeenTime":1577031583222,"difficulty":0.6642335766423357,"difficultyWeight":137,"publicGameCount":10},"janitor":{"count":237,"lastSeenTime":1577030406930,"difficulty":0.7211538461538461,"difficultyWeight":104,"publicGameCount":10},"jaw":{"count":416,"lastSeenTime":1577018262363,"difficulty":0.6192307692307693,"difficultyWeight":260,"publicGameCount":20},"jeep":{"count":225,"lastSeenTime":1577031536041,"difficulty":0.5277777777777778,"difficultyWeight":72,"publicGameCount":7},"jello":{"count":218,"lastSeenTime":1577003035473,"publicGameCount":12,"difficulty":0.584070796460177,"difficultyWeight":113},"jelly":{"count":248,"lastSeenTime":1577033407643,"difficulty":0.5943396226415094,"difficultyWeight":212,"publicGameCount":12},"jellyfish":{"count":223,"lastSeenTime":1577014939690,"difficulty":0.46031746031746035,"difficultyWeight":252,"publicGameCount":17},"jet ski":{"count":210,"lastSeenTime":1577034329984,"publicGameCount":11,"difficulty":0.7272727272727273,"difficultyWeight":88},"joker":{"count":214,"lastSeenTime":1577020810865,"publicGameCount":12,"difficulty":0.47126436781609193,"difficultyWeight":174},"journalist":{"count":244,"lastSeenTime":1577033163970,"publicGameCount":8,"difficulty":0.82,"difficultyWeight":50},"judge":{"count":215,"lastSeenTime":1577019635326,"difficulty":0.6203703703703702,"difficultyWeight":108,"publicGameCount":10},"juice":{"count":236,"lastSeenTime":1577037511458,"publicGameCount":11,"difficulty":0.5093167701863354,"difficultyWeight":161},"jump rope":{"count":209,"lastSeenTime":1577034656692,"publicGameCount":13,"difficulty":0.6811594202898551,"difficultyWeight":138},"junk food":{"count":226,"lastSeenTime":1577024698445,"publicGameCount":15,"difficulty":0.7529411764705882,"difficultyWeight":85},"kangaroo":{"count":220,"lastSeenTime":1577010822941,"difficulty":0.6216216216216216,"difficultyWeight":111,"publicGameCount":9},"karaoke":{"count":225,"lastSeenTime":1577033765748,"publicGameCount":13,"difficulty":0.7047619047619048,"difficultyWeight":105},"karate":{"count":235,"lastSeenTime":1577025144281,"difficulty":0.6120689655172413,"difficultyWeight":116,"publicGameCount":7},"katana":{"count":223,"lastSeenTime":1577002585121,"publicGameCount":11,"difficulty":0.6420454545454546,"difficultyWeight":176},"kebab":{"count":235,"lastSeenTime":1576955799822,"difficulty":0.6666666666666666,"difficultyWeight":84,"publicGameCount":7},"ketchup":{"count":238,"lastSeenTime":1577013730906,"publicGameCount":20,"difficulty":0.5445544554455445,"difficultyWeight":202},"key":{"count":225,"lastSeenTime":1577031259619,"publicGameCount":4,"difficulty":0.45555555555555555,"difficultyWeight":270},"kidney":{"count":410,"lastSeenTime":1577030984080,"difficulty":0.6153846153846154,"difficultyWeight":182,"publicGameCount":19},"kite":{"count":221,"lastSeenTime":1576985103686,"publicGameCount":13,"difficulty":0.41,"difficultyWeight":200},"kitten":{"count":240,"lastSeenTime":1577030096351,"publicGameCount":14,"difficulty":0.6089385474860335,"difficultyWeight":179},"kiwi":{"count":417,"lastSeenTime":1577033794297,"difficulty":0.522633744855967,"difficultyWeight":243,"publicGameCount":28},"kneel":{"count":200,"lastSeenTime":1577008308852,"publicGameCount":8,"difficulty":0.6907216494845361,"difficultyWeight":97},"knight":{"count":223,"lastSeenTime":1577035150930,"difficulty":0.6091954022988506,"difficultyWeight":87,"publicGameCount":10},"kraken":{"count":243,"lastSeenTime":1577037535729,"difficulty":0.7241379310344828,"difficultyWeight":87,"publicGameCount":6},"ladder":{"count":232,"lastSeenTime":1576996463561,"difficulty":0.5,"difficultyWeight":210,"publicGameCount":9},"lady":{"count":243,"lastSeenTime":1577020597928,"publicGameCount":14,"difficulty":0.6907894736842104,"difficultyWeight":152},"lamb":{"count":209,"lastSeenTime":1577035494111,"difficulty":0.5637583892617449,"difficultyWeight":149,"publicGameCount":11},"language":{"count":234,"lastSeenTime":1577013723748,"publicGameCount":12,"difficulty":0.71,"difficultyWeight":100},"lantern":{"count":239,"lastSeenTime":1577030325616,"publicGameCount":13,"difficulty":0.5806451612903226,"difficultyWeight":155},"lava lamp":{"count":212,"lastSeenTime":1577033078485,"publicGameCount":15,"difficulty":0.6030534351145039,"difficultyWeight":131},"lawn mower":{"count":218,"lastSeenTime":1577019187643,"publicGameCount":21,"difficulty":0.5592105263157895,"difficultyWeight":152},"lawyer":{"count":231,"lastSeenTime":1577035568579,"publicGameCount":3,"difficulty":0.9411764705882353,"difficultyWeight":68},"leaf":{"count":435,"lastSeenTime":1577005212976,"publicGameCount":37,"difficulty":0.41555555555555557,"difficultyWeight":450},"leak":{"count":229,"lastSeenTime":1577033633532,"publicGameCount":5,"difficulty":0.6385542168674698,"difficultyWeight":83},"leash":{"count":227,"lastSeenTime":1577009842635,"difficulty":0.6363636363636362,"difficultyWeight":154,"publicGameCount":10},"lemon":{"count":240,"lastSeenTime":1576971136739,"publicGameCount":11,"difficulty":0.5217391304347826,"difficultyWeight":253},"lemonade":{"count":196,"lastSeenTime":1577006756167,"difficulty":0.6738197424892703,"difficultyWeight":233,"publicGameCount":14},"lettuce":{"count":229,"lastSeenTime":1577018472586,"publicGameCount":6,"difficulty":0.5901639344262295,"difficultyWeight":122},"lid":{"count":221,"lastSeenTime":1577035372815,"publicGameCount":11,"difficulty":0.6153846153846154,"difficultyWeight":143},"lighter":{"count":230,"lastSeenTime":1577019809349,"difficulty":0.5422885572139304,"difficultyWeight":201,"publicGameCount":14},"limbo":{"count":236,"lastSeenTime":1577001745670,"publicGameCount":8,"difficulty":0.7435897435897436,"difficultyWeight":117},"lime":{"count":242,"lastSeenTime":1577024525038,"publicGameCount":13,"difficulty":0.532258064516129,"difficultyWeight":186},"limousine":{"count":230,"lastSeenTime":1577036283076,"publicGameCount":3,"difficulty":0.6000000000000001,"difficultyWeight":45},"line":{"count":225,"lastSeenTime":1576943162317,"difficulty":0.5136363636363636,"difficultyWeight":220,"publicGameCount":4},"lizard":{"count":200,"lastSeenTime":1576931077329,"publicGameCount":11,"difficulty":0.5546218487394957,"difficultyWeight":119},"llama":{"count":252,"lastSeenTime":1577034290492,"difficulty":0.5813953488372093,"difficultyWeight":129,"publicGameCount":9},"loading":{"count":255,"lastSeenTime":1577025502724,"publicGameCount":20,"difficulty":0.6053811659192825,"difficultyWeight":223},"log":{"count":399,"lastSeenTime":1577000170176,"difficulty":0.5561797752808989,"difficultyWeight":356,"publicGameCount":14},"lollipop":{"count":215,"lastSeenTime":1577004699540,"publicGameCount":13,"difficulty":0.5421686746987951,"difficultyWeight":166},"loser":{"count":208,"lastSeenTime":1577036293187,"publicGameCount":10,"difficulty":0.6558441558441559,"difficultyWeight":154},"low":{"count":458,"lastSeenTime":1577014053725,"publicGameCount":28,"difficulty":0.600877192982456,"difficultyWeight":228},"luck":{"count":229,"lastSeenTime":1577033647739,"difficulty":0.6419753086419753,"difficultyWeight":81,"publicGameCount":5},"lumberjack":{"count":226,"lastSeenTime":1577035483877,"publicGameCount":15,"difficulty":0.75,"difficultyWeight":104},"lung":{"count":419,"lastSeenTime":1577037392013,"publicGameCount":27,"difficulty":0.5239726027397259,"difficultyWeight":292},"machine":{"count":221,"lastSeenTime":1577018038260,"publicGameCount":5,"difficulty":0.5857142857142857,"difficultyWeight":70},"magazine":{"count":223,"lastSeenTime":1577000170176,"publicGameCount":11,"difficulty":0.64,"difficultyWeight":100},"magic":{"count":215,"lastSeenTime":1577031023734,"difficulty":0.6358024691358025,"difficultyWeight":162,"publicGameCount":12},"magic wand":{"count":204,"lastSeenTime":1577034229193,"difficulty":0.5999999999999999,"difficultyWeight":175,"publicGameCount":22},"magician":{"count":231,"lastSeenTime":1577024317066,"difficulty":0.6111111111111112,"difficultyWeight":126,"publicGameCount":8},"magma":{"count":198,"lastSeenTime":1577025240259,"difficulty":0.5677966101694916,"difficultyWeight":118,"publicGameCount":8},"magnet":{"count":233,"lastSeenTime":1577024499507,"publicGameCount":7,"difficulty":0.546875,"difficultyWeight":192},"mailbox":{"count":430,"lastSeenTime":1577035823959,"publicGameCount":39,"difficulty":0.4632768361581921,"difficultyWeight":354},"mailman":{"count":243,"lastSeenTime":1577001935445,"publicGameCount":15,"difficulty":0.5570469798657719,"difficultyWeight":149},"makeup":{"count":235,"lastSeenTime":1577035568579,"publicGameCount":18,"difficulty":0.5321637426900584,"difficultyWeight":171},"manicure":{"count":214,"lastSeenTime":1577013836576,"publicGameCount":10,"difficulty":0.7777777777777778,"difficultyWeight":72},"mansion":{"count":465,"lastSeenTime":1577021218762,"publicGameCount":23,"difficulty":0.6347305389221558,"difficultyWeight":167},"maracas":{"count":405,"lastSeenTime":1577037016878,"publicGameCount":30,"difficulty":0.6879699248120301,"difficultyWeight":266},"marathon":{"count":215,"lastSeenTime":1577032051558,"publicGameCount":7,"difficulty":0.6000000000000001,"difficultyWeight":50},"marmot":{"count":216,"lastSeenTime":1577024485059,"publicGameCount":2,"difficulty":0.9285714285714286,"difficultyWeight":14},"marshmallow":{"count":235,"lastSeenTime":1577025599091,"difficulty":0.771551724137931,"difficultyWeight":232,"publicGameCount":32},"mascot":{"count":218,"lastSeenTime":1577035865974,"publicGameCount":7,"difficulty":0.6956521739130435,"difficultyWeight":69},"matchbox":{"count":222,"lastSeenTime":1577031458931,"publicGameCount":21,"difficulty":0.6551724137931033,"difficultyWeight":174},"mattress":{"count":215,"lastSeenTime":1577031033935,"publicGameCount":11,"difficulty":0.6548672566371682,"difficultyWeight":113},"meat":{"count":257,"lastSeenTime":1577018005177,"difficulty":0.5454545454545454,"difficultyWeight":132,"publicGameCount":12},"meatball":{"count":223,"lastSeenTime":1577035629904,"publicGameCount":12,"difficulty":0.6293706293706294,"difficultyWeight":143},"megaphone":{"count":226,"lastSeenTime":1577016849135,"publicGameCount":17,"difficulty":0.6568047337278108,"difficultyWeight":169},"melon":{"count":260,"lastSeenTime":1577003426912,"publicGameCount":19,"difficulty":0.5589743589743591,"difficultyWeight":195},"meme":{"count":233,"lastSeenTime":1576998359206,"difficulty":0.4819277108433735,"difficultyWeight":83,"publicGameCount":7},"message":{"count":250,"lastSeenTime":1577035324132,"difficulty":0.5692307692307693,"difficultyWeight":195,"publicGameCount":18},"metal":{"count":209,"lastSeenTime":1577002509579,"publicGameCount":7,"difficulty":0.6428571428571429,"difficultyWeight":98},"microphone":{"count":223,"lastSeenTime":1577014895707,"publicGameCount":24,"difficulty":0.5235294117647059,"difficultyWeight":170},"microwave":{"count":260,"lastSeenTime":1577032161683,"publicGameCount":19,"difficulty":0.6374269005847953,"difficultyWeight":171},"midnight":{"count":236,"lastSeenTime":1576997601884,"difficulty":0.5548780487804879,"difficultyWeight":164,"publicGameCount":21},"military":{"count":243,"lastSeenTime":1577036791454,"publicGameCount":12,"difficulty":0.7128712871287128,"difficultyWeight":101},"milk":{"count":225,"lastSeenTime":1577017157118,"publicGameCount":10,"difficulty":0.5321100917431192,"difficultyWeight":218},"milkman":{"count":215,"lastSeenTime":1577036598485,"publicGameCount":14,"difficulty":0.6423357664233575,"difficultyWeight":137},"milkshake":{"count":230,"lastSeenTime":1577018647384,"publicGameCount":17,"difficulty":0.6111111111111113,"difficultyWeight":162},"mime":{"count":221,"lastSeenTime":1577011482424,"publicGameCount":6,"difficulty":0.7,"difficultyWeight":50},"minigolf":{"count":212,"lastSeenTime":1577004556511,"difficulty":0.6153846153846154,"difficultyWeight":91,"publicGameCount":8},"mint":{"count":238,"lastSeenTime":1576996149073,"publicGameCount":9,"difficulty":0.5675675675675675,"difficultyWeight":111},"minute":{"count":229,"lastSeenTime":1576973429723,"publicGameCount":9,"difficulty":0.5611510791366906,"difficultyWeight":139},"mirror":{"count":225,"lastSeenTime":1577025204663,"publicGameCount":12,"difficulty":0.6408163265306122,"difficultyWeight":245},"missile":{"count":250,"lastSeenTime":1577034679025,"publicGameCount":19,"difficulty":0.6875,"difficultyWeight":160},"mohawk":{"count":203,"lastSeenTime":1577036293187,"publicGameCount":15,"difficulty":0.5730994152046783,"difficultyWeight":171},"money":{"count":216,"lastSeenTime":1577035238778,"difficulty":0.4703196347031963,"difficultyWeight":219,"publicGameCount":3},"monk":{"count":223,"lastSeenTime":1576996401384,"publicGameCount":2,"difficulty":0.5909090909090909,"difficultyWeight":44},"monkey":{"count":217,"lastSeenTime":1577036473654,"publicGameCount":10,"difficulty":0.6134969325153373,"difficultyWeight":163},"monster":{"count":211,"lastSeenTime":1577010723399,"publicGameCount":13,"difficulty":0.6529411764705884,"difficultyWeight":170},"moon":{"count":223,"lastSeenTime":1576985294535,"difficulty":0.5165876777251186,"difficultyWeight":211,"publicGameCount":6},"mop":{"count":240,"lastSeenTime":1577031419224,"difficulty":0.6374269005847953,"difficultyWeight":171,"publicGameCount":12},"morning":{"count":209,"lastSeenTime":1576982634040,"publicGameCount":7,"difficulty":0.5833333333333331,"difficultyWeight":120},"mosquito":{"count":231,"lastSeenTime":1577035593475,"publicGameCount":13,"difficulty":0.6382978723404257,"difficultyWeight":141},"moth":{"count":228,"lastSeenTime":1576983921524,"difficulty":0.5697674418604651,"difficultyWeight":86,"publicGameCount":9},"mother":{"count":245,"lastSeenTime":1576988808941,"publicGameCount":16,"difficulty":0.5970149253731343,"difficultyWeight":134},"motorbike":{"count":237,"lastSeenTime":1577032752804,"difficulty":0.7,"difficultyWeight":80,"publicGameCount":10},"mountain":{"count":425,"lastSeenTime":1577025711695,"publicGameCount":47,"difficulty":0.4394736842105263,"difficultyWeight":380},"mousetrap":{"count":230,"lastSeenTime":1577036953671,"publicGameCount":12,"difficulty":0.5839416058394161,"difficultyWeight":137},"movie":{"count":226,"lastSeenTime":1577032716307,"publicGameCount":8,"difficulty":0.6766917293233082,"difficultyWeight":133},"muffin":{"count":210,"lastSeenTime":1576973587711,"difficulty":0.5445026178010471,"difficultyWeight":191,"publicGameCount":13},"mug":{"count":225,"lastSeenTime":1577007268089,"difficulty":0.5990566037735849,"difficultyWeight":212},"murderer":{"count":200,"lastSeenTime":1577019371561,"publicGameCount":12,"difficulty":0.6341463414634146,"difficultyWeight":164},"musket":{"count":223,"lastSeenTime":1577036598485,"difficulty":0.696969696969697,"difficultyWeight":99,"publicGameCount":4},"mustache":{"count":423,"lastSeenTime":1577036329616,"difficulty":0.6166666666666666,"difficultyWeight":420,"publicGameCount":51},"mustard":{"count":236,"lastSeenTime":1577025893054,"difficulty":0.5428571428571427,"difficultyWeight":105,"publicGameCount":10},"nail file":{"count":229,"lastSeenTime":1577013825828,"publicGameCount":3,"difficulty":0.7419354838709677,"difficultyWeight":31},"napkin":{"count":241,"lastSeenTime":1576994965500,"difficulty":0.73,"difficultyWeight":100,"publicGameCount":9},"narwhal":{"count":250,"lastSeenTime":1577032763018,"publicGameCount":7,"difficulty":0.7551020408163265,"difficultyWeight":98},"nerd":{"count":222,"lastSeenTime":1577016110707,"difficulty":0.6212121212121212,"difficultyWeight":132,"publicGameCount":5},"network":{"count":264,"lastSeenTime":1577014443779,"difficulty":0.5217391304347826,"difficultyWeight":115,"publicGameCount":11},"nickel":{"count":229,"lastSeenTime":1577011993887,"difficulty":0.7058823529411765,"difficultyWeight":102,"publicGameCount":5},"night":{"count":224,"lastSeenTime":1577009233758,"difficulty":0.5040322580645162,"difficultyWeight":248,"publicGameCount":19},"nightmare":{"count":230,"lastSeenTime":1577037521580,"publicGameCount":7,"difficulty":0.7283950617283951,"difficultyWeight":81},"ninja":{"count":201,"lastSeenTime":1577030541096,"difficulty":0.48872180451127817,"difficultyWeight":133,"publicGameCount":6},"noob":{"count":233,"lastSeenTime":1577029593108,"difficulty":0.6280487804878049,"difficultyWeight":164,"publicGameCount":14},"north":{"count":420,"lastSeenTime":1577034531942,"publicGameCount":47,"difficulty":0.44693877551020406,"difficultyWeight":490},"nose":{"count":442,"lastSeenTime":1577017937665,"publicGameCount":41,"difficulty":0.4392764857881137,"difficultyWeight":387},"nose hair":{"count":454,"lastSeenTime":1577026115551,"publicGameCount":44,"difficulty":0.6413994169096209,"difficultyWeight":343},"nosebleed":{"count":203,"lastSeenTime":1577024196032,"publicGameCount":12,"difficulty":0.6290322580645161,"difficultyWeight":186},"nostrils":{"count":411,"lastSeenTime":1577037316766,"difficulty":0.6711590296495957,"difficultyWeight":371,"publicGameCount":41},"notepad":{"count":228,"lastSeenTime":1577004326772,"difficulty":0.6744186046511628,"difficultyWeight":129,"publicGameCount":12},"nothing":{"count":233,"lastSeenTime":1577037117265,"difficulty":0.726027397260274,"difficultyWeight":146,"publicGameCount":9},"novel":{"count":221,"lastSeenTime":1577034229193,"publicGameCount":15,"difficulty":0.6879432624113475,"difficultyWeight":141},"nugget":{"count":217,"lastSeenTime":1577025104122,"publicGameCount":12,"difficulty":0.4855072463768116,"difficultyWeight":138},"nuke":{"count":246,"lastSeenTime":1577031765159,"publicGameCount":19,"difficulty":0.5723270440251572,"difficultyWeight":159},"nutcracker":{"count":433,"lastSeenTime":1577029996661,"publicGameCount":23,"difficulty":0.6705882352941176,"difficultyWeight":170},"nutshell":{"count":218,"lastSeenTime":1577032834915,"publicGameCount":4,"difficulty":0.7,"difficultyWeight":30},"ocean":{"count":404,"lastSeenTime":1577037031237,"publicGameCount":42,"difficulty":0.43258426966292135,"difficultyWeight":356},"office":{"count":429,"lastSeenTime":1577035789503,"difficulty":0.605095541401274,"difficultyWeight":157,"publicGameCount":18},"old":{"count":450,"lastSeenTime":1577036740392,"publicGameCount":25,"difficulty":0.5641891891891891,"difficultyWeight":296},"omelet":{"count":196,"lastSeenTime":1577005234169,"publicGameCount":8,"difficulty":0.6835443037974683,"difficultyWeight":79},"onion":{"count":212,"lastSeenTime":1577032076358,"publicGameCount":8,"difficulty":0.5378151260504201,"difficultyWeight":119},"orange":{"count":232,"lastSeenTime":1577032383846,"difficulty":0.5051546391752578,"difficultyWeight":194,"publicGameCount":8},"orangutan":{"count":240,"lastSeenTime":1577024591466,"publicGameCount":4,"difficulty":0.6578947368421053,"difficultyWeight":38},"ostrich":{"count":229,"lastSeenTime":1577036549571,"difficulty":0.5894736842105263,"difficultyWeight":95,"publicGameCount":9},"outside":{"count":246,"lastSeenTime":1576998606975,"publicGameCount":8,"difficulty":0.5967741935483871,"difficultyWeight":62},"overweight":{"count":431,"lastSeenTime":1577034350570,"publicGameCount":37,"difficulty":0.7872340425531915,"difficultyWeight":282},"owl":{"count":237,"lastSeenTime":1577032505816,"difficulty":0.5555555555555557,"difficultyWeight":171,"publicGameCount":12},"oyster":{"count":216,"lastSeenTime":1577029554508,"difficulty":0.6481481481481481,"difficultyWeight":54,"publicGameCount":6},"paddle":{"count":228,"lastSeenTime":1577007708551,"publicGameCount":6,"difficulty":0.6136363636363636,"difficultyWeight":88},"page":{"count":230,"lastSeenTime":1577036487959,"difficulty":0.624,"difficultyWeight":125,"publicGameCount":3},"pain":{"count":224,"lastSeenTime":1577035823959,"difficulty":0.47058823529411764,"difficultyWeight":102,"publicGameCount":7},"paint":{"count":222,"lastSeenTime":1577033178896,"difficulty":0.6358024691358025,"difficultyWeight":162,"publicGameCount":13},"pancake":{"count":208,"lastSeenTime":1577010282547,"publicGameCount":26,"difficulty":0.5782312925170067,"difficultyWeight":294},"paper":{"count":226,"lastSeenTime":1577018556567,"difficulty":0.5637583892617449,"difficultyWeight":149,"publicGameCount":4},"paper bag":{"count":261,"lastSeenTime":1576987482426,"publicGameCount":21,"difficulty":0.6289308176100629,"difficultyWeight":159},"parachute":{"count":232,"lastSeenTime":1577033983037,"publicGameCount":21,"difficulty":0.5388888888888891,"difficultyWeight":180},"parakeet":{"count":201,"lastSeenTime":1577013440470,"publicGameCount":1,"difficulty":0.6,"difficultyWeight":20},"parents":{"count":246,"lastSeenTime":1577034239310,"publicGameCount":15,"difficulty":0.5688073394495412,"difficultyWeight":109},"park":{"count":437,"lastSeenTime":1577032037095,"publicGameCount":26,"difficulty":0.539855072463768,"difficultyWeight":276},"parking":{"count":419,"lastSeenTime":1577015899997,"publicGameCount":38,"difficulty":0.6285714285714286,"difficultyWeight":315},"parrot":{"count":235,"lastSeenTime":1577036487959,"publicGameCount":6,"difficulty":0.6796116504854369,"difficultyWeight":103},"party":{"count":225,"lastSeenTime":1576989499887,"publicGameCount":5,"difficulty":0.6020408163265306,"difficultyWeight":98},"password":{"count":234,"lastSeenTime":1577031444488,"difficulty":0.5164835164835164,"difficultyWeight":182,"publicGameCount":18},"pasta":{"count":212,"lastSeenTime":1577020454463,"difficulty":0.6352941176470588,"difficultyWeight":170,"publicGameCount":11},"paw":{"count":222,"lastSeenTime":1577033216553,"publicGameCount":5,"difficulty":0.5269709543568465,"difficultyWeight":241},"peace":{"count":228,"lastSeenTime":1576991908852,"difficulty":0.5064102564102566,"difficultyWeight":156,"publicGameCount":3},"peach":{"count":196,"lastSeenTime":1577002538320,"difficulty":0.5802469135802469,"difficultyWeight":81,"publicGameCount":3},"peacock":{"count":203,"lastSeenTime":1577031845373,"difficulty":0.6767676767676769,"difficultyWeight":99,"publicGameCount":6},"pedal":{"count":220,"lastSeenTime":1577037688224,"publicGameCount":4,"difficulty":0.6274509803921569,"difficultyWeight":51},"pencil case":{"count":226,"lastSeenTime":1577031845373,"publicGameCount":18,"difficulty":0.6692913385826772,"difficultyWeight":127},"pencil sharpener":{"count":196,"lastSeenTime":1577025517516,"publicGameCount":26,"difficulty":0.7485714285714286,"difficultyWeight":175},"pendulum":{"count":229,"lastSeenTime":1577032591482,"publicGameCount":6,"difficulty":0.7777777777777778,"difficultyWeight":63},"penny":{"count":229,"lastSeenTime":1577035348501,"difficulty":0.5785714285714286,"difficultyWeight":140,"publicGameCount":4},"pepper":{"count":247,"lastSeenTime":1577034742470,"publicGameCount":16,"difficulty":0.46099290780141844,"difficultyWeight":141},"perfume":{"count":237,"lastSeenTime":1577018979029,"publicGameCount":13,"difficulty":0.6153846153846153,"difficultyWeight":117},"person":{"count":226,"lastSeenTime":1577020612196,"publicGameCount":12,"difficulty":0.6789473684210526,"difficultyWeight":190},"pet food":{"count":252,"lastSeenTime":1577032208262,"publicGameCount":14,"difficulty":0.7870370370370371,"difficultyWeight":108},"petal":{"count":444,"lastSeenTime":1577031128007,"publicGameCount":26,"difficulty":0.5454545454545453,"difficultyWeight":231},"photo frame":{"count":217,"lastSeenTime":1577000556936,"difficulty":0.6808510638297871,"difficultyWeight":188,"publicGameCount":25},"photograph":{"count":211,"lastSeenTime":1576988139074,"publicGameCount":22,"difficulty":0.633136094674556,"difficultyWeight":169},"photographer":{"count":255,"lastSeenTime":1577034121420,"publicGameCount":22,"difficulty":0.7019867549668874,"difficultyWeight":151},"pickle":{"count":219,"lastSeenTime":1577025055649,"difficulty":0.5555555555555556,"difficultyWeight":153,"publicGameCount":6},"pie":{"count":219,"lastSeenTime":1577031845373,"publicGameCount":8,"difficulty":0.5048076923076923,"difficultyWeight":208},"pill":{"count":225,"lastSeenTime":1576995408982,"difficulty":0.5445026178010471,"difficultyWeight":191,"publicGameCount":6},"pillow":{"count":225,"lastSeenTime":1577035914736,"difficulty":0.5976331360946746,"difficultyWeight":169,"publicGameCount":6},"pillow fight":{"count":235,"lastSeenTime":1577034350569,"difficulty":0.5833333333333334,"difficultyWeight":108,"publicGameCount":13},"pilot":{"count":216,"lastSeenTime":1577031818464,"difficulty":0.6857142857142857,"difficultyWeight":70,"publicGameCount":5},"pinball":{"count":215,"lastSeenTime":1577016407755,"difficulty":0.6767676767676768,"difficultyWeight":99,"publicGameCount":7},"pine":{"count":420,"lastSeenTime":1577020810866,"difficulty":0.5527950310559007,"difficultyWeight":161,"publicGameCount":12},"pine cone":{"count":459,"lastSeenTime":1577025277614,"difficulty":0.6767241379310345,"difficultyWeight":232,"publicGameCount":29},"pinky":{"count":432,"lastSeenTime":1577029862138,"publicGameCount":41,"difficulty":0.4666666666666667,"difficultyWeight":300},"pinwheel":{"count":238,"lastSeenTime":1576998816553,"publicGameCount":3,"difficulty":0.5897435897435898,"difficultyWeight":39},"pirate":{"count":252,"lastSeenTime":1577011796049,"publicGameCount":13,"difficulty":0.5796178343949044,"difficultyWeight":157},"pirate ship":{"count":233,"lastSeenTime":1577015776309,"publicGameCount":22,"difficulty":0.5612903225806452,"difficultyWeight":155},"pitchfork":{"count":236,"lastSeenTime":1577036574064,"publicGameCount":18,"difficulty":0.5527950310559007,"difficultyWeight":161},"pizza":{"count":258,"lastSeenTime":1576996939934,"publicGameCount":17,"difficulty":0.4537037037037037,"difficultyWeight":216},"plague":{"count":241,"lastSeenTime":1577020011949,"publicGameCount":5,"difficulty":0.828125,"difficultyWeight":64},"planet":{"count":229,"lastSeenTime":1577030287128,"difficulty":0.5869565217391302,"difficultyWeight":230,"publicGameCount":23},"plank":{"count":211,"lastSeenTime":1577032777377,"publicGameCount":13,"difficulty":0.6486486486486488,"difficultyWeight":148},"platypus":{"count":223,"lastSeenTime":1577034135613,"publicGameCount":13,"difficulty":0.6470588235294118,"difficultyWeight":102},"playground":{"count":457,"lastSeenTime":1577035876160,"publicGameCount":46,"difficulty":0.6510903426791277,"difficultyWeight":321},"pocket":{"count":205,"lastSeenTime":1577015538245,"difficulty":0.6344086021505377,"difficultyWeight":186,"publicGameCount":6},"poisonous":{"count":445,"lastSeenTime":1577036715889,"publicGameCount":34,"difficulty":0.7871485943775101,"difficultyWeight":249},"pollution":{"count":224,"lastSeenTime":1577005017478,"difficulty":0.7755102040816326,"difficultyWeight":98,"publicGameCount":7},"polo":{"count":231,"lastSeenTime":1576993408685,"publicGameCount":9,"difficulty":0.575,"difficultyWeight":80},"pond":{"count":394,"lastSeenTime":1577025613326,"difficulty":0.62890625,"difficultyWeight":256,"publicGameCount":15},"pony":{"count":230,"lastSeenTime":1577017142818,"difficulty":0.5858585858585859,"difficultyWeight":99,"publicGameCount":4},"poodle":{"count":200,"lastSeenTime":1577012460971,"publicGameCount":7,"difficulty":0.6722689075630253,"difficultyWeight":119},"poop":{"count":227,"lastSeenTime":1577032483552,"difficulty":0.4417808219178082,"difficultyWeight":292,"publicGameCount":6},"porch":{"count":222,"lastSeenTime":1577035277440,"publicGameCount":5,"difficulty":0.8,"difficultyWeight":70},"porcupine":{"count":225,"lastSeenTime":1577020363890,"publicGameCount":12,"difficulty":0.7480314960629921,"difficultyWeight":127},"portrait":{"count":223,"lastSeenTime":1577036303309,"publicGameCount":12,"difficulty":0.6296296296296297,"difficultyWeight":108},"positive":{"count":397,"lastSeenTime":1577036559751,"publicGameCount":33,"difficulty":0.6849315068493153,"difficultyWeight":292},"poster":{"count":207,"lastSeenTime":1577032968561,"difficulty":0.5967741935483871,"difficultyWeight":62,"publicGameCount":2},"pot":{"count":225,"lastSeenTime":1577003149686,"difficulty":0.5942028985507246,"difficultyWeight":138,"publicGameCount":7},"pot of gold":{"count":207,"lastSeenTime":1577001474096,"publicGameCount":25,"difficulty":0.7162162162162162,"difficultyWeight":148},"potion":{"count":222,"lastSeenTime":1577015620718,"difficulty":0.631578947368421,"difficultyWeight":171,"publicGameCount":10},"powder":{"count":232,"lastSeenTime":1577033608923,"publicGameCount":6,"difficulty":0.7045454545454546,"difficultyWeight":88},"pray":{"count":218,"lastSeenTime":1577036740392,"publicGameCount":15,"difficulty":0.45925925925925926,"difficultyWeight":135},"preach":{"count":241,"lastSeenTime":1577017456065,"difficulty":0.8085106382978723,"difficultyWeight":47,"publicGameCount":5},"pregnant":{"count":412,"lastSeenTime":1577034425936,"publicGameCount":54,"difficulty":0.5407407407407405,"difficultyWeight":405},"present":{"count":206,"lastSeenTime":1577037117265,"difficulty":0.5555555555555556,"difficultyWeight":207,"publicGameCount":4},"president":{"count":235,"lastSeenTime":1577016293273,"difficulty":0.5751633986928104,"difficultyWeight":153,"publicGameCount":17},"pretzel":{"count":205,"lastSeenTime":1577015586196,"publicGameCount":7,"difficulty":0.644927536231884,"difficultyWeight":138},"prince":{"count":205,"lastSeenTime":1577030652854,"difficulty":0.6618705035971222,"difficultyWeight":139,"publicGameCount":8},"princess":{"count":227,"lastSeenTime":1577031536040,"publicGameCount":18,"difficulty":0.5864978902953587,"difficultyWeight":237},"prison":{"count":421,"lastSeenTime":1577036022358,"publicGameCount":50,"difficulty":0.5371702637889686,"difficultyWeight":417},"professor":{"count":224,"lastSeenTime":1577017022501,"difficulty":0.7252747252747253,"difficultyWeight":91,"publicGameCount":10},"programmer":{"count":237,"lastSeenTime":1577001594957,"publicGameCount":4,"difficulty":0.6296296296296297,"difficultyWeight":27},"protest":{"count":246,"lastSeenTime":1577035593475,"difficulty":0.6346153846153846,"difficultyWeight":52,"publicGameCount":3},"pudding":{"count":233,"lastSeenTime":1577012169647,"publicGameCount":7,"difficulty":0.7349397590361446,"difficultyWeight":83},"puddle":{"count":465,"lastSeenTime":1577032090593,"difficulty":0.6570397111913358,"difficultyWeight":277,"publicGameCount":31},"puffin":{"count":218,"lastSeenTime":1577031971915,"publicGameCount":4,"difficulty":0.7428571428571429,"difficultyWeight":35},"puma":{"count":234,"lastSeenTime":1577032051558,"difficulty":0.5844155844155844,"difficultyWeight":77,"publicGameCount":6},"purse":{"count":229,"lastSeenTime":1577032283871,"difficulty":0.6796116504854369,"difficultyWeight":103,"publicGameCount":4},"puzzle":{"count":201,"lastSeenTime":1577017071398,"difficulty":0.5398773006134968,"difficultyWeight":163,"publicGameCount":11},"pyramid":{"count":205,"lastSeenTime":1577034462634,"difficulty":0.6518987341772152,"difficultyWeight":158,"publicGameCount":8},"quarter":{"count":243,"lastSeenTime":1577036527277,"difficulty":0.6496350364963503,"difficultyWeight":137,"publicGameCount":18},"queen":{"count":238,"lastSeenTime":1577016849135,"difficulty":0.4870689655172414,"difficultyWeight":232,"publicGameCount":9},"queue":{"count":255,"lastSeenTime":1577002548484,"publicGameCount":5,"difficulty":0.7837837837837838,"difficultyWeight":37},"race":{"count":230,"lastSeenTime":1577013387198,"publicGameCount":7,"difficulty":0.422680412371134,"difficultyWeight":97},"racecar":{"count":202,"lastSeenTime":1577036892935,"publicGameCount":6,"difficulty":0.7285714285714285,"difficultyWeight":70},"radish":{"count":219,"lastSeenTime":1577016752940,"publicGameCount":5,"difficulty":0.5294117647058824,"difficultyWeight":51},"raft":{"count":263,"lastSeenTime":1577024563450,"publicGameCount":10,"difficulty":0.4945054945054945,"difficultyWeight":91},"rail":{"count":421,"lastSeenTime":1577032662789,"difficulty":0.5950920245398773,"difficultyWeight":163,"publicGameCount":17},"rainbow":{"count":450,"lastSeenTime":1577031193533,"publicGameCount":43,"difficulty":0.4088176352705411,"difficultyWeight":499},"raindrop":{"count":444,"lastSeenTime":1577037306624,"publicGameCount":43,"difficulty":0.5449275362318838,"difficultyWeight":345},"raisin":{"count":207,"lastSeenTime":1577034135613,"publicGameCount":6,"difficulty":0.7454545454545455,"difficultyWeight":55},"rake":{"count":265,"lastSeenTime":1577018482673,"difficulty":0.4788732394366197,"difficultyWeight":71,"publicGameCount":8},"ram":{"count":212,"lastSeenTime":1577019236659,"difficulty":0.45,"difficultyWeight":60,"publicGameCount":4},"rapper":{"count":225,"lastSeenTime":1577035886295,"publicGameCount":13,"difficulty":0.6185567010309279,"difficultyWeight":97},"raspberry":{"count":215,"lastSeenTime":1577037042051,"publicGameCount":16,"difficulty":0.7049180327868853,"difficultyWeight":122},"razorblade":{"count":226,"lastSeenTime":1577037070414,"publicGameCount":11,"difficulty":0.6463414634146342,"difficultyWeight":82},"reality":{"count":230,"lastSeenTime":1577033043901,"difficulty":0.7115384615384616,"difficultyWeight":52,"publicGameCount":4},"rectangle":{"count":219,"lastSeenTime":1577021060711,"publicGameCount":14,"difficulty":0.5950920245398773,"difficultyWeight":163},"recycling":{"count":240,"lastSeenTime":1577019031436,"publicGameCount":12,"difficulty":0.625,"difficultyWeight":136},"red carpet":{"count":239,"lastSeenTime":1577020250301,"publicGameCount":27,"difficulty":0.7598039215686274,"difficultyWeight":204},"reflection":{"count":229,"lastSeenTime":1577031521720,"publicGameCount":16,"difficulty":0.7214285714285714,"difficultyWeight":140},"relationship":{"count":218,"lastSeenTime":1577037202537,"publicGameCount":15,"difficulty":0.6363636363636362,"difficultyWeight":99},"rewind":{"count":226,"lastSeenTime":1577033583113,"publicGameCount":3,"difficulty":0.6612903225806451,"difficultyWeight":62},"rhinoceros":{"count":211,"lastSeenTime":1576977112030,"difficulty":0.7777777777777778,"difficultyWeight":45,"publicGameCount":7},"ribbon":{"count":236,"lastSeenTime":1577007506033,"publicGameCount":11,"difficulty":0.5490196078431373,"difficultyWeight":102},"rice":{"count":201,"lastSeenTime":1577008267383,"difficulty":0.576,"difficultyWeight":125,"publicGameCount":5},"river":{"count":430,"lastSeenTime":1577031607937,"publicGameCount":48,"difficulty":0.44274809160305345,"difficultyWeight":393},"robin":{"count":242,"lastSeenTime":1577037016878,"difficulty":0.5223880597014925,"difficultyWeight":67,"publicGameCount":7},"robot":{"count":212,"lastSeenTime":1577037178254,"publicGameCount":7,"difficulty":0.5069124423963135,"difficultyWeight":217},"rockstar":{"count":234,"lastSeenTime":1577031166738,"difficulty":0.6577181208053692,"difficultyWeight":149,"publicGameCount":15},"room":{"count":226,"lastSeenTime":1577014691828,"difficulty":0.6024096385542169,"difficultyWeight":83,"publicGameCount":5},"rooster":{"count":220,"lastSeenTime":1577034462634,"difficulty":0.6551724137931034,"difficultyWeight":87,"publicGameCount":4},"root":{"count":413,"lastSeenTime":1577018853704,"publicGameCount":18,"difficulty":0.4999999999999999,"difficultyWeight":258},"rose":{"count":439,"lastSeenTime":1577032147462,"publicGameCount":39,"difficulty":0.44075829383886256,"difficultyWeight":422},"rubber":{"count":458,"lastSeenTime":1577030226184,"difficulty":0.6494252873563219,"difficultyWeight":174,"publicGameCount":20},"ruby":{"count":201,"lastSeenTime":1577031234774,"publicGameCount":10,"difficulty":0.7307692307692307,"difficultyWeight":130},"run":{"count":237,"lastSeenTime":1577036701657,"publicGameCount":2,"difficulty":0.5460992907801419,"difficultyWeight":141},"rune":{"count":225,"lastSeenTime":1577020153208,"publicGameCount":3,"difficulty":0.6571428571428571,"difficultyWeight":35},"sad":{"count":235,"lastSeenTime":1577012421074,"difficulty":0.4980694980694981,"difficultyWeight":259,"publicGameCount":5},"salad":{"count":238,"lastSeenTime":1577009895556,"publicGameCount":10,"difficulty":0.6046511627906976,"difficultyWeight":172},"salmon":{"count":423,"lastSeenTime":1577030082147,"publicGameCount":27,"difficulty":0.5733944954128439,"difficultyWeight":218},"sandbox":{"count":192,"lastSeenTime":1577017319731,"difficulty":0.6153846153846154,"difficultyWeight":130,"publicGameCount":16},"sandstorm":{"count":432,"lastSeenTime":1577024430436,"publicGameCount":25,"difficulty":0.6499999999999999,"difficultyWeight":180},"satellite":{"count":219,"lastSeenTime":1576996666059,"publicGameCount":12,"difficulty":0.7457627118644068,"difficultyWeight":118},"sauce":{"count":214,"lastSeenTime":1577015910164,"publicGameCount":7,"difficulty":0.6209677419354839,"difficultyWeight":124},"scarf":{"count":223,"lastSeenTime":1577030802925,"publicGameCount":16,"difficulty":0.47878787878787876,"difficultyWeight":165},"scent":{"count":245,"lastSeenTime":1577034214987,"publicGameCount":7,"difficulty":0.7222222222222222,"difficultyWeight":54},"scream":{"count":202,"lastSeenTime":1577015899997,"difficulty":0.6030927835051546,"difficultyWeight":194,"publicGameCount":10},"screen":{"count":235,"lastSeenTime":1577034632349,"publicGameCount":12,"difficulty":0.6,"difficultyWeight":155},"screw":{"count":189,"lastSeenTime":1577019457765,"publicGameCount":6,"difficulty":0.6335877862595419,"difficultyWeight":131},"scribble":{"count":220,"lastSeenTime":1577024452061,"difficulty":0.632258064516129,"difficultyWeight":155,"publicGameCount":7},"scythe":{"count":227,"lastSeenTime":1577021060711,"publicGameCount":12,"difficulty":0.5462962962962961,"difficultyWeight":108},"sea":{"count":437,"lastSeenTime":1577019066716,"difficulty":0.4537572254335259,"difficultyWeight":346,"publicGameCount":26},"sea lion":{"count":222,"lastSeenTime":1577033670196,"publicGameCount":12,"difficulty":0.6626506024096386,"difficultyWeight":83},"seafood":{"count":212,"lastSeenTime":1577031618529,"publicGameCount":15,"difficulty":0.6756756756756758,"difficultyWeight":111},"seal":{"count":224,"lastSeenTime":1577017417153,"publicGameCount":7,"difficulty":0.5975609756097561,"difficultyWeight":164},"seashell":{"count":469,"lastSeenTime":1577035324132,"publicGameCount":32,"difficulty":0.6532846715328469,"difficultyWeight":274},"season":{"count":201,"lastSeenTime":1577030973803,"publicGameCount":7,"difficulty":0.725,"difficultyWeight":80},"seat belt":{"count":233,"lastSeenTime":1577025564446,"publicGameCount":27,"difficulty":0.671875,"difficultyWeight":192},"seaweed":{"count":468,"lastSeenTime":1577017265397,"publicGameCount":28,"difficulty":0.6280991735537189,"difficultyWeight":242},"second":{"count":232,"lastSeenTime":1576998400404,"publicGameCount":17,"difficulty":0.6052631578947368,"difficultyWeight":152},"seed":{"count":437,"lastSeenTime":1577031113164,"publicGameCount":37,"difficulty":0.6107784431137722,"difficultyWeight":334},"seesaw":{"count":214,"lastSeenTime":1577037216675,"difficulty":0.6582278481012658,"difficultyWeight":79,"publicGameCount":4},"semicircle":{"count":224,"lastSeenTime":1577031282203,"publicGameCount":11,"difficulty":0.6804123711340206,"difficultyWeight":97},"sewing machine":{"count":227,"lastSeenTime":1577032208262,"publicGameCount":11,"difficulty":0.68,"difficultyWeight":75},"shadow":{"count":213,"lastSeenTime":1577031219834,"publicGameCount":16,"difficulty":0.5699481865284974,"difficultyWeight":193},"sheep":{"count":184,"lastSeenTime":1577036135826,"difficulty":0.45689655172413796,"difficultyWeight":232,"publicGameCount":7},"shelf":{"count":237,"lastSeenTime":1576983583807,"publicGameCount":9,"difficulty":0.6138613861386139,"difficultyWeight":101},"shell":{"count":414,"lastSeenTime":1577013397940,"publicGameCount":24,"difficulty":0.5472440944881891,"difficultyWeight":254},"shipwreck":{"count":446,"lastSeenTime":1577032786045,"publicGameCount":19,"difficulty":0.6484375,"difficultyWeight":128},"shock":{"count":206,"lastSeenTime":1577014063844,"difficulty":0.6513761467889908,"difficultyWeight":109,"publicGameCount":5},"shoe":{"count":219,"lastSeenTime":1577014366031,"publicGameCount":11,"difficulty":0.4933920704845815,"difficultyWeight":227},"shoebox":{"count":227,"lastSeenTime":1577032483552,"difficulty":0.5949367088607594,"difficultyWeight":158,"publicGameCount":12},"shop":{"count":457,"lastSeenTime":1577033308316,"difficulty":0.5950413223140495,"difficultyWeight":242,"publicGameCount":23},"shopping cart":{"count":225,"lastSeenTime":1577008938640,"publicGameCount":20,"difficulty":0.6168831168831169,"difficultyWeight":154},"shoulder":{"count":466,"lastSeenTime":1577036225894,"publicGameCount":38,"difficulty":0.6017699115044248,"difficultyWeight":339},"shout":{"count":215,"lastSeenTime":1576995704012,"publicGameCount":7,"difficulty":0.6583333333333333,"difficultyWeight":120},"shower":{"count":220,"lastSeenTime":1576955385547,"difficulty":0.49019607843137253,"difficultyWeight":153,"publicGameCount":8},"shrub":{"count":437,"lastSeenTime":1577032738629,"publicGameCount":15,"difficulty":0.7115384615384616,"difficultyWeight":104},"sick":{"count":226,"lastSeenTime":1577010162289,"publicGameCount":10,"difficulty":0.5107913669064749,"difficultyWeight":139},"signature":{"count":231,"lastSeenTime":1577008963878,"publicGameCount":11,"difficulty":0.5906432748538013,"difficultyWeight":171},"silence":{"count":213,"lastSeenTime":1577021380401,"publicGameCount":9,"difficulty":0.581081081081081,"difficultyWeight":74},"silver":{"count":234,"lastSeenTime":1577033058121,"publicGameCount":11,"difficulty":0.5208333333333334,"difficultyWeight":144},"silverware":{"count":227,"lastSeenTime":1577030240458,"publicGameCount":16,"difficulty":0.7063492063492064,"difficultyWeight":126},"sing":{"count":223,"lastSeenTime":1577026040111,"difficulty":0.5363636363636363,"difficultyWeight":220,"publicGameCount":10},"sink":{"count":234,"lastSeenTime":1576992818479,"difficulty":0.6126126126126128,"difficultyWeight":111,"publicGameCount":6},"six pack":{"count":666,"lastSeenTime":1577035387934,"publicGameCount":81,"difficulty":0.6969696969696971,"difficultyWeight":627},"skateboard":{"count":225,"lastSeenTime":1577034081969,"publicGameCount":19,"difficulty":0.5511363636363636,"difficultyWeight":176},"skateboarder":{"count":208,"lastSeenTime":1577036574064,"publicGameCount":16,"difficulty":0.6956521739130435,"difficultyWeight":138},"ski jump":{"count":238,"lastSeenTime":1576986579349,"publicGameCount":9,"difficulty":0.7160493827160493,"difficultyWeight":81},"sky":{"count":402,"lastSeenTime":1577006890843,"difficulty":0.5022727272727273,"difficultyWeight":440,"publicGameCount":16},"sledge":{"count":202,"lastSeenTime":1577036836029,"difficulty":0.6935483870967742,"difficultyWeight":62,"publicGameCount":2},"sleeve":{"count":232,"lastSeenTime":1576979880408,"difficulty":0.7009345794392523,"difficultyWeight":107,"publicGameCount":7},"slide":{"count":416,"lastSeenTime":1577035823959,"publicGameCount":23,"difficulty":0.482394366197183,"difficultyWeight":284},"slime":{"count":229,"lastSeenTime":1577036137207,"publicGameCount":9,"difficulty":0.625,"difficultyWeight":136},"slippery":{"count":424,"lastSeenTime":1577031259619,"publicGameCount":17,"difficulty":0.6986301369863014,"difficultyWeight":146},"sloth":{"count":230,"lastSeenTime":1577030506619,"publicGameCount":4,"difficulty":0.6792452830188679,"difficultyWeight":53},"slow":{"count":440,"lastSeenTime":1577010137946,"publicGameCount":29,"difficulty":0.5594713656387665,"difficultyWeight":227},"smile":{"count":445,"lastSeenTime":1577036513099,"difficulty":0.4460580912863071,"difficultyWeight":482,"publicGameCount":53},"smoke":{"count":229,"lastSeenTime":1577036559751,"difficulty":0.521276595744681,"difficultyWeight":188,"publicGameCount":13},"snowball fight":{"count":206,"lastSeenTime":1577017579132,"publicGameCount":17,"difficulty":0.7619047619047619,"difficultyWeight":126},"snowboard":{"count":225,"lastSeenTime":1577025129454,"publicGameCount":14,"difficulty":0.576,"difficultyWeight":125},"snowman":{"count":205,"lastSeenTime":1577035554960,"difficulty":0.4444444444444444,"difficultyWeight":225,"publicGameCount":16},"soccer":{"count":212,"lastSeenTime":1577024845093,"publicGameCount":7,"difficulty":0.5139664804469273,"difficultyWeight":179},"soda":{"count":199,"lastSeenTime":1577021133236,"difficulty":0.4801762114537445,"difficultyWeight":227,"publicGameCount":14},"sound":{"count":209,"lastSeenTime":1577011245370,"publicGameCount":2,"difficulty":0.48951048951048953,"difficultyWeight":143},"soup":{"count":246,"lastSeenTime":1577036183989,"difficulty":0.5075757575757576,"difficultyWeight":132,"publicGameCount":9},"south":{"count":423,"lastSeenTime":1577036730175,"publicGameCount":20,"difficulty":0.4605809128630705,"difficultyWeight":241},"space":{"count":208,"lastSeenTime":1576992937668,"difficulty":0.6141078838174274,"difficultyWeight":241,"publicGameCount":5},"spade":{"count":216,"lastSeenTime":1576964722158,"publicGameCount":11,"difficulty":0.6195652173913045,"difficultyWeight":92},"spark":{"count":228,"lastSeenTime":1577004186315,"difficulty":0.5714285714285714,"difficultyWeight":84,"publicGameCount":7},"sparkles":{"count":199,"lastSeenTime":1577029886480,"publicGameCount":9,"difficulty":0.8192771084337349,"difficultyWeight":83},"spear":{"count":226,"lastSeenTime":1576951863939,"difficulty":0.5999999999999999,"difficultyWeight":175,"publicGameCount":8},"spelunker":{"count":207,"lastSeenTime":1577018327956,"difficulty":0.8636363636363636,"difficultyWeight":22,"publicGameCount":1},"spider":{"count":222,"lastSeenTime":1577001885793,"publicGameCount":10,"difficulty":0.4389312977099237,"difficultyWeight":262},"spin":{"count":212,"lastSeenTime":1577011621389,"publicGameCount":9,"difficulty":0.6260869565217392,"difficultyWeight":115},"spinach":{"count":213,"lastSeenTime":1577010615663,"difficulty":0.7681159420289855,"difficultyWeight":69,"publicGameCount":7},"spiral":{"count":236,"lastSeenTime":1577019885747,"difficulty":0.6016260162601627,"difficultyWeight":123,"publicGameCount":11},"sponge":{"count":233,"lastSeenTime":1577024917709,"difficulty":0.6104651162790697,"difficultyWeight":172,"publicGameCount":12},"spool":{"count":196,"lastSeenTime":1577030951342,"publicGameCount":2,"difficulty":0.627906976744186,"difficultyWeight":43},"spoon":{"count":436,"lastSeenTime":1577032859509,"publicGameCount":45,"difficulty":0.49645390070922,"difficultyWeight":423},"sports":{"count":255,"lastSeenTime":1577010995697,"difficulty":0.656,"difficultyWeight":125,"publicGameCount":13},"sprinkler":{"count":216,"lastSeenTime":1577018733113,"difficulty":0.628099173553719,"difficultyWeight":121,"publicGameCount":7},"square":{"count":243,"lastSeenTime":1577013947672,"publicGameCount":19,"difficulty":0.5117370892018781,"difficultyWeight":213},"squid":{"count":219,"lastSeenTime":1577019935685,"publicGameCount":11,"difficulty":0.5657894736842105,"difficultyWeight":152},"squirrel":{"count":212,"lastSeenTime":1577007278407,"difficulty":0.7130434782608696,"difficultyWeight":115,"publicGameCount":12},"stab":{"count":239,"lastSeenTime":1577019494384,"publicGameCount":17,"difficulty":0.6196319018404908,"difficultyWeight":163},"stadium":{"count":444,"lastSeenTime":1577014707226,"publicGameCount":16,"difficulty":0.7421875,"difficultyWeight":128},"stand":{"count":234,"lastSeenTime":1577016005533,"publicGameCount":15,"difficulty":0.6068965517241379,"difficultyWeight":145},"star":{"count":216,"lastSeenTime":1577011192091,"publicGameCount":11,"difficulty":0.43288590604026844,"difficultyWeight":298},"starfish":{"count":201,"lastSeenTime":1576983895924,"difficulty":0.5219512195121951,"difficultyWeight":205,"publicGameCount":12},"statue":{"count":425,"lastSeenTime":1577036473654,"publicGameCount":28,"difficulty":0.6282051282051282,"difficultyWeight":234},"steam":{"count":226,"lastSeenTime":1577032958355,"difficulty":0.6464646464646465,"difficultyWeight":99,"publicGameCount":9},"step":{"count":248,"lastSeenTime":1577018165583,"publicGameCount":11,"difficulty":0.5182481751824818,"difficultyWeight":137},"stomach":{"count":446,"lastSeenTime":1576988931782,"publicGameCount":32,"difficulty":0.6812749003984063,"difficultyWeight":251},"stone":{"count":238,"lastSeenTime":1577019896135,"publicGameCount":9,"difficulty":0.5763888888888888,"difficultyWeight":144},"stove":{"count":248,"lastSeenTime":1577037117265,"publicGameCount":13,"difficulty":0.6453900709219859,"difficultyWeight":141},"straw":{"count":251,"lastSeenTime":1576995740856,"publicGameCount":16,"difficulty":0.603896103896104,"difficultyWeight":154},"strawberry":{"count":226,"lastSeenTime":1577033891936,"difficulty":0.4675324675324675,"difficultyWeight":231,"publicGameCount":28},"street":{"count":435,"lastSeenTime":1577015197399,"publicGameCount":36,"difficulty":0.681081081081081,"difficultyWeight":370},"stress":{"count":218,"lastSeenTime":1577011621389,"difficulty":0.6363636363636364,"difficultyWeight":22,"publicGameCount":2},"student":{"count":223,"lastSeenTime":1577007071313,"publicGameCount":10,"difficulty":0.6250000000000001,"difficultyWeight":96},"studio":{"count":390,"lastSeenTime":1577035508304,"difficulty":0.5853658536585366,"difficultyWeight":41,"publicGameCount":3},"study":{"count":411,"lastSeenTime":1577037653341,"publicGameCount":24,"difficulty":0.6041666666666666,"difficultyWeight":240},"subway":{"count":214,"lastSeenTime":1576988731899,"publicGameCount":13,"difficulty":0.49640287769784175,"difficultyWeight":139},"suitcase":{"count":220,"lastSeenTime":1577030301299,"publicGameCount":8,"difficulty":0.6528925619834711,"difficultyWeight":121},"summer":{"count":246,"lastSeenTime":1576985365869,"difficulty":0.6204819277108434,"difficultyWeight":166,"publicGameCount":13},"sun":{"count":219,"lastSeenTime":1577016080437,"difficulty":0.44061302681992337,"difficultyWeight":261,"publicGameCount":2},"sunshade":{"count":218,"lastSeenTime":1576970324105,"publicGameCount":9,"difficulty":0.7903225806451613,"difficultyWeight":62},"supermarket":{"count":453,"lastSeenTime":1577033336640,"publicGameCount":33,"difficulty":0.7565217391304347,"difficultyWeight":230},"surfboard":{"count":233,"lastSeenTime":1576995576227,"difficulty":0.5972850678733032,"difficultyWeight":221,"publicGameCount":15},"surgeon":{"count":213,"lastSeenTime":1577014074125,"publicGameCount":5,"difficulty":0.6744186046511628,"difficultyWeight":43},"survivor":{"count":225,"lastSeenTime":1577031618529,"difficulty":0.7419354838709677,"difficultyWeight":62,"publicGameCount":6},"swamp":{"count":450,"lastSeenTime":1577034411762,"publicGameCount":23,"difficulty":0.5170731707317073,"difficultyWeight":205},"swan":{"count":211,"lastSeenTime":1577036730175,"publicGameCount":9,"difficulty":0.5725806451612904,"difficultyWeight":124},"swarm":{"count":208,"lastSeenTime":1577019885747,"difficulty":0.6296296296296297,"difficultyWeight":54,"publicGameCount":4},"sweat":{"count":233,"lastSeenTime":1577020239958,"publicGameCount":13,"difficulty":0.5466666666666665,"difficultyWeight":150},"sweater":{"count":219,"lastSeenTime":1577008687049,"difficulty":0.6562499999999999,"difficultyWeight":160,"publicGameCount":9},"swimming pool":{"count":253,"lastSeenTime":1576980949563,"publicGameCount":31,"difficulty":0.7422222222222222,"difficultyWeight":225},"swimsuit":{"count":237,"lastSeenTime":1577030240458,"publicGameCount":14,"difficulty":0.680672268907563,"difficultyWeight":119},"swordfish":{"count":234,"lastSeenTime":1577033960762,"publicGameCount":16,"difficulty":0.5749999999999998,"difficultyWeight":160},"table tennis":{"count":204,"lastSeenTime":1577033708898,"publicGameCount":18,"difficulty":0.6363636363636364,"difficultyWeight":132},"tablet":{"count":452,"lastSeenTime":1577032752804,"publicGameCount":42,"difficulty":0.596923076923077,"difficultyWeight":325},"tadpole":{"count":230,"lastSeenTime":1577017517304,"difficulty":0.7431192660550459,"difficultyWeight":109,"publicGameCount":7},"tail":{"count":218,"lastSeenTime":1577015524015,"difficulty":0.5129533678756475,"difficultyWeight":193,"publicGameCount":3},"take off":{"count":236,"lastSeenTime":1577024859631,"publicGameCount":10,"difficulty":0.8311688311688312,"difficultyWeight":77},"tangerine":{"count":219,"lastSeenTime":1577035287582,"difficulty":0.7204301075268817,"difficultyWeight":93,"publicGameCount":9},"tarantula":{"count":227,"lastSeenTime":1576971438912,"difficulty":0.7079646017699115,"difficultyWeight":113,"publicGameCount":10},"taxi driver":{"count":218,"lastSeenTime":1576991662877,"publicGameCount":16,"difficulty":0.6074766355140186,"difficultyWeight":107},"teapot":{"count":226,"lastSeenTime":1577029725408,"difficulty":0.5746268656716418,"difficultyWeight":134,"publicGameCount":5},"tear":{"count":430,"lastSeenTime":1577034703857,"publicGameCount":41,"difficulty":0.510843373493976,"difficultyWeight":415},"teaspoon":{"count":232,"lastSeenTime":1576987040770,"publicGameCount":5,"difficulty":0.7903225806451613,"difficultyWeight":62},"teddy bear":{"count":220,"lastSeenTime":1576989119508,"publicGameCount":29,"difficulty":0.5046728971962618,"difficultyWeight":214},"telephone":{"count":233,"lastSeenTime":1577020551055,"publicGameCount":11,"difficulty":0.5414364640883977,"difficultyWeight":181},"telescope":{"count":239,"lastSeenTime":1577031322805,"publicGameCount":11,"difficulty":0.5454545454545454,"difficultyWeight":154},"television":{"count":235,"lastSeenTime":1577012079857,"difficulty":0.4327485380116959,"difficultyWeight":171,"publicGameCount":19},"temperature":{"count":211,"lastSeenTime":1577001314234,"difficulty":0.688622754491018,"difficultyWeight":167,"publicGameCount":20},"tennis":{"count":220,"lastSeenTime":1577034200815,"difficulty":0.5882352941176473,"difficultyWeight":187,"publicGameCount":9},"tennis racket":{"count":206,"lastSeenTime":1576994867256,"publicGameCount":29,"difficulty":0.69377990430622,"difficultyWeight":209},"tent":{"count":462,"lastSeenTime":1576996730066,"publicGameCount":42,"difficulty":0.4789473684210526,"difficultyWeight":380},"tentacle":{"count":216,"lastSeenTime":1577010855712,"publicGameCount":10,"difficulty":0.6271186440677966,"difficultyWeight":118},"thief":{"count":213,"lastSeenTime":1577020536744,"publicGameCount":15,"difficulty":0.6357142857142857,"difficultyWeight":140},"thirst":{"count":223,"lastSeenTime":1577019935685,"publicGameCount":12,"difficulty":0.5757575757575758,"difficultyWeight":99},"throat":{"count":437,"lastSeenTime":1577017714611,"publicGameCount":26,"difficulty":0.7322175732217573,"difficultyWeight":239},"tickle":{"count":232,"lastSeenTime":1577000582457,"difficulty":0.7741935483870968,"difficultyWeight":31,"publicGameCount":1},"tie":{"count":496,"lastSeenTime":1577037031237,"publicGameCount":49,"difficulty":0.5518987341772152,"difficultyWeight":395},"tiger":{"count":221,"lastSeenTime":1577016205028,"publicGameCount":8,"difficulty":0.5503875968992249,"difficultyWeight":129},"time machine":{"count":219,"lastSeenTime":1577033508319,"publicGameCount":11,"difficulty":0.8552631578947368,"difficultyWeight":76},"timpani":{"count":450,"lastSeenTime":1577013426420,"publicGameCount":8,"difficulty":0.7868852459016393,"difficultyWeight":61},"tired":{"count":213,"lastSeenTime":1577034411762,"publicGameCount":10,"difficulty":0.6214285714285714,"difficultyWeight":140},"toad":{"count":218,"lastSeenTime":1577018472586,"publicGameCount":3,"difficulty":0.6236559139784946,"difficultyWeight":93},"toast":{"count":212,"lastSeenTime":1577033920831,"difficulty":0.5729166666666666,"difficultyWeight":192,"publicGameCount":10},"toaster":{"count":242,"lastSeenTime":1577009805383,"publicGameCount":9,"difficulty":0.5786802030456852,"difficultyWeight":197},"toenail":{"count":413,"lastSeenTime":1577031419224,"publicGameCount":33,"difficulty":0.5187713310580204,"difficultyWeight":293},"toilet":{"count":256,"lastSeenTime":1577019361234,"difficulty":0.544642857142857,"difficultyWeight":224,"publicGameCount":12},"tomato":{"count":205,"lastSeenTime":1577012106287,"difficulty":0.5757575757575758,"difficultyWeight":264,"publicGameCount":4},"tomb":{"count":211,"lastSeenTime":1576995155567,"difficulty":0.6616541353383458,"difficultyWeight":133,"publicGameCount":9},"tombstone":{"count":246,"lastSeenTime":1577010930973,"publicGameCount":18,"difficulty":0.6196319018404908,"difficultyWeight":163},"tongue":{"count":463,"lastSeenTime":1577035961642,"publicGameCount":56,"difficulty":0.578494623655914,"difficultyWeight":465},"toothpaste":{"count":233,"lastSeenTime":1576998176725,"publicGameCount":25,"difficulty":0.5207373271889401,"difficultyWeight":217},"top hat":{"count":223,"lastSeenTime":1577036022358,"publicGameCount":35,"difficulty":0.5785123966942148,"difficultyWeight":242},"torch":{"count":217,"lastSeenTime":1577036907083,"publicGameCount":7,"difficulty":0.5714285714285713,"difficultyWeight":231},"totem":{"count":217,"lastSeenTime":1577009010620,"difficulty":0.6105263157894737,"difficultyWeight":95,"publicGameCount":8},"toucan":{"count":235,"lastSeenTime":1577037341722,"difficulty":0.7058823529411765,"difficultyWeight":51,"publicGameCount":4},"tow truck":{"count":223,"lastSeenTime":1577034613528,"publicGameCount":7,"difficulty":0.5806451612903226,"difficultyWeight":62},"tower":{"count":441,"lastSeenTime":1577032849365,"publicGameCount":35,"difficulty":0.5773480662983427,"difficultyWeight":362},"toy":{"count":243,"lastSeenTime":1577036096380,"publicGameCount":8,"difficulty":0.6138613861386139,"difficultyWeight":101},"tractor":{"count":208,"lastSeenTime":1577037202537,"publicGameCount":3,"difficulty":0.6395348837209303,"difficultyWeight":86},"traffic":{"count":411,"lastSeenTime":1577017692184,"publicGameCount":34,"difficulty":0.5671641791044776,"difficultyWeight":268},"trailer":{"count":205,"lastSeenTime":1577033269629,"publicGameCount":3,"difficulty":0.6666666666666666,"difficultyWeight":57},"train":{"count":215,"lastSeenTime":1577033007248,"publicGameCount":2,"difficulty":0.5245901639344263,"difficultyWeight":183},"trap":{"count":221,"lastSeenTime":1576981344984,"publicGameCount":4,"difficulty":0.7945205479452054,"difficultyWeight":73},"trash can":{"count":237,"lastSeenTime":1577024591466,"publicGameCount":21,"difficulty":0.6602564102564104,"difficultyWeight":156},"traveler":{"count":260,"lastSeenTime":1577037638341,"publicGameCount":7,"difficulty":0.7575757575757576,"difficultyWeight":66},"treasure":{"count":235,"lastSeenTime":1577035813853,"publicGameCount":14,"difficulty":0.5371900826446281,"difficultyWeight":121},"tree":{"count":417,"lastSeenTime":1577036635725,"difficulty":0.39667458432304037,"difficultyWeight":421,"publicGameCount":39},"treehouse":{"count":430,"lastSeenTime":1577031496440,"publicGameCount":47,"difficulty":0.4255813953488372,"difficultyWeight":430},"trend":{"count":240,"lastSeenTime":1577015571780,"publicGameCount":3,"difficulty":0.7692307692307693,"difficultyWeight":39},"triangle":{"count":238,"lastSeenTime":1577032564741,"difficulty":0.4823529411764706,"difficultyWeight":170,"publicGameCount":15},"tricycle":{"count":229,"lastSeenTime":1576949271003,"publicGameCount":10,"difficulty":0.5444444444444445,"difficultyWeight":90},"trigger":{"count":222,"lastSeenTime":1577033068320,"publicGameCount":8,"difficulty":0.6363636363636364,"difficultyWeight":88},"triplets":{"count":253,"lastSeenTime":1577013585761,"publicGameCount":16,"difficulty":0.6423357664233577,"difficultyWeight":137},"tripod":{"count":225,"lastSeenTime":1577025817270,"difficulty":0.532258064516129,"difficultyWeight":62,"publicGameCount":3},"trombone":{"count":436,"lastSeenTime":1577008552896,"publicGameCount":20,"difficulty":0.72,"difficultyWeight":175},"trophy":{"count":233,"lastSeenTime":1577017359795,"difficulty":0.5471698113207547,"difficultyWeight":159,"publicGameCount":10},"truck":{"count":231,"lastSeenTime":1577035522572,"difficulty":0.5053191489361702,"difficultyWeight":188,"publicGameCount":5},"truck driver":{"count":223,"lastSeenTime":1577024994037,"publicGameCount":11,"difficulty":0.625,"difficultyWeight":72},"trumpet":{"count":487,"lastSeenTime":1577025251101,"difficulty":0.5163043478260869,"difficultyWeight":184,"publicGameCount":23},"tug":{"count":461,"lastSeenTime":1577033733248,"publicGameCount":19,"difficulty":0.753731343283582,"difficultyWeight":134},"turd":{"count":229,"lastSeenTime":1577001701665,"difficulty":0.72,"difficultyWeight":100,"publicGameCount":8},"turnip":{"count":228,"lastSeenTime":1577034531942,"publicGameCount":4,"difficulty":0.6857142857142857,"difficultyWeight":35},"turtle":{"count":213,"lastSeenTime":1577025115050,"difficulty":0.46938775510204084,"difficultyWeight":245,"publicGameCount":10},"tuxedo":{"count":209,"lastSeenTime":1577018571006,"publicGameCount":10,"difficulty":0.6633663366336634,"difficultyWeight":101},"udder":{"count":242,"lastSeenTime":1577034764802,"publicGameCount":6,"difficulty":0.574074074074074,"difficultyWeight":54},"ukulele":{"count":441,"lastSeenTime":1577036401976,"publicGameCount":22,"difficulty":0.6904761904761906,"difficultyWeight":168},"umbrella":{"count":191,"lastSeenTime":1577017445912,"publicGameCount":19,"difficulty":0.4900662251655628,"difficultyWeight":302},"uncle":{"count":200,"lastSeenTime":1577015499271,"difficulty":0.5409836065573771,"difficultyWeight":61,"publicGameCount":5},"unicorn":{"count":238,"lastSeenTime":1577014016599,"difficulty":0.4126984126984127,"difficultyWeight":189,"publicGameCount":13},"universe":{"count":223,"lastSeenTime":1577031204146,"publicGameCount":16,"difficulty":0.6739130434782609,"difficultyWeight":138},"valley":{"count":412,"lastSeenTime":1577012045277,"publicGameCount":21,"difficulty":0.7150537634408602,"difficultyWeight":186},"vampire":{"count":218,"lastSeenTime":1577030912743,"publicGameCount":9,"difficulty":0.493975903614458,"difficultyWeight":166},"vanilla":{"count":232,"lastSeenTime":1577005159929,"difficulty":0.6770833333333334,"difficultyWeight":96,"publicGameCount":9},"vegetable":{"count":199,"lastSeenTime":1577011218462,"publicGameCount":16,"difficulty":0.6146341463414634,"difficultyWeight":205},"vein":{"count":421,"lastSeenTime":1577031296608,"publicGameCount":28,"difficulty":0.5755395683453235,"difficultyWeight":278},"vent":{"count":213,"lastSeenTime":1577004559679,"difficulty":0.4909090909090909,"difficultyWeight":55,"publicGameCount":5},"victim":{"count":206,"lastSeenTime":1577036498776,"difficulty":0.6938775510204082,"difficultyWeight":49,"publicGameCount":6},"victory":{"count":223,"lastSeenTime":1576976111834,"difficulty":0.5677966101694916,"difficultyWeight":118,"publicGameCount":11},"video":{"count":237,"lastSeenTime":1577005054567,"difficulty":0.5736040609137056,"difficultyWeight":197,"publicGameCount":18},"video game":{"count":222,"lastSeenTime":1577030492374,"publicGameCount":26,"difficulty":0.7419354838709677,"difficultyWeight":186},"vine":{"count":413,"lastSeenTime":1577036121146,"publicGameCount":16,"difficulty":0.6610878661087864,"difficultyWeight":239},"vise":{"count":240,"lastSeenTime":1577024354735,"difficulty":0.6764705882352942,"difficultyWeight":34,"publicGameCount":2},"vodka":{"count":236,"lastSeenTime":1577007782564,"publicGameCount":12,"difficulty":0.5348837209302325,"difficultyWeight":129},"volleyball":{"count":229,"lastSeenTime":1577002683374,"publicGameCount":32,"difficulty":0.5269709543568465,"difficultyWeight":241},"volume":{"count":201,"lastSeenTime":1577004186315,"difficulty":0.5706214689265536,"difficultyWeight":177,"publicGameCount":14},"vomit":{"count":216,"lastSeenTime":1576998921481,"publicGameCount":10,"difficulty":0.553072625698324,"difficultyWeight":179},"vortex":{"count":237,"lastSeenTime":1576970308945,"publicGameCount":4,"difficulty":0.8043478260869565,"difficultyWeight":46},"waist":{"count":407,"lastSeenTime":1577036635725,"difficulty":0.6467391304347825,"difficultyWeight":184,"publicGameCount":19},"wallpaper":{"count":234,"lastSeenTime":1577030057610,"publicGameCount":6,"difficulty":0.6666666666666666,"difficultyWeight":63},"walrus":{"count":247,"lastSeenTime":1577036387422,"difficulty":0.6268656716417911,"difficultyWeight":67,"publicGameCount":7},"watch":{"count":483,"lastSeenTime":1577032066062,"publicGameCount":50,"difficulty":0.5214285714285715,"difficultyWeight":420},"water":{"count":393,"lastSeenTime":1577034007333,"difficulty":0.45416666666666666,"difficultyWeight":480,"publicGameCount":47},"water cycle":{"count":229,"lastSeenTime":1576984747355,"publicGameCount":9,"difficulty":0.85,"difficultyWeight":60},"water gun":{"count":209,"lastSeenTime":1577030861848,"publicGameCount":30,"difficulty":0.5,"difficultyWeight":210},"wealth":{"count":233,"lastSeenTime":1577035383092,"difficulty":0.6605504587155964,"difficultyWeight":109,"publicGameCount":8},"weapon":{"count":225,"lastSeenTime":1577017753478,"publicGameCount":11,"difficulty":0.5826086956521739,"difficultyWeight":115},"weasel":{"count":232,"lastSeenTime":1577033068320,"publicGameCount":2,"difficulty":0.6206896551724138,"difficultyWeight":29},"weather":{"count":432,"lastSeenTime":1577034546199,"publicGameCount":27,"difficulty":0.6148148148148149,"difficultyWeight":270},"web":{"count":233,"lastSeenTime":1577013555945,"difficulty":0.5690607734806631,"difficultyWeight":181,"publicGameCount":4},"website":{"count":248,"lastSeenTime":1577024636673,"publicGameCount":13,"difficulty":0.5413533834586465,"difficultyWeight":133},"well":{"count":475,"lastSeenTime":1577029578873,"difficulty":0.5381944444444444,"difficultyWeight":288,"publicGameCount":29},"whale":{"count":221,"lastSeenTime":1577031334229,"publicGameCount":8,"difficulty":0.5198237885462555,"difficultyWeight":227},"whistle":{"count":417,"lastSeenTime":1577032824600,"publicGameCount":30,"difficulty":0.5772357723577237,"difficultyWeight":246},"wind":{"count":461,"lastSeenTime":1577037632002,"publicGameCount":30,"difficulty":0.4868421052631579,"difficultyWeight":228},"window":{"count":199,"lastSeenTime":1576981481678,"difficulty":0.4585987261146497,"difficultyWeight":157,"publicGameCount":3},"wine":{"count":243,"lastSeenTime":1577025336889,"difficulty":0.5924170616113745,"difficultyWeight":211,"publicGameCount":6},"wine glass":{"count":244,"lastSeenTime":1577033780065,"difficulty":0.5617977528089888,"difficultyWeight":178,"publicGameCount":21},"wing":{"count":230,"lastSeenTime":1577032161683,"publicGameCount":10,"difficulty":0.49765258215962427,"difficultyWeight":213},"winner":{"count":242,"lastSeenTime":1577024591466,"publicGameCount":13,"difficulty":0.6145833333333331,"difficultyWeight":192},"winter":{"count":231,"lastSeenTime":1577008822217,"publicGameCount":12,"difficulty":0.6211180124223602,"difficultyWeight":161},"wire":{"count":223,"lastSeenTime":1577030325616,"difficulty":0.5864197530864198,"difficultyWeight":162,"publicGameCount":8},"wireless":{"count":207,"lastSeenTime":1577019386006,"publicGameCount":13,"difficulty":0.5511811023622047,"difficultyWeight":127},"wizard":{"count":227,"lastSeenTime":1577025827446,"publicGameCount":18,"difficulty":0.5347826086956522,"difficultyWeight":230},"wolf":{"count":214,"lastSeenTime":1577037141569,"difficulty":0.4649122807017544,"difficultyWeight":114,"publicGameCount":7},"wonderland":{"count":220,"lastSeenTime":1577018743300,"publicGameCount":6,"difficulty":0.6896551724137931,"difficultyWeight":58},"woodpecker":{"count":216,"lastSeenTime":1577016345341,"difficulty":0.569620253164557,"difficultyWeight":79,"publicGameCount":9},"wool":{"count":232,"lastSeenTime":1576994611979,"difficulty":0.6129032258064515,"difficultyWeight":124,"publicGameCount":8},"work":{"count":229,"lastSeenTime":1576981150242,"difficulty":0.6304347826086957,"difficultyWeight":46,"publicGameCount":3},"worm":{"count":227,"lastSeenTime":1577003987414,"difficulty":0.4336734693877551,"difficultyWeight":196,"publicGameCount":5},"wound":{"count":215,"lastSeenTime":1577019177354,"publicGameCount":5,"difficulty":0.6951219512195121,"difficultyWeight":82},"wrapping":{"count":235,"lastSeenTime":1577014911739,"difficulty":0.4473684210526316,"difficultyWeight":38,"publicGameCount":4},"wreath":{"count":256,"lastSeenTime":1577017849635,"publicGameCount":8,"difficulty":0.691358024691358,"difficultyWeight":81},"wrench":{"count":223,"lastSeenTime":1576997095980,"publicGameCount":10,"difficulty":0.626984126984127,"difficultyWeight":126},"wrestling":{"count":219,"lastSeenTime":1577004520443,"publicGameCount":6,"difficulty":0.6491228070175439,"difficultyWeight":57},"wrist":{"count":439,"lastSeenTime":1577035409514,"publicGameCount":37,"difficulty":0.570987654320988,"difficultyWeight":324},"x-ray":{"count":225,"lastSeenTime":1577011993887,"publicGameCount":11,"difficulty":0.6716417910447762,"difficultyWeight":67},"xylophone":{"count":400,"lastSeenTime":1577010272408,"publicGameCount":19,"difficulty":0.6440677966101697,"difficultyWeight":118},"yacht":{"count":244,"lastSeenTime":1576981974478,"publicGameCount":6,"difficulty":0.7032967032967034,"difficultyWeight":91},"yeti":{"count":256,"lastSeenTime":1577020536744,"publicGameCount":14,"difficulty":0.5061728395061729,"difficultyWeight":81},"yo-yo":{"count":217,"lastSeenTime":1577033946337,"publicGameCount":43,"difficulty":0.5562913907284768,"difficultyWeight":302},"yogurt":{"count":244,"lastSeenTime":1576996416399,"publicGameCount":15,"difficulty":0.6120689655172413,"difficultyWeight":116},"yolk":{"count":204,"lastSeenTime":1577007452649,"difficulty":0.5833333333333334,"difficultyWeight":168,"publicGameCount":6},"young":{"count":439,"lastSeenTime":1577034350570,"publicGameCount":23,"difficulty":0.5882352941176472,"difficultyWeight":187},"zebra":{"count":214,"lastSeenTime":1577036927354,"difficulty":0.5491329479768787,"difficultyWeight":173,"publicGameCount":8},"zigzag":{"count":212,"lastSeenTime":1577015524015,"publicGameCount":12,"difficulty":0.5777777777777777,"difficultyWeight":135},"zipper":{"count":226,"lastSeenTime":1577036426489,"publicGameCount":12,"difficulty":0.6111111111111112,"difficultyWeight":144},"zombie":{"count":226,"lastSeenTime":1577029617419,"publicGameCount":13,"difficulty":0.5555555555555556,"difficultyWeight":144},"zoom":{"count":241,"lastSeenTime":1577031155319,"difficulty":0.6518518518518519,"difficultyWeight":135,"publicGameCount":11},"W-LAN":{"count":226,"lastSeenTime":1577008267383,"publicGameCount":6,"difficulty":0.8909090909090909,"difficultyWeight":55},"cherry blossom":{"count":440,"lastSeenTime":1577035714898,"difficulty":0.73992673992674,"difficultyWeight":273,"publicGameCount":38},"Adidas":{"count":419,"lastSeenTime":1577035455493,"difficulty":0.5552560646900269,"difficultyWeight":371,"publicGameCount":44},"galaxy":{"count":212,"lastSeenTime":1577031856118,"publicGameCount":11,"difficulty":0.5359477124183007,"difficultyWeight":153},"procrastination":{"count":229,"lastSeenTime":1576986816477,"publicGameCount":4,"difficulty":0.8620689655172413,"difficultyWeight":29},"vote":{"count":226,"lastSeenTime":1577035372815,"difficulty":0.4365079365079365,"difficultyWeight":126,"publicGameCount":10},"burrito":{"count":252,"lastSeenTime":1577021253681,"publicGameCount":13,"difficulty":0.5094339622641509,"difficultyWeight":106},"snowflake":{"count":433,"lastSeenTime":1577037178254,"difficulty":0.5217391304347823,"difficultyWeight":437,"publicGameCount":56},"wheelbarrow":{"count":217,"lastSeenTime":1577012475718,"publicGameCount":11,"difficulty":0.735632183908046,"difficultyWeight":87},"Jesus Christ":{"count":418,"lastSeenTime":1577033680486,"publicGameCount":55,"difficulty":0.6112412177985944,"difficultyWeight":427},"Einstein":{"count":439,"lastSeenTime":1577035886295,"publicGameCount":20,"difficulty":0.6939890710382512,"difficultyWeight":183},"Porky Pig":{"count":440,"lastSeenTime":1577000593113,"publicGameCount":19,"difficulty":0.7152777777777778,"difficultyWeight":144},"chew":{"count":235,"lastSeenTime":1576996198033,"difficulty":0.5652173913043478,"difficultyWeight":69,"publicGameCount":8},"underground":{"count":450,"lastSeenTime":1577030347875,"publicGameCount":32,"difficulty":0.7522123893805309,"difficultyWeight":226},"China":{"count":449,"lastSeenTime":1577024929912,"difficulty":0.5127478753541076,"difficultyWeight":353,"publicGameCount":33},"Skrillex":{"count":425,"lastSeenTime":1577035161889,"publicGameCount":5,"difficulty":0.8163265306122449,"difficultyWeight":49},"dock":{"count":451,"lastSeenTime":1577031583222,"publicGameCount":22,"difficulty":0.6158192090395479,"difficultyWeight":177},"streamer":{"count":217,"lastSeenTime":1577020128841,"difficulty":0.711864406779661,"difficultyWeight":59,"publicGameCount":5},"gender":{"count":212,"lastSeenTime":1577034253534,"difficulty":0.6258064516129033,"difficultyWeight":155,"publicGameCount":7},"echo":{"count":237,"lastSeenTime":1577013787870,"publicGameCount":9,"difficulty":0.5774647887323944,"difficultyWeight":71},"MTV":{"count":455,"lastSeenTime":1577030172832,"publicGameCount":11,"difficulty":0.5478260869565218,"difficultyWeight":115},"Canada":{"count":441,"lastSeenTime":1577036000120,"publicGameCount":40,"difficulty":0.525974025974026,"difficultyWeight":308},"magic trick":{"count":205,"lastSeenTime":1577034200815,"publicGameCount":16,"difficulty":0.7281553398058253,"difficultyWeight":103},"SpongeBob":{"count":446,"lastSeenTime":1577033755621,"publicGameCount":58,"difficulty":0.49460043196544284,"difficultyWeight":463},"Spiderman":{"count":419,"lastSeenTime":1577032373261,"publicGameCount":45,"difficulty":0.5544303797468356,"difficultyWeight":395},"asymmetry":{"count":217,"lastSeenTime":1577016345341,"publicGameCount":3,"difficulty":0.6428571428571429,"difficultyWeight":28},"Monday":{"count":228,"lastSeenTime":1577033931737,"difficulty":0.596638655462185,"difficultyWeight":119,"publicGameCount":10},"Bomberman":{"count":428,"lastSeenTime":1577020774303,"publicGameCount":11,"difficulty":0.7474747474747475,"difficultyWeight":99},"Crash Bandicoot":{"count":430,"lastSeenTime":1577036416241,"publicGameCount":20,"difficulty":0.8106060606060606,"difficultyWeight":132},"firecracker":{"count":242,"lastSeenTime":1577019674312,"publicGameCount":19,"difficulty":0.7172413793103448,"difficultyWeight":145},"Usain Bolt":{"count":436,"lastSeenTime":1577035761130,"publicGameCount":30,"difficulty":0.7535545023696683,"difficultyWeight":211},"disease":{"count":246,"lastSeenTime":1577019036151,"publicGameCount":5,"difficulty":0.8181818181818182,"difficultyWeight":77},"adult":{"count":221,"lastSeenTime":1577007668912,"publicGameCount":9,"difficulty":0.5254237288135593,"difficultyWeight":118},"slump":{"count":217,"lastSeenTime":1577036268892,"publicGameCount":2,"difficulty":0.7916666666666666,"difficultyWeight":24},"Pink Panther":{"count":449,"lastSeenTime":1577012155351,"publicGameCount":35,"difficulty":0.7,"difficultyWeight":230},"jester":{"count":230,"lastSeenTime":1577034315724,"publicGameCount":5,"difficulty":0.75,"difficultyWeight":48},"Wall-e":{"count":465,"lastSeenTime":1577033283809,"publicGameCount":27,"difficulty":0.6528497409326426,"difficultyWeight":193},"rat":{"count":245,"lastSeenTime":1576993659400,"difficulty":0.5144508670520233,"difficultyWeight":173,"publicGameCount":3},"ballet":{"count":235,"lastSeenTime":1577031644668,"publicGameCount":6,"difficulty":0.6391752577319587,"difficultyWeight":97},"writer":{"count":227,"lastSeenTime":1577024525038,"difficulty":0.8271604938271605,"difficultyWeight":81,"publicGameCount":6},"Android":{"count":425,"lastSeenTime":1577015388643,"publicGameCount":36,"difficulty":0.5247148288973384,"difficultyWeight":263},"Cupid":{"count":210,"lastSeenTime":1576983598019,"difficulty":0.4621212121212121,"difficultyWeight":132,"publicGameCount":14},"headband":{"count":237,"lastSeenTime":1577035544830,"publicGameCount":12,"difficulty":0.6435643564356436,"difficultyWeight":101},"alligator":{"count":106,"lastSeenTime":1576870146221,"publicGameCount":5,"difficulty":0.7339449541284404,"difficultyWeight":109},"foil":{"count":230,"lastSeenTime":1577030677699,"publicGameCount":3,"difficulty":0.5833333333333334,"difficultyWeight":48},"Lego":{"count":198,"lastSeenTime":1577029947635,"publicGameCount":21,"difficulty":0.5340501792114697,"difficultyWeight":279},"text":{"count":231,"lastSeenTime":1577032283871,"publicGameCount":13,"difficulty":0.518796992481203,"difficultyWeight":133},"Mona Lisa":{"count":235,"lastSeenTime":1576996381190,"publicGameCount":12,"difficulty":0.6886792452830188,"difficultyWeight":106},"Zorro":{"count":449,"lastSeenTime":1577025402030,"publicGameCount":13,"difficulty":0.753968253968254,"difficultyWeight":126},"Teletubby":{"count":428,"lastSeenTime":1577031672748,"publicGameCount":30,"difficulty":0.7336065573770493,"difficultyWeight":244},"social media":{"count":242,"lastSeenTime":1577020474773,"publicGameCount":21,"difficulty":0.6942675159235668,"difficultyWeight":157},"skin":{"count":417,"lastSeenTime":1577024168827,"difficulty":0.5833333333333333,"difficultyWeight":216,"publicGameCount":26},"WhatsApp":{"count":460,"lastSeenTime":1577037070414,"publicGameCount":29,"difficulty":0.6506024096385542,"difficultyWeight":249},"Easter":{"count":211,"lastSeenTime":1577007198808,"difficulty":0.6521739130434782,"difficultyWeight":184,"publicGameCount":6},"gasp":{"count":208,"lastSeenTime":1576992767532,"publicGameCount":7,"difficulty":0.6097560975609755,"difficultyWeight":82},"east":{"count":463,"lastSeenTime":1577015121316,"publicGameCount":26,"difficulty":0.5,"difficultyWeight":246},"Finn and Jake":{"count":483,"lastSeenTime":1577032113038,"publicGameCount":36,"difficulty":0.7665369649805448,"difficultyWeight":257},"Robin Hood":{"count":411,"lastSeenTime":1577009740704,"publicGameCount":26,"difficulty":0.6616915422885573,"difficultyWeight":201},"mammoth":{"count":204,"lastSeenTime":1577019236659,"publicGameCount":12,"difficulty":0.6762589928057554,"difficultyWeight":139},"kitchen":{"count":267,"lastSeenTime":1577024859631,"publicGameCount":12,"difficulty":0.6115702479338843,"difficultyWeight":121},"armadillo":{"count":222,"lastSeenTime":1577020587743,"difficulty":0.7446808510638298,"difficultyWeight":47,"publicGameCount":5},"Mexico":{"count":440,"lastSeenTime":1577035187744,"publicGameCount":29,"difficulty":0.5258620689655171,"difficultyWeight":232},"deep":{"count":428,"lastSeenTime":1577016799930,"publicGameCount":24,"difficulty":0.558252427184466,"difficultyWeight":206},"leprechaun":{"count":204,"lastSeenTime":1577019066716,"publicGameCount":12,"difficulty":0.6869565217391305,"difficultyWeight":115},"Lasagna":{"count":210,"lastSeenTime":1576951729940,"publicGameCount":13,"difficulty":0.7452830188679245,"difficultyWeight":106},"fire alarm":{"count":228,"lastSeenTime":1577033530627,"publicGameCount":21,"difficulty":0.618421052631579,"difficultyWeight":152},"Kim Jong-un":{"count":440,"lastSeenTime":1577037056234,"publicGameCount":31,"difficulty":0.782051282051282,"difficultyWeight":234},"Uranus":{"count":228,"lastSeenTime":1577019226526,"publicGameCount":10,"difficulty":0.5384615384615384,"difficultyWeight":117},"internet":{"count":215,"lastSeenTime":1577034401652,"difficulty":0.6408839779005526,"difficultyWeight":181,"publicGameCount":14},"chimpanzee":{"count":222,"lastSeenTime":1577035508304,"publicGameCount":10,"difficulty":0.6304347826086957,"difficultyWeight":92},"Chuck Norris":{"count":436,"lastSeenTime":1577014177490,"difficulty":0.6923076923076923,"difficultyWeight":91,"publicGameCount":10},"Tower Bridge":{"count":428,"lastSeenTime":1577020501514,"publicGameCount":24,"difficulty":0.7116564417177914,"difficultyWeight":163},"controller":{"count":222,"lastSeenTime":1577036426489,"publicGameCount":28,"difficulty":0.5714285714285714,"difficultyWeight":217},"neck":{"count":438,"lastSeenTime":1577034571183,"publicGameCount":27,"difficulty":0.4730158730158731,"difficultyWeight":315},"donkey":{"count":207,"lastSeenTime":1577018979029,"difficulty":0.5126050420168069,"difficultyWeight":119,"publicGameCount":4},"superpower":{"count":193,"lastSeenTime":1577035654185,"publicGameCount":12,"difficulty":0.7425742574257426,"difficultyWeight":101},"Mr Bean":{"count":207,"lastSeenTime":1577025104122,"publicGameCount":14,"difficulty":0.8378378378378378,"difficultyWeight":111},"trick shot":{"count":218,"lastSeenTime":1577032198145,"publicGameCount":11,"difficulty":0.7,"difficultyWeight":80},"John Cena":{"count":424,"lastSeenTime":1577037653341,"difficulty":0.6901408450704225,"difficultyWeight":213,"publicGameCount":29},"catfish":{"count":221,"lastSeenTime":1577024677438,"difficulty":0.5720524017467249,"difficultyWeight":229,"publicGameCount":16},"bobsled":{"count":204,"lastSeenTime":1577036169423,"difficulty":0.6774193548387096,"difficultyWeight":31,"publicGameCount":2},"bamboo":{"count":460,"lastSeenTime":1577033619352,"publicGameCount":31,"difficulty":0.6079999999999999,"difficultyWeight":250},"Lion King":{"count":468,"lastSeenTime":1577033322479,"publicGameCount":41,"difficulty":0.7075471698113207,"difficultyWeight":318},"periscope":{"count":209,"lastSeenTime":1577008232089,"publicGameCount":7,"difficulty":0.813953488372093,"difficultyWeight":86},"generator":{"count":229,"lastSeenTime":1576999434864,"publicGameCount":6,"difficulty":0.6527777777777778,"difficultyWeight":72},"roadblock":{"count":460,"lastSeenTime":1577034071183,"publicGameCount":19,"difficulty":0.7412587412587412,"difficultyWeight":143},"licorice":{"count":234,"lastSeenTime":1577001733732,"publicGameCount":9,"difficulty":0.734375,"difficultyWeight":64},"Phineas and Ferb":{"count":420,"lastSeenTime":1577035297722,"publicGameCount":34,"difficulty":0.7578125,"difficultyWeight":256},"binoculars":{"count":212,"lastSeenTime":1577025537901,"publicGameCount":15,"difficulty":0.6783216783216783,"difficultyWeight":143},"Finn":{"count":437,"lastSeenTime":1577026115551,"publicGameCount":20,"difficulty":0.6614583333333335,"difficultyWeight":192},"workplace":{"count":229,"lastSeenTime":1577016914668,"publicGameCount":13,"difficulty":0.6212121212121212,"difficultyWeight":132},"bartender":{"count":247,"lastSeenTime":1577003628703,"difficulty":0.6029411764705882,"difficultyWeight":68,"publicGameCount":8},"Norway":{"count":425,"lastSeenTime":1577033058121,"publicGameCount":15,"difficulty":0.7062937062937062,"difficultyWeight":143},"collapse":{"count":201,"lastSeenTime":1577007012836,"publicGameCount":4,"difficulty":0.825,"difficultyWeight":40},"waffle":{"count":202,"lastSeenTime":1577019674312,"difficulty":0.57487922705314,"difficultyWeight":207,"publicGameCount":16},"Asia":{"count":444,"lastSeenTime":1577036527277,"publicGameCount":26,"difficulty":0.5278969957081544,"difficultyWeight":233},"whisk":{"count":222,"lastSeenTime":1577034425936,"difficulty":0.7088607594936709,"difficultyWeight":79,"publicGameCount":3},"gangster":{"count":210,"lastSeenTime":1577020985528,"publicGameCount":12,"difficulty":0.7256637168141593,"difficultyWeight":113},"Monster":{"count":218,"lastSeenTime":1577032236778,"difficulty":0.6518987341772153,"difficultyWeight":158,"publicGameCount":5},"employer":{"count":229,"lastSeenTime":1577015285487,"difficulty":0.7619047619047619,"difficultyWeight":42,"publicGameCount":4},"Obelix":{"count":444,"lastSeenTime":1577036872584,"difficulty":0.7088607594936709,"difficultyWeight":79,"publicGameCount":6},"Jimmy Neutron":{"count":423,"lastSeenTime":1577035494111,"publicGameCount":25,"difficulty":0.7925531914893617,"difficultyWeight":188},"mold":{"count":209,"lastSeenTime":1577019997716,"difficulty":0.5647058823529412,"difficultyWeight":85,"publicGameCount":7},"motorcycle":{"count":232,"lastSeenTime":1577018362555,"publicGameCount":19,"difficulty":0.5727272727272728,"difficultyWeight":110},"Spartacus":{"count":461,"lastSeenTime":1577032469364,"publicGameCount":9,"difficulty":0.8588235294117647,"difficultyWeight":85},"Portugal":{"count":418,"lastSeenTime":1577034642507,"difficulty":0.6595744680851063,"difficultyWeight":94,"publicGameCount":10},"laboratory":{"count":391,"lastSeenTime":1577036081186,"publicGameCount":14,"difficulty":0.7744360902255639,"difficultyWeight":133},"Paypal":{"count":482,"lastSeenTime":1577033043901,"publicGameCount":28,"difficulty":0.6093023255813952,"difficultyWeight":215},"fireproof":{"count":444,"lastSeenTime":1577035216186,"publicGameCount":22,"difficulty":0.6963350785340315,"difficultyWeight":191},"toe":{"count":438,"lastSeenTime":1577020301493,"difficulty":0.5583596214511038,"difficultyWeight":317,"publicGameCount":20},"Thor":{"count":447,"lastSeenTime":1577036081186,"publicGameCount":35,"difficulty":0.5119453924914675,"difficultyWeight":293},"Chewbacca":{"count":448,"lastSeenTime":1577034033521,"difficulty":0.7142857142857143,"difficultyWeight":182,"publicGameCount":19},"referee":{"count":258,"lastSeenTime":1577021339910,"publicGameCount":8,"difficulty":0.7931034482758621,"difficultyWeight":87},"dress":{"count":244,"lastSeenTime":1577034593673,"publicGameCount":8,"difficulty":0.5238095238095237,"difficultyWeight":147},"guitar":{"count":421,"lastSeenTime":1577011431541,"difficulty":0.4467005076142132,"difficultyWeight":394,"publicGameCount":40},"allergy":{"count":213,"lastSeenTime":1577016886171,"difficulty":0.6851851851851852,"difficultyWeight":108,"publicGameCount":12},"Olaf":{"count":420,"lastSeenTime":1577018155425,"publicGameCount":41,"difficulty":0.5478260869565222,"difficultyWeight":345},"Mount Everest":{"count":455,"lastSeenTime":1577037226802,"publicGameCount":48,"difficulty":0.6486486486486484,"difficultyWeight":333},"vertical":{"count":229,"lastSeenTime":1577029784063,"difficulty":0.6349206349206349,"difficultyWeight":63,"publicGameCount":6},"aircraft":{"count":221,"lastSeenTime":1576999516005,"publicGameCount":9,"difficulty":0.7647058823529411,"difficultyWeight":102},"Atlantis":{"count":265,"lastSeenTime":1577007329399,"publicGameCount":5,"difficulty":0.6857142857142857,"difficultyWeight":35},"archer":{"count":239,"lastSeenTime":1577015985232,"publicGameCount":13,"difficulty":0.6666666666666666,"difficultyWeight":150},"toolbox":{"count":226,"lastSeenTime":1577034689603,"publicGameCount":9,"difficulty":0.5882352941176471,"difficultyWeight":119},"hyena":{"count":223,"lastSeenTime":1577032763018,"difficulty":0.8,"difficultyWeight":45,"publicGameCount":5},"pipe":{"count":238,"lastSeenTime":1576991278078,"publicGameCount":10,"difficulty":0.5579710144927537,"difficultyWeight":138},"undo":{"count":235,"lastSeenTime":1577000929474,"publicGameCount":11,"difficulty":0.627906976744186,"difficultyWeight":86},"reindeer":{"count":231,"lastSeenTime":1577019605874,"publicGameCount":13,"difficulty":0.5537190082644629,"difficultyWeight":121},"NASCAR":{"count":245,"lastSeenTime":1576996365789,"publicGameCount":7,"difficulty":0.5510204081632653,"difficultyWeight":49},"cousin":{"count":222,"lastSeenTime":1577018410162,"publicGameCount":7,"difficulty":0.6588235294117646,"difficultyWeight":85},"Big Ben":{"count":438,"lastSeenTime":1577034239310,"publicGameCount":33,"difficulty":0.7066115702479339,"difficultyWeight":242},"dome":{"count":208,"lastSeenTime":1577034022367,"publicGameCount":7,"difficulty":0.546875,"difficultyWeight":64},"coast":{"count":429,"lastSeenTime":1577030043413,"publicGameCount":18,"difficulty":0.6211180124223602,"difficultyWeight":161},"whisper":{"count":268,"lastSeenTime":1576989329890,"publicGameCount":18,"difficulty":0.6106870229007634,"difficultyWeight":131},"coyote":{"count":207,"lastSeenTime":1577018818664,"publicGameCount":2,"difficulty":0.5833333333333334,"difficultyWeight":36},"sting":{"count":206,"lastSeenTime":1577036825894,"difficulty":0.6981132075471698,"difficultyWeight":106,"publicGameCount":7},"dig":{"count":200,"lastSeenTime":1577020587743,"difficulty":0.484375,"difficultyWeight":128,"publicGameCount":4},"cowboy":{"count":228,"lastSeenTime":1577019636661,"difficulty":0.5691056910569106,"difficultyWeight":123,"publicGameCount":8},"vaccine":{"count":248,"lastSeenTime":1577015499271,"difficulty":0.5757575757575758,"difficultyWeight":99,"publicGameCount":11},"piano":{"count":476,"lastSeenTime":1577011647836,"difficulty":0.5481727574750831,"difficultyWeight":301,"publicGameCount":32},"ceiling":{"count":218,"lastSeenTime":1576998592191,"difficulty":0.5463917525773195,"difficultyWeight":97,"publicGameCount":6},"marigold":{"count":455,"lastSeenTime":1577032676999,"publicGameCount":9,"difficulty":0.865979381443299,"difficultyWeight":97},"map":{"count":471,"lastSeenTime":1577012475718,"difficulty":0.5310880829015544,"difficultyWeight":386,"publicGameCount":38},"Squidward":{"count":397,"lastSeenTime":1577034713991,"difficulty":0.5569620253164557,"difficultyWeight":237,"publicGameCount":34},"Beethoven":{"count":430,"lastSeenTime":1577011492557,"publicGameCount":9,"difficulty":0.7931034482758621,"difficultyWeight":87},"Colosseum":{"count":421,"lastSeenTime":1577030433295,"publicGameCount":19,"difficulty":0.808641975308642,"difficultyWeight":162},"touch":{"count":233,"lastSeenTime":1577025841683,"publicGameCount":6,"difficulty":0.5443037974683544,"difficultyWeight":79},"Kung Fu":{"count":193,"lastSeenTime":1577036000120,"publicGameCount":17,"difficulty":0.7520661157024794,"difficultyWeight":121},"canister":{"count":239,"lastSeenTime":1577016031951,"publicGameCount":5,"difficulty":0.71875,"difficultyWeight":32},"Youtube":{"count":438,"lastSeenTime":1577025214850,"publicGameCount":65,"difficulty":0.4058919803600655,"difficultyWeight":611},"goat":{"count":246,"lastSeenTime":1577026115551,"publicGameCount":12,"difficulty":0.6174863387978142,"difficultyWeight":183},"customer":{"count":220,"lastSeenTime":1577030262784,"publicGameCount":7,"difficulty":0.611764705882353,"difficultyWeight":85},"France":{"count":427,"lastSeenTime":1577030951342,"difficulty":0.6213592233009708,"difficultyWeight":309,"publicGameCount":33},"country":{"count":442,"lastSeenTime":1577016173491,"publicGameCount":26,"difficulty":0.6933333333333332,"difficultyWeight":225},"mannequin":{"count":222,"lastSeenTime":1576999022677,"difficulty":0.75,"difficultyWeight":60,"publicGameCount":5},"Harry Potter":{"count":465,"lastSeenTime":1577037131444,"publicGameCount":59,"difficulty":0.6574712643678161,"difficultyWeight":435},"risk":{"count":221,"lastSeenTime":1577030937070,"publicGameCount":6,"difficulty":0.6206896551724138,"difficultyWeight":58},"walk":{"count":223,"lastSeenTime":1577009740704,"publicGameCount":8,"difficulty":0.6232876712328766,"difficultyWeight":146},"delivery":{"count":235,"lastSeenTime":1577035937353,"publicGameCount":9,"difficulty":0.5316455696202531,"difficultyWeight":79},"roof":{"count":223,"lastSeenTime":1577017800715,"publicGameCount":8,"difficulty":0.5000000000000001,"difficultyWeight":134},"Steam":{"count":216,"lastSeenTime":1576990865256,"publicGameCount":13,"difficulty":0.6232876712328768,"difficultyWeight":146},"Argentina":{"count":411,"lastSeenTime":1577032857353,"publicGameCount":12,"difficulty":0.5480769230769231,"difficultyWeight":104},"Iron Giant":{"count":202,"lastSeenTime":1577024820240,"publicGameCount":6,"difficulty":0.631578947368421,"difficultyWeight":38},"bookshelf":{"count":232,"lastSeenTime":1576991898546,"difficulty":0.639751552795031,"difficultyWeight":161,"publicGameCount":16},"Pepsi":{"count":436,"lastSeenTime":1577030530959,"publicGameCount":54,"difficulty":0.5100401606425703,"difficultyWeight":498},"cringe":{"count":230,"lastSeenTime":1577032123143,"difficulty":0.7586206896551724,"difficultyWeight":87,"publicGameCount":10},"Greece":{"count":476,"lastSeenTime":1577036927354,"publicGameCount":16,"difficulty":0.7133333333333334,"difficultyWeight":150},"Mozart":{"count":450,"lastSeenTime":1577019721923,"difficulty":0.7525773195876289,"difficultyWeight":97,"publicGameCount":9},"popular":{"count":413,"lastSeenTime":1577015274772,"publicGameCount":24,"difficulty":0.64804469273743,"difficultyWeight":179},"repeat":{"count":233,"lastSeenTime":1577013811336,"publicGameCount":4,"difficulty":0.6,"difficultyWeight":40},"pub":{"count":404,"lastSeenTime":1577035975818,"difficulty":0.550561797752809,"difficultyWeight":89,"publicGameCount":7},"spatula":{"count":243,"lastSeenTime":1577032161683,"publicGameCount":14,"difficulty":0.5193798449612403,"difficultyWeight":129},"skyline":{"count":406,"lastSeenTime":1577026064542,"publicGameCount":16,"difficulty":0.6981132075471698,"difficultyWeight":159},"frosting":{"count":248,"lastSeenTime":1577032591482,"difficulty":0.6595744680851063,"difficultyWeight":47,"publicGameCount":4},"Saturn":{"count":210,"lastSeenTime":1577018276584,"difficulty":0.5662650602409639,"difficultyWeight":166,"publicGameCount":8},"dew":{"count":437,"lastSeenTime":1577037446644,"publicGameCount":14,"difficulty":0.7265625000000001,"difficultyWeight":128},"lane":{"count":442,"lastSeenTime":1577020835639,"publicGameCount":16,"difficulty":0.622093023255814,"difficultyWeight":172},"garden":{"count":213,"lastSeenTime":1577009379377,"publicGameCount":11,"difficulty":0.6793893129770993,"difficultyWeight":131},"boil":{"count":229,"lastSeenTime":1577003346224,"difficulty":0.6428571428571429,"difficultyWeight":70,"publicGameCount":2},"Katy Perry":{"count":476,"lastSeenTime":1577034044177,"publicGameCount":22,"difficulty":0.7421383647798742,"difficultyWeight":159},"blush":{"count":194,"lastSeenTime":1576993062459,"difficulty":0.664179104477612,"difficultyWeight":134,"publicGameCount":3},"London":{"count":418,"lastSeenTime":1577034315724,"publicGameCount":20,"difficulty":0.6163522012578618,"difficultyWeight":159},"religion":{"count":221,"lastSeenTime":1576985623739,"difficulty":0.6605504587155964,"difficultyWeight":109,"publicGameCount":7},"waiter":{"count":237,"lastSeenTime":1577025115050,"publicGameCount":9,"difficulty":0.6140350877192982,"difficultyWeight":114},"brainwash":{"count":225,"lastSeenTime":1577010201020,"publicGameCount":10,"difficulty":0.7428571428571429,"difficultyWeight":70},"Cuba":{"count":452,"lastSeenTime":1577029900661,"difficulty":0.6533333333333333,"difficultyWeight":150,"publicGameCount":13},"Earth":{"count":220,"lastSeenTime":1577034376972,"publicGameCount":7,"difficulty":0.5,"difficultyWeight":196},"antenna":{"count":211,"lastSeenTime":1577024317066,"difficulty":0.611764705882353,"difficultyWeight":85,"publicGameCount":6},"goatee":{"count":214,"lastSeenTime":1577037472968,"difficulty":0.6857142857142857,"difficultyWeight":140,"publicGameCount":8},"grumpy":{"count":229,"lastSeenTime":1576993128309,"publicGameCount":15,"difficulty":0.6027397260273972,"difficultyWeight":146},"gravel":{"count":224,"lastSeenTime":1576931267636,"difficulty":0.6923076923076923,"difficultyWeight":39,"publicGameCount":3},"kendama":{"count":210,"lastSeenTime":1577033694684,"difficulty":0.8518518518518519,"difficultyWeight":27,"publicGameCount":2},"peninsula":{"count":450,"lastSeenTime":1577036463485,"publicGameCount":18,"difficulty":0.7941176470588235,"difficultyWeight":136},"windshield":{"count":226,"lastSeenTime":1577032037095,"publicGameCount":9,"difficulty":0.6,"difficultyWeight":70},"Vault boy":{"count":414,"lastSeenTime":1577031409078,"publicGameCount":19,"difficulty":0.831081081081081,"difficultyWeight":148},"stork":{"count":240,"lastSeenTime":1577013987614,"difficulty":0.8157894736842105,"difficultyWeight":76,"publicGameCount":4},"fake teeth":{"count":239,"lastSeenTime":1577009881239,"publicGameCount":12,"difficulty":0.7244897959183674,"difficultyWeight":98},"croissant":{"count":246,"lastSeenTime":1577037436536,"publicGameCount":16,"difficulty":0.6287878787878788,"difficultyWeight":132},"Deadpool":{"count":483,"lastSeenTime":1577037131444,"publicGameCount":44,"difficulty":0.6242424242424244,"difficultyWeight":330},"Santa":{"count":439,"lastSeenTime":1577032334398,"publicGameCount":48,"difficulty":0.4295774647887324,"difficultyWeight":426},"cornfield":{"count":214,"lastSeenTime":1576962903510,"publicGameCount":5,"difficulty":0.7368421052631579,"difficultyWeight":57},"engineer":{"count":240,"lastSeenTime":1577030702095,"difficulty":0.7432432432432432,"difficultyWeight":74,"publicGameCount":8},"Vatican":{"count":447,"lastSeenTime":1577030072028,"difficulty":0.8425925925925926,"difficultyWeight":108,"publicGameCount":10},"reptile":{"count":226,"lastSeenTime":1577033143595,"publicGameCount":12,"difficulty":0.6161616161616161,"difficultyWeight":99},"camping":{"count":236,"lastSeenTime":1577026107044,"difficulty":0.5592105263157896,"difficultyWeight":152,"publicGameCount":14},"slope":{"count":219,"lastSeenTime":1577012339365,"publicGameCount":9,"difficulty":0.6938775510204082,"difficultyWeight":98},"Japan":{"count":455,"lastSeenTime":1577036248643,"publicGameCount":34,"difficulty":0.5085910652920962,"difficultyWeight":291},"sausage":{"count":225,"lastSeenTime":1577030096351,"difficulty":0.6194690265486725,"difficultyWeight":113,"publicGameCount":7},"fort":{"count":424,"lastSeenTime":1577015311021,"publicGameCount":23,"difficulty":0.5555555555555556,"difficultyWeight":234},"sunrise":{"count":200,"lastSeenTime":1577029639639,"difficulty":0.5465838509316772,"difficultyWeight":322,"publicGameCount":15},"nature":{"count":433,"lastSeenTime":1577034728271,"publicGameCount":22,"difficulty":0.597989949748744,"difficultyWeight":199},"shotgun":{"count":214,"lastSeenTime":1577025827446,"publicGameCount":18,"difficulty":0.5837320574162679,"difficultyWeight":209},"poison":{"count":252,"lastSeenTime":1577033322479,"difficulty":0.5458167330677292,"difficultyWeight":251,"publicGameCount":24},"Stone Age":{"count":198,"lastSeenTime":1576983573415,"publicGameCount":11,"difficulty":0.7142857142857143,"difficultyWeight":84},"sleep":{"count":240,"lastSeenTime":1577036801585,"difficulty":0.421875,"difficultyWeight":192,"publicGameCount":8},"headphones":{"count":214,"lastSeenTime":1577014657759,"publicGameCount":23,"difficulty":0.41578947368421054,"difficultyWeight":190},"jail":{"count":467,"lastSeenTime":1577029725408,"publicGameCount":54,"difficulty":0.5081374321880653,"difficultyWeight":553},"welder":{"count":243,"lastSeenTime":1577025975223,"difficulty":0.5636363636363637,"difficultyWeight":55,"publicGameCount":3},"Dracula":{"count":488,"lastSeenTime":1577036441110,"publicGameCount":28,"difficulty":0.7103174603174605,"difficultyWeight":252},"scuba":{"count":217,"lastSeenTime":1577029784063,"publicGameCount":2,"difficulty":0.7105263157894737,"difficultyWeight":38},"Lady Gaga":{"count":466,"lastSeenTime":1577030433295,"publicGameCount":17,"difficulty":0.8103448275862069,"difficultyWeight":116},"firefly":{"count":212,"lastSeenTime":1577030616301,"publicGameCount":9,"difficulty":0.8064516129032258,"difficultyWeight":93},"Audi":{"count":410,"lastSeenTime":1577019350603,"publicGameCount":32,"difficulty":0.5954198473282444,"difficultyWeight":262},"espresso":{"count":235,"lastSeenTime":1577029664662,"publicGameCount":8,"difficulty":0.7,"difficultyWeight":70},"Neptune":{"count":208,"lastSeenTime":1577024220453,"publicGameCount":6,"difficulty":0.5616438356164384,"difficultyWeight":73},"leather":{"count":198,"lastSeenTime":1577012388447,"difficulty":0.6190476190476191,"difficultyWeight":63,"publicGameCount":4},"zeppelin":{"count":252,"lastSeenTime":1576998517639,"publicGameCount":2,"difficulty":0.8846153846153846,"difficultyWeight":26},"slingshot":{"count":221,"lastSeenTime":1577002117401,"difficulty":0.5874125874125874,"difficultyWeight":143,"publicGameCount":12},"lily":{"count":414,"lastSeenTime":1577018600637,"publicGameCount":18,"difficulty":0.6296296296296295,"difficultyWeight":189},"Russia":{"count":403,"lastSeenTime":1577007668912,"publicGameCount":36,"difficulty":0.5555555555555556,"difficultyWeight":270},"pro":{"count":217,"lastSeenTime":1577033163970,"difficulty":0.6384615384615384,"difficultyWeight":130,"publicGameCount":10},"cicada":{"count":225,"lastSeenTime":1577020190238,"difficulty":1,"difficultyWeight":4},"Statue of Liberty":{"count":407,"lastSeenTime":1577037436536,"publicGameCount":41,"difficulty":0.7395498392282959,"difficultyWeight":311},"kettle":{"count":221,"lastSeenTime":1577013531039,"difficulty":0.5862068965517241,"difficultyWeight":87,"publicGameCount":4},"Europe":{"count":441,"lastSeenTime":1576997288948,"publicGameCount":17,"difficulty":0.6690647482014388,"difficultyWeight":139},"flight attendant":{"count":226,"lastSeenTime":1576996198033,"publicGameCount":5,"difficulty":0.8518518518518519,"difficultyWeight":27},"election":{"count":243,"lastSeenTime":1577030802925,"publicGameCount":2,"difficulty":0.75,"difficultyWeight":20},"origami":{"count":221,"lastSeenTime":1577036195110,"difficulty":0.6323529411764706,"difficultyWeight":68,"publicGameCount":4},"hill":{"count":388,"lastSeenTime":1577032246891,"publicGameCount":25,"difficulty":0.5357142857142856,"difficultyWeight":336},"continent":{"count":444,"lastSeenTime":1577032459097,"publicGameCount":19,"difficulty":0.7062937062937062,"difficultyWeight":143},"soldier":{"count":202,"lastSeenTime":1577015835147,"publicGameCount":13,"difficulty":0.631578947368421,"difficultyWeight":114},"Home Alone":{"count":210,"lastSeenTime":1577035297722,"publicGameCount":9,"difficulty":0.7285714285714285,"difficultyWeight":70},"antelope":{"count":225,"lastSeenTime":1577029650059,"difficulty":0.8,"difficultyWeight":55,"publicGameCount":4},"Cat Woman":{"count":464,"lastSeenTime":1577031259619,"publicGameCount":32,"difficulty":0.70995670995671,"difficultyWeight":231},"Captain America":{"count":456,"lastSeenTime":1577016789684,"difficulty":0.736318407960199,"difficultyWeight":402,"publicGameCount":51},"Intel":{"count":424,"lastSeenTime":1577020636784,"publicGameCount":9,"difficulty":0.7011494252873564,"difficultyWeight":87},"Eiffel tower":{"count":443,"lastSeenTime":1577037426426,"publicGameCount":57,"difficulty":0.6568627450980392,"difficultyWeight":408},"betray":{"count":257,"lastSeenTime":1577024830624,"difficulty":0.7142857142857143,"difficultyWeight":7},"duck":{"count":233,"lastSeenTime":1577018661849,"publicGameCount":4,"difficulty":0.4019607843137255,"difficultyWeight":204},"piggy bank":{"count":222,"lastSeenTime":1576996012229,"difficulty":0.5433526011560693,"difficultyWeight":173,"publicGameCount":24},"skunk":{"count":222,"lastSeenTime":1577035656351,"publicGameCount":4,"difficulty":0.6515151515151515,"difficultyWeight":66},"Pluto":{"count":414,"lastSeenTime":1577011956828,"publicGameCount":28,"difficulty":0.5,"difficultyWeight":240},"Tarzan":{"count":452,"lastSeenTime":1577032787613,"publicGameCount":27,"difficulty":0.5119617224880384,"difficultyWeight":209},"God":{"count":233,"lastSeenTime":1577000522384,"difficulty":0.558139534883721,"difficultyWeight":215,"publicGameCount":9},"acid":{"count":233,"lastSeenTime":1577025190112,"publicGameCount":9,"difficulty":0.6190476190476191,"difficultyWeight":84},"bed bug":{"count":201,"lastSeenTime":1577010496834,"publicGameCount":15,"difficulty":0.7024793388429752,"difficultyWeight":121},"Oreo":{"count":221,"lastSeenTime":1576982169774,"publicGameCount":18,"difficulty":0.5063829787234041,"difficultyWeight":235},"freckles":{"count":440,"lastSeenTime":1577017628796,"publicGameCount":34,"difficulty":0.6876876876876877,"difficultyWeight":333},"chemical":{"count":206,"lastSeenTime":1577009379377,"publicGameCount":19,"difficulty":0.6948051948051948,"difficultyWeight":154},"tissue":{"count":215,"lastSeenTime":1577033719031,"publicGameCount":10,"difficulty":0.5873015873015873,"difficultyWeight":126},"mantis":{"count":230,"lastSeenTime":1577019187643,"publicGameCount":5,"difficulty":0.7536231884057971,"difficultyWeight":69},"clarinet":{"count":459,"lastSeenTime":1577025827446,"publicGameCount":20,"difficulty":0.7298850574712644,"difficultyWeight":174},"tunnel":{"count":460,"lastSeenTime":1577030520806,"difficulty":0.617363344051447,"difficultyWeight":311,"publicGameCount":36},"knot":{"count":231,"lastSeenTime":1577010323756,"publicGameCount":10,"difficulty":0.5918367346938775,"difficultyWeight":98},"Nintendo Switch":{"count":466,"lastSeenTime":1577018696562,"publicGameCount":59,"difficulty":0.6941176470588233,"difficultyWeight":425},"shallow":{"count":429,"lastSeenTime":1577036225894,"difficulty":0.7966101694915254,"difficultyWeight":59,"publicGameCount":7},"cobra":{"count":210,"lastSeenTime":1577037103049,"publicGameCount":15,"difficulty":0.5228758169934641,"difficultyWeight":153},"Yoshi":{"count":454,"lastSeenTime":1577031807616,"publicGameCount":36,"difficulty":0.6470588235294118,"difficultyWeight":272},"drip":{"count":215,"lastSeenTime":1577029872241,"difficulty":0.5471698113207547,"difficultyWeight":106,"publicGameCount":4},"BMX":{"count":229,"lastSeenTime":1577034081969,"publicGameCount":10,"difficulty":0.5675675675675675,"difficultyWeight":74},"North Korea":{"count":435,"lastSeenTime":1577035387934,"publicGameCount":31,"difficulty":0.7624521072796935,"difficultyWeight":261},"crowbar":{"count":249,"lastSeenTime":1577033092734,"publicGameCount":10,"difficulty":0.7391304347826086,"difficultyWeight":92},"Mummy":{"count":233,"lastSeenTime":1577025742812,"publicGameCount":10,"difficulty":0.6275862068965518,"difficultyWeight":145},"space suit":{"count":228,"lastSeenTime":1577009327318,"publicGameCount":11,"difficulty":0.611764705882353,"difficultyWeight":85},"Jack-o-lantern":{"count":210,"lastSeenTime":1576945758832,"publicGameCount":23,"difficulty":0.6624203821656052,"difficultyWeight":157},"meerkat":{"count":234,"lastSeenTime":1577024712891,"publicGameCount":2,"difficulty":0.7586206896551724,"difficultyWeight":29},"Sonic":{"count":415,"lastSeenTime":1577037627992,"difficulty":0.5281501340482575,"difficultyWeight":373,"publicGameCount":36},"Fred Flintstone":{"count":437,"lastSeenTime":1577031871352,"publicGameCount":14,"difficulty":0.8623853211009175,"difficultyWeight":109},"embers":{"count":215,"lastSeenTime":1577009668770,"publicGameCount":3,"difficulty":0.8064516129032258,"difficultyWeight":31},"coral":{"count":452,"lastSeenTime":1577017071398,"publicGameCount":21,"difficulty":0.6435643564356436,"difficultyWeight":202},"radar":{"count":224,"lastSeenTime":1577024393446,"publicGameCount":5,"difficulty":0.6097560975609756,"difficultyWeight":82},"DNA":{"count":220,"lastSeenTime":1577036513099,"difficulty":0.551912568306011,"difficultyWeight":183,"publicGameCount":5},"violence":{"count":214,"lastSeenTime":1577020760004,"difficulty":0.7714285714285715,"difficultyWeight":70,"publicGameCount":8},"ham":{"count":237,"lastSeenTime":1577013426420,"difficulty":0.6764705882352942,"difficultyWeight":136,"publicGameCount":6},"pistachio":{"count":216,"lastSeenTime":1577031792602,"publicGameCount":12,"difficulty":0.7209302325581396,"difficultyWeight":86},"comfortable":{"count":413,"lastSeenTime":1577035900512,"publicGameCount":12,"difficulty":0.8241758241758241,"difficultyWeight":91},"Croatia":{"count":432,"lastSeenTime":1577032459097,"publicGameCount":6,"difficulty":0.7391304347826086,"difficultyWeight":69},"Hula Hoop":{"count":198,"lastSeenTime":1576999174479,"publicGameCount":10,"difficulty":0.6097560975609756,"difficultyWeight":82},"translate":{"count":201,"lastSeenTime":1577031672748,"publicGameCount":8,"difficulty":0.6588235294117647,"difficultyWeight":85},"cymbal":{"count":412,"lastSeenTime":1577011010114,"publicGameCount":8,"difficulty":0.734375,"difficultyWeight":64},"neighbor":{"count":209,"lastSeenTime":1577010360204,"publicGameCount":14,"difficulty":0.6616541353383458,"difficultyWeight":133},"beet":{"count":261,"lastSeenTime":1577008650446,"publicGameCount":4,"difficulty":0.6136363636363636,"difficultyWeight":44},"margarine":{"count":231,"lastSeenTime":1577037192421,"publicGameCount":4,"difficulty":0.8260869565217391,"difficultyWeight":46},"Michael Jackson":{"count":441,"lastSeenTime":1577030347875,"publicGameCount":39,"difficulty":0.7794676806083649,"difficultyWeight":263},"bricklayer":{"count":231,"lastSeenTime":1577035263186,"publicGameCount":4,"difficulty":0.8148148148148148,"difficultyWeight":27},"Black Friday":{"count":236,"lastSeenTime":1577035358654,"publicGameCount":13,"difficulty":0.7894736842105263,"difficultyWeight":95},"sugar":{"count":206,"lastSeenTime":1577019684566,"publicGameCount":8,"difficulty":0.6333333333333333,"difficultyWeight":120},"witness":{"count":229,"lastSeenTime":1577034391339,"publicGameCount":8,"difficulty":0.6865671641791045,"difficultyWeight":67},"greed":{"count":222,"lastSeenTime":1577020821191,"difficulty":0.7027027027027027,"difficultyWeight":74,"publicGameCount":4},"shake":{"count":228,"lastSeenTime":1577035150930,"difficulty":0.6710526315789473,"difficultyWeight":76,"publicGameCount":6},"neighborhood":{"count":470,"lastSeenTime":1577035865974,"publicGameCount":26,"difficulty":0.8157894736842105,"difficultyWeight":190},"Doritos":{"count":219,"lastSeenTime":1577019838761,"difficulty":0.4700460829493088,"difficultyWeight":217,"publicGameCount":14},"doctor":{"count":239,"lastSeenTime":1577026093155,"difficulty":0.5602094240837696,"difficultyWeight":191,"publicGameCount":9},"Minotaur":{"count":245,"lastSeenTime":1577015070110,"publicGameCount":11,"difficulty":0.75,"difficultyWeight":84},"Reddit":{"count":435,"lastSeenTime":1577020190238,"publicGameCount":23,"difficulty":0.6329787234042554,"difficultyWeight":188},"poppy":{"count":459,"lastSeenTime":1577036515120,"difficulty":0.6887417218543046,"difficultyWeight":151,"publicGameCount":14},"nail polish":{"count":238,"lastSeenTime":1577008601707,"publicGameCount":21,"difficulty":0.7284768211920529,"difficultyWeight":151},"Pikachu":{"count":462,"lastSeenTime":1577015222488,"publicGameCount":59,"difficulty":0.5194508009153317,"difficultyWeight":437},"Excalibur":{"count":222,"lastSeenTime":1576989813585,"difficulty":0.703125,"difficultyWeight":64,"publicGameCount":8},"cow":{"count":208,"lastSeenTime":1576997396108,"difficulty":0.4416243654822335,"difficultyWeight":197,"publicGameCount":5},"throne":{"count":235,"lastSeenTime":1577031633688,"difficulty":0.6219512195121951,"difficultyWeight":82,"publicGameCount":5},"braces":{"count":233,"lastSeenTime":1576998697393,"publicGameCount":8,"difficulty":0.5250000000000001,"difficultyWeight":200},"retail":{"count":227,"lastSeenTime":1577031498760,"difficulty":0.5454545454545454,"difficultyWeight":44,"publicGameCount":2},"badger":{"count":232,"lastSeenTime":1577037521580,"publicGameCount":3,"difficulty":0.813953488372093,"difficultyWeight":43},"fizz":{"count":227,"lastSeenTime":1577009445318,"difficulty":0.5833333333333334,"difficultyWeight":96,"publicGameCount":10},"Elmo":{"count":431,"lastSeenTime":1577004674031,"publicGameCount":50,"difficulty":0.5670588235294118,"difficultyWeight":425},"yawn":{"count":219,"lastSeenTime":1576966776767,"publicGameCount":13,"difficulty":0.5688073394495414,"difficultyWeight":109},"Mars":{"count":229,"lastSeenTime":1577033906184,"publicGameCount":13,"difficulty":0.5680473372781066,"difficultyWeight":169},"quilt":{"count":226,"lastSeenTime":1577001434887,"publicGameCount":5,"difficulty":0.75,"difficultyWeight":64},"firefighter":{"count":225,"lastSeenTime":1577020200660,"publicGameCount":27,"difficulty":0.54337899543379,"difficultyWeight":219},"oil":{"count":193,"lastSeenTime":1576988731899,"publicGameCount":10,"difficulty":0.6153846153846154,"difficultyWeight":117},"bus":{"count":207,"lastSeenTime":1577011324920,"difficulty":0.4719626168224299,"difficultyWeight":214},"Anubis":{"count":206,"lastSeenTime":1576965573413,"difficulty":0.7142857142857143,"difficultyWeight":70,"publicGameCount":7},"floodlight":{"count":215,"lastSeenTime":1577034401652,"publicGameCount":6,"difficulty":0.7567567567567568,"difficultyWeight":37},"mayor":{"count":221,"lastSeenTime":1577025416426,"publicGameCount":6,"difficulty":0.5818181818181818,"difficultyWeight":55},"ravioli":{"count":204,"lastSeenTime":1577018048472,"publicGameCount":9,"difficulty":0.675,"difficultyWeight":80},"cap":{"count":221,"lastSeenTime":1577010712375,"difficulty":0.5119047619047619,"difficultyWeight":84,"publicGameCount":1},"match":{"count":235,"lastSeenTime":1577033733248,"publicGameCount":9,"difficulty":0.5289855072463768,"difficultyWeight":138},"Asterix":{"count":433,"lastSeenTime":1577035876160,"publicGameCount":9,"difficulty":0.8541666666666666,"difficultyWeight":96},"arch":{"count":221,"lastSeenTime":1577037638341,"difficulty":0.7075471698113207,"difficultyWeight":106,"publicGameCount":8},"Goofy":{"count":399,"lastSeenTime":1577037667912,"publicGameCount":12,"difficulty":0.5503355704697986,"difficultyWeight":149},"tampon":{"count":229,"lastSeenTime":1577033017430,"difficulty":0.6382978723404256,"difficultyWeight":141,"publicGameCount":8},"building":{"count":413,"lastSeenTime":1577029872241,"publicGameCount":43,"difficulty":0.641833810888252,"difficultyWeight":349},"pin":{"count":234,"lastSeenTime":1577033814863,"difficulty":0.5669291338582677,"difficultyWeight":127,"publicGameCount":6},"Tower of Pisa":{"count":441,"lastSeenTime":1576982169774,"publicGameCount":26,"difficulty":0.7969543147208121,"difficultyWeight":197},"Jenga":{"count":221,"lastSeenTime":1577037365574,"publicGameCount":11,"difficulty":0.706422018348624,"difficultyWeight":109},"vacation":{"count":204,"lastSeenTime":1577011285181,"publicGameCount":5,"difficulty":0.6296296296296297,"difficultyWeight":54},"sauna":{"count":225,"lastSeenTime":1577010111283,"publicGameCount":5,"difficulty":0.6511627906976745,"difficultyWeight":43},"Tetris":{"count":240,"lastSeenTime":1577033216553,"difficulty":0.6616541353383458,"difficultyWeight":133,"publicGameCount":11},"nest":{"count":195,"lastSeenTime":1577002693201,"publicGameCount":8,"difficulty":0.5250000000000001,"difficultyWeight":120},"bunk bed":{"count":257,"lastSeenTime":1577030010895,"publicGameCount":23,"difficulty":0.6424242424242426,"difficultyWeight":165},"ABBA":{"count":460,"lastSeenTime":1577036953671,"publicGameCount":13,"difficulty":0.5217391304347826,"difficultyWeight":92},"scary":{"count":460,"lastSeenTime":1577020163387,"publicGameCount":28,"difficulty":0.6395348837209305,"difficultyWeight":258},"arm":{"count":464,"lastSeenTime":1577032801953,"difficulty":0.4507462686567164,"difficultyWeight":335,"publicGameCount":36},"iPhone":{"count":219,"lastSeenTime":1577017990731,"difficulty":0.5201793721973094,"difficultyWeight":223,"publicGameCount":20},"Susan Wojcicki":{"count":430,"lastSeenTime":1577021368947,"publicGameCount":15,"difficulty":0.8348623853211009,"difficultyWeight":109},"nun":{"count":236,"lastSeenTime":1576990865256,"publicGameCount":10,"difficulty":0.5686274509803921,"difficultyWeight":102},"parade":{"count":240,"lastSeenTime":1577001935445,"publicGameCount":7,"difficulty":0.6875,"difficultyWeight":64},"crawl space":{"count":226,"lastSeenTime":1577013344367,"publicGameCount":11,"difficulty":0.6790123456790124,"difficultyWeight":81},"Pac-Man":{"count":438,"lastSeenTime":1577037141569,"publicGameCount":89,"difficulty":0.5050651230101304,"difficultyWeight":691},"soil":{"count":465,"lastSeenTime":1577001522879,"publicGameCount":19,"difficulty":0.6411764705882353,"difficultyWeight":170},"lens":{"count":234,"lastSeenTime":1577031765159,"publicGameCount":3,"difficulty":0.5576923076923077,"difficultyWeight":52},"gas":{"count":220,"lastSeenTime":1577036096380,"publicGameCount":13,"difficulty":0.6267605633802817,"difficultyWeight":142},"mall":{"count":451,"lastSeenTime":1577019105920,"publicGameCount":17,"difficulty":0.49324324324324326,"difficultyWeight":148},"Green Lantern":{"count":445,"lastSeenTime":1577016282546,"publicGameCount":32,"difficulty":0.7022222222222222,"difficultyWeight":225},"celebrity":{"count":234,"lastSeenTime":1577024296338,"publicGameCount":13,"difficulty":0.6886792452830188,"difficultyWeight":106},"promotion":{"count":229,"lastSeenTime":1577037535729,"difficulty":0.6170212765957447,"difficultyWeight":47,"publicGameCount":3},"hammock":{"count":216,"lastSeenTime":1577014089395,"difficulty":0.6477272727272727,"difficultyWeight":88,"publicGameCount":5},"stereo":{"count":229,"lastSeenTime":1577016935320,"publicGameCount":11,"difficulty":0.6727272727272727,"difficultyWeight":110},"pillar":{"count":220,"lastSeenTime":1577037316766,"difficulty":0.7555555555555555,"difficultyWeight":45,"publicGameCount":2},"Capricorn":{"count":244,"lastSeenTime":1577036258761,"publicGameCount":2,"difficulty":0.5217391304347826,"difficultyWeight":23},"facade":{"count":247,"lastSeenTime":1577030172832,"difficulty":0.9666666666666667,"difficultyWeight":30,"publicGameCount":1},"Titanic":{"count":224,"lastSeenTime":1577036811707,"publicGameCount":14,"difficulty":0.5329949238578681,"difficultyWeight":197},"dinner":{"count":229,"lastSeenTime":1576994893392,"difficulty":0.5733333333333334,"difficultyWeight":75,"publicGameCount":4},"Luigi":{"count":421,"lastSeenTime":1577016522371,"publicGameCount":31,"difficulty":0.5348837209302324,"difficultyWeight":258},"Winnie the Pooh":{"count":449,"lastSeenTime":1577036498776,"publicGameCount":41,"difficulty":0.6783216783216782,"difficultyWeight":286},"Gandalf":{"count":456,"lastSeenTime":1577037678090,"publicGameCount":22,"difficulty":0.7415730337078652,"difficultyWeight":178},"Charlie Chaplin":{"count":435,"lastSeenTime":1577025889721,"publicGameCount":14,"difficulty":0.8,"difficultyWeight":100},"villain":{"count":212,"lastSeenTime":1576964936100,"publicGameCount":11,"difficulty":0.6702127659574468,"difficultyWeight":94},"Johnny Bravo":{"count":424,"lastSeenTime":1577018909748,"publicGameCount":16,"difficulty":0.7952755905511811,"difficultyWeight":127},"halo":{"count":226,"lastSeenTime":1577018671994,"publicGameCount":10,"difficulty":0.6694214876033058,"difficultyWeight":121},"pigeon":{"count":220,"lastSeenTime":1577011472230,"publicGameCount":11,"difficulty":0.6911764705882353,"difficultyWeight":136},"butt cheeks":{"count":443,"lastSeenTime":1577025302098,"publicGameCount":55,"difficulty":0.75,"difficultyWeight":424},"hip hop":{"count":404,"lastSeenTime":1577034507564,"publicGameCount":17,"difficulty":0.8243243243243243,"difficultyWeight":148},"macho":{"count":455,"lastSeenTime":1577025104883,"publicGameCount":10,"difficulty":0.8588235294117647,"difficultyWeight":85},"hovercraft":{"count":216,"lastSeenTime":1577036513099,"publicGameCount":7,"difficulty":0.6615384615384615,"difficultyWeight":65},"needle":{"count":204,"lastSeenTime":1576991450871,"publicGameCount":7,"difficulty":0.644927536231884,"difficultyWeight":138},"hair roller":{"count":211,"lastSeenTime":1577033178896,"publicGameCount":2,"difficulty":0.8333333333333334,"difficultyWeight":12},"Notch":{"count":463,"lastSeenTime":1577037316766,"difficulty":0.7394957983193278,"difficultyWeight":119,"publicGameCount":15},"upgrade":{"count":202,"lastSeenTime":1577031469464,"difficulty":0.6203703703703703,"difficultyWeight":108,"publicGameCount":14},"bean bag":{"count":250,"lastSeenTime":1577016194818,"publicGameCount":8,"difficulty":0.8194444444444444,"difficultyWeight":72},"bellow":{"count":207,"lastSeenTime":1576954501686,"publicGameCount":4,"difficulty":0.723404255319149,"difficultyWeight":47},"plunger":{"count":216,"lastSeenTime":1577001542782,"publicGameCount":12,"difficulty":0.6684210526315791,"difficultyWeight":190},"Mario":{"count":422,"lastSeenTime":1577030262784,"publicGameCount":28,"difficulty":0.4525993883792049,"difficultyWeight":327},"pigsty":{"count":423,"lastSeenTime":1577033936117,"publicGameCount":10,"difficulty":0.7956989247311828,"difficultyWeight":93},"KFC":{"count":372,"lastSeenTime":1577019302199,"difficulty":0.5886699507389161,"difficultyWeight":406,"publicGameCount":24},"wheel":{"count":224,"lastSeenTime":1577014128670,"publicGameCount":9,"difficulty":0.5653710247349824,"difficultyWeight":283},"Brazil":{"count":465,"lastSeenTime":1577035455493,"difficulty":0.7044334975369458,"difficultyWeight":203,"publicGameCount":21},"swag":{"count":229,"lastSeenTime":1577017118352,"publicGameCount":5,"difficulty":0.654320987654321,"difficultyWeight":81},"Nasa":{"count":460,"lastSeenTime":1577020311647,"publicGameCount":36,"difficulty":0.5431034482758622,"difficultyWeight":348},"autograph":{"count":240,"lastSeenTime":1577036329616,"publicGameCount":12,"difficulty":0.7380952380952381,"difficultyWeight":84},"hilarious":{"count":458,"lastSeenTime":1577003366572,"publicGameCount":19,"difficulty":0.7672955974842768,"difficultyWeight":159},"acne":{"count":402,"lastSeenTime":1577036401976,"difficulty":0.6024096385542169,"difficultyWeight":249,"publicGameCount":24},"backpack":{"count":199,"lastSeenTime":1577004757603,"publicGameCount":14,"difficulty":0.5888324873096445,"difficultyWeight":197},"manhole":{"count":429,"lastSeenTime":1577018038260,"publicGameCount":23,"difficulty":0.7076023391812867,"difficultyWeight":171},"applause":{"count":239,"lastSeenTime":1577035714898,"difficulty":0.7307692307692307,"difficultyWeight":52,"publicGameCount":5},"Bruce Lee":{"count":445,"lastSeenTime":1577034703857,"publicGameCount":11,"difficulty":0.7888888888888889,"difficultyWeight":90},"Segway":{"count":201,"lastSeenTime":1577025478336,"publicGameCount":5,"difficulty":0.6494845360824743,"difficultyWeight":97},"advertisement":{"count":226,"lastSeenTime":1576976891248,"publicGameCount":14,"difficulty":0.6869565217391305,"difficultyWeight":115},"Poseidon":{"count":386,"lastSeenTime":1577037151662,"publicGameCount":22,"difficulty":0.6558441558441559,"difficultyWeight":154},"reception":{"count":240,"lastSeenTime":1576997044902,"publicGameCount":7,"difficulty":0.8208955223880597,"difficultyWeight":67},"vinegar":{"count":230,"lastSeenTime":1577010111283,"publicGameCount":6,"difficulty":0.7727272727272727,"difficultyWeight":66},"geography":{"count":412,"lastSeenTime":1577007820280,"publicGameCount":17,"difficulty":0.6696428571428571,"difficultyWeight":112},"peasant":{"count":241,"lastSeenTime":1577032383846,"publicGameCount":5,"difficulty":0.7627118644067796,"difficultyWeight":59},"Skittles":{"count":223,"lastSeenTime":1577033102907,"publicGameCount":24,"difficulty":0.5600000000000002,"difficultyWeight":225},"teacher":{"count":248,"lastSeenTime":1577025028815,"publicGameCount":11,"difficulty":0.582089552238806,"difficultyWeight":134},"bed sheet":{"count":208,"lastSeenTime":1577025807131,"publicGameCount":15,"difficulty":0.7407407407407407,"difficultyWeight":108},"abyss":{"count":237,"lastSeenTime":1577002423477,"difficulty":1,"difficultyWeight":13},"corner":{"count":217,"lastSeenTime":1577035216186,"difficulty":0.6068965517241379,"difficultyWeight":145,"publicGameCount":4},"cat":{"count":238,"lastSeenTime":1577029947635,"difficulty":0.5299539170506911,"difficultyWeight":217,"publicGameCount":2},"Miniclip":{"count":390,"lastSeenTime":1577007467354,"publicGameCount":12,"difficulty":0.8301886792452831,"difficultyWeight":106},"saxophone":{"count":403,"lastSeenTime":1577020454463,"publicGameCount":20,"difficulty":0.6081871345029239,"difficultyWeight":171},"safe":{"count":246,"lastSeenTime":1577036416241,"difficulty":0.6114649681528661,"difficultyWeight":157,"publicGameCount":9},"model":{"count":221,"lastSeenTime":1577029810408,"publicGameCount":5,"difficulty":0.5172413793103449,"difficultyWeight":29},"trapdoor":{"count":209,"lastSeenTime":1577018338118,"publicGameCount":5,"difficulty":0.6461538461538462,"difficultyWeight":65},"copper":{"count":214,"lastSeenTime":1577035569138,"difficulty":0.8571428571428571,"difficultyWeight":70,"publicGameCount":5},"anvil":{"count":221,"lastSeenTime":1577014904417,"difficulty":0.6821192052980133,"difficultyWeight":151,"publicGameCount":7},"Leonardo da Vinci":{"count":454,"lastSeenTime":1577011492557,"publicGameCount":15,"difficulty":0.8037383177570093,"difficultyWeight":107},"lounge":{"count":244,"lastSeenTime":1576976513111,"publicGameCount":5,"difficulty":0.6507936507936508,"difficultyWeight":63},"plumber":{"count":245,"lastSeenTime":1577036473654,"publicGameCount":17,"difficulty":0.6170212765957447,"difficultyWeight":141},"eel":{"count":224,"lastSeenTime":1577020032335,"publicGameCount":7,"difficulty":0.6233766233766235,"difficultyWeight":77},"blanket":{"count":238,"lastSeenTime":1576995190104,"publicGameCount":12,"difficulty":0.5686274509803922,"difficultyWeight":102},"house":{"count":437,"lastSeenTime":1577025316429,"difficulty":0.38779527559055116,"difficultyWeight":508,"publicGameCount":36},"otter":{"count":214,"lastSeenTime":1577032691219,"publicGameCount":11,"difficulty":0.7722772277227723,"difficultyWeight":101},"Mr. Meeseeks":{"count":217,"lastSeenTime":1577015560740,"publicGameCount":1,"difficulty":0.9193548387096774,"difficultyWeight":62},"kazoo":{"count":429,"lastSeenTime":1577018938852,"publicGameCount":18,"difficulty":0.7073170731707316,"difficultyWeight":205},"think":{"count":219,"lastSeenTime":1577007452649,"difficulty":0.59,"difficultyWeight":200,"publicGameCount":6},"youtuber":{"count":207,"lastSeenTime":1577029699092,"publicGameCount":10,"difficulty":0.6287878787878788,"difficultyWeight":132},"frostbite":{"count":239,"lastSeenTime":1577002452174,"difficulty":0.6721311475409836,"difficultyWeight":61,"publicGameCount":8},"octagon":{"count":214,"lastSeenTime":1577009560276,"difficulty":0.6431924882629108,"difficultyWeight":213,"publicGameCount":13},"Bible":{"count":200,"lastSeenTime":1576983820374,"publicGameCount":9,"difficulty":0.47802197802197804,"difficultyWeight":182},"figurine":{"count":207,"lastSeenTime":1577025767393,"difficulty":0.9285714285714286,"difficultyWeight":14,"publicGameCount":1},"pear":{"count":221,"lastSeenTime":1577030691919,"difficulty":0.49624060150375937,"difficultyWeight":266,"publicGameCount":5},"world":{"count":219,"lastSeenTime":1576996350217,"difficulty":0.576923076923077,"difficultyWeight":182,"publicGameCount":14},"peanut":{"count":224,"lastSeenTime":1576988381834,"publicGameCount":7,"difficulty":0.6267942583732058,"difficultyWeight":209},"daughter":{"count":219,"lastSeenTime":1577020215138,"publicGameCount":14,"difficulty":0.739884393063584,"difficultyWeight":173},"Pringles":{"count":213,"lastSeenTime":1577016532618,"difficulty":0.5531914893617021,"difficultyWeight":141,"publicGameCount":12},"gravity":{"count":224,"lastSeenTime":1577032997046,"publicGameCount":8,"difficulty":0.7105263157894737,"difficultyWeight":76},"willow":{"count":435,"lastSeenTime":1577019664821,"publicGameCount":10,"difficulty":0.6185567010309279,"difficultyWeight":97},"sew":{"count":236,"lastSeenTime":1577002452173,"publicGameCount":6,"difficulty":0.6923076923076923,"difficultyWeight":52},"Northern Lights":{"count":436,"lastSeenTime":1577037092671,"publicGameCount":19,"difficulty":0.7985611510791367,"difficultyWeight":139},"health":{"count":226,"lastSeenTime":1577034268153,"difficulty":0.6236559139784946,"difficultyWeight":93,"publicGameCount":8},"backflip":{"count":226,"lastSeenTime":1577007604955,"publicGameCount":9,"difficulty":0.5441176470588235,"difficultyWeight":68},"Mont Blanc":{"count":420,"lastSeenTime":1577036825894,"publicGameCount":8,"difficulty":0.8,"difficultyWeight":60},"crucible":{"count":218,"lastSeenTime":1577016562092,"difficulty":0.8181818181818182,"difficultyWeight":22,"publicGameCount":2},"Bugs Bunny":{"count":387,"lastSeenTime":1577033780065,"publicGameCount":33,"difficulty":0.6973684210526315,"difficultyWeight":228},"cement":{"count":226,"lastSeenTime":1577025781863,"difficulty":0.8309859154929577,"difficultyWeight":71,"publicGameCount":8},"actor":{"count":210,"lastSeenTime":1577009158040,"publicGameCount":3,"difficulty":0.6428571428571429,"difficultyWeight":28},"comedy":{"count":214,"lastSeenTime":1577007506033,"difficulty":0.8064516129032258,"difficultyWeight":62,"publicGameCount":1},"chainsaw":{"count":214,"lastSeenTime":1577017128569,"publicGameCount":19,"difficulty":0.5829145728643218,"difficultyWeight":199},"virtual reality":{"count":221,"lastSeenTime":1577020239958,"publicGameCount":12,"difficulty":0.8095238095238095,"difficultyWeight":105},"England":{"count":468,"lastSeenTime":1577035803681,"difficulty":0.6455696202531644,"difficultyWeight":237,"publicGameCount":24},"polar bear":{"count":222,"lastSeenTime":1577037568133,"publicGameCount":27,"difficulty":0.6021505376344087,"difficultyWeight":186},"fern":{"count":450,"lastSeenTime":1577009073445,"publicGameCount":18,"difficulty":0.7285714285714285,"difficultyWeight":140},"folder":{"count":220,"lastSeenTime":1577024929912,"difficulty":0.7450980392156863,"difficultyWeight":153,"publicGameCount":12},"microscope":{"count":233,"lastSeenTime":1576987263425,"difficulty":0.7045454545454546,"difficultyWeight":132,"publicGameCount":18},"tattoo":{"count":228,"lastSeenTime":1576976036447,"publicGameCount":11,"difficulty":0.6225165562913907,"difficultyWeight":151},"lynx":{"count":237,"lastSeenTime":1577035985945,"publicGameCount":2,"difficulty":0.7037037037037037,"difficultyWeight":27},"shopping":{"count":211,"lastSeenTime":1577032516007,"publicGameCount":12,"difficulty":0.5585585585585586,"difficultyWeight":111},"violin":{"count":442,"lastSeenTime":1577030033309,"publicGameCount":25,"difficulty":0.6008583690987125,"difficultyWeight":233},"Mr. Bean":{"count":248,"lastSeenTime":1577017456065,"difficulty":0.717391304347826,"difficultyWeight":92,"publicGameCount":5},"Velociraptor":{"count":239,"lastSeenTime":1577019187643,"publicGameCount":7,"difficulty":0.7959183673469388,"difficultyWeight":49},"macaroni":{"count":220,"lastSeenTime":1576922210439,"publicGameCount":12,"difficulty":0.7628865979381443,"difficultyWeight":97},"quicksand":{"count":453,"lastSeenTime":1577030581728,"publicGameCount":22,"difficulty":0.782608695652174,"difficultyWeight":184},"UFO":{"count":217,"lastSeenTime":1577032857352,"difficulty":0.47572815533980584,"difficultyWeight":206,"publicGameCount":7},"patient":{"count":209,"lastSeenTime":1576997705631,"difficulty":0.8846153846153846,"difficultyWeight":26,"publicGameCount":2},"glue":{"count":231,"lastSeenTime":1577007668912,"publicGameCount":8,"difficulty":0.5463917525773195,"difficultyWeight":97},"wrestler":{"count":223,"lastSeenTime":1577033608923,"publicGameCount":7,"difficulty":0.8285714285714286,"difficultyWeight":70},"duel":{"count":234,"lastSeenTime":1577024907310,"publicGameCount":4,"difficulty":0.684931506849315,"difficultyWeight":73},"Sudoku":{"count":227,"lastSeenTime":1577001113903,"publicGameCount":14,"difficulty":0.5307692307692308,"difficultyWeight":130},"cushion":{"count":236,"lastSeenTime":1577015315181,"publicGameCount":6,"difficulty":0.5636363636363637,"difficultyWeight":55},"walnut":{"count":209,"lastSeenTime":1576993566290,"publicGameCount":8,"difficulty":0.7,"difficultyWeight":110},"drama":{"count":248,"lastSeenTime":1576989489716,"difficulty":0.6491228070175439,"difficultyWeight":57,"publicGameCount":5},"caviar":{"count":236,"lastSeenTime":1577031871353,"publicGameCount":2,"difficulty":0.7857142857142857,"difficultyWeight":14},"King Kong":{"count":418,"lastSeenTime":1577007630765,"publicGameCount":28,"difficulty":0.6682692307692305,"difficultyWeight":208},"USB":{"count":219,"lastSeenTime":1577036917213,"publicGameCount":17,"difficulty":0.6175438596491226,"difficultyWeight":285},"Darwin Watterson":{"count":252,"lastSeenTime":1577002203423,"publicGameCount":9,"difficulty":0.8783783783783784,"difficultyWeight":74},"saddle":{"count":224,"lastSeenTime":1577037402133,"publicGameCount":8,"difficulty":0.6209677419354839,"difficultyWeight":124},"paintball":{"count":247,"lastSeenTime":1577035629904,"publicGameCount":15,"difficulty":0.675,"difficultyWeight":120},"baklava":{"count":244,"lastSeenTime":1577018964063,"publicGameCount":2,"difficulty":0.8636363636363636,"difficultyWeight":22},"hermit":{"count":207,"lastSeenTime":1576986977281,"difficulty":0.625,"difficultyWeight":56,"publicGameCount":3},"diploma":{"count":223,"lastSeenTime":1577015732671,"difficulty":0.7808219178082192,"difficultyWeight":73,"publicGameCount":7},"candle":{"count":212,"lastSeenTime":1577017763955,"difficulty":0.4959016393442623,"difficultyWeight":244,"publicGameCount":6},"Madagascar":{"count":464,"lastSeenTime":1577018327956,"publicGameCount":17,"difficulty":0.7482014388489209,"difficultyWeight":139},"beetle":{"count":231,"lastSeenTime":1577030201858,"publicGameCount":7,"difficulty":0.547945205479452,"difficultyWeight":73},"Morty":{"count":419,"lastSeenTime":1577037355436,"publicGameCount":19,"difficulty":0.6600985221674877,"difficultyWeight":203},"dashboard":{"count":216,"lastSeenTime":1576995423938,"publicGameCount":9,"difficulty":0.5972222222222222,"difficultyWeight":72},"nutmeg":{"count":190,"lastSeenTime":1577020860567,"publicGameCount":2,"difficulty":0.5185185185185185,"difficultyWeight":54},"Hercules":{"count":463,"lastSeenTime":1577033007248,"publicGameCount":17,"difficulty":0.7890625,"difficultyWeight":128},"Solar System":{"count":229,"lastSeenTime":1577036527277,"publicGameCount":22,"difficulty":0.6411764705882353,"difficultyWeight":170},"camera":{"count":230,"lastSeenTime":1577011606837,"publicGameCount":14,"difficulty":0.549407114624506,"difficultyWeight":253},"tuba":{"count":404,"lastSeenTime":1576993882569,"publicGameCount":12,"difficulty":0.5564516129032259,"difficultyWeight":124},"leech":{"count":229,"lastSeenTime":1576988203694,"publicGameCount":5,"difficulty":0.7014925373134329,"difficultyWeight":67},"search":{"count":208,"lastSeenTime":1577030851645,"publicGameCount":7,"difficulty":0.5963855421686747,"difficultyWeight":166},"Slinky":{"count":239,"lastSeenTime":1576996381190,"publicGameCount":6,"difficulty":0.6190476190476191,"difficultyWeight":63},"lipstick":{"count":224,"lastSeenTime":1577004001722,"publicGameCount":26,"difficulty":0.44981412639405205,"difficultyWeight":269},"headache":{"count":234,"lastSeenTime":1577025363327,"publicGameCount":12,"difficulty":0.5514018691588786,"difficultyWeight":107},"Paris":{"count":429,"lastSeenTime":1577033891936,"difficulty":0.5563549160671462,"difficultyWeight":417,"publicGameCount":46},"pogo stick":{"count":199,"lastSeenTime":1577032738629,"publicGameCount":17,"difficulty":0.6046511627906976,"difficultyWeight":129},"lemur":{"count":217,"lastSeenTime":1577036701657,"difficulty":0.7567567567567568,"difficultyWeight":37,"publicGameCount":3},"Mr Meeseeks":{"count":232,"lastSeenTime":1577018492804,"difficulty":0.8333333333333334,"difficultyWeight":96,"publicGameCount":11},"player":{"count":217,"lastSeenTime":1577017667709,"difficulty":0.7480314960629921,"difficultyWeight":127,"publicGameCount":8},"invention":{"count":200,"lastSeenTime":1577002350973,"publicGameCount":2,"difficulty":0.6071428571428571,"difficultyWeight":28},"bumper":{"count":231,"lastSeenTime":1577009177631,"publicGameCount":9,"difficulty":0.6185567010309279,"difficultyWeight":97},"handle":{"count":244,"lastSeenTime":1577031193533,"difficulty":0.7169811320754716,"difficultyWeight":53,"publicGameCount":3},"sword":{"count":235,"lastSeenTime":1577011105897,"publicGameCount":12,"difficulty":0.45964912280701753,"difficultyWeight":285},"tabletop":{"count":235,"lastSeenTime":1577025627579,"publicGameCount":4,"difficulty":0.7,"difficultyWeight":50},"shark":{"count":231,"lastSeenTime":1577025952720,"difficulty":0.5128205128205128,"difficultyWeight":156},"laundry":{"count":208,"lastSeenTime":1577011695040,"difficulty":0.6133333333333333,"difficultyWeight":75,"publicGameCount":6},"Chinatown":{"count":404,"lastSeenTime":1577025841683,"publicGameCount":11,"difficulty":0.6506024096385542,"difficultyWeight":83},"Spain":{"count":410,"lastSeenTime":1577032968561,"publicGameCount":14,"difficulty":0.5909090909090909,"difficultyWeight":176},"label":{"count":210,"lastSeenTime":1577031546307,"difficulty":0.6470588235294118,"difficultyWeight":85,"publicGameCount":7},"vanish":{"count":230,"lastSeenTime":1577033804412,"publicGameCount":7,"difficulty":0.6818181818181818,"difficultyWeight":88},"nose ring":{"count":245,"lastSeenTime":1577010384587,"publicGameCount":27,"difficulty":0.5929648241206029,"difficultyWeight":199},"drought":{"count":440,"lastSeenTime":1577034022367,"difficulty":0.8307692307692308,"difficultyWeight":130,"publicGameCount":12},"policeman":{"count":224,"lastSeenTime":1577002051390,"publicGameCount":16,"difficulty":0.5661764705882353,"difficultyWeight":136},"Stegosaurus":{"count":215,"lastSeenTime":1577013975511,"publicGameCount":9,"difficulty":0.72,"difficultyWeight":75},"dice":{"count":254,"lastSeenTime":1577031234774,"difficulty":0.5078125,"difficultyWeight":256,"publicGameCount":14},"pope":{"count":230,"lastSeenTime":1577025018536,"publicGameCount":5,"difficulty":0.7176470588235293,"difficultyWeight":85},"attic":{"count":223,"lastSeenTime":1576998400404,"difficulty":0.6470588235294118,"difficultyWeight":51,"publicGameCount":3},"Family Guy":{"count":247,"lastSeenTime":1576983442566,"publicGameCount":18,"difficulty":0.672,"difficultyWeight":125},"server":{"count":208,"lastSeenTime":1577033043901,"publicGameCount":4,"difficulty":0.8214285714285714,"difficultyWeight":56},"vulture":{"count":212,"lastSeenTime":1577031248949,"publicGameCount":7,"difficulty":0.6931818181818182,"difficultyWeight":88},"banker":{"count":216,"lastSeenTime":1577010447702,"difficulty":0.7065217391304348,"difficultyWeight":92,"publicGameCount":5},"treadmill":{"count":231,"lastSeenTime":1577037341722,"publicGameCount":10,"difficulty":0.6373626373626373,"difficultyWeight":91},"chestnut":{"count":210,"lastSeenTime":1577010593183,"difficulty":0.7454545454545455,"difficultyWeight":55,"publicGameCount":4},"scarecrow":{"count":239,"lastSeenTime":1577033308316,"publicGameCount":10,"difficulty":0.6434782608695652,"difficultyWeight":115},"lake":{"count":426,"lastSeenTime":1577016713300,"difficulty":0.4876543209876543,"difficultyWeight":324,"publicGameCount":28},"doll":{"count":230,"lastSeenTime":1577031458931,"difficulty":0.464,"difficultyWeight":125,"publicGameCount":10},"impact":{"count":232,"lastSeenTime":1576994494324,"publicGameCount":4,"difficulty":0.7741935483870968,"difficultyWeight":31},"papaya":{"count":226,"lastSeenTime":1577035338348,"difficulty":0.6354166666666667,"difficultyWeight":96,"publicGameCount":9},"landlord":{"count":229,"lastSeenTime":1577009049641,"publicGameCount":1,"difficulty":0.8571428571428571,"difficultyWeight":7},"flying pig":{"count":202,"lastSeenTime":1577034300607,"publicGameCount":20,"difficulty":0.6620689655172414,"difficultyWeight":145},"brunette":{"count":211,"lastSeenTime":1577036608773,"publicGameCount":7,"difficulty":0.7611940298507462,"difficultyWeight":67},"flask":{"count":208,"lastSeenTime":1577035277440,"difficulty":0.7101449275362319,"difficultyWeight":138,"publicGameCount":8},"notebook":{"count":233,"lastSeenTime":1577013787870,"difficulty":0.5894039735099338,"difficultyWeight":151,"publicGameCount":10},"boat":{"count":219,"lastSeenTime":1577036836029,"difficulty":0.43356643356643354,"difficultyWeight":286,"publicGameCount":3},"bookmark":{"count":241,"lastSeenTime":1577014895707,"publicGameCount":13,"difficulty":0.5769230769230769,"difficultyWeight":130},"floppy disk":{"count":213,"lastSeenTime":1577025817270,"publicGameCount":10,"difficulty":0.72,"difficultyWeight":75},"back pain":{"count":242,"lastSeenTime":1576992076643,"publicGameCount":13,"difficulty":0.7525773195876289,"difficultyWeight":97},"shrew":{"count":217,"lastSeenTime":1577033891936,"difficulty":0.9655172413793104,"difficultyWeight":29,"publicGameCount":1},"T-rex":{"count":193,"lastSeenTime":1577010511117,"publicGameCount":25,"difficulty":0.5235294117647058,"difficultyWeight":170},"motherboard":{"count":234,"lastSeenTime":1576992062315,"publicGameCount":10,"difficulty":0.8333333333333334,"difficultyWeight":60},"stylus":{"count":254,"lastSeenTime":1577003174559,"publicGameCount":4,"difficulty":0.7073170731707317,"difficultyWeight":41},"magnifier":{"count":218,"lastSeenTime":1577033647739,"publicGameCount":13,"difficulty":0.6666666666666666,"difficultyWeight":111},"Band-Aid":{"count":222,"lastSeenTime":1576994596924,"publicGameCount":21,"difficulty":0.6845637583892618,"difficultyWeight":149},"journey":{"count":232,"lastSeenTime":1577017189646,"difficulty":0.5681818181818182,"difficultyWeight":44,"publicGameCount":4},"minivan":{"count":196,"lastSeenTime":1577024539413,"difficulty":0.7162162162162162,"difficultyWeight":74,"publicGameCount":8},"lotion":{"count":245,"lastSeenTime":1577036927354,"publicGameCount":7,"difficulty":0.6704545454545454,"difficultyWeight":88},"cartoon":{"count":229,"lastSeenTime":1576992213093,"publicGameCount":5,"difficulty":0.5955056179775281,"difficultyWeight":89},"skates":{"count":235,"lastSeenTime":1577031282203,"difficulty":0.5063291139240507,"difficultyWeight":158,"publicGameCount":8},"barcode":{"count":221,"lastSeenTime":1576998517639,"difficulty":0.7322834645669292,"difficultyWeight":127,"publicGameCount":10},"conversation":{"count":223,"lastSeenTime":1577000593113,"publicGameCount":14,"difficulty":0.7419354838709677,"difficultyWeight":124},"maid":{"count":221,"lastSeenTime":1577015985232,"difficulty":0.6055045871559633,"difficultyWeight":109,"publicGameCount":9},"desperate":{"count":244,"lastSeenTime":1577025599091,"publicGameCount":1,"difficulty":0.8888888888888888,"difficultyWeight":9},"Chrome":{"count":444,"lastSeenTime":1577036754761,"publicGameCount":39,"difficulty":0.4968553459119497,"difficultyWeight":318},"waterfall":{"count":438,"lastSeenTime":1577036588307,"publicGameCount":62,"difficulty":0.5926640926640926,"difficultyWeight":518},"furniture":{"count":244,"lastSeenTime":1576994478529,"publicGameCount":7,"difficulty":0.6491228070175439,"difficultyWeight":57},"Yin and Yang":{"count":221,"lastSeenTime":1576994622929,"publicGameCount":33,"difficulty":0.7345132743362832,"difficultyWeight":226},"wig":{"count":222,"lastSeenTime":1577004363564,"difficulty":0.6666666666666666,"difficultyWeight":144,"publicGameCount":9},"food":{"count":226,"lastSeenTime":1577024946172,"difficulty":0.5389610389610391,"difficultyWeight":154,"publicGameCount":7},"sensei":{"count":195,"lastSeenTime":1577030602131,"publicGameCount":6,"difficulty":0.7215189873417721,"difficultyWeight":79},"Venus":{"count":214,"lastSeenTime":1577031895972,"difficulty":0.6666666666666666,"difficultyWeight":78,"publicGameCount":5},"albatross":{"count":211,"lastSeenTime":1577009186739,"publicGameCount":4,"difficulty":0.8378378378378378,"difficultyWeight":37},"vegetarian":{"count":236,"lastSeenTime":1577034229193,"publicGameCount":14,"difficulty":0.7086614173228346,"difficultyWeight":127},"Florida":{"count":449,"lastSeenTime":1577037263306,"publicGameCount":20,"difficulty":0.6423841059602649,"difficultyWeight":151},"Milky Way":{"count":228,"lastSeenTime":1577012349812,"publicGameCount":16,"difficulty":0.625,"difficultyWeight":112},"aristocrat":{"count":226,"lastSeenTime":1577036195110,"difficulty":0.6538461538461539,"difficultyWeight":26,"publicGameCount":3},"flush":{"count":233,"lastSeenTime":1577037632002,"difficulty":0.620253164556962,"difficultyWeight":79,"publicGameCount":5},"tumor":{"count":220,"lastSeenTime":1577011724574,"difficulty":0.6,"difficultyWeight":15,"publicGameCount":1},"safari":{"count":222,"lastSeenTime":1577024514106,"publicGameCount":9,"difficulty":0.7920792079207921,"difficultyWeight":101},"catalog":{"count":225,"lastSeenTime":1577017108045,"difficulty":0.675,"difficultyWeight":40,"publicGameCount":2},"veterinarian":{"count":201,"lastSeenTime":1576991253422,"publicGameCount":7,"difficulty":0.8135593220338984,"difficultyWeight":59},"high score":{"count":226,"lastSeenTime":1577033283809,"publicGameCount":17,"difficulty":0.7338709677419355,"difficultyWeight":124},"afterlife":{"count":212,"lastSeenTime":1577020215138,"publicGameCount":9,"difficulty":0.6435643564356436,"difficultyWeight":101},"logo":{"count":205,"lastSeenTime":1577003987414,"publicGameCount":9,"difficulty":0.5394736842105263,"difficultyWeight":76},"mushroom":{"count":220,"lastSeenTime":1577011071361,"difficulty":0.4980237154150198,"difficultyWeight":253,"publicGameCount":15},"mole":{"count":249,"lastSeenTime":1577018796307,"publicGameCount":8,"difficulty":0.6607142857142857,"difficultyWeight":112},"marmalade":{"count":238,"lastSeenTime":1577032261139,"publicGameCount":4,"difficulty":0.8837209302325582,"difficultyWeight":43},"eraser":{"count":185,"lastSeenTime":1576983157896,"publicGameCount":11,"difficulty":0.6034482758620688,"difficultyWeight":174},"gummy bear":{"count":206,"lastSeenTime":1577035761130,"publicGameCount":29,"difficulty":0.5693779904306221,"difficultyWeight":209},"comet":{"count":227,"lastSeenTime":1577025287762,"difficulty":0.7156862745098039,"difficultyWeight":102,"publicGameCount":7},"hunter":{"count":206,"lastSeenTime":1577024820240,"publicGameCount":4,"difficulty":0.6603773584905659,"difficultyWeight":106},"bouncer":{"count":224,"lastSeenTime":1577000209447,"publicGameCount":6,"difficulty":0.65,"difficultyWeight":40},"exercise":{"count":208,"lastSeenTime":1576960300833,"publicGameCount":15,"difficulty":0.6268656716417911,"difficultyWeight":134},"commander":{"count":195,"lastSeenTime":1577015378171,"difficulty":0.7101449275362319,"difficultyWeight":69,"publicGameCount":6},"classroom":{"count":233,"lastSeenTime":1577020948126,"publicGameCount":6,"difficulty":0.6097560975609755,"difficultyWeight":82},"lava":{"count":199,"lastSeenTime":1577019263045,"publicGameCount":9,"difficulty":0.542857142857143,"difficultyWeight":245},"koala":{"count":211,"lastSeenTime":1577030372247,"difficulty":0.6524822695035462,"difficultyWeight":141,"publicGameCount":10},"market":{"count":235,"lastSeenTime":1577036169423,"difficulty":0.6095238095238096,"difficultyWeight":105,"publicGameCount":7},"miner":{"count":212,"lastSeenTime":1577014794126,"difficulty":0.5192307692307693,"difficultyWeight":104,"publicGameCount":6},"marble":{"count":237,"lastSeenTime":1577024946172,"difficulty":0.7184466019417476,"difficultyWeight":103,"publicGameCount":7},"fur":{"count":225,"lastSeenTime":1577024845092,"difficulty":0.580952380952381,"difficultyWeight":105,"publicGameCount":10},"raincoat":{"count":220,"lastSeenTime":1577031885678,"difficulty":0.5675675675675677,"difficultyWeight":111,"publicGameCount":12},"sunburn":{"count":195,"lastSeenTime":1577011807131,"publicGameCount":15,"difficulty":0.6022099447513812,"difficultyWeight":181},"robber":{"count":249,"lastSeenTime":1577030973803,"difficulty":0.5632911392405063,"difficultyWeight":158,"publicGameCount":12},"leave":{"count":194,"lastSeenTime":1577033479516,"difficulty":0.4098360655737705,"difficultyWeight":61,"publicGameCount":8},"girl":{"count":243,"lastSeenTime":1577037042051,"difficulty":0.5116279069767442,"difficultyWeight":258,"publicGameCount":11}} ================================================ FILE: tools/skribbliohintsconverter/german.json ================================================ {"Sommersprossen":{"count":5,"lastSeenTime":1586959168567},"inkognito":{"count":7,"lastSeenTime":1586901586361},"Marienkäfer":{"count":7,"lastSeenTime":1586958264090,"difficulty":0.8902439024390244,"difficultyWeight":82},"Zaun":{"count":8,"lastSeenTime":1586958848320},"graben":{"count":6,"lastSeenTime":1586896977731,"publicGameCount":1},"Erfrierung":{"count":7,"lastSeenTime":1586900635930},"Kessel":{"count":7,"lastSeenTime":1586839270292},"Kellner":{"count":6,"lastSeenTime":1586900763534},"Panzerband":{"count":4,"lastSeenTime":1586860197013,"difficulty":1,"difficultyWeight":11},"Schnorchel":{"count":12,"lastSeenTime":1586901554174,"difficulty":1,"difficultyWeight":4},"Abgrund":{"count":10,"lastSeenTime":1586869078737,"difficulty":1,"difficultyWeight":2},"geduldig":{"count":8,"lastSeenTime":1586959178759,"publicGameCount":1,"difficulty":0.8888888888888888,"difficultyWeight":9},"Edelstein":{"count":8,"lastSeenTime":1586954627819,"difficulty":1,"difficultyWeight":1},"Rasseln":{"count":6,"lastSeenTime":1586919552513,"difficulty":1,"difficultyWeight":3},"Ohr":{"count":11,"lastSeenTime":1586900881142,"difficulty":0.5833333333333334,"difficultyWeight":12},"Elektron":{"count":9,"lastSeenTime":1586903684169},"Telefonbuch":{"count":7,"lastSeenTime":1586908504643},"Kim Jong-Un":{"count":5,"lastSeenTime":1586904405029},"Backenzahn":{"count":9,"lastSeenTime":1586915737415},"Ameisenbär":{"count":9,"lastSeenTime":1586916550509,"difficulty":0.8,"difficultyWeight":5},"Zaubertrick":{"count":4,"lastSeenTime":1586783316765,"difficulty":1,"difficultyWeight":4},"Angestellter":{"count":5,"lastSeenTime":1586858975693,"publicGameCount":1},"Beförderung":{"count":6,"lastSeenTime":1586914119532,"difficulty":1,"difficultyWeight":6},"Krokodil":{"count":8,"lastSeenTime":1586901461723},"keuchen":{"count":6,"lastSeenTime":1586875186652},"Bleiche":{"count":6,"lastSeenTime":1586785407694},"The Rock":{"count":8,"lastSeenTime":1586901554174},"Karteikasten":{"count":8,"lastSeenTime":1586958934411,"difficulty":0.875,"difficultyWeight":8},"fliegendes Schwein":{"count":13,"lastSeenTime":1586920922732,"difficulty":0.9473684210526315,"difficultyWeight":19},"wachsen":{"count":7,"lastSeenTime":1586920637722,"difficulty":1,"difficultyWeight":1},"scharfe Soße":{"count":4,"lastSeenTime":1586959595986},"Grab":{"count":8,"lastSeenTime":1586919297771},"Milchmann":{"count":10,"lastSeenTime":1586955716758},"Pfanne":{"count":11,"lastSeenTime":1586958959180},"Säbel":{"count":11,"lastSeenTime":1586900301076,"difficulty":0.75,"difficultyWeight":28},"Peperoni":{"count":9,"lastSeenTime":1586901643471,"difficulty":1,"difficultyWeight":17},"Pony":{"count":6,"lastSeenTime":1586914196223},"Zirkus":{"count":8,"lastSeenTime":1586959814583,"publicGameCount":1,"difficulty":0.375,"difficultyWeight":8},"Kredithai":{"count":2,"lastSeenTime":1586784756252,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":5},"Triangel":{"count":4,"lastSeenTime":1586954834961},"Jo-Jo":{"count":10,"lastSeenTime":1586919312988,"publicGameCount":1},"Tür":{"count":8,"lastSeenTime":1586826993481,"difficulty":0.8181818181818182,"difficultyWeight":11},"Bauchnabel":{"count":6,"lastSeenTime":1586896963540,"difficulty":1,"difficultyWeight":1},"Wecker":{"count":5,"lastSeenTime":1586903561657},"Ravioli":{"count":7,"lastSeenTime":1586916277356},"Kolosseum":{"count":9,"lastSeenTime":1586868692820,"difficulty":0.8,"difficultyWeight":15},"Herde":{"count":5,"lastSeenTime":1586959031017},"zeigen":{"count":5,"lastSeenTime":1586954989864},"lächeln":{"count":10,"lastSeenTime":1586839535428,"difficulty":1,"difficultyWeight":9},"Götterspeise":{"count":7,"lastSeenTime":1586958784537,"difficulty":1,"difficultyWeight":5},"Injektion":{"count":5,"lastSeenTime":1586956145689},"Gewürz":{"count":12,"lastSeenTime":1586908982317,"difficulty":1,"difficultyWeight":9},"Tal":{"count":8,"lastSeenTime":1586913596578},"Seerose":{"count":8,"lastSeenTime":1586901672587,"difficulty":0.625,"difficultyWeight":8},"Erdkern":{"count":8,"lastSeenTime":1586959814583,"difficulty":0.8918918918918919,"difficultyWeight":37},"Motorrad":{"count":8,"lastSeenTime":1586914280738,"difficulty":0.9285714285714286,"difficultyWeight":14},"Billard":{"count":7,"lastSeenTime":1586915767461},"Tourist":{"count":5,"lastSeenTime":1586896203705},"Nachbar":{"count":6,"lastSeenTime":1586890615582},"Gesicht":{"count":6,"lastSeenTime":1586868886553,"difficulty":0.7058823529411765,"difficultyWeight":17},"Rick":{"count":10,"lastSeenTime":1586913893763},"detonieren":{"count":7,"lastSeenTime":1586958100659},"Elsa":{"count":7,"lastSeenTime":1586916469958,"difficulty":1,"difficultyWeight":9},"Ehefrau":{"count":2,"lastSeenTime":1586956145689},"atmen":{"count":5,"lastSeenTime":1586812666102},"Laser":{"count":5,"lastSeenTime":1586901839909},"Basketball":{"count":12,"lastSeenTime":1586909325207,"difficulty":1,"difficultyWeight":3},"Kegelrobbe":{"count":8,"lastSeenTime":1586920346900,"difficulty":1,"difficultyWeight":6},"Hagel":{"count":6,"lastSeenTime":1586897064138,"publicGameCount":1,"difficulty":0.9473684210526315,"difficultyWeight":19},"Sitzsack":{"count":9,"lastSeenTime":1586958719765,"publicGameCount":1,"difficulty":0.9024390243902439,"difficultyWeight":41},"Seuche":{"count":8,"lastSeenTime":1586954664216},"Bambi":{"count":8,"lastSeenTime":1586900739157},"Schutzhelm":{"count":6,"lastSeenTime":1586903323590},"undicht":{"count":7,"lastSeenTime":1586909063921},"Mund":{"count":6,"lastSeenTime":1586959840559},"Chips":{"count":5,"lastSeenTime":1586896769426,"difficulty":0.7857142857142857,"difficultyWeight":14},"Eis":{"count":9,"lastSeenTime":1586897078678,"difficulty":0.7435897435897436,"difficultyWeight":39},"Kühlschrank":{"count":8,"lastSeenTime":1586959391653,"difficulty":0.8771929824561403,"difficultyWeight":57},"Ehemann":{"count":10,"lastSeenTime":1586909226093},"Hammerhai":{"count":11,"lastSeenTime":1586955559002,"difficulty":1,"difficultyWeight":16},"Lasso":{"count":7,"lastSeenTime":1586902973020,"difficulty":0.8260869565217391,"difficultyWeight":23},"Elon Musk":{"count":8,"lastSeenTime":1586956273734},"Steve Jobs":{"count":9,"lastSeenTime":1586908290545},"Redner":{"count":10,"lastSeenTime":1586920690415,"difficulty":0.896551724137931,"difficultyWeight":29},"Schaukel":{"count":8,"lastSeenTime":1586913942457},"Feuerwehrmann":{"count":7,"lastSeenTime":1586891283320,"difficulty":0.9555555555555556,"difficultyWeight":45},"Atmosphäre":{"count":8,"lastSeenTime":1586904287692,"difficulty":0.9,"difficultyWeight":10},"Android":{"count":6,"lastSeenTime":1586901554174},"Frankenstein":{"count":5,"lastSeenTime":1586958748793},"Neptun":{"count":6,"lastSeenTime":1586954713056},"Bruch":{"count":5,"lastSeenTime":1586880896100,"difficulty":0.7142857142857143,"difficultyWeight":7},"Handschlag":{"count":6,"lastSeenTime":1586895467027},"Wolke":{"count":6,"lastSeenTime":1586954975722},"Schwarm":{"count":12,"lastSeenTime":1586959633128,"publicGameCount":1,"difficulty":1,"difficultyWeight":9},"Rettich":{"count":3,"lastSeenTime":1586819449062},"Kirsche":{"count":5,"lastSeenTime":1586921142411},"Anime":{"count":8,"lastSeenTime":1586955286110,"difficulty":1,"difficultyWeight":1},"Wasserschildkröte":{"count":7,"lastSeenTime":1586903673095,"difficulty":0.7777777777777778,"difficultyWeight":18},"Baguette":{"count":9,"lastSeenTime":1586959242580,"difficulty":0.9,"difficultyWeight":50},"Badewanne":{"count":6,"lastSeenTime":1586879384676,"difficulty":1,"difficultyWeight":36},"Maulkorb":{"count":8,"lastSeenTime":1586921043126},"Bullauge":{"count":8,"lastSeenTime":1586908191616},"Songtext":{"count":5,"lastSeenTime":1586908418545},"Fred Feuerstein":{"count":7,"lastSeenTime":1586920843703},"funkeln":{"count":6,"lastSeenTime":1586869723557,"difficulty":1,"difficultyWeight":5},"Fossil":{"count":8,"lastSeenTime":1586956453935},"Widder":{"count":6,"lastSeenTime":1586919477051},"Bulle":{"count":9,"lastSeenTime":1586920637722},"Welt":{"count":6,"lastSeenTime":1586914742004,"difficulty":0.5454545454545454,"difficultyWeight":11},"Surfbrett":{"count":6,"lastSeenTime":1586727413339},"Benachrichtigung":{"count":6,"lastSeenTime":1586818022119,"difficulty":1,"difficultyWeight":7},"tief":{"count":6,"lastSeenTime":1586955737202},"Richter":{"count":6,"lastSeenTime":1586782749678,"publicGameCount":1,"difficulty":0.6666666666666666,"difficultyWeight":3},"Guillotine":{"count":8,"lastSeenTime":1586915609902,"difficulty":1,"difficultyWeight":7},"Zahnlücke":{"count":5,"lastSeenTime":1586913571135,"difficulty":0.36363636363636365,"difficultyWeight":11,"publicGameCount":1},"warm":{"count":6,"lastSeenTime":1586955763543},"Nachricht":{"count":10,"lastSeenTime":1586914387880,"difficulty":1,"difficultyWeight":10},"Figur":{"count":4,"lastSeenTime":1586620030988,"difficulty":0.8076923076923077,"difficultyWeight":26},"Kartoffelpuffer":{"count":6,"lastSeenTime":1586915428040},"Sprudel":{"count":3,"lastSeenTime":1586828072825},"Radieschen":{"count":11,"lastSeenTime":1586903975283},"Pizza":{"count":5,"lastSeenTime":1586807229861,"publicGameCount":1,"difficulty":0.6818181818181818,"difficultyWeight":22},"Schulter":{"count":7,"lastSeenTime":1586916048294},"Türkei":{"count":4,"lastSeenTime":1586908304826},"Kanalisation":{"count":6,"lastSeenTime":1586913988149,"difficulty":1,"difficultyWeight":10},"Wasserpistole":{"count":6,"lastSeenTime":1586727892454,"difficulty":0.6818181818181818,"difficultyWeight":22},"Pudding":{"count":6,"lastSeenTime":1586954713056,"difficulty":1,"difficultyWeight":6},"Benzin":{"count":4,"lastSeenTime":1586706898795,"difficulty":0.9491525423728814,"difficultyWeight":59},"Spaghetti":{"count":6,"lastSeenTime":1586879335186,"difficulty":0.625,"difficultyWeight":8},"Micky Maus":{"count":6,"lastSeenTime":1586881158128,"difficulty":1,"difficultyWeight":15,"publicGameCount":1},"Mark Zuckerberg":{"count":7,"lastSeenTime":1586716859656},"Elefant":{"count":2,"lastSeenTime":1586714038574,"difficulty":0.875,"difficultyWeight":16},"Bühne":{"count":3,"lastSeenTime":1586818507852,"difficulty":0.5714285714285714,"difficultyWeight":7},"Oreo":{"count":5,"lastSeenTime":1586958375030,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Nasenbluten":{"count":5,"lastSeenTime":1586827386179,"publicGameCount":1,"difficulty":0.8823529411764706,"difficultyWeight":17},"Rapper":{"count":6,"lastSeenTime":1586959290196,"difficulty":1,"difficultyWeight":45},"Bungee Jumping":{"count":7,"lastSeenTime":1586874829202,"publicGameCount":1,"difficulty":0.625,"difficultyWeight":8},"Abend":{"count":9,"lastSeenTime":1586915115067,"difficulty":0.75,"difficultyWeight":8},"Crash Bandicoot":{"count":6,"lastSeenTime":1586900136092},"Welle":{"count":5,"lastSeenTime":1586954727368,"difficulty":0.8695652173913043,"difficultyWeight":23},"Fass":{"count":7,"lastSeenTime":1586907500591,"publicGameCount":1,"difficulty":0.7142857142857143,"difficultyWeight":7},"beten":{"count":5,"lastSeenTime":1586859052667,"difficulty":0.8181818181818182,"difficultyWeight":11},"Marionette":{"count":8,"lastSeenTime":1586956477794},"Pferdeschwanz":{"count":5,"lastSeenTime":1586904244327,"difficulty":1,"difficultyWeight":8},"Käfig":{"count":5,"lastSeenTime":1586902702172},"Dirndl":{"count":7,"lastSeenTime":1586958037635,"publicGameCount":1,"difficulty":0.85,"difficultyWeight":20},"Fensterbank":{"count":7,"lastSeenTime":1586954834961},"Laubhaufen":{"count":4,"lastSeenTime":1586959429213,"publicGameCount":1,"difficulty":0.625,"difficultyWeight":8},"frei schweben":{"count":5,"lastSeenTime":1586915236139,"difficulty":1,"difficultyWeight":10},"Lineal":{"count":7,"lastSeenTime":1586900054688,"difficulty":1,"difficultyWeight":20,"publicGameCount":1},"Mr. Meeseeks":{"count":5,"lastSeenTime":1586903133369},"Volleyball":{"count":9,"lastSeenTime":1586914918478},"Kanister":{"count":8,"lastSeenTime":1586710393999,"difficulty":0.7142857142857143,"difficultyWeight":7},"Nasenhaar":{"count":8,"lastSeenTime":1586919917033},"Apokalypse":{"count":5,"lastSeenTime":1586874424086},"Hürdenlauf":{"count":4,"lastSeenTime":1586913556716},"Sprache":{"count":8,"lastSeenTime":1586956501071,"difficulty":1,"difficultyWeight":4},"Bomberman":{"count":6,"lastSeenTime":1586874456666,"difficulty":0.75,"difficultyWeight":12},"Labyrinth":{"count":6,"lastSeenTime":1586957848254,"difficulty":1,"difficultyWeight":4},"Rasierschaum":{"count":5,"lastSeenTime":1586874742120},"Skrillex":{"count":4,"lastSeenTime":1586914501681},"Laboratorium":{"count":9,"lastSeenTime":1586958278719},"Kapitän":{"count":8,"lastSeenTime":1586954900699},"Chihuahua":{"count":8,"lastSeenTime":1586920761496,"publicGameCount":1},"giftig":{"count":5,"lastSeenTime":1586814434311},"winzig":{"count":8,"lastSeenTime":1586919868530},"Friseur":{"count":7,"lastSeenTime":1586908996510},"Weizen":{"count":5,"lastSeenTime":1586913670980,"difficulty":0.7,"difficultyWeight":10},"Trompete":{"count":9,"lastSeenTime":1586958821795,"publicGameCount":1,"difficulty":0.8125,"difficultyWeight":16},"backen":{"count":8,"lastSeenTime":1586920926700},"Brennnessel":{"count":9,"lastSeenTime":1586959557107,"difficulty":1,"difficultyWeight":9},"goldenes Ei":{"count":4,"lastSeenTime":1586880869166,"publicGameCount":1,"difficulty":0.3333333333333333,"difficultyWeight":6},"Feuerball":{"count":5,"lastSeenTime":1586908079268,"difficulty":0.75,"difficultyWeight":16},"Maikäfer":{"count":3,"lastSeenTime":1586839864880},"Clownfisch":{"count":7,"lastSeenTime":1586907361110,"difficulty":0.75,"difficultyWeight":40,"publicGameCount":1},"Sonnenbrand":{"count":9,"lastSeenTime":1586915960185},"Vitamin":{"count":5,"lastSeenTime":1586880100518},"Fastfood":{"count":6,"lastSeenTime":1586958998098},"Suppe":{"count":9,"lastSeenTime":1586956516194,"difficulty":0.625,"difficultyWeight":8},"Diener":{"count":4,"lastSeenTime":1586903271433,"difficulty":1,"difficultyWeight":2},"Diva":{"count":10,"lastSeenTime":1586909335317},"stark":{"count":9,"lastSeenTime":1586956477794,"difficulty":0.375,"difficultyWeight":8},"Eiszapfen":{"count":4,"lastSeenTime":1586901471842},"Physalis":{"count":9,"lastSeenTime":1586920069685},"Marshmallow":{"count":12,"lastSeenTime":1586959455308},"Velociraptor":{"count":10,"lastSeenTime":1586915529401,"difficulty":1,"difficultyWeight":3},"Umweltverschmutzung":{"count":4,"lastSeenTime":1586826994350},"schüchtern":{"count":7,"lastSeenTime":1586907327679},"Bayern":{"count":5,"lastSeenTime":1586869155093},"Gottesanbeterin":{"count":6,"lastSeenTime":1586916027724},"Pirat":{"count":7,"lastSeenTime":1586920737024},"Leuchtreklame":{"count":3,"lastSeenTime":1586900446863,"difficulty":1,"difficultyWeight":5},"Argentinien":{"count":7,"lastSeenTime":1586890826443},"Zug":{"count":11,"lastSeenTime":1586891319807,"publicGameCount":1,"difficulty":0.9333333333333333,"difficultyWeight":15},"Ärmel":{"count":5,"lastSeenTime":1586896252833,"difficulty":0.9,"difficultyWeight":10},"Dschungel":{"count":6,"lastSeenTime":1586832410030,"publicGameCount":1,"difficulty":1,"difficultyWeight":6},"Zigarette":{"count":12,"lastSeenTime":1586915365103,"difficulty":0.7857142857142857,"difficultyWeight":14},"Goldfisch":{"count":13,"lastSeenTime":1586907414380,"difficulty":0.7777777777777778,"difficultyWeight":18},"Junk Food":{"count":6,"lastSeenTime":1586903867648},"Löwe":{"count":9,"lastSeenTime":1586955726995,"difficulty":1,"difficultyWeight":7},"Pflaster":{"count":3,"lastSeenTime":1586955249129,"difficulty":1,"difficultyWeight":10},"zelten":{"count":2,"lastSeenTime":1586958907689,"difficulty":0.8571428571428571,"difficultyWeight":7},"Gemüse":{"count":7,"lastSeenTime":1586916153776,"difficulty":0.75,"difficultyWeight":12},"verteidigen":{"count":6,"lastSeenTime":1586921022722},"Schnauze":{"count":8,"lastSeenTime":1586839274332},"Dieb":{"count":10,"lastSeenTime":1586832874040},"Cajon":{"count":5,"lastSeenTime":1586907829080},"Saxofon":{"count":3,"lastSeenTime":1586955385136},"Turmalin":{"count":2,"lastSeenTime":1586959314784},"alt":{"count":6,"lastSeenTime":1586908731467},"Safari":{"count":5,"lastSeenTime":1586908006992},"Teich":{"count":8,"lastSeenTime":1586921142411,"publicGameCount":1,"difficulty":0.9166666666666666,"difficultyWeight":12},"Wildwasserbahn":{"count":8,"lastSeenTime":1586868482944},"Hula Hoop":{"count":6,"lastSeenTime":1586900001994,"difficulty":0.7692307692307693,"difficultyWeight":13},"Zahnpasta":{"count":2,"lastSeenTime":1586568563727,"publicGameCount":1,"difficulty":0.5238095238095238,"difficultyWeight":21},"Rindfleisch":{"count":4,"lastSeenTime":1586860097373},"Zehnagel":{"count":7,"lastSeenTime":1586914683667},"Mosaik":{"count":6,"lastSeenTime":1586896117394},"Rockstar":{"count":4,"lastSeenTime":1586726069070},"Opfer":{"count":9,"lastSeenTime":1586958697329},"Kiefer":{"count":9,"lastSeenTime":1586959106188,"difficulty":0.9285714285714286,"difficultyWeight":70},"Düne":{"count":5,"lastSeenTime":1586915406529,"difficulty":1,"difficultyWeight":17},"Urlaub":{"count":6,"lastSeenTime":1586901521530,"difficulty":0.5,"difficultyWeight":4},"Satellit":{"count":5,"lastSeenTime":1586958859906,"difficulty":0,"difficultyWeight":1},"Bargeld":{"count":3,"lastSeenTime":1586817668923},"links":{"count":8,"lastSeenTime":1586959840559},"klettern":{"count":5,"lastSeenTime":1586889515810},"Graffiti":{"count":8,"lastSeenTime":1586954914968},"Schrank":{"count":7,"lastSeenTime":1586919941975,"difficulty":0.75,"difficultyWeight":8},"Apple":{"count":10,"lastSeenTime":1586903370090},"Flasche":{"count":9,"lastSeenTime":1586958510664},"Untersetzer":{"count":6,"lastSeenTime":1586901812091,"difficulty":0.88,"difficultyWeight":25},"Rom":{"count":10,"lastSeenTime":1586908893157},"Höhlenforscher":{"count":3,"lastSeenTime":1586812916765},"Picasso":{"count":9,"lastSeenTime":1586897236338,"difficulty":1,"difficultyWeight":6},"Türsteher":{"count":6,"lastSeenTime":1586916101564},"Ukulele":{"count":5,"lastSeenTime":1586920797958,"difficulty":0.8571428571428571,"difficultyWeight":14},"Medaille":{"count":4,"lastSeenTime":1586724733005,"difficulty":0.9830508474576272,"difficultyWeight":59},"Cousin":{"count":6,"lastSeenTime":1586879212090},"Bongo":{"count":8,"lastSeenTime":1586881205453,"difficulty":0.45454545454545453,"difficultyWeight":11},"jung":{"count":10,"lastSeenTime":1586902787660,"publicGameCount":1,"difficulty":0.6666666666666667,"difficultyWeight":9},"Computer":{"count":7,"lastSeenTime":1586907977622,"publicGameCount":1,"difficulty":0.9285714285714286,"difficultyWeight":14},"Schotter":{"count":6,"lastSeenTime":1586903429291},"Flöte":{"count":5,"lastSeenTime":1586908480352,"difficulty":0.9166666666666666,"difficultyWeight":12},"Eselsohr":{"count":8,"lastSeenTime":1586879959531,"publicGameCount":1,"difficulty":0.9333333333333333,"difficultyWeight":45},"Rezeptionist":{"count":5,"lastSeenTime":1586874966390},"Junge":{"count":10,"lastSeenTime":1586958582243},"Straßenbahn":{"count":6,"lastSeenTime":1586920843703,"difficulty":1,"difficultyWeight":37},"Murmeln":{"count":7,"lastSeenTime":1586956545635},"Schere":{"count":9,"lastSeenTime":1586869695200,"publicGameCount":1,"difficulty":0.47058823529411764,"difficultyWeight":17},"Heckspoiler":{"count":4,"lastSeenTime":1586955958335},"verdampfen":{"count":10,"lastSeenTime":1586955701781},"Truthahn":{"count":13,"lastSeenTime":1586958335993},"Avocado":{"count":9,"lastSeenTime":1586915960185,"difficulty":0.7,"difficultyWeight":10},"gestresst":{"count":6,"lastSeenTime":1586916023587},"Sonne":{"count":10,"lastSeenTime":1586958719765,"difficulty":0.5238095238095238,"difficultyWeight":21,"publicGameCount":1},"Diät":{"count":5,"lastSeenTime":1586896181329},"traurig":{"count":10,"lastSeenTime":1586955138676,"difficulty":0.6666666666666666,"difficultyWeight":6},"Elch":{"count":7,"lastSeenTime":1586916027724,"difficulty":0.5,"difficultyWeight":8},"Luftmatratze":{"count":4,"lastSeenTime":1586840877832,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":8},"Rubin":{"count":3,"lastSeenTime":1586904161945,"difficulty":0.9285714285714286,"difficultyWeight":14,"publicGameCount":1},"Waschlappen":{"count":7,"lastSeenTime":1586908504643},"Eselsbrücke":{"count":4,"lastSeenTime":1586813267167,"difficulty":0.8387096774193549,"difficultyWeight":62},"Eistee":{"count":9,"lastSeenTime":1586908118744},"Reise":{"count":10,"lastSeenTime":1586880290728},"Glücksspiel":{"count":5,"lastSeenTime":1586891062617,"difficulty":1,"difficultyWeight":7},"Party":{"count":5,"lastSeenTime":1586826796918,"difficulty":0.7674418604651163,"difficultyWeight":43},"Feuerzeug":{"count":8,"lastSeenTime":1586959207698,"difficulty":1,"difficultyWeight":7},"Trend":{"count":6,"lastSeenTime":1586895477389},"Schlüsselbund":{"count":4,"lastSeenTime":1586840879616},"Zeuge":{"count":2,"lastSeenTime":1586896530203},"Einschlag":{"count":6,"lastSeenTime":1586955224835},"Tablet":{"count":12,"lastSeenTime":1586958755749},"Aussichtspunkt":{"count":12,"lastSeenTime":1586920576642,"difficulty":0.6875,"difficultyWeight":16},"Käfer":{"count":8,"lastSeenTime":1586890093454},"Gänseblümchen":{"count":12,"lastSeenTime":1586956263288,"difficulty":1,"difficultyWeight":10},"ABBA":{"count":5,"lastSeenTime":1586959728501},"Desoxyribonukleinsäure":{"count":7,"lastSeenTime":1586815682131},"draußen":{"count":5,"lastSeenTime":1586920119062},"Präsident":{"count":5,"lastSeenTime":1586815439060},"Tuba":{"count":6,"lastSeenTime":1586908204031},"betrügen":{"count":8,"lastSeenTime":1586880201224},"Kleeblatt":{"count":13,"lastSeenTime":1586959753084,"difficulty":0.7833333333333333,"difficultyWeight":60},"Fahrrad":{"count":3,"lastSeenTime":1586707253394},"Seestern":{"count":12,"lastSeenTime":1586921241738,"difficulty":0.5,"difficultyWeight":12,"publicGameCount":1},"Comic":{"count":5,"lastSeenTime":1586874869836},"Safe":{"count":6,"lastSeenTime":1586916266718},"Tschechien":{"count":3,"lastSeenTime":1586707005648,"difficulty":0.7,"difficultyWeight":10},"Baum":{"count":6,"lastSeenTime":1586908996510,"publicGameCount":1,"difficulty":1,"difficultyWeight":10},"W-LAN":{"count":7,"lastSeenTime":1586959622590},"Pokemon":{"count":9,"lastSeenTime":1586957940022},"Gehirnwäsche":{"count":9,"lastSeenTime":1586904343119},"Patriot":{"count":12,"lastSeenTime":1586914845805},"Schwimmbad":{"count":9,"lastSeenTime":1586869648250,"publicGameCount":2,"difficulty":0.75,"difficultyWeight":16},"Limousine":{"count":6,"lastSeenTime":1586959391653},"Gesichtsbemalung":{"count":9,"lastSeenTime":1586919941975},"Paprika":{"count":4,"lastSeenTime":1586895689435},"Absperrband":{"count":8,"lastSeenTime":1586889393401},"Kamm":{"count":7,"lastSeenTime":1586904357384,"difficulty":0.85,"difficultyWeight":20},"Irland":{"count":2,"lastSeenTime":1586889696772},"Föhn":{"count":7,"lastSeenTime":1586959168567},"Rose":{"count":7,"lastSeenTime":1586959106188,"difficulty":0.9090909090909091,"difficultyWeight":11},"Seilrutsche":{"count":10,"lastSeenTime":1586920285874},"Herbst":{"count":6,"lastSeenTime":1586959533143,"difficulty":1,"difficultyWeight":4},"Apfel":{"count":9,"lastSeenTime":1586909335317},"Fahnenstange":{"count":5,"lastSeenTime":1586903221605},"Skateboard":{"count":6,"lastSeenTime":1586915392140},"spucken":{"count":3,"lastSeenTime":1586723813838},"Meerjungfrau":{"count":8,"lastSeenTime":1586914109258,"publicGameCount":1,"difficulty":0.5,"difficultyWeight":8},"Löwenzahn":{"count":4,"lastSeenTime":1586834155226,"difficulty":0.7777777777777778,"difficultyWeight":9},"Armbanduhr":{"count":9,"lastSeenTime":1586909311071,"publicGameCount":2,"difficulty":0.6666666666666666,"difficultyWeight":6},"Fabrik":{"count":2,"lastSeenTime":1586633994738},"Berühmtheit":{"count":6,"lastSeenTime":1586955938117},"NASCAR":{"count":4,"lastSeenTime":1586713655448},"Urknall":{"count":4,"lastSeenTime":1586812433787},"Nest":{"count":7,"lastSeenTime":1586919750850,"difficulty":0.8571428571428571,"difficultyWeight":14},"Bernstein":{"count":13,"lastSeenTime":1586959585641,"difficulty":1,"difficultyWeight":4},"Auge":{"count":19,"lastSeenTime":1586920265574,"difficulty":0.5789473684210527,"difficultyWeight":19,"publicGameCount":1},"Skispringen":{"count":4,"lastSeenTime":1586954588805},"Sphinx":{"count":4,"lastSeenTime":1586881119264},"Wind":{"count":7,"lastSeenTime":1586919968806,"difficulty":1,"difficultyWeight":16},"Piratenschiff":{"count":4,"lastSeenTime":1586900828046,"difficulty":0.9459459459459459,"difficultyWeight":37},"Twitter":{"count":10,"lastSeenTime":1586958848321,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":10},"genau":{"count":8,"lastSeenTime":1586826669362,"difficulty":1,"difficultyWeight":3},"Pelikan":{"count":5,"lastSeenTime":1586954698858,"difficulty":1,"difficultyWeight":2},"Katastrophe":{"count":4,"lastSeenTime":1586914754340},"Hotdog":{"count":5,"lastSeenTime":1586908838335},"Sport":{"count":6,"lastSeenTime":1586813898884},"Toilette":{"count":5,"lastSeenTime":1586873774235,"difficulty":0.9166666666666666,"difficultyWeight":12},"Schranke":{"count":6,"lastSeenTime":1586903059681},"lustig":{"count":6,"lastSeenTime":1586858614527},"Fleischbällchen":{"count":7,"lastSeenTime":1586958385310,"difficulty":1,"difficultyWeight":6},"Strudel":{"count":5,"lastSeenTime":1586959193290},"Spiegelei":{"count":7,"lastSeenTime":1586869103569,"difficulty":0.6666666666666667,"difficultyWeight":9},"Einhorn":{"count":10,"lastSeenTime":1586901028464,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":8},"Rücken":{"count":6,"lastSeenTime":1586959417006,"difficulty":1,"difficultyWeight":36},"pflügen":{"count":5,"lastSeenTime":1586908054437},"Goofy":{"count":9,"lastSeenTime":1586959789851},"Seifenoper":{"count":4,"lastSeenTime":1586902616627},"Kopflaus":{"count":3,"lastSeenTime":1586879608242},"Traumfänger":{"count":5,"lastSeenTime":1586903097380},"Kernspintomografie":{"count":6,"lastSeenTime":1586921270600},"klingen":{"count":5,"lastSeenTime":1586914243836},"Kaulquappe":{"count":6,"lastSeenTime":1586913698511,"difficulty":0.8823529411764706,"difficultyWeight":17},"vorspulen":{"count":6,"lastSeenTime":1586913816802},"Augenlid":{"count":10,"lastSeenTime":1586957950175},"Panda":{"count":11,"lastSeenTime":1586920637722},"Singapur":{"count":5,"lastSeenTime":1586840929412},"Zauberer":{"count":6,"lastSeenTime":1586955238992},"Himbeere":{"count":10,"lastSeenTime":1586909016736},"Cerberus":{"count":7,"lastSeenTime":1586959830012},"Pfirsich":{"count":5,"lastSeenTime":1586806870118},"Dachs":{"count":2,"lastSeenTime":1586914418213},"bleichen":{"count":6,"lastSeenTime":1586881168379},"Photoshop":{"count":7,"lastSeenTime":1586899941163},"Hut":{"count":7,"lastSeenTime":1586955344691},"Text":{"count":6,"lastSeenTime":1586959269543},"Jesus":{"count":3,"lastSeenTime":1586880616380,"difficulty":0.8888888888888888,"difficultyWeight":9},"stehen":{"count":8,"lastSeenTime":1586957974879},"Chinatown":{"count":4,"lastSeenTime":1586832383649},"Tausendfüßer":{"count":11,"lastSeenTime":1586903624140,"difficulty":0.6,"difficultyWeight":10},"Schlitten":{"count":8,"lastSeenTime":1586873964321,"difficulty":0.7647058823529411,"difficultyWeight":34},"Rakete":{"count":12,"lastSeenTime":1586955838030,"difficulty":1,"difficultyWeight":104},"Glatze":{"count":4,"lastSeenTime":1586891242624,"difficulty":0.7441860465116279,"difficultyWeight":43},"Kopie":{"count":8,"lastSeenTime":1586955392320},"älter":{"count":10,"lastSeenTime":1586955634694},"Weihnachtsbaum":{"count":7,"lastSeenTime":1586913606771,"difficulty":0.6,"difficultyWeight":5},"Ruder":{"count":5,"lastSeenTime":1586897420912,"difficulty":0.8333333333333334,"difficultyWeight":24},"Ecke":{"count":7,"lastSeenTime":1586920576642},"Bohne":{"count":8,"lastSeenTime":1586958998098},"Apotheker":{"count":9,"lastSeenTime":1586915566245,"difficulty":0.8333333333333334,"difficultyWeight":18},"Scherzkeks":{"count":5,"lastSeenTime":1586955654939},"Küste":{"count":9,"lastSeenTime":1586900749848,"publicGameCount":1,"difficulty":0.625,"difficultyWeight":8},"anzünden":{"count":8,"lastSeenTime":1586958027091,"difficulty":0.8,"difficultyWeight":20},"googeln":{"count":7,"lastSeenTime":1586920133284,"difficulty":1,"difficultyWeight":6},"wackeln":{"count":4,"lastSeenTime":1586873308659},"Roter Teppich":{"count":3,"lastSeenTime":1586890539988,"difficulty":1,"difficultyWeight":3},"Scheune":{"count":6,"lastSeenTime":1586920034941},"Schlachter":{"count":5,"lastSeenTime":1586873642917},"Vogelscheuche":{"count":7,"lastSeenTime":1586959417006,"publicGameCount":1,"difficulty":0.5714285714285714,"difficultyWeight":14},"Sauerstoff":{"count":5,"lastSeenTime":1586897343815},"Ente":{"count":4,"lastSeenTime":1586914831496,"difficulty":0.9333333333333333,"difficultyWeight":15},"blind":{"count":6,"lastSeenTime":1586859567294,"difficulty":0.7222222222222222,"difficultyWeight":18},"Blasebalg":{"count":9,"lastSeenTime":1586920483192,"difficulty":1,"difficultyWeight":6},"Kathedrale":{"count":7,"lastSeenTime":1586915624112},"Altglascontainer":{"count":2,"lastSeenTime":1586619769643},"Poster":{"count":11,"lastSeenTime":1586955913834,"difficulty":0.5,"difficultyWeight":8},"rot":{"count":6,"lastSeenTime":1586900776963},"Windel":{"count":5,"lastSeenTime":1586726463833},"Bösewicht":{"count":4,"lastSeenTime":1586903915052},"Bettwanze":{"count":7,"lastSeenTime":1586915006438},"schwingen":{"count":10,"lastSeenTime":1586956009184,"difficulty":0.9166666666666666,"difficultyWeight":12},"Kaffee":{"count":9,"lastSeenTime":1586908494479},"Tennis":{"count":5,"lastSeenTime":1586710847152},"Priester":{"count":7,"lastSeenTime":1586955517664},"elektrisch":{"count":3,"lastSeenTime":1586914280738},"Schneeflocke":{"count":10,"lastSeenTime":1586921032863,"difficulty":0.5714285714285714,"difficultyWeight":7},"Bus":{"count":7,"lastSeenTime":1586956453935},"Kindergarten":{"count":5,"lastSeenTime":1586900125985},"Goblin":{"count":4,"lastSeenTime":1586869879731},"Revolver":{"count":9,"lastSeenTime":1586956489403},"Versteck":{"count":6,"lastSeenTime":1586902853216},"Polarlicht":{"count":12,"lastSeenTime":1586907486194,"difficulty":0.8431372549019608,"difficultyWeight":51},"Speer":{"count":8,"lastSeenTime":1586913581904},"befehlen":{"count":5,"lastSeenTime":1586726791412},"Beute":{"count":5,"lastSeenTime":1586879469524},"Möhre":{"count":10,"lastSeenTime":1586954713056},"MTV":{"count":13,"lastSeenTime":1586914373601},"Nutella":{"count":4,"lastSeenTime":1586869069583,"difficulty":1,"difficultyWeight":2},"Grinsen":{"count":6,"lastSeenTime":1586959121500,"difficulty":1,"difficultyWeight":8},"saufen":{"count":3,"lastSeenTime":1586726288386},"Koralle":{"count":14,"lastSeenTime":1586955224835},"Ende":{"count":3,"lastSeenTime":1586813572686,"difficulty":0.6666666666666666,"difficultyWeight":3},"Halbinsel":{"count":6,"lastSeenTime":1586869576824},"Wasserfall":{"count":5,"lastSeenTime":1586916565022,"difficulty":0.6666666666666666,"difficultyWeight":9,"publicGameCount":1},"Fuß":{"count":3,"lastSeenTime":1586909104982},"Thermometer":{"count":4,"lastSeenTime":1586897053852},"Chat":{"count":6,"lastSeenTime":1586838997852,"difficulty":0.7058823529411765,"difficultyWeight":17},"Werbespot":{"count":4,"lastSeenTime":1586726387745},"Gebrauchtwagenhändler":{"count":9,"lastSeenTime":1586920538046,"difficulty":1,"difficultyWeight":10},"Fisch":{"count":11,"lastSeenTime":1586916404987,"difficulty":1,"difficultyWeight":36},"zerreißen":{"count":5,"lastSeenTime":1586919697403,"difficulty":1,"difficultyWeight":10},"Schaufensterpuppe":{"count":7,"lastSeenTime":1586916382544},"Tapete":{"count":11,"lastSeenTime":1586903246007,"difficulty":0.6111111111111112,"difficultyWeight":18},"Ober":{"count":8,"lastSeenTime":1586955809521,"difficulty":1,"difficultyWeight":4},"Diplom":{"count":7,"lastSeenTime":1586916252219},"Strahlung":{"count":8,"lastSeenTime":1586900895312},"stechen":{"count":10,"lastSeenTime":1586958642478},"Espresso":{"count":5,"lastSeenTime":1586909006610,"difficulty":0.8333333333333334,"difficultyWeight":18},"Rutsche":{"count":6,"lastSeenTime":1586868015613},"skribbl.io":{"count":4,"lastSeenTime":1586832435328},"kurz":{"count":10,"lastSeenTime":1586907668803},"Wörterbuch":{"count":4,"lastSeenTime":1586727362775,"difficulty":1,"difficultyWeight":17},"Mont Blanc":{"count":6,"lastSeenTime":1586815159300},"Hamster":{"count":7,"lastSeenTime":1586869613566},"Artist":{"count":3,"lastSeenTime":1586914869480},"Champion":{"count":3,"lastSeenTime":1586817823665,"difficulty":0.875,"difficultyWeight":8},"Addition":{"count":6,"lastSeenTime":1586956253026},"Haselnuss":{"count":6,"lastSeenTime":1586921096637},"Oktoberfest":{"count":8,"lastSeenTime":1586955862348},"Kürbislaterne":{"count":6,"lastSeenTime":1586900927708},"Glücksrad":{"count":9,"lastSeenTime":1586818937722},"schielen":{"count":3,"lastSeenTime":1586596228156},"zerren":{"count":10,"lastSeenTime":1586955409372},"Hockey":{"count":4,"lastSeenTime":1586900226190,"difficulty":0.8636363636363636,"difficultyWeight":22},"Keller":{"count":3,"lastSeenTime":1586839939626},"Playstation":{"count":9,"lastSeenTime":1586915493381,"difficulty":0.7692307692307693,"difficultyWeight":13},"Bugs Bunny":{"count":5,"lastSeenTime":1586954698858},"Spender":{"count":7,"lastSeenTime":1586784575401},"Flaschendrehen":{"count":6,"lastSeenTime":1586879929914,"publicGameCount":1,"difficulty":0.7,"difficultyWeight":10},"Stuhlbein":{"count":7,"lastSeenTime":1586900412247,"difficulty":1,"difficultyWeight":32},"angreifen":{"count":4,"lastSeenTime":1586827564451},"Popeye":{"count":6,"lastSeenTime":1586873629254},"Verbrecher":{"count":8,"lastSeenTime":1586916342434,"difficulty":0.8,"difficultyWeight":5},"Federmäppchen":{"count":5,"lastSeenTime":1586902813258},"BMX":{"count":6,"lastSeenTime":1586916266718},"Chamäleon":{"count":8,"lastSeenTime":1586880818922,"difficulty":0.8571428571428571,"difficultyWeight":14},"Europa":{"count":5,"lastSeenTime":1586873585720},"Sattelschlepper":{"count":6,"lastSeenTime":1586828072825},"Magma":{"count":5,"lastSeenTime":1586717707336,"difficulty":1,"difficultyWeight":8},"Beule":{"count":6,"lastSeenTime":1586859604461},"Jalapeno":{"count":5,"lastSeenTime":1586869197437},"Detektiv":{"count":7,"lastSeenTime":1586913497512},"Ei":{"count":8,"lastSeenTime":1586859308294,"difficulty":0.6666666666666666,"difficultyWeight":48},"Storch":{"count":3,"lastSeenTime":1586895909639},"Gasse":{"count":4,"lastSeenTime":1586958873120,"difficulty":1,"difficultyWeight":9},"Champagner":{"count":7,"lastSeenTime":1586920676259},"Werbung":{"count":7,"lastSeenTime":1586914094806,"difficulty":0.9565217391304348,"difficultyWeight":46},"Hulk":{"count":3,"lastSeenTime":1586880213361,"difficulty":1,"difficultyWeight":8},"Mafia":{"count":7,"lastSeenTime":1586920153587,"difficulty":1,"difficultyWeight":8},"Strandkorb":{"count":9,"lastSeenTime":1586956016971},"kitzeln":{"count":8,"lastSeenTime":1586920883005},"Mexiko":{"count":6,"lastSeenTime":1586879731749},"Hochzeitskutsche":{"count":5,"lastSeenTime":1586957989157,"difficulty":1,"difficultyWeight":9},"Pastete":{"count":8,"lastSeenTime":1586819518500},"Schilf":{"count":9,"lastSeenTime":1586897164255},"Intel":{"count":11,"lastSeenTime":1586919413397},"Weihnachten":{"count":3,"lastSeenTime":1586880506505,"difficulty":1,"difficultyWeight":12},"Dose":{"count":7,"lastSeenTime":1586920237009},"Luchs":{"count":3,"lastSeenTime":1586595496641,"difficulty":1,"difficultyWeight":11},"Vogelstrauß":{"count":7,"lastSeenTime":1586902713347,"difficulty":0.9090909090909091,"difficultyWeight":11},"Stirn":{"count":2,"lastSeenTime":1586890418363},"Bar":{"count":9,"lastSeenTime":1586903925357},"Lama":{"count":9,"lastSeenTime":1586956501071},"Orchidee":{"count":3,"lastSeenTime":1586899991881},"berühmt":{"count":9,"lastSeenTime":1586909119149},"Boris Becker":{"count":2,"lastSeenTime":1586580996457,"difficulty":1,"difficultyWeight":5},"Katana":{"count":4,"lastSeenTime":1586724355196},"Riesenrad":{"count":5,"lastSeenTime":1586955681359},"Social Media":{"count":5,"lastSeenTime":1586896605134},"Voodoo":{"count":10,"lastSeenTime":1586901206044,"difficulty":1,"difficultyWeight":6},"Radar":{"count":5,"lastSeenTime":1586900301076,"difficulty":1,"difficultyWeight":5},"Tortenheber":{"count":10,"lastSeenTime":1586913827190},"Bauernhof":{"count":3,"lastSeenTime":1586901801777},"Segway":{"count":3,"lastSeenTime":1586920900377,"difficulty":0.7575757575757576,"difficultyWeight":33},"Ringelblume":{"count":4,"lastSeenTime":1586914903455},"Trophäe":{"count":7,"lastSeenTime":1586900881142},"Atem":{"count":5,"lastSeenTime":1586958012186},"Oase":{"count":7,"lastSeenTime":1586896127512},"Weinglas":{"count":3,"lastSeenTime":1586895726867,"difficulty":1,"difficultyWeight":3},"Reinkarnation":{"count":14,"lastSeenTime":1586916637868},"Matrjoschka":{"count":6,"lastSeenTime":1586915664822},"Regenmantel":{"count":6,"lastSeenTime":1586955737202},"Peppa Pig":{"count":6,"lastSeenTime":1586818357030},"Tastatur":{"count":9,"lastSeenTime":1586919394915,"difficulty":1,"difficultyWeight":8},"Samstag":{"count":13,"lastSeenTime":1586955370991,"difficulty":1,"difficultyWeight":8},"Killerwal":{"count":6,"lastSeenTime":1586895562695},"Sternfrucht":{"count":9,"lastSeenTime":1586921256075,"difficulty":0.6666666666666666,"difficultyWeight":6},"Muskel":{"count":8,"lastSeenTime":1586959695898},"erschreckend":{"count":4,"lastSeenTime":1586709223746,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":6},"Allergie":{"count":6,"lastSeenTime":1586956352310,"difficulty":0.42857142857142855,"difficultyWeight":7},"Himmel":{"count":10,"lastSeenTime":1586919736561,"difficulty":0.94,"difficultyWeight":50},"Oberteil":{"count":7,"lastSeenTime":1586958642478},"Kreide":{"count":9,"lastSeenTime":1586958973713},"Kermit":{"count":6,"lastSeenTime":1586869916885},"Eis am Stiel":{"count":4,"lastSeenTime":1586914134487},"Staffelei":{"count":8,"lastSeenTime":1586909063921,"publicGameCount":1,"difficulty":1,"difficultyWeight":32},"Kissenschlacht":{"count":7,"lastSeenTime":1586914590565},"Falle":{"count":6,"lastSeenTime":1586900828046,"difficulty":0.8421052631578947,"difficultyWeight":38},"Korb":{"count":10,"lastSeenTime":1586920346900},"Limette":{"count":6,"lastSeenTime":1586954664216,"difficulty":0.9310344827586207,"difficultyWeight":29},"Rauch":{"count":8,"lastSeenTime":1586914820916},"Helium":{"count":6,"lastSeenTime":1586916550509},"Ahorn":{"count":5,"lastSeenTime":1586890315125},"Klobrille":{"count":7,"lastSeenTime":1586903271433,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":16},"falten":{"count":5,"lastSeenTime":1586868317304,"difficulty":0.7142857142857143,"difficultyWeight":14},"Preisschild":{"count":4,"lastSeenTime":1586908189842},"Shampoo":{"count":5,"lastSeenTime":1586596511045},"Hängematte":{"count":4,"lastSeenTime":1586913783575,"difficulty":0.4444444444444444,"difficultyWeight":9},"Monaco":{"count":9,"lastSeenTime":1586955385136},"Laptop":{"count":11,"lastSeenTime":1586956545635,"difficulty":0.42857142857142855,"difficultyWeight":7},"Banane":{"count":6,"lastSeenTime":1586873408581},"Pac-Man":{"count":7,"lastSeenTime":1586889858351,"difficulty":0.9375,"difficultyWeight":16},"Radio":{"count":3,"lastSeenTime":1586727102331,"difficulty":0.7777777777777778,"difficultyWeight":36},"Mörder":{"count":3,"lastSeenTime":1586727017449,"difficulty":1,"difficultyWeight":6},"Sanduhr":{"count":7,"lastSeenTime":1586826882193,"difficulty":0.7,"difficultyWeight":10},"Jay Z":{"count":4,"lastSeenTime":1586879531452},"Einkaufswagen":{"count":8,"lastSeenTime":1586816175412,"difficulty":1,"difficultyWeight":8},"Bluterguss":{"count":7,"lastSeenTime":1586956324955,"publicGameCount":1,"difficulty":1,"difficultyWeight":7},"Green Lantern":{"count":7,"lastSeenTime":1586959595986},"Quartal":{"count":2,"lastSeenTime":1586716898363},"Spinne":{"count":8,"lastSeenTime":1586913633876,"difficulty":0.5263157894736842,"difficultyWeight":19},"Pfannkuchen":{"count":9,"lastSeenTime":1586956545635,"difficulty":0.9607843137254902,"difficultyWeight":51},"Rippe":{"count":14,"lastSeenTime":1586958471219,"difficulty":0.9166666666666666,"difficultyWeight":12},"schwarz":{"count":5,"lastSeenTime":1586954999969,"publicGameCount":1,"difficulty":0.6666666666666666,"difficultyWeight":3},"Silberbesteck":{"count":8,"lastSeenTime":1586816892701},"Russland":{"count":2,"lastSeenTime":1586568214189,"difficulty":1,"difficultyWeight":8},"Sumpf":{"count":7,"lastSeenTime":1586915428040},"Vogelbad":{"count":6,"lastSeenTime":1586903781874},"Torte":{"count":6,"lastSeenTime":1586914727219,"difficulty":0.8,"difficultyWeight":20},"Klaue":{"count":4,"lastSeenTime":1586919394915},"Sherlock Holmes":{"count":7,"lastSeenTime":1586891268927,"difficulty":1,"difficultyWeight":8},"Kronleuchter":{"count":4,"lastSeenTime":1586900076992,"difficulty":0.5714285714285714,"difficultyWeight":7},"Muskelkater":{"count":9,"lastSeenTime":1586958683104,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Land":{"count":5,"lastSeenTime":1586896155897},"Käse":{"count":2,"lastSeenTime":1586712115480,"difficulty":0.75,"difficultyWeight":4},"Vatikan":{"count":7,"lastSeenTime":1586880423720,"publicGameCount":1},"Südpol":{"count":7,"lastSeenTime":1586916317911,"difficulty":1,"difficultyWeight":12},"feiern":{"count":12,"lastSeenTime":1586955286110},"Netzwerk":{"count":8,"lastSeenTime":1586908672662,"difficulty":0.7272727272727273,"difficultyWeight":11},"Taschenlampe":{"count":5,"lastSeenTime":1586880869166,"difficulty":0.5238095238095238,"difficultyWeight":21},"Spieß":{"count":10,"lastSeenTime":1586919384885,"difficulty":0.2222222222222222,"difficultyWeight":9},"Wohnzimmer":{"count":3,"lastSeenTime":1586569967340,"publicGameCount":1},"königlich":{"count":8,"lastSeenTime":1586921180981},"Strand":{"count":8,"lastSeenTime":1586954925078,"difficulty":0.8571428571428571,"difficultyWeight":28},"Bärenfalle":{"count":8,"lastSeenTime":1586901239971},"Abfall":{"count":8,"lastSeenTime":1586807202609,"difficulty":0.84,"difficultyWeight":25,"publicGameCount":1},"LKW-Fahrer":{"count":6,"lastSeenTime":1586915354278,"difficulty":0.875,"difficultyWeight":72},"Wand":{"count":6,"lastSeenTime":1586908175585},"schwimmen":{"count":5,"lastSeenTime":1586916127462,"difficulty":0.9722222222222222,"difficultyWeight":36},"Peitsche":{"count":5,"lastSeenTime":1586914893907,"difficulty":1,"difficultyWeight":52},"Leichtsinn":{"count":8,"lastSeenTime":1586903925357},"Luftkissenboot":{"count":7,"lastSeenTime":1586958485799},"Einhornwal":{"count":8,"lastSeenTime":1586919423610},"Iron Man":{"count":5,"lastSeenTime":1586890464755,"publicGameCount":1},"Schlüssel":{"count":5,"lastSeenTime":1586834021563,"difficulty":0.4444444444444444,"difficultyWeight":9},"Basis":{"count":12,"lastSeenTime":1586874906969},"Pickel":{"count":8,"lastSeenTime":1586959695898},"unendlich":{"count":7,"lastSeenTime":1586955691477,"difficulty":0.4166666666666667,"difficultyWeight":12},"Gru":{"count":9,"lastSeenTime":1586919797630},"Trittstufe":{"count":6,"lastSeenTime":1586957855578},"Handfläche":{"count":8,"lastSeenTime":1586919640209},"jonglieren":{"count":8,"lastSeenTime":1586958658325},"Korallenriff":{"count":5,"lastSeenTime":1586916127462,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":8},"Achselhöhle":{"count":7,"lastSeenTime":1586916680436},"Taco":{"count":11,"lastSeenTime":1586920858569,"difficulty":0.7560975609756098,"difficultyWeight":41,"publicGameCount":1},"Violine":{"count":6,"lastSeenTime":1586806873561,"difficulty":0.38461538461538464,"difficultyWeight":13},"Bahnschiene":{"count":11,"lastSeenTime":1586889379582},"mürrisch":{"count":6,"lastSeenTime":1586919797630,"difficulty":0.5625,"difficultyWeight":16},"Rechnung":{"count":7,"lastSeenTime":1586879558728,"difficulty":0.975609756097561,"difficultyWeight":41},"Panzerfaust":{"count":7,"lastSeenTime":1586955125492},"Wahl":{"count":4,"lastSeenTime":1586873925511},"Farbe":{"count":6,"lastSeenTime":1586916266718},"Hafenbecken":{"count":7,"lastSeenTime":1586958264090},"Mario":{"count":6,"lastSeenTime":1586956599160},"Zahnstocher":{"count":4,"lastSeenTime":1586900670423},"Mumie":{"count":4,"lastSeenTime":1586920005337,"difficulty":1,"difficultyWeight":26},"Stativ":{"count":4,"lastSeenTime":1586900162376},"Fernglas":{"count":10,"lastSeenTime":1586921022722},"parallel":{"count":6,"lastSeenTime":1586916565022,"difficulty":1,"difficultyWeight":3},"Rüstung":{"count":7,"lastSeenTime":1586827071400},"Gang":{"count":4,"lastSeenTime":1586813707177},"Insel":{"count":8,"lastSeenTime":1586959020405,"difficulty":0.631578947368421,"difficultyWeight":19},"Versicherungskaufmann":{"count":8,"lastSeenTime":1586955088291},"Euro":{"count":7,"lastSeenTime":1586959850831},"Charlie Chaplin":{"count":12,"lastSeenTime":1586958907689,"publicGameCount":1},"Barbecue":{"count":8,"lastSeenTime":1586914554202,"difficulty":0.8,"difficultyWeight":20},"Haus":{"count":4,"lastSeenTime":1586785382597,"difficulty":0.5,"difficultyWeight":10},"Nachtclub":{"count":6,"lastSeenTime":1586881045754},"Toaster":{"count":9,"lastSeenTime":1586896242674},"Nacht":{"count":10,"lastSeenTime":1586958769937},"Elmo":{"count":8,"lastSeenTime":1586955620355},"König der Löwen":{"count":6,"lastSeenTime":1586895858023,"difficulty":1,"difficultyWeight":5},"Mona Lisa":{"count":5,"lastSeenTime":1586920751201},"Muskete":{"count":5,"lastSeenTime":1586956033779,"difficulty":0,"difficultyWeight":2},"Handgelenk":{"count":3,"lastSeenTime":1586957888650,"publicGameCount":1,"difficulty":1,"difficultyWeight":13},"Lasagne":{"count":9,"lastSeenTime":1586908494479},"KFC":{"count":7,"lastSeenTime":1586909250467},"Überlebender":{"count":10,"lastSeenTime":1586868863888},"Bandnudel":{"count":5,"lastSeenTime":1586879785134},"Lemur":{"count":10,"lastSeenTime":1586956453935},"Walross":{"count":7,"lastSeenTime":1586956197682,"difficulty":0.7142857142857143,"difficultyWeight":7},"Baseballschläger":{"count":10,"lastSeenTime":1586891023780},"Oktopus":{"count":12,"lastSeenTime":1586957837428,"difficulty":1,"difficultyWeight":6},"Rennen":{"count":6,"lastSeenTime":1586915767461,"difficulty":0.5,"difficultyWeight":10},"Mikrofon":{"count":8,"lastSeenTime":1586895872235,"publicGameCount":1,"difficulty":0.6,"difficultyWeight":10},"Bogen":{"count":6,"lastSeenTime":1586806308278},"Superman":{"count":9,"lastSeenTime":1586920336794,"publicGameCount":1,"difficulty":0.5555555555555556,"difficultyWeight":9},"Dudelsack":{"count":7,"lastSeenTime":1586914181975},"Lippen":{"count":12,"lastSeenTime":1586903726114,"difficulty":1,"difficultyWeight":9},"Fotograf":{"count":14,"lastSeenTime":1586958561895,"difficulty":1,"difficultyWeight":18},"Popcorn":{"count":8,"lastSeenTime":1586955809521,"publicGameCount":1,"difficulty":0.3333333333333333,"difficultyWeight":6},"Haarschuppen":{"count":5,"lastSeenTime":1586896700238},"vollständig":{"count":8,"lastSeenTime":1586958547642},"Batman":{"count":5,"lastSeenTime":1586914243836},"Vulkanologe":{"count":7,"lastSeenTime":1586956287941},"Geschirrschrank":{"count":3,"lastSeenTime":1586782917680},"Taschentuch":{"count":4,"lastSeenTime":1586879263241},"Lamm":{"count":8,"lastSeenTime":1586955300241,"difficulty":1,"difficultyWeight":1},"Megafon":{"count":7,"lastSeenTime":1586920651904},"Lockenwickler":{"count":4,"lastSeenTime":1586784602447},"Bienenstich":{"count":10,"lastSeenTime":1586916368116,"publicGameCount":1,"difficulty":0.4117647058823529,"difficultyWeight":17},"Ohrring":{"count":3,"lastSeenTime":1586784746074},"wütend":{"count":8,"lastSeenTime":1586920029620},"Hölle":{"count":4,"lastSeenTime":1586901682745,"difficulty":1,"difficultyWeight":11},"Plätzchen":{"count":4,"lastSeenTime":1586827227421},"Traktor":{"count":11,"lastSeenTime":1586908787449},"Skorpion":{"count":7,"lastSeenTime":1586959633128},"Fell":{"count":6,"lastSeenTime":1586955517664},"Lady Gaga":{"count":5,"lastSeenTime":1586901511433},"übergewichtig":{"count":6,"lastSeenTime":1586959117095},"Himmelbett":{"count":9,"lastSeenTime":1586914903455},"Boot":{"count":7,"lastSeenTime":1586958683104,"difficulty":0.5625,"difficultyWeight":16,"publicGameCount":1},"Chinesische Mauer":{"count":4,"lastSeenTime":1586890378764},"Link":{"count":5,"lastSeenTime":1586907863533},"Cartoon":{"count":5,"lastSeenTime":1586907707534,"publicGameCount":1,"difficulty":1,"difficultyWeight":10},"Seegurke":{"count":7,"lastSeenTime":1586897025198,"difficulty":1,"difficultyWeight":7},"Zucker":{"count":5,"lastSeenTime":1586907778315},"Bambus":{"count":6,"lastSeenTime":1586954617410},"Marathon":{"count":7,"lastSeenTime":1586955392320},"Donner":{"count":5,"lastSeenTime":1586832635442},"Schottland":{"count":5,"lastSeenTime":1586957863554},"beißen":{"count":6,"lastSeenTime":1586889525947},"Konzert":{"count":7,"lastSeenTime":1586914403534},"Vogel":{"count":2,"lastSeenTime":1586896941227,"difficulty":0.86,"difficultyWeight":50},"Maniküre":{"count":9,"lastSeenTime":1586957960523},"Personenschützer":{"count":5,"lastSeenTime":1586920094776},"Nagel":{"count":12,"lastSeenTime":1586955456078},"Flammkuchen":{"count":5,"lastSeenTime":1586896242674},"Kopftuch":{"count":5,"lastSeenTime":1586915949972,"difficulty":0.8571428571428571,"difficultyWeight":14},"Faustkampf":{"count":4,"lastSeenTime":1586816692499},"Bikini":{"count":7,"lastSeenTime":1586900635930},"schütteln":{"count":6,"lastSeenTime":1586955334605},"Klebestift":{"count":6,"lastSeenTime":1586957950175,"difficulty":1,"difficultyWeight":19},"Florist":{"count":6,"lastSeenTime":1586959522880},"Ananas":{"count":6,"lastSeenTime":1586826228383},"Oper":{"count":6,"lastSeenTime":1586916574944,"difficulty":0.5714285714285714,"difficultyWeight":7},"Klippe":{"count":5,"lastSeenTime":1586900422423},"Riese":{"count":5,"lastSeenTime":1586858562011,"difficulty":0.5,"difficultyWeight":8},"Krankenhaus":{"count":7,"lastSeenTime":1586908697152},"müde":{"count":2,"lastSeenTime":1586958171361},"prokrastinieren":{"count":3,"lastSeenTime":1586806544125},"Wrestler":{"count":6,"lastSeenTime":1586889892808},"Eiskaffee":{"count":7,"lastSeenTime":1586914270411},"Auspuff":{"count":7,"lastSeenTime":1586954925078},"erinnern":{"count":3,"lastSeenTime":1586909119149},"Walnuss":{"count":4,"lastSeenTime":1586903726114,"difficulty":0.875,"difficultyWeight":16},"Pech":{"count":8,"lastSeenTime":1586899941163,"difficulty":1,"difficultyWeight":2},"Garage":{"count":8,"lastSeenTime":1586915200929},"Lego":{"count":6,"lastSeenTime":1586838924837,"difficulty":0.6,"difficultyWeight":5},"Ballon":{"count":6,"lastSeenTime":1586908541127,"difficulty":0.72,"difficultyWeight":50},"Barkeeper":{"count":11,"lastSeenTime":1586958809891},"vergrößern":{"count":5,"lastSeenTime":1586913973573},"insolvent":{"count":9,"lastSeenTime":1586915806469},"Demonstration":{"count":4,"lastSeenTime":1586859897712,"publicGameCount":1,"difficulty":0.375,"difficultyWeight":8},"denken":{"count":4,"lastSeenTime":1586838914729},"Goldtopf":{"count":7,"lastSeenTime":1586920275708},"Wanderstock":{"count":9,"lastSeenTime":1586915417224,"difficulty":1,"difficultyWeight":20},"Papagei":{"count":8,"lastSeenTime":1586916141879},"Fledermaus":{"count":6,"lastSeenTime":1586890056241,"difficulty":1,"difficultyWeight":6},"Sudoku":{"count":1,"lastSeenTime":1586552881359,"difficulty":1,"difficultyWeight":1},"Cola":{"count":11,"lastSeenTime":1586958983867,"difficulty":1,"difficultyWeight":8},"Kakao":{"count":5,"lastSeenTime":1586904343119,"publicGameCount":1},"untergewichtig":{"count":3,"lastSeenTime":1586914491372,"difficulty":0.8421052631578947,"difficultyWeight":19},"Zeitlupe":{"count":9,"lastSeenTime":1586920053882,"difficulty":0.8888888888888888,"difficultyWeight":36},"Österreich":{"count":9,"lastSeenTime":1586915919352},"Nintendo":{"count":4,"lastSeenTime":1586913633876,"difficulty":1,"difficultyWeight":3},"Eltern":{"count":5,"lastSeenTime":1586955429782,"difficulty":0.4666666666666667,"difficultyWeight":15},"Tannenbaum":{"count":9,"lastSeenTime":1586907472056,"difficulty":1,"difficultyWeight":5},"Hyäne":{"count":7,"lastSeenTime":1586806967390,"difficulty":1,"difficultyWeight":4},"Komödie":{"count":4,"lastSeenTime":1586589955120},"Daune":{"count":8,"lastSeenTime":1586914806527},"Axt":{"count":6,"lastSeenTime":1586901361357},"Heuschrecke":{"count":5,"lastSeenTime":1586908118744,"difficulty":1,"difficultyWeight":25},"Baumkrone":{"count":8,"lastSeenTime":1586881235651},"Bier":{"count":7,"lastSeenTime":1586921059401,"publicGameCount":1,"difficulty":0.967741935483871,"difficultyWeight":93},"Maibaum":{"count":8,"lastSeenTime":1586915299932},"Haarfarbe":{"count":7,"lastSeenTime":1586959814583,"difficulty":1,"difficultyWeight":43},"Webseite":{"count":5,"lastSeenTime":1586815794279,"difficulty":0.6923076923076923,"difficultyWeight":26},"Gift":{"count":5,"lastSeenTime":1586959020405},"Buch":{"count":5,"lastSeenTime":1586956009184},"Pflug":{"count":4,"lastSeenTime":1586901375521,"difficulty":1,"difficultyWeight":4},"Blut":{"count":7,"lastSeenTime":1586958983867},"Igel":{"count":9,"lastSeenTime":1586859619922},"machomäßig":{"count":3,"lastSeenTime":1586805850042,"difficulty":0.9,"difficultyWeight":10},"Schnürsenkel":{"count":9,"lastSeenTime":1586920604951,"difficulty":0.42857142857142855,"difficultyWeight":7},"Felsen":{"count":12,"lastSeenTime":1586954834961,"difficulty":0.5882352941176471,"difficultyWeight":17,"publicGameCount":1},"Mähdrescher":{"count":5,"lastSeenTime":1586901067015},"Anglerfisch":{"count":5,"lastSeenTime":1586785741382},"Kanarienvogel":{"count":3,"lastSeenTime":1586873649256,"difficulty":1,"difficultyWeight":10},"Lautstärke":{"count":8,"lastSeenTime":1586890045700},"Dynamo":{"count":5,"lastSeenTime":1586869422590},"Brust":{"count":5,"lastSeenTime":1586897420912,"difficulty":1,"difficultyWeight":1},"Fahrer":{"count":5,"lastSeenTime":1586958561895},"Schaukelpferd":{"count":5,"lastSeenTime":1586958697329,"difficulty":1,"difficultyWeight":5},"Schatten":{"count":5,"lastSeenTime":1586840034942,"difficulty":1,"difficultyWeight":5},"Entensuppe":{"count":6,"lastSeenTime":1586897164255,"difficulty":1,"difficultyWeight":6},"Abraham Lincoln":{"count":6,"lastSeenTime":1586956599160},"Papageientaucher":{"count":11,"lastSeenTime":1586956363582},"Milch":{"count":4,"lastSeenTime":1586959193290,"difficulty":0.9166666666666666,"difficultyWeight":12},"Yeti":{"count":5,"lastSeenTime":1586955152448},"dreckig":{"count":4,"lastSeenTime":1586920552243},"Steigung":{"count":4,"lastSeenTime":1586908838335},"Schaumschläger":{"count":10,"lastSeenTime":1586955681359,"difficulty":1,"difficultyWeight":9},"Möbel":{"count":5,"lastSeenTime":1586909133282,"difficulty":1,"difficultyWeight":27},"Feueralarm":{"count":4,"lastSeenTime":1586914428482},"Fahrkarte":{"count":9,"lastSeenTime":1586904061376},"Kredit":{"count":7,"lastSeenTime":1586920972036},"Alphorn":{"count":10,"lastSeenTime":1586958278719},"Partnerlook":{"count":8,"lastSeenTime":1586916352907,"difficulty":1,"difficultyWeight":9},"Panflöte":{"count":5,"lastSeenTime":1586827260902},"Blumenkohl":{"count":5,"lastSeenTime":1586958809891},"Geist":{"count":3,"lastSeenTime":1586868785173,"difficulty":0.75,"difficultyWeight":32},"Nordpol":{"count":5,"lastSeenTime":1586958360375,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":10},"Fanta":{"count":8,"lastSeenTime":1586919783421,"difficulty":0.6666666666666666,"difficultyWeight":18},"Periskop":{"count":6,"lastSeenTime":1586915731157},"erbrechen":{"count":6,"lastSeenTime":1586954798444},"Bonbon":{"count":9,"lastSeenTime":1586915703672,"difficulty":0.625,"difficultyWeight":8,"publicGameCount":1},"Oboe":{"count":9,"lastSeenTime":1586916574944},"Schnurrbart":{"count":8,"lastSeenTime":1586914157190,"publicGameCount":1,"difficulty":0.7142857142857143,"difficultyWeight":7},"Höhlenmensch":{"count":7,"lastSeenTime":1586954975722},"Büroklammer":{"count":13,"lastSeenTime":1586959570753,"difficulty":0.7608695652173914,"difficultyWeight":46},"Tunnelblick":{"count":6,"lastSeenTime":1586958077398},"Besenstiel":{"count":3,"lastSeenTime":1586903648591,"difficulty":1,"difficultyWeight":27},"Kreuzung":{"count":8,"lastSeenTime":1586913670980,"difficulty":0.9423076923076923,"difficultyWeight":52},"Zentaur":{"count":4,"lastSeenTime":1586908583500,"difficulty":0.8,"difficultyWeight":5},"Papaya":{"count":6,"lastSeenTime":1586955263523},"Notch":{"count":4,"lastSeenTime":1586826344267},"Arm":{"count":9,"lastSeenTime":1586828011219,"difficulty":1,"difficultyWeight":6},"Dolch":{"count":8,"lastSeenTime":1586914565215},"DNS":{"count":4,"lastSeenTime":1586873397605,"difficulty":1,"difficultyWeight":2},"Seelöwe":{"count":5,"lastSeenTime":1586858858134,"difficulty":1,"difficultyWeight":6},"Blutspende":{"count":8,"lastSeenTime":1586955113604,"publicGameCount":1},"Astronaut":{"count":6,"lastSeenTime":1586959279701},"Frankreich":{"count":3,"lastSeenTime":1586596653489},"Beine":{"count":8,"lastSeenTime":1586913768003},"Logo":{"count":7,"lastSeenTime":1586920015464},"Freitag":{"count":4,"lastSeenTime":1586812381709,"publicGameCount":1,"difficulty":0.6875,"difficultyWeight":16},"Süßholz raspeln":{"count":4,"lastSeenTime":1586812346307},"Schock":{"count":4,"lastSeenTime":1586897287249},"Alufolie":{"count":8,"lastSeenTime":1586900724985,"difficulty":1,"difficultyWeight":6},"Geysir":{"count":3,"lastSeenTime":1586727718047},"Kirche":{"count":4,"lastSeenTime":1586651112698,"difficulty":0.5454545454545454,"difficultyWeight":11},"Kinderwagen":{"count":4,"lastSeenTime":1586816753545},"Kuckucksuhr":{"count":4,"lastSeenTime":1586815755534},"Grinch":{"count":10,"lastSeenTime":1586958239433,"difficulty":1,"difficultyWeight":10},"Klempner":{"count":6,"lastSeenTime":1586903531503,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":8},"Geröll":{"count":7,"lastSeenTime":1586903634298},"Hologramm":{"count":4,"lastSeenTime":1586726805561},"Rollladen":{"count":4,"lastSeenTime":1586839583890},"Dikdik":{"count":4,"lastSeenTime":1586890005207},"Gladiator":{"count":5,"lastSeenTime":1586921032863,"difficulty":0.8421052631578947,"difficultyWeight":19,"publicGameCount":1},"Brasilien":{"count":6,"lastSeenTime":1586827712672},"Glanz":{"count":4,"lastSeenTime":1586913853735},"Karte":{"count":6,"lastSeenTime":1586919287618,"difficulty":1,"difficultyWeight":15},"Silber":{"count":6,"lastSeenTime":1586896166029,"publicGameCount":1},"Sicherheitsdienst":{"count":5,"lastSeenTime":1586915949972},"Uranus":{"count":5,"lastSeenTime":1586874623611,"difficulty":1,"difficultyWeight":11},"Knöchel":{"count":9,"lastSeenTime":1586958944806},"Eiche":{"count":4,"lastSeenTime":1586920566543,"difficulty":1,"difficultyWeight":79},"Schnecke":{"count":9,"lastSeenTime":1586919773316},"Bleistift":{"count":3,"lastSeenTime":1586717347143},"Reh":{"count":5,"lastSeenTime":1586914831496,"publicGameCount":1,"difficulty":0.6,"difficultyWeight":5},"Anzug":{"count":3,"lastSeenTime":1586806231030,"difficulty":1,"difficultyWeight":5},"Süden":{"count":5,"lastSeenTime":1586782502910,"difficulty":0.2222222222222222,"difficultyWeight":9},"Spitzer":{"count":5,"lastSeenTime":1586958375030},"lesen":{"count":5,"lastSeenTime":1586958973713,"difficulty":0.8387096774193549,"difficultyWeight":31},"Köder":{"count":3,"lastSeenTime":1586832725500,"difficulty":1,"difficultyWeight":1},"Nike":{"count":9,"lastSeenTime":1586959492934,"difficulty":0.7857142857142857,"difficultyWeight":14},"Vault boy":{"count":3,"lastSeenTime":1586907877908},"Handy":{"count":6,"lastSeenTime":1586890188914,"difficulty":1,"difficultyWeight":1},"Garten":{"count":6,"lastSeenTime":1586901605672},"Fuchs":{"count":3,"lastSeenTime":1586920566543,"difficulty":0.8666666666666667,"difficultyWeight":30},"Musik":{"count":3,"lastSeenTime":1586879877998,"difficulty":1,"difficultyWeight":6},"niedrig":{"count":8,"lastSeenTime":1586880759383},"Scheibenwischer":{"count":9,"lastSeenTime":1586959304612},"Roboter":{"count":6,"lastSeenTime":1586909133282},"Säge":{"count":2,"lastSeenTime":1586633399505,"difficulty":0.4,"difficultyWeight":10},"blau":{"count":9,"lastSeenTime":1586914403534,"publicGameCount":1,"difficulty":0.96875,"difficultyWeight":32},"Treibsand":{"count":7,"lastSeenTime":1586959695898},"Segelflieger":{"count":5,"lastSeenTime":1586954774095},"Zahnseide":{"count":4,"lastSeenTime":1586903333845},"glühen":{"count":5,"lastSeenTime":1586818299882},"Inuit":{"count":10,"lastSeenTime":1586914258463},"Flaschenpost":{"count":6,"lastSeenTime":1586907451820},"Christbaumkugel":{"count":8,"lastSeenTime":1586957903080},"Hummer":{"count":12,"lastSeenTime":1586958052113},"Vin Diesel":{"count":10,"lastSeenTime":1586915186679},"offen":{"count":6,"lastSeenTime":1586889697457},"Windmühle":{"count":3,"lastSeenTime":1586833318970,"difficulty":0.9166666666666666,"difficultyWeight":24},"fernsehen":{"count":5,"lastSeenTime":1586915846579},"Zeitmaschine":{"count":7,"lastSeenTime":1586897211835},"Tasche":{"count":5,"lastSeenTime":1586858696188,"publicGameCount":1,"difficulty":1,"difficultyWeight":10},"Abendessen":{"count":8,"lastSeenTime":1586903965187,"difficulty":0.75,"difficultyWeight":8},"Moskito":{"count":11,"lastSeenTime":1586959714261,"difficulty":0.5714285714285714,"difficultyWeight":7},"Lava":{"count":8,"lastSeenTime":1586902766371,"difficulty":1,"difficultyWeight":6},"Eingabestift":{"count":5,"lastSeenTime":1586915021163},"Tropfen":{"count":4,"lastSeenTime":1586958748793,"difficulty":0.875,"difficultyWeight":40},"Zoowärter":{"count":8,"lastSeenTime":1586959290196,"difficulty":1,"difficultyWeight":3},"Flugzeug":{"count":4,"lastSeenTime":1586915149693},"doppelt":{"count":4,"lastSeenTime":1586806127412},"Senf":{"count":5,"lastSeenTime":1586900422423},"Klassenzimmer":{"count":5,"lastSeenTime":1586908801649,"difficulty":0.75,"difficultyWeight":4},"schminken":{"count":7,"lastSeenTime":1586955209647},"Knoten":{"count":6,"lastSeenTime":1586909005772},"kahl":{"count":7,"lastSeenTime":1586957903080},"Ketchup":{"count":6,"lastSeenTime":1586875034252,"publicGameCount":1,"difficulty":0.5555555555555556,"difficultyWeight":9},"Armbrust":{"count":5,"lastSeenTime":1586897226069},"Kehle":{"count":5,"lastSeenTime":1586900524596},"Deckenventilator":{"count":7,"lastSeenTime":1586815355269},"Hobbit":{"count":2,"lastSeenTime":1586784590637,"difficulty":1,"difficultyWeight":18},"Boxer":{"count":5,"lastSeenTime":1586814868590,"difficulty":1,"difficultyWeight":1},"Lupe":{"count":9,"lastSeenTime":1586897078678,"difficulty":1,"difficultyWeight":24},"Steinbock":{"count":8,"lastSeenTime":1586914631184,"difficulty":0.9696969696969697,"difficultyWeight":33},"Tor":{"count":7,"lastSeenTime":1586958636395,"difficulty":1,"difficultyWeight":10},"Kneipe":{"count":10,"lastSeenTime":1586890339661,"difficulty":0.8,"difficultyWeight":15},"Zement":{"count":7,"lastSeenTime":1586895733096},"Träne":{"count":8,"lastSeenTime":1586873585720,"difficulty":0.7222222222222222,"difficultyWeight":18},"Veranda":{"count":7,"lastSeenTime":1586954727368},"Oberarm":{"count":3,"lastSeenTime":1586806833684},"Marmelade":{"count":7,"lastSeenTime":1586903836685,"difficulty":1,"difficultyWeight":40},"Banjo":{"count":8,"lastSeenTime":1586958200965},"Herz":{"count":7,"lastSeenTime":1586879684720,"difficulty":0.8695652173913043,"difficultyWeight":23,"publicGameCount":1},"Vision":{"count":10,"lastSeenTime":1586907654631},"Katze":{"count":7,"lastSeenTime":1586874013016},"Knopf":{"count":2,"lastSeenTime":1586710517071,"difficulty":0.4166666666666667,"difficultyWeight":12},"biegen":{"count":7,"lastSeenTime":1586916455715},"Prüfung":{"count":9,"lastSeenTime":1586955948209},"Psychologe":{"count":6,"lastSeenTime":1586959585641},"zusammenzucken":{"count":10,"lastSeenTime":1586915354278},"Baumhaus":{"count":5,"lastSeenTime":1586909260571,"difficulty":1,"difficultyWeight":5},"Alpaka":{"count":12,"lastSeenTime":1586900125985},"Hieroglyphen":{"count":12,"lastSeenTime":1586958596468},"Saugglocke":{"count":7,"lastSeenTime":1586832373335},"Kasino":{"count":8,"lastSeenTime":1586915974465},"Funke":{"count":7,"lastSeenTime":1586955385136,"difficulty":1,"difficultyWeight":10},"Venus":{"count":10,"lastSeenTime":1586959076238,"difficulty":0.7,"difficultyWeight":20},"Feuersalamander":{"count":1,"lastSeenTime":1586561707947},"Lebensmittel":{"count":3,"lastSeenTime":1586726805561,"difficulty":1,"difficultyWeight":3},"Säule":{"count":4,"lastSeenTime":1586895477389,"difficulty":0.6666666666666666,"difficultyWeight":6},"dürr":{"count":3,"lastSeenTime":1586955913834},"Audi":{"count":6,"lastSeenTime":1586880818922,"difficulty":1,"difficultyWeight":6},"langsam":{"count":3,"lastSeenTime":1586709182856},"Lutscher":{"count":7,"lastSeenTime":1586869733694},"haarig":{"count":5,"lastSeenTime":1586889811471,"publicGameCount":1,"difficulty":0.6666666666666666,"difficultyWeight":15},"Monobraue":{"count":9,"lastSeenTime":1586958697329},"bekifft":{"count":10,"lastSeenTime":1586915716336},"Elfenbein":{"count":11,"lastSeenTime":1586959090713},"Medusa":{"count":4,"lastSeenTime":1586832990793},"Schlumpf":{"count":6,"lastSeenTime":1586916164227,"publicGameCount":1},"Muschel":{"count":16,"lastSeenTime":1586959232575,"publicGameCount":1,"difficulty":0.3333333333333333,"difficultyWeight":6},"Kartoffel":{"count":4,"lastSeenTime":1586901839909},"Maler":{"count":7,"lastSeenTime":1586908838335},"stoßen":{"count":5,"lastSeenTime":1586901166652},"Nemo":{"count":4,"lastSeenTime":1586954910317,"publicGameCount":1,"difficulty":1,"difficultyWeight":15},"Schimpanse":{"count":6,"lastSeenTime":1586879248947,"difficulty":0.7777777777777778,"difficultyWeight":9},"schlafen":{"count":7,"lastSeenTime":1586956048018,"difficulty":0.4,"difficultyWeight":5},"Einzelhandel":{"count":5,"lastSeenTime":1586879799373,"publicGameCount":1},"Frühling":{"count":8,"lastSeenTime":1586957837428,"difficulty":0.3333333333333333,"difficultyWeight":6},"Corn Flakes":{"count":5,"lastSeenTime":1586919687264,"difficulty":0.875,"difficultyWeight":8},"Tarzan":{"count":7,"lastSeenTime":1586959455308},"Baumstumpf":{"count":7,"lastSeenTime":1586902713347},"schneiden":{"count":7,"lastSeenTime":1586919348003},"Kopfhörer":{"count":7,"lastSeenTime":1586955609964,"difficulty":1,"difficultyWeight":6},"Suppenkelle":{"count":3,"lastSeenTime":1586959482662},"Paralleluniversum":{"count":5,"lastSeenTime":1586826400303},"Friedhof":{"count":8,"lastSeenTime":1586954627819,"difficulty":1,"difficultyWeight":6},"Auster":{"count":5,"lastSeenTime":1586958100659},"Flammenwerfer":{"count":6,"lastSeenTime":1586956599160},"Bürgersteig":{"count":4,"lastSeenTime":1586913482555},"Luxemburg":{"count":5,"lastSeenTime":1586890217261},"Hotel":{"count":6,"lastSeenTime":1586816892701},"Spirale":{"count":3,"lastSeenTime":1586706667073},"schauen":{"count":7,"lastSeenTime":1586879469524},"Lavalampe":{"count":3,"lastSeenTime":1586807857048,"difficulty":1,"difficultyWeight":3},"Nussschale":{"count":6,"lastSeenTime":1586895833706},"Kette":{"count":6,"lastSeenTime":1586956048018},"Trinkgeld":{"count":4,"lastSeenTime":1586868835247},"Leuchtturm":{"count":6,"lastSeenTime":1586896740857},"Fingernagel":{"count":10,"lastSeenTime":1586903359622},"Weinrebe":{"count":5,"lastSeenTime":1586834116405},"Raum":{"count":6,"lastSeenTime":1586955238992},"Clown":{"count":8,"lastSeenTime":1586907400222},"Granate":{"count":5,"lastSeenTime":1586919664805,"difficulty":0.6,"difficultyWeight":5},"William Wallace":{"count":5,"lastSeenTime":1586914080489},"Rückenschmerzen":{"count":9,"lastSeenTime":1586920872823},"Tasse":{"count":5,"lastSeenTime":1586834116405,"difficulty":0.25,"difficultyWeight":8},"Nagelpflege":{"count":6,"lastSeenTime":1586914729019},"Torpedo":{"count":5,"lastSeenTime":1586956181125,"publicGameCount":1,"difficulty":0.5714285714285714,"difficultyWeight":7},"Glitzer":{"count":4,"lastSeenTime":1586919460885,"difficulty":0.8,"difficultyWeight":10},"Wiesel":{"count":9,"lastSeenTime":1586955286110},"schweben":{"count":9,"lastSeenTime":1586919773316,"difficulty":0.8378378378378378,"difficultyWeight":37},"Mücke":{"count":6,"lastSeenTime":1586904248334},"Schatz":{"count":6,"lastSeenTime":1586815563232},"Hahn":{"count":7,"lastSeenTime":1586833201869,"difficulty":0.75,"difficultyWeight":32},"Essiggurke":{"count":5,"lastSeenTime":1586919610641},"Glühbirne":{"count":4,"lastSeenTime":1586913868342,"difficulty":0.96,"difficultyWeight":50},"Deodorant":{"count":5,"lastSeenTime":1586826254067,"difficulty":0.4,"difficultyWeight":5},"Harfe":{"count":6,"lastSeenTime":1586919327173,"difficulty":0.8421052631578947,"difficultyWeight":19},"umarmen":{"count":7,"lastSeenTime":1586921094172,"publicGameCount":2,"difficulty":0.9,"difficultyWeight":10},"Diagonale":{"count":6,"lastSeenTime":1586900402067},"Axolotl":{"count":5,"lastSeenTime":1586827401622},"Radioaktivität":{"count":9,"lastSeenTime":1586958253918},"Kirby":{"count":7,"lastSeenTime":1586914387880},"Achterbahn":{"count":5,"lastSeenTime":1586914270411,"difficulty":0.5333333333333333,"difficultyWeight":15},"Hand":{"count":6,"lastSeenTime":1586900278764,"difficulty":0.4,"difficultyWeight":5},"Sattel":{"count":8,"lastSeenTime":1586958525123,"difficulty":1,"difficultyWeight":12},"Tacker":{"count":4,"lastSeenTime":1586815146910},"Vorstellungskraft":{"count":3,"lastSeenTime":1586959401878},"umkehren":{"count":7,"lastSeenTime":1586915974465},"Bürste":{"count":6,"lastSeenTime":1586954749821},"Regen":{"count":2,"lastSeenTime":1586569585076,"publicGameCount":1,"difficulty":0.8727272727272727,"difficultyWeight":55},"aufwachen":{"count":12,"lastSeenTime":1586914869480,"difficulty":1,"difficultyWeight":9},"Kettensäge":{"count":5,"lastSeenTime":1586955634694},"Paris":{"count":6,"lastSeenTime":1586880936347},"Thunfisch":{"count":8,"lastSeenTime":1586902616627},"Picknick":{"count":5,"lastSeenTime":1586840420314,"difficulty":1,"difficultyWeight":12},"Nagelschere":{"count":7,"lastSeenTime":1586881247045},"Waschbrettbauch":{"count":4,"lastSeenTime":1586807932952},"Donald Duck":{"count":6,"lastSeenTime":1586903750797},"Hecht":{"count":8,"lastSeenTime":1586903048902},"Schallplatte":{"count":4,"lastSeenTime":1586826573783},"Laterne":{"count":7,"lastSeenTime":1586895872235,"difficulty":1,"difficultyWeight":9},"singen":{"count":7,"lastSeenTime":1586914181975},"Hampelmann":{"count":7,"lastSeenTime":1586805325864},"Krawatte":{"count":3,"lastSeenTime":1586815863706,"publicGameCount":1,"difficulty":1,"difficultyWeight":8},"Werkzeugkasten":{"count":9,"lastSeenTime":1586919821927},"Qualle":{"count":3,"lastSeenTime":1586711756970,"difficulty":0.8648648648648649,"difficultyWeight":37,"publicGameCount":1},"Gans":{"count":6,"lastSeenTime":1586897445244},"Flutlicht":{"count":4,"lastSeenTime":1586869078737,"difficulty":1,"difficultyWeight":8},"Dampf":{"count":3,"lastSeenTime":1586859475541,"difficulty":0.25,"difficultyWeight":8},"Reißverschlussverfahren":{"count":4,"lastSeenTime":1586913868342},"Polizist":{"count":6,"lastSeenTime":1586881085327,"difficulty":1,"difficultyWeight":6},"Aschenbecher":{"count":7,"lastSeenTime":1586879531452},"Drillinge":{"count":4,"lastSeenTime":1586897154134,"difficulty":0.8275862068965517,"difficultyWeight":29},"Insekt":{"count":11,"lastSeenTime":1586955938117},"Spongebob":{"count":8,"lastSeenTime":1586901003976},"Slalom":{"count":9,"lastSeenTime":1586903939910,"difficulty":1,"difficultyWeight":26},"Brieftaube":{"count":7,"lastSeenTime":1586919394915,"difficulty":0.8571428571428571,"difficultyWeight":7},"Gebäck":{"count":6,"lastSeenTime":1586879170331,"difficulty":1,"difficultyWeight":3},"Wasserhahn":{"count":4,"lastSeenTime":1586959207698},"tippen":{"count":9,"lastSeenTime":1586903673095},"Robin Hood":{"count":4,"lastSeenTime":1586873676367},"Lieferung":{"count":5,"lastSeenTime":1586806294106},"Strauß":{"count":3,"lastSeenTime":1586817693807},"fleischfressend":{"count":4,"lastSeenTime":1586816002310},"Faultier":{"count":6,"lastSeenTime":1586915856980},"Geburtstag":{"count":6,"lastSeenTime":1586806643897,"publicGameCount":1,"difficulty":0.9090909090909091,"difficultyWeight":11},"Tierfutter":{"count":4,"lastSeenTime":1586901089526},"Obelix":{"count":6,"lastSeenTime":1586891242624,"difficulty":0.2857142857142857,"difficultyWeight":7},"Dollar":{"count":10,"lastSeenTime":1586955654939,"difficulty":0.375,"difficultyWeight":8},"Eichhörnchen":{"count":6,"lastSeenTime":1586958325841},"kratzen":{"count":7,"lastSeenTime":1586896509911,"difficulty":1,"difficultyWeight":5},"klatschen":{"count":5,"lastSeenTime":1586858550508},"Raumschiff":{"count":3,"lastSeenTime":1586713907372,"publicGameCount":2,"difficulty":1,"difficultyWeight":7},"Ikea":{"count":3,"lastSeenTime":1586897039497},"sternhagelvoll":{"count":5,"lastSeenTime":1586812941735},"Keksdose":{"count":14,"lastSeenTime":1586955419506,"difficulty":1,"difficultyWeight":1},"Ameisenhaufen":{"count":10,"lastSeenTime":1586913424347},"Pilz":{"count":5,"lastSeenTime":1586957940022},"heiß":{"count":5,"lastSeenTime":1586868067356,"difficulty":0.9761904761904762,"difficultyWeight":42},"Tabak":{"count":9,"lastSeenTime":1586907386047,"difficulty":1,"difficultyWeight":10},"High Heels":{"count":5,"lastSeenTime":1586915139518},"Schublade":{"count":3,"lastSeenTime":1586874917114},"Coffeeshop":{"count":5,"lastSeenTime":1586896530203},"Schlauch":{"count":5,"lastSeenTime":1586889566614},"Teletubby":{"count":7,"lastSeenTime":1586902641439},"Butter":{"count":10,"lastSeenTime":1586889682224},"Münze":{"count":3,"lastSeenTime":1586909250467,"difficulty":1,"difficultyWeight":38},"Überschrift":{"count":7,"lastSeenTime":1586914883727,"difficulty":0.5,"difficultyWeight":6},"Rapunzel":{"count":5,"lastSeenTime":1586956130879},"Ofen":{"count":10,"lastSeenTime":1586908141001},"Afrofrisur":{"count":5,"lastSeenTime":1586913696698},"Aufkleber":{"count":5,"lastSeenTime":1586897455407},"magersüchtig":{"count":7,"lastSeenTime":1586919650407,"difficulty":1,"difficultyWeight":6},"Pflaume":{"count":5,"lastSeenTime":1586869723557},"Giftzwerg":{"count":4,"lastSeenTime":1586840557813,"difficulty":0.9767441860465116,"difficultyWeight":43},"Pfadfinder":{"count":8,"lastSeenTime":1586913606771},"Barcode":{"count":9,"lastSeenTime":1586956552197,"difficulty":1,"difficultyWeight":5},"Morgen":{"count":7,"lastSeenTime":1586818656558,"difficulty":1,"difficultyWeight":5},"Tisch":{"count":9,"lastSeenTime":1586955654939,"publicGameCount":1,"difficulty":0.42857142857142855,"difficultyWeight":7},"Rotkehlchen":{"count":11,"lastSeenTime":1586914181975},"Kalender":{"count":5,"lastSeenTime":1586904040749},"Elektroauto":{"count":6,"lastSeenTime":1586955025294},"Jäger":{"count":6,"lastSeenTime":1586956019428,"difficulty":1,"difficultyWeight":7},"Hase":{"count":7,"lastSeenTime":1586903333845},"Kiste":{"count":4,"lastSeenTime":1586879520233},"Käsekuchen":{"count":11,"lastSeenTime":1586909201701},"Kreuzfahrt":{"count":7,"lastSeenTime":1586959570753,"publicGameCount":1,"difficulty":0.33333333333333337,"difficultyWeight":9},"Corn Dog":{"count":6,"lastSeenTime":1586826796918},"Parade":{"count":10,"lastSeenTime":1586915442369,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Überfall":{"count":9,"lastSeenTime":1586919650407},"Quelle":{"count":6,"lastSeenTime":1586873482759},"Kontrabass":{"count":11,"lastSeenTime":1586919348003,"difficulty":1,"difficultyWeight":10},"Matratze":{"count":8,"lastSeenTime":1586920957237},"Xylofon":{"count":8,"lastSeenTime":1586955429782},"Daumen":{"count":5,"lastSeenTime":1586916404987,"publicGameCount":1,"difficulty":0.95,"difficultyWeight":20},"Tischdecke":{"count":9,"lastSeenTime":1586958983867},"Dachschaden":{"count":6,"lastSeenTime":1586817605940},"Sonnenaufgang":{"count":8,"lastSeenTime":1586959789851,"publicGameCount":2,"difficulty":0.7777777777777778,"difficultyWeight":27},"Halbleiter":{"count":4,"lastSeenTime":1586954678504},"Kranz":{"count":8,"lastSeenTime":1586908175585},"High Score":{"count":8,"lastSeenTime":1586874283356},"Fliegenklatsche":{"count":9,"lastSeenTime":1586920005337,"difficulty":0.9622641509433962,"difficultyWeight":53},"Maskottchen":{"count":3,"lastSeenTime":1586725969582,"difficulty":0.9,"difficultyWeight":10},"Tank":{"count":10,"lastSeenTime":1586913948292,"difficulty":0.5555555555555556,"difficultyWeight":9},"Kung Fu":{"count":6,"lastSeenTime":1586958325841},"lachen":{"count":8,"lastSeenTime":1586869397751,"difficulty":0.25,"difficultyWeight":8},"Klarinette":{"count":5,"lastSeenTime":1586896444515},"Hacker":{"count":8,"lastSeenTime":1586904412233},"vertikal":{"count":5,"lastSeenTime":1586959482662,"difficulty":1,"difficultyWeight":4},"Sicherheitsgurt":{"count":6,"lastSeenTime":1586903950072},"Schokolade":{"count":9,"lastSeenTime":1586913948292},"Schminke":{"count":5,"lastSeenTime":1586902926018},"Stoff":{"count":5,"lastSeenTime":1586858918703},"Grashüpfer":{"count":6,"lastSeenTime":1586916116567,"difficulty":0.3333333333333333,"difficultyWeight":12},"Schule":{"count":7,"lastSeenTime":1586914893907},"Schmied":{"count":4,"lastSeenTime":1586958077398},"erzählen":{"count":6,"lastSeenTime":1586920322622},"Weide":{"count":8,"lastSeenTime":1586901346838},"Golfwagen":{"count":9,"lastSeenTime":1586907900355},"Lichtschalter":{"count":4,"lastSeenTime":1586712768631},"Perle":{"count":6,"lastSeenTime":1586896769426,"difficulty":0.9333333333333333,"difficultyWeight":15,"publicGameCount":1},"Explosion":{"count":8,"lastSeenTime":1586958873120,"publicGameCount":1,"difficulty":0.7333333333333333,"difficultyWeight":15},"Kleid":{"count":4,"lastSeenTime":1586959417006,"difficulty":0.8857142857142857,"difficultyWeight":70},"Klingelton":{"count":6,"lastSeenTime":1586901606974},"depressiv":{"count":6,"lastSeenTime":1586958821795,"difficulty":1,"difficultyWeight":6},"Bauer":{"count":5,"lastSeenTime":1586827875892},"Bildschirm":{"count":10,"lastSeenTime":1586903836685},"Sparschwein":{"count":15,"lastSeenTime":1586914575777,"difficulty":0.5714285714285714,"difficultyWeight":7},"Lakritz":{"count":9,"lastSeenTime":1586914387880},"fahren":{"count":8,"lastSeenTime":1586890826443,"difficulty":0.5,"difficultyWeight":4},"Pistole":{"count":4,"lastSeenTime":1586907962530,"difficulty":1,"difficultyWeight":8},"Held":{"count":6,"lastSeenTime":1586907729754},"Eiffelturm":{"count":4,"lastSeenTime":1586874677647,"difficulty":1,"difficultyWeight":8},"Brücke":{"count":10,"lastSeenTime":1586908141001},"Kreis":{"count":5,"lastSeenTime":1586879705061},"Skalpell":{"count":7,"lastSeenTime":1586956215415},"Batterie":{"count":10,"lastSeenTime":1586954900699,"difficulty":0.5333333333333333,"difficultyWeight":15},"Hühnchen":{"count":14,"lastSeenTime":1586959738785},"Thron":{"count":6,"lastSeenTime":1586915365103,"difficulty":1,"difficultyWeight":5},"Narbe":{"count":5,"lastSeenTime":1586839235965},"Spielzeug":{"count":8,"lastSeenTime":1586915767461,"difficulty":1,"difficultyWeight":35},"Lunge":{"count":5,"lastSeenTime":1586815863706,"difficulty":0.82,"difficultyWeight":50},"Seepferdchen":{"count":5,"lastSeenTime":1586916074772},"melken":{"count":4,"lastSeenTime":1586874527694},"Paparazzi":{"count":7,"lastSeenTime":1586879892909},"Wange":{"count":8,"lastSeenTime":1586920312527,"difficulty":0.30000000000000004,"difficultyWeight":10},"Schneemann":{"count":7,"lastSeenTime":1586907351001,"difficulty":0.5,"difficultyWeight":14},"Muttermal":{"count":5,"lastSeenTime":1586908721366,"publicGameCount":1,"difficulty":0,"difficultyWeight":1},"Groschen":{"count":6,"lastSeenTime":1586958052113},"differenzieren":{"count":4,"lastSeenTime":1586901181085},"Domino":{"count":8,"lastSeenTime":1586959482662,"difficulty":0.4444444444444444,"difficultyWeight":9},"schreien":{"count":6,"lastSeenTime":1586954588805},"Hawaiihemd":{"count":4,"lastSeenTime":1586874677647,"difficulty":0.7222222222222222,"difficultyWeight":18},"Brustkorb":{"count":6,"lastSeenTime":1586954967541,"difficulty":1,"difficultyWeight":7},"rechnen":{"count":4,"lastSeenTime":1586708948976,"difficulty":0.8181818181818182,"difficultyWeight":11},"Steckdose":{"count":7,"lastSeenTime":1586959178760,"difficulty":0.75,"difficultyWeight":20},"Gürtel":{"count":2,"lastSeenTime":1586874869836},"Hirsch":{"count":8,"lastSeenTime":1586956145689},"Pantomime":{"count":6,"lastSeenTime":1586858586343},"Rochen":{"count":5,"lastSeenTime":1586833743451,"difficulty":0.7777777777777778,"difficultyWeight":9},"Spiderman":{"count":7,"lastSeenTime":1586908697152,"difficulty":0.8409090909090909,"difficultyWeight":44},"Schlafenszeit":{"count":7,"lastSeenTime":1586916118321,"difficulty":0.8,"difficultyWeight":5},"Samsung":{"count":10,"lastSeenTime":1586896554510},"Nahrung":{"count":5,"lastSeenTime":1586957848254},"Harry Potter":{"count":8,"lastSeenTime":1586920722806,"difficulty":1,"difficultyWeight":24},"Katy Perry":{"count":5,"lastSeenTime":1586833719821},"Rückspiegel":{"count":4,"lastSeenTime":1586869324825},"Erdnuss-flips":{"count":9,"lastSeenTime":1586920690415},"Weltraum":{"count":4,"lastSeenTime":1586919697403,"difficulty":1,"difficultyWeight":12},"Virtual Reality":{"count":7,"lastSeenTime":1586869058242},"brüllen":{"count":3,"lastSeenTime":1586875005520},"Heinzelmännchen":{"count":6,"lastSeenTime":1586914560752,"difficulty":1,"difficultyWeight":8},"Spiel":{"count":3,"lastSeenTime":1586727314043},"Form":{"count":3,"lastSeenTime":1586921270600},"Küchentuch":{"count":6,"lastSeenTime":1586881021273},"Pilot":{"count":6,"lastSeenTime":1586958141882,"difficulty":0.8545454545454545,"difficultyWeight":55},"Gnom":{"count":4,"lastSeenTime":1586832821211},"Rettungsring":{"count":6,"lastSeenTime":1586914109258},"Augenbraue":{"count":4,"lastSeenTime":1586880956767,"difficulty":1,"difficultyWeight":3},"Schleichwerbung":{"count":2,"lastSeenTime":1586955457642},"Unfall":{"count":6,"lastSeenTime":1586920285874,"difficulty":1,"difficultyWeight":5},"Photosynthese":{"count":3,"lastSeenTime":1586955392320,"difficulty":1,"difficultyWeight":13},"Donald Trump":{"count":6,"lastSeenTime":1586901719438,"publicGameCount":1,"difficulty":1,"difficultyWeight":4},"Farbpalette":{"count":9,"lastSeenTime":1586908721968},"Schlafstörung":{"count":6,"lastSeenTime":1586919858412},"Geldbeutel":{"count":3,"lastSeenTime":1586908494479},"Dreirad":{"count":6,"lastSeenTime":1586903421160},"Ziege":{"count":6,"lastSeenTime":1586826949191},"Palme":{"count":4,"lastSeenTime":1586908787449},"Grabstein":{"count":7,"lastSeenTime":1586867963918,"difficulty":0.33333333333333337,"difficultyWeight":9},"Wunde":{"count":13,"lastSeenTime":1586955152448},"Eule":{"count":8,"lastSeenTime":1586873598800},"Huf":{"count":8,"lastSeenTime":1586903867648},"Gourmet":{"count":1,"lastSeenTime":1586564694384},"Emoji":{"count":3,"lastSeenTime":1586633980478,"difficulty":0.7941176470588235,"difficultyWeight":34},"Stereo":{"count":6,"lastSeenTime":1586959595986,"difficulty":0.9333333333333333,"difficultyWeight":15},"Ski":{"count":5,"lastSeenTime":1586840301535},"Brezel":{"count":5,"lastSeenTime":1586921071907,"difficulty":0.625,"difficultyWeight":8},"Leine":{"count":6,"lastSeenTime":1586890378764},"Gepäckträger":{"count":8,"lastSeenTime":1586959279701,"difficulty":1,"difficultyWeight":36},"Jaguar":{"count":8,"lastSeenTime":1586920336794},"Paypal":{"count":9,"lastSeenTime":1586901166652,"difficulty":1,"difficultyWeight":22},"Spitzmaus":{"count":5,"lastSeenTime":1586921209345,"difficulty":1,"difficultyWeight":9},"Glas":{"count":11,"lastSeenTime":1586916328101,"difficulty":1,"difficultyWeight":1},"Wasserkreislauf":{"count":5,"lastSeenTime":1586880595683,"difficulty":1,"difficultyWeight":8},"Veröffentlichung":{"count":7,"lastSeenTime":1586916382544},"Henne":{"count":8,"lastSeenTime":1586840782545},"Barbar":{"count":6,"lastSeenTime":1586875120930},"Happy Meal":{"count":9,"lastSeenTime":1586919433115},"Kleber":{"count":7,"lastSeenTime":1586816382821},"schenken":{"count":4,"lastSeenTime":1586916731964,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":24},"Portugal":{"count":8,"lastSeenTime":1586914309641,"difficulty":0.42857142857142855,"difficultyWeight":7},"Stirnband":{"count":6,"lastSeenTime":1586813412560,"difficulty":0.8333333333333334,"difficultyWeight":6},"Tannenzapfen":{"count":9,"lastSeenTime":1586958325841},"Uniform":{"count":8,"lastSeenTime":1586907547051,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":5},"Aubergine":{"count":7,"lastSeenTime":1586958642478,"difficulty":0.8571428571428571,"difficultyWeight":49},"Bruce Lee":{"count":4,"lastSeenTime":1586908921509},"Schacht":{"count":4,"lastSeenTime":1586839026220},"Youtuber":{"count":8,"lastSeenTime":1586959804291},"Leiche":{"count":5,"lastSeenTime":1586954999969,"difficulty":0.9,"difficultyWeight":10},"Mond":{"count":2,"lastSeenTime":1586806443319},"Pyramide":{"count":10,"lastSeenTime":1586955716758,"difficulty":0.5714285714285714,"difficultyWeight":14},"Tandem":{"count":4,"lastSeenTime":1586890378764,"difficulty":0.9333333333333333,"difficultyWeight":15},"Rucksack":{"count":6,"lastSeenTime":1586914557302},"Reisepass":{"count":5,"lastSeenTime":1586921104275},"Seite":{"count":7,"lastSeenTime":1586954664216,"difficulty":1,"difficultyWeight":10},"Abzug":{"count":6,"lastSeenTime":1586919836074},"Hosentasche":{"count":10,"lastSeenTime":1586879853156,"difficulty":0.9411764705882353,"difficultyWeight":17},"Rübe":{"count":4,"lastSeenTime":1586880531589},"Katzenklo":{"count":5,"lastSeenTime":1586959508307},"Zirkel":{"count":2,"lastSeenTime":1586902738828,"difficulty":1,"difficultyWeight":6},"Kohlrübe":{"count":6,"lastSeenTime":1586879359526,"difficulty":1,"difficultyWeight":5},"Jacht":{"count":5,"lastSeenTime":1586900866878,"difficulty":1,"difficultyWeight":23},"Serviette":{"count":4,"lastSeenTime":1586902776556},"hart":{"count":3,"lastSeenTime":1586874767406},"Karate":{"count":11,"lastSeenTime":1586902738828,"difficulty":0.75,"difficultyWeight":4},"Diamant":{"count":9,"lastSeenTime":1586958289143,"publicGameCount":1,"difficulty":0.918918918918919,"difficultyWeight":37},"Lagerfeuer":{"count":8,"lastSeenTime":1586903853302},"Deadpool":{"count":6,"lastSeenTime":1586901547884},"Universum":{"count":6,"lastSeenTime":1586959090713},"Bär":{"count":8,"lastSeenTime":1586895747389,"difficulty":0.8,"difficultyWeight":15,"publicGameCount":1},"Verkehrskontrolle":{"count":8,"lastSeenTime":1586959789851,"difficulty":1,"difficultyWeight":19},"Komet":{"count":8,"lastSeenTime":1586916382544},"übergeben":{"count":7,"lastSeenTime":1586900739157,"difficulty":1,"difficultyWeight":16},"Röntgenstrahlung":{"count":5,"lastSeenTime":1586916565022},"Polo":{"count":7,"lastSeenTime":1586919552513},"Gott":{"count":3,"lastSeenTime":1586707906596,"difficulty":1,"difficultyWeight":1},"Nasenlöcher":{"count":4,"lastSeenTime":1586920836680,"difficulty":0.8571428571428571,"difficultyWeight":7},"Berlin":{"count":5,"lastSeenTime":1586868603483,"difficulty":0.7222222222222222,"difficultyWeight":18},"küssen":{"count":10,"lastSeenTime":1586919783421},"Schleim":{"count":9,"lastSeenTime":1586890237676},"Flipper":{"count":2,"lastSeenTime":1586907839176,"difficulty":0.8,"difficultyWeight":5},"Schubkarre":{"count":4,"lastSeenTime":1586783730394},"Airbag":{"count":3,"lastSeenTime":1586827613351,"difficulty":0.5714285714285714,"difficultyWeight":7},"Schwerkraft":{"count":3,"lastSeenTime":1586826965958},"Gürteltier":{"count":5,"lastSeenTime":1586711447154},"Tunnel":{"count":6,"lastSeenTime":1586908054437,"difficulty":0.8888888888888888,"difficultyWeight":63},"Freiheitsstatue":{"count":5,"lastSeenTime":1586908392957},"Idee":{"count":7,"lastSeenTime":1586957888650,"difficulty":0.25,"difficultyWeight":8},"Black Friday":{"count":5,"lastSeenTime":1586958299322,"publicGameCount":1,"difficulty":0.6666666666666666,"difficultyWeight":12},"Parkplatz":{"count":4,"lastSeenTime":1586920954248,"difficulty":0.8,"difficultyWeight":5},"Video":{"count":9,"lastSeenTime":1586908315438,"difficulty":0.8,"difficultyWeight":10},"Speck":{"count":3,"lastSeenTime":1586710915055},"Nebel":{"count":4,"lastSeenTime":1586954808666},"Queue":{"count":4,"lastSeenTime":1586859189711},"Stegosaurus":{"count":6,"lastSeenTime":1586916368116},"Hälfte":{"count":4,"lastSeenTime":1586920180037},"ernten":{"count":7,"lastSeenTime":1586873461546},"pieksen":{"count":7,"lastSeenTime":1586907414380},"Zahnarzt":{"count":7,"lastSeenTime":1586916153776,"difficulty":0.7142857142857143,"difficultyWeight":7},"Brownie":{"count":6,"lastSeenTime":1586914683667},"Busch":{"count":5,"lastSeenTime":1586879770813},"Fluss":{"count":9,"lastSeenTime":1586919384885},"Besen":{"count":5,"lastSeenTime":1586812283796},"Federball":{"count":5,"lastSeenTime":1586900264634,"difficulty":0.8125,"difficultyWeight":16},"Keyboard":{"count":8,"lastSeenTime":1586915609902,"difficulty":0.7333333333333333,"difficultyWeight":15},"James Bond":{"count":6,"lastSeenTime":1586904332915,"difficulty":1,"difficultyWeight":3},"Armleuchter":{"count":6,"lastSeenTime":1586919327173},"Litschi":{"count":6,"lastSeenTime":1586913581904,"publicGameCount":1,"difficulty":1,"difficultyWeight":12},"Barbier":{"count":9,"lastSeenTime":1586902713347},"Sweatshirt":{"count":7,"lastSeenTime":1586907547051},"Fenster":{"count":2,"lastSeenTime":1586632836406,"difficulty":0.4,"difficultyWeight":10},"Lavendel":{"count":3,"lastSeenTime":1586889943537},"Taille":{"count":7,"lastSeenTime":1586908315438},"Befehlshaber":{"count":5,"lastSeenTime":1586904102272},"falsche Zähne":{"count":6,"lastSeenTime":1586915031903},"Sonic":{"count":5,"lastSeenTime":1586817982440},"Eber":{"count":6,"lastSeenTime":1586812232504},"Tonleiter":{"count":11,"lastSeenTime":1586908392957,"difficulty":1,"difficultyWeight":26},"Döner":{"count":8,"lastSeenTime":1586919797630,"difficulty":1,"difficultyWeight":3},"Dracula":{"count":5,"lastSeenTime":1586901152323,"difficulty":1,"difficultyWeight":4},"Seife":{"count":5,"lastSeenTime":1586913596578},"Feldstecher":{"count":5,"lastSeenTime":1586873383077},"Saft":{"count":10,"lastSeenTime":1586908697152,"difficulty":1,"difficultyWeight":12},"Portal":{"count":7,"lastSeenTime":1586880741697},"Badeanzug":{"count":4,"lastSeenTime":1586897368245,"publicGameCount":1},"Trüffel":{"count":6,"lastSeenTime":1586919927137},"Bräutigam":{"count":10,"lastSeenTime":1586919836074,"difficulty":1,"difficultyWeight":26},"Baklava":{"count":6,"lastSeenTime":1586907693323},"studieren":{"count":5,"lastSeenTime":1586914206725,"difficulty":0.9130434782608695,"difficultyWeight":46},"Norwegen":{"count":9,"lastSeenTime":1586954588805},"Fidget Spinner":{"count":7,"lastSeenTime":1586901014103,"difficulty":0.9090909090909091,"difficultyWeight":11},"Schwanz":{"count":9,"lastSeenTime":1586915529401,"difficulty":0.9285714285714286,"difficultyWeight":14},"schnell":{"count":10,"lastSeenTime":1586909080709,"difficulty":0.33333333333333337,"difficultyWeight":9},"Grubenarbeiter":{"count":3,"lastSeenTime":1586838964600},"flach":{"count":2,"lastSeenTime":1586590610487},"Maki":{"count":8,"lastSeenTime":1586919433115},"Xbox":{"count":5,"lastSeenTime":1586954617410,"difficulty":1,"difficultyWeight":3},"Holz":{"count":5,"lastSeenTime":1586916731964},"Grippe":{"count":4,"lastSeenTime":1586913633876},"spannen":{"count":6,"lastSeenTime":1586890968538},"Allee":{"count":5,"lastSeenTime":1586868169552},"Anker":{"count":3,"lastSeenTime":1586890117788,"difficulty":0.8571428571428571,"difficultyWeight":21},"Stoppuhr":{"count":7,"lastSeenTime":1586958959180},"Gesundheit":{"count":7,"lastSeenTime":1586914820916,"publicGameCount":1,"difficulty":0.3333333333333333,"difficultyWeight":6},"Tattoo":{"count":3,"lastSeenTime":1586874552382,"difficulty":1,"difficultyWeight":8},"Alkohol":{"count":13,"lastSeenTime":1586896554510,"difficulty":0.33333333333333337,"difficultyWeight":9},"Müller":{"count":4,"lastSeenTime":1586706924436},"Schweiz":{"count":6,"lastSeenTime":1586921032863},"verlassen":{"count":5,"lastSeenTime":1586840121442},"Pfannenwender":{"count":11,"lastSeenTime":1586879170331},"Kamel":{"count":3,"lastSeenTime":1586813676447,"difficulty":0.9090909090909091,"difficultyWeight":44},"Raupe":{"count":8,"lastSeenTime":1586818853521},"Hexe":{"count":5,"lastSeenTime":1586869324825,"difficulty":1,"difficultyWeight":11},"Vorschlaghammer":{"count":4,"lastSeenTime":1586920483192},"Dora":{"count":5,"lastSeenTime":1586959193290},"rollen":{"count":8,"lastSeenTime":1586896877511},"epilieren":{"count":7,"lastSeenTime":1586890675024},"herunterladen":{"count":4,"lastSeenTime":1586908155214,"difficulty":1,"difficultyWeight":3},"Lampe":{"count":4,"lastSeenTime":1586709093864,"difficulty":0.6153846153846154,"difficultyWeight":13},"Diskette":{"count":7,"lastSeenTime":1586955763543},"Umhang":{"count":8,"lastSeenTime":1586957874303},"Jeep":{"count":6,"lastSeenTime":1586954808666},"Horn":{"count":15,"lastSeenTime":1586915299932,"publicGameCount":1,"difficulty":0.7857142857142857,"difficultyWeight":28},"Goldkette":{"count":6,"lastSeenTime":1586896854975,"difficulty":1,"difficultyWeight":11},"Kissen":{"count":9,"lastSeenTime":1586958794944},"Sechserpack":{"count":6,"lastSeenTime":1586921241738},"Keks":{"count":5,"lastSeenTime":1586956166526,"difficulty":1,"difficultyWeight":8},"Kettenkarussell":{"count":5,"lastSeenTime":1586913518787,"difficulty":1,"difficultyWeight":6},"Zeus":{"count":10,"lastSeenTime":1586919337853,"publicGameCount":1,"difficulty":1,"difficultyWeight":24},"Leuchtstab":{"count":8,"lastSeenTime":1586919423610,"difficulty":1,"difficultyWeight":6},"Eisen":{"count":7,"lastSeenTime":1586955877308,"publicGameCount":1,"difficulty":0.5714285714285714,"difficultyWeight":14},"Fee":{"count":5,"lastSeenTime":1586832498107},"Seilspringen":{"count":4,"lastSeenTime":1586805458421,"difficulty":1,"difficultyWeight":11},"Kopfschmerzen":{"count":6,"lastSeenTime":1586908757151},"Feuerwerk":{"count":2,"lastSeenTime":1586706242194,"difficulty":0.6666666666666667,"difficultyWeight":9},"Snoopy":{"count":7,"lastSeenTime":1586959401878,"difficulty":1,"difficultyWeight":6},"Waschbecken":{"count":5,"lastSeenTime":1586955923939,"difficulty":0.75,"difficultyWeight":4},"Karotte":{"count":9,"lastSeenTime":1586900941854,"difficulty":1,"difficultyWeight":11},"Dachboden":{"count":5,"lastSeenTime":1586875174443,"difficulty":1,"difficultyWeight":24},"Löffel":{"count":16,"lastSeenTime":1586959570753,"difficulty":0.625,"difficultyWeight":24},"Pups":{"count":10,"lastSeenTime":1586919522211,"difficulty":1,"difficultyWeight":3},"Stuhl":{"count":5,"lastSeenTime":1586956504597,"difficulty":0.11111111111111116,"difficultyWeight":9},"Vorhang":{"count":8,"lastSeenTime":1586955862348},"Abschleppwagen":{"count":3,"lastSeenTime":1586957989157},"Geier":{"count":9,"lastSeenTime":1586955209647},"rülpsen":{"count":5,"lastSeenTime":1586955138676,"difficulty":0.8974358974358975,"difficultyWeight":39},"Venusfliegenfalle":{"count":6,"lastSeenTime":1586958769937},"Klebeband":{"count":9,"lastSeenTime":1586891163944},"Tomate":{"count":9,"lastSeenTime":1586915529401},"Morse Code":{"count":5,"lastSeenTime":1586814103524,"difficulty":1,"difficultyWeight":16},"Morgan Freeman":{"count":6,"lastSeenTime":1586897139972,"difficulty":0.14285714285714293,"difficultyWeight":7},"sanft":{"count":3,"lastSeenTime":1586727828851},"Affe":{"count":7,"lastSeenTime":1586907839176},"Sieg":{"count":1,"lastSeenTime":1586567404446},"Feder":{"count":8,"lastSeenTime":1586901511433,"difficulty":0.8260869565217391,"difficultyWeight":23,"publicGameCount":1},"niedlich":{"count":5,"lastSeenTime":1586860007509},"Bücherregal":{"count":5,"lastSeenTime":1586915417224,"difficulty":1,"difficultyWeight":8},"Frost":{"count":6,"lastSeenTime":1586959608297},"Melone":{"count":4,"lastSeenTime":1586828046616,"difficulty":0.24999999999999997,"difficultyWeight":12},"Gummiwürmchen":{"count":4,"lastSeenTime":1586834124544},"laden":{"count":6,"lastSeenTime":1586956253026},"Kokon":{"count":3,"lastSeenTime":1586651382688},"kalt":{"count":5,"lastSeenTime":1586958510664},"Talentshow":{"count":6,"lastSeenTime":1586916048294,"difficulty":0.9722222222222222,"difficultyWeight":36},"Asteroid":{"count":7,"lastSeenTime":1586913452717,"difficulty":0.9565217391304348,"difficultyWeight":23},"Spanien":{"count":7,"lastSeenTime":1586908646355},"Gitarre":{"count":9,"lastSeenTime":1586955532027,"difficulty":0.4444444444444444,"difficultyWeight":9},"Kohle":{"count":6,"lastSeenTime":1586817852869,"difficulty":0.8461538461538461,"difficultyWeight":13},"Pauke":{"count":8,"lastSeenTime":1586890654439,"difficulty":1,"difficultyWeight":11},"Festival":{"count":5,"lastSeenTime":1586920932924},"Orbit":{"count":4,"lastSeenTime":1586826458119,"difficulty":1,"difficultyWeight":2},"London":{"count":5,"lastSeenTime":1586901786675},"Wirbelsäule":{"count":4,"lastSeenTime":1586903543797},"Essen":{"count":3,"lastSeenTime":1586722986815},"Publikum":{"count":8,"lastSeenTime":1586900387786},"Fassade":{"count":9,"lastSeenTime":1586915731157,"difficulty":0.7954545454545454,"difficultyWeight":44},"Tiramisu":{"count":5,"lastSeenTime":1586955503431,"difficulty":0.7777777777777778,"difficultyWeight":9},"Eierschachtel":{"count":4,"lastSeenTime":1586955310334},"Schlagsahne":{"count":5,"lastSeenTime":1586959508307},"Laubsäge":{"count":4,"lastSeenTime":1586890704484,"difficulty":1,"difficultyWeight":7},"Discord":{"count":7,"lastSeenTime":1586958582243,"difficulty":0.42857142857142855,"difficultyWeight":14},"Bombe":{"count":6,"lastSeenTime":1586908304826,"difficulty":0.6666666666666666,"difficultyWeight":12},"Gold":{"count":4,"lastSeenTime":1586915503496},"Risiko":{"count":5,"lastSeenTime":1586955609964,"difficulty":0.6,"difficultyWeight":10},"Vampir":{"count":5,"lastSeenTime":1586958794944,"difficulty":1,"difficultyWeight":8},"McDonalds":{"count":5,"lastSeenTime":1586839555615},"Big Ben":{"count":2,"lastSeenTime":1586568977728},"Nussknacker":{"count":7,"lastSeenTime":1586860031219,"difficulty":0.125,"difficultyWeight":8},"Mutter":{"count":5,"lastSeenTime":1586909094851,"difficulty":0.7931034482758621,"difficultyWeight":29},"Huhn":{"count":6,"lastSeenTime":1586909201701,"difficulty":0.9545454545454546,"difficultyWeight":22},"Presslufthammer":{"count":5,"lastSeenTime":1586908368588},"Albtraum":{"count":5,"lastSeenTime":1586859971727,"difficulty":0.6666666666666666,"difficultyWeight":9},"Moskau":{"count":7,"lastSeenTime":1586903572367,"difficulty":1,"difficultyWeight":8},"Silo":{"count":6,"lastSeenTime":1586920397655,"difficulty":1,"difficultyWeight":10},"Otter":{"count":6,"lastSeenTime":1586816739369},"Untergrund":{"count":8,"lastSeenTime":1586900087077},"Antarktis":{"count":10,"lastSeenTime":1586955948209,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Königin":{"count":4,"lastSeenTime":1586880790147},"Brecheisen":{"count":4,"lastSeenTime":1586727600390,"difficulty":0.6,"difficultyWeight":10},"Rentner":{"count":6,"lastSeenTime":1586874242781},"Tretmühle":{"count":4,"lastSeenTime":1586723037365,"difficulty":1,"difficultyWeight":6},"Luftschiff":{"count":7,"lastSeenTime":1586858614527},"Gewitter":{"count":6,"lastSeenTime":1586907654631,"difficulty":0.5714285714285714,"difficultyWeight":7},"Fingerhut":{"count":5,"lastSeenTime":1586881031416},"Tierhandlung":{"count":5,"lastSeenTime":1586915503496},"Ägypten":{"count":3,"lastSeenTime":1586868093681},"schwitzen":{"count":12,"lastSeenTime":1586955010181},"John Cena":{"count":9,"lastSeenTime":1586900016201},"Türklinke":{"count":7,"lastSeenTime":1586909296939},"Garnele":{"count":7,"lastSeenTime":1586833778222,"difficulty":1,"difficultyWeight":3},"Gepard":{"count":9,"lastSeenTime":1586908165354},"Meteorit":{"count":3,"lastSeenTime":1586569956865},"stricken":{"count":7,"lastSeenTime":1586908541127},"predigen":{"count":5,"lastSeenTime":1586959767498},"Hello Kitty":{"count":9,"lastSeenTime":1586901067015,"difficulty":0.33333333333333337,"difficultyWeight":9},"Wunschliste":{"count":11,"lastSeenTime":1586891326336,"difficulty":0.2857142857142857,"difficultyWeight":7},"Stacheldraht":{"count":6,"lastSeenTime":1586890854897},"Fingerspitze":{"count":8,"lastSeenTime":1586899916722,"difficulty":0.8333333333333334,"difficultyWeight":6},"Orang-Utan":{"count":5,"lastSeenTime":1586873319498,"publicGameCount":1,"difficulty":0.45714285714285713,"difficultyWeight":35},"Minion":{"count":6,"lastSeenTime":1586858650110,"difficulty":1,"difficultyWeight":44},"anzeigen":{"count":6,"lastSeenTime":1586901225801,"difficulty":1,"difficultyWeight":10},"Ballett":{"count":3,"lastSeenTime":1586817809043,"difficulty":1,"difficultyWeight":11},"Neuseeland":{"count":5,"lastSeenTime":1586921241738},"Schamesröte":{"count":4,"lastSeenTime":1586826573783},"Interview":{"count":7,"lastSeenTime":1586874880231,"difficulty":0.7857142857142857,"difficultyWeight":14},"Krankenschwester":{"count":8,"lastSeenTime":1586959218404,"difficulty":1,"difficultyWeight":2},"Kugelfisch":{"count":4,"lastSeenTime":1586900785753,"publicGameCount":1,"difficulty":0.8181818181818182,"difficultyWeight":22},"Glück":{"count":3,"lastSeenTime":1586813998210},"Dexter":{"count":11,"lastSeenTime":1586913556716},"Schuh":{"count":4,"lastSeenTime":1586916116567},"gähnen":{"count":7,"lastSeenTime":1586919433115},"Socken":{"count":8,"lastSeenTime":1586914270411},"Dach":{"count":6,"lastSeenTime":1586914699787,"difficulty":1,"difficultyWeight":4},"Falte":{"count":4,"lastSeenTime":1586839830482},"Oscar":{"count":5,"lastSeenTime":1586914526456},"kauen":{"count":7,"lastSeenTime":1586897264698,"difficulty":0.75,"difficultyWeight":12},"Flughafen":{"count":8,"lastSeenTime":1586920446574,"difficulty":1,"difficultyWeight":4},"Chewbacca":{"count":4,"lastSeenTime":1586958471219},"Klimaanlage":{"count":5,"lastSeenTime":1586806917088},"Drama":{"count":8,"lastSeenTime":1586955238992,"difficulty":0.8181818181818182,"difficultyWeight":11},"Luigi":{"count":7,"lastSeenTime":1586920108914},"Teelicht":{"count":7,"lastSeenTime":1586920982151,"publicGameCount":1},"Gießkanne":{"count":3,"lastSeenTime":1586958350172,"difficulty":0.7666666666666667,"difficultyWeight":60},"Spule":{"count":8,"lastSeenTime":1586913581904},"Papier":{"count":6,"lastSeenTime":1586900349607},"Kokosnuss":{"count":4,"lastSeenTime":1586859513029,"difficulty":0.3333333333333333,"difficultyWeight":6},"Cowboy":{"count":4,"lastSeenTime":1586904308260},"Community":{"count":4,"lastSeenTime":1586784190547},"Bodybuilding":{"count":14,"lastSeenTime":1586919954168,"difficulty":1,"difficultyWeight":7},"Vene":{"count":3,"lastSeenTime":1586718507669},"schreiben":{"count":7,"lastSeenTime":1586818118151,"difficulty":0.375,"difficultyWeight":8},"Medizin":{"count":8,"lastSeenTime":1586833955534},"Minecraft":{"count":5,"lastSeenTime":1586901346838},"gemütlich":{"count":3,"lastSeenTime":1586896791819,"difficulty":0.7777777777777778,"difficultyWeight":18},"Glockenspiel":{"count":5,"lastSeenTime":1586858799129,"difficulty":0.5833333333333334,"difficultyWeight":36},"Trommel":{"count":4,"lastSeenTime":1586921180981},"Notizblock":{"count":1,"lastSeenTime":1586568332043},"Knast":{"count":5,"lastSeenTime":1586916590016},"besuchen":{"count":9,"lastSeenTime":1586920722806,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":6},"Kolibri":{"count":5,"lastSeenTime":1586914729019},"Amor":{"count":7,"lastSeenTime":1586839459663,"difficulty":0.9523809523809523,"difficultyWeight":21},"Windbeutel":{"count":9,"lastSeenTime":1586958100659,"difficulty":0.875,"difficultyWeight":8},"Joghurt":{"count":8,"lastSeenTime":1586915517726,"difficulty":1,"difficultyWeight":23},"sauber":{"count":9,"lastSeenTime":1586959714261,"difficulty":0.8571428571428571,"difficultyWeight":7},"Etagenbett":{"count":6,"lastSeenTime":1586915795632,"difficulty":1,"difficultyWeight":3},"Looping":{"count":5,"lastSeenTime":1586859083000},"Arzt":{"count":4,"lastSeenTime":1586958299322,"publicGameCount":1,"difficulty":0.5,"difficultyWeight":4},"Handschuh":{"count":8,"lastSeenTime":1586901346838,"difficulty":0.5555555555555556,"difficultyWeight":9},"Tee":{"count":8,"lastSeenTime":1586896252833,"difficulty":0.9375,"difficultyWeight":64},"Gong":{"count":6,"lastSeenTime":1586897506792},"Jeans":{"count":4,"lastSeenTime":1586890675024,"difficulty":0.9558823529411765,"difficultyWeight":68},"Sonnenfinsternis":{"count":6,"lastSeenTime":1586921156587,"difficulty":0.2,"difficultyWeight":5},"Murmeltier":{"count":4,"lastSeenTime":1586807799590},"Pinsel":{"count":9,"lastSeenTime":1586958187063},"Angry Birds":{"count":4,"lastSeenTime":1586879770813},"Euter":{"count":5,"lastSeenTime":1586839296530,"difficulty":0.7777777777777778,"difficultyWeight":9},"Verband":{"count":9,"lastSeenTime":1586907522819,"difficulty":1,"difficultyWeight":7},"zusammenbrechen":{"count":4,"lastSeenTime":1586916116567},"Stein":{"count":11,"lastSeenTime":1586915846579},"Sekunde":{"count":7,"lastSeenTime":1586920883005,"difficulty":0.6521739130434783,"difficultyWeight":23},"Tupperdose":{"count":6,"lastSeenTime":1586895427458},"Hashtag":{"count":5,"lastSeenTime":1586920069685},"Fässchen":{"count":5,"lastSeenTime":1586920666083},"Roller":{"count":3,"lastSeenTime":1586956582710,"difficulty":1,"difficultyWeight":3},"zupfen":{"count":4,"lastSeenTime":1586874143406,"difficulty":1,"difficultyWeight":29},"Eidechse":{"count":11,"lastSeenTime":1586879622531},"Aufhänger":{"count":6,"lastSeenTime":1586920751201,"difficulty":1,"difficultyWeight":10},"Bohnenstange":{"count":3,"lastSeenTime":1586806443319,"difficulty":1,"difficultyWeight":12},"Eierbecher":{"count":6,"lastSeenTime":1586891038128},"Schiffstaufe":{"count":3,"lastSeenTime":1586879583717},"Pegasus":{"count":6,"lastSeenTime":1586955838030,"difficulty":0.5555555555555556,"difficultyWeight":9},"Kartoffelbrei":{"count":10,"lastSeenTime":1586897125781},"Nähmaschine":{"count":8,"lastSeenTime":1586900660239,"difficulty":1,"difficultyWeight":3},"Dusche":{"count":9,"lastSeenTime":1586908028334},"Zahnfee":{"count":7,"lastSeenTime":1586901812091,"difficulty":0.8444444444444444,"difficultyWeight":45},"Regenbogen":{"count":9,"lastSeenTime":1586954627819,"difficulty":0.5714285714285714,"difficultyWeight":7},"King Kong":{"count":8,"lastSeenTime":1586954798445},"Pause":{"count":7,"lastSeenTime":1586914716657,"difficulty":0.5,"difficultyWeight":8},"Helikopter":{"count":12,"lastSeenTime":1586956033779},"Windsack":{"count":6,"lastSeenTime":1586909226093},"Titanic":{"count":5,"lastSeenTime":1586901692884,"difficulty":0.9130434782608695,"difficultyWeight":23},"Gitter":{"count":8,"lastSeenTime":1586959031017},"Schinken":{"count":3,"lastSeenTime":1586873772670},"Yin Yang":{"count":11,"lastSeenTime":1586958859906,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":4},"Biene":{"count":8,"lastSeenTime":1586921094172,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":6},"Mr. Bean":{"count":3,"lastSeenTime":1586718534191,"difficulty":1,"difficultyWeight":1},"Regal":{"count":7,"lastSeenTime":1586920397655},"Dämon":{"count":8,"lastSeenTime":1586958212167,"difficulty":1,"difficultyWeight":10},"Harpune":{"count":3,"lastSeenTime":1586879479650},"Schoß":{"count":9,"lastSeenTime":1586958897546},"Kaugummi":{"count":6,"lastSeenTime":1586903915052,"difficulty":0.847457627118644,"difficultyWeight":59},"Ninja":{"count":10,"lastSeenTime":1586914699787,"difficulty":1,"difficultyWeight":8},"Tentakel":{"count":4,"lastSeenTime":1586867988600},"Sonnenbrille":{"count":4,"lastSeenTime":1586897178546},"Abflussrohr":{"count":3,"lastSeenTime":1586651439627},"Reißverschluss":{"count":7,"lastSeenTime":1586955456078,"difficulty":1,"difficultyWeight":9},"Spaghettimonster":{"count":8,"lastSeenTime":1586908028334,"difficulty":1,"difficultyWeight":28,"publicGameCount":1},"Koch":{"count":12,"lastSeenTime":1586919858412},"Kuckuck":{"count":10,"lastSeenTime":1586914792295,"difficulty":1,"difficultyWeight":10},"Rohr":{"count":3,"lastSeenTime":1586955409372,"difficulty":0.5384615384615384,"difficultyWeight":13},"Spargel":{"count":5,"lastSeenTime":1586956238875,"publicGameCount":1,"difficulty":1,"difficultyWeight":5},"Bäcker":{"count":8,"lastSeenTime":1586919983033},"Skateboardfahrer":{"count":9,"lastSeenTime":1586959728501},"Nagellack":{"count":3,"lastSeenTime":1586908470256},"Nashorn":{"count":4,"lastSeenTime":1586826260649,"difficulty":0.25,"difficultyWeight":4},"Scooby Doo":{"count":7,"lastSeenTime":1586915806469,"publicGameCount":1,"difficulty":0.9642857142857143,"difficultyWeight":28},"Dumbo":{"count":3,"lastSeenTime":1586633389254},"Tablette":{"count":4,"lastSeenTime":1586812594958,"difficulty":0.75,"difficultyWeight":16},"Brot":{"count":8,"lastSeenTime":1586959142159},"Brille":{"count":6,"lastSeenTime":1586817023533},"Taxi":{"count":7,"lastSeenTime":1586914080489,"difficulty":1,"difficultyWeight":8},"Croissant":{"count":6,"lastSeenTime":1586958748793,"difficulty":1,"difficultyWeight":30},"Zwillinge":{"count":7,"lastSeenTime":1586874360889,"publicGameCount":1,"difficulty":0.16666666666666663,"difficultyWeight":6},"Minotaurus":{"count":7,"lastSeenTime":1586901274634,"difficulty":1,"difficultyWeight":10},"Supermarkt":{"count":7,"lastSeenTime":1586908816075,"difficulty":1,"difficultyWeight":5},"Schwert":{"count":7,"lastSeenTime":1586900311185},"Xerox":{"count":8,"lastSeenTime":1586840371821},"Möwe":{"count":3,"lastSeenTime":1586920407752},"Wolf":{"count":7,"lastSeenTime":1586957888650,"difficulty":0.5714285714285714,"difficultyWeight":7},"Lebkuchenhaus":{"count":4,"lastSeenTime":1586909046293},"Reinheit":{"count":6,"lastSeenTime":1586914742004},"Saftpresse":{"count":3,"lastSeenTime":1586718309085},"Heiße Schokolade":{"count":3,"lastSeenTime":1586900534749},"glücklich":{"count":7,"lastSeenTime":1586889682224,"difficulty":1,"difficultyWeight":32},"Drache":{"count":8,"lastSeenTime":1586955138676},"Rahmen":{"count":5,"lastSeenTime":1586859593426},"Malkasten":{"count":6,"lastSeenTime":1586920858569},"Seeigel":{"count":5,"lastSeenTime":1586879384676,"publicGameCount":1,"difficulty":0.30000000000000004,"difficultyWeight":10},"drehen":{"count":4,"lastSeenTime":1586919312988},"Apfelkuchen":{"count":6,"lastSeenTime":1586813030635,"publicGameCount":2,"difficulty":0.8823529411764706,"difficultyWeight":34},"Zwiebel":{"count":5,"lastSeenTime":1586915021163},"Gebiss":{"count":8,"lastSeenTime":1586955344691,"difficulty":1,"difficultyWeight":12},"Didgeridoo":{"count":10,"lastSeenTime":1586903543797},"gebrochenes Herz":{"count":4,"lastSeenTime":1586954975722,"difficulty":1,"difficultyWeight":2},"Falltür":{"count":7,"lastSeenTime":1586901521530,"difficulty":0.8571428571428571,"difficultyWeight":7},"Schlucht":{"count":8,"lastSeenTime":1586955503431,"difficulty":0.7333333333333333,"difficultyWeight":15},"Gewinner":{"count":5,"lastSeenTime":1586957855578},"Bestrafung":{"count":5,"lastSeenTime":1586902728303},"Dienstag":{"count":6,"lastSeenTime":1586806009929},"Vakuum":{"count":6,"lastSeenTime":1586959076238},"Wolkenkratzer":{"count":3,"lastSeenTime":1586859907934,"difficulty":0.9090909090909091,"difficultyWeight":22,"publicGameCount":1},"Feierabend":{"count":6,"lastSeenTime":1586915985961},"Wirbel":{"count":9,"lastSeenTime":1586913768003},"Anhängerkupplung":{"count":7,"lastSeenTime":1586955899639},"Mikrowelle":{"count":5,"lastSeenTime":1586881081098,"publicGameCount":1},"Kappe":{"count":5,"lastSeenTime":1586818561318,"difficulty":0.7692307692307693,"difficultyWeight":13},"Schweiß":{"count":8,"lastSeenTime":1586915406529},"Slinky":{"count":3,"lastSeenTime":1586869537106},"Bagel":{"count":4,"lastSeenTime":1586713516288},"Lehrer":{"count":6,"lastSeenTime":1586914918478},"Kreditkarte":{"count":8,"lastSeenTime":1586920872823},"Wetter":{"count":6,"lastSeenTime":1586920421902},"Polizei":{"count":6,"lastSeenTime":1586916575467,"difficulty":1,"difficultyWeight":11},"Pfau":{"count":4,"lastSeenTime":1586907788446},"Gras":{"count":8,"lastSeenTime":1586959344881},"Maßstab":{"count":6,"lastSeenTime":1586920576642},"Kontinent":{"count":4,"lastSeenTime":1586913816802},"Religion":{"count":5,"lastSeenTime":1586716941543},"Family Guy":{"count":3,"lastSeenTime":1586840180011},"Skydiving":{"count":6,"lastSeenTime":1586832445534},"Bergkette":{"count":4,"lastSeenTime":1586833456845},"Waschbär":{"count":7,"lastSeenTime":1586896816116},"Erbsen":{"count":3,"lastSeenTime":1586807947102},"Usain Bolt":{"count":9,"lastSeenTime":1586908597667},"Berg":{"count":3,"lastSeenTime":1586914683667},"Krebs":{"count":5,"lastSeenTime":1586957863554,"difficulty":0.375,"difficultyWeight":8},"Las Vegas":{"count":5,"lastSeenTime":1586860284075},"Finger":{"count":4,"lastSeenTime":1586903070812},"Pfeil":{"count":7,"lastSeenTime":1586869144958,"difficulty":0.7727272727272727,"difficultyWeight":22},"Gefrierschrank":{"count":2,"lastSeenTime":1586920226877},"Frühstück":{"count":3,"lastSeenTime":1586833915389},"Maske":{"count":4,"lastSeenTime":1586889552321,"difficulty":0.85,"difficultyWeight":20},"rasieren":{"count":4,"lastSeenTime":1586869412000,"publicGameCount":1,"difficulty":0.631578947368421,"difficultyWeight":19},"Punktestand":{"count":8,"lastSeenTime":1586909030886},"Honig":{"count":6,"lastSeenTime":1586896569941,"difficulty":0.5,"difficultyWeight":8},"Haarspange":{"count":4,"lastSeenTime":1586874324510},"Sarg":{"count":6,"lastSeenTime":1586921071907,"difficulty":0.375,"difficultyWeight":8},"Der Rosarote Panther":{"count":6,"lastSeenTime":1586827465786},"Park":{"count":2,"lastSeenTime":1586880262858,"difficulty":0.8181818181818182,"difficultyWeight":11},"Rettungsweste":{"count":6,"lastSeenTime":1586907351001},"träumen":{"count":4,"lastSeenTime":1586873278128,"difficulty":1,"difficultyWeight":1},"Mopp":{"count":4,"lastSeenTime":1586827202213},"Jimmy Neutron":{"count":7,"lastSeenTime":1586920954248},"Wall-e":{"count":7,"lastSeenTime":1586903447898,"difficulty":0.5,"difficultyWeight":8},"Monster":{"count":10,"lastSeenTime":1586959131863,"difficulty":0.7368421052631579,"difficultyWeight":57},"Quadrat":{"count":6,"lastSeenTime":1586890615582,"difficulty":0.782608695652174,"difficultyWeight":23},"Limonade":{"count":9,"lastSeenTime":1586956166526},"Kaugummikugel":{"count":10,"lastSeenTime":1586913783574,"difficulty":0.875,"difficultyWeight":8},"reparieren":{"count":7,"lastSeenTime":1586914727219},"Adler":{"count":9,"lastSeenTime":1586954886360,"difficulty":0.6666666666666666,"difficultyWeight":3},"Aquarium":{"count":7,"lastSeenTime":1586909046293},"Teekanne":{"count":9,"lastSeenTime":1586958187063},"tanzen":{"count":5,"lastSeenTime":1586783155447},"Pinocchio":{"count":4,"lastSeenTime":1586955620355},"Hähnchen":{"count":7,"lastSeenTime":1586959608297},"Profi":{"count":5,"lastSeenTime":1586916469958},"Luftschloss":{"count":4,"lastSeenTime":1586717552913,"publicGameCount":1,"difficulty":0.8888888888888888,"difficultyWeight":9},"Dänemark":{"count":7,"lastSeenTime":1586817683501},"Frucht":{"count":8,"lastSeenTime":1586915186679},"Gefängnis":{"count":6,"lastSeenTime":1586880581425},"Mammut":{"count":3,"lastSeenTime":1586919511658},"Durst":{"count":3,"lastSeenTime":1586880834242,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Lippenstift":{"count":3,"lastSeenTime":1586956336636},"Schweinchen Dick":{"count":8,"lastSeenTime":1586903726114},"Erdmännchen":{"count":4,"lastSeenTime":1586955848155},"Zelle":{"count":7,"lastSeenTime":1586915392140},"Krähe":{"count":2,"lastSeenTime":1586832774449,"publicGameCount":1,"difficulty":1,"difficultyWeight":9},"Sonnenblume":{"count":3,"lastSeenTime":1586903736584,"difficulty":0.4,"difficultyWeight":5},"Hawaii":{"count":8,"lastSeenTime":1586956166526},"essen":{"count":5,"lastSeenTime":1586920957237},"Gefahr":{"count":4,"lastSeenTime":1586718488883},"Cyborg":{"count":7,"lastSeenTime":1586914600906,"difficulty":1,"difficultyWeight":4},"Italien":{"count":2,"lastSeenTime":1586707253394,"difficulty":0.7000000000000001,"difficultyWeight":10},"Türschloss":{"count":6,"lastSeenTime":1586916415277,"difficulty":0.9285714285714286,"difficultyWeight":28},"aufnehmen":{"count":6,"lastSeenTime":1586901486180},"Yoshi":{"count":6,"lastSeenTime":1586899955403},"Leiter":{"count":11,"lastSeenTime":1586958525123},"Vollkornbrot":{"count":5,"lastSeenTime":1586902983849},"Arbeitszimmer":{"count":5,"lastSeenTime":1586904322754,"difficulty":0.9,"difficultyWeight":10},"Turban":{"count":6,"lastSeenTime":1586873614695},"Landschaft":{"count":5,"lastSeenTime":1586958897546},"Rührei":{"count":4,"lastSeenTime":1586956552197,"difficulty":0.8,"difficultyWeight":5},"Steam":{"count":6,"lastSeenTime":1586916328101},"schlagen":{"count":8,"lastSeenTime":1586909296939},"Gleichgewicht":{"count":9,"lastSeenTime":1586955862348},"Bratsche":{"count":5,"lastSeenTime":1586868707935},"Herkules":{"count":8,"lastSeenTime":1586959850831,"difficulty":1,"difficultyWeight":8},"überwintern":{"count":7,"lastSeenTime":1586873642917},"Anubis":{"count":6,"lastSeenTime":1586902587809},"Känguru":{"count":9,"lastSeenTime":1586914904157,"difficulty":1,"difficultyWeight":53},"Erde":{"count":6,"lastSeenTime":1586916690790,"publicGameCount":1,"difficulty":0.30000000000000004,"difficultyWeight":10},"Tiegel":{"count":5,"lastSeenTime":1586868982986},"Steinzeit":{"count":8,"lastSeenTime":1586956489403},"Brett":{"count":8,"lastSeenTime":1586959031017},"Puder":{"count":7,"lastSeenTime":1586859727901},"Räucherstäbchen":{"count":5,"lastSeenTime":1586959218404},"ausruhen":{"count":3,"lastSeenTime":1586782238298,"difficulty":0.8,"difficultyWeight":10},"Anwalt":{"count":4,"lastSeenTime":1586904135139,"difficulty":1,"difficultyWeight":3},"Indien":{"count":8,"lastSeenTime":1586814402764},"Wasserfarbkasten":{"count":6,"lastSeenTime":1586955948209},"Finnland":{"count":5,"lastSeenTime":1586955634694},"Susan Wojcicki":{"count":10,"lastSeenTime":1586921043126},"Handtuch":{"count":7,"lastSeenTime":1586957940022,"difficulty":0.4444444444444444,"difficultyWeight":9},"Antilope":{"count":6,"lastSeenTime":1586916415277},"Schleifpapier":{"count":4,"lastSeenTime":1586899930998},"Bart Simpson":{"count":6,"lastSeenTime":1586901606974},"Thaddäus Tentakel":{"count":4,"lastSeenTime":1586958848321,"difficulty":0.7142857142857143,"difficultyWeight":7},"riechen":{"count":7,"lastSeenTime":1586903587379},"Cupcake":{"count":3,"lastSeenTime":1586839889181},"Verlies":{"count":6,"lastSeenTime":1586858765870},"Maurer":{"count":11,"lastSeenTime":1586955429782,"difficulty":1,"difficultyWeight":7},"Phineas und Ferb":{"count":11,"lastSeenTime":1586880631457},"Zoo":{"count":3,"lastSeenTime":1586833481600},"Schiedsrichter":{"count":8,"lastSeenTime":1586889725951},"Vlogger":{"count":4,"lastSeenTime":1586833392800},"erröten":{"count":5,"lastSeenTime":1586816678295,"difficulty":1,"difficultyWeight":1},"John Lennon":{"count":5,"lastSeenTime":1586833992491},"Protest":{"count":5,"lastSeenTime":1586907461933},"Pedal":{"count":6,"lastSeenTime":1586896644364},"Stadion":{"count":8,"lastSeenTime":1586955098414,"difficulty":0.75,"difficultyWeight":8},"Pfad":{"count":9,"lastSeenTime":1586919327173},"Nagelfeile":{"count":9,"lastSeenTime":1586916430600},"Kleiderbügel":{"count":8,"lastSeenTime":1586959391653,"difficulty":0.45454545454545453,"difficultyWeight":11},"Kleinbus":{"count":5,"lastSeenTime":1586879867638},"Anhalter":{"count":8,"lastSeenTime":1586869459522},"Puzzle":{"count":8,"lastSeenTime":1586955595532},"Fächer":{"count":4,"lastSeenTime":1586895604165},"Bienenstock":{"count":10,"lastSeenTime":1586921298152},"Türstopper":{"count":9,"lastSeenTime":1586959508307,"difficulty":1,"difficultyWeight":1},"Honigwabe":{"count":8,"lastSeenTime":1586900549029},"dünn":{"count":3,"lastSeenTime":1586609722124,"difficulty":0.875,"difficultyWeight":24},"Japan":{"count":5,"lastSeenTime":1586839151208},"Mitfahrgelegenheit":{"count":6,"lastSeenTime":1586891149686},"Trauben":{"count":5,"lastSeenTime":1586879608242},"Schwertfisch":{"count":4,"lastSeenTime":1586915299932,"difficulty":1,"difficultyWeight":7},"Osterhase":{"count":11,"lastSeenTime":1586916164227,"difficulty":1,"difficultyWeight":15},"Elster":{"count":3,"lastSeenTime":1586901572201},"Bart":{"count":4,"lastSeenTime":1586901672587,"difficulty":0.6363636363636364,"difficultyWeight":11},"Bibliothekar":{"count":10,"lastSeenTime":1586955691477},"Olivenöl":{"count":5,"lastSeenTime":1586868185306},"Krug":{"count":5,"lastSeenTime":1586913893763},"Motte":{"count":4,"lastSeenTime":1586915129381,"difficulty":1,"difficultyWeight":4},"Meister":{"count":6,"lastSeenTime":1586900650119},"Südafrika":{"count":8,"lastSeenTime":1586919687264},"Pfund":{"count":7,"lastSeenTime":1586915985961},"Schimmel":{"count":7,"lastSeenTime":1586903359622,"publicGameCount":1,"difficulty":0.8181818181818182,"difficultyWeight":11},"Decke":{"count":5,"lastSeenTime":1586914465537},"Superkraft":{"count":4,"lastSeenTime":1586874652224,"difficulty":0.8571428571428571,"difficultyWeight":14},"Blaubeere":{"count":7,"lastSeenTime":1586914515993},"Nerd":{"count":4,"lastSeenTime":1586890454038},"Pfeffersalami":{"count":6,"lastSeenTime":1586873383077},"Mount Rushmore":{"count":6,"lastSeenTime":1586890816340,"difficulty":1,"difficultyWeight":4},"Kamera":{"count":7,"lastSeenTime":1586915566245},"Reisender":{"count":3,"lastSeenTime":1586874966390},"Manege":{"count":7,"lastSeenTime":1586896030801},"Linse":{"count":5,"lastSeenTime":1586880201224},"Spieler":{"count":7,"lastSeenTime":1586901500696},"übersetzen":{"count":6,"lastSeenTime":1586890714906,"difficulty":1,"difficultyWeight":6},"Verkehr":{"count":4,"lastSeenTime":1586818927139},"Lachs":{"count":7,"lastSeenTime":1586958496125,"difficulty":1,"difficultyWeight":4},"Truhe":{"count":6,"lastSeenTime":1586858897962,"difficulty":0.625,"difficultyWeight":16},"Zuckerwatte":{"count":3,"lastSeenTime":1586958658325},"Oberfläche":{"count":6,"lastSeenTime":1586914893907},"William Shakespeare":{"count":4,"lastSeenTime":1586904147395},"Zitteraal":{"count":7,"lastSeenTime":1586839545523,"publicGameCount":1,"difficulty":0.5555555555555556,"difficultyWeight":9},"Schweinestall":{"count":4,"lastSeenTime":1586959753084,"difficulty":1,"difficultyWeight":4},"Mars":{"count":5,"lastSeenTime":1586908982317,"publicGameCount":1,"difficulty":0,"difficultyWeight":8},"Kürbis":{"count":3,"lastSeenTime":1586907386047},"Fahrbahn":{"count":6,"lastSeenTime":1586956477794},"Knie":{"count":7,"lastSeenTime":1586956016971},"Stiefel":{"count":9,"lastSeenTime":1586956181125,"difficulty":0.9047619047619048,"difficultyWeight":21},"Hunger":{"count":13,"lastSeenTime":1586957925802,"difficulty":1,"difficultyWeight":60},"Konsole":{"count":3,"lastSeenTime":1586724124838,"difficulty":1,"difficultyWeight":6},"Magier":{"count":13,"lastSeenTime":1586889696772},"Badekappe":{"count":3,"lastSeenTime":1586826659168},"Sommer":{"count":6,"lastSeenTime":1586874622713,"difficulty":1,"difficultyWeight":4},"abheben":{"count":4,"lastSeenTime":1586903771458},"Weintrauben":{"count":8,"lastSeenTime":1586908721968,"publicGameCount":1,"difficulty":0,"difficultyWeight":8},"Band":{"count":5,"lastSeenTime":1586916352907},"Tablett":{"count":10,"lastSeenTime":1586907743895},"Fahrwerk":{"count":4,"lastSeenTime":1586908470256},"Dattel":{"count":6,"lastSeenTime":1586916493492},"Darwin":{"count":4,"lastSeenTime":1586833367687},"Festung":{"count":2,"lastSeenTime":1586914221389},"Haltestelle":{"count":5,"lastSeenTime":1586908763208,"difficulty":1,"difficultyWeight":6},"Kaktus":{"count":6,"lastSeenTime":1586889576969,"difficulty":0.45454545454545453,"difficultyWeight":11},"Nachos":{"count":6,"lastSeenTime":1586959714261,"publicGameCount":1,"difficulty":0.9090909090909091,"difficultyWeight":11},"Stoßstange":{"count":6,"lastSeenTime":1586955848155},"Wattestäbchen":{"count":3,"lastSeenTime":1586913962978,"difficulty":0.9111111111111111,"difficultyWeight":45},"Ratatouille":{"count":4,"lastSeenTime":1586880239561},"Wonder Woman":{"count":7,"lastSeenTime":1586920947128},"Wanze":{"count":6,"lastSeenTime":1586920566543},"Vater":{"count":7,"lastSeenTime":1586890353925,"difficulty":1,"difficultyWeight":7},"Pappe":{"count":11,"lastSeenTime":1586919858412},"Augenbinde":{"count":8,"lastSeenTime":1586956263288},"Bank":{"count":4,"lastSeenTime":1586833496863},"Blume":{"count":6,"lastSeenTime":1586959547988,"difficulty":1,"difficultyWeight":9},"Mercedes":{"count":5,"lastSeenTime":1586880609937,"publicGameCount":1,"difficulty":0.9,"difficultyWeight":10},"gehen":{"count":6,"lastSeenTime":1586895808940},"Angelina Jolie":{"count":6,"lastSeenTime":1586919711626},"Versicherung":{"count":5,"lastSeenTime":1586955877308},"Straße":{"count":12,"lastSeenTime":1586920627218},"USB":{"count":8,"lastSeenTime":1586904234099},"Aristokrat":{"count":2,"lastSeenTime":1586901089526},"Fischer":{"count":5,"lastSeenTime":1586959121500,"difficulty":1,"difficultyWeight":10},"Pavian":{"count":6,"lastSeenTime":1586907743895},"Wunderland":{"count":4,"lastSeenTime":1586958077398,"difficulty":1,"difficultyWeight":1},"Glut":{"count":5,"lastSeenTime":1586915215166},"Grenze":{"count":8,"lastSeenTime":1586907436625},"Gabel":{"count":9,"lastSeenTime":1586839654737,"difficulty":0.4,"difficultyWeight":15},"Cat Woman":{"count":2,"lastSeenTime":1586907707534},"Skyline":{"count":5,"lastSeenTime":1586954603172,"difficulty":1,"difficultyWeight":5},"Erdbeere":{"count":7,"lastSeenTime":1586915186679,"publicGameCount":1,"difficulty":0.7352941176470589,"difficultyWeight":34},"Finn und Jake":{"count":4,"lastSeenTime":1586958572090},"Mel Gibson":{"count":7,"lastSeenTime":1586958658325},"Hausnummer":{"count":7,"lastSeenTime":1586908204031,"difficulty":0.5,"difficultyWeight":6},"Spitzhacke":{"count":6,"lastSeenTime":1586956019428},"Bajonett":{"count":9,"lastSeenTime":1586958141882},"Sumo":{"count":5,"lastSeenTime":1586895467027},"gelangweilt":{"count":6,"lastSeenTime":1586920947128},"Ziegenbart":{"count":4,"lastSeenTime":1586896444515,"difficulty":0.8333333333333334,"difficultyWeight":24},"Tetra Pak":{"count":9,"lastSeenTime":1586915821415,"difficulty":1,"difficultyWeight":7},"ringen":{"count":5,"lastSeenTime":1586813390059},"Salzwasser":{"count":4,"lastSeenTime":1586783782593,"difficulty":1,"difficultyWeight":7},"Zeitung":{"count":2,"lastSeenTime":1586916230527,"difficulty":0.6,"difficultyWeight":10},"Rad":{"count":3,"lastSeenTime":1586840557813,"difficulty":0.9545454545454546,"difficultyWeight":44},"Scheidung":{"count":3,"lastSeenTime":1586958755749},"Schneesturm":{"count":7,"lastSeenTime":1586955088291,"difficulty":0.8571428571428571,"difficultyWeight":7},"Lexikon":{"count":4,"lastSeenTime":1586897164255},"Haken":{"count":2,"lastSeenTime":1586784919921},"Mechaniker":{"count":6,"lastSeenTime":1586896926779},"Skulptur":{"count":6,"lastSeenTime":1586880423720,"difficulty":1,"difficultyWeight":8},"Server":{"count":4,"lastSeenTime":1586726377611},"Bademantel":{"count":7,"lastSeenTime":1586895639777,"publicGameCount":1,"difficulty":0.8709677419354839,"difficultyWeight":31},"Griechenland":{"count":3,"lastSeenTime":1586902926018,"publicGameCount":1,"difficulty":0.9285714285714286,"difficultyWeight":14},"trinken":{"count":7,"lastSeenTime":1586914631184},"schlecht":{"count":6,"lastSeenTime":1586896595013,"publicGameCount":1},"vergessen":{"count":7,"lastSeenTime":1586955559002},"Muffin":{"count":8,"lastSeenTime":1586913798295},"Halbkreis":{"count":3,"lastSeenTime":1586899902236},"Schreibfeder":{"count":2,"lastSeenTime":1586816295247},"Tierarzt":{"count":4,"lastSeenTime":1586916441133},"Navy":{"count":11,"lastSeenTime":1586958897546},"Ferkel":{"count":5,"lastSeenTime":1586913467503,"difficulty":1,"difficultyWeight":5},"Patronenhülse":{"count":6,"lastSeenTime":1586873513174,"difficulty":0.9166666666666666,"difficultyWeight":12},"Bibel":{"count":6,"lastSeenTime":1586839953759},"geizig":{"count":3,"lastSeenTime":1586889892808},"Minze":{"count":5,"lastSeenTime":1586957855578},"Wolle":{"count":8,"lastSeenTime":1586916731964},"Cappuccino":{"count":4,"lastSeenTime":1586955517665},"Krankenwagen":{"count":5,"lastSeenTime":1586920982151},"Lüfter":{"count":4,"lastSeenTime":1586895847874},"Wal":{"count":4,"lastSeenTime":1586896080519,"difficulty":1,"difficultyWeight":3},"Ufer":{"count":6,"lastSeenTime":1586873419448},"chemisch":{"count":12,"lastSeenTime":1586959342619,"difficulty":0.375,"difficultyWeight":8},"Lisa Simpson":{"count":10,"lastSeenTime":1586903158426},"zurückspulen":{"count":8,"lastSeenTime":1586955300241},"Garfield":{"count":8,"lastSeenTime":1586869383090},"Schal":{"count":7,"lastSeenTime":1586958858535,"difficulty":1,"difficultyWeight":1},"Tischtennisschläger":{"count":4,"lastSeenTime":1586889489199},"Flagge":{"count":5,"lastSeenTime":1586915442369},"E-Gitarre":{"count":7,"lastSeenTime":1586903097380,"difficulty":1,"difficultyWeight":2},"einkaufen":{"count":9,"lastSeenTime":1586889566614,"difficulty":0.8333333333333334,"difficultyWeight":6},"Beerdigung":{"count":5,"lastSeenTime":1586904002117,"difficulty":1,"difficultyWeight":3},"Zylinder":{"count":3,"lastSeenTime":1586873715364},"Toast":{"count":4,"lastSeenTime":1586915478982},"Kompass":{"count":5,"lastSeenTime":1586832545576},"Schnellstraße":{"count":8,"lastSeenTime":1586919736561},"Sonnensystem":{"count":6,"lastSeenTime":1586955063993},"Liebe":{"count":6,"lastSeenTime":1586920421902},"Windsurfer":{"count":5,"lastSeenTime":1586920446574},"Fingerpuppe":{"count":2,"lastSeenTime":1586712445503},"Frisbee":{"count":5,"lastSeenTime":1586880408576,"difficulty":1,"difficultyWeight":1},"Rune":{"count":6,"lastSeenTime":1586915456714},"Mistgabel":{"count":5,"lastSeenTime":1586919664805},"Komiker":{"count":4,"lastSeenTime":1586915960185},"Floh":{"count":6,"lastSeenTime":1586870018417,"difficulty":0.8571428571428571,"difficultyWeight":7},"Pinienkerne":{"count":1,"lastSeenTime":1586580794838},"Puppe":{"count":5,"lastSeenTime":1586958154127},"Aktion":{"count":5,"lastSeenTime":1586896095108},"Amsel":{"count":8,"lastSeenTime":1586959738785},"Cockpit":{"count":10,"lastSeenTime":1586919477051,"difficulty":0.7142857142857143,"difficultyWeight":7},"Patenonkel":{"count":7,"lastSeenTime":1586915924921},"Sandkasten":{"count":4,"lastSeenTime":1586914806527},"Ampelmännchen":{"count":4,"lastSeenTime":1586955063993,"difficulty":0.8823529411764706,"difficultyWeight":34},"voll":{"count":4,"lastSeenTime":1586915806469},"Ostern":{"count":3,"lastSeenTime":1586879394962,"difficulty":0.5,"difficultyWeight":8},"feuerfest":{"count":8,"lastSeenTime":1586954774095},"Geige":{"count":7,"lastSeenTime":1586920872823,"difficulty":0.8571428571428571,"difficultyWeight":28},"Kiwi":{"count":10,"lastSeenTime":1586919501543,"publicGameCount":1,"difficulty":1,"difficultyWeight":33},"Getränk":{"count":7,"lastSeenTime":1586919722216},"Ingenieur":{"count":3,"lastSeenTime":1586903281878,"difficulty":1,"difficultyWeight":3},"Tetris":{"count":8,"lastSeenTime":1586914932818},"Ast":{"count":3,"lastSeenTime":1586868143512,"difficulty":1,"difficultyWeight":38},"Dinosaurier":{"count":4,"lastSeenTime":1586915099808,"difficulty":0.33333333333333337,"difficultyWeight":9},"Spritze":{"count":3,"lastSeenTime":1586954763962,"publicGameCount":1,"difficulty":0.42857142857142855,"difficultyWeight":7},"Schaukelstuhl":{"count":7,"lastSeenTime":1586881119264},"Google":{"count":6,"lastSeenTime":1586959443697},"Tukan":{"count":6,"lastSeenTime":1586900941854,"difficulty":1,"difficultyWeight":6},"Hackbraten":{"count":4,"lastSeenTime":1586919434514},"Trainer":{"count":6,"lastSeenTime":1586914465537},"arbeiten":{"count":7,"lastSeenTime":1586902658307},"Streichholz":{"count":5,"lastSeenTime":1586896595013,"difficulty":1,"difficultyWeight":20},"Lüftung":{"count":2,"lastSeenTime":1586817610330,"difficulty":0.75,"difficultyWeight":8},"Erfindung":{"count":5,"lastSeenTime":1586902587810},"Origami":{"count":5,"lastSeenTime":1586913757766},"Armband":{"count":6,"lastSeenTime":1586955324504},"Hügel":{"count":5,"lastSeenTime":1586920552243},"Bestatter":{"count":10,"lastSeenTime":1586874409884,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":10},"Wissenschaftler":{"count":5,"lastSeenTime":1586920324660},"Grafiktablett":{"count":6,"lastSeenTime":1586879298099,"difficulty":0.8181818181818182,"difficultyWeight":11},"Sand":{"count":5,"lastSeenTime":1586916153776},"Lady":{"count":6,"lastSeenTime":1586913893763},"Kazoo":{"count":2,"lastSeenTime":1586915737415},"toter Winkel":{"count":6,"lastSeenTime":1586891099195},"Omelett":{"count":5,"lastSeenTime":1586880936347},"Pluto":{"count":3,"lastSeenTime":1586859933316,"difficulty":1,"difficultyWeight":7},"Schornstein":{"count":5,"lastSeenTime":1586920265574,"difficulty":1,"difficultyWeight":7},"Mottenkugel":{"count":5,"lastSeenTime":1586955249129},"Zaubertrank":{"count":5,"lastSeenTime":1586958027091},"Gully":{"count":2,"lastSeenTime":1586955838030},"Pobacken":{"count":3,"lastSeenTime":1586908597667,"difficulty":1,"difficultyWeight":1},"Stewardess":{"count":5,"lastSeenTime":1586907472056},"Klaviersaite":{"count":8,"lastSeenTime":1586920895382},"Organ":{"count":9,"lastSeenTime":1586959767498},"Fußball":{"count":7,"lastSeenTime":1586901146209},"Bedienung":{"count":3,"lastSeenTime":1586909030886},"Grafik":{"count":3,"lastSeenTime":1586920153587},"Teufel":{"count":6,"lastSeenTime":1586818535737,"publicGameCount":1,"difficulty":1,"difficultyWeight":11},"Linie":{"count":6,"lastSeenTime":1586890443871},"Jupiter":{"count":5,"lastSeenTime":1586860123492},"Lanze":{"count":10,"lastSeenTime":1586913962978},"Ring":{"count":2,"lastSeenTime":1586724556569,"publicGameCount":1,"difficulty":0.6538461538461539,"difficultyWeight":26},"High Five":{"count":6,"lastSeenTime":1586896166029,"publicGameCount":1,"difficulty":0.8235294117647058,"difficultyWeight":17},"Wimper":{"count":6,"lastSeenTime":1586913497512,"difficulty":0.9428571428571428,"difficultyWeight":35},"zoomen":{"count":5,"lastSeenTime":1586921094172},"Rechen":{"count":4,"lastSeenTime":1586958253918},"Amboss":{"count":4,"lastSeenTime":1586889697457,"difficulty":1,"difficultyWeight":7},"Zickzack":{"count":12,"lastSeenTime":1586954688633},"Ohrhörer":{"count":7,"lastSeenTime":1586914243836,"difficulty":1,"difficultyWeight":3},"Parfüm":{"count":3,"lastSeenTime":1586915021163},"Rollschuhe":{"count":6,"lastSeenTime":1586908103784,"difficulty":0.8636363636363636,"difficultyWeight":44},"Hippie":{"count":4,"lastSeenTime":1586718322766},"Kuba":{"count":5,"lastSeenTime":1586900776963},"Rolltreppe":{"count":9,"lastSeenTime":1586903048902},"Schlange":{"count":7,"lastSeenTime":1586920751201},"Ellbogen":{"count":4,"lastSeenTime":1586904161945,"difficulty":1,"difficultyWeight":1},"Donut":{"count":6,"lastSeenTime":1586958289143,"difficulty":1,"difficultyWeight":21},"Zeppelin":{"count":10,"lastSeenTime":1586955419506,"difficulty":1,"difficultyWeight":46},"reinigen":{"count":6,"lastSeenTime":1586858960624},"Wasserpfeife":{"count":4,"lastSeenTime":1586916637868},"beizen":{"count":8,"lastSeenTime":1586908996510},"Comicbuch":{"count":5,"lastSeenTime":1586915624112,"difficulty":1,"difficultyWeight":10},"Palast":{"count":7,"lastSeenTime":1586908204031},"Yoda":{"count":3,"lastSeenTime":1586955010181,"difficulty":1,"difficultyWeight":2},"Mixer":{"count":6,"lastSeenTime":1586915339348,"publicGameCount":1,"difficulty":0.5,"difficultyWeight":8},"Hosenstall":{"count":4,"lastSeenTime":1586956336636,"publicGameCount":1,"difficulty":0.5714285714285714,"difficultyWeight":7},"Chinchilla":{"count":4,"lastSeenTime":1586908945942},"Briefkasten":{"count":5,"lastSeenTime":1586881205453},"The Beatles":{"count":6,"lastSeenTime":1586959232575},"Birke":{"count":8,"lastSeenTime":1586902687551},"Brunnen":{"count":4,"lastSeenTime":1586826911367},"Reifen":{"count":5,"lastSeenTime":1586873308659},"Dosenöffner":{"count":6,"lastSeenTime":1586891228286},"Ordner":{"count":8,"lastSeenTime":1586958278719,"difficulty":1,"difficultyWeight":3},"Müllabfuhr":{"count":3,"lastSeenTime":1586900240367},"Mais":{"count":3,"lastSeenTime":1586900866878,"publicGameCount":1,"difficulty":0.8,"difficultyWeight":10},"Galaxie":{"count":6,"lastSeenTime":1586907754016,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":4},"Tweety":{"count":9,"lastSeenTime":1586908757151},"Kirschblüte":{"count":5,"lastSeenTime":1586920690415},"Anhänger":{"count":4,"lastSeenTime":1586916074772},"Milchshake":{"count":6,"lastSeenTime":1586913988149},"Irokesenfrisur":{"count":5,"lastSeenTime":1586958944806,"difficulty":0.6666666666666667,"difficultyWeight":9},"Sohn":{"count":1,"lastSeenTime":1586589989733,"difficulty":1,"difficultyWeight":1},"Schneeballschlacht":{"count":3,"lastSeenTime":1586954910317},"sabbern":{"count":6,"lastSeenTime":1586954939261},"Tintenpatrone":{"count":5,"lastSeenTime":1586959142159},"Essig":{"count":7,"lastSeenTime":1586907754016},"Lilie":{"count":6,"lastSeenTime":1586955370991,"difficulty":1,"difficultyWeight":6},"Ferse":{"count":3,"lastSeenTime":1586916540283,"difficulty":0.42857142857142855,"difficultyWeight":7},"föhnen":{"count":7,"lastSeenTime":1586959131863},"Akne":{"count":4,"lastSeenTime":1586880759383},"Prinz":{"count":6,"lastSeenTime":1586889638222},"Ampel":{"count":6,"lastSeenTime":1586889591248,"publicGameCount":2,"difficulty":0.7333333333333333,"difficultyWeight":45},"Patrick Star":{"count":8,"lastSeenTime":1586954967541,"publicGameCount":1,"difficulty":0.875,"difficultyWeight":8},"Einrad":{"count":6,"lastSeenTime":1586890806055,"difficulty":0.9,"difficultyWeight":10},"Schwalbe":{"count":5,"lastSeenTime":1586901274634},"Postbote":{"count":6,"lastSeenTime":1586954603173,"difficulty":0.7,"difficultyWeight":10},"Korkenzieher":{"count":3,"lastSeenTime":1586814402764},"Heiligenschein":{"count":6,"lastSeenTime":1586859642077},"Rennauto":{"count":3,"lastSeenTime":1586874409884,"difficulty":0.9,"difficultyWeight":10},"Schüssel":{"count":6,"lastSeenTime":1586959207698,"difficulty":1,"difficultyWeight":1},"Leck":{"count":6,"lastSeenTime":1586958668588},"prallen":{"count":6,"lastSeenTime":1586916493492,"difficulty":1,"difficultyWeight":36},"Schweißer":{"count":8,"lastSeenTime":1586921283836},"Köcher":{"count":7,"lastSeenTime":1586958239433},"Rote Beete":{"count":6,"lastSeenTime":1586920237009},"Hollywood":{"count":4,"lastSeenTime":1586880759383},"Bob Ross":{"count":6,"lastSeenTime":1586914515993},"Donnerstag":{"count":3,"lastSeenTime":1586826344267,"difficulty":0.4117647058823529,"difficultyWeight":17},"Fallschirm":{"count":9,"lastSeenTime":1586908583500,"difficulty":1,"difficultyWeight":11},"Gorilla":{"count":7,"lastSeenTime":1586956033779},"Orchester":{"count":6,"lastSeenTime":1586956336636},"Lagerhaus":{"count":5,"lastSeenTime":1586859907934},"Bienenkönigin":{"count":4,"lastSeenTime":1586901397893,"difficulty":0.7878787878787878,"difficultyWeight":33},"Mayonnaise":{"count":5,"lastSeenTime":1586955716758},"Reptil":{"count":12,"lastSeenTime":1586915059551},"Lichtschwert":{"count":4,"lastSeenTime":1586896127512,"difficulty":1,"difficultyWeight":6},"Sandburg":{"count":3,"lastSeenTime":1586807745991},"Brathering":{"count":2,"lastSeenTime":1586895949288},"Leonardo da Vinci":{"count":5,"lastSeenTime":1586900226190},"U-Bahn":{"count":6,"lastSeenTime":1586916574944},"Echo":{"count":5,"lastSeenTime":1586897250506,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":6},"Biss":{"count":1,"lastSeenTime":1586590631736},"Fernbedienung":{"count":3,"lastSeenTime":1586913648704},"Vodka":{"count":6,"lastSeenTime":1586919711626},"Captain America":{"count":4,"lastSeenTime":1586916038112},"Pfeffer":{"count":7,"lastSeenTime":1586920926700,"difficulty":0.7428571428571429,"difficultyWeight":35,"publicGameCount":1},"Gummibärchen":{"count":4,"lastSeenTime":1586916063451},"Beethoven":{"count":4,"lastSeenTime":1586954900699},"Rasierklinge":{"count":7,"lastSeenTime":1586958264090},"Seiltänzer":{"count":5,"lastSeenTime":1586900749260},"Zucchini":{"count":5,"lastSeenTime":1586955542167,"difficulty":0.6666666666666666,"difficultyWeight":24},"Sandsturm":{"count":3,"lastSeenTime":1586959547988},"Fliegenpilz":{"count":8,"lastSeenTime":1586881220427,"difficulty":0.8888888888888888,"difficultyWeight":9},"Zügel":{"count":7,"lastSeenTime":1586915176554},"Barack Obama":{"count":7,"lastSeenTime":1586839026220},"Schleife":{"count":4,"lastSeenTime":1586913868342},"Mahlzeit":{"count":6,"lastSeenTime":1586880019286,"difficulty":1,"difficultyWeight":1},"Autoradio":{"count":8,"lastSeenTime":1586902787660,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":4},"lernen":{"count":5,"lastSeenTime":1586897039497},"Matsch":{"count":3,"lastSeenTime":1586815745247},"seekrank":{"count":3,"lastSeenTime":1586908382794,"difficulty":0.25,"difficultyWeight":8},"Olaf":{"count":6,"lastSeenTime":1586915919352},"Schaf":{"count":8,"lastSeenTime":1586890490289,"publicGameCount":1},"Spiegel":{"count":4,"lastSeenTime":1586881220427,"difficulty":1,"difficultyWeight":14},"positiv":{"count":3,"lastSeenTime":1586956363582,"difficulty":0.8305084745762712,"difficultyWeight":59},"Cheeseburger":{"count":5,"lastSeenTime":1586958561895},"Liechtenstein":{"count":5,"lastSeenTime":1586896569941},"fabelhaft":{"count":5,"lastSeenTime":1586909006610},"Winzer":{"count":2,"lastSeenTime":1586908395891},"kopieren":{"count":7,"lastSeenTime":1586959242580,"difficulty":1,"difficultyWeight":50},"Doritos":{"count":6,"lastSeenTime":1586919423610},"gehorchen":{"count":6,"lastSeenTime":1586920836680},"Niederlande":{"count":2,"lastSeenTime":1586903158426},"WhatsApp":{"count":7,"lastSeenTime":1586914491372,"difficulty":0.5,"difficultyWeight":4},"Fernseher":{"count":4,"lastSeenTime":1586919811805,"difficulty":0.9333333333333333,"difficultyWeight":15},"Geld":{"count":2,"lastSeenTime":1586726008015},"Wrestling":{"count":5,"lastSeenTime":1586900650119},"tot":{"count":11,"lastSeenTime":1586958212167},"Kuhglocke":{"count":10,"lastSeenTime":1586901321700},"Gehirn":{"count":7,"lastSeenTime":1586958859906,"difficulty":1,"difficultyWeight":5},"New York":{"count":9,"lastSeenTime":1586914373601},"Gepäck":{"count":10,"lastSeenTime":1586956016971,"difficulty":1,"difficultyWeight":16},"Spartacus":{"count":7,"lastSeenTime":1586890454038},"Kabel":{"count":7,"lastSeenTime":1586806153755},"Armaturenbrett":{"count":5,"lastSeenTime":1586954674416},"Wein":{"count":7,"lastSeenTime":1586955923939,"difficulty":0.36363636363636365,"difficultyWeight":11},"Michael Jackson":{"count":3,"lastSeenTime":1586920375356},"Videospiel":{"count":9,"lastSeenTime":1586913482555},"Curry":{"count":10,"lastSeenTime":1586955532027},"Kitesurfen":{"count":1,"lastSeenTime":1586591460245},"Reis":{"count":8,"lastSeenTime":1586907764126},"Jenga":{"count":9,"lastSeenTime":1586915089601},"massieren":{"count":3,"lastSeenTime":1586840060848},"Zündschnur":{"count":4,"lastSeenTime":1586954999969,"difficulty":1,"difficultyWeight":7},"Eigelb":{"count":4,"lastSeenTime":1586708871882},"Wurm":{"count":7,"lastSeenTime":1586858975693},"unsichtbar":{"count":7,"lastSeenTime":1586920922732},"gut":{"count":4,"lastSeenTime":1586817823665},"Schottenrock":{"count":5,"lastSeenTime":1586900254522},"Kopfende":{"count":5,"lastSeenTime":1586903572367,"difficulty":1,"difficultyWeight":6},"Fischgräte":{"count":4,"lastSeenTime":1586833356919},"nichts":{"count":5,"lastSeenTime":1586955823724},"Braut":{"count":14,"lastSeenTime":1586916680436},"Mischpult":{"count":6,"lastSeenTime":1586860406384},"Lehm":{"count":7,"lastSeenTime":1586889638222},"Erdnuss":{"count":7,"lastSeenTime":1586958887354},"Briefträger":{"count":4,"lastSeenTime":1586959269543,"difficulty":0.9375,"difficultyWeight":16},"Miniclip":{"count":7,"lastSeenTime":1586913998392},"Blumenstrauß":{"count":4,"lastSeenTime":1586916013387},"Ziegelstein":{"count":6,"lastSeenTime":1586840420314},"Öl":{"count":4,"lastSeenTime":1586958212167},"Aprikose":{"count":5,"lastSeenTime":1586891163944,"publicGameCount":1,"difficulty":0.6666666666666667,"difficultyWeight":9},"Taube":{"count":6,"lastSeenTime":1586901052765},"Wissenschaft":{"count":6,"lastSeenTime":1586916237094},"Champagnersorbet":{"count":6,"lastSeenTime":1586896666647},"fallen":{"count":2,"lastSeenTime":1586805561130},"Israel":{"count":4,"lastSeenTime":1586827800087,"difficulty":1,"difficultyWeight":4},"Milchstraße":{"count":8,"lastSeenTime":1586900660239},"Wippe":{"count":4,"lastSeenTime":1586955726995,"difficulty":1,"difficultyWeight":5},"Kaviar":{"count":6,"lastSeenTime":1586959622590},"Hafen":{"count":7,"lastSeenTime":1586958171361,"publicGameCount":1,"difficulty":0.7931034482758621,"difficultyWeight":29},"Minute":{"count":8,"lastSeenTime":1586897516933},"Zuckerguss":{"count":2,"lastSeenTime":1586707490326},"Bock":{"count":3,"lastSeenTime":1586806457936},"Fleisch":{"count":6,"lastSeenTime":1586903122787,"difficulty":0.875,"difficultyWeight":8},"Schnabel":{"count":7,"lastSeenTime":1586958456673},"Erdbeben":{"count":5,"lastSeenTime":1586900724985},"Zwerg":{"count":1,"lastSeenTime":1586595084509},"Außerirdischer":{"count":4,"lastSeenTime":1586902687551},"Zunge":{"count":4,"lastSeenTime":1586920922732},"Harz":{"count":5,"lastSeenTime":1586915312713},"Nasa":{"count":5,"lastSeenTime":1586896902340},"LKW":{"count":7,"lastSeenTime":1586956009184},"Salz":{"count":6,"lastSeenTime":1586896095108},"Schicksal":{"count":7,"lastSeenTime":1586920326688},"arm":{"count":7,"lastSeenTime":1586919522211,"difficulty":1,"difficultyWeight":1},"Schmetterling":{"count":4,"lastSeenTime":1586958289143},"Mäusefalle":{"count":10,"lastSeenTime":1586956504597,"difficulty":0.9444444444444444,"difficultyWeight":36},"Hals":{"count":3,"lastSeenTime":1586826301547},"Teddybär":{"count":6,"lastSeenTime":1586955370991,"difficulty":0.8235294117647058,"difficultyWeight":17},"Biber":{"count":7,"lastSeenTime":1586916461517,"difficulty":1,"difficultyWeight":16},"Eminem":{"count":3,"lastSeenTime":1586904308260},"Nasenring":{"count":6,"lastSeenTime":1586955823724,"difficulty":1,"difficultyWeight":9},"Daffy Duck":{"count":4,"lastSeenTime":1586873936206},"Darm":{"count":8,"lastSeenTime":1586959255115},"kleiner Finger":{"count":2,"lastSeenTime":1586651151122,"publicGameCount":1,"difficulty":0.4666666666666667,"difficultyWeight":15},"Mütze":{"count":3,"lastSeenTime":1586815197615,"difficulty":1,"difficultyWeight":8},"Sitzbank":{"count":9,"lastSeenTime":1586958471219,"publicGameCount":1,"difficulty":0.9655172413793104,"difficultyWeight":29},"Schiffswrack":{"count":2,"lastSeenTime":1586596602460},"Archäologe":{"count":3,"lastSeenTime":1586840929412},"Duell":{"count":8,"lastSeenTime":1586907557164,"difficulty":0.5,"difficultyWeight":12},"Kröte":{"count":8,"lastSeenTime":1586908626057},"Punkte":{"count":3,"lastSeenTime":1586904287692,"difficulty":0.6666666666666666,"difficultyWeight":3},"Kojote":{"count":6,"lastSeenTime":1586956570180},"Reddit":{"count":9,"lastSeenTime":1586958052113,"difficulty":0.8333333333333334,"difficultyWeight":18},"iPad":{"count":6,"lastSeenTime":1586896714278},"Katapult":{"count":3,"lastSeenTime":1586919983033},"Leiterwagen":{"count":6,"lastSeenTime":1586901191898},"Schalter":{"count":6,"lastSeenTime":1586833150052},"Lotterie":{"count":3,"lastSeenTime":1586955644811,"difficulty":0.9583333333333334,"difficultyWeight":24},"China":{"count":3,"lastSeenTime":1586915856980,"difficulty":1,"difficultyWeight":7},"Anführer":{"count":4,"lastSeenTime":1586815327708},"Waschstraße":{"count":4,"lastSeenTime":1586874562516},"Seetang":{"count":4,"lastSeenTime":1586955542167,"difficulty":1,"difficultyWeight":11},"Tasmanischer Teufel":{"count":3,"lastSeenTime":1586916368116},"bauchpinseln":{"count":5,"lastSeenTime":1586879160227,"publicGameCount":1},"Filter":{"count":3,"lastSeenTime":1586859018427},"Bett":{"count":9,"lastSeenTime":1586955409372,"difficulty":1,"difficultyWeight":7},"Schlüsselanhänger":{"count":4,"lastSeenTime":1586916461517,"difficulty":1,"difficultyWeight":6},"Giraffe":{"count":2,"lastSeenTime":1586874945892,"difficulty":1,"difficultyWeight":9},"Wildschwein":{"count":6,"lastSeenTime":1586956130879},"Kino":{"count":3,"lastSeenTime":1586921170819},"Chirurg":{"count":9,"lastSeenTime":1586889475038,"difficulty":0.8,"difficultyWeight":5},"Lampenschirm":{"count":6,"lastSeenTime":1586914094806},"schwach":{"count":6,"lastSeenTime":1586889917123},"Leonardo DiCaprio":{"count":4,"lastSeenTime":1586827438446},"Pringles":{"count":2,"lastSeenTime":1586915417224},"Terrasse":{"count":5,"lastSeenTime":1586840254824,"difficulty":0.8787878787878788,"difficultyWeight":33},"rauchen":{"count":7,"lastSeenTime":1586873988685},"Kerze":{"count":2,"lastSeenTime":1586717755995,"difficulty":0.7,"difficultyWeight":10},"gelb":{"count":3,"lastSeenTime":1586908541127},"Bitcoin":{"count":5,"lastSeenTime":1586920180037},"Homer Simpson":{"count":6,"lastSeenTime":1586840216366},"Patrone":{"count":4,"lastSeenTime":1586889725951},"Kuh":{"count":7,"lastSeenTime":1586956324955},"Mülleimer":{"count":11,"lastSeenTime":1586959020405},"Sushi":{"count":6,"lastSeenTime":1586896805974},"Poker":{"count":3,"lastSeenTime":1586859615003},"Waffel":{"count":7,"lastSeenTime":1586958794944},"Gazelle":{"count":4,"lastSeenTime":1586908518895,"difficulty":0.7857142857142857,"difficultyWeight":14},"Morty":{"count":2,"lastSeenTime":1586785081909},"Waldbrand":{"count":7,"lastSeenTime":1586959344881},"Delle":{"count":3,"lastSeenTime":1586805672921},"Virus":{"count":5,"lastSeenTime":1586907788446},"Veganer":{"count":3,"lastSeenTime":1586868461473,"difficulty":0.7142857142857143,"difficultyWeight":21},"nähen":{"count":4,"lastSeenTime":1586727015282},"Sandwich":{"count":5,"lastSeenTime":1586901361357},"Ozean":{"count":6,"lastSeenTime":1586956570180,"difficulty":0.5555555555555556,"difficultyWeight":9},"Stern":{"count":5,"lastSeenTime":1586901461723},"Jahreszeit":{"count":8,"lastSeenTime":1586958499761},"Mozart":{"count":5,"lastSeenTime":1586832383649,"difficulty":0.8571428571428571,"difficultyWeight":7},"Schornsteinfeger":{"count":7,"lastSeenTime":1586879670490,"difficulty":1,"difficultyWeight":9},"Magazin":{"count":5,"lastSeenTime":1586916415277,"difficulty":0.6666666666666666,"difficultyWeight":6},"schmelzen":{"count":6,"lastSeenTime":1586890729326},"Silvester":{"count":7,"lastSeenTime":1586958375030,"difficulty":0.9411764705882353,"difficultyWeight":17},"Eintopf":{"count":6,"lastSeenTime":1586921071907},"Lidschatten":{"count":5,"lastSeenTime":1586955503431},"Traum":{"count":5,"lastSeenTime":1586959804291},"Kruste":{"count":4,"lastSeenTime":1586920432273},"pfeifen":{"count":3,"lastSeenTime":1586896458746,"difficulty":0.4,"difficultyWeight":10},"zertrümmern":{"count":7,"lastSeenTime":1586889393401},"chaotisch":{"count":8,"lastSeenTime":1586908175585},"Schmerz":{"count":5,"lastSeenTime":1586920119062},"Limbo":{"count":4,"lastSeenTime":1586879298099,"difficulty":0.7684210526315789,"difficultyWeight":95},"Baumwolle":{"count":3,"lastSeenTime":1586915099808},"Schneebesen":{"count":5,"lastSeenTime":1586813662034},"Balkon":{"count":4,"lastSeenTime":1586896769426,"difficulty":0.5,"difficultyWeight":8},"Freibad":{"count":7,"lastSeenTime":1586913827190},"kriechen":{"count":7,"lastSeenTime":1586958887354},"Model":{"count":5,"lastSeenTime":1586889489199},"Grillen":{"count":7,"lastSeenTime":1586956048018},"Schreibtisch":{"count":9,"lastSeenTime":1586959290196},"Leder":{"count":4,"lastSeenTime":1586920361074},"Osten":{"count":2,"lastSeenTime":1586634009548},"Rezeption":{"count":6,"lastSeenTime":1586913827190},"Madagaskar":{"count":2,"lastSeenTime":1586914309641},"rutschen":{"count":7,"lastSeenTime":1586919811805,"difficulty":1,"difficultyWeight":12},"Punkt":{"count":3,"lastSeenTime":1586868381050},"Frosch":{"count":4,"lastSeenTime":1586814181157},"Tennisschläger":{"count":3,"lastSeenTime":1586954603173},"Tragfläche":{"count":3,"lastSeenTime":1586889719019},"spielen":{"count":4,"lastSeenTime":1586904147395},"Australien":{"count":3,"lastSeenTime":1586817485337},"Schwan":{"count":4,"lastSeenTime":1586868119871},"Seekuh":{"count":2,"lastSeenTime":1586817081429},"stampfen":{"count":5,"lastSeenTime":1586900361272},"Vegetarier":{"count":2,"lastSeenTime":1586713274267},"Streichholzschachtel":{"count":4,"lastSeenTime":1586913648704,"publicGameCount":1,"difficulty":1,"difficultyWeight":4},"Eimer":{"count":5,"lastSeenTime":1586959633128,"difficulty":0.6,"difficultyWeight":10},"Telefon":{"count":5,"lastSeenTime":1586919434514,"difficulty":0.65,"difficultyWeight":20},"Onkel":{"count":4,"lastSeenTime":1586897484538},"Warnweste":{"count":9,"lastSeenTime":1586916013387,"difficulty":1,"difficultyWeight":6},"Dompteur":{"count":9,"lastSeenTime":1586908931787},"Mittwoch":{"count":9,"lastSeenTime":1586955113604},"pink":{"count":6,"lastSeenTime":1586914080489,"difficulty":0.5,"difficultyWeight":12},"Krake":{"count":4,"lastSeenTime":1586958944806},"goldener Apfel":{"count":7,"lastSeenTime":1586895761615},"Maisfeld":{"count":7,"lastSeenTime":1586903711780},"Holzfäller":{"count":2,"lastSeenTime":1586727362775,"difficulty":0.6571428571428571,"difficultyWeight":35},"Familie":{"count":6,"lastSeenTime":1586920538046},"Paintball":{"count":1,"lastSeenTime":1586608344685},"Kuchen":{"count":4,"lastSeenTime":1586955263523},"Tauchgang":{"count":7,"lastSeenTime":1586904234099},"Filmriss":{"count":5,"lastSeenTime":1586915731157},"Kristall":{"count":4,"lastSeenTime":1586896530203},"Straßensperre":{"count":3,"lastSeenTime":1586859787263},"Jagdziel":{"count":6,"lastSeenTime":1586914258463,"publicGameCount":1},"Zimmermann":{"count":5,"lastSeenTime":1586914792295},"Erkältung":{"count":8,"lastSeenTime":1586959344881},"Blase":{"count":5,"lastSeenTime":1586919413397},"Moos":{"count":4,"lastSeenTime":1586900318835,"difficulty":1,"difficultyWeight":7},"Einsiedler":{"count":4,"lastSeenTime":1586896040899,"publicGameCount":1},"Kanada":{"count":2,"lastSeenTime":1586710340067,"difficulty":0.8333333333333334,"difficultyWeight":6},"Glühwürmchen":{"count":3,"lastSeenTime":1586833885395},"Sonnenschirm":{"count":7,"lastSeenTime":1586914428482},"Brieföffner":{"count":7,"lastSeenTime":1586957925802},"Orgel":{"count":5,"lastSeenTime":1586859816236},"Seifenblase":{"count":4,"lastSeenTime":1586920043786,"difficulty":0.5714285714285714,"difficultyWeight":7},"Notenschlüssel":{"count":5,"lastSeenTime":1586916118321},"Kroatien":{"count":10,"lastSeenTime":1586959728501},"Snowboard":{"count":4,"lastSeenTime":1586954577957},"Zahn":{"count":3,"lastSeenTime":1586890131974,"difficulty":1,"difficultyWeight":31},"Zugbrücke":{"count":5,"lastSeenTime":1586916717644},"Distanz":{"count":4,"lastSeenTime":1586907361110},"Dreieck":{"count":9,"lastSeenTime":1586955681359,"difficulty":0.6,"difficultyWeight":5},"Flaschenöffner":{"count":6,"lastSeenTime":1586874409884},"Roman":{"count":2,"lastSeenTime":1586839953759},"Nase":{"count":6,"lastSeenTime":1586916637868},"Regentropfen":{"count":4,"lastSeenTime":1586958141882,"difficulty":1,"difficultyWeight":10},"Statue":{"count":7,"lastSeenTime":1586920034941},"Studio":{"count":5,"lastSeenTime":1586889446349},"Portrait":{"count":6,"lastSeenTime":1586919399142,"difficulty":1,"difficultyWeight":32},"kabellos":{"count":7,"lastSeenTime":1586920034941,"difficulty":1,"difficultyWeight":6},"Zimmerpflanze":{"count":2,"lastSeenTime":1586919501543},"Prinzessin":{"count":2,"lastSeenTime":1586921008446},"Vollmond":{"count":5,"lastSeenTime":1586908395891,"difficulty":0.9565217391304348,"difficultyWeight":23},"Kupfer":{"count":4,"lastSeenTime":1586816578375},"Biologie":{"count":3,"lastSeenTime":1586954727368},"Papst":{"count":5,"lastSeenTime":1586840892251},"rutschig":{"count":3,"lastSeenTime":1586955113604},"Zyklop":{"count":4,"lastSeenTime":1586881056350,"publicGameCount":1,"difficulty":1,"difficultyWeight":12},"Grotte":{"count":4,"lastSeenTime":1586915236139},"Stachelschwein":{"count":3,"lastSeenTime":1586839250104,"difficulty":0.7142857142857143,"difficultyWeight":7,"publicGameCount":1},"Smaragd":{"count":3,"lastSeenTime":1586812763441},"Kriegsschiff":{"count":5,"lastSeenTime":1586858883401},"Dürre":{"count":6,"lastSeenTime":1586908276050},"Puma":{"count":5,"lastSeenTime":1586896290835},"Symphonie":{"count":4,"lastSeenTime":1586908315438},"ClickBait":{"count":7,"lastSeenTime":1586900856713,"difficulty":0.8181818181818182,"difficultyWeight":11},"Kuppel":{"count":4,"lastSeenTime":1586875034252},"applaudieren":{"count":6,"lastSeenTime":1586915821415},"Flügel":{"count":5,"lastSeenTime":1586907814926,"difficulty":0.5833333333333333,"difficultyWeight":12},"Frieden":{"count":6,"lastSeenTime":1586955224835,"difficulty":0.6896551724137931,"difficultyWeight":29},"Wort":{"count":8,"lastSeenTime":1586920456841},"Teller":{"count":3,"lastSeenTime":1586907682972,"difficulty":0.4,"difficultyWeight":10},"Teppich":{"count":5,"lastSeenTime":1586875186652,"difficulty":1,"difficultyWeight":8},"Schraube":{"count":3,"lastSeenTime":1586873383077},"Tag":{"count":6,"lastSeenTime":1586903370090},"Kopf":{"count":13,"lastSeenTime":1586920143399},"Ferien":{"count":5,"lastSeenTime":1586890156350},"Fischernetz":{"count":2,"lastSeenTime":1586782926490,"difficulty":0.5555555555555556,"difficultyWeight":9},"Wurst":{"count":4,"lastSeenTime":1586904367956,"difficulty":1,"difficultyWeight":3},"Triebwerk":{"count":4,"lastSeenTime":1586827603168},"Robbe":{"count":7,"lastSeenTime":1586921156587},"Wald":{"count":3,"lastSeenTime":1586712987795},"Netz":{"count":8,"lastSeenTime":1586920666083,"difficulty":0.2857142857142857,"difficultyWeight":7},"Fehler":{"count":3,"lastSeenTime":1586868805974},"Kastagnetten":{"count":4,"lastSeenTime":1586903148142},"Aladdin":{"count":2,"lastSeenTime":1586957874303,"difficulty":1,"difficultyWeight":13},"Scharfschütze":{"count":3,"lastSeenTime":1586826372203},"Korken":{"count":8,"lastSeenTime":1586916237094,"difficulty":0.875,"difficultyWeight":8},"Atlantis":{"count":3,"lastSeenTime":1586958572090},"Wüste":{"count":5,"lastSeenTime":1586859799165,"publicGameCount":1,"difficulty":0.8888888888888888,"difficultyWeight":9},"Fernsehturm":{"count":5,"lastSeenTime":1586908382794},"Lautsprecher":{"count":3,"lastSeenTime":1586869993172,"difficulty":0.8,"difficultyWeight":5},"binden":{"count":8,"lastSeenTime":1586919773316,"difficulty":1,"difficultyWeight":2},"Pinguin":{"count":4,"lastSeenTime":1586901166652},"Gier":{"count":6,"lastSeenTime":1586902813258},"sterben":{"count":6,"lastSeenTime":1586915200929},"versagen":{"count":6,"lastSeenTime":1586956384816},"Unterschrift":{"count":3,"lastSeenTime":1586812458521},"Vuvuzela":{"count":5,"lastSeenTime":1586900861532},"Geografie":{"count":6,"lastSeenTime":1586896730722},"Oval":{"count":1,"lastSeenTime":1586618468051},"Marke":{"count":5,"lastSeenTime":1586914554202,"difficulty":0.6666666666666666,"difficultyWeight":15},"Observatorium":{"count":2,"lastSeenTime":1586909094851,"difficulty":1,"difficultyWeight":6},"Lesezeichen":{"count":8,"lastSeenTime":1586959455308,"difficulty":1,"difficultyWeight":7},"Pogo Stick":{"count":6,"lastSeenTime":1586902943577},"Zikade":{"count":5,"lastSeenTime":1586814522290},"Bulldozer":{"count":5,"lastSeenTime":1586955532027},"Gummi":{"count":7,"lastSeenTime":1586954678504},"Zuma":{"count":5,"lastSeenTime":1586908504643},"Saturn":{"count":6,"lastSeenTime":1586956352310,"difficulty":1,"difficultyWeight":7},"Tower Bridge":{"count":7,"lastSeenTime":1586914475739},"Zelt":{"count":8,"lastSeenTime":1586907327679,"difficulty":1,"difficultyWeight":23},"Darts":{"count":3,"lastSeenTime":1586650835510,"difficulty":0.75,"difficultyWeight":12},"Karaoke":{"count":4,"lastSeenTime":1586904384265},"Mitternacht":{"count":5,"lastSeenTime":1586955025294,"difficulty":1,"difficultyWeight":25},"Sechseck":{"count":8,"lastSeenTime":1586914157190},"Afrika":{"count":2,"lastSeenTime":1586895919376,"difficulty":0.8,"difficultyWeight":15,"publicGameCount":1},"Arztkoffer":{"count":5,"lastSeenTime":1586889432199,"difficulty":0.8,"difficultyWeight":5},"Niere":{"count":9,"lastSeenTime":1586958385310},"Windrad":{"count":4,"lastSeenTime":1586869955906},"Baumkuchen":{"count":4,"lastSeenTime":1586900534749,"difficulty":1,"difficultyWeight":5},"Rasenmäher":{"count":6,"lastSeenTime":1586955691477},"Schiefer Turm von Pisa":{"count":6,"lastSeenTime":1586834077836},"Messer":{"count":12,"lastSeenTime":1586958636395},"Rechteck":{"count":6,"lastSeenTime":1586916744663},"behindert":{"count":8,"lastSeenTime":1586901239971,"publicGameCount":1,"difficulty":0.8333333333333334,"difficultyWeight":6},"Hitze":{"count":1,"lastSeenTime":1586619376532,"difficulty":0.6521739130434783,"difficultyWeight":23},"König":{"count":6,"lastSeenTime":1586920604951,"publicGameCount":1,"difficulty":0.42857142857142855,"difficultyWeight":7},"Akkordeon":{"count":6,"lastSeenTime":1586954577957},"Autogramm":{"count":6,"lastSeenTime":1586914716657,"publicGameCount":1},"Dalmatiner":{"count":7,"lastSeenTime":1586955263523},"Fata Morgana":{"count":4,"lastSeenTime":1586958973713},"Meerschweinchen":{"count":10,"lastSeenTime":1586839691166,"publicGameCount":1,"difficulty":0.2857142857142857,"difficultyWeight":7},"Pudel":{"count":6,"lastSeenTime":1586955310334},"Asien":{"count":3,"lastSeenTime":1586816712958,"difficulty":0.625,"difficultyWeight":8},"Haut":{"count":5,"lastSeenTime":1586900573287},"brünett":{"count":4,"lastSeenTime":1586920858569,"difficulty":1,"difficultyWeight":3},"Mohn":{"count":3,"lastSeenTime":1586889591248},"Aufnahme":{"count":1,"lastSeenTime":1586619614046},"Zuckerstange":{"count":6,"lastSeenTime":1586832545576},"Floß":{"count":6,"lastSeenTime":1586814801167},"Gips":{"count":7,"lastSeenTime":1586958719765},"rückgängig":{"count":4,"lastSeenTime":1586915456714,"difficulty":1,"difficultyWeight":9},"Schaltknüppel":{"count":8,"lastSeenTime":1586916288751,"difficulty":0.6,"difficultyWeight":5},"Poseidon":{"count":10,"lastSeenTime":1586956516194,"difficulty":0.75,"difficultyWeight":4},"Helm":{"count":4,"lastSeenTime":1586959106188},"Hütte":{"count":4,"lastSeenTime":1586832859836},"Tintenfisch":{"count":3,"lastSeenTime":1586901572201},"Skittles":{"count":8,"lastSeenTime":1586920722806},"Freddie Faulig":{"count":5,"lastSeenTime":1586921195186},"Bildhauer":{"count":5,"lastSeenTime":1586896885306},"Hund":{"count":8,"lastSeenTime":1586959142159,"difficulty":1,"difficultyWeight":3},"Dachfenster":{"count":4,"lastSeenTime":1586956197682,"difficulty":1,"difficultyWeight":1},"Postkarte":{"count":3,"lastSeenTime":1586896214025,"difficulty":0.8545454545454545,"difficultyWeight":55},"Großmutter":{"count":5,"lastSeenTime":1586903760979,"difficulty":1,"difficultyWeight":7},"Tochter":{"count":4,"lastSeenTime":1586920771641},"Motherboard":{"count":2,"lastSeenTime":1586724278124},"Panther":{"count":2,"lastSeenTime":1586908672662,"difficulty":1,"difficultyWeight":8},"Küstenwache":{"count":4,"lastSeenTime":1586813867768},"Chuck Norris":{"count":5,"lastSeenTime":1586914903455},"Hammer":{"count":6,"lastSeenTime":1586880115013,"publicGameCount":1,"difficulty":0.7272727272727273,"difficultyWeight":11},"Apfelsaft":{"count":7,"lastSeenTime":1586903344033},"Kameramann":{"count":5,"lastSeenTime":1586956302197},"Gebäude":{"count":4,"lastSeenTime":1586816998752,"difficulty":1,"difficultyWeight":8},"Nickel":{"count":4,"lastSeenTime":1586879731749},"Schnuller":{"count":5,"lastSeenTime":1586891340621,"difficulty":0.8928571428571429,"difficultyWeight":28},"wählen":{"count":6,"lastSeenTime":1586916441133},"Pikachu":{"count":5,"lastSeenTime":1586958959180},"wiederholen":{"count":7,"lastSeenTime":1586874577908},"Amerika":{"count":5,"lastSeenTime":1586914615571,"difficulty":1,"difficultyWeight":3},"Zeh":{"count":6,"lastSeenTime":1586840668869,"difficulty":0.5,"difficultyWeight":8},"Skelett":{"count":6,"lastSeenTime":1586907814926},"Box":{"count":6,"lastSeenTime":1586956570180},"Hängebrücke":{"count":7,"lastSeenTime":1586903975283,"difficulty":0.4,"difficultyWeight":10},"Kätzchen":{"count":2,"lastSeenTime":1586891134706},"Bandscheibenvorfall":{"count":9,"lastSeenTime":1586900301076},"Pfeife":{"count":2,"lastSeenTime":1586900162376,"difficulty":0.4,"difficultyWeight":5},"Tauchen":{"count":5,"lastSeenTime":1586815355269},"Maschine":{"count":8,"lastSeenTime":1586915493381,"publicGameCount":1,"difficulty":0.75,"difficultyWeight":4},"Sandalen":{"count":7,"lastSeenTime":1586896912568},"Sichel":{"count":8,"lastSeenTime":1586874931565},"Atombombe":{"count":7,"lastSeenTime":1586955457642},"Wachs":{"count":3,"lastSeenTime":1586958456673},"England":{"count":7,"lastSeenTime":1586957950175},"Temperatur":{"count":5,"lastSeenTime":1586958062580,"difficulty":0.8888888888888888,"difficultyWeight":9},"Gärtner":{"count":6,"lastSeenTime":1586907729754},"Nadelkissen":{"count":5,"lastSeenTime":1586902602080,"difficulty":0.75,"difficultyWeight":4},"Geschlecht":{"count":3,"lastSeenTime":1586806009929},"sitzen":{"count":5,"lastSeenTime":1586915924921},"Spaghettieis":{"count":4,"lastSeenTime":1586920375356},"Viertel":{"count":5,"lastSeenTime":1586901042640},"Nudel":{"count":3,"lastSeenTime":1586805458421,"difficulty":1,"difficultyWeight":8},"Maulwurf":{"count":5,"lastSeenTime":1586914157190,"difficulty":0.6666666666666666,"difficultyWeight":3},"Ferrari":{"count":4,"lastSeenTime":1586955823724,"difficulty":0.95,"difficultyWeight":20},"Cello":{"count":2,"lastSeenTime":1586711665898,"difficulty":0.75,"difficultyWeight":8},"Regisseur":{"count":6,"lastSeenTime":1586954953467},"Schuhkarton":{"count":5,"lastSeenTime":1586909286837},"Passwort":{"count":6,"lastSeenTime":1586958413299,"difficulty":0.7142857142857143,"difficultyWeight":7},"Markt":{"count":5,"lastSeenTime":1586826599494,"difficulty":0.5,"difficultyWeight":10},"Teleskop":{"count":3,"lastSeenTime":1586958485799,"difficulty":0.875,"difficultyWeight":8},"Töne":{"count":2,"lastSeenTime":1586868568396,"difficulty":0.9285714285714286,"difficultyWeight":14},"Schwarzes Loch":{"count":5,"lastSeenTime":1586955025293,"difficulty":1,"difficultyWeight":7},"Rumänien":{"count":5,"lastSeenTime":1586914501681},"Generator":{"count":3,"lastSeenTime":1586880812768,"difficulty":1,"difficultyWeight":9},"Leidenschaft":{"count":5,"lastSeenTime":1586958012186,"difficulty":0.75,"difficultyWeight":4},"Parkuhr":{"count":4,"lastSeenTime":1586958385310},"Universität":{"count":4,"lastSeenTime":1586814778569},"Rentier":{"count":7,"lastSeenTime":1586958525123},"Magie":{"count":4,"lastSeenTime":1586959242580},"Pumba":{"count":5,"lastSeenTime":1586959533143},"Zombie":{"count":6,"lastSeenTime":1586958547642,"publicGameCount":1,"difficulty":0.36363636363636365,"difficultyWeight":11},"Maus":{"count":4,"lastSeenTime":1586920069685},"Darsteller":{"count":8,"lastSeenTime":1586959492934,"difficulty":0.7857142857142857,"difficultyWeight":14},"Norden":{"count":3,"lastSeenTime":1586817033855,"publicGameCount":1},"Rasiermesser":{"count":4,"lastSeenTime":1586913973573},"Liane":{"count":5,"lastSeenTime":1586955457642,"difficulty":0.8,"difficultyWeight":5},"Ruhe":{"count":3,"lastSeenTime":1586813181137},"Kanone":{"count":3,"lastSeenTime":1586859826495},"Konversation":{"count":4,"lastSeenTime":1586826301547},"Windows":{"count":4,"lastSeenTime":1586955209647,"difficulty":0.9852941176470589,"difficultyWeight":68},"Villa":{"count":3,"lastSeenTime":1586919374724},"Papiertüte":{"count":6,"lastSeenTime":1586959304612},"rechts":{"count":5,"lastSeenTime":1586959608297},"Tornado":{"count":4,"lastSeenTime":1586874513513,"difficulty":0.9354838709677419,"difficultyWeight":31},"Kondenswasser":{"count":6,"lastSeenTime":1586890429362},"Sprühfarbe":{"count":4,"lastSeenTime":1586813950788,"difficulty":1,"difficultyWeight":10},"Ziel":{"count":3,"lastSeenTime":1586826637533,"difficulty":1,"difficultyWeight":10},"Sombrero":{"count":7,"lastSeenTime":1586958062580,"publicGameCount":1},"Bushaltestelle":{"count":3,"lastSeenTime":1586783233936},"Purzelbaum":{"count":3,"lastSeenTime":1586915757073,"difficulty":0.8571428571428571,"difficultyWeight":7},"Haare":{"count":1,"lastSeenTime":1586634491034,"difficulty":1,"difficultyWeight":10},"Zypresse":{"count":7,"lastSeenTime":1586958809891},"Amsterdam":{"count":4,"lastSeenTime":1586920627218},"Makkaroni":{"count":6,"lastSeenTime":1586959830012},"taub":{"count":4,"lastSeenTime":1586880907839},"Bill Gates":{"count":4,"lastSeenTime":1586915129381},"provozieren":{"count":5,"lastSeenTime":1586896840770},"Raumanzug":{"count":8,"lastSeenTime":1586956019428,"difficulty":1,"difficultyWeight":82},"Punker":{"count":4,"lastSeenTime":1586959255115},"Thor":{"count":4,"lastSeenTime":1586880911950},"Globus":{"count":5,"lastSeenTime":1586889772751},"Tischplatte":{"count":3,"lastSeenTime":1586889906994},"hypnotisieren":{"count":4,"lastSeenTime":1586959401878},"Schnabeltier":{"count":7,"lastSeenTime":1586908611825},"Kreuzotter":{"count":5,"lastSeenTime":1586920957237,"publicGameCount":1,"difficulty":0.45454545454545453,"difficultyWeight":11},"Sauna":{"count":9,"lastSeenTime":1586956363582},"Planke":{"count":5,"lastSeenTime":1586903323590},"bezaubernd":{"count":5,"lastSeenTime":1586889746364},"Nonne":{"count":4,"lastSeenTime":1586955958335},"Bücherei":{"count":5,"lastSeenTime":1586903231734},"Kakerlake":{"count":3,"lastSeenTime":1586827501149,"difficulty":1,"difficultyWeight":13},"Traubensaft":{"count":5,"lastSeenTime":1586881168379},"Wohnung":{"count":6,"lastSeenTime":1586839175430},"Fussel":{"count":10,"lastSeenTime":1586908054437},"Perücke":{"count":6,"lastSeenTime":1586955334605},"Querflöte":{"count":5,"lastSeenTime":1586921170820},"Vogelspinne":{"count":7,"lastSeenTime":1586908090329},"Kinn":{"count":5,"lastSeenTime":1586916063451,"difficulty":0.8666666666666667,"difficultyWeight":15},"Spinat":{"count":6,"lastSeenTime":1586959255115},"Glocke":{"count":7,"lastSeenTime":1586903888016},"Bäckerei":{"count":5,"lastSeenTime":1586921231641,"difficulty":1,"difficultyWeight":10},"Seehund":{"count":5,"lastSeenTime":1586959547988},"Konfetti":{"count":4,"lastSeenTime":1586919927137,"difficulty":1,"difficultyWeight":3},"Pfote":{"count":4,"lastSeenTime":1586869599214},"Nordkorea":{"count":5,"lastSeenTime":1586858711737},"Schlittschuh":{"count":5,"lastSeenTime":1586874687834},"Wolverine":{"count":6,"lastSeenTime":1586959429213},"Drucker":{"count":2,"lastSeenTime":1586713676145},"Elektriker":{"count":6,"lastSeenTime":1586959533143,"difficulty":1,"difficultyWeight":5},"Hausmeister":{"count":5,"lastSeenTime":1586958873120},"Schneeball":{"count":9,"lastSeenTime":1586920005337},"Zebra":{"count":4,"lastSeenTime":1586879903131,"difficulty":0.25,"difficultyWeight":8},"Ladebalken":{"count":6,"lastSeenTime":1586959218404,"difficulty":0.875,"difficultyWeight":8},"Blutegel":{"count":10,"lastSeenTime":1586920265574},"Feuerwehrauto":{"count":7,"lastSeenTime":1586873974505,"difficulty":0.8974358974358975,"difficultyWeight":39},"Architekt":{"count":2,"lastSeenTime":1586879685669,"difficulty":1,"difficultyWeight":4},"Kabine":{"count":4,"lastSeenTime":1586959850831},"Waffe":{"count":3,"lastSeenTime":1586895782227},"Heizungskessel":{"count":5,"lastSeenTime":1586913998392},"Recycling":{"count":1,"lastSeenTime":1586652085658},"Narwal":{"count":9,"lastSeenTime":1586920043786},"Würfel":{"count":5,"lastSeenTime":1586913696698},"tropisch":{"count":4,"lastSeenTime":1586908931787},"Bügeleisen":{"count":3,"lastSeenTime":1586955984837,"difficulty":1,"difficultyWeight":4},"Militär":{"count":2,"lastSeenTime":1586833977662},"Motor":{"count":5,"lastSeenTime":1586916288751},"Diagramm":{"count":4,"lastSeenTime":1586873676367},"Katamaran":{"count":5,"lastSeenTime":1586880408576},"Windschutzscheibe":{"count":3,"lastSeenTime":1586900587471},"Bob":{"count":6,"lastSeenTime":1586959279701,"publicGameCount":1,"difficulty":0.4166666666666667,"difficultyWeight":12},"Scheibenwelt":{"count":5,"lastSeenTime":1586908191616},"Höhle":{"count":7,"lastSeenTime":1586956253026,"difficulty":0.9090909090909091,"difficultyWeight":11},"Werwolf":{"count":5,"lastSeenTime":1586916430600,"difficulty":1,"difficultyWeight":14},"Grapefruit":{"count":3,"lastSeenTime":1586833416769},"Waschmaschine":{"count":7,"lastSeenTime":1586909094851},"salto schlagen":{"count":9,"lastSeenTime":1586958496125},"Totenkopf":{"count":4,"lastSeenTime":1586900436732,"difficulty":0.7391304347826086,"difficultyWeight":23},"Gandalf":{"count":6,"lastSeenTime":1586916690790},"Spaten":{"count":5,"lastSeenTime":1586915788288,"difficulty":0.7777777777777778,"difficultyWeight":9},"Schlagzeug":{"count":5,"lastSeenTime":1586920771641},"Person":{"count":7,"lastSeenTime":1586954914968,"difficulty":0.7586206896551724,"difficultyWeight":29},"Büro":{"count":5,"lastSeenTime":1586838842778},"Ameise":{"count":4,"lastSeenTime":1586959314784,"difficulty":0.7,"difficultyWeight":10},"Nilpferd":{"count":8,"lastSeenTime":1586958821795,"difficulty":0.9565217391304348,"difficultyWeight":46},"Krabbe":{"count":5,"lastSeenTime":1586954798444},"Granatapfel":{"count":8,"lastSeenTime":1586919460885},"Tumor":{"count":7,"lastSeenTime":1586908480352},"Pi":{"count":6,"lastSeenTime":1586915129381},"Pferd":{"count":2,"lastSeenTime":1586858562011},"Textmarker":{"count":2,"lastSeenTime":1586709415728,"difficulty":1,"difficultyWeight":12},"Student":{"count":4,"lastSeenTime":1586955542167},"schwanger":{"count":5,"lastSeenTime":1586955701781,"difficulty":1,"difficultyWeight":6},"Gymnastik":{"count":6,"lastSeenTime":1586955195086,"difficulty":0.7142857142857143,"difficultyWeight":7},"Fackel":{"count":4,"lastSeenTime":1586859593426},"Essstäbchen":{"count":4,"lastSeenTime":1586897115648,"difficulty":1,"difficultyWeight":3},"Wellensittich":{"count":7,"lastSeenTime":1586956070276},"Wildnis":{"count":3,"lastSeenTime":1586889432199},"Strumpfhose":{"count":5,"lastSeenTime":1586958934411,"difficulty":0.75,"difficultyWeight":12},"Laktoseintoleranz":{"count":4,"lastSeenTime":1586879349367},"Knallfrosch":{"count":3,"lastSeenTime":1586713746274},"suchen":{"count":4,"lastSeenTime":1586957960523},"Eichel":{"count":8,"lastSeenTime":1586903939910,"difficulty":0.9166666666666666,"difficultyWeight":48},"Hose":{"count":8,"lastSeenTime":1586959178759,"difficulty":0.45,"difficultyWeight":40},"Brokkoli":{"count":4,"lastSeenTime":1586955063993},"Blitz":{"count":8,"lastSeenTime":1586959522880,"difficulty":1,"difficultyWeight":5},"Excalibur":{"count":3,"lastSeenTime":1586908207834,"difficulty":0.75,"difficultyWeight":8},"Creeper":{"count":6,"lastSeenTime":1586833067061,"difficulty":0.7272727272727273,"difficultyWeight":11},"Röstaroma":{"count":7,"lastSeenTime":1586958335993},"Sahne":{"count":7,"lastSeenTime":1586959557107},"abstrakt":{"count":7,"lastSeenTime":1586915788288},"Bagger":{"count":8,"lastSeenTime":1586916579758},"Dorf":{"count":5,"lastSeenTime":1586955419506,"difficulty":0.92,"difficultyWeight":25},"Mineralwasser":{"count":6,"lastSeenTime":1586901647547,"difficulty":0.9166666666666666,"difficultyWeight":12},"Regenwald":{"count":3,"lastSeenTime":1586860432423},"Frühlingsrolle":{"count":5,"lastSeenTime":1586903034208},"Abonnement":{"count":5,"lastSeenTime":1586900318835,"difficulty":0.375,"difficultyWeight":8},"Stubenhocker":{"count":6,"lastSeenTime":1586895895138},"berühren":{"count":4,"lastSeenTime":1586958360375},"Schraubenschlüssel":{"count":1,"lastSeenTime":1586707602434},"Kurzschluss":{"count":4,"lastSeenTime":1586900212280},"Jacke":{"count":5,"lastSeenTime":1586955098414},"Samen":{"count":3,"lastSeenTime":1586868411733},"Narr":{"count":2,"lastSeenTime":1586895651423},"Kronkorken":{"count":3,"lastSeenTime":1586869743912},"Blüte":{"count":4,"lastSeenTime":1586827737429},"Ladegerät":{"count":5,"lastSeenTime":1586914932818},"weinen":{"count":6,"lastSeenTime":1586956070276,"difficulty":1,"difficultyWeight":3},"Sau":{"count":7,"lastSeenTime":1586920143399},"obdachlos":{"count":5,"lastSeenTime":1586879940075},"Einbahnstraße":{"count":3,"lastSeenTime":1586956384816},"Stangenbrot":{"count":1,"lastSeenTime":1586708591047},"Odysseus":{"count":4,"lastSeenTime":1586959492934},"London Eye":{"count":4,"lastSeenTime":1586955620355,"difficulty":0.75,"difficultyWeight":4},"Hundehütte":{"count":4,"lastSeenTime":1586913545993},"Eisberg":{"count":5,"lastSeenTime":1586915639271,"difficulty":0.7272727272727273,"difficultyWeight":11},"Evolution":{"count":4,"lastSeenTime":1586815367180,"difficulty":0.7857142857142857,"difficultyWeight":14},"Beziehung":{"count":9,"lastSeenTime":1586900559143},"Koffer":{"count":5,"lastSeenTime":1586954698858,"difficulty":0.8,"difficultyWeight":30},"Meerenge":{"count":8,"lastSeenTime":1586908583500,"difficulty":1,"difficultyWeight":8},"Posaune":{"count":4,"lastSeenTime":1586806917088},"Sturm":{"count":2,"lastSeenTime":1586920133284},"Lächeln":{"count":1,"lastSeenTime":1586708983645},"Star Wars":{"count":4,"lastSeenTime":1586919917033,"difficulty":0.42857142857142855,"difficultyWeight":7},"Halskette":{"count":5,"lastSeenTime":1586916655791},"Spore":{"count":4,"lastSeenTime":1586890203054,"difficulty":1,"difficultyWeight":7},"Ass":{"count":6,"lastSeenTime":1586916655791},"Böller":{"count":3,"lastSeenTime":1586919511658,"difficulty":1,"difficultyWeight":6},"Flohmarkt":{"count":5,"lastSeenTime":1586957837428},"Einkaufszentrum":{"count":4,"lastSeenTime":1586909133282,"difficulty":1,"difficultyWeight":7},"Locher":{"count":3,"lastSeenTime":1586889772751},"Fliege":{"count":4,"lastSeenTime":1586827275317,"difficulty":0.75,"difficultyWeight":8},"Kastanie":{"count":5,"lastSeenTime":1586921057562},"Kernkraftwerk":{"count":5,"lastSeenTime":1586915354278},"Wäschespinne":{"count":4,"lastSeenTime":1586907778315},"Strohhalm":{"count":6,"lastSeenTime":1586901264460},"Räuber":{"count":5,"lastSeenTime":1586958596468},"Mönch":{"count":5,"lastSeenTime":1586868078333},"Deutschland":{"count":7,"lastSeenTime":1586921231641,"difficulty":0.75,"difficultyWeight":8},"Schleuder":{"count":3,"lastSeenTime":1586903624140,"difficulty":0.5625,"difficultyWeight":32},"Terminator":{"count":5,"lastSeenTime":1586959090713},"Beatbox":{"count":4,"lastSeenTime":1586956273734,"difficulty":0.8333333333333334,"difficultyWeight":12},"Miss Piggy":{"count":6,"lastSeenTime":1586920153587},"Facebook":{"count":6,"lastSeenTime":1586816946669},"Schreibschrift":{"count":3,"lastSeenTime":1586920326688,"publicGameCount":1,"difficulty":0.8571428571428571,"difficultyWeight":7},"Katalog":{"count":3,"lastSeenTime":1586921008446},"Gasmaske":{"count":4,"lastSeenTime":1586901500696},"Arbeiter":{"count":2,"lastSeenTime":1586913698511},"Mädchen":{"count":7,"lastSeenTime":1586958510664},"Restaurant":{"count":3,"lastSeenTime":1586954953467},"Achsel":{"count":7,"lastSeenTime":1586955923939,"difficulty":0.5,"difficultyWeight":6},"Burrito":{"count":6,"lastSeenTime":1586908686991,"difficulty":0.9411764705882353,"difficultyWeight":34},"Lederhose":{"count":2,"lastSeenTime":1586891124151},"UFO":{"count":2,"lastSeenTime":1586867998752,"difficulty":0.5,"difficultyWeight":14},"See":{"count":9,"lastSeenTime":1586955310334,"difficulty":1,"difficultyWeight":13},"Vogelbeere":{"count":5,"lastSeenTime":1586903221605},"Gipfelkreuz":{"count":6,"lastSeenTime":1586954989864},"Hai":{"count":6,"lastSeenTime":1586954808666},"grinsen":{"count":6,"lastSeenTime":1586916288751,"difficulty":0.3333333333333333,"difficultyWeight":6},"Youtube":{"count":5,"lastSeenTime":1586954641977},"Aufzug":{"count":4,"lastSeenTime":1586921156587},"Internet":{"count":3,"lastSeenTime":1586869993172},"Apfelkern":{"count":2,"lastSeenTime":1586727732259},"Leiterbahn":{"count":2,"lastSeenTime":1586956504597,"difficulty":1,"difficultyWeight":6},"Stephen Hawking":{"count":3,"lastSeenTime":1586907532918},"Topf":{"count":7,"lastSeenTime":1586902587809},"Degen":{"count":5,"lastSeenTime":1586897394573},"Zahnbürste":{"count":12,"lastSeenTime":1586914806527,"difficulty":0.8518518518518519,"difficultyWeight":27},"knien":{"count":3,"lastSeenTime":1586955195086},"Geschäft":{"count":5,"lastSeenTime":1586959804291,"difficulty":0.8571428571428571,"difficultyWeight":7},"Marge Simpson":{"count":8,"lastSeenTime":1586956516194,"difficulty":0.5,"difficultyWeight":6},"Stoppschild":{"count":6,"lastSeenTime":1586901606974},"CO2":{"count":3,"lastSeenTime":1586957989157,"difficulty":1,"difficultyWeight":3},"Schlacht":{"count":5,"lastSeenTime":1586957863554},"Wurzel":{"count":2,"lastSeenTime":1586903877862},"Jazz":{"count":3,"lastSeenTime":1586901284755},"Margarine":{"count":4,"lastSeenTime":1586813965844},"asymmetrisch":{"count":4,"lastSeenTime":1586891113896},"Natur":{"count":3,"lastSeenTime":1586839235965,"difficulty":1,"difficultyWeight":7},"Kamin":{"count":3,"lastSeenTime":1586903750797},"Vulkan":{"count":3,"lastSeenTime":1586815464569,"difficulty":0.75,"difficultyWeight":52},"read":{"count":1,"lastSeenTime":1586711191040,"difficulty":0.9333333333333333,"difficultyWeight":15},"verschwinden":{"count":8,"lastSeenTime":1586904051087},"skull":{"count":1,"lastSeenTime":1586711214119,"difficulty":0.8666666666666667,"difficultyWeight":15},"Vermieter":{"count":3,"lastSeenTime":1586838964600},"tennis":{"count":1,"lastSeenTime":1586711276270,"difficulty":0.6470588235294117,"difficultyWeight":17},"axe":{"count":1,"lastSeenTime":1586711304408,"difficulty":0.8823529411764706,"difficultyWeight":17},"book":{"count":1,"lastSeenTime":1586711308520},"glass":{"count":1,"lastSeenTime":1586711308520},"Sprungturm":{"count":6,"lastSeenTime":1586955074091},"Professor":{"count":5,"lastSeenTime":1586880438207},"Spion":{"count":2,"lastSeenTime":1586859922496},"Säure":{"count":5,"lastSeenTime":1586916717644},"Sonntag":{"count":2,"lastSeenTime":1586915048330},"Kendama":{"count":6,"lastSeenTime":1586921057562},"Montag":{"count":6,"lastSeenTime":1586954688633},"Brusthaare":{"count":7,"lastSeenTime":1586879731749},"Brause":{"count":6,"lastSeenTime":1586916600438},"verletzt":{"count":7,"lastSeenTime":1586919511658,"difficulty":1,"difficultyWeight":17},"Specht":{"count":5,"lastSeenTime":1586827905301},"Nuss":{"count":2,"lastSeenTime":1586840446597,"difficulty":1,"difficultyWeight":7},"Skype":{"count":4,"lastSeenTime":1586958611285},"Rasensprenger":{"count":6,"lastSeenTime":1586914526456,"difficulty":0.875,"difficultyWeight":8},"Indianer":{"count":2,"lastSeenTime":1586718330257},"Geschenk":{"count":6,"lastSeenTime":1586903400691,"difficulty":0.8181818181818182,"difficultyWeight":11},"Einstein":{"count":1,"lastSeenTime":1586712023064,"difficulty":1,"difficultyWeight":5},"Kennzeichen":{"count":3,"lastSeenTime":1586955644812,"difficulty":1,"difficultyWeight":13},"Baby":{"count":4,"lastSeenTime":1586920843703},"Pasta":{"count":2,"lastSeenTime":1586839545523},"Pistazie":{"count":4,"lastSeenTime":1586915741689},"niesen":{"count":5,"lastSeenTime":1586903059681,"difficulty":0.9807692307692307,"difficultyWeight":52},"Nadel":{"count":3,"lastSeenTime":1586921022722},"Biotonne":{"count":2,"lastSeenTime":1586896127512},"Pinzette":{"count":4,"lastSeenTime":1586869906740},"Notizbuch":{"count":3,"lastSeenTime":1586833628220},"krank":{"count":6,"lastSeenTime":1586908611825},"Klavier":{"count":4,"lastSeenTime":1586908707244},"Salat":{"count":3,"lastSeenTime":1586813485208},"Geologe":{"count":6,"lastSeenTime":1586919640209,"difficulty":1,"difficultyWeight":6},"Trampolin":{"count":2,"lastSeenTime":1586813624926,"difficulty":0.8,"difficultyWeight":5},"Iron Giant":{"count":5,"lastSeenTime":1586890368170},"sinken":{"count":4,"lastSeenTime":1586908079268,"difficulty":0.625,"difficultyWeight":8},"Schaufel":{"count":3,"lastSeenTime":1586958062580},"Soße":{"count":5,"lastSeenTime":1586869017466},"Stöpsel":{"count":3,"lastSeenTime":1586827250323},"Operation":{"count":2,"lastSeenTime":1586958755749},"Litfaßsäule":{"count":5,"lastSeenTime":1586812468912},"Soldat":{"count":6,"lastSeenTime":1586903634298,"difficulty":0.7272727272727273,"difficultyWeight":11},"Karneval":{"count":7,"lastSeenTime":1586908518895},"Küche":{"count":7,"lastSeenTime":1586916063451,"difficulty":1,"difficultyWeight":9},"Olive":{"count":2,"lastSeenTime":1586900473463,"difficulty":1,"difficultyWeight":14},"Regenschirm":{"count":2,"lastSeenTime":1586901225801,"difficulty":0.631578947368421,"difficultyWeight":19},"Rückgrat":{"count":5,"lastSeenTime":1586897383053},"Eisverkäufer":{"count":2,"lastSeenTime":1586900763534,"difficulty":0.6818181818181818,"difficultyWeight":22},"Sicherheitsnadel":{"count":1,"lastSeenTime":1586713732056},"Merkur":{"count":6,"lastSeenTime":1586954641977},"Buntstift":{"count":8,"lastSeenTime":1586958200965,"difficulty":1,"difficultyWeight":9},"Achteck":{"count":5,"lastSeenTime":1586900212280,"publicGameCount":1,"difficulty":0.5833333333333333,"difficultyWeight":12},"Gurke":{"count":9,"lastSeenTime":1586955037756},"Zitrone":{"count":3,"lastSeenTime":1586826941060},"Nacken":{"count":3,"lastSeenTime":1586913816802,"difficulty":0.7,"difficultyWeight":10},"Film":{"count":6,"lastSeenTime":1586959622590},"Kind":{"count":6,"lastSeenTime":1586920771641},"weiß":{"count":5,"lastSeenTime":1586907500591,"difficulty":0.5,"difficultyWeight":6},"Totem":{"count":4,"lastSeenTime":1586913962978,"difficulty":0.3333333333333333,"difficultyWeight":3},"trainieren":{"count":10,"lastSeenTime":1586958200965},"Sturz":{"count":4,"lastSeenTime":1586919522211},"Cheerleader":{"count":5,"lastSeenTime":1586916277356},"Adidas":{"count":4,"lastSeenTime":1586869335019,"publicGameCount":1},"Fritten":{"count":3,"lastSeenTime":1586955344691},"kiffen":{"count":7,"lastSeenTime":1586896912568},"Schweden":{"count":3,"lastSeenTime":1586921059401},"Gelee":{"count":6,"lastSeenTime":1586915478982},"Gentleman":{"count":2,"lastSeenTime":1586869144958},"Kobra":{"count":6,"lastSeenTime":1586913497512,"difficulty":0.5517241379310345,"difficultyWeight":29},"BMW":{"count":3,"lastSeenTime":1586908017512,"difficulty":1,"difficultyWeight":14},"Feld":{"count":6,"lastSeenTime":1586955569169},"Athlet":{"count":3,"lastSeenTime":1586859853848},"Würfelqualle":{"count":4,"lastSeenTime":1586901839909},"Gekritzel":{"count":5,"lastSeenTime":1586920954248},"Birne":{"count":7,"lastSeenTime":1586908763208},"Wespe":{"count":4,"lastSeenTime":1586908432802,"difficulty":0.75,"difficultyWeight":24},"Karussell":{"count":5,"lastSeenTime":1586909155516},"Schwein":{"count":4,"lastSeenTime":1586921043126},"Hochzeit":{"count":5,"lastSeenTime":1586958299322},"Äffchen":{"count":2,"lastSeenTime":1586827841092},"Inlineskates":{"count":4,"lastSeenTime":1586919487290,"difficulty":0.9,"difficultyWeight":10},"Wetterfrosch":{"count":4,"lastSeenTime":1586904262976},"Taxifahrer":{"count":8,"lastSeenTime":1586955999033},"Einschränkung":{"count":5,"lastSeenTime":1586959522880},"verwirrt":{"count":2,"lastSeenTime":1586900387786},"flüssig":{"count":2,"lastSeenTime":1586875135071},"Schauspieler":{"count":6,"lastSeenTime":1586900278764},"U-Boot":{"count":3,"lastSeenTime":1586834009704},"Mandel":{"count":1,"lastSeenTime":1586723339566},"Dynamit":{"count":6,"lastSeenTime":1586908165354},"Weihnachtsmann":{"count":7,"lastSeenTime":1586915609902,"difficulty":0.25,"difficultyWeight":8},"Mantel":{"count":6,"lastSeenTime":1586919610641,"difficulty":0.125,"difficultyWeight":8},"Zahnstein":{"count":3,"lastSeenTime":1586899955403},"tauchen":{"count":3,"lastSeenTime":1586915089601},"Westen":{"count":7,"lastSeenTime":1586954939261,"difficulty":0.55,"difficultyWeight":20},"Zwischendecke":{"count":6,"lastSeenTime":1586959429213},"Pepsi":{"count":3,"lastSeenTime":1586908646355},"Busfahrer":{"count":4,"lastSeenTime":1586858858134},"Ringelschwanz":{"count":3,"lastSeenTime":1586896203705},"aufwerten":{"count":5,"lastSeenTime":1586956130879},"Efeu":{"count":7,"lastSeenTime":1586921256075},"Knoblauch":{"count":3,"lastSeenTime":1586916717644},"Meteorologe":{"count":5,"lastSeenTime":1586818368744,"difficulty":1,"difficultyWeight":6},"Nachtisch":{"count":5,"lastSeenTime":1586958037635},"Warze":{"count":3,"lastSeenTime":1586904186629,"difficulty":1,"difficultyWeight":7},"Pu der Bär":{"count":2,"lastSeenTime":1586726449700},"Bauarbeiter":{"count":7,"lastSeenTime":1586956384816},"Programmierer":{"count":4,"lastSeenTime":1586915985961},"Angebot":{"count":5,"lastSeenTime":1586903048902},"Stau":{"count":4,"lastSeenTime":1586916579758},"Antivirus":{"count":2,"lastSeenTime":1586805694894},"Anzeige":{"count":8,"lastSeenTime":1586916141879},"Museum":{"count":2,"lastSeenTime":1586914491372,"difficulty":0.8809523809523809,"difficultyWeight":42},"Anakonda":{"count":6,"lastSeenTime":1586954763962},"Suezkanal":{"count":4,"lastSeenTime":1586868821062},"Terrarium":{"count":3,"lastSeenTime":1586840867744},"Äquator":{"count":3,"lastSeenTime":1586919413397},"Zecke":{"count":3,"lastSeenTime":1586889746630},"Haarspray":{"count":4,"lastSeenTime":1586916252219},"Golf":{"count":2,"lastSeenTime":1586959232575},"Island":{"count":4,"lastSeenTime":1586956215415},"Simon and Garfunkel":{"count":3,"lastSeenTime":1586832474075},"Zebrastreifen":{"count":4,"lastSeenTime":1586880491865},"spülen":{"count":4,"lastSeenTime":1586955249129,"difficulty":0.625,"difficultyWeight":8},"Mundharmonika":{"count":6,"lastSeenTime":1586909211843},"fliegen":{"count":3,"lastSeenTime":1586921283836,"difficulty":0.8571428571428571,"difficultyWeight":14},"begrüßen":{"count":4,"lastSeenTime":1586920029620,"difficulty":1,"difficultyWeight":6},"Vanille":{"count":3,"lastSeenTime":1586812607253},"Emu":{"count":3,"lastSeenTime":1586873739947},"Gangster":{"count":4,"lastSeenTime":1586815888370},"Krümelmonster":{"count":5,"lastSeenTime":1586868628439,"difficulty":0.8666666666666667,"difficultyWeight":15},"Skilift":{"count":5,"lastSeenTime":1586913545993},"Verlierer":{"count":5,"lastSeenTime":1586869966082},"Gumball":{"count":4,"lastSeenTime":1586958668588},"Uhr":{"count":4,"lastSeenTime":1586958907689,"difficulty":0.33333333333333337,"difficultyWeight":9},"Kebab":{"count":6,"lastSeenTime":1586919750850,"difficulty":1,"difficultyWeight":4},"Tiger":{"count":4,"lastSeenTime":1586907863533},"Journalist":{"count":4,"lastSeenTime":1586896644364},"Finn":{"count":2,"lastSeenTime":1586914991061},"Salami":{"count":6,"lastSeenTime":1586907900355},"Pendel":{"count":6,"lastSeenTime":1586957974879},"Wettervorhersage":{"count":6,"lastSeenTime":1586919664805},"Stempel":{"count":3,"lastSeenTime":1586879283630},"Bettdecke":{"count":6,"lastSeenTime":1586916168548,"difficulty":0.8461538461538461,"difficultyWeight":13},"Halskrause":{"count":5,"lastSeenTime":1586904384265},"Albatros":{"count":4,"lastSeenTime":1586956552197},"Bücherwurm":{"count":1,"lastSeenTime":1586727461944},"Mikroskop":{"count":5,"lastSeenTime":1586958012186},"Läufer":{"count":6,"lastSeenTime":1586959767498},"Creme":{"count":6,"lastSeenTime":1586901152323},"Libelle":{"count":4,"lastSeenTime":1586839691166,"difficulty":1,"difficultyWeight":8},"Segelboot":{"count":3,"lastSeenTime":1586840135568,"difficulty":1,"difficultyWeight":39},"Hängebauchschwein":{"count":4,"lastSeenTime":1586908395891},"Radiergummi":{"count":5,"lastSeenTime":1586916252219},"Bumerang":{"count":3,"lastSeenTime":1586873278128},"schwindelig":{"count":6,"lastSeenTime":1586920108914},"Ohrwurm":{"count":2,"lastSeenTime":1586814854011},"Schwamm":{"count":4,"lastSeenTime":1586920926700},"flüstern":{"count":3,"lastSeenTime":1586903447898},"Modedesigner":{"count":5,"lastSeenTime":1586958239433},"Hip Hop":{"count":2,"lastSeenTime":1586813888653,"difficulty":0.8,"difficultyWeight":10},"Cocktail":{"count":5,"lastSeenTime":1586915139518},"sperren":{"count":3,"lastSeenTime":1586839270292},"Mount Everest":{"count":4,"lastSeenTime":1586957925802},"Puppenhaus":{"count":3,"lastSeenTime":1586879335186},"Jetski":{"count":3,"lastSeenTime":1586904223932},"Holzscheit":{"count":6,"lastSeenTime":1586890178799},"Zahnspange":{"count":3,"lastSeenTime":1586915974465,"difficulty":1,"difficultyWeight":5},"Florida":{"count":3,"lastSeenTime":1586896941227,"difficulty":0.8,"difficultyWeight":5},"Lorbeeren":{"count":3,"lastSeenTime":1586890464755},"Zirkusdirektor":{"count":3,"lastSeenTime":1586817544108,"difficulty":0.5555555555555556,"difficultyWeight":9},"Steuergerät":{"count":2,"lastSeenTime":1586784694118},"Shrek":{"count":6,"lastSeenTime":1586916342434},"copy":{"count":1,"lastSeenTime":1586783576683,"difficulty":0.5,"difficultyWeight":8},"blood":{"count":1,"lastSeenTime":1586783594582,"difficulty":0.6,"difficultyWeight":5},"Farn":{"count":5,"lastSeenTime":1586919722216},"eclipse":{"count":1,"lastSeenTime":1586783732447,"difficulty":0.9411764705882353,"difficultyWeight":34},"palm tree":{"count":1,"lastSeenTime":1586783812435,"difficulty":0.5,"difficultyWeight":12},"AC/DC":{"count":5,"lastSeenTime":1586958154127},"Schlafanzug":{"count":2,"lastSeenTime":1586813334338},"Teig":{"count":8,"lastSeenTime":1586919287618},"Kegel":{"count":3,"lastSeenTime":1586954910317},"Hamburger":{"count":4,"lastSeenTime":1586914590565,"difficulty":0.8928571428571429,"difficultyWeight":28},"Stecknadel":{"count":6,"lastSeenTime":1586907609327},"Invasion":{"count":3,"lastSeenTime":1586873772670},"klebrig":{"count":3,"lastSeenTime":1586895452509},"Flamingo":{"count":4,"lastSeenTime":1586908104595,"difficulty":0.5714285714285714,"difficultyWeight":7},"Orange":{"count":4,"lastSeenTime":1586890743822,"difficulty":0.9,"difficultyWeight":40},"Ball":{"count":2,"lastSeenTime":1586840879616},"Becken":{"count":5,"lastSeenTime":1586958547642,"difficulty":1,"difficultyWeight":8},"Verpackung":{"count":3,"lastSeenTime":1586815146910},"Bogenschütze":{"count":3,"lastSeenTime":1586920143399},"versöhnen":{"count":6,"lastSeenTime":1586959830012},"Rampe":{"count":3,"lastSeenTime":1586903111992},"Bronze":{"count":5,"lastSeenTime":1586959585641},"Wohlstand":{"count":4,"lastSeenTime":1586914991061},"Dessert":{"count":3,"lastSeenTime":1586903011803},"Bowling":{"count":4,"lastSeenTime":1586914615571},"Animation":{"count":4,"lastSeenTime":1586840045031},"Fitness Trainer":{"count":6,"lastSeenTime":1586956462502},"Hydrant":{"count":4,"lastSeenTime":1586959342619,"difficulty":1,"difficultyWeight":1},"Alligator":{"count":6,"lastSeenTime":1586919958324},"Atom":{"count":5,"lastSeenTime":1586959076238},"farbenblind":{"count":2,"lastSeenTime":1586814501266},"erfrieren":{"count":1,"lastSeenTime":1586805684110},"Tails":{"count":1,"lastSeenTime":1586805694893},"Staudamm":{"count":2,"lastSeenTime":1586901547884},"Pfütze":{"count":3,"lastSeenTime":1586895782227},"Engel":{"count":2,"lastSeenTime":1586956582710},"Wunderlampe":{"count":4,"lastSeenTime":1586869345288,"difficulty":1,"difficultyWeight":7},"Fechten":{"count":4,"lastSeenTime":1586954989864},"Gas":{"count":5,"lastSeenTime":1586920226877},"Kunde":{"count":4,"lastSeenTime":1586955456078},"Zelda":{"count":2,"lastSeenTime":1586880631457},"Atomuhr":{"count":3,"lastSeenTime":1586873715364},"Realität":{"count":4,"lastSeenTime":1586839250104},"Feuerwache":{"count":5,"lastSeenTime":1586959304612},"Schnee":{"count":5,"lastSeenTime":1586958769937,"difficulty":0.7777777777777778,"difficultyWeight":9},"Altweibersommer":{"count":3,"lastSeenTime":1586859631642},"Asterix":{"count":4,"lastSeenTime":1586959557107},"Bingo":{"count":7,"lastSeenTime":1586954925078},"Rosine":{"count":5,"lastSeenTime":1586919750850},"Koala":{"count":5,"lastSeenTime":1586958350172},"Propeller":{"count":6,"lastSeenTime":1586915200929},"hüpfen":{"count":6,"lastSeenTime":1586959753084},"Blatt":{"count":2,"lastSeenTime":1586920407752},"Asche":{"count":2,"lastSeenTime":1586958413299},"Tau":{"count":4,"lastSeenTime":1586908368588},"Seewolf":{"count":2,"lastSeenTime":1586955999033},"Minigolf":{"count":2,"lastSeenTime":1586815692372},"smell":{"count":1,"lastSeenTime":1586813203038,"difficulty":0.45454545454545453,"difficultyWeight":11},"sunglasses":{"count":1,"lastSeenTime":1586813258085,"difficulty":0.7272727272727273,"difficultyWeight":11},"waist":{"count":1,"lastSeenTime":1586813304541,"difficulty":0.2222222222222222,"difficultyWeight":9},"compass":{"count":1,"lastSeenTime":1586813320650,"difficulty":1,"difficultyWeight":9},"drinnen":{"count":3,"lastSeenTime":1586874931565},"Sprecher":{"count":3,"lastSeenTime":1586890093454},"flashlight":{"count":1,"lastSeenTime":1586813394246,"difficulty":0.4444444444444444,"difficultyWeight":9},"Fußende":{"count":5,"lastSeenTime":1586915406529},"Rasierer":{"count":3,"lastSeenTime":1586901284755,"difficulty":0.9375,"difficultyWeight":32},"Turm":{"count":1,"lastSeenTime":1586813676447},"Bürgermeister":{"count":2,"lastSeenTime":1586816602699,"difficulty":1,"difficultyWeight":5},"Esel":{"count":4,"lastSeenTime":1586958350172,"difficulty":1,"difficultyWeight":8},"Meme":{"count":2,"lastSeenTime":1586833304748,"difficulty":0.625,"difficultyWeight":16},"Horizont":{"count":2,"lastSeenTime":1586914638481},"schnorcheln":{"count":4,"lastSeenTime":1586903429291},"Abschluss":{"count":2,"lastSeenTime":1586868207231},"Belgien":{"count":4,"lastSeenTime":1586909070561,"difficulty":0.5555555555555556,"difficultyWeight":9},"Grille":{"count":1,"lastSeenTime":1586814301944},"Meeresfrüchte":{"count":7,"lastSeenTime":1586904308260},"sea":{"count":1,"lastSeenTime":1586814732814,"difficulty":1,"difficultyWeight":2},"Jesus Christ":{"count":1,"lastSeenTime":1586814734854},"cell":{"count":1,"lastSeenTime":1586814734854},"Schach":{"count":5,"lastSeenTime":1586959443697,"difficulty":0.8484848484848485,"difficultyWeight":33},"Schädel":{"count":3,"lastSeenTime":1586880722993,"difficulty":0.7333333333333333,"difficultyWeight":15},"Delfin":{"count":1,"lastSeenTime":1586815327708,"difficulty":0.7142857142857143,"difficultyWeight":7},"mother":{"count":1,"lastSeenTime":1586815477720,"difficulty":0.8444444444444444,"difficultyWeight":45},"wart":{"count":1,"lastSeenTime":1586815533308,"difficulty":1,"difficultyWeight":10},"cone":{"count":1,"lastSeenTime":1586815591945,"difficulty":0.9,"difficultyWeight":10},"sneeze":{"count":1,"lastSeenTime":1586815651308,"difficulty":0.6923076923076923,"difficultyWeight":13},"rice":{"count":1,"lastSeenTime":1586815683909,"difficulty":0.6923076923076923,"difficultyWeight":13},"Anfänger":{"count":3,"lastSeenTime":1586955999033},"kochen":{"count":2,"lastSeenTime":1586955569169,"difficulty":1,"difficultyWeight":3},"westlich":{"count":1,"lastSeenTime":1586816279864},"Burgruine":{"count":1,"lastSeenTime":1586816334630},"Gandhi":{"count":3,"lastSeenTime":1586955334605},"Haarschnitt":{"count":5,"lastSeenTime":1586914820916},"Planet":{"count":3,"lastSeenTime":1586909201701,"difficulty":0.8,"difficultyWeight":20},"Nessie":{"count":2,"lastSeenTime":1586839320824},"Kim Kardashian":{"count":3,"lastSeenTime":1586859216557},"Widerstand":{"count":2,"lastSeenTime":1586839211738},"Lebkuchen":{"count":3,"lastSeenTime":1586897469693},"Genie":{"count":3,"lastSeenTime":1586900436732},"Tyrannosaurus Rex":{"count":2,"lastSeenTime":1586956352310},"grün":{"count":4,"lastSeenTime":1586907557164},"Flash":{"count":2,"lastSeenTime":1586909155516},"Zorro":{"count":3,"lastSeenTime":1586859604461},"Kommunismus":{"count":3,"lastSeenTime":1586915919352},"Camping":{"count":3,"lastSeenTime":1586900977668,"difficulty":1,"difficultyWeight":9},"Vogelhaus":{"count":2,"lastSeenTime":1586890938315,"difficulty":0.5714285714285714,"difficultyWeight":7},"Ritter":{"count":3,"lastSeenTime":1586915741689},"Brocken":{"count":5,"lastSeenTime":1586958253918},"Krankheit":{"count":3,"lastSeenTime":1586914119532,"difficulty":1,"difficultyWeight":8},"Teelöffel":{"count":5,"lastSeenTime":1586921104275,"difficulty":1,"difficultyWeight":3},"Kaltwachsstreifen":{"count":4,"lastSeenTime":1586916127462},"Keim":{"count":2,"lastSeenTime":1586909311071},"Jahrbuch":{"count":1,"lastSeenTime":1586827501149,"difficulty":1,"difficultyWeight":1},"verrückt":{"count":1,"lastSeenTime":1586827603168},"Gewalt":{"count":4,"lastSeenTime":1586916540283},"Hüpfkästchen":{"count":3,"lastSeenTime":1586870007658},"Kerzenständer":{"count":3,"lastSeenTime":1586860109145},"Zauberstab":{"count":4,"lastSeenTime":1586956324955},"Telefonkabel":{"count":3,"lastSeenTime":1586915048330},"Filmemacher":{"count":3,"lastSeenTime":1586958611285,"difficulty":1,"difficultyWeight":2},"Spielplatz":{"count":2,"lastSeenTime":1586904412233},"Ohrenschmalz":{"count":1,"lastSeenTime":1586839211738,"difficulty":0.8888888888888888,"difficultyWeight":9},"Kerzenleuchter":{"count":2,"lastSeenTime":1586958572090},"Winter":{"count":2,"lastSeenTime":1586915225560,"difficulty":0.6153846153846154,"difficultyWeight":13},"Chef":{"count":5,"lastSeenTime":1586920932924},"iPhone":{"count":5,"lastSeenTime":1586958596468},"Chrome":{"count":1,"lastSeenTime":1586840244704,"difficulty":0.75,"difficultyWeight":8},"Speichel":{"count":2,"lastSeenTime":1586873812676},"Ratte":{"count":2,"lastSeenTime":1586889601390},"Grill":{"count":2,"lastSeenTime":1586896066306},"Prisma":{"count":2,"lastSeenTime":1586920346900},"Orca":{"count":1,"lastSeenTime":1586859539297},"Sicherung":{"count":5,"lastSeenTime":1586920397655},"Sandbank":{"count":2,"lastSeenTime":1586869853196},"Nachthemd":{"count":1,"lastSeenTime":1586868911645},"Bauch":{"count":1,"lastSeenTime":1586869237926,"difficulty":0.8421052631578947,"difficultyWeight":19},"Johnny Bravo":{"count":2,"lastSeenTime":1586874716360},"Stachelrochen":{"count":3,"lastSeenTime":1586956215415},"Dreck":{"count":1,"lastSeenTime":1586874073864},"Taser":{"count":2,"lastSeenTime":1586907375887,"difficulty":1,"difficultyWeight":9},"Metall":{"count":4,"lastSeenTime":1586955010181},"Doktor":{"count":3,"lastSeenTime":1586955763543},"Schriftsteller":{"count":6,"lastSeenTime":1586958934411},"laufen":{"count":1,"lastSeenTime":1586880438207},"Alarm":{"count":2,"lastSeenTime":1586959269543},"Bankier":{"count":2,"lastSeenTime":1586916756124},"Stinktier":{"count":3,"lastSeenTime":1586920275708},"Tresorraum":{"count":1,"lastSeenTime":1586890625702},"Nichtschwimmer":{"count":1,"lastSeenTime":1586890743822},"Opernhaus Sydney":{"count":2,"lastSeenTime":1586907532918},"jagen":{"count":2,"lastSeenTime":1586902702172},"Autor":{"count":2,"lastSeenTime":1586959840559},"Jackie Chan":{"count":1,"lastSeenTime":1586900412247},"Reflexion":{"count":2,"lastSeenTime":1586919650407},"Zweig":{"count":2,"lastSeenTime":1586955899639},"Experiment":{"count":1,"lastSeenTime":1586908921510},"Badezimmer":{"count":3,"lastSeenTime":1586959738785},"Spüllappen":{"count":1,"lastSeenTime":1586915543878},"Magnet":{"count":1,"lastSeenTime":1586915703672},"Fühler":{"count":2,"lastSeenTime":1586955098414},"Eisbär":{"count":1,"lastSeenTime":1586920361074},"Grabmal":{"count":1,"lastSeenTime":1586958636395}} ================================================ FILE: tools/skribbliohintsconverter/main.go ================================================ package main import ( "encoding/json" "fmt" "io" "os" ) func main() { languageFile, err := os.Open(os.Args[len(os.Args)-1]) if err != nil { panic(err) } data, err := io.ReadAll(languageFile) if err != nil { panic(err) } var words map[string]json.RawMessage err = json.Unmarshal(data, &words) if err != nil { panic(err) } for word := range words { fmt.Println(word) } } ================================================ FILE: tools/statcollector/main.go ================================================ package main import ( "encoding/json" "flag" "io" "log" "net/http" "os" "time" ) type Stat struct { Time time.Time Data string } func main() { duration := flag.Duration("duration", (7*24)*time.Hour, "the duration for which we'll collect stats.") interval := flag.Duration("interval", 5*time.Minute, "interval in which we'll send requests.") page := flag.String("page", "https://scribblers-official.herokuapp.com", "page on which we'll call /v1/stats") output := flag.String("output", "output.json", "output file for retrieved data") flag.Parse() url := *page + "/v1/stats" outputFile, err := os.OpenFile(*output, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o644) if err != nil { panic(err) } encoder := json.NewEncoder(outputFile) shutdownTimer := time.NewTimer(*duration) collectionTicker := time.Tick(*interval) for { select { case <-collectionTicker: { response, err := http.Get(url) if err == nil { data, err := io.ReadAll(response.Body) if err != nil { log.Printf("Error reading response: %s\n", err) } stat := &Stat{ Time: time.Now(), Data: string(data), } encodeError := encoder.Encode(stat) if encodeError != nil { log.Printf("Error writing data to hard-drive: %s\n", encodeError) } } else { log.Printf("Error retrieving stats: %s\n", err) } } case <-shutdownTimer.C: { os.Exit(0) } } } } ================================================ FILE: tools/translate.sh ================================================ #!/usr/bin/env bash if [ -z ${FROM+x} ]; then echo "FROM is unset"; exit 1; fi if [ -z ${TO+x} ]; then echo "TO is unset"; exit 1; fi SOURCE_FILE="../resources/words/${FROM}" DESTINATION_FILE="../resources/words/${TO}" if [ ! -f ${SOURCE_FILE} ]; then echo "file: ${SOURCE_FILE} does not exist"; fi; if [ -f ${DESTINATION_FILE} ]; then echo "WARNING! file: ${DESTINATION_FILE} already exist!"; echo "Do you want to override it? [yes/no]" read -r choice if [[ "${choice}" != "yes" ]]; then echo "Aborting" exit 1; fi rm -f ${DESTINATION_FILE} fi; touch ${DESTINATION_FILE} while read sourceWord; do cleanWord=$(echo "$sourceWord" | sed -En "s/(.*)\#.*/\1/p") tag=$(echo "$sourceWord" | sed -En "s/.*\#(.*)/\1/p") echo -n "Translating '${cleanWord}'... " # Wanna exclude some words based on a tag? # Just un-comment and edit the following lines if [[ ${tag} == "i" ]]; then echo "❌ Skipping due to tag setting." continue; fi # non-optimized AWS call # Must use a translation-job here translation=$(aws translate translate-text --text "${cleanWord}" --source-language-code "${FROM}" --target-language-code "${TO}" | jq -r .TranslatedText) echo "${translation}" >> ${DESTINATION_FILE} echo "✅" done <${SOURCE_FILE} echo "Done!" ================================================ FILE: windows.Dockerfile ================================================ # # Builder for Golang # # We explicitly use a certain major version of go, to make sure we don't build # with a newer verison than we are using for CI tests, as we don't directly # test the produced binary but from source code directly. FROM docker.io/golang:1.25.5-nanoserver-ltsc2022 AS builder WORKDIR /app # This causes caching of the downloaded go modules and makes repeated local # builds much faster. We must not copy the code first though, as a change in # the code causes a redownload. COPY go.mod go.sum ./ RUN go mod download -x # Import that this comes after mod download, as it breaks caching. ARG VERSION="dev" # Copy actual codebase, since we only have the go.mod and go.sum so far. COPY . /app/ ENV CGO_ENABLED=0 RUN go build -trimpath -ldflags "-w -s -X 'github.com/scribble-rs/scribble.rs/internal/version.Version=$VERSION'" -tags timetzdata -o ./scribblers ./cmd/scribblers # # Runner # FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 COPY --from=builder /app/scribblers /scribblers ENTRYPOINT ["/scribblers"]