{
  "properties": {
    "config": {
      "description": "Full or partial configuration object. Any missing fields use defaults. If both configUrl and config are set, configUrl takes precedence.",
      "properties": {
        "contentGuard": {
          "properties": {
            "enableLTBEEFDetection": {
              "description": "Enable LTBEEF exploit GUI detection (default: true)",
              "type": "boolean"
            },
            "enabled": {
              "description": "Enable content guard protection (default: true)",
              "type": "boolean"
            },
            "maxHistoryPushesPerSecond": {
              "description": "History pushState threshold per second before triggering flood detection (default: 50)",
              "type": "integer"
            }
          },
          "type": "object"
        },
        "domains": {
          "properties": {
            "additionalBlacklist": {
              "description": "Additional domains to block via dynamic rules (matched at network origin). Example: 'unblockedgames.io'",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "additionalUrlFilters": {
              "description": "Additional DNR urlFilter patterns to block (main_frame and sub_frame only). Use for path-prefix blocks where the origin itself is legitimate. Example: '||sites.google.com/classroom.center/' to block a specific Google Sites owner-path without blocking sites.google.com as a whole.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "additionalWhitelist": {
              "description": "Additional domains to whitelist (added to built-in educational whitelist)",
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          },
          "type": "object"
        },
        "googleSitesInspector": {
          "properties": {
            "additionalIframeAllowlist": {
              "description": "Additional iframe origins to permit when enableStrictSitesMode is true. Each entry can be: an exact hostname ('phet.colorado.edu'), a hostname-suffix pattern starting with a dot ('.example.com' matches example.com and any subdomain), or a full URL prefix ('https://script.google.com/macros/' allows any URL starting with that prefix). Use URL-prefix entries to permit specific paths on otherwise-blocked hosts (e.g. allow Apps Script web apps without unblocking the rest of script.google.com).",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "enableAppsScriptDetection": {
              "description": "Block Google-hosted game embeds on Google Sites when the parent page URL matches known unblocked-games-hub patterns (e.g. drive-u-, unblocked-games-, proxy-hub-). Covers Apps Script web apps (script.google.com/macros/.../exec), the Sites Embed Code widget intermediate frame (gstatic.com/atari/embeds/...), and the per-tenant inner frame (*.atari-embeds.googleusercontent.com/embeds/...). Legitimate teacher embeds on normal-named class pages are unaffected (default: true)",
              "type": "boolean"
            },
            "enableBase64Detection": {
              "description": "Detect Base64-encoded game content in scripts (default: true)",
              "type": "boolean"
            },
            "enableBlobBlocking": {
              "description": "Block blob URL iframes on Google Sites (default: true)",
              "type": "boolean"
            },
            "enableGameDetection": {
              "description": "Detect and block game engine signatures in iframes (default: true)",
              "type": "boolean"
            },
            "enableStrictSitesMode": {
              "description": "Tier 3 default-deny mode. When true, blocks ALL cross-origin iframes on sites.google.com except those matching the built-in or admin-extended allowlist (additionalIframeAllowlist). Strongest available defense against evasion-hub iframe embedding, but will break legitimate teacher embeds for any service not in the allowlist \u2014 recommended only for districts willing to maintain additions. Built-in allowlist covers Google services (docs, calendar, drive, maps, YouTube), major educational platforms (PhET, GeoGebra, Desmos, Khan, Quizlet, Nearpod, Padlet, Quizizz, Blooket, CommonLit, Newsela, BrainPOP, Canva, Prezi, etc.), and common code playgrounds (CodePen, JSFiddle, Replit, Scratch, Tinkercad). NOT in default allowlist (most-abused surfaces): script.google.com, www.gstatic.com, *.atari-embeds.googleusercontent.com \u2014 districts that need these can add them to additionalIframeAllowlist. Default: false (use multi-signal detection only)",
              "type": "boolean"
            },
            "enableWorkerDetection": {
              "description": "Detect Cloudflare Worker proxy iframes (default: true)",
              "type": "boolean"
            },
            "enabled": {
              "description": "Master toggle for the entire Google Sites inspector. Set to false to disable all sites.google.com DOM inspection \u2014 useful as a panic switch if a release interferes with a legitimate resource (default: true)",
              "type": "boolean"
            },
            "minSuspiciousFrameSize": {
              "description": "Minimum iframe pixel size to be considered suspicious (default: 400)",
              "type": "integer"
            },
            "scanInterval": {
              "description": "Iframe scan interval in ms (default: 2000)",
              "type": "integer"
            }
          },
          "type": "object"
        },
        "heartbeat": {
          "properties": {
            "enabled": {
              "description": "Enable heartbeat monitoring (default: true)",
              "type": "boolean"
            },
            "interval": {
              "description": "Heartbeat check interval in ms (default: 5000)",
              "type": "integer"
            }
          },
          "type": "object"
        },
        "rules": {
          "description": "Toggle individual blocking rules by ID. Keys are rule IDs (e.g. '1002'). Each value is an object with an 'enabled' boolean.",
          "patternProperties": {
            "^[0-9]+$": {
              "properties": {
                "enabled": {
                  "type": "boolean"
                }
              },
              "type": "object"
            }
          },
          "type": "object"
        },
        "tabLimits": {
          "properties": {
            "maxTabs": {
              "description": "Maximum total tabs allowed (default: 15)",
              "type": "integer"
            },
            "maxTabsInWindow": {
              "description": "Max tabs created within the time window before triggering spam detection (default: 5)",
              "type": "integer"
            },
            "tabCreationWindow": {
              "description": "Time window in ms for spam detection (default: 2000)",
              "type": "integer"
            }
          },
          "type": "object"
        },
        "version": {
          "description": "Schema version number",
          "type": "integer"
        }
      },
      "title": "Inline Configuration",
      "type": "object"
    },
    "configUrl": {
      "description": "URL to a hosted JSON configuration file. The extension will fetch this on startup and periodically refresh it.",
      "title": "Configuration URL",
      "type": "string"
    }
  },
  "type": "object"
}