From 44c9a24aacf4f8df124f0be4c6c403dfc4d73f44 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 18 Jul 2026 05:01:00 +0000 Subject: [PATCH] Add cover image URLs for all library books Populate every empty coverImage field in web/data/books.json with public cover URLs from Open Library, publisher sites, and related sources so BookCard can render real covers instead of placeholders. Co-authored-by: Muhammad Saim Shafique --- scripts/.gitignore | 2 + scripts/fetch_book_covers.py | 281 ++++++ scripts/fetch_book_covers_pass2.py | 328 +++++++ scripts/fetch_book_covers_pass3.py | 396 +++++++++ web/data/books.json | 1268 ++++++++++++++-------------- 5 files changed, 1641 insertions(+), 634 deletions(-) create mode 100644 scripts/.gitignore create mode 100644 scripts/fetch_book_covers.py create mode 100644 scripts/fetch_book_covers_pass2.py create mode 100644 scripts/fetch_book_covers_pass3.py diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 0000000..74c441c --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1,2 @@ +.cover_cache.json +__pycache__/ diff --git a/scripts/fetch_book_covers.py b/scripts/fetch_book_covers.py new file mode 100644 index 0000000..aee20db --- /dev/null +++ b/scripts/fetch_book_covers.py @@ -0,0 +1,281 @@ +#!/usr/bin/env python3 +"""Fill coverImage URLs in web/data/books.json via Open Library search.""" + +from __future__ import annotations + +import json +import re +import time +import urllib.error +import urllib.parse +import urllib.request +from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +BOOKS_PATH = ROOT / "web" / "data" / "books.json" +CACHE_PATH = ROOT / "scripts" / ".cover_cache.json" +UA = "FreeProgrammingBooksCoverBot/1.0 (github.com/EbookFoundation; cover lookup)" +COVER_ID_TMPL = "https://covers.openlibrary.org/b/id/{cover_id}-L.jpg" +COVER_ISBN_TMPL = "https://covers.openlibrary.org/b/isbn/{isbn}-L.jpg" +MAX_WORKERS = 5 +REQUEST_PAUSE = 0.15 + + +def load_json(path: Path, default): + if path.exists(): + return json.loads(path.read_text(encoding="utf-8")) + return default + + +def save_json(path: Path, data) -> None: + path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") + + +def normalize(text: str) -> str: + text = text.lower() + # Common programming-title normalizations + repl = { + "c++": "cpp", + "c#": "csharp", + "f#": "fsharp", + "javascript": "java script", + "typescript": "type script", + "objective-c": "objective c", + "node.js": "nodejs", + "node js": "nodejs", + ".net": "dotnet", + "asp.net": "aspnet", + } + for a, b in repl.items(): + text = text.replace(a, b) + text = re.sub(r"[^\w\s]", " ", text) + text = re.sub(r"\s+", " ", text).strip() + # Collapse java script -> javascript for comparison consistency after split words + text = text.replace("java script", "javascript") + text = text.replace("type script", "typescript") + return text + + +def title_core(title: str) -> str: + # Drop subtitle / series noise. + t = re.split(r"[:–—|(]", title, maxsplit=1)[0] + t = re.sub( + r"\b(series|volume|vol\.?|part|edition|ed\.?)\b.*$", + "", + t, + flags=re.I, + ) + return normalize(t).strip() + + +def edition_tokens(edition: str) -> set[str]: + ed = normalize(edition or "") + tokens: set[str] = set() + m = re.search(r"(\d+)\s*(st|nd|rd|th)?\s*edition", ed) + if m: + tokens.add(f"{m.group(1)} edition") + year = re.search(r"\b(19|20)\d{2}\b", ed) + if year: + tokens.add(year.group(0)) + return tokens + + +def http_get_json(url: str) -> dict: + req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"}) + with urllib.request.urlopen(req, timeout=30) as resp: + return json.loads(resp.read().decode("utf-8")) + + +def cover_exists(url: str) -> bool: + # Open Library returns 404 when default=false and cover missing. + check = url + ("&" if "?" in url else "?") + "default=false" + req = urllib.request.Request(check, method="HEAD", headers={"User-Agent": UA}) + try: + with urllib.request.urlopen(req, timeout=20) as resp: + return 200 <= resp.status < 400 + except urllib.error.HTTPError as exc: + return exc.code != 404 + except Exception: # noqa: BLE001 + return False + + +def search_openlibrary(query: str, mode: str = "q") -> list[dict]: + params = urllib.parse.urlencode({mode: query, "limit": 20}) + url = f"https://openlibrary.org/search.json?{params}" + data = http_get_json(url) + return data.get("docs") or [] + + +def word_overlap(a: str, b: str) -> float: + aw = set(a.split()) + bw = set(b.split()) + if not aw or not bw: + return 0.0 + return len(aw & bw) / max(len(aw), 1) + + +def score_doc(doc: dict, book_title: str, edition: str, require_cover: bool = True) -> int: + if require_cover and not doc.get("cover_i"): + return -1 + score = 5 + doc_title = doc.get("title") or "" + nt = normalize(book_title) + nd = normalize(doc_title) + tc = title_core(book_title) + dc = title_core(doc_title) + + if nd == nt or dc == tc: + score += 60 + elif tc and (tc in nd or nd in nt or dc in nt): + score += 40 + else: + overlap = max(word_overlap(tc, dc), word_overlap(nt, nd)) + if overlap < 0.45: + return -1 + score += int(overlap * 30) + + # Penalize clearly unrelated programming-adjacent collisions a bit less harshly + # but drop obvious fiction false positives when query is technical. + fiction_markers = ("sherlock", "tale of two", "harry potter", "pride and prejudice") + if any(m in nd for m in fiction_markers): + return -1 + + ed_tokens = edition_tokens(edition) + for tok in ed_tokens: + if tok and tok in nd: + score += 20 + break + + score += min(int(doc.get("edition_count") or 0), 25) // 5 + if doc.get("cover_i"): + score += 5 + return score + + +def isbn_candidates(doc: dict) -> list[str]: + out: list[str] = [] + for key in ("isbn",): + vals = doc.get(key) or [] + if isinstance(vals, list): + for v in vals: + s = re.sub(r"[^0-9Xx]", "", str(v)) + if len(s) in (10, 13): + out.append(s) + # Prefer ISBN-13 + out.sort(key=lambda x: (0 if len(x) == 13 else 1, x)) + # unique preserve order + seen = set() + uniq = [] + for x in out: + if x not in seen: + seen.add(x) + uniq.append(x) + return uniq[:6] + + +def pick_cover_url(docs: list[dict], book_title: str, edition: str) -> str: + ranked = sorted( + ((score_doc(d, book_title, edition, require_cover=False), d) for d in docs), + key=lambda x: x[0], + reverse=True, + ) + for score, doc in ranked: + if score < 0: + continue + cover_i = doc.get("cover_i") + if cover_i: + return COVER_ID_TMPL.format(cover_id=int(cover_i)) + # Fallback: ISBN cover endpoint + for isbn in isbn_candidates(doc): + url = COVER_ISBN_TMPL.format(isbn=isbn) + if cover_exists(url): + return url + return "" + + +def query_variants(title: str) -> list[str]: + variants = [title] + core = re.split(r"[:–—|(]", title, maxsplit=1)[0].strip() + if core and core not in variants: + variants.append(core) + # Strip trailing Series / Handbook noise + stripped = re.sub(r"\b(Series|Collection)\b", "", core, flags=re.I).strip(" -") + if stripped and stripped not in variants: + variants.append(stripped) + # Soft punctuation cleanup + soft = re.sub(r"[^\w\s+#.+]", " ", core) + soft = re.sub(r"\s+", " ", soft).strip() + if soft and soft not in variants: + variants.append(soft) + return variants + + +def lookup_cover(book: dict) -> str: + title = book["title"] + edition = book.get("edition") or "" + + for q in query_variants(title): + for mode in ("q", "title"): + try: + docs = search_openlibrary(q, mode=mode) + except Exception as exc: # noqa: BLE001 + print(f" warn: search failed for {book['id']!r} ({mode}): {exc}") + time.sleep(0.6) + continue + url = pick_cover_url(docs, title, edition) + if url: + return url + time.sleep(REQUEST_PAUSE) + return "" + + +def main() -> None: + books = load_json(BOOKS_PATH, []) + cache = load_json(CACHE_PATH, {}) + + # Retry previously empty cache entries. + pending = [b for b in books if not (b.get("coverImage") or "").strip()] + for b in pending: + cache.pop(b["id"], None) + + print(f"Books total: {len(books)}") + print(f"Pending lookups: {len(pending)}") + + done = 0 + found = 0 + missing = 0 + + def worker(book: dict) -> tuple[str, str]: + time.sleep(REQUEST_PAUSE) + return book["id"], lookup_cover(book) + + with ThreadPoolExecutor(max_workers=MAX_WORKERS) as pool: + futures = {pool.submit(worker, b): b for b in pending} + for fut in as_completed(futures): + book = futures[fut] + try: + book_id, url = fut.result() + except Exception as exc: # noqa: BLE001 + print(f"error: {book['id']}: {exc}") + book_id, url = book["id"], "" + cache[book_id] = url + if url: + book["coverImage"] = url + found += 1 + else: + missing += 1 + done += 1 + if done % 20 == 0 or done == len(pending): + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + print(f"progress {done}/{len(pending)} found={found} missing={missing}") + + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + filled = sum(1 for b in books if (b.get("coverImage") or "").strip()) + print(f"Done. Covers filled: {filled}/{len(books)}") + + +if __name__ == "__main__": + main() diff --git a/scripts/fetch_book_covers_pass2.py b/scripts/fetch_book_covers_pass2.py new file mode 100644 index 0000000..fb60994 --- /dev/null +++ b/scripts/fetch_book_covers_pass2.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python3 +"""Second pass: fill remaining coverImage values via ISBN + Goodreads/ISBNdb.""" + +from __future__ import annotations + +import html as html_lib +import json +import re +import time +import urllib.error +import urllib.parse +import urllib.request +from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +BOOKS_PATH = ROOT / "web" / "data" / "books.json" +CACHE_PATH = ROOT / "scripts" / ".cover_cache.json" +UA = ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/124.0.0.0 Safari/537.36" +) +OL_UA = "FreeProgrammingBooksCoverBot/1.0 (cover lookup; second pass)" +MAX_WORKERS = 4 +PAUSE = 0.25 + + +def load_json(path: Path, default): + if path.exists(): + return json.loads(path.read_text(encoding="utf-8")) + return default + + +def save_json(path: Path, data) -> None: + path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") + + +def normalize(text: str) -> str: + text = text.lower() + text = text.replace("c++", "cpp").replace("c#", "csharp") + text = text.replace("javascript", "java script").replace("typescript", "type script") + text = re.sub(r"[^\w\s]", " ", text) + text = re.sub(r"\s+", " ", text).strip() + return text.replace("java script", "javascript").replace("type script", "typescript") + + +def title_core(title: str) -> str: + t = re.split(r"[:–—|(]", title, maxsplit=1)[0] + t = re.sub(r"\b(series|collection)\b", "", t, flags=re.I) + return normalize(t).strip() + + +def http_get(url: str, ua: str = UA, timeout: int = 30) -> tuple[str, str]: + req = urllib.request.Request( + url, + headers={ + "User-Agent": ua, + "Accept": "text/html,application/json;q=0.9,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.9", + }, + ) + with urllib.request.urlopen(req, timeout=timeout) as resp: + charset = resp.headers.get_content_charset() or "utf-8" + return resp.geturl(), resp.read().decode(charset, "replace") + + +def http_get_json(url: str) -> dict: + final, body = http_get(url, ua=OL_UA) + return json.loads(body) + + +def og_image(page: str) -> str: + m = re.search( + r'property=["\']og:image["\']\s+content=["\']([^"\']+)["\']', + page, + flags=re.I, + ) + if not m: + m = re.search( + r'content=["\']([^"\']+)["\']\s+property=["\']og:image["\']', + page, + flags=re.I, + ) + if not m: + return "" + return html_lib.unescape(m.group(1)).strip() + + +def word_overlap(a: str, b: str) -> float: + aw, bw = set(a.split()), set(b.split()) + if not aw: + return 0.0 + return len(aw & bw) / len(aw) + + +def score_title(candidate: str, wanted: str) -> float: + return max( + word_overlap(title_core(wanted), title_core(candidate)), + word_overlap(normalize(wanted), normalize(candidate)), + ) + + +def ol_isbns_for_title(title: str) -> list[str]: + isbns: list[str] = [] + queries = [title, re.split(r"[:–—|(]", title, maxsplit=1)[0].strip()] + seen_q = set() + for q in queries: + if not q or q in seen_q: + continue + seen_q.add(q) + try: + data = http_get_json( + "https://openlibrary.org/search.json?" + + urllib.parse.urlencode({"q": q, "limit": 8}) + ) + except Exception: + continue + docs = data.get("docs") or [] + ranked = sorted( + docs, + key=lambda d: score_title(d.get("title") or "", title), + reverse=True, + ) + for doc in ranked[:3]: + if score_title(doc.get("title") or "", title) < 0.45: + continue + for isbn in doc.get("isbn") or []: + clean = re.sub(r"[^0-9Xx]", "", str(isbn)) + if len(clean) in (10, 13): + isbns.append(clean) + key = doc.get("key") + if key and key.startswith("/works/"): + try: + editions = http_get_json( + f"https://openlibrary.org{key}/editions.json?limit=12" + ) + except Exception: + editions = {} + for entry in editions.get("entries") or []: + for field in ("isbn_13", "isbn_10"): + for isbn in entry.get(field) or []: + clean = re.sub(r"[^0-9Xx]", "", str(isbn)) + if len(clean) in (10, 13): + isbns.append(clean) + time.sleep(PAUSE) + # unique, prefer isbn13 + uniq: list[str] = [] + seen = set() + for isbn in sorted(isbns, key=lambda x: (0 if len(x) == 13 else 1, x)): + if isbn not in seen: + seen.add(isbn) + uniq.append(isbn) + return uniq[:8] + + +def cover_from_goodreads_isbn(isbn: str) -> str: + url = f"https://www.goodreads.com/book/isbn/{isbn}" + try: + final, page = http_get(url) + except Exception: + return "" + if "verify" in final or "captcha" in final.lower(): + return "" + img = og_image(page) + if not img: + return "" + # Ignore site-wide fallback logos + low = img.lower() + if "goodreads_logo" in low or "facebook_default" in low: + return "" + if "/books/" not in low and "images/i/" not in low and "photo.goodreads" not in low: + # still accept amazon media book images + if "media-amazon.com" not in low and "ssl-images-amazon.com" not in low: + return "" + return img + + +def cover_from_isbnsearch(isbn: str) -> str: + url = f"https://isbnsearch.org/isbn/{isbn}" + try: + _, page = http_get(url) + except Exception: + return "" + m = re.search(r'https://images\.isbndb\.com/covers/\d+\.jpg', page) + return m.group(0) if m else "" + + +def cover_from_google_books_page(isbn: str) -> str: + url = f"https://books.google.com/books?vid=ISBN{isbn}&printsec=frontcover" + try: + _, page = http_get(url) + except Exception: + return "" + img = og_image(page) + if not img: + return "" + # Prefer non-tokenized publisher content URL if present + m = re.search( + r'https://books\.google\.com/books/publisher/content\?[^"\']+', + page, + ) + if m: + return html_lib.unescape(m.group(0)).split("&")[0] if False else html_lib.unescape(m.group(0)) + return img + + +def cover_from_goodreads_search(title: str) -> str: + url = "https://www.goodreads.com/search?q=" + urllib.parse.quote(title) + try: + _, page = http_get(url) + except Exception: + return "" + # Result rows include book title links and cover images. + # Example: / + pattern = re.compile( + r'class="bookTitle"[^>]*>\s*([^<]+?)\s*.*?' + r'(?:src|data-src)=["\'](https://[^"\']+(?:goodreads|gr-assets|media-amazon)[^"\']+)["\']', + flags=re.I | re.S, + ) + # Simpler: find book covers near title text + # Goodreads search often has: Quarkus in Action + for m in re.finditer( + r']+alt=["\']([^"\']+)["\'][^>]+src=["\'](https://[^"\']+)["\']', + page, + flags=re.I, + ): + alt, src = m.group(1), m.group(2) + if score_title(alt, title) >= 0.55 and ("books" in src or "gr-assets" in src or "goodreads" in src or "media-amazon" in src): + return html_lib.unescape(src) + for m in re.finditer( + r']+src=["\'](https://[^"\']+)["\'][^>]+alt=["\']([^"\']+)["\']', + page, + flags=re.I, + ): + src, alt = m.group(1), m.group(2) + if score_title(alt, title) >= 0.55 and ("books" in src or "gr-assets" in src or "goodreads" in src or "media-amazon" in src): + return html_lib.unescape(src) + return "" + + +def cover_from_manning(title: str) -> str: + slug = re.sub(r"[^\w\s-]", "", title.lower()) + slug = re.sub(r"\s+", "-", slug.strip()) + url = f"https://www.manning.com/books/{slug}" + try: + final, page = http_get(url) + except urllib.error.HTTPError: + return "" + except Exception: + return "" + if "/books/" not in final: + return "" + img = og_image(page) + if img and "manning.com" in img: + return img + return "" + + +def lookup_cover(book: dict) -> str: + title = book["title"] + + # Publisher shortcut for Manning-style titles + manning = cover_from_manning(title) + if manning: + return manning + + isbns = ol_isbns_for_title(title) + for isbn in isbns: + for fn in (cover_from_goodreads_isbn, cover_from_isbnsearch, cover_from_google_books_page): + try: + url = fn(isbn) + except Exception: + url = "" + if url: + return url + time.sleep(PAUSE) + + # Title search fallback + try: + url = cover_from_goodreads_search(title) + except Exception: + url = "" + return url or "" + + +def main() -> None: + books = load_json(BOOKS_PATH, []) + cache = load_json(CACHE_PATH, {}) + pending = [b for b in books if not (b.get("coverImage") or "").strip()] + print(f"Pending: {len(pending)}") + + done = found = missing = 0 + + def worker(book: dict) -> tuple[str, str]: + time.sleep(PAUSE) + return book["id"], lookup_cover(book) + + with ThreadPoolExecutor(max_workers=MAX_WORKERS) as pool: + futures = {pool.submit(worker, b): b for b in pending} + for fut in as_completed(futures): + book = futures[fut] + try: + book_id, url = fut.result() + except Exception as exc: # noqa: BLE001 + print(f"error {book['id']}: {exc}") + book_id, url = book["id"], "" + cache[book_id] = url + if url: + book["coverImage"] = url + found += 1 + print(f" + {book['title'][:60]} -> {url[:80]}") + else: + missing += 1 + done += 1 + if done % 10 == 0 or done == len(pending): + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + print(f"progress {done}/{len(pending)} found={found} missing={missing}") + + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + filled = sum(1 for b in books if (b.get("coverImage") or "").strip()) + print(f"Done. Covers filled: {filled}/{len(books)}") + + +if __name__ == "__main__": + main() diff --git a/scripts/fetch_book_covers_pass3.py b/scripts/fetch_book_covers_pass3.py new file mode 100644 index 0000000..e8b63a5 --- /dev/null +++ b/scripts/fetch_book_covers_pass3.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python3 +"""Third pass: publisher pages, docs og:images, and Manning cover fixes.""" + +from __future__ import annotations + +import html as html_lib +import json +import re +import time +import urllib.error +import urllib.parse +import urllib.request +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +BOOKS_PATH = ROOT / "web" / "data" / "books.json" +CACHE_PATH = ROOT / "scripts" / ".cover_cache.json" +UA = ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/124.0.0.0 Safari/537.36" +) + +# Known online docs / guides → stable public images +CURATED: dict[str, str] = { + "MDN Web Docs": "https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png", + "MDN Web Docs — HTML": "https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png", + "MDN Web Docs — CSS": "https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png", + "Official Go Documentation": "https://go.dev/blog/go-brand/Go-Logo/PNG/Go-Logo_Blue.png", + "The TypeScript Handbook": "https://www.typescriptlang.org/images/branding/logo-grouping.png", + "TypeScript Deep Dive": "https://basarat.gitbook.io/typescript/~gitbook/ogimage/-LxQ3jd_Z3snLZ7ef2c3", + "Kotlin Documentation": "https://kotlinlang.org/assets/images/open-graph/docs.png", + "Official Ruby Documentation": "https://www.ruby-lang.org/images/header-ruby-logo@2x.png", + "The Ruby Style Guide": "https://raw.githubusercontent.com/rubocop/ruby-style-guide/master/images/cover.png", + "Effective Dart": "https://dart.dev/assets/shared/dart-logo-for-shares.png?2", + "Dart Language Documentation": "https://dart.dev/assets/shared/dart-logo-for-shares.png?2", + "A Tour of the Dart Language": "https://dart.dev/assets/shared/dart-logo-for-shares.png?2", + "Scala Documentation": "https://www.scala-lang.org/resources/img/scala-logo-red-circle-transparent.png", + "Scala 3 Book": "https://docs.scala-lang.org/static/img/scala-spiral-white.png", + "Elixir Getting Started Guide": "https://elixir-lang.org/images/logo/logo.png", + "Official Elixir Documentation": "https://elixir-lang.org/images/logo/logo.png", + "Elixir on HexDocs": "https://hexdocs.pm/images/apple-touch-icon.png", + "HexDocs": "https://hexdocs.pm/images/apple-touch-icon.png", + "Erlang/OTP Documentation": "https://www.erlang.org/img/erlang.png", + "Greg's Wiki — BashGuide": "https://mywiki.wooledge.org/htdocs/apple-touch-icon.png", + "ShellCheck": "https://www.shellcheck.net/shellcheck.png", + "Google Shell Style Guide": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", + "RDocumentation": "https://www.r-project.org/logo/Rlogo.png", + "The Julia Language Documentation": "https://julialang.org/assets/infra/julia-opengraph.png", + "JuliaAcademy": "https://julialang.org/assets/infra/julia-opengraph.png", + "Lua 5.4 Reference Manual": "https://www.lua.org/images/lua-logo.gif", + "Official Lua Documentation": "https://www.lua.org/images/lua-logo.gif", + "Lua Users Wiki": "https://www.lua.org/images/lua-logo.gif", + "MathWorks MATLAB Documentation": "https://www.mathworks.com/favicon.ico", + "MATLAB Onramp": "https://www.mathworks.com/favicon.ico", + "Official Haskell Documentation": "https://www.haskell.org/img/haskell-logo.svg", + "Microsoft PowerShell Documentation": "https://learn.microsoft.com/favicon.ico", + "PowerShell Gallery": "https://www.powershellgallery.com/Content/Images/Branding/packageDefaultIcon-50x50.png", + "Zig Language Reference": "https://ziglang.org/img/zig-logo-dark.svg", + "Ziglearn": "https://ziglang.org/img/zig-logo-dark.svg", + "Zig Documentation — Advanced Language Features": "https://ziglang.org/img/zig-logo-dark.svg", + "Zig Build System Documentation": "https://ziglang.org/img/zig-logo-dark.svg", + "Using Zig as a C Compiler / Cross Linker": "https://ziglang.org/img/zig-logo-dark.svg", + "Official Zig Documentation": "https://ziglang.org/img/zig-logo-dark.svg", + "Zig Standard Library Docs": "https://ziglang.org/img/zig-logo-dark.svg", + "Writing an OS in Zig (community guides)": "https://ziglang.org/img/zig-logo-dark.svg", + "Solidity by Example": "https://soliditylang.org/images/logo.svg", + "Solidity Language Documentation": "https://docs.soliditylang.org/en/latest/_images/logo.svg", + "CryptoZombies": "https://cryptozombies.io/images/preview_image.png", + "Ethereum Developer Documentation": "https://ethereum.org/images/eth-diamond-black.png", + "Ethereum Developer Docs": "https://ethereum.org/images/eth-diamond-black.png", + "Ethereum Smart Contract Security Best Practices": "https://ethereum.org/images/eth-diamond-black.png", + "Ethernaut / Capture the Ether style challenges": "https://ethereum.org/images/eth-diamond-black.png", + "Official Perl Documentation": "https://cdn.perl.org/perlweb/images/camel_head.png", + "Perl Maven": "https://perlmaven.com/img/perl_maven_150x214.png", + "Apple Objective-C Documentation": "https://developer.apple.com/news/images/og/apple-developer-og.png", + "Apple Cocoa Documentation": "https://developer.apple.com/news/images/og/apple-developer-og.png", + "Official Clojure Documentation": "https://clojure.org/images/clojure-logo-120b.png", + "ClojureDocs": "https://clojuredocs.org/images/cd-icon.png", + "The Rustonomicon": "https://www.rust-lang.org/static/images/rust-logo-blk.svg", + "The Embedded Rust Book": "https://www.rust-lang.org/static/images/rust-logo-blk.svg", + "Beej's Guide to C Programming": "https://beej.us/guide/bgc/img/book-cover.png", + "x86 Instruction Reference": "https://www.felixcloutier.com/favicon.ico", + "Fortran Standards / ISO references": "https://fortran-lang.org/assets/img/fortran-logo.png", + "Fortran Discourse & Community Docs": "https://fortran-lang.org/assets/img/fortran-logo.png", + "TypeScript Weekly": "https://www.typescriptlang.org/images/branding/logo-grouping.png", + "Utility Types Reference": "https://www.typescriptlang.org/images/branding/logo-grouping.png", + "Tackling TypeScript": "https://exploringjs.com/img/cover.jpg", +} + + +def load_json(path: Path, default): + if path.exists(): + return json.loads(path.read_text(encoding="utf-8")) + return default + + +def save_json(path: Path, data) -> None: + path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") + + +def slugify(title: str) -> str: + s = title.lower() + s = s.replace("&", " and ") + s = s.replace("c++", "c-plus-plus").replace("c#", "c-sharp") + s = re.sub(r"[^\w\s-]", "", s) + s = re.sub(r"\s+", "-", s.strip()) + return s + + +def http_get(url: str) -> tuple[str, str]: + req = urllib.request.Request( + url, + headers={"User-Agent": UA, "Accept": "text/html,application/xhtml+xml", "Accept-Language": "en"}, + ) + with urllib.request.urlopen(req, timeout=30) as resp: + charset = resp.headers.get_content_charset() or "utf-8" + return resp.geturl(), resp.read().decode(charset, "replace") + + +def extract_og_image(page: str) -> str: + for pat in ( + r'property=["\']og:image(?::url)?["\']\s+content=["\']([^"\']+)["\']', + r'content=["\']([^"\']+)["\']\s+property=["\']og:image(?::url)?["\']', + r'name=["\']twitter:image["\']\s+content=["\']([^"\']+)["\']', + ): + m = re.search(pat, page, flags=re.I) + if m: + return html_lib.unescape(m.group(1)).strip() + return "" + + +def first_matching_image(page: str, host_substr: str) -> str: + imgs = re.findall(r'https://[^"\']+\.(?:jpg|jpeg|png|webp)', page, flags=re.I) + for img in imgs: + if host_substr in img and "logo" not in img.lower() and "icon" not in img.lower(): + return html_lib.unescape(img) + return "" + + +def cover_from_manning(title: str) -> str: + slug = slugify(title) + url = f"https://www.manning.com/books/{slug}" + try: + final, page = http_get(url) + except Exception: + return "" + if "/books/" not in final: + return "" + # Prefer explicit product cover assets over social twitter.png + m = re.search( + r'https://images\.manning\.com/310/310/crop/book/[^"\']+', + page, + ) + if m: + # Upgrade crop URL to a nicer portrait resize when possible + path = m.group(0) + upgraded = re.sub( + r"https://images\.manning\.com/310/310/crop/", + "https://images.manning.com/360/480/resize/", + path, + ) + return upgraded + img = extract_og_image(page) + if img and "twitter.png" not in img: + return img + return "" + + +def cover_from_nostarch(title: str) -> str: + candidates = [ + f"https://nostarch.com/{slugify(title)}", + f"https://nostarch.com/{slugify(title).replace('-', '')}", + ] + # Common No Starch aliases + aliases = { + "beyond-the-basic-stuff-with-python": "beyond-basic-stuff-python", + "the-recursive-book-of-recursion": "recursive-book-recursion", + "automate-the-boring-stuff-with-python": "automate-boring-stuff-python-3rd-edition", + "python-crash-course": "python-crash-course-3rd-edition", + "black-hat-python": "black-hat-python2e", + "black-hat-go": "black-hat-go", + "black-hat-rust": "black-hat-rust", + } + slug = slugify(title) + if slug in aliases: + candidates.insert(0, f"https://nostarch.com/{aliases[slug]}") + for url in candidates: + try: + final, page = http_get(url) + except Exception: + continue + if "nostarch.com" not in final: + continue + img = extract_og_image(page) or first_matching_image(page, "nostarch.com/sites/default/files") + if img and "placeholder" not in img: + return img + return "" + + +def cover_from_leanpub(title: str) -> str: + aliases = { + "javascript-allong": "javascriptallongesix", + "javascript-allongé": "javascriptallongesix", + "you-dont-know-js-yet-series": "get-started", + "zionomicon": "zionomicon", + "scala-with-cats": "scala-with-cats", + "functional-programming-for-mortals-with-scalaz": "fp-for-mortals", + "clojurescript-unraveled": "clojurescript-unraveled", + "black-hat-rust": "black-hat-rust", + "black-hat-ruby": "black-hat-ruby", + "effective-pandas-2": "effective-pandas", + "swift-gems": "swiftgems", + "swiftui-views-mastery": "swiftuiviewsmastery", + } + slug = slugify(title) + keys = [aliases.get(slug, slug), slug.replace("-", "")] + for key in keys: + url = f"https://leanpub.com/{key}" + try: + final, page = http_get(url) + except Exception: + continue + if "/404" in final or "Page not found" in page[:2000]: + continue + img = extract_og_image(page) + if img and "leanpub" in img or "cloudfront" in img: + return img + return "" + + +def cover_from_pragprog(title: str) -> str: + slug = slugify(title) + url = f"https://pragprog.com/titles/{slug}/" + try: + final, page = http_get(url) + except Exception: + # try search + search = "https://pragprog.com/search/?q=" + urllib.parse.quote(title) + try: + final, page = http_get(search) + except Exception: + return "" + m = re.search(r'href="(https://pragprog.com/titles/[^"]+/)"', page) + if not m: + return "" + try: + final, page = http_get(m.group(1)) + except Exception: + return "" + img = extract_og_image(page) or first_matching_image(page, "pragprog.com") + return img + + +def cover_from_oreilly(title: str) -> str: + # O'Reilly search page often includes cover images. + url = "https://www.oreilly.com/search/?q=" + urllib.parse.quote(title) + try: + _, page = http_get(url) + except Exception: + return "" + # Look for cover images near the exact title + for m in re.finditer( + r'https://learning\.oreilly\.com/library/cover/[^"\']+', + page, + ): + return html_lib.unescape(m.group(0)) + img = extract_og_image(page) + if img and "oreilly" in img: + return img + return "" + + +def cover_from_packt(title: str) -> str: + url = "https://www.packtpub.com/search?query=" + urllib.parse.quote(title) + try: + _, page = http_get(url) + except Exception: + return "" + imgs = re.findall(r'https://[^"\']+packt[^"\']+\.(?:jpg|png|webp)', page, flags=re.I) + for img in imgs: + if "cover" in img.lower() or "products" in img.lower(): + return html_lib.unescape(img) + return "" + + +def cover_from_isbnsearch_title(title: str) -> str: + url = "https://isbnsearch.org/search?s=" + urllib.parse.quote(title) + try: + _, page = http_get(url) + except Exception: + return "" + # Result cards include cover + title + for m in re.finditer( + r'https://images\.isbndb\.com/covers/\d+\.jpg', + page, + ): + return m.group(0) + return "" + + +def cover_from_google_books_html(title: str) -> str: + url = "https://www.google.com/search?tbm=bks&q=" + urllib.parse.quote(f'"{title}"') + try: + _, page = http_get(url) + except Exception: + return "" + m = re.search( + r'https://books\.google\.[^"\']+/books/content\?[^"\']+', + page, + ) + if m: + return html_lib.unescape(m.group(0)).replace("&", "&") + m = re.search(r'data-src=["\'](https://books\.google[^"\']+)["\']', page) + if m: + return html_lib.unescape(m.group(1)).replace("&", "&") + return "" + + +def fix_manning_social(url: str, title: str) -> str: + if "social-images.manning.com" not in url and "twitter.png" not in url: + return url + fixed = cover_from_manning(title) + return fixed or url + + +def lookup(book: dict) -> str: + title = book["title"] + if title in CURATED: + return CURATED[title] + + for fn in ( + cover_from_manning, + cover_from_nostarch, + cover_from_leanpub, + cover_from_pragprog, + cover_from_oreilly, + cover_from_packt, + cover_from_isbnsearch_title, + cover_from_google_books_html, + ): + try: + url = fn(title) + except Exception: + url = "" + if url: + return url + time.sleep(0.15) + return "" + + +def main() -> None: + books = load_json(BOOKS_PATH, []) + cache = load_json(CACHE_PATH, {}) + + # Fix bad Manning social images first + fixed = 0 + for b in books: + img = b.get("coverImage") or "" + if "social-images.manning.com" in img or img.endswith("twitter.png"): + new = fix_manning_social(img, b["title"]) + if new and new != img: + b["coverImage"] = new + cache[b["id"]] = new + fixed += 1 + print(f"fixed manning: {b['title']} -> {new}") + print(f"Manning fixes: {fixed}") + + pending = [b for b in books if not (b.get("coverImage") or "").strip()] + print(f"Pending: {len(pending)}") + + found = missing = 0 + for i, book in enumerate(pending, 1): + url = lookup(book) + cache[book["id"]] = url + if url: + book["coverImage"] = url + found += 1 + print(f"+ {book['title'][:70]} -> {url[:100]}") + else: + missing += 1 + print(f"- miss: {book['title']}") + if i % 10 == 0 or i == len(pending): + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + print(f"progress {i}/{len(pending)} found={found} missing={missing}") + time.sleep(0.1) + + save_json(CACHE_PATH, cache) + save_json(BOOKS_PATH, books) + filled = sum(1 for b in books if (b.get("coverImage") or "").strip()) + print(f"Done. Covers filled: {filled}/{len(books)}") + + +if __name__ == "__main__": + main() diff --git a/web/data/books.json b/web/data/books.json index 58274e1..681a18c 100644 --- a/web/data/books.json +++ b/web/data/books.json @@ -7,7 +7,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1uQAJEhukgO4JmJGMJpKM_jqxNLX7NM8_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509385-L.jpg" }, { "id": "python-python-crash-course", @@ -17,7 +17,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/18VgBH8O9Vy1q3zCkpssl6VO8RxzwIKzm/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8245395-L.jpg" }, { "id": "python-automate-the-boring-stuff-with-python", @@ -27,7 +27,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1NbLN0H0_nait6xOildlg0RSehU5PXzDP/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7363640-L.jpg" }, { "id": "python-introducing-python-modern-computing-in-simple-packages", @@ -37,7 +37,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1-_8Zcoh2K9iIY2yQ_kcnuXw5d187wk8b/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7503511-L.jpg" }, { "id": "python-head-first-python", @@ -47,7 +47,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1FY7tFJ_TqOqokSHfUZwiDfUt_IzIYBfQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6681113-L.jpg" }, { "id": "python-learn-python-3-the-hard-way", @@ -57,7 +57,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/18DYbGGuxNqtcXHXpncT2dE-I6N1czoKe/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510257-L.jpg" }, { "id": "python-the-quick-python-book", @@ -67,7 +67,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1Iqq_s71shEtgb5j7Y0g2-7gFU-UMtjiH/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508566-L.jpg" }, { "id": "python-effective-python-125-specific-ways-to-write-better-python", @@ -77,7 +77,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/104VUEoNCp00NPc4-3h3QtDUb7xIM9Qrb/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7363706-L.jpg" }, { "id": "python-refactoring-improving-the-design-of-existing-code", @@ -87,7 +87,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1ba9n8rsoSMMUyMrLqfZIitsgoYau_7C6/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7087623-L.jpg" }, { "id": "python-clean-architecture-with-python", @@ -97,7 +97,7 @@ "category": "intermediate", "edition": "2025 Edition", "driveUrl": "https://drive.google.com/file/d/10vEHHNbhFzPcyoUzf00xrYkUT_A5RAti/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511934-L.jpg" }, { "id": "python-python-cookbook", @@ -107,7 +107,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/18VgBH8O9Vy1q3zCkpssl6VO8RxzwIKzm/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388536-L.jpg" }, { "id": "python-python-distilled", @@ -117,7 +117,7 @@ "category": "intermediate", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1Vt3Jn8oaBsALVVrUuK4Ho8Qg2wfndgXM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13259024-L.jpg" }, { "id": "python-python-tricks-a-buffet-of-awesome-features", @@ -127,7 +127,7 @@ "category": "intermediate", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/155g_0vl_JzQdRzg_KfpY9qPsb65LFL0S/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509237-L.jpg" }, { "id": "python-clean-code-in-python", @@ -137,7 +137,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1ECxFQB2lWIv6CdYiC6cOJkDV53VeV7ia/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10541843-L.jpg" }, { "id": "python-high-performance-python", @@ -147,7 +147,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://www.oreilly.com/library/view/high-performance-python/9781492055013/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511886-L.jpg" }, { "id": "python-expert-python-programming", @@ -157,7 +157,7 @@ "category": "advanced", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1ER9iFwUlm5vJ2dY4e__TCUmDRIE1riGE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11326025-L.jpg" }, { "id": "python-fluent-python", @@ -167,7 +167,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1EqAKCmgiWFj_NAAlUxx9mF0h2rSs3Ngf/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8743408-L.jpg" }, { "id": "python-serious-python-black-belt-advice-on-deployment-scalability-testing-and-more", @@ -177,7 +177,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/1IpYDx3r32s8wlHBDvgh4vndn_LATqF2n/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507736-L.jpg" }, { "id": "python-robust-python", @@ -187,7 +187,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1hR8h4KzK1L18CA_ral_5vdnydup-4cGE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12932198-L.jpg" }, { "id": "python-python-microservices-development", @@ -197,7 +197,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1muURujieIYs-2X5nyfnGlUv-6N5T8uGV/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14683494-L.jpg" }, { "id": "python-python-concurrency-with-asyncio", @@ -207,7 +207,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/10ke1suH-FHzaDrW7T0Ey1d_DrBoBDQYG/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13869105-L.jpg" }, { "id": "python-cpython-internals", @@ -217,7 +217,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1dcPzFC2bmL1WQ7PzGZu8iuVRkZHYT0_0/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11505175-L.jpg" }, { "id": "python-python-for-data-analysis", @@ -227,7 +227,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1EhoR0GurifXZUgZRyrROBw1-pR0aPy_B/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7548132-L.jpg" }, { "id": "python-python-data-science-handbook", @@ -237,7 +237,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1dXDoiPg9N4VGBgFLllYixG2p58IfKzqe/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512092-L.jpg" }, { "id": "python-effective-pandas-2", @@ -247,7 +247,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1ainAQctlM2_IPOYi3X9pjU0tCWyH5w_N/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/24037683488906.jpg" }, { "id": "python-building-data-science-applications-with-fastapi", @@ -257,7 +257,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/12T1F60yUscujv-dnqZqKqj2K2XVPWGoD/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13314942-L.jpg" }, { "id": "python-python-for-finance", @@ -267,7 +267,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1Vo7fH6e1ds04jh2DMJiAwiXtmk2Le8S5/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510255-L.jpg" }, { "id": "python-advances-in-financial-machine-learning", @@ -277,7 +277,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1rhp--FYDX8HN7PZjIsYoV9DZsygApH9d/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9224592-L.jpg" }, { "id": "python-black-hat-python", @@ -287,7 +287,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1A-6FFzKsKH8KBWKe-Xex6x3nKUJRttpn/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513526-L.jpg" }, { "id": "python-python-for-cybersecurity", @@ -297,7 +297,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/12hIC_ehrC4CJGsH3vzWxgjoNGC4sta8Y/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13878767-L.jpg" }, { "id": "python-violent-python", @@ -307,7 +307,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1mxMoCVmS7eMq66kW0ovEnoanT_cuRhje/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7642040-L.jpg" }, { "id": "python-python-for-devops", @@ -317,7 +317,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1wbWMACWbiBHWHiarr8FY2lJ9v3fuzXVr/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10236917-L.jpg" }, { "id": "python-architecture-patterns-with-python", @@ -327,7 +327,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1Q_nliXhHs9fkZCHFHgwvWj1uJeYxr-k5/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14814018-L.jpg" }, { "id": "python-test-driven-development-with-python", @@ -337,7 +337,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1_P1u1TDWiWD6DTAIqmgQL-W21TsD7FkQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508810-L.jpg" }, { "id": "python-the-recursive-book-of-recursion", @@ -347,7 +347,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/11nnT8dGaRsLTwEa7u52LDH7959IgM-_g/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1632871112i/58680284.jpg" }, { "id": "python-learning-robotics-using-python", @@ -357,7 +357,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/16rTVNUDlGiTjDs3fj0QjnYwa5BDQBrIs/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508689-L.jpg" }, { "id": "python-create-gui-applications-with-python-qt5", @@ -367,7 +367,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1SwShjrM2iuFJS75jEDciu_Gux2W-kgqE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1627608927i/58659402.jpg" }, { "id": "python-python-gui-programming-with-tkinter", @@ -377,7 +377,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/18M1yiC_W2OBmBD_Ob4VrKaMwr4V1-5J1/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508634-L.jpg" }, { "id": "python-raspberry-pi-cookbook", @@ -387,7 +387,7 @@ "category": "specialized", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1MsNorEk-M_9uHR6L-xAXMjtAekDlfF31/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9159681-L.jpg" }, { "id": "python-introduction-to-machine-learning-with-python", @@ -397,7 +397,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1jbetUiu-ahTJqQK-ATHOf5Zg1Sm4s9_z/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7435335-L.jpg" }, { "id": "python-designing-machine-learning-systems", @@ -407,7 +407,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1z5_PQLSi1wFen0h99_95n0wFQYNVz29C/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13314480-L.jpg" }, { "id": "python-hands-on-machine-learning-with-scikit-learn-keras-tensorflow", @@ -417,7 +417,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1jMLJE4NA7tdSBIE-KZkWznJxdKQr8UrO/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9388208-L.jpg" }, { "id": "python-machine-learning-engineering-in-action", @@ -427,7 +427,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1xWWLZfXJG7qrju6Mh17We_G9pr4RT4ph/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13313304-L.jpg" }, { "id": "python-deep-learning-with-python", @@ -437,7 +437,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1wmqeThVLxX5SgRmioQcXGdRdBC6vN_Y7/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507718-L.jpg" }, { "id": "python-natural-language-processing-with-transformers", @@ -447,7 +447,7 @@ "category": "specialized", "edition": "Revised Edition", "driveUrl": "https://drive.google.com/file/d/1a3pv09qyxMtJxSnfZwSOrqXf8zt4dQO8/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14559602-L.jpg" }, { "id": "python-build-a-large-language-model-from-scratch", @@ -457,7 +457,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1qgnbndzOPoViT4eJ7gU9bWkTkF1CjN0O/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15225524-L.jpg" }, { "id": "python-llm-engineer-s-handbook", @@ -467,7 +467,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1Yfzv4pICwMugTm11xPleiLwgR3TPePLv/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1721757928i/216260213.jpg" }, { "id": "python-generative-ai-with-python-and-pytorch", @@ -477,7 +477,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1twRF-j2ktalTCE89ThfI51eHzp64kf6w/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1722522434i/216726761.jpg" }, { "id": "python-flask-web-development", @@ -487,7 +487,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1_b19XqS6UDqgnKXPlL8Dyeb4LTVqsYYN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7481281-L.jpg" }, { "id": "python-django-for-professional", @@ -497,7 +497,7 @@ "category": "specialized", "edition": "4.0 Edition", "driveUrl": "https://drive.google.com/file/d/1IYtzXesvaaMi2twWpSQlC1Bi0Wdi03YI/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9395215-L.jpg" }, { "id": "python-fastapi-modern-python-web-development", @@ -507,7 +507,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1HTXonEDa0utaa1ewACDhClS_AIstECEz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14601403-L.jpg" }, { "id": "python-two-scoops-of-django", @@ -517,7 +517,7 @@ "category": "specialized", "edition": "*3.x Edition*", "driveUrl": "https://drive.google.com/file/d/1lz1_ww3kNobzHqCjYpfnk8gYwFqNzgfq/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11385173-L.jpg" }, { "id": "python-python-pocket-reference", @@ -527,7 +527,7 @@ "category": "references", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1fAiatWg2i2BwHviGybMPUrwafRDBtgEg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/988215-L.jpg" }, { "id": "python-python-testing-with-pytest", @@ -537,7 +537,7 @@ "category": "references", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1CanVLEhQ_XOgrq4YRm2fRUkfWx07CqF0/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508770-L.jpg" }, { "id": "python-beyond-the-basic-stuff-with-python", @@ -547,7 +547,7 @@ "category": "references", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1txbFLEtmJrp4H9P7oUC048jwLUPOYHBa/view?usp=sharing", - "coverImage": "" + "coverImage": "https://nostarch.com/sites/default/files/BeyondBasicPython.jpg" }, { "id": "python-the-python-3-standard-library-by-example", @@ -557,7 +557,7 @@ "category": "references", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/134t_JdiXzJ6vKcEjaprmm8X7uCs7AHjH/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508847-L.jpg" }, { "id": "python-learning-python", @@ -567,7 +567,7 @@ "category": "references", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1rIJ6NyKuTAM9hgGC2HDoMKaxBVIcAWt-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1312568-L.jpg" }, { "id": "javascript-javascript-from-beginner-to-professional", @@ -577,7 +577,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1GKtF2crx0wmUIku4jwCgbuTy9eDoxo3_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1699864552i/198480854.jpg" }, { "id": "javascript-eloquent-javascript", @@ -587,7 +587,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1Z8AS0zomMHxPY1wbcE6vCp7aD_s0oqxq/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7082166-L.jpg" }, { "id": "javascript-head-first-javascript-programming", @@ -597,7 +597,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1fYezQ9QtxOqnS_99ETaWVYMlOPsUtJfF/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1718975574i/212162930.jpg" }, { "id": "javascript-a-smarter-way-to-learn-javascript", @@ -607,7 +607,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1skBO-GQHUkffKL57VDDVIM6KoICQIQF3/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513204-L.jpg" }, { "id": "javascript-learn-javascript-quickly", @@ -617,7 +617,7 @@ "category": "beginner", "edition": "2025 Edition", "driveUrl": "https://drive.google.com/file/d/1B5VlqlzrieiSHoWQYsygvyESx8iy53DK/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11209788-L.jpg" }, { "id": "javascript-you-don-t-know-js-yet-series", @@ -627,7 +627,7 @@ "category": "intermediate", "edition": "Complete Series", "driveUrl": "https://drive.google.com/drive/folders/1KVPu5zMerN2ky7_NaVDq6I5N2ZJXbPN0?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12539693-L.jpg" }, { "id": "javascript-javascript-the-good-parts", @@ -637,7 +637,7 @@ "category": "intermediate", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/19bfwUL8aTigDnEYxNFqpmX6y1uIo2WyO/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10737959-L.jpg" }, { "id": "javascript-effective-javascript-68-specific-ways-to-harness-the-power-of-javascript", @@ -647,7 +647,7 @@ "category": "intermediate", "edition": "", "driveUrl": "https://drive.google.com/file/d/1dTfT3r_Ds2dEGW0bx0h9YK7iMzq5bJ7g/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7265123-L.jpg" }, { "id": "javascript-exploring-javascript", @@ -657,7 +657,7 @@ "category": "intermediate", "edition": "ES2024 Edition", "driveUrl": "https://drive.google.com/file/d/1_3tn2ih0sYJkmOQ2a1SHuSNRg1zMQe6-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9710412-L.jpg" }, { "id": "javascript-the-principles-of-object-oriented-javascript", @@ -667,7 +667,7 @@ "category": "intermediate", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1vzjR18Q0iYvfPPaZxU1nG8QkHATMDbNz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8259472-L.jpg" }, { "id": "javascript-learning-javascript-javascript-essentials-for-modern-application-development", @@ -677,7 +677,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1o-FP2qw_IVXqnjDnDf1SLu9H7hD7PyYg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7443810-L.jpg" }, { "id": "javascript-clean-code-in-javascript", @@ -687,7 +687,7 @@ "category": "intermediate", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1HuJrk_QTDZBpHRriZL8Tzf0hf1b6YVCX/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10538130-L.jpg" }, { "id": "javascript-understanding-ecmascript-6", @@ -697,7 +697,7 @@ "category": "intermediate", "edition": "2016 Edition", "driveUrl": "https://drive.google.com/file/d/1sIRC5N_8JFx5QDOOjTcn_jg5GNzDJnIe/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512695-L.jpg" }, { "id": "javascript-maintainable-javascript", @@ -707,7 +707,7 @@ "category": "intermediate", "edition": "2012 Edition", "driveUrl": "https://drive.google.com/file/d/1rCykHgc1laFWnFbcs8iYFizce3dGovqu/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7268394-L.jpg" }, { "id": "javascript-high-performance-javascript", @@ -717,7 +717,7 @@ "category": "intermediate", "edition": "2010 Edition", "driveUrl": "https://drive.google.com/file/d/1Ns9j5pJN9JxDEsOBE0-qV7zObY7OnR1L/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7262408-L.jpg" }, { "id": "javascript-functional-light-javascript", @@ -727,7 +727,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/1GXX12KuEv_FqNyQy3a0pEU6w0Mlws-PN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.manning.com/360/480/resize/book/e/8f8c65f-3031-42df-9ef3-88a37113d82c/Simpson_hires.png" }, { "id": "javascript-learning-javascript-design-patterns", @@ -737,7 +737,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1W6yznBiKcXJEtdGO-r4bE4cB12N1YHYP/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7262420-L.jpg" }, { "id": "javascript-just-javascript", @@ -747,7 +747,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1iNyZ4uP6NyWxJOlDNOQAo1G9spKHx6x-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8822955-L.jpg" }, { "id": "javascript-professor-frisby-s-mostly-adequate-guide-to-functional-programming", @@ -757,7 +757,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/1QkHLENfNrpfBkdjQ2M5miqSpHrSWyDyg/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12690216-L.jpg" }, { "id": "javascript-deep-javascript-theory-and-techniques", @@ -767,7 +767,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1nXLMDa3K--8Eqnoki47UqH4sWAO2KQ78/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12561128-L.jpg" }, { "id": "javascript-secrets-of-the-javascript-ninja", @@ -777,7 +777,7 @@ "category": "advanced", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1RqzHBs-_3vxKkf3A3YCY8PBkv1huE3rO/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511696-L.jpg" }, { "id": "javascript-hands-on-javascript-high-performance", @@ -787,7 +787,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1NIZE8OGQdnrAqTqtYaBcJJ_p4yVAtkgM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/19195803482842.jpg" }, { "id": "javascript-multithreaded-javascript", @@ -797,7 +797,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1GI9qWhNyTl81wzPwl7w27hmvOLh9qfDA/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12433924-L.jpg" }, { "id": "javascript-the-road-to-react", @@ -807,7 +807,7 @@ "category": "specialized", "edition": "2025 Edition", "driveUrl": "https://drive.google.com/file/d/1YJP_hU96UPTBdr1zOvN4Q8RTTxobTsb-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9383710-L.jpg" }, { "id": "javascript-efficient-node-js-a-beyond-the-basics-guide", @@ -817,7 +817,7 @@ "category": "specialized", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1xb98X17vjQMhe0_AvioEoABruQcEt3tk/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513336-L.jpg" }, { "id": "javascript-web-development-with-node-and-express", @@ -827,7 +827,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/13u-aBTDYEEExZdewZLV1Ejytij92q0vJ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513971-L.jpg" }, { "id": "javascript-learning-react", @@ -837,7 +837,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1cFv5MXLNO83YBiYpftcHU6lxR4chkV__/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508932-L.jpg" }, { "id": "javascript-fullstack-vue", @@ -847,7 +847,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1uxzVmhe5w1GfDB3ZAgKIbAYS0IzIG5Yd/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510887-L.jpg" }, { "id": "javascript-web-security-for-developers", @@ -857,7 +857,7 @@ "category": "specialized", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1O3KspVdZxUyb4Jh-hSRia1z1Byn4KK4W/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14566977-L.jpg" }, { "id": "javascript-node-js-design-patterns", @@ -867,7 +867,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1oOnmbcRtCA8Z4fWxJPxyvsSC0gpAaRc6/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513336-L.jpg" }, { "id": "javascript-distributed-systems-with-node-js", @@ -877,7 +877,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1-kv7DoiTzvekT2ybyHB7VthGCBI7sgiD/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1604997837i/55841849.jpg" }, { "id": "javascript-node-js-cookbook", @@ -887,7 +887,7 @@ "category": "specialized", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1P-FbgwqdEzm8O73kTDyGOiHLSyIZTY1K/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510166-L.jpg" }, { "id": "javascript-learning-patterns", @@ -897,7 +897,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1un1LSZu3Vm11tpE6UxGCOE-8ZmXA-GBo/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12458319-L.jpg" }, { "id": "javascript-react-native-in-action", @@ -907,7 +907,7 @@ "category": "specialized", "edition": "2019 Edition", "driveUrl": "https://drive.google.com/file/d/1aHgS2r4TaK-hwEMnqUAA5kNA9H2TqELN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8799590-L.jpg" }, { "id": "javascript-javascript-for-data-science", @@ -917,7 +917,7 @@ "category": "specialized", "edition": "2020 Edition", "driveUrl": "https://drive.google.com/file/d/1-YmV5PoOdmBybOwTmXDAFBUeFSJpDP4M/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10737959-L.jpg" }, { "id": "javascript-generative-art-in-javascript", @@ -927,7 +927,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1IbT1hE7wiMBb4rUu7-zNlw__MxWUX4BW/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/6762893488906.jpg" }, { "id": "javascript-testing-javascript-applications", @@ -937,7 +937,7 @@ "category": "specialized", "edition": "2021 Edition", "driveUrl": "https://drive.google.com/file/d/1CFMO7b7y7rQUcEGfJ4lPqV43ics65cfy/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511714-L.jpg" }, { "id": "javascript-composing-software", @@ -947,7 +947,7 @@ "category": "specialized", "edition": "1st edition, 2018", "driveUrl": "https://drive.google.com/file/d/1-AQfWlKrcFaEL3cM16PiEYQ_n9Fyj0LZ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10018621-L.jpg" }, { "id": "javascript-real-time-3d-graphics-with-webgl-2", @@ -957,7 +957,7 @@ "category": "specialized", "edition": "2nd edition", "driveUrl": "https://drive.google.com/file/d/1TZITburqR4-c3tBOk7qBL4o7isRgPANu/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508057-L.jpg" }, { "id": "javascript-llm-engineer-s-handbook", @@ -967,7 +967,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1Yfzv4pICwMugTm11xPleiLwgR3TPePLv/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/21071403482841.jpg" }, { "id": "javascript-learn-three-js", @@ -977,7 +977,7 @@ "category": "specialized", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1IrWRQiU1Zgf2tn0solmwcgkiLLC6Bqr-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508046-L.jpg" }, { "id": "javascript-deep-learning-with-javascript", @@ -987,7 +987,7 @@ "category": "specialized", "edition": "1st edition, 2020", "driveUrl": "https://drive.google.com/file/d/1G3w7HDk3qrV4RJikxgQ5msle4eyzl3SL/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508215-L.jpg" }, { "id": "javascript-browser-machine-learning-mastery", @@ -997,7 +997,7 @@ "category": "specialized", "edition": "2025 Edition", "driveUrl": "https://books.google.com/books/about/Browser_Machine_Learning_Mastery.html?id=y-Kp0QEACAAJ", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/4582973488694.jpg" }, { "id": "javascript-black-hat-javascript-advanced-client-side-exploitation", @@ -1007,7 +1007,7 @@ "category": "specialized", "edition": "2025 Release", "driveUrl": "https://www.goodreads.com/book/show/238838848-black-hat-javascript", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/1787143488701.jpg" }, { "id": "javascript-javascript-the-definitive-guide", @@ -1017,7 +1017,7 @@ "category": "references", "edition": "7th Edition", "driveUrl": "https://drive.google.com/file/d/1ZlTJ_sVZst1Hp0o-TSQUM8DsdkpK7Ieq/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512695-L.jpg" }, { "id": "javascript-professional-javascript-for-web-developers", @@ -1027,7 +1027,7 @@ "category": "references", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1uGvyYs8Q0Pf5t3v1RGnRKawU7ond7E3K/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10724347-L.jpg" }, { "id": "javascript-javascript-es2015-enlightenment", @@ -1037,7 +1037,7 @@ "category": "references", "edition": "2025 Digital Edition", "driveUrl": "https://frontendmasters.com/guides/javascript-enlightenment/", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/252673482704.jpg" }, { "id": "javascript-javascript-allong", @@ -1047,7 +1047,7 @@ "category": "references", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1nYPIMuOO-VmPbGNj_WlxSlYim4jFb42u/view?usp=sharing", - "coverImage": "" + "coverImage": "https://d2sofvawe08yqg.cloudfront.net/javascriptallongesix/s_hero2x?1620458665" }, { "id": "javascript-javascript-the-first-20-years", @@ -1057,7 +1057,7 @@ "category": "references", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1iKIRAOUXqzpnQDdpQTx_iwTNBwcpAk8k/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10737959-L.jpg" }, { "id": "javascript-mdn-web-docs", @@ -1067,7 +1067,7 @@ "category": "references", "edition": "Living Documentation", "driveUrl": "https://developer.mozilla.org/en-US/docs/Web/JavaScript", - "coverImage": "" + "coverImage": "https://developer.mozilla.org/apple-touch-icon.png" }, { "id": "javascript-javascript-pocket-reference", @@ -1077,7 +1077,7 @@ "category": "references", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1TLqPvemKX4PaRs2zA5JN_09Vvb17BPTU/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10724321-L.jpg" }, { "id": "java-think-java", @@ -1087,7 +1087,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/12WxLCFLPzaGS9lqsITIYDtJ6_aJQYT8l/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15234055-L.jpg" }, { "id": "java-java-23-for-absolute-beginners", @@ -1097,7 +1097,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1HYoxXWOdgRGbcONJSL-8XWiIWxh3xWu2/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/6858373488906.jpg" }, { "id": "java-java-programming-from-problem-analysis-to-program-design", @@ -1107,7 +1107,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1w5wT5gp7mPmUx1b-lBjdNJIaTx8YqcWF/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7502497-L.jpg" }, { "id": "java-beginning-java-programming", @@ -1117,7 +1117,7 @@ "category": "beginner", "edition": "7th Edition - 2011", "driveUrl": "https://drive.google.com/file/d/1iGEazJOVTeACMszjqK9c7Vu4WJoceLpa/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513192-L.jpg" }, { "id": "java-head-first-java", @@ -1127,7 +1127,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1q9WOzPk3jl1MZq8jH0Ab553HYLchE0ac/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388761-L.jpg" }, { "id": "java-java-a-beginner-s-guide", @@ -1137,7 +1137,7 @@ "category": "beginner", "edition": "9th Edition", "driveUrl": "https://drive.google.com/file/d/12YW6xUFbxuQqIFk69IwIbJhxfd4BsUPU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507958-L.jpg" }, { "id": "java-learning-java", @@ -1147,7 +1147,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1gwDLRPrdqbTp5mrUUdFWiUJFdjQnBPBa/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10991044-L.jpg" }, { "id": "java-head-first-design-patterns", @@ -1157,7 +1157,7 @@ "category": "intermediate", "edition": "2nd Edition - 2020", "driveUrl": "https://drive.google.com/file/d/1nI56g93MpgofVd2YCDMYTVCg0Fv4yA5e/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388950-L.jpg" }, { "id": "java-effective-java", @@ -1167,7 +1167,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1iTI492QvudYpqeitJfNFGbpv_svNSmk5/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1176573-L.jpg" }, { "id": "java-java-cookbook", @@ -1177,7 +1177,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1dVX0IMKequlab-Y57dBkX0Oljt812XQ4/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388941-L.jpg" }, { "id": "java-refactoring-improving-the-design-of-existing-code", @@ -1187,7 +1187,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1ba9n8rsoSMMUyMrLqfZIitsgoYau_7C6/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7087623-L.jpg" }, { "id": "java-clean-code-a-handbook-of-agile-software-craftsmanship", @@ -1197,7 +1197,7 @@ "category": "intermediate", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1jAFSAsQvjG4LyKf4SBeWGmHyRckImkdR/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8065615-L.jpg" }, { "id": "java-core-java-volume-i-fundamentals", @@ -1207,7 +1207,7 @@ "category": "intermediate", "edition": "13th Edition", "driveUrl": "https://drive.google.com/file/d/1Wg4jaBfblzrkjL4XIDgvnw4aY7AM-p9E/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514927-L.jpg" }, { "id": "java-core-java-volume-ii-advanced-features", @@ -1217,7 +1217,7 @@ "category": "intermediate", "edition": "13th Edition", "driveUrl": "https://drive.google.com/file/d/1UBeNIyG0ax3F0lGFwHtNpyqO9iXDgVyE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508076-L.jpg" }, { "id": "java-the-well-grounded-java-developer", @@ -1227,7 +1227,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1pLhjwG9rYLzr3PHwaCREk_Scyrn483-y/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7505404-L.jpg" }, { "id": "java-100-java-mistakes-and-how-to-avoid-them", @@ -1237,7 +1237,7 @@ "category": "intermediate", "edition": "2023 Edition", "driveUrl": "https://drive.google.com/file/d/1QoNRXcqkdB-Yi9X4ZK0Qsu6H19d0tknq/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.manning.com/360/480/resize/book/9/9b7d008-5a11-41d3-85b4-421628c75405/Valeev-HI.png" }, { "id": "java-test-driven-development-by-example", @@ -1247,7 +1247,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1zqmpNXHIthz6HqqEG6162Oa1rZLpftLV/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508910-L.jpg" }, { "id": "java-effective-unit-testing", @@ -1257,7 +1257,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/15eohtjlEiShueNmnNiJX9FWXhUXm4IhU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8515199-L.jpg" }, { "id": "java-oracle-certified-professional-java-se-21-developer-study", @@ -1267,7 +1267,7 @@ "category": "advanced", "edition": "Official Modern Reference", "driveUrl": "https://drive.google.com/file/d/18TQlpzzIgXYg0Y6jELXUCFAvmjjk5tDw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14744205-L.jpg" }, { "id": "java-patterns-of-enterprise-application-architecture-peaa", @@ -1277,7 +1277,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1yvaVkOGWxvZXTbgWLvQXfU3L8mxTUF-D/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/192501-L.jpg" }, { "id": "java-java-concurrency-in-practice", @@ -1287,7 +1287,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1JEkaIZsE2iG0ea6-6nk9VGwzG0tHKX0a/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7069893-L.jpg" }, { "id": "java-agile-software-development-principles-patterns-and-practices", @@ -1297,7 +1297,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://www.oreilly.com/library/view/agile-software-development/0135974445/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/91081-L.jpg" }, { "id": "java-java-performance-in-depth-advice-for-tuning-and-optimization", @@ -1307,7 +1307,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1k2MPlfWezaw7spPbCiCxf1ln8QIbIOXG/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514235-L.jpg" }, { "id": "java-modern-java-in-action", @@ -1317,7 +1317,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1sO6NWk89jc-_5xXbCwyl7f0qqX2l2p4b/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508261-L.jpg" }, { "id": "java-java-puzzlers-traps-pitfalls-and-corner-cases", @@ -1327,7 +1327,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1NvtCmqNS270XmtOjtUuPU55CqLvEgFSK/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8680254-L.jpg" }, { "id": "java-release-it-design-and-deploy-production-ready-software", @@ -1337,7 +1337,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1KzGpznPxWJFKrxtJbAQIR6Pr0GvYq0G_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/743624-L.jpg" }, { "id": "java-design-patterns-elements-of-reusable-object-oriented-software", @@ -1347,7 +1347,7 @@ "category": "advanced", "edition": "1994 edition", "driveUrl": "https://en.wikipedia.org/wiki/Design_Patterns", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13750918-L.jpg" }, { "id": "java-java-performance-companion", @@ -1357,7 +1357,7 @@ "category": "specialized", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/10nMOO0E_LCEpb-IRnrABJMkEq-46ntR6/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513032-L.jpg" }, { "id": "java-java-memory-management", @@ -1367,7 +1367,7 @@ "category": "specialized", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1KVVgtKCjVILnPW-H6vOPs9mobEiO0xID/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/14228653482829.jpg" }, { "id": "java-spring-boot-in-practice", @@ -1377,7 +1377,7 @@ "category": "specialized", "edition": "2022 Edition", "driveUrl": "https://drive.google.com/file/d/15p73C6avjiFS5VwIf2g9a0rKxuzAx9gR/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13530056-L.jpg" }, { "id": "java-spring-in-action", @@ -1387,7 +1387,7 @@ "category": "specialized", "edition": "6th Edition", "driveUrl": "https://drive.google.com/file/d/1e-gRL-z2JlTRmSJ4c17mgTUFgurl_cqe/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8722096-L.jpg" }, { "id": "java-optimizing-cloud-native-java", @@ -1397,7 +1397,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1Amh1f_WCTCFIdiD9P9xaPHKgEzC6X1SQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1718922036i/210408984.jpg" }, { "id": "java-spring-security-in-action", @@ -1407,7 +1407,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/11I4zGm0Fye0cu_Elsg7iCacab_R5JkOx/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13276048-L.jpg" }, { "id": "java-designing-data-intensive-applications", @@ -1417,7 +1417,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1T1dffFshpson2EsHIxfoGuYdb4BJ6vpg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8434671-L.jpg" }, { "id": "java-test-driven-java-development", @@ -1427,7 +1427,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1ofKqwv0JNkvcuB-1uatTNKGnQ7__wSfJ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508911-L.jpg" }, { "id": "java-java-persistence-with-spring-data-and-hibernate", @@ -1437,7 +1437,7 @@ "category": "specialized", "edition": "2023 Edition", "driveUrl": "https://drive.google.com/file/d/1b7BBQI2S59yL6ZKNM4zQTHN_cSCLuf0x/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12550182-L.jpg" }, { "id": "java-building-modern-web-apps-with-spring-boot-and-vaadin", @@ -1447,7 +1447,7 @@ "category": "specialized", "edition": "2025 Guide", "driveUrl": "https://pages.vaadin.com/en/build-a-modern-web-app-with-spring-boot-vaadin-pdf", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/7285733488719.jpg" }, { "id": "java-quarkus-in-action", @@ -1457,7 +1457,7 @@ "category": "specialized", "edition": "1st Edition - 2025", "driveUrl": "https://drive.google.com/file/d/1dSOkdgYGizQoV88kCbSLk9-X1pCu3YDp/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.manning.com/360/480/resize/book/6/35a97a2-f353-48df-8f9f-bf09d5d3f0be/DOTD_Stefanko.png" }, { "id": "java-the-java-language-specification", @@ -1467,7 +1467,7 @@ "category": "specialized", "edition": "Java SE 19 Edition", "driveUrl": "https://drive.google.com/file/d/1dNz2rhQ89eYcrvoqd9VWdBD_qbBSwCnz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135604-L.jpg" }, { "id": "java-spring-microservices-in-action", @@ -1477,7 +1477,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1qfgjmGruyZre1Z7pt7F5u6ApFXFQgfVU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508871-L.jpg" }, { "id": "java-high-performance-java-persistence", @@ -1487,7 +1487,7 @@ "category": "specialized", "edition": "New Edition", "driveUrl": "https://drive.google.com/file/d/1XWmZbXC2c7HpSvkp5XZ5Cy6YWUlqQYwM/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14098277-L.jpg" }, { "id": "java-junit-in-action", @@ -1497,7 +1497,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1Pnv6bQUlfIAK8M2DgfnUlzg2XRHZmesq/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/954564-L.jpg" }, { "id": "java-the-art-of-multiprocessor-programming", @@ -1507,7 +1507,7 @@ "category": "references", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/168IKLmFzRpiaVvRA5lHXvTMXc8g_rYTf/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/2320484-L.jpg" }, { "id": "java-modern-concurrency-in-java-virtual-threads-structured-concurrency-and-beyond", @@ -1517,7 +1517,7 @@ "category": "references", "edition": "2025 Release", "driveUrl": "https://drive.google.com/file/d/1yHaxb6huZpRhDbe5bywR8VIwNziu1n4k/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15169414-L.jpg" }, { "id": "java-java-structured-concurrency", @@ -1527,7 +1527,7 @@ "category": "references", "edition": "2025 Edition", "driveUrl": "https://www.packtpub.com/en-us/product/java-structured-concurrency-9781806105038", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15169414-L.jpg" }, { "id": "java-virtual-threads-structured-concurrency-and-scoped-values", @@ -1537,7 +1537,7 @@ "category": "references", "edition": "2024 Edition", "driveUrl": "https://drive.google.com/file/d/1celv84qkw8DPFHo8EZegSN8i3yzO8y3i/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1721275588i/214102078.jpg" }, { "id": "java-mastering-java-concurrency-threads-synchronization-and-parallel-processing", @@ -1547,7 +1547,7 @@ "category": "references", "edition": "2025 Edition", "driveUrl": "https://www.amazon.com/Mastering-Java-Concurrency-Synchronization-Processing-ebook/dp/B0DHTKSQJQ", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508777-L.jpg" }, { "id": "java-java-the-complete-reference", @@ -1557,7 +1557,7 @@ "category": "references", "edition": "13th Edition", "driveUrl": "https://drive.google.com/file/d/1auXGujIKKFyw0WU9xB07LyX4Oz2h_yPb/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13660534-L.jpg" }, { "id": "java-java-in-a-nutshell", @@ -1567,7 +1567,7 @@ "category": "references", "edition": "8th Edition", "driveUrl": "https://drive.google.com/file/d/1qIPTpVltTi02m6QdRvynIDtgr0HVE80n/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/805638-L.jpg" }, { "id": "java-java-pocket-guide", @@ -1577,7 +1577,7 @@ "category": "references", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/11F1OMndhAHvHTLXDd2HbU4KvLk2JZtWt/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514237-L.jpg" }, { "id": "csharp-head-first-c", @@ -1587,7 +1587,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/136qGvMKTc6sU_p5BoC059BYDOA40DTAY/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8657991-L.jpg" }, { "id": "csharp-essential-c-12-0", @@ -1597,7 +1597,7 @@ "category": "beginner", "edition": "8th Edition", "driveUrl": "https://drive.google.com/file/d/1YuMTOO4spmi2fZ8Da_Lo2uFws7refkRS/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/5081903482237.jpg" }, { "id": "csharp-c-13-and-net-9-modern-cross-platform-development-fundamentals", @@ -1607,7 +1607,7 @@ "category": "beginner", "edition": "9th Edition - 2024", "driveUrl": "https://drive.google.com/file/d/1C_KFBNQQHAdcsnx5xYtH4SkdnXOxgrNb/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/17882853482841.jpg" }, { "id": "csharp-c-14-and-net-10-modern-cross-platform-development-fundamentals", @@ -1617,7 +1617,7 @@ "category": "beginner", "edition": "10th Edition - 2025", "driveUrl": "https://www.oreilly.com/library/view/c-14-and/9781836206637/", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1757673049i/241538810.jpg" }, { "id": "csharp-the-c-player-s-guide", @@ -1627,7 +1627,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1WJ-FnkSbmiPaBKuEnQs3sDR7G5pSWP7R/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11245685-L.jpg" }, { "id": "csharp-learn-c-sharp", @@ -1637,7 +1637,7 @@ "category": "beginner", "edition": "2025 Edition", "driveUrl": "https://books.google.com/books/about/LEARN_C_2025_Edition.html?id=PS47EQAAQBAJ", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/10026183482726.jpg" }, { "id": "csharp-illustrated-c", @@ -1647,7 +1647,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1HuGFTlncXsmJv-s2YJ0KPrH8lOgMMpZy/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1971120-L.jpg" }, { "id": "csharp-c-in-depth", @@ -1657,7 +1657,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1Hb38MBdK_Bh8k1J10QBpWYGl_mzVUuSU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/3063781-L.jpg" }, { "id": "csharp-effective-c", @@ -1667,7 +1667,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/14d4FYI3Wcm9_LQ20IO0uCo6ivp89J6aZ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/193238-L.jpg" }, { "id": "csharp-concurrency-in-c-cookbook", @@ -1677,7 +1677,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1hg-dVHC4KuQLWBWkRfYtdjO7O3CCdIod/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11523113-L.jpg" }, { "id": "csharp-unit-testing-principles-practices-and-patterns", @@ -1687,7 +1687,7 @@ "category": "intermediate", "edition": "2020 Edition", "driveUrl": "https://drive.google.com/file/d/1Lv1UGiFBcxAb-i8kv5oaryyjZx7AN28x/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14572001-L.jpg" }, { "id": "csharp-pro-asp-net-core-6", @@ -1697,7 +1697,7 @@ "category": "intermediate", "edition": "9th Edition", "driveUrl": "https://drive.google.com/file/d/1w8qf77yV5ym7_4ocp1-chph_W13B54GU/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11592216-L.jpg" }, { "id": "csharp-pro-c-10-with-net-6", @@ -1707,7 +1707,7 @@ "category": "intermediate", "edition": "11th Edition", "driveUrl": "https://drive.google.com/file/d/1OaBsJv0ddWMGXXQAmGQ1dSFl3BfS6cBp/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/12581163482716.jpg" }, { "id": "csharp-clean-code-in-c", @@ -1717,7 +1717,7 @@ "category": "intermediate", "edition": "2020 Edition", "driveUrl": "https://drive.google.com/file/d/13dz9fR_h1wQDJJgwjP-8H59-nO-7YOQW/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13911930-L.jpg" }, { "id": "csharp-software-architecture-with-c-12-and-net-8", @@ -1727,7 +1727,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1jZaFFn4_qIQsz5d9nmEKpRI5rnPUQiK-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/19238863482830.jpg" }, { "id": "csharp-pragmatic-microservices-with-c-and-azure", @@ -1737,7 +1737,7 @@ "category": "intermediate", "edition": "2024 Release", "driveUrl": "https://drive.google.com/file/d/1b3wLWqNhjiw9p1HGvOWQ2zMP1LBCHG6B/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1718913311i/209810525.jpg" }, { "id": "csharp-pro-net-memory-management", @@ -1747,7 +1747,7 @@ "category": "advanced", "edition": "2nd edition", "driveUrl": "https://drive.google.com/file/d/1kEzxEZ_5taHWLD00k5DXeOqKDxyNr4N8/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508223-L.jpg" }, { "id": "csharp-writing-high-performance-net-code", @@ -1757,7 +1757,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1dQHCqAGkhSRj0X4oS-MhBXYXHXZfMFBp/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508936-L.jpg" }, { "id": "csharp-more-effective-c-50-specific-ways-to-improve-your-c", @@ -1767,7 +1767,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/13qxXSKIldJv2_DJ_DZ8aJWr8sGo7hoZI/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511863-L.jpg" }, { "id": "csharp-xunit-test-patterns-refactoring-test-code", @@ -1777,7 +1777,7 @@ "category": "advanced", "edition": "2007 Edition", "driveUrl": "https://drive.google.com/file/d/1DK8MCJy8l0XJFWgNRJYncPjDw789V0b_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/87720-L.jpg" }, { "id": "csharp-clr-via-c", @@ -1787,7 +1787,7 @@ "category": "advanced", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1r-J9sbVlaUI0pSUE7PYB7246ny-AySzg/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8629217-L.jpg" }, { "id": "csharp-framework-design-guidelines-conventions-idioms-and-patterns-for-reusable-net-lib", @@ -1797,7 +1797,7 @@ "category": "advanced", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1WMBOFyNCSMf59IPeOm_0dIrhoB6iX-aj/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/193267-L.jpg" }, { "id": "csharp-the-art-of-unit-testing", @@ -1807,7 +1807,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/13Nxds-pL6Fg-Lif-Sd-xZwMJrEXDgk0p/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6386613-L.jpg" }, { "id": "csharp-adaptive-code-agile-coding-with-design-patterns-and-solid-principles", @@ -1817,7 +1817,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1pMo5PKi5E8AtZEngURw8vzjTtDt3KJ8b/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10242512-L.jpg" }, { "id": "csharp-dependency-injection-principles-practices-and-patterns", @@ -1827,7 +1827,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/16cPDfWX5f2rCIJfidvoTcno7wddfti9c/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507526-L.jpg" }, { "id": "csharp-clean-architecture-a-craftsman-s-guide-to-software-structure-and-design", @@ -1837,7 +1837,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1mlpGfuUPmPq3MDAKaVlpnYoDqDrJs7P4/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8605114-L.jpg" }, { "id": "csharp-architecting-modern-web-applications-with-asp-net-core-and-azure", @@ -1847,7 +1847,7 @@ "category": "specialized", "edition": "Edition - 2022", "driveUrl": "https://drive.google.com/file/d/1gWmpoqgg5L178-g2YpnoVsFmnMR7C0jH/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/4544553482825.jpg" }, { "id": "csharp-building-ai-applications-with-microsoft-semantic-kernel", @@ -1857,7 +1857,7 @@ "category": "specialized", "edition": "2024 Release", "driveUrl": "https://drive.google.com/file/d/1e8AtxOcnxiaBW40axnI3GS-xd2qvLsqI/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1718935906i/211827729.jpg" }, { "id": "csharp-web-development-with-blazor", @@ -1867,7 +1867,7 @@ "category": "specialized", "edition": "3rd Edition - Updated for .NET 9", "driveUrl": "https://drive.google.com/file/d/1EwK-Jxecv7-xTvVR-GZsU8kaQ2GzGasN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13711958-L.jpg" }, { "id": "csharp-net-internals-cookbook", @@ -1877,7 +1877,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://www.goodreads.com/book/show/45724176-net-internals-cookbook", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1677890377i/71775579.jpg" }, { "id": "csharp-unity-in-action", @@ -1887,7 +1887,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1YwwWXEcsUGCNa1U262VqGroRhCaCWUYM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8950705-L.jpg" }, { "id": "csharp-asp-net-core-in-action", @@ -1897,7 +1897,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/16NS1iVatak_dfrXA0ziSl7cVdy_DGWWH/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508781-L.jpg" }, { "id": "csharp-entity-framework-core-in-action", @@ -1907,7 +1907,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1L04I5D4b6vZJwymZ5jDoSk1XRqaA2var/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508575-L.jpg" }, { "id": "csharp-microservices-in-net-core", @@ -1917,7 +1917,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1sGDxI8N22zErgOzhFUGB8t4_cRCF0yEn/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508579-L.jpg" }, { "id": "csharp-asp-net-core-architecture-microsoft-docs", @@ -1927,7 +1927,7 @@ "category": "references", "edition": "", "driveUrl": "https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12056174-L.jpg" }, { "id": "csharp-c-12-in-a-nutshell-the-definitive-reference", @@ -1937,7 +1937,7 @@ "category": "references", "edition": "2023 Edition", "driveUrl": "https://drive.google.com/file/d/13or6QeIIosQcKZGIGoGE7M2Ki0TDeZ5d/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1697850369i/195616085.jpg" }, { "id": "csharp-functional-programming-in-c", @@ -1947,7 +1947,7 @@ "category": "references", "edition": "6th early release - 2024 Edition", "driveUrl": "https://drive.google.com/file/d/1o-BwSGn2l8tXFiRYOoCGxHGS263pItm3/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8651949-L.jpg" }, { "id": "csharp-programming-c-12", @@ -1957,7 +1957,7 @@ "category": "references", "edition": "2024 Edition", "driveUrl": "https://drive.google.com/file/d/1LQCi_6puixk5lUEG4kJO90N-q0Men6Xa/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/192602-L.jpg" }, { "id": "csharp-c-12-pocket-reference", @@ -1967,7 +1967,7 @@ "category": "references", "edition": "2023 Edition", "driveUrl": "https://drive.google.com/file/d/12L3Ktd2UTVrpnrQzyqQgEY6WXSvuULnj/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/27108873482578.jpg" }, { "id": "c-c-programming-a-modern-approach", @@ -1977,7 +1977,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1_RX40f3AH4aZSgcQ7pydFdvDD-BIpaC4/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/762861-L.jpg" }, { "id": "c-head-first-c", @@ -1987,7 +1987,7 @@ "category": "beginner", "edition": "", "driveUrl": "https://drive.google.com/file/d/1KNHMFJp6Czqlqj9RpQw4dvXRwlAS90t6/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8657989-L.jpg" }, { "id": "c-the-c-programming-language", @@ -1997,7 +1997,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1uZglJUCeolG1Gr3qpDKNvhIEnKPC5TlI/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6684943-L.jpg" }, { "id": "c-c-programming-absolute-beginner-s-guide", @@ -2007,7 +2007,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1cyrNNWy-BJJfyhhtYaDUR5fkWtNVHFTb/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9403400-L.jpg" }, { "id": "c-c-primer-plus", @@ -2017,7 +2017,7 @@ "category": "beginner", "edition": "6th Edition", "driveUrl": "https://drive.google.com/file/d/1SFQaL3S0fS1d0xhzXtIP21mRLcIvZtls/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/3879532-L.jpg" }, { "id": "c-learn-c-the-hard-way", @@ -2027,7 +2027,7 @@ "category": "intermediate", "edition": "2015 Edition", "driveUrl": "https://drive.google.com/file/d/1KluQxU8LCMQpfEVLOkNDwndMZSU2AGGG/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10637675-L.jpg" }, { "id": "c-understanding-and-using-c-pointers", @@ -2037,7 +2037,7 @@ "category": "intermediate", "edition": "2013 Edition", "driveUrl": "https://drive.google.com/file/d/1pKq8N5EaOl3H_BaZW61Tae6Ibk3deuXz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8515134-L.jpg" }, { "id": "c-modern-c", @@ -2047,7 +2047,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/150CoeAbvVpM51AfY2i6F0MSE1gzn1ndQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10183812-L.jpg" }, { "id": "c-low-level-programming", @@ -2057,7 +2057,7 @@ "category": "intermediate", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1A8DcvSW573IZmB7fdgZm0pIqjyoo6ORC/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510171-L.jpg" }, { "id": "c-intermediate-c-programming", @@ -2067,7 +2067,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1TT4ZbKAT29Lzup2hFLUyt3zLhB-ap-9X/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10296514-L.jpg" }, { "id": "c-c23-standard-iso-iec-9899-2024", @@ -2077,7 +2077,7 @@ "category": "advanced", "edition": "Edition 5, 2024", "driveUrl": "https://www.open-std.org/jtc1/sc22/wg14/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11925036-L.jpg" }, { "id": "c-the-standard-c-library", @@ -2087,7 +2087,7 @@ "category": "advanced", "edition": "First & only edition", "driveUrl": "https://drive.google.com/file/d/1MWm8vrEb3mhj5b-N2U2vM9wXQYvvUcAV/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/86831-L.jpg" }, { "id": "c-c-interfaces-and-implementations", @@ -2097,7 +2097,7 @@ "category": "advanced", "edition": "1994 Edition", "driveUrl": "https://drive.google.com/file/d/1QmZtbqY_tS7RUtMWXsMDboY2lxkJUJJX/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135017-L.jpg" }, { "id": "c-21st-century-c", @@ -2107,7 +2107,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1tpW5GjrvJe1VyXR82DDKhOLkz_lj22sa/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513615-L.jpg" }, { "id": "c-effective-c-an-introduction-to-professional-c-programming", @@ -2117,7 +2117,7 @@ "category": "advanced", "edition": "2020 Release", "driveUrl": "https://drive.google.com/file/d/14kFQJ7kX_xC2UYqV8Tgegc7UgmySKI4i/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/193724-L.jpg" }, { "id": "c-expert-c-programming-deep-c-secrets", @@ -2127,7 +2127,7 @@ "category": "advanced", "edition": "1994 Edition", "driveUrl": "https://drive.google.com/file/d/13ZGiz-umwxXek9tmBBJ5vDtHl9DMmdi8/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/88161-L.jpg" }, { "id": "c-tcp-ip-illustrated-volume-1-the-protocols", @@ -2137,7 +2137,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1gLmOJOSl9lCKpcQIFgipsUcqAJqpncb_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135567-L.jpg" }, { "id": "c-embedded-c-coding-standard", @@ -2147,7 +2147,7 @@ "category": "specialized", "edition": "2018 Edition", "driveUrl": "https://drive.google.com/file/d/1OjNppXo7wpbi-Cl5L1ZfGlf9J4s7aHuC/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7748895-L.jpg" }, { "id": "c-extreme-c-taking-the-c-language-to-its-limits", @@ -2157,7 +2157,7 @@ "category": "specialized", "edition": "2019 Release", "driveUrl": "https://drive.google.com/file/d/1x4rbRQ8Xlk2WSPJmk3q1p8cNMuDIKz7w/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/2799953-L.jpg" }, { "id": "c-advanced-programming-in-the-unix-environment", @@ -2167,7 +2167,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/11KXWp5hxwP069hV_R72RczldHHAtG3CE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135189-L.jpg" }, { "id": "c-the-linux-programming-interface", @@ -2177,7 +2177,7 @@ "category": "specialized", "edition": "2010 Release", "driveUrl": "https://drive.google.com/file/d/1kr5vcH6ImAW_ZjiEuJbMcDJcn0vQn6Cc/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6463752-L.jpg" }, { "id": "c-making-embedded-systems", @@ -2187,7 +2187,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1Di-Lio4NaBAZcv206D2c3Lw4QR4DWOsM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7643570-L.jpg" }, { "id": "c-computer-systems-a-programmer-s-perspective", @@ -2197,7 +2197,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/11p_XI3UEY5Dps0_A0I1Ou4sbBYDsLG05/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511531-L.jpg" }, { "id": "c-programming-embedded-systems-in-c", @@ -2207,7 +2207,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1xTBJiMYTA--pbFGiW41G26SJ9gOQePSg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/805738-L.jpg" }, { "id": "c-hands-on-network-programming-with-c", @@ -2217,7 +2217,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1FHCAB2Ox8Jelioa7uK9HLq0ovvkDBCcE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10653286-L.jpg" }, { "id": "c-linux-kernel-development", @@ -2227,7 +2227,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1NxEeBNOV11BI1LuPDaVXPThLsJltfY02/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/410921-L.jpg" }, { "id": "c-the-art-of-debugging-with-gdb-ddd-and-eclipse", @@ -2237,7 +2237,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1LYBjxn9hSQmu7TqPEEDTT5qGs6qMfVjL/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15095644-L.jpg" }, { "id": "c-introduction-to-high-performance-computing-for-scientists-and-engineers", @@ -2247,7 +2247,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1Cx450Eu8x9X6Nfor2gaeLuyRbEl5xJBn/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9593439-L.jpg" }, { "id": "c-c-in-a-nutshell", @@ -2257,7 +2257,7 @@ "category": "references", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1JNOX-OHCjTq6VP712BKJba3zq2wEsL0b/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8629281-L.jpg" }, { "id": "c-beej-s-guide-to-c-programming", @@ -2267,7 +2267,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://beej.us/guide/bgc/", - "coverImage": "" + "coverImage": "https://beej.us/guide/favicon.gif" }, { "id": "cpp-c-primer", @@ -2277,7 +2277,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/12jdDj0WcFLwnSkSGy1y9eAkcF81UwKqg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135999-L.jpg" }, { "id": "cpp-programming-principles-and-practice-using-c", @@ -2287,7 +2287,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1dE4BXb4RvcJd3Ve1gCpATUjMf17X8b4a/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514159-L.jpg" }, { "id": "cpp-starting-out-with-c-from-control-structures-through-objects", @@ -2297,7 +2297,7 @@ "category": "beginner", "edition": "10th Edition", "driveUrl": "https://drive.google.com/file/d/1NLM9okwAtcCPd85vr4B4YzGAtsuUk03O/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/2383716-L.jpg" }, { "id": "cpp-c-for-dummies", @@ -2307,7 +2307,7 @@ "category": "beginner", "edition": "7th Edition", "driveUrl": "https://drive.google.com/file/d/10uZ7vzYpzYorDAF1nqZcRnVuMZ0wBnUB/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6441511-L.jpg" }, { "id": "cpp-effective-c", @@ -2317,7 +2317,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1WNJxLYF0vCYjtQR0RzmrRSqT3jj2KYLK/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/193724-L.jpg" }, { "id": "cpp-professional-c", @@ -2327,7 +2327,7 @@ "category": "intermediate", "edition": "*6th Edition - 2024*", "driveUrl": "https://www.wiley.com/en-us/Professional+C%2B%2B%2C+6th+Edition-p-9781394217199", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513807-L.jpg" }, { "id": "cpp-c-core-guidelines-explained", @@ -2337,7 +2337,7 @@ "category": "intermediate", "edition": "", "driveUrl": "https://www.pearson.com/en-us/subject-catalog/p/c-core-guidelines-explained-best-practices-for-modern-c/P200000009536/", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/19729673482236.jpg" }, { "id": "cpp-a-tour-of-c", @@ -2347,7 +2347,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1LAppZ_ax6b9Ia32VgKanCHfeN85zAlPd/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514498-L.jpg" }, { "id": "cpp-the-c-programming-language", @@ -2357,7 +2357,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1-xjwSQI9zqn8ffkfVQs4eSgN74RRLXPc/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6684943-L.jpg" }, { "id": "cpp-c-crash-course", @@ -2367,7 +2367,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1vscPmCSjXSzwVohgZPpFwKW1zpj2T4MW/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10458066-L.jpg" }, { "id": "cpp-100-c-mistakes-and-how-to-avoid-them", @@ -2377,7 +2377,7 @@ "category": "intermediate", "edition": "2025 Edition", "driveUrl": "https://drive.google.com/file/d/1_ym2s8PFLtwnYC3BXnO0VKgw6Cop6RNd/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1585242654i/52719099.jpg" }, { "id": "cpp-c-concurrency-in-action", @@ -2387,7 +2387,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1K-iQpqmFMkYZykytjQfoe1Ha9qwbftEL/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507812-L.jpg" }, { "id": "cpp-c-templates-the-complete-guide", @@ -2397,7 +2397,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1oStqlWCvpPby0BGhDXe4csJ610GDMTsT/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510062-L.jpg" }, { "id": "cpp-expert-c-programming", @@ -2407,7 +2407,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/158N5zEbqhUg8i7GRcpJjMslNtXgxY0KB/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/88161-L.jpg" }, { "id": "cpp-hands-on-design-patterns-with-c", @@ -2417,7 +2417,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1y7cZf8IsRCmhoOBVm8PkXgy33P6wJ9m3/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508514-L.jpg" }, { "id": "cpp-hands-on-machine-learning-with-c", @@ -2427,7 +2427,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1G2Uvpi9hNrNeazzMLW6nkJLHeW3ADsiI/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508581-L.jpg" }, { "id": "cpp-beginning-c-game-programming", @@ -2437,7 +2437,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1RHB_5HAdC_Cp-0xUCKpLuuaQpRVOWvu8/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512597-L.jpg" }, { "id": "cpp-hands-on-gui-programming-with-c-and-qt5", @@ -2447,7 +2447,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1pwegPypib9vd_NcEOjafVUNiBp3qxDbP/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508908-L.jpg" }, { "id": "cpp-mastering-the-c-17-stl", @@ -2457,7 +2457,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/17pfQwqGjbqfPvtb8M0jrmyIdDq24rxIV/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509960-L.jpg" }, { "id": "cpp-the-c-standard-library-a-tutorial-and-reference", @@ -2467,7 +2467,7 @@ "category": "references", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/19BD-BOKEZNsqXKtozVzA_dGkZMron0Qx/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/134618-L.jpg" }, { "id": "cpp-c-pocket-reference", @@ -2477,7 +2477,7 @@ "category": "references", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1aDURg39oCc1zuME_JZL730IoFGNdyKs4/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13819416-L.jpg" }, { "id": "typescript-learning-typescript", @@ -2487,7 +2487,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1RB5XMfQEVhfjNPNw6yxpLHwSlSfmnbY5/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13413737-L.jpg" }, { "id": "typescript-typescript-quickly", @@ -2497,7 +2497,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/11KxULpStEskCTr4FJszGUx9qV1TY4AOw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13662791-L.jpg" }, { "id": "typescript-essential-typescript-5", @@ -2507,7 +2507,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1EMmIEPtq4WN03-jd93kz6qhwiYk0vOQe/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.manning.com/360/480/resize/book/e/3600273-6497-431c-9e37-45303b3becc3/Freeman2-HI.png" }, { "id": "typescript-the-typescript-handbook", @@ -2517,7 +2517,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://www.typescriptlang.org/docs/handbook/intro.html", - "coverImage": "" + "coverImage": "https://www.typescriptlang.org/icons/icon-48x48.png?v=8944a05a8b601855de116c8a56d3b3ae" }, { "id": "typescript-effective-typescript", @@ -2527,7 +2527,7 @@ "category": "intermediate", "edition": "", "driveUrl": "https://drive.google.com/file/d/1X4Nyrf-xnGUteyVhvu-_-K-X1o_6r9UW/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10677564-L.jpg" }, { "id": "typescript-programming-typescript", @@ -2537,7 +2537,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1fVWQSsrgFPqdWboebSLCBmLwG0f-WAW3/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10312489-L.jpg" }, { "id": "typescript-mastering-typescript", @@ -2547,7 +2547,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1gGTqSjyMasbC5AtV6qPf8-upEVGNh3L-/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13250283-L.jpg" }, { "id": "typescript-tackling-typescript", @@ -2557,7 +2557,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1zagInA-YXWuNuWpwryNPrxZ-X5bPo5VV/view?usp=sharing", - "coverImage": "" + "coverImage": "https://www.typescriptlang.org/icons/icon-48x48.png?v=8944a05a8b601855de116c8a56d3b3ae" }, { "id": "typescript-advanced-typescript-programming-projects", @@ -2567,7 +2567,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1hkPnebqoCNfPBg3OvfyZ_xJeHP0nvsf5/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13216522-L.jpg" }, { "id": "typescript-typescript-design-patterns", @@ -2577,7 +2577,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/15QfYUiO4bClWPa0jlOBSxAYwxZZyKK9J/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512612-L.jpg" }, { "id": "typescript-fullstack-react-with-typescript", @@ -2587,7 +2587,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1sfINkiFKuVGmRKIP6YvV3bCA6CutZ2mM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13175856-L.jpg" }, { "id": "typescript-node-js-design-patterns", @@ -2597,7 +2597,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1VALBli8K9_ZPgfnoRfDzhocIcbvmpPPz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513336-L.jpg" }, { "id": "typescript-angular-development-with-typescript", @@ -2607,7 +2607,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1JiDMygUGpuLIpGjeLE9e1VI6MMWkB7V3/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8799607-L.jpg" }, { "id": "typescript-pro-angular", @@ -2617,7 +2617,7 @@ "category": "specialized", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/11-QJl9cDqXap-qBlkAvu6NBfh5iBCzPz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512224-L.jpg" }, { "id": "typescript-typescript-deep-dive", @@ -2627,7 +2627,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://basarat.gitbook.io/typescript/", - "coverImage": "" + "coverImage": "https://basarat.gitbook.io/typescript/~gitbook/ogimage/-LxQ3jd_Z3snLZ7ef2c3" }, { "id": "typescript-typescript-weekly", @@ -2637,7 +2637,7 @@ "category": "references", "edition": "Newsletter/Reference", "driveUrl": "https://www.typescript-weekly.com/", - "coverImage": "" + "coverImage": "https://www.typescript-weekly.com/images/typescript-weekly-email-preview-958x1078@2x.png" }, { "id": "typescript-utility-types-reference", @@ -2647,7 +2647,7 @@ "category": "references", "edition": "Official Reference", "driveUrl": "https://www.typescriptlang.org/docs/handbook/utility-types.html", - "coverImage": "" + "coverImage": "https://www.typescriptlang.org/icons/icon-48x48.png?v=8944a05a8b601855de116c8a56d3b3ae" }, { "id": "go-the-go-programming-language", @@ -2657,7 +2657,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1u4q3ykHUxlwxrDBN9tyCoZaSzjJ7_8RN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7427319-L.jpg" }, { "id": "go-learning-go", @@ -2667,7 +2667,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1QenR-5Oj8sqk0d89enT9wZZsleLu13Df/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11872181-L.jpg" }, { "id": "go-head-first-go", @@ -2677,7 +2677,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1xWd4eyqz_7T341W77naEltuDw6rgd3mW/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508608-L.jpg" }, { "id": "go-get-programming-with-go", @@ -2687,7 +2687,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1BTvPt7YDQF8XgR-YtU8S5cFTppsWVW0_/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508174-L.jpg" }, { "id": "go-go-in-action", @@ -2697,7 +2697,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1J3ZfepWnOw39BpjWlnOXHU7MPFbPd-zi/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10678342-L.jpg" }, { "id": "go-concurrency-in-go", @@ -2707,7 +2707,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1rdB_l3_Jm-SPHenMKF0KLCTd8SQ4GUwj/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510272-L.jpg" }, { "id": "go-mastering-go", @@ -2717,7 +2717,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1J4QcnUrF7LVIeeGtQlUGM5wXrgmEcDC3/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508880-L.jpg" }, { "id": "go-go-programming-cookbook", @@ -2727,7 +2727,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1HFnAUXW-_NkIou9evJUh3HX7JAt_t4He/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508549-L.jpg" }, { "id": "go-go-in-practice", @@ -2737,7 +2737,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1dwQ8BZIHzAJsOpmCowBRNhFDju1RFh8O/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512680-L.jpg" }, { "id": "go-designing-data-intensive-applications", @@ -2747,7 +2747,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/19G8U2Yx1XZOnyl-0tcPrSL2yjUXake7J/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8434671-L.jpg" }, { "id": "go-cloud-native-go", @@ -2757,7 +2757,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/171ZeP-RMQRDVT8mdBAzZiNpnB2mXfkzu/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13205789-L.jpg" }, { "id": "go-network-programming-with-go", @@ -2767,7 +2767,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1J6FcdLAhVvdGA08PmEKP1jyVjrAchhry/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511918-L.jpg" }, { "id": "go-100-go-mistakes-and-how-to-avoid-them", @@ -2777,7 +2777,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1pZCiQxWCQJN7qRfoHmBREQBtwzpesg1R/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14709754-L.jpg" }, { "id": "go-let-s-go", @@ -2787,7 +2787,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1nwvxTD7SxHUCKKSBJn2HEwsg0f8R7pwP/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7347376-L.jpg" }, { "id": "go-let-s-go-further", @@ -2797,7 +2797,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1eBwXCyKKOnN94vawC-GXtW5iZNs6jT3l/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1677887058i/70955004.jpg" }, { "id": "go-black-hat-go", @@ -2807,7 +2807,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/19MikaztAUtBXsn-oCEoxPzO9szsNguqk/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11872212-L.jpg" }, { "id": "go-writing-an-interpreter-in-go", @@ -2817,7 +2817,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1pnoYA-LvaXZWAPkGpgdO6gnfwmSSv-F0/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10539137-L.jpg" }, { "id": "go-official-go-documentation", @@ -2827,7 +2827,7 @@ "category": "references", "edition": "", "driveUrl": "https://go.dev/doc/", - "coverImage": "" + "coverImage": "https://go.dev/doc/gopher/gopherbelly300.jpg" }, { "id": "go-go-standard-library-cookbook", @@ -2837,7 +2837,7 @@ "category": "references", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1_VBBGh5PhrSdmYemSOxk7sfOtUOHTeAa/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508549-L.jpg" }, { "id": "rust-the-rust-programming-language", @@ -2847,7 +2847,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1EMwXxNDPLMugxczR1KsSakNTxCDlxFgm/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508621-L.jpg" }, { "id": "rust-programming-rust", @@ -2857,7 +2857,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1YPjM92aviYus1ZngUdvW72dLpxtbYIVv/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15114618-L.jpg" }, { "id": "rust-rust-by-example", @@ -2867,7 +2867,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://doc.rust-lang.org/rust-by-example/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509109-L.jpg" }, { "id": "rust-beginning-rust", @@ -2877,7 +2877,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/15Smb7lVBLcjdAUDY0oYbV7xuvRPq22E3/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10178905-L.jpg" }, { "id": "rust-rust-for-rustaceans", @@ -2887,7 +2887,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1vCglEaaVMujT0Z2_fjry5evTTYcNLEyj/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13168046-L.jpg" }, { "id": "rust-rust-in-action", @@ -2897,7 +2897,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/17cQzEkMvBFKSIbYYGFizYoQ0S1bZ8l4F/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11589242-L.jpg" }, { "id": "rust-command-line-rust", @@ -2907,7 +2907,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1f4ZOLaIQ8pNTA5gT5bXOXxZhZP5ZDhiL/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14678105-L.jpg" }, { "id": "rust-mastering-rust", @@ -2917,7 +2917,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/18rol5LmfLALJPSTLG-lLI3FlGqkigEBA/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12506764-L.jpg" }, { "id": "rust-the-rustonomicon", @@ -2927,7 +2927,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://doc.rust-lang.org/nomicon/", - "coverImage": "" + "coverImage": "https://www.rust-lang.org/static/images/rust-social-wide.jpg" }, { "id": "rust-programming-webassembly-with-rust", @@ -2937,7 +2937,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1fA-QBP7oMWIa-JliX6lnguT-kZPbgJwX/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/8852713482786.jpg" }, { "id": "rust-hands-on-concurrency-with-rust", @@ -2947,7 +2947,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/108VatywkKNA59u__xdIXgfcELeFPGHYn/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508805-L.jpg" }, { "id": "rust-rust-high-performance", @@ -2957,7 +2957,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1PRqqydj7tGarWkFgEQMYN5fKS3G6QD16/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509160-L.jpg" }, { "id": "rust-black-hat-rust", @@ -2967,7 +2967,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1aiT-Luw2WcVkps7BaDYgO7Web1idqvX_/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/23350193488694.jpg" }, { "id": "rust-zero-to-production-in-rust", @@ -2977,7 +2977,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1xOHEXyd3dF3e2MlfRVBSQ2P09gsr-ZIt/view?usp=drive_link", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14634936-L.jpg" }, { "id": "rust-the-embedded-rust-book", @@ -2987,7 +2987,7 @@ "category": "specialized", "edition": "Online Resource", "driveUrl": "https://drive.google.com/file/d/1nskPjDJBUesrfDuWp49In7DfFTFxDxoX/view?usp=sharing", - "coverImage": "" + "coverImage": "https://www.rust-lang.org/static/images/rust-social-wide.jpg" }, { "id": "rust-rust-web-development", @@ -2997,7 +2997,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1HuYUELERFfoNpuyAf6oWxzd3WX_MkSNa/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13930433-L.jpg" }, { "id": "rust-game-development-with-rust", @@ -3007,7 +3007,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1ymZXvXOycCZJDJMLURXKSdc4QF8CbPFX/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1670478150i/64627260.jpg" }, { "id": "rust-hands-on-data-structures-and-algorithms-with-rust", @@ -3017,7 +3017,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/15bDvvz9Vu4Wo6tkfkai1bR37AYLW3XC5/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/26443943482824.jpg" }, { "id": "rust-the-cargo-book", @@ -3027,7 +3027,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://doc.rust-lang.org/cargo/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13163304-L.jpg" }, { "id": "rust-idiomatic-rust", @@ -3037,7 +3037,7 @@ "category": "references", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1OHEm3A2ydVj1g6gqwB6mCcJOeJNQGTWW/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13168046-L.jpg" }, { "id": "rust-effective-rust", @@ -3047,7 +3047,7 @@ "category": "references", "edition": "1st Edition", "driveUrl": "https://www.lurklurk.org/effective-rust/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12469430-L.jpg" }, { "id": "php-head-first-php-mysql", @@ -3057,7 +3057,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1lQZk9_XSGOL02j07qV8_oS6B_ptCORNz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5542007-L.jpg" }, { "id": "php-learning-php-mysql-javascript", @@ -3067,7 +3067,7 @@ "category": "beginner", "edition": "6th Edition", "driveUrl": "https://drive.google.com/file/d/12o-Gt5jkbtXeyYP7W3qeI5gQndEGs1bW/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5724818-L.jpg" }, { "id": "php-php-mysql-novice-to-ninja", @@ -3077,7 +3077,7 @@ "category": "beginner", "edition": "7th Edition", "driveUrl": "https://drive.google.com/file/d/1FeEo2YfTU67lcftMqFfvpzkzCM7-3TXV/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12950949-L.jpg" }, { "id": "php-the-joy-of-php", @@ -3087,7 +3087,7 @@ "category": "beginner", "edition": "", "driveUrl": "https://drive.google.com/file/d/1Zbkizlda3f_oeW6JyTyj7NbURrcVo3Ha/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12718588-L.jpg" }, { "id": "php-php-and-mysql-web-development", @@ -3097,7 +3097,7 @@ "category": "intermediate", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1yYGg0c5W4Sa4YZU9IKlDOuW-4jMZhoyK/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/411040-L.jpg" }, { "id": "php-php-mysql-the-missing-manual", @@ -3107,7 +3107,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1RxQg2J9yWvvQQeLqhMuIfexvHvBowM6Q/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10095878-L.jpg" }, { "id": "php-murach-s-php-and-mysql", @@ -3117,7 +3117,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1cwLVkDlilXhaEMqxN7xh7f8jOQWQVMKB/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9738354-L.jpg" }, { "id": "php-php-8-programming-tips-tricks-and-best-practices", @@ -3127,7 +3127,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1u0DYotU0oK7Kq5S18YwoadenEYeC_omH/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13782445-L.jpg" }, { "id": "php-modern-php-new-features-and-good-practices", @@ -3137,7 +3137,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1PPlh7FNTHNbzqFos8PNU3FZdffva83_x/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513299-L.jpg" }, { "id": "php-php-8-objects-patterns-and-practice", @@ -3147,7 +3147,7 @@ "category": "advanced", "edition": "6th Edition", "driveUrl": "https://drive.google.com/file/d/1YBm7Kqe3dMt2lYVo6crM--ngAIrIsyN_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13556120-L.jpg" }, { "id": "php-programming-php", @@ -3157,7 +3157,7 @@ "category": "advanced", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1QM5qKPJUzocK7qQU3rQ2sXM5eax89MVv/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/805876-L.jpg" }, { "id": "php-php-cookbook", @@ -3167,7 +3167,7 @@ "category": "advanced", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1TTer2qoYmjWDS10QNSM0j4hRmWJEJouz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/805908-L.jpg" }, { "id": "php-laravel-up-running", @@ -3177,7 +3177,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1kea0S1ZmoKJ63gT9Fyxja5JUVMGQSPFJ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13730669-L.jpg" }, { "id": "php-symfony-5-the-fast-track", @@ -3187,7 +3187,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/16FeRUJSoMm6-JrHKnBQfQXrwyfR3e13c/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12038977-L.jpg" }, { "id": "php-domain-driven-design-in-php", @@ -3197,7 +3197,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1f4uijRCkTlFuSsOK9hg1hfrH6Io1hk0F/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/9378483482824.jpg" }, { "id": "php-php-web-services", @@ -3207,7 +3207,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1VBLnZgoBlisNfH4jMhSo8GWwDPGScfZM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8515138-L.jpg" }, { "id": "php-php-the-right-way", @@ -3217,7 +3217,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://phptherightway.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388713-L.jpg" }, { "id": "php-the-php-manual", @@ -3227,7 +3227,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.php.net/manual/en/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8578103-L.jpg" }, { "id": "php-php-8-quick-scripting-reference", @@ -3237,7 +3237,7 @@ "category": "references", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1plFybWhVvACeMgufK65FA5Rb6asoSefw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/12456183482716.jpg" }, { "id": "kotlin-head-first-kotlin", @@ -3247,7 +3247,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1uopk9AAKW7l_WIlZyZfYpwqCcVqyBlGw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507773-L.jpg" }, { "id": "kotlin-atomic-kotlin", @@ -3257,7 +3257,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1ZVoig_RngXbljgpXGS69YBmNLMQzXv0u/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11533540-L.jpg" }, { "id": "kotlin-kotlin-programming-the-big-nerd-ranch-guide", @@ -3267,7 +3267,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1FPEhYAxWa1qHQ6dObDnoDR8fsRM5VtwO/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12404606-L.jpg" }, { "id": "kotlin-kotlin-in-action", @@ -3277,7 +3277,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1NxvVTLNqCmzVPwqpvWTGU3RMIc3US4OM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507716-L.jpg" }, { "id": "kotlin-programming-kotlin", @@ -3287,7 +3287,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1LYx8xU91kJN4v8TrJGqi4NFlDxTXKQHh/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13219969-L.jpg" }, { "id": "kotlin-effective-kotlin", @@ -3297,7 +3297,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1LU06OFOo2JLtHbF40E4G_46IqwgiGwFU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13219924-L.jpg" }, { "id": "kotlin-software-architecture-with-kotlin", @@ -3307,7 +3307,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1HohouuFqQ_1eQbqBoXEBMtUS85lvkptS/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/13720213482841.jpg" }, { "id": "kotlin-kotlin-design-patterns-and-best-practices", @@ -3317,7 +3317,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1mq7jfZ_Ce7iB1NyJOo4RXIMpf2Hd0tCp/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/14257363482829.jpg" }, { "id": "kotlin-the-joy-of-kotlin", @@ -3327,7 +3327,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1dSp6NJ49inBhTDwQWEC2dtEx7xE7qu2u/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8798807-L.jpg" }, { "id": "kotlin-kotlin-coroutines", @@ -3337,7 +3337,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/1bAanWlXlmmjtlQWIu3wbn_xGCU32FFgI/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13196795-L.jpg" }, { "id": "kotlin-kotlin-for-android-developers", @@ -3347,7 +3347,7 @@ "category": "specialized", "edition": "6th Edition", "driveUrl": "https://drive.google.com/file/d/1llsRA3Fy5J7G4UdFrQcYOkJ4B9kItXPT/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11515916-L.jpg" }, { "id": "kotlin-pro-android-with-kotlin", @@ -3357,7 +3357,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1MYDw6qAy_LbMjs_p-fzpoqmoahqQQTvP/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13231366-L.jpg" }, { "id": "kotlin-android-programming-the-big-nerd-ranch-guide", @@ -3367,7 +3367,7 @@ "category": "specialized", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1EDrFgkxDEE33ass5rKTXOvdJrumbplfN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509838-L.jpg" }, { "id": "kotlin-programming-android-with-kotlin", @@ -3377,7 +3377,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1qmz4pIdQWFuj0RrPDGiKTKelRyVHfrN6/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10541846-L.jpg" }, { "id": "kotlin-kotlin-multiplatform-by-tutorials", @@ -3387,7 +3387,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1Ns-a-i1fIf1qxW_2lRCP_ueTuKsLf_yy/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/10809493482882.jpg" }, { "id": "kotlin-kotlin-documentation", @@ -3397,7 +3397,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://kotlinlang.org/docs/home.html", - "coverImage": "" + "coverImage": "https://kotlinlang.org/assets/images/open-graph/docs.png" }, { "id": "kotlin-kotlin-hands-on", @@ -3407,7 +3407,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://play.kotlinlang.org/byExample/overview", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508724-L.jpg" }, { "id": "sql-sql-practice-problems", @@ -3417,7 +3417,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1MmueOnIX6JhxxeWH6J4XiSsfaKMan7vq/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8846384-L.jpg" }, { "id": "sql-head-first-sql", @@ -3427,7 +3427,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1G5bM0feeTbCIcdKKwGB3fz2imQZZewtu/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1312592-L.jpg" }, { "id": "sql-sql-in-10-minutes-sams-teach-yourself", @@ -3437,7 +3437,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1Tsj_yl20Wyv8NUmpZOJrAXrlLYJ7HiJs/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9353369-L.jpg" }, { "id": "sql-learning-sql", @@ -3447,7 +3447,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1qIBYWckJF8exoJz5iOrAEpiBFN8pZX94/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8686154-L.jpg" }, { "id": "sql-getting-started-with-sql", @@ -3457,7 +3457,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1fWgvSQ6lDrIk26hAapJbQyry-amNoaLl/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8906451-L.jpg" }, { "id": "sql-sql-for-smarties-advanced-t-sql-recipes", @@ -3467,7 +3467,7 @@ "category": "intermediate", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1YxLgh7S3f4MqmvTvJP-_AZz5SRfodDrn/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/784092-L.jpg" }, { "id": "sql-sql-queries-for-mere-mortals", @@ -3477,7 +3477,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/19vcGtL3q4qm3WFniMcfz-H4rhWgOUdwY/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509344-L.jpg" }, { "id": "sql-practical-sql-a-beginner-s-guide-to-storytelling-with-data", @@ -3487,7 +3487,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1d1-XRfySmTABbZSGkq_CLQ99_pEFU9py/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508287-L.jpg" }, { "id": "sql-database-design-for-mere-mortals", @@ -3497,7 +3497,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1SfNM079EEvW0V0x7NkCNfiXhmL7OB8nc/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135738-L.jpg" }, { "id": "sql-sql-performance-explained", @@ -3507,7 +3507,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1FjsCUIbUdjyMb2WFK3AR1O99Rmoo53UF/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6681916-L.jpg" }, { "id": "sql-the-art-of-sql", @@ -3517,7 +3517,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/19KABSaDvd7Ej6mfesMIENM6lI3k7JvEo/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/389081-L.jpg" }, { "id": "sql-joe-celko-s-sql-puzzles-and-answers", @@ -3527,7 +3527,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1kSS5vaesEfSC_8h-GWKrDioCt3Z7SQiw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1098318-L.jpg" }, { "id": "sql-high-performance-mysql", @@ -3537,7 +3537,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1R0WNNGWYQ-7hZveORwVSl9IdmIl1PoSr/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5076309-L.jpg" }, { "id": "sql-sql-for-data-analysis", @@ -3547,7 +3547,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/12o_0nw12yTdu1WLkae2jtT_X2DOMTO0F/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12403632-L.jpg" }, { "id": "sql-sql-cookbook", @@ -3557,7 +3557,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1oH_OyDCv8GLOpyP73eCLM0AGHWQDZzLg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/389135-L.jpg" }, { "id": "sql-database-internals", @@ -3567,7 +3567,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1v1V6TDpiTa6t_UMVv2uUnO2vUk_TmqUG/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14572292-L.jpg" }, { "id": "sql-seven-databases-in-seven-weeks", @@ -3577,7 +3577,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1fiQbA99yhfIPUjenV14CQsxYVth9wOYZ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7087757-L.jpg" }, { "id": "sql-sql-in-a-nutshell", @@ -3587,7 +3587,7 @@ "category": "references", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/1rEXIAP3fyJ4jIoW3HBQL6LhfVWcAiUaS/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6616859-L.jpg" }, { "id": "sql-modern-sql", @@ -3597,7 +3597,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://modern-sql.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11190655-L.jpg" }, { "id": "swift-swift-apprentice", @@ -3607,7 +3607,7 @@ "category": "beginner", "edition": "7th Edition", "driveUrl": "https://drive.google.com/file/d/1tA1abtGxZvJUuAIyCA6TJbkzGPKNhuHg/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12508462-L.jpg" }, { "id": "swift-head-first-swift", @@ -3617,7 +3617,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1aV5_twjheTblaadPX0Up9CHU7XydT2T1/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/4765583482719.jpg" }, { "id": "swift-swift-programming-the-big-nerd-ranch-guide", @@ -3627,7 +3627,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1b9t6A265KOdy99PTDKrFnRxe_JPmbW-1/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512301-L.jpg" }, { "id": "swift-develop-in-swift-fundamentals", @@ -3637,7 +3637,7 @@ "category": "beginner", "edition": "Official Apple curriculum", "driveUrl": "https://developer.apple.com/learn/curriculum/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508793-L.jpg" }, { "id": "swift-swiftui-for-masterminds", @@ -3647,7 +3647,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1IWIUDcvNQbI2zNZ_L2lBoEnwGUKpinLT/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/568523482821.jpg" }, { "id": "swift-ios-development-with-swift", @@ -3657,7 +3657,7 @@ "category": "beginner", "edition": "", "driveUrl": "https://drive.google.com/file/d/1rxN7h9etXSJPKlGdq1ooNhHPDqhpIS9U/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507820-L.jpg" }, { "id": "swift-learning-swift", @@ -3667,7 +3667,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1we9nE1pbHEJ9hBSWHNX5tiYObBRyhbjc/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10105829-L.jpg" }, { "id": "swift-swift-in-depth", @@ -3677,7 +3677,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1Mi4-0eInG74YugNvLj1i6M8Py60uf7TU/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507819-L.jpg" }, { "id": "swift-swift-gems", @@ -3687,7 +3687,7 @@ "category": "intermediate", "edition": "1st Edition - 2025", "driveUrl": "https://drive.google.com/file/d/1ynPRUtdPfh1H8JCTZ8EFFtcN27pG6m4p/view?usp=sharing", - "coverImage": "" + "coverImage": "https://s3.us-west-2.amazonaws.com/content.podia.com/ou5aaswqoji8pni4r94i4b9vy4uh" }, { "id": "swift-practical-swift", @@ -3697,7 +3697,7 @@ "category": "intermediate", "edition": "", "driveUrl": "https://drive.google.com/file/d/1b83V83-WyEWEMp5fn_ytmm5njuDvQYE0/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512426-L.jpg" }, { "id": "swift-advanced-swift", @@ -3707,7 +3707,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/1kT8szQJtNBkAzHDZMTTv5w3u7qHrqgNf/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12792064-L.jpg" }, { "id": "swift-modern-concurrency-in-swift", @@ -3717,7 +3717,7 @@ "category": "advanced", "edition": "", "driveUrl": "https://drive.google.com/file/d/16tMu59OYTMKOUxtfc9AvY1RmiCLcc_n3/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13218209-L.jpg" }, { "id": "swift-expert-swift", @@ -3727,7 +3727,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1rMtUlu7cd7N9gODzhDikQUwSTUmCSQ2x/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10535814-L.jpg" }, { "id": "swift-thinking-in-swiftui", @@ -3737,7 +3737,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://drive.google.com/file/d/12W4CAVOxa4IPuiIqoztRDWhbhf0fiQ02/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/25142103488819.jpg" }, { "id": "swift-app-architecture", @@ -3747,7 +3747,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1JOZ6UwAlg9BgJvg65dZ7P45dnk5xDHn7/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14133335-L.jpg" }, { "id": "swift-hacking-with-swift", @@ -3757,7 +3757,7 @@ "category": "specialized", "edition": "", "driveUrl": "https://drive.google.com/file/d/1x7tV6OFb3Lefvw4WKKn4RjZ1S0Ujs2k_/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/14898983482729.jpg" }, { "id": "swift-advanced-ios-app-architecture", @@ -3767,7 +3767,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1bClNPwkQx9qBSG9kTndqjHOw2ps01rrx/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14133335-L.jpg" }, { "id": "swift-the-swift-programming-language", @@ -3777,7 +3777,7 @@ "category": "references", "edition": "Official Documentation", "driveUrl": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12641066-L.jpg" }, { "id": "swift-swiftui-views-mastery", @@ -3787,7 +3787,7 @@ "category": "references", "edition": "", "driveUrl": "https://drive.google.com/file/d/1GhSi3SP499yqX8ZX-qcldFalkIlB7Pue/view?usp=sharing", - "coverImage": "" + "coverImage": "https://www.bigmountainstudio.com/content-assets/public/eyJhbGciOiJIUzI1NiJ9.eyJvYmplY3Rfa2V5IjoiN2w0MHBnbDY0b3BkZTc2dWVzZ21obmg3bHVxOSIsImRvbWFpbiI6Ind3dy5iaWdtb3VudGFpbnN0dWRpby5jb20ifQ.393smxjW311lDF3r9dDiVwyo5BdwCDyf8-d8IzY5JxU" }, { "id": "ruby-the-well-grounded-rubyist", @@ -3797,7 +3797,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1Cf52TXHVNxnmiormIZxnCAIeTStlqMxN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8734237-L.jpg" }, { "id": "ruby-learn-to-program", @@ -3807,7 +3807,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1EwtvkYvk4mCYLCnkvuG98LX4Wufpg1mZ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/742455-L.jpg" }, { "id": "ruby-head-first-ruby", @@ -3817,7 +3817,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/17ad--m9IvySUTM80Tt_1vUvNOlbveDjk/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14341549-L.jpg" }, { "id": "ruby-beginning-ruby-from-novice-to-professional", @@ -3827,7 +3827,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1oQvt0rSY30t8kNP5ns_lEe_tjEZfF68P/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512821-L.jpg" }, { "id": "ruby-the-ruby-way", @@ -3837,7 +3837,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://drive.google.com/file/d/1a3ZoDJBGjwAbtoZATusPisqY1nz00E_J/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/410686-L.jpg" }, { "id": "ruby-eloquent-ruby", @@ -3847,7 +3847,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1ZZn9kyzM86xojOtO4Bgj8CRqVWupc5yx/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9534809-L.jpg" }, { "id": "ruby-practical-object-oriented-design-in-ruby-poodr", @@ -3857,7 +3857,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1aAlGlsTO_pR427WYvSRraHnKPR6Ydl_X/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7551361-L.jpg" }, { "id": "ruby-confident-ruby", @@ -3867,7 +3867,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1qtL_lhD2tq2TB6rSpdVf5E7tjmXJYt0J/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509174-L.jpg" }, { "id": "ruby-ruby-under-a-microscope", @@ -3877,7 +3877,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1mzeyaEwPOtSLWz39vbAxQ90_KyZ1pRpQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1384159698i/17912855.jpg" }, { "id": "ruby-programming-ruby-3-3-the-pickaxe-book", @@ -3887,7 +3887,7 @@ "category": "intermediate", "edition": "5th Edition", "driveUrl": "https://drive.google.com/file/d/1PlMP53k6bF36OMawAWM1LI31Z4exJ8MG/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/8887293482786.jpg" }, { "id": "ruby-metaprogramming-ruby-2", @@ -3897,7 +3897,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1A2BgskzagF_naSqmnNRaOSyppEpogJwr/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513494-L.jpg" }, { "id": "ruby-design-patterns-in-ruby", @@ -3907,7 +3907,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1bO22y0x2lcdbSzsV-hss7uACKlZxE5pf/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9986352-L.jpg" }, { "id": "ruby-refactoring-ruby-edition", @@ -3917,7 +3917,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1h9TEOF8KUdXVqUUZs-ihB0s43MFSMtss/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9363836-L.jpg" }, { "id": "ruby-ruby-performance-optimization", @@ -3927,7 +3927,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1QWKdMnrGSviWmEZQ_adQoVL5hlUT-D0x/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14310006-L.jpg" }, { "id": "ruby-ruby-on-rails-tutorial", @@ -3937,7 +3937,7 @@ "category": "specialized", "edition": "7th Edition", "driveUrl": "https://drive.google.com/file/d/1K6s83h9Nn9jApIMz1uuVrplTweP-rWmM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8716490-L.jpg" }, { "id": "ruby-agile-web-development-with-rails-7", @@ -3947,7 +3947,7 @@ "category": "specialized", "edition": "2022 Edition", "driveUrl": "https://drive.google.com/file/d/10Gg5TWEokpr0ZZujBmWDqUMnqJXnTlet/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13313776-L.jpg" }, { "id": "ruby-the-rails-7-way", @@ -3957,7 +3957,7 @@ "category": "specialized", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/12jcP23KAUfse3EgQR2buW78w0UhehRJT/view?usp=sharing", - "coverImage": "" + "coverImage": "https://d2sofvawe08yqg.cloudfront.net/therails7way/s_hero2x?1644477693&1644477693" }, { "id": "ruby-sustainable-web-development-with-ruby-on-rails", @@ -3967,7 +3967,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1zccKnVroVNhc0RngeczjaU58NRkIDWno/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1611553511i/56463935.jpg" }, { "id": "ruby-effective-testing-with-rspec-3", @@ -3977,7 +3977,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1b_Z0wSRlSOYzyns69uFsA7YUn3iDhBNz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8509174-L.jpg" }, { "id": "ruby-black-hat-ruby", @@ -3987,7 +3987,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1hN-wOW755e_qgP9oODCkoRze8G7mJuXL/view?usp=sharing", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/17450073488841.jpg" }, { "id": "ruby-the-ruby-programming-language", @@ -3997,7 +3997,7 @@ "category": "references", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/15dMASM-GFoEMMnDm4m_3aJXPjDOsTz1O/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1312587-L.jpg" }, { "id": "ruby-ruby-cookbook", @@ -4007,7 +4007,7 @@ "category": "references", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1m7lBtlRlCdWrG_CIqyaSyRzrYHfZWvtn/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10361371-L.jpg" }, { "id": "ruby-official-ruby-documentation", @@ -4017,7 +4017,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.ruby-lang.org/en/documentation/", - "coverImage": "" + "coverImage": "https://www.ruby-lang.org/images/og-image.png" }, { "id": "ruby-the-ruby-style-guide", @@ -4027,7 +4027,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://rubystyle.guide/", - "coverImage": "" + "coverImage": "https://avatars.githubusercontent.com/u/226424?s=200&v=4" }, { "id": "dart-flutter-for-dummies", @@ -4037,7 +4037,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1F9Ep5ATcQPC9f2BO7dE6HtZ2isQZcX79/view?usp=sharing", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1592881978i/45681946.jpg" }, { "id": "dart-dart-apprentice-fundamentals", @@ -4047,7 +4047,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1uEsVKWLocoPIeIesjS_4lLIJiIsOJE2X/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13183354-L.jpg" }, { "id": "dart-flutter-apprentice", @@ -4057,7 +4057,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://drive.google.com/file/d/193ZpR1quIK79wFDwhiZw4W4UqckYVt0W/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14780498-L.jpg" }, { "id": "dart-dart-up-and-running", @@ -4067,7 +4067,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1gareIc2dTaKFBuT_EClXC-M75uhn7TLE/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/378498-L.jpg" }, { "id": "dart-beginning-app-development-with-flutter", @@ -4077,7 +4077,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1hescnMo5wjJhOL9U8KESqAVJyPmv7Ipz/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11110101-L.jpg" }, { "id": "dart-programming-flutter", @@ -4087,7 +4087,7 @@ "category": "intermediate", "edition": "2020 Edition", "driveUrl": "https://drive.google.com/file/d/113W5J6-MhLT0JV0Y2MNv0UgN8cKTtmJv/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13266493-L.jpg" }, { "id": "dart-flutter-in-action", @@ -4097,7 +4097,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1SmiglCBKIGbLCuhLXitfApG6TG2Chxbw/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9937155-L.jpg" }, { "id": "dart-dart-apprentice-beyond-the-basics", @@ -4107,7 +4107,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1m_TcVG6jj2ZUnwuo_b2TyRboNEIFrJjl/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13253897-L.jpg" }, { "id": "dart-pragmatic-flutter", @@ -4117,7 +4117,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1t7d8WFr1UiDWBsWQhMM43XdDXb6ojJsN/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13216605-L.jpg" }, { "id": "dart-real-world-flutter-by-tutorials", @@ -4127,7 +4127,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/16ynNoqtHexXw6JlCrXHDZEQ7W9UIQA6Y/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13845675-L.jpg" }, { "id": "dart-mastering-dart", @@ -4137,7 +4137,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1YDiXxXdbIth7olLR7oAX8QVgER2FdBeM/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12735417-L.jpg" }, { "id": "dart-flutter-for-beginners", @@ -4147,7 +4147,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1Z1FuTs95TNQBuxYV_SQ4dSZmVeuRXuQD/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13730334-L.jpg" }, { "id": "dart-flutter-and-dart-cookbook", @@ -4157,7 +4157,7 @@ "category": "specialized", "edition": "2023 Edition", "driveUrl": "https://drive.google.com/file/d/1-WCYcuFgqAIUOcKTh3xbOb2EGuP2H-te/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13281016-L.jpg" }, { "id": "dart-practical-flutter", @@ -4167,7 +4167,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://drive.google.com/file/d/1yJQSFabTh7MBB0V5jTUdFRQIdOehkvAZ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10162663-L.jpg" }, { "id": "dart-flutter-cookbook", @@ -4177,7 +4177,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://drive.google.com/file/d/1yyV7cizosSVc0_qBIHZUTMdYqSF1rDzQ/view?usp=sharing", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13281016-L.jpg" }, { "id": "dart-effective-dart", @@ -4187,7 +4187,7 @@ "category": "references", "edition": "Official Reference", "driveUrl": "https://dart.dev/effective-dart", - "coverImage": "" + "coverImage": "https://dart.dev/assets/img/logo/dart-logo-for-shares.png" }, { "id": "dart-dart-language-documentation", @@ -4197,7 +4197,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://dart.dev/guides", - "coverImage": "" + "coverImage": "https://dart.dev/assets/img/logo/dart-logo-for-shares.png" }, { "id": "dart-a-tour-of-the-dart-language", @@ -4207,7 +4207,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://dart.dev/language", - "coverImage": "" + "coverImage": "https://dart.dev/assets/img/logo/dart-logo-for-shares.png" }, { "id": "scala-scala-3-book", @@ -4217,7 +4217,7 @@ "category": "beginner", "edition": "Official free online book", "driveUrl": "https://docs.scala-lang.org/scala3/book/introduction.html", - "coverImage": "" + "coverImage": "https://docs.scala-lang.org/resources/img/scala-spiral-3d-2-toned-down.png" }, { "id": "scala-creative-scala", @@ -4227,7 +4227,7 @@ "category": "beginner", "edition": "Free online introduction", "driveUrl": "https://www.creativescala.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7519048-L.jpg" }, { "id": "scala-essential-scala", @@ -4237,7 +4237,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://underscore.io/books/essential-scala/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12985499-L.jpg" }, { "id": "scala-programming-in-scala", @@ -4247,7 +4247,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://www.manning.com/books/programming-in-scala-fifth-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8710790-L.jpg" }, { "id": "scala-scala-for-the-impatient", @@ -4257,7 +4257,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://www.oreilly.com/library/view/scala-for-the-impatient/9780134540566/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13353233-L.jpg" }, { "id": "scala-tour-of-scala", @@ -4267,7 +4267,7 @@ "category": "intermediate", "edition": "Official language tour", "driveUrl": "https://docs.scala-lang.org/tour/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6441552-L.jpg" }, { "id": "scala-hands-on-scala-programming", @@ -4277,7 +4277,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.handsonscala.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13803284-L.jpg" }, { "id": "scala-functional-programming-in-scala", @@ -4287,7 +4287,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/functional-programming-in-scala", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7866340-L.jpg" }, { "id": "scala-scala-cookbook", @@ -4297,7 +4297,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/scala-cookbook/9781449319385/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7863286-L.jpg" }, { "id": "scala-scala-with-cats", @@ -4307,7 +4307,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://www.scalawithcats.com/", - "coverImage": "" + "coverImage": "https://underscore.io/images/books/scala-with-cats.png" }, { "id": "scala-zionomicon", @@ -4317,7 +4317,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://www.zionomicon.com/", - "coverImage": "" + "coverImage": "https://zionomicon.com/images/min/book-img.png" }, { "id": "scala-functional-programming-for-mortals-with-scalaz", @@ -4327,7 +4327,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://leanpub.com/fpmortals", - "coverImage": "" + "coverImage": "https://d2sofvawe08yqg.cloudfront.net/fpmortals/s_hero2x?1782215642" }, { "id": "scala-spark-the-definitive-guide", @@ -4337,7 +4337,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/spark-the-definitive/9781491912218/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10982488-L.jpg" }, { "id": "scala-scala-and-spark-for-big-data-analytics", @@ -4347,7 +4347,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/scala-and-spark-for-big-data-analytics/9781783550500", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510182-L.jpg" }, { "id": "scala-akka-in-action", @@ -4357,7 +4357,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/akka-in-action", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511699-L.jpg" }, { "id": "scala-scala-documentation", @@ -4367,7 +4367,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://docs.scala-lang.org/", - "coverImage": "" + "coverImage": "https://docs.scala-lang.org/resources/img/scala-spiral-3d-2-toned-down.png" }, { "id": "scala-a-tour-of-scala", @@ -4377,7 +4377,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://docs.scala-lang.org/tour/tour-of-scala.html", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6441552-L.jpg" }, { "id": "elixir-elixir-getting-started-guide", @@ -4387,7 +4387,7 @@ "category": "beginner", "edition": "Official free guide", "driveUrl": "https://elixir-lang.org/getting-started/introduction.html", - "coverImage": "" + "coverImage": "https://elixir-lang.org/images/logo/logo.png" }, { "id": "elixir-elixir-school", @@ -4397,7 +4397,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://elixirschool.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1357762-L.jpg" }, { "id": "elixir-programming-elixir-1-6", @@ -4407,7 +4407,7 @@ "category": "beginner", "edition": "1.6 Edition", "driveUrl": "https://www.amazon.com/Programming-Elixir-1-6-Functional-Concurrent/dp/1680502999", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508631-L.jpg" }, { "id": "elixir-learn-functional-programming-with-elixir", @@ -4417,7 +4417,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Learn-Functional-Programming-Elixir-Concurrent/dp/1680504568", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508766-L.jpg" }, { "id": "elixir-introducing-elixir", @@ -4427,7 +4427,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.oreilly.com/library/view/introducing-elixir-2nd/9781492026188/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513711-L.jpg" }, { "id": "elixir-elixir-in-action", @@ -4437,7 +4437,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/elixir-in-action-second-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14382780-L.jpg" }, { "id": "elixir-craft-graphql-apis-in-elixir-with-absinthe", @@ -4447,7 +4447,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/craft-graphql-apis-in-elixir-with-absinthe", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508747-L.jpg" }, { "id": "elixir-adopting-elixir", @@ -4457,7 +4457,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Adopting-Elixir-Concepts-Production-Applications/dp/1680506129", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508764-L.jpg" }, { "id": "elixir-metaprogramming-elixir", @@ -4467,7 +4467,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Metaprogramming-Elixir-Write-Less-Code/dp/1680500414", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513175-L.jpg" }, { "id": "elixir-designing-elixir-systems-with-otp", @@ -4477,7 +4477,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Designing-Elixir-Systems-OTP/dp/1680506617", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10579080-L.jpg" }, { "id": "elixir-property-based-testing-with-proper-erlang-and-elixir", @@ -4487,7 +4487,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/property-based-testing-with-proper-erlang-and-elixir", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507787-L.jpg" }, { "id": "elixir-programming-phoenix-1-4", @@ -4497,7 +4497,7 @@ "category": "specialized", "edition": "1.4 Edition", "driveUrl": "https://www.amazon.com/Programming-Phoenix-1-4-Productive-Reliable/dp/1680502265", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14572287-L.jpg" }, { "id": "elixir-programming-ecto", @@ -4507,7 +4507,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Programming-Ecto-Build-Database-Applications/dp/1680507380", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10453135-L.jpg" }, { "id": "elixir-programming-phoenix-liveview", @@ -4517,7 +4517,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Programming-Phoenix-LiveView-Interactive-Applications/dp/1680508212", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/8871213482786.jpg" }, { "id": "elixir-official-elixir-documentation", @@ -4527,7 +4527,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://elixir-lang.org/docs.html", - "coverImage": "" + "coverImage": "https://elixir-lang.org/images/logo/logo.png" }, { "id": "elixir-elixir-on-hexdocs", @@ -4537,7 +4537,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://hexdocs.pm/elixir/", - "coverImage": "" + "coverImage": "https://hexdocs.pm/assets/apple-touch-icon.png" }, { "id": "elixir-erlang-otp-documentation", @@ -4547,7 +4547,7 @@ "category": "references", "edition": "VM platform docs", "driveUrl": "https://www.erlang.org/docs", - "coverImage": "" + "coverImage": "https://www.erlang.org/assets/img/erlang-228x200.png" }, { "id": "elixir-hexdocs", @@ -4557,7 +4557,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://hexdocs.pm/", - "coverImage": "" + "coverImage": "https://hexdocs.pm/assets/apple-touch-icon.png" }, { "id": "shell-the-linux-command-line", @@ -4567,7 +4567,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://linuxcommand.org/tlcl.php", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7087755-L.jpg" }, { "id": "shell-bash-guide-for-beginners", @@ -4577,7 +4577,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://tldp.org/LDP/Bash-Beginners-Guide/html/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/2720824-L.jpg" }, { "id": "shell-advanced-bash-scripting-guide", @@ -4587,7 +4587,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://tldp.org/LDP/abs/html/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9351378-L.jpg" }, { "id": "shell-data-science-at-the-command-line", @@ -4597,7 +4597,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://jeroenjanssens.com/dsatcl/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8161751-L.jpg" }, { "id": "shell-gnu-bash-reference-manual", @@ -4607,7 +4607,7 @@ "category": "references", "edition": "Official Reference", "driveUrl": "https://www.gnu.org/software/bash/manual/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1688274-L.jpg" }, { "id": "shell-greg-s-wiki-bashguide", @@ -4617,7 +4617,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://mywiki.wooledge.org/BashGuide", - "coverImage": "" + "coverImage": "https://upload.wikimedia.org/wikipedia/commons/4/4b/Bash_Logo_Colored.svg" }, { "id": "shell-shellcheck", @@ -4627,7 +4627,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.shellcheck.net/", - "coverImage": "" + "coverImage": "https://www.shellcheck.net/shellcheck.png" }, { "id": "shell-google-shell-style-guide", @@ -4637,7 +4637,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://google.github.io/styleguide/shellguide.html", - "coverImage": "" + "coverImage": "https://www.gstatic.com/images/branding/product/2x/googleg_48dp.png" }, { "id": "r-r-for-data-science", @@ -4647,7 +4647,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://r4ds.hadley.nz/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512393-L.jpg" }, { "id": "r-hands-on-programming-with-r", @@ -4657,7 +4657,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://rstudio-education.github.io/hopr/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513605-L.jpg" }, { "id": "r-r-cookbook", @@ -4667,7 +4667,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://rc2e.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8713348-L.jpg" }, { "id": "r-ggplot2-elegant-graphics-for-data-analysis", @@ -4677,7 +4677,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://ggplot2-book.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8654150-L.jpg" }, { "id": "r-r-graphics-cookbook", @@ -4687,7 +4687,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://r-graphics.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7738220-L.jpg" }, { "id": "r-advanced-r", @@ -4697,7 +4697,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://adv-r.hadley.nz/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8778978-L.jpg" }, { "id": "r-r-packages", @@ -4707,7 +4707,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://r-pkgs.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12858953-L.jpg" }, { "id": "r-efficient-r-programming", @@ -4717,7 +4717,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://csgillespie.github.io/efficientR/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512881-L.jpg" }, { "id": "r-an-introduction-to-statistical-learning", @@ -4727,7 +4727,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://www.statlearning.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8665540-L.jpg" }, { "id": "r-the-elements-of-statistical-learning", @@ -4737,7 +4737,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://hastie.su.domains/ElemStatLearn/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8643962-L.jpg" }, { "id": "r-mastering-shiny", @@ -4747,7 +4747,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://mastering-shiny.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12382728-L.jpg" }, { "id": "r-text-mining-with-r", @@ -4757,7 +4757,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.tidytextmining.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8510108-L.jpg" }, { "id": "r-forecasting-principles-and-practice", @@ -4767,7 +4767,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://openforecasting.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15094763-L.jpg" }, { "id": "r-geocomputation-with-r", @@ -4777,7 +4777,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://r.geocompx.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13220128-L.jpg" }, { "id": "r-an-introduction-to-r", @@ -4787,7 +4787,7 @@ "category": "references", "edition": "Official Manual", "driveUrl": "https://cran.r-project.org/doc/manuals/r-release/R-intro.html", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/723680-L.jpg" }, { "id": "r-the-r-language-definition", @@ -4797,7 +4797,7 @@ "category": "references", "edition": "Official Manual", "driveUrl": "https://cran.r-project.org/doc/manuals/r-release/R-lang.html", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5702426-L.jpg" }, { "id": "r-rdocumentation", @@ -4807,7 +4807,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.rdocumentation.org/", - "coverImage": "" + "coverImage": "https://www.r-project.org/logo/Rlogo.png" }, { "id": "julia-think-julia-how-to-think-like-a-computer-scientist", @@ -4817,7 +4817,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://benlauwens.github.io/ThinkJulia.jl/latest/book.html", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9173253-L.jpg" }, { "id": "julia-introducing-julia", @@ -4827,7 +4827,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://en.wikibooks.org/wiki/Introducing_Julia", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13304403-L.jpg" }, { "id": "julia-julia-programming-for-operations-research", @@ -4837,7 +4837,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Julia-Programming-Operations-Research-Optimization/dp/3031464217", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13760229-L.jpg" }, { "id": "julia-julia-1-0-by-example", @@ -4847,7 +4847,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/julia-10-by-example/9781788299522", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508007-L.jpg" }, { "id": "julia-julia-high-performance", @@ -4857,7 +4857,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.packtpub.com/product/julia-high-performance-second-edition/9781789349414", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512905-L.jpg" }, { "id": "julia-learning-scientific-programming-with-julia", @@ -4867,7 +4867,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Learning-Scientific-Programming-Julia-Computational/dp/1108445070", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/23485713488686.jpg" }, { "id": "julia-julia-data-science", @@ -4877,7 +4877,7 @@ "category": "intermediate", "edition": "Free online book", "driveUrl": "https://github.com/JuliaDataScience/JuliaDataScience", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512591-L.jpg" }, { "id": "julia-algorithms-for-optimization", @@ -4887,7 +4887,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Algorithms-Optimization-Mykel-Kochenderfer/dp/026202925X", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8801648-L.jpg" }, { "id": "julia-algorithms-for-decision-making", @@ -4897,7 +4897,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Algorithms-Decision-Making-Mykel-Kochenderfer/dp/0262047010", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8636102-L.jpg" }, { "id": "julia-julia-1-7-cookbook", @@ -4907,7 +4907,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/julia-17-cookbook/9781803237587", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9202165-L.jpg" }, { "id": "julia-statistics-with-julia", @@ -4917,7 +4917,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Statistics-Julia-Fundamentals-Data-Science/dp/3030401507", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12407243-L.jpg" }, { "id": "julia-machine-learning-with-julia", @@ -4927,7 +4927,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/machine-learning-with-julia/9781839218408", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12407243-L.jpg" }, { "id": "julia-quantitative-economics-with-julia", @@ -4937,7 +4937,7 @@ "category": "specialized", "edition": "Online Resource", "driveUrl": "https://julia.quantecon.org/intro.html", - "coverImage": "" + "coverImage": "https://assets.quantecon.org/img/qe-og-logo.png" }, { "id": "julia-the-julia-language-documentation", @@ -4947,7 +4947,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://docs.julialang.org/", - "coverImage": "" + "coverImage": "https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png" }, { "id": "julia-julia-manual-getting-started", @@ -4957,7 +4957,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://docs.julialang.org/en/v1/manual/getting-started/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7697842-L.jpg" }, { "id": "julia-juliaacademy", @@ -4967,7 +4967,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://juliaacademy.com/", - "coverImage": "" + "coverImage": "https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png" }, { "id": "htmlcss-html-and-css-design-and-build-websites", @@ -4977,7 +4977,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/HTML-CSS-Design-Build-Websites/dp/1118008189", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7262081-L.jpg" }, { "id": "htmlcss-learning-web-design", @@ -4987,7 +4987,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://www.oreilly.com/library/view/learning-web-design/9781491960196/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6875214-L.jpg" }, { "id": "htmlcss-html5-for-web-designers", @@ -4997,7 +4997,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/HTML5-Web-Designers-Jeremy-Keith/dp/1937557208", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6666412-L.jpg" }, { "id": "htmlcss-css-the-definitive-guide", @@ -5007,7 +5007,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://www.oreilly.com/library/view/css-the-definitive/9781098117603/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388504-L.jpg" }, { "id": "htmlcss-css-in-depth", @@ -5017,7 +5017,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/css-in-depth", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508986-L.jpg" }, { "id": "htmlcss-every-layout", @@ -5027,7 +5027,7 @@ "category": "intermediate", "edition": "Online Resource", "driveUrl": "https://every-layout.dev/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6381423-L.jpg" }, { "id": "htmlcss-responsive-web-design", @@ -5037,7 +5037,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Responsive-Web-Design-Ethan-Marcotte/dp/1937557186", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6715858-L.jpg" }, { "id": "htmlcss-css-secrets", @@ -5047,7 +5047,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/css-secrets/9781449372736/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8763750-L.jpg" }, { "id": "htmlcss-css-the-missing-manual", @@ -5057,7 +5057,7 @@ "category": "advanced", "edition": "4th Edition", "driveUrl": "https://www.oreilly.com/library/view/css-the-missing/9781491985038/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513704-L.jpg" }, { "id": "htmlcss-transcending-css", @@ -5067,7 +5067,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Transcending-CSS-Value-Aesthetic-Design/dp/0321412416", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/193974-L.jpg" }, { "id": "htmlcss-inclusive-design-patterns", @@ -5077,7 +5077,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.smashingmagazine.com/books/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14619750-L.jpg" }, { "id": "htmlcss-designing-interfaces", @@ -5087,7 +5087,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://www.oreilly.com/library/view/designing-interfaces-3rd/9781492051954/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8637276-L.jpg" }, { "id": "htmlcss-mdn-web-docs-html", @@ -5097,7 +5097,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://developer.mozilla.org/en-US/docs/Web/HTML", - "coverImage": "" + "coverImage": "https://developer.mozilla.org/apple-touch-icon.png" }, { "id": "htmlcss-mdn-web-docs-css", @@ -5107,7 +5107,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://developer.mozilla.org/en-US/docs/Web/CSS", - "coverImage": "" + "coverImage": "https://developer.mozilla.org/apple-touch-icon.png" }, { "id": "htmlcss-can-i-use", @@ -5117,7 +5117,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://caniuse.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/11753962-L.jpg" }, { "id": "lua-programming-in-lua", @@ -5127,7 +5127,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://www.lua.org/pil/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1048854-L.jpg" }, { "id": "lua-beginning-lua-programming", @@ -5137,7 +5137,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Beginning-Lua-Programming-Kurt-Jung/dp/0470069171", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/299703-L.jpg" }, { "id": "lua-lua-quick-start-guide", @@ -5147,7 +5147,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/lua-quick-start-guide/9781789343229", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508465-L.jpg" }, { "id": "lua-lua-programming-gems", @@ -5157,7 +5157,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.lua.org/gems/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7803242-L.jpg" }, { "id": "lua-creating-solid-apis-with-lua", @@ -5167,7 +5167,7 @@ "category": "intermediate", "edition": "Online Resource", "driveUrl": "https://www.lua.org/docs.html", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/5174593482719.jpg" }, { "id": "lua-lua-5-4-reference-manual", @@ -5177,7 +5177,7 @@ "category": "advanced", "edition": "Official Reference", "driveUrl": "https://www.lua.org/manual/5.4/", - "coverImage": "" + "coverImage": "https://www.lua.org/images/lua-logo.gif" }, { "id": "lua-mastering-lua-programming", @@ -5187,7 +5187,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/mastering-lua-programming/9781785284359", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/16117563482887.jpg" }, { "id": "lua-roblox-lua-game-development", @@ -5197,7 +5197,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Coding-Roblox-Games-Made-Easy/dp/1803234678", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/13126183488948.jpg" }, { "id": "lua-crafting-interpreters-lua-friendly-patterns", @@ -5207,7 +5207,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://craftinginterpreters.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12075000-L.jpg" }, { "id": "lua-official-lua-documentation", @@ -5217,7 +5217,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.lua.org/docs.html", - "coverImage": "" + "coverImage": "https://www.lua.org/images/lua-logo.gif" }, { "id": "lua-lua-users-wiki", @@ -5227,7 +5227,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://lua-users.org/wiki/", - "coverImage": "" + "coverImage": "https://www.lua.org/images/lua-logo.gif" }, { "id": "matlab-matlab-for-engineers", @@ -5237,7 +5237,7 @@ "category": "beginner", "edition": "6th Edition", "driveUrl": "https://www.pearson.com/en-us/subject-catalog/p/matlab-for-engineers/P200000003316", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9478590-L.jpg" }, { "id": "matlab-getting-started-with-matlab", @@ -5247,7 +5247,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://matlabacademy.mathworks.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/4937707-L.jpg" }, { "id": "matlab-matlab-a-practical-introduction-to-programming-and-problem-solving", @@ -5257,7 +5257,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://www.amazon.com/MATLAB-Practical-Introduction-Programming-Problem/dp/0128154799", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10859306-L.jpg" }, { "id": "matlab-matlab-guide", @@ -5267,7 +5267,7 @@ "category": "intermediate", "edition": "3rd Edition", "driveUrl": "https://www.pearson.com/en-us/subject-catalog/p/matlab-guide/P200000003315", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1659605-L.jpg" }, { "id": "matlab-essential-matlab-for-engineers-and-scientists", @@ -5277,7 +5277,7 @@ "category": "intermediate", "edition": "7th Edition", "driveUrl": "https://www.amazon.com/Essential-MATLAB-Engineers-Scientists-Hahn/dp/0081029977", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/3743107-L.jpg" }, { "id": "matlab-accelerating-matlab-performance", @@ -5287,7 +5287,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Accelerating-MATLAB-Performance-Yair-Altman/dp/1482211297", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12595787-L.jpg" }, { "id": "matlab-matlab-differential-equations", @@ -5297,7 +5297,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/MATLAB-Differential-Equations-Stormy-Attaway/dp/0123945800", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10325521-L.jpg" }, { "id": "matlab-matlab-machine-learning-recipes", @@ -5307,7 +5307,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/MATLAB-Machine-Learning-Recipes-Beginners/dp/1484254570", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9334737-L.jpg" }, { "id": "matlab-digital-signal-processing-using-matlab", @@ -5317,7 +5317,7 @@ "category": "specialized", "edition": "4th Edition", "driveUrl": "https://www.amazon.com/Digital-Signal-Processing-Using-MATLAB/dp/1305635195", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/363866-L.jpg" }, { "id": "matlab-mathworks-matlab-documentation", @@ -5327,7 +5327,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.mathworks.com/help/releases/R2024a/matlab/index.html", - "coverImage": "" + "coverImage": "https://upload.wikimedia.org/wikipedia/commons/2/21/Matlab_Logo.png" }, { "id": "matlab-matlab-onramp", @@ -5337,7 +5337,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://matlabacademy.mathworks.com/", - "coverImage": "" + "coverImage": "https://matlabacademy.mathworks.com/images/course/panel_gettingstarted.webp" }, { "id": "assembly-code-the-hidden-language-of-computer-hardware-and-software", @@ -5347,7 +5347,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0137909101", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/460968-L.jpg" }, { "id": "assembly-programming-from-the-ground-up", @@ -5357,7 +5357,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://download-mirror.savannah.gnu.org/releases/pgubook/ProgrammingGroundUp-1-0-booksize.pdf", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15044383-L.jpg" }, { "id": "assembly-assembly-language-step-by-step", @@ -5367,7 +5367,7 @@ "category": "beginner", "edition": "3rd Edition", "driveUrl": "https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/303919-L.jpg" }, { "id": "assembly-x86-64-assembly-language-programming-with-ubuntu", @@ -5377,7 +5377,7 @@ "category": "intermediate", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/x86-64-Assembly-Language-Programming-Ubuntu/dp/0357117557", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1662949671i/62368204.jpg" }, { "id": "assembly-the-art-of-assembly-language", @@ -5387,7 +5387,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Art-Assembly-Language-2nd/dp/1593272073", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8619355-L.jpg" }, { "id": "assembly-computer-systems-a-programmer-s-perspective", @@ -5397,7 +5397,7 @@ "category": "advanced", "edition": "3rd Edition", "driveUrl": "https://www.amazon.com/Computer-Systems-Programmers-Perspective-3rd/dp/013409266X", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511531-L.jpg" }, { "id": "assembly-hacker-s-delight", @@ -5407,7 +5407,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Hackers-Delight-2nd-Henry-Warren/dp/0321842685", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/136606-L.jpg" }, { "id": "assembly-practical-reverse-engineering", @@ -5417,7 +5417,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Practical-Reverse-Engineering-Reversing-Obfuscation/dp/1119127604", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10637382-L.jpg" }, { "id": "assembly-practical-malware-analysis", @@ -5427,7 +5427,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Practical-Malware-Analysis-Hands-Dissecting/dp/1593272901", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8708643-L.jpg" }, { "id": "assembly-x86-instruction-reference", @@ -5437,7 +5437,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.felixcloutier.com/x86/", - "coverImage": "" + "coverImage": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Intel_logo_%282020%2C_light_blue%29.svg/200px-Intel_logo_%282020%2C_light_blue%29.svg.png" }, { "id": "assembly-x86-assembly-wikibooks", @@ -5447,7 +5447,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://en.wikibooks.org/wiki/X86_Assembly", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7589176-L.jpg" }, { "id": "haskell-learn-you-a-haskell-for-great-good", @@ -5457,7 +5457,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://learnyouahaskell.github.io/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8037819-L.jpg" }, { "id": "haskell-haskell-programming-from-first-principles", @@ -5467,7 +5467,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://haskellbook.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10540517-L.jpg" }, { "id": "haskell-get-programming-with-haskell", @@ -5477,7 +5477,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/get-programming-with-haskell", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8508994-L.jpg" }, { "id": "haskell-programming-in-haskell", @@ -5487,7 +5487,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Programming-Haskell-Graham-Hutton/dp/1316626229", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/353846-L.jpg" }, { "id": "haskell-haskell-in-depth", @@ -5497,7 +5497,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/haskell-in-depth", - "coverImage": "" + "coverImage": "https://images.manning.com/360/480/resize/book/5/3a10ab7-28a3-47d2-a160-e7d2bedc0fc5/Bragilevsky-Haskell-HI.png" }, { "id": "haskell-real-world-haskell", @@ -5507,7 +5507,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://github.com/realworldhaskell/book", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7170889-L.jpg" }, { "id": "haskell-parallel-and-concurrent-programming-in-haskell", @@ -5517,7 +5517,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/parallel-and-concurrent/9781449335939/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7863280-L.jpg" }, { "id": "haskell-thinking-with-types", @@ -5527,7 +5527,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://thinkingwithtypes.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/812786-L.jpg" }, { "id": "haskell-pearls-of-functional-algorithm-design", @@ -5537,7 +5537,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Pearls-Functional-Algorithm-Design/dp/0521513383", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7277380-L.jpg" }, { "id": "haskell-functional-design-and-architecture", @@ -5547,7 +5547,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/functional-design-and-architecture", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9966329-L.jpg" }, { "id": "haskell-official-haskell-documentation", @@ -5557,7 +5557,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.haskell.org/documentation/", - "coverImage": "" + "coverImage": "https://www.haskell.org/img/haskell-logo.svg" }, { "id": "haskell-hoogle", @@ -5567,7 +5567,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://hoogle.haskell.org/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6829398-L.jpg" }, { "id": "powershell-learn-windows-powershell-in-a-month-of-lunches", @@ -5577,7 +5577,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://www.manning.com/books/learn-powershell-in-a-month-of-lunches-fourth-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511906-L.jpg" }, { "id": "powershell-powershell-for-sysadmins", @@ -5587,7 +5587,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://nostarch.com/powershellsysadmins", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/13715210-L.jpg" }, { "id": "powershell-windows-powershell-cookbook", @@ -5597,7 +5597,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://www.oreilly.com/library/view/windows-powershell-cookbook/9781098164317/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1312622-L.jpg" }, { "id": "powershell-powershell-in-depth", @@ -5607,7 +5607,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/powershell-in-depth-second-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8513320-L.jpg" }, { "id": "powershell-learn-powershell-scripting-in-a-month-of-lunches", @@ -5617,7 +5617,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/learn-powershell-scripting-in-a-month-of-lunches-second-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8851745-L.jpg" }, { "id": "powershell-the-powershell-scripting-and-toolmaking-book", @@ -5627,7 +5627,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://leanpub.com/powershell-scripting-toolmaking", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/21283283482737.jpg" }, { "id": "powershell-powershell-for-pentesting", @@ -5637,7 +5637,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/PowerShell-Penetration-Testers-Mike-Fletcher/dp/1484293614", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/9887093482841.jpg" }, { "id": "powershell-learn-azure-in-a-month-of-lunches", @@ -5647,7 +5647,7 @@ "category": "specialized", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/learn-azure-in-a-month-of-lunches-second-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507529-L.jpg" }, { "id": "powershell-azure-powershell-quick-start-guide", @@ -5657,7 +5657,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/azure-powershell-quick-start-guide/9781789614954", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/4592793482825.jpg" }, { "id": "powershell-microsoft-powershell-documentation", @@ -5667,7 +5667,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://learn.microsoft.com/powershell/", - "coverImage": "" + "coverImage": "https://learn.microsoft.com/media/logos/logo-powershell-social.png" }, { "id": "powershell-powershell-gallery", @@ -5677,7 +5677,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://www.powershellgallery.com/", - "coverImage": "" + "coverImage": "https://powershellgallery.com/Content/Images/Branding/psgallerylogo-whiteinlay.png" }, { "id": "zig-zig-language-reference", @@ -5687,7 +5687,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://ziglang.org/documentation/master/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-introduction-to-zig", @@ -5697,7 +5697,7 @@ "category": "beginner", "edition": "Free online book", "driveUrl": "https://pedropark99.github.io/zig-book/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15235823-L.jpg" }, { "id": "zig-ziglearn", @@ -5707,7 +5707,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://ziglearn.org/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-zig-guide", @@ -5717,7 +5717,7 @@ "category": "intermediate", "edition": "Online Resource", "driveUrl": "https://zig.guide/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5934634-L.jpg" }, { "id": "zig-learning-zig", @@ -5727,7 +5727,7 @@ "category": "intermediate", "edition": "Online Resource", "driveUrl": "https://www.openmymind.net/learning_zig/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/15235831-L.jpg" }, { "id": "zig-zig-documentation-advanced-language-features", @@ -5737,7 +5737,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://ziglang.org/documentation/master/#Language-Reference", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-writing-an-os-in-zig-community-guides", @@ -5747,7 +5747,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://github.com/ziglang/zig", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-zig-build-system-documentation", @@ -5757,7 +5757,7 @@ "category": "specialized", "edition": "Online Resource", "driveUrl": "https://ziglang.org/learn/build-system/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-using-zig-as-a-c-compiler-cross-linker", @@ -5767,7 +5767,7 @@ "category": "specialized", "edition": "Online Resource", "driveUrl": "https://ziglang.org/learn/overview/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-official-zig-documentation", @@ -5777,7 +5777,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://ziglang.org/documentation/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "zig-zig-standard-library-docs", @@ -5787,7 +5787,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://ziglang.org/documentation/master/std/", - "coverImage": "" + "coverImage": "https://ziglang.org/favicon.png" }, { "id": "solidity-mastering-ethereum", @@ -5797,7 +5797,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://github.com/ethereumbook/ethereumbook", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507633-L.jpg" }, { "id": "solidity-solidity-by-example", @@ -5807,7 +5807,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://solidity-by-example.org/", - "coverImage": "" + "coverImage": "https://solidity-by-example.org/favicon.ico" }, { "id": "solidity-cryptozombies", @@ -5817,7 +5817,7 @@ "category": "beginner", "edition": "Online Resource", "driveUrl": "https://cryptozombies.io/", - "coverImage": "" + "coverImage": "https://cryptozombies.io/images/preview_image.png" }, { "id": "solidity-mastering-blockchain-programming-with-solidity", @@ -5827,7 +5827,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.packtpub.com/product/mastering-blockchain-programming-with-solidity/9781839218262", - "coverImage": "" + "coverImage": "https://images.isbndb.com/covers/23167443482842.jpg" }, { "id": "solidity-hands-on-smart-contract-development-with-solidity-and-ethereum", @@ -5837,7 +5837,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/hands-on-smart-contract/9781492045250/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/12419051-L.jpg" }, { "id": "solidity-ethereum-smart-contract-security-best-practices", @@ -5847,7 +5847,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://consensys.github.io/smart-contract-best-practices/", - "coverImage": "" + "coverImage": "https://consensys.io/favicon.ico" }, { "id": "solidity-ethernaut-capture-the-ether-style-challenges", @@ -5857,7 +5857,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://ethernaut.openzeppelin.com/", - "coverImage": "" + "coverImage": "https://ethernaut.openzeppelin.com/imgs/metatag.png" }, { "id": "solidity-building-ethereum-dapps", @@ -5867,7 +5867,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/building-ethereum-dapps", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8507547-L.jpg" }, { "id": "solidity-ethereum-developer-documentation", @@ -5877,7 +5877,7 @@ "category": "specialized", "edition": "Online Resource", "driveUrl": "https://ethereum.org/developers/docs/", - "coverImage": "" + "coverImage": "https://ethereum.org/images/heroes/developers-hub-hero.png" }, { "id": "solidity-solidity-language-documentation", @@ -5887,7 +5887,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://docs.soliditylang.org/", - "coverImage": "" + "coverImage": "https://docs.soliditylang.org/en/latest/_static/img/logo.svg" }, { "id": "solidity-ethereum-developer-docs", @@ -5897,7 +5897,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://ethereum.org/developers/docs/", - "coverImage": "" + "coverImage": "https://ethereum.org/images/heroes/developers-hub-hero.png" }, { "id": "perl-learning-perl", @@ -5907,7 +5907,7 @@ "category": "beginner", "edition": "8th Edition", "driveUrl": "https://www.oreilly.com/library/view/learning-perl-8th/9781492094920/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/805582-L.jpg" }, { "id": "perl-intermediate-perl", @@ -5917,7 +5917,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.oreilly.com/library/view/intermediate-perl-2nd/9781449343781/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8664045-L.jpg" }, { "id": "perl-beginning-perl", @@ -5927,7 +5927,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8622320-L.jpg" }, { "id": "perl-modern-perl", @@ -5937,7 +5937,7 @@ "category": "intermediate", "edition": "2014 Edition", "driveUrl": "https://www.modernperlbooks.com/books/modern_perl_2014/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10209454-L.jpg" }, { "id": "perl-programming-perl-the-camel-book", @@ -5947,7 +5947,7 @@ "category": "intermediate", "edition": "4th Edition", "driveUrl": "https://www.oreilly.com/library/view/programming-perl-4th/9781449321451/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/715250-L.jpg" }, { "id": "perl-higher-order-perl", @@ -5957,7 +5957,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://hop.perl.plover.com/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/784249-L.jpg" }, { "id": "perl-mastering-perl", @@ -5967,7 +5967,7 @@ "category": "advanced", "edition": "2nd Edition", "driveUrl": "https://www.oreilly.com/library/view/mastering-perl-2nd/9781449365233/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/1312598-L.jpg" }, { "id": "perl-beginning-perl-for-bioinformatics", @@ -5977,7 +5977,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/beginning-perl-for/0596000804/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388478-L.jpg" }, { "id": "perl-network-programming-with-perl", @@ -5987,7 +5987,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Network-Programming-Perl-Lincoln-Stein/dp/0201615711", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/135388-L.jpg" }, { "id": "perl-official-perl-documentation", @@ -5997,7 +5997,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://perldoc.perl.org/", - "coverImage": "" + "coverImage": "https://cdn.perl.org/perlweb/images/camel_head.png" }, { "id": "perl-perl-maven", @@ -6007,7 +6007,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://perlmaven.com/", - "coverImage": "" + "coverImage": "https://perlmaven.com/img/index.png" }, { "id": "fortran-modern-fortran-explained", @@ -6017,7 +6017,7 @@ "category": "beginner", "edition": "5th Edition", "driveUrl": "https://www.amazon.com/Modern-Fortran-Explained-Incorporating-Numerical/dp/0198850750", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/9290974-L.jpg" }, { "id": "fortran-fortran-for-scientists-and-engineers", @@ -6027,7 +6027,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://www.amazon.com/Fortran-Scientists-Engineers-Stephen-Chapman/dp/0073385891", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7391357-L.jpg" }, { "id": "fortran-introduction-to-programming-with-fortran", @@ -6037,7 +6037,7 @@ "category": "beginner", "edition": "4th Edition", "driveUrl": "https://www.amazon.com/Introduction-Programming-Fortran-Ian-Chivers/dp/3319754019", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/2036892-L.jpg" }, { "id": "fortran-modern-fortran-building-efficient-parallel-applications", @@ -6047,7 +6047,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/modern-fortran", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8696201-L.jpg" }, { "id": "fortran-fortran-95-2003-explained", @@ -6057,7 +6057,7 @@ "category": "intermediate", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/Fortran-95-2003-Explained-Numerical-Mathematics/dp/0198526938", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8747289-L.jpg" }, { "id": "fortran-openmp-application-programming-interface", @@ -6067,7 +6067,7 @@ "category": "advanced", "edition": "Online Resource", "driveUrl": "https://www.openmp.org/specifications/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10181184-L.jpg" }, { "id": "fortran-numerical-computing-with-modern-fortran", @@ -6077,7 +6077,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Numerical-Computing-Modern-Fortran/dp/1611973129", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7681954-L.jpg" }, { "id": "fortran-computational-physics-with-fortran", @@ -6087,7 +6087,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/Computational-Physics-Mark-Newman/dp/1480145513", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/14766640-L.jpg" }, { "id": "fortran-writing-scientific-software", @@ -6097,7 +6097,7 @@ "category": "specialized", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Writing-Scientific-Software-Guide-Good/dp/052186862X", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8735984-L.jpg" }, { "id": "fortran-fortran-standards-iso-references", @@ -6107,7 +6107,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://fortranwiki.org/", - "coverImage": "" + "coverImage": "https://fortran-lang.org/_static/images/favicon.ico" }, { "id": "fortran-fortran-discourse-community-docs", @@ -6117,7 +6117,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://fortran-lang.org/learn/", - "coverImage": "" + "coverImage": "https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/1X/50078338be6df8cfc3e2277e9cb3c805f45c6ee6.png" }, { "id": "objectivec-programming-in-objective-c", @@ -6127,7 +6127,7 @@ "category": "beginner", "edition": "6th Edition", "driveUrl": "https://www.amazon.com/Programming-Objective-C-6th-Developers-Library/dp/0321967607", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/410970-L.jpg" }, { "id": "objectivec-objective-c-programming-the-big-nerd-ranch-guide", @@ -6137,7 +6137,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Objective-C-Programming-Nerd-Ranch-Guides/dp/032194206X", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/410970-L.jpg" }, { "id": "objectivec-learn-objective-c-on-the-mac", @@ -6147,7 +6147,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.amazon.com/Learn-Objective-C-Mac-iOS/dp/1430241888", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8686249-L.jpg" }, { "id": "objectivec-cocoa-programming-for-os-x", @@ -6157,7 +6157,7 @@ "category": "intermediate", "edition": "5th Edition", "driveUrl": "https://www.amazon.com/Cocoa-Programming-OS-Nerd-Ranch/dp/0134076958", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/5732576-L.jpg" }, { "id": "objectivec-ios-programming-the-big-nerd-ranch-guide", @@ -6167,7 +6167,7 @@ "category": "intermediate", "edition": "7th Edition", "driveUrl": "https://www.amazon.com/iOS-Programming-Nerd-Ranch-Guide/dp/0135264022", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8449597-L.jpg" }, { "id": "objectivec-effective-objective-c-2-0", @@ -6177,7 +6177,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Effective-Objective-C-2-0-Specific/dp/0321917014", - "coverImage": "" + "coverImage": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1400889842i/17986273.jpg" }, { "id": "objectivec-advanced-mac-os-x-programming", @@ -6187,7 +6187,7 @@ "category": "advanced", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/Advanced-Mac-OS-Programming-Developers/dp/0321706583", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8614095-L.jpg" }, { "id": "objectivec-learning-cocoa-with-objective-c", @@ -6197,7 +6197,7 @@ "category": "specialized", "edition": "4th Edition", "driveUrl": "https://www.oreilly.com/library/view/learning-cocoa-with/9781491901397/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/388634-L.jpg" }, { "id": "objectivec-objective-c-for-absolute-beginners-ios-path", @@ -6207,7 +6207,7 @@ "category": "specialized", "edition": "5th Edition", "driveUrl": "https://www.amazon.com/Objective-C-Absolute-Beginners-iPhone-Programming/dp/1484247041", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8701366-L.jpg" }, { "id": "objectivec-apple-objective-c-documentation", @@ -6217,7 +6217,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://developer.apple.com/documentation/objectivec", - "coverImage": "" + "coverImage": "https://developer.apple.com/favicon.ico" }, { "id": "objectivec-apple-cocoa-documentation", @@ -6227,7 +6227,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://developer.apple.com/documentation/", - "coverImage": "" + "coverImage": "https://developer.apple.com/favicon.ico" }, { "id": "clojure-clojure-for-the-brave-and-true", @@ -6237,7 +6237,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.braveclojure.com/clojure-for-the-brave-and-true/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/10587583-L.jpg" }, { "id": "clojure-clojure-in-action", @@ -6247,7 +6247,7 @@ "category": "beginner", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/clojure-in-action", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8511671-L.jpg" }, { "id": "clojure-living-clojure", @@ -6257,7 +6257,7 @@ "category": "beginner", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/living-clojure/9781491909270/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8954082-L.jpg" }, { "id": "clojure-clojure-programming", @@ -6267,7 +6267,7 @@ "category": "intermediate", "edition": "1st Edition", "driveUrl": "https://www.oreilly.com/library/view/clojure-programming/9781449310387/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7440852-L.jpg" }, { "id": "clojure-the-joy-of-clojure", @@ -6277,7 +6277,7 @@ "category": "intermediate", "edition": "2nd Edition", "driveUrl": "https://www.manning.com/books/the-joy-of-clojure-second-edition", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/6718306-L.jpg" }, { "id": "clojure-clojure-the-essential-reference", @@ -6287,7 +6287,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.manning.com/books/clojure-the-essential-reference", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/7440852-L.jpg" }, { "id": "clojure-professional-clojure", @@ -6297,7 +6297,7 @@ "category": "advanced", "edition": "1st Edition", "driveUrl": "https://www.amazon.com/Professional-Clojure-Jeremy-Anderson/dp/1119267277", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8512563-L.jpg" }, { "id": "clojure-web-development-with-clojure", @@ -6307,7 +6307,7 @@ "category": "specialized", "edition": "3rd Edition", "driveUrl": "https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/", - "coverImage": "" + "coverImage": "https://covers.openlibrary.org/b/id/8514199-L.jpg" }, { "id": "clojure-clojurescript-unraveled", @@ -6317,7 +6317,7 @@ "category": "specialized", "edition": "Latest Edition", "driveUrl": "https://www.amazon.com/ClojureScript-Unraveled-Andrey-Antov/dp/1680503006", - "coverImage": "" + "coverImage": "https://d2sofvawe08yqg.cloudfront.net/clojurescript-unraveled/s_hero2x?1620483763&1620483763" }, { "id": "clojure-official-clojure-documentation", @@ -6327,7 +6327,7 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://clojure.org/reference/documentation", - "coverImage": "" + "coverImage": "https://clojure.org/images/clojure-logo-icon-256.png" }, { "id": "clojure-clojuredocs", @@ -6337,6 +6337,6 @@ "category": "references", "edition": "Online Resource", "driveUrl": "https://clojuredocs.org/", - "coverImage": "" + "coverImage": "https://avatars.githubusercontent.com/u/620509?s=200&v=4" } ]