// src/types.ts
var Operations = /* @__PURE__ */ ((Operations2) => {
  Operations2["SUBTRACT"] = "-";
  Operations2["ADD"] = "+";
  Operations2["MULTIPLY"] = "*";
  Operations2["DIVIDE"] = "/";
  Operations2["POWER"] = "^";
  Operations2["LOGIC_AND"] = "&&";
  Operations2["LOGIC_OR"] = "||";
  Operations2["LOGIC_NOT"] = "!";
  return Operations2;
})(Operations || {});
var SupportedFormats = /* @__PURE__ */ ((SupportedFormats2) => {
  SupportedFormats2["PX"] = "px";
  SupportedFormats2["EM"] = "em";
  SupportedFormats2["REM"] = "rem";
  SupportedFormats2["VW"] = "vw";
  SupportedFormats2["VH"] = "vh";
  SupportedFormats2["PT"] = "pt";
  SupportedFormats2["IN"] = "in";
  SupportedFormats2["CM"] = "cm";
  SupportedFormats2["MM"] = "mm";
  SupportedFormats2["DEG"] = "deg";
  SupportedFormats2["PERCENTAGE"] = "%";
  return SupportedFormats2;
})(SupportedFormats || {});
var ReservedKeyword = /* @__PURE__ */ ((ReservedKeyword2) => {
  ReservedKeyword2["TRUE"] = "true";
  ReservedKeyword2["FALSE"] = "false";
  ReservedKeyword2["NULL"] = "null";
  ReservedKeyword2["UNDEFINED"] = "undefined";
  ReservedKeyword2["WHILE"] = "while";
  ReservedKeyword2["IF"] = "if";
  ReservedKeyword2["ELSE"] = "else";
  ReservedKeyword2["ELIF"] = "elif";
  ReservedKeyword2["RETURN"] = "return";
  ReservedKeyword2["VARIABLE"] = "variable";
  return ReservedKeyword2;
})(ReservedKeyword || {});

// src/interpreter/errors.ts
var LanguageError = class extends Error {
  constructor(message, line, token, meta) {
    super(message);
    this.name = this.constructor.name;
    this.line = line;
    if (token && !line && token.line) {
      this.line = token.line;
    }
    this.token = token;
    this.originalMessage = message;
    this.message = this.formatMessage();
    this.meta = meta;
  }
  formatMessage() {
    let base = this.message;
    if (this.line !== void 0) {
      base = `Line ${this.line}: ${base}`;
    }
    if (this.token?.value) {
      base += `
Near token: ${String(this.token.value)}`;
    }
    return base;
  }
};
var InterpreterError = class extends LanguageError {
  constructor(message, line, token, meta, type) {
    super(message, line, token, meta);
    this.name = "InterpreterError";
    this.type = type;
  }
};

// src/interpreter/utils/type.ts
var isSome = (v) => {
  return v != null;
};
var isNone = (v) => {
  return v == null;
};
var isNull = (v) => {
  return v === null;
};
var isUndefined = (v) => {
  return v === void 0;
};
var isObject = (v) => {
  return typeof v === "object" && v !== null && !Array.isArray(v);
};
var isString = (v) => {
  return typeof v === "string";
};
var isNumber = (v) => {
  return typeof v === "number" && !Number.isNaN(v);
};
var isArray = (v) => {
  return Array.isArray(v);
};
var isMap = (v) => v instanceof Map;
var isOutOfBounds = (value, index) => {
  if (!isArray(value)) return true;
  return index < 0 || index >= value.length;
};
var isOutOfBoundsInclusive = (value, index) => {
  if (!isArray(value)) return true;
  return index < 0 || index > value.length;
};
var nullToUndefined = (v) => isNull(v) ? void 0 : v;

// src/interpreter/utils/color.ts
function isValidHex(value) {
  if (!isString(value)) return false;
  if (!value.startsWith("#")) return false;
  const hexPart = value.substring(1);
  if (!(hexPart.length === 3 || hexPart.length === 6)) return false;
  for (let i = 0; i < hexPart.length; i++) {
    const char = hexPart[i].toLowerCase();
    if (!(char >= "0" && char <= "9" || char >= "a" && char <= "f")) {
      return false;
    }
  }
  return true;
}

// src/interpreter/utils/string.ts
var capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1).toLowerCase()}`;

// src/interpreter/symbols.ts
var typeEquals = (typeA, typeB) => typeA?.toLowerCase() === typeB?.toLowerCase();
var typeName = (base, sub) => {
  const baseStr = capitalize(base);
  if (sub) {
    const subStr = capitalize(sub);
    return `${baseStr}.${subStr}`;
  }
  return baseStr;
};
var formatObjectEntries = (data) => {
  let entries;
  if (isArray(data)) {
    entries = data;
  } else if (isMap(data)) {
    entries = Array.from(data.entries());
  } else {
    entries = Object.entries(data);
  }
  const formattedEntries = entries.map(([key, value]) => `${key}: ${String(value)}`).join(", ");
  return `{${formattedEntries}}`;
};
var expectStringKey = (key) => {
  if (isString(key)) {
    return key;
  }
  if (key instanceof StringSymbol && isSome(key.value)) {
    return key.value;
  }
  throw new InterpreterError(`Key must be a StringSymbol or string, got ${typeof key}.`);
};
var DictionaryImpl = {
  get(value, key, config) {
    const keyStr = expectStringKey(key);
    const result = value.get(keyStr);
    if (isSome(result)) {
      return result;
    }
    return new NullSymbol(config);
  },
  set(value, key, val) {
    const keyStr = expectStringKey(key);
    value.set(keyStr, val.cloneIfMutable());
  },
  deleteKey(value, key) {
    const keyStr = expectStringKey(key);
    value.delete(keyStr);
  },
  keys(value, config) {
    const keys = Array.from(value.keys()).map((key) => new StringSymbol(key, config));
    return new ListSymbol(keys, false, config);
  },
  values(value, config) {
    const values = Array.from(value.values());
    return new ListSymbol(values, false, config);
  },
  keyExists(value, key, config) {
    const keyStr = expectStringKey(key);
    return new BooleanSymbol(value.has(keyStr), config);
  },
  length(value, config) {
    return new NumberSymbol(value.size, config);
  },
  clear(value) {
    value.clear();
  },
  deepCopy(value) {
    const copiedMap = /* @__PURE__ */ new Map();
    for (const [key, val] of value.entries()) {
      copiedMap.set(key, val.deepCopy());
    }
    return copiedMap;
  },
  toString(value) {
    return formatObjectEntries(value);
  },
  hasAttribute(value, attributeName) {
    return value.has(attributeName);
  },
  getAttribute(value, attributeName) {
    const val = value.get(attributeName);
    return val !== void 0 ? val : null;
  }
};
var ListImpl = {
  append(value, item) {
    value.push(item.cloneIfMutable());
  },
  extend(value, ...items) {
    for (const item of items) {
      if (item instanceof ListSymbol) {
        value.push(...item.value.map((element) => element.cloneIfMutable()));
      } else {
        value.push(item.cloneIfMutable());
      }
    }
  },
  insert(value, indexSymbol, item) {
    const index = indexSymbol.value;
    if (isOutOfBoundsInclusive(value, index)) {
      throw new InterpreterError("Index out of range for insert.");
    }
    value.splice(index, 0, item.cloneIfMutable());
  },
  deleteAt(value, indexSymbol) {
    const index = indexSymbol.value;
    if (isOutOfBounds(value, index)) {
      throw new InterpreterError("Index out of range for deletion.");
    }
    value.splice(index, 1);
  },
  length(value, config) {
    return new NumberSymbol(value.length, config);
  },
  indexOf(value, item, config) {
    const idx = value.findIndex((el) => el.equals(item));
    return new NumberSymbol(idx, config);
  },
  get(value, indexSymbol) {
    const index = indexSymbol.value;
    if (isOutOfBounds(value, index)) {
      throw new InterpreterError("Index out of range for get.");
    }
    return value[index];
  },
  update(value, indexSymbol, item) {
    const index = indexSymbol.value;
    if (isOutOfBounds(value, index)) {
      throw new InterpreterError("Index out of range for update.");
    }
    value[index] = item.cloneIfMutable();
  },
  join(value, separator, config) {
    const sep = separator?.value || "";
    const stringElements = value.map((element) => {
      if (element.value === null) {
        return "null";
      }
      return element.toString();
    });
    return new StringSymbol(stringElements.join(sep), config);
  },
  deepCopy(value) {
    return value.map((element) => element.deepCopy());
  },
  toString(value, isImplicit = false) {
    const delimiter = isImplicit ? " " : ", ";
    return value.map((x) => x.value === null ? "null" : x.toString()).join(delimiter);
  }
};
var BaseSymbolType = class {
  constructor(value, config) {
    this.value = value;
    this.config = config;
  }
  toString() {
    return String(this.value);
  }
  getTypeName() {
    return this.type;
  }
  typeEquals(other) {
    return typeEquals(this.type, other.type);
  }
  equals(other) {
    return this.typeEquals(other) && this.value === other.value;
  }
  hasMethod(methodName, args) {
    const methodDefinition = this.constructor._SUPPORTED_METHODS?.[methodName.toLowerCase()];
    if (!methodDefinition) return false;
    if (methodDefinition.args.length === 0) return true;
    const requiredArgs = methodDefinition.args.filter((arg) => !arg.optional);
    if (args.length < requiredArgs.length) {
      return false;
    }
    if (args.length > methodDefinition.args.length) {
      return false;
    }
    return true;
  }
  callMethod(methodName, args) {
    const methodDefinition = this.constructor._SUPPORTED_METHODS?.[methodName.toLowerCase()];
    if (!methodDefinition || !this.hasMethod?.(methodName, args)) {
      throw new InterpreterError(
        `Method '${methodName}' not found or invalid arguments on type '${this.type}'.`
      );
    }
    if (methodDefinition.args.length === 0) {
      return methodDefinition.function.call(this, ...args);
    }
    const processedArgs = [];
    methodDefinition.args.forEach((argDef, index) => {
      if (args[index] !== void 0) {
        processedArgs.push(args[index]);
      } else if (!argDef.optional) {
        throw new InterpreterError(
          `Missing required argument '${argDef.name}' for method '${methodName}'.`
        );
      }
    });
    return methodDefinition.function.call(this, ...processedArgs);
  }
  hasAttribute(_attributeName) {
    return false;
  }
  getAttribute(attributeName) {
    throw new InterpreterError(`Attribute '${attributeName}' not found on type '${this.type}'.`);
  }
  setAttribute(attributeName, _value) {
    throw new InterpreterError(`Cannot set attribute '${attributeName}' on type '${this.type}'.`);
  }
};
var _NullSymbol = class _NullSymbol extends BaseSymbolType {
  constructor(config) {
    super(null, config);
    this.type = "Null";
  }
  validValue(val) {
    return isNone(val);
  }
  toString() {
    return "null";
  }
  deepCopy() {
    return new _NullSymbol(this.config);
  }
  cloneIfMutable() {
    return this;
  }
  equals(other) {
    return other instanceof _NullSymbol;
  }
  static empty() {
    return new _NullSymbol();
  }
};
_NullSymbol.type = "Null";
var NullSymbol = _NullSymbol;
var _NumberSymbol = class _NumberSymbol extends BaseSymbolType {
  constructor(value, config) {
    let safeValue;
    if (isNumber(value)) {
      safeValue = value;
    } else if (value instanceof _NumberSymbol || value instanceof NumberWithUnitSymbol) {
      safeValue = value.value;
    } else if (isNull(value)) {
      safeValue = null;
    } else {
      throw new InterpreterError(`Value must be int or float, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "Number";
    this.value = safeValue;
  }
  validValue(val) {
    return isNumber(val) || val instanceof _NumberSymbol;
  }
  expectSafeValue(val) {
    if (isNone(val)) {
      throw new InterpreterError("Value must be int or float, got null.");
    }
  }
  toString() {
    return String(this.value);
  }
  deepCopy() {
    return new _NumberSymbol(this.value, this.config);
  }
  cloneIfMutable() {
    return this;
  }
  static empty() {
    return new _NumberSymbol(null);
  }
  hasAttribute(attributeName) {
    return attributeName === "value";
  }
  getAttribute(attributeName) {
    if (attributeName === "value") {
      return new _NumberSymbol(this.value, this.config);
    }
    throw new InterpreterError(`Attribute '${attributeName}' not found on Number.`);
  }
  // Direct translation of to_string method from token_interpreter/symbols.py
  toStringSymbol(radix) {
    this.expectSafeValue(this.value);
    if (radix) {
      this.expectSafeValue(radix?.value);
    } else {
      return new StringSymbol(String(this.value), this.config);
    }
    const base = radix.value;
    if (!Number.isInteger(base) || base < 2 || base > 36) {
      throw new InterpreterError(`Invalid radix: ${base}. Must be between 2 and 36.`);
    }
    let numValue;
    if (base === 16) {
      numValue = Math.round(this.value);
      const fractionalPart = Math.abs(this.value % 1);
      if (fractionalPart === 0.5) {
        numValue = Math.floor(this.value);
      } else {
        numValue = Math.round(this.value);
      }
    } else {
      numValue = this.value;
    }
    try {
      if (Number.isInteger(numValue) && radix) {
        return new StringSymbol(numValue.toString(base), this.config);
      } else {
        return new StringSymbol(String(this.value), this.config);
      }
    } catch (e) {
      throw new InterpreterError(`Error converting to base ${base}: ${String(e)}.`);
    }
  }
};
_NumberSymbol.type = "Number";
_NumberSymbol._SUPPORTED_METHODS = {
  to_string: {
    name: "to_string",
    function: function(radix) {
      return this.toStringSymbol(radix);
    },
    args: [
      {
        name: "radix",
        type: "Number",
        optional: true
      }
    ],
    returnType: "String"
  }
};
var NumberSymbol = _NumberSymbol;
var _StringSymbol = class _StringSymbol extends BaseSymbolType {
  constructor(value, config) {
    let safeValue;
    if (typeof value === "string") {
      safeValue = value;
    } else if (value instanceof _StringSymbol) {
      safeValue = value.value;
    } else if (value === null) {
      safeValue = null;
    } else {
      throw new InterpreterError(`Value must be string, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "String";
    this.value = safeValue;
  }
  validValue(val) {
    return typeof val === "string" || val instanceof _StringSymbol;
  }
  expectSafeValue(val) {
    if (val === null || val === void 0) {
      throw new InterpreterError("Value must be a string, got null.");
    }
  }
  upper() {
    this.expectSafeValue(this.value);
    return new _StringSymbol(this.value.toUpperCase(), this.config);
  }
  deepCopy() {
    return new _StringSymbol(this.value, this.config);
  }
  cloneIfMutable() {
    return this;
  }
  static empty() {
    return new _StringSymbol(null);
  }
  lower() {
    this.expectSafeValue(this.value);
    return new _StringSymbol(this.value.toLowerCase(), this.config);
  }
  length() {
    this.expectSafeValue(this.value);
    return new NumberSymbol(this.value.length, this.config);
  }
  concat(other) {
    this.expectSafeValue(this.value);
    if (other instanceof _StringSymbol) {
      other.expectSafeValue(other.value);
      return new _StringSymbol(this.value + other.value, this.config);
    }
    throw new InterpreterError(`Cannot concatenate String ${typeof other} to String.`);
  }
  split(delimiter) {
    this.expectSafeValue(this.value);
    const strValue = this.value;
    if (delimiter instanceof _StringSymbol) {
      const parts = strValue.split(delimiter.value);
      return new ListSymbol(
        parts.map((p) => new _StringSymbol(p, this.config)),
        false,
        this.config
      );
    } else if (typeof delimiter === "string") {
      const parts = strValue.split(delimiter);
      return new ListSymbol(
        parts.map((p) => new _StringSymbol(p, this.config)),
        false,
        this.config
      );
    } else if (delimiter === void 0 || delimiter === null) {
      const parts = Array.from(strValue);
      return new ListSymbol(
        parts.map((p) => new _StringSymbol(p, this.config)),
        false,
        this.config
      );
    }
    throw new InterpreterError(`Cannot split String by ${typeof delimiter}.`);
  }
};
_StringSymbol.type = "String";
_StringSymbol._SUPPORTED_METHODS = {
  upper: {
    function: function() {
      return this.upper();
    },
    args: [],
    returnType: "String"
  },
  lower: {
    function: function() {
      return this.lower();
    },
    args: [],
    returnType: "String"
  },
  length: {
    function: function() {
      return this.length();
    },
    args: [],
    returnType: "Number"
  },
  concat: {
    function: function(other) {
      return this.concat(other);
    },
    args: [{ name: "other", type: "String" }],
    returnType: "String"
  },
  split: {
    function: function(delimiter) {
      return this.split(delimiter);
    },
    args: [{ name: "delimiter", type: "String", optional: true }],
    returnType: "List"
  }
};
var StringSymbol = _StringSymbol;
var _BooleanSymbol = class _BooleanSymbol extends BaseSymbolType {
  constructor(value, config) {
    let safeValue;
    if (typeof value === "boolean") {
      safeValue = value;
    } else if (value instanceof _BooleanSymbol) {
      safeValue = value.value;
    } else if (value === null) {
      safeValue = null;
    } else {
      throw new InterpreterError(`Value must be boolean, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "Boolean";
    this.value = safeValue;
  }
  validValue(val) {
    return typeof val === "boolean" || val instanceof _BooleanSymbol;
  }
  expectSafeValue(val) {
    if (val === null || val === void 0) {
      throw new InterpreterError("Value must be a boolean, got null.");
    }
  }
  deepCopy() {
    return new _BooleanSymbol(this.value, this.config);
  }
  cloneIfMutable() {
    return this;
  }
  static empty() {
    return new _BooleanSymbol(null);
  }
};
_BooleanSymbol.type = "Boolean";
var BooleanSymbol = _BooleanSymbol;
var _ListSymbol = class _ListSymbol extends BaseSymbolType {
  constructor(elements, isImplicit = false, config) {
    const safeElements = elements === null ? [] : elements;
    super(safeElements, config);
    this.type = "List";
    this.value = safeElements;
    this.isImplicit = isImplicit;
  }
  validValue(val) {
    return Array.isArray(val) || val instanceof _ListSymbol;
  }
  toString() {
    return ListImpl.toString(this.value, this.isImplicit);
  }
  append(item) {
    ListImpl.append(this.value, item);
    return this;
  }
  extend(...items) {
    ListImpl.extend(this.value, ...items);
    return this;
  }
  insert(indexSymbol, item) {
    ListImpl.insert(this.value, indexSymbol, item);
    return this;
  }
  delete(indexSymbol) {
    ListImpl.deleteAt(this.value, indexSymbol);
    return this;
  }
  length() {
    return ListImpl.length(this.value, this.config);
  }
  index(item) {
    return ListImpl.indexOf(this.value, item, this.config);
  }
  get(indexSymbol) {
    return ListImpl.get(this.value, indexSymbol);
  }
  update(indexSymbol, item) {
    ListImpl.update(this.value, indexSymbol, item);
    return this;
  }
  join(separator) {
    return ListImpl.join(this.value, separator, this.config);
  }
  deepCopy() {
    const copiedElements = ListImpl.deepCopy(this.value);
    return new _ListSymbol(copiedElements, this.isImplicit, this.config);
  }
  cloneIfMutable() {
    return this.deepCopy();
  }
  static empty() {
    return new _ListSymbol(null);
  }
  getTypeName() {
    return this.isImplicit ? typeName(this.type, "Implicit") : typeName(this.type);
  }
};
_ListSymbol.type = "List";
_ListSymbol._SUPPORTED_METHODS = {
  append: {
    function: function(item) {
      return this.append(item);
    },
    args: [{ name: "item", type: "any" }],
    returnType: "List"
  },
  extend: {
    function: function(...items) {
      return this.extend(...items);
    },
    args: [],
    returnType: "List"
  },
  insert: {
    function: function(index, item) {
      return this.insert(index, item);
    },
    args: [
      { name: "index", type: "Number" },
      { name: "item", type: "any" }
    ],
    returnType: "List"
  },
  delete: {
    function: function(index) {
      return this.delete(index);
    },
    args: [{ name: "index", type: "Number" }],
    returnType: "List"
  },
  length: {
    function: function() {
      return this.length();
    },
    args: [],
    returnType: "Number"
  },
  index: {
    function: function(item) {
      return this.index(item);
    },
    args: [{ name: "item", type: "any" }],
    returnType: "Number"
  },
  get: {
    function: function(index) {
      return this.get(index);
    },
    args: [{ name: "index", type: "Number" }],
    returnType: "any"
  },
  update: {
    function: function(index, item) {
      return this.update(index, item);
    },
    args: [
      { name: "index", type: "Number" },
      { name: "item", type: "any" }
    ],
    returnType: "List"
  },
  join: {
    function: function(separator) {
      return this.join(separator);
    },
    args: [{ name: "separator", type: "String", optional: true }],
    returnType: "String"
  }
};
var ListSymbol = _ListSymbol;
var _NumberWithUnitSymbol = class _NumberWithUnitSymbol extends BaseSymbolType {
  constructor(value, unit, config) {
    let safeValue;
    if (typeof value === "number") {
      safeValue = value;
    } else if (value instanceof NumberSymbol) {
      safeValue = value.value;
    } else if (value === null) {
      safeValue = null;
    } else {
      throw new InterpreterError(`Value must be number or NumberSymbol, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "NumberWithUnit";
    this.value = safeValue;
    if (typeof unit === "string" && !Object.values(SupportedFormats).includes(unit)) {
      throw new InterpreterError(`Invalid unit: ${unit}`);
    }
    this.unit = typeof unit === "string" ? unit : unit;
  }
  validValue(val) {
    return val instanceof _NumberWithUnitSymbol;
  }
  static fromRecord(record, config) {
    if (record === null || typeof record !== "object") return;
    if (record.type !== "NumberWithUnit") return;
    if (!record.value && !record.unit) return;
    if (typeof record.value !== "number") return;
    return new _NumberWithUnitSymbol(record.value, record.unit, config);
  }
  toString() {
    return `${this.value}${this.unit}`;
  }
  expectSafeValue(val) {
    if (val === null || val === void 0) {
      throw new InterpreterError("Value must be a number, got null.");
    }
  }
  toStringSymbol() {
    this.expectSafeValue(this.value);
    return new StringSymbol(`${this.value}${this.unit}`, this.config);
  }
  to_number() {
    this.expectSafeValue(this.value);
    return new NumberSymbol(this.value, this.config);
  }
  equals(other) {
    return other instanceof _NumberWithUnitSymbol && this.value === other.value && this.unit.toLowerCase() === other?.unit.toLowerCase();
  }
  deepCopy() {
    return new _NumberWithUnitSymbol(this.value, this.unit, this.config);
  }
  cloneIfMutable() {
    return this;
  }
  static empty() {
    return new _NumberWithUnitSymbol(null, "px");
  }
  hasAttribute(attributeName) {
    return attributeName === "value";
  }
  getAttribute(attributeName) {
    if (attributeName === "value") {
      return new NumberSymbol(this.value, this.config);
    }
    throw new InterpreterError(`Attribute '${attributeName}' not found on NumberWithUnit.`);
  }
  getTypeName() {
    return `${this.type}.${capitalize(this.unit)}`;
  }
};
_NumberWithUnitSymbol.type = "NumberWithUnit";
_NumberWithUnitSymbol._SUPPORTED_METHODS = {
  to_string: {
    name: "to_string",
    function: function() {
      return this.toStringSymbol();
    },
    args: [
      {
        name: "radix",
        type: "Number",
        optional: true
      }
    ],
    returnType: "String"
  },
  to_number: {
    function: function() {
      return this.to_number();
    },
    args: [],
    returnType: "Number"
  }
};
var NumberWithUnitSymbol = _NumberWithUnitSymbol;
var _DictionarySymbol = class _DictionarySymbol extends BaseSymbolType {
  constructor(value, config) {
    let safeValue;
    if (value instanceof _DictionarySymbol) {
      safeValue = value.value;
    } else if (isMap(value)) {
      safeValue = value;
    } else if (isNull(value)) {
      safeValue = /* @__PURE__ */ new Map();
    } else if (isObject(value)) {
      safeValue = new Map(Object.entries(value));
    } else {
      throw new InterpreterError(`Value must be dict, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "Dictionary";
    this.value = safeValue;
  }
  validValue(val) {
    return isMap(val) || isNull(val);
  }
  toString() {
    return DictionaryImpl.toString(this.value);
  }
  get(key) {
    return DictionaryImpl.get(this.value, key, this.config);
  }
  set(key, value) {
    DictionaryImpl.set(this.value, key, value);
    return this;
  }
  delete(key) {
    DictionaryImpl.deleteKey(this.value, key);
    return this;
  }
  keys() {
    return DictionaryImpl.keys(this.value, this.config);
  }
  values() {
    return DictionaryImpl.values(this.value, this.config);
  }
  keyExists(key) {
    return DictionaryImpl.keyExists(this.value, key, this.config);
  }
  length() {
    return DictionaryImpl.length(this.value, this.config);
  }
  clear() {
    DictionaryImpl.clear(this.value);
    return this;
  }
  deepCopy() {
    const copiedMap = DictionaryImpl.deepCopy(this.value);
    return new _DictionarySymbol(copiedMap, this.config);
  }
  cloneIfMutable() {
    return this.deepCopy();
  }
  static empty() {
    return new _DictionarySymbol(null);
  }
  hasAttribute(attributeName) {
    return DictionaryImpl.hasAttribute(this.value, attributeName);
  }
  getAttribute(attributeName) {
    return DictionaryImpl.getAttribute(this.value, attributeName);
  }
};
_DictionarySymbol.type = "Dictionary";
_DictionarySymbol._SUPPORTED_METHODS = {
  get: {
    function: function(key) {
      return this.get(key);
    },
    args: [{ name: "key", type: "String", optional: false }],
    returnType: "any"
  },
  set: {
    function: function(key, value) {
      return this.set(key, value);
    },
    args: [
      { name: "key", type: "String", optional: false },
      { name: "value", type: "any", optional: false }
    ],
    returnType: "Dictionary"
  },
  delete: {
    function: function(key) {
      return this.delete(key);
    },
    args: [{ name: "key", type: "String", optional: false }],
    returnType: "Dictionary"
  },
  keys: {
    function: function() {
      return this.keys();
    },
    args: [],
    returnType: "List"
  },
  values: {
    function: function() {
      return this.values();
    },
    args: [],
    returnType: "List"
  },
  key_exists: {
    function: function(key) {
      return this.keyExists(key);
    },
    args: [{ name: "key", type: "String", optional: false }],
    returnType: "Boolean"
  },
  length: {
    function: function() {
      return this.length();
    },
    args: [],
    returnType: "Number"
  },
  clear: {
    function: function() {
      return this.clear();
    },
    args: [],
    returnType: "Dictionary"
  }
};
var DictionarySymbol = _DictionarySymbol;
var _TokenSymbol = class _TokenSymbol extends BaseSymbolType {
  constructor(subType, value, config) {
    let safeValue;
    if (value instanceof _TokenSymbol) {
      safeValue = value.value;
    } else if (isMap(value)) {
      safeValue = value;
    } else if (isObject(value)) {
      safeValue = new Map(Object.entries(value));
    } else if (isArray(value)) {
      safeValue = value;
    } else if (isNull(value)) {
      safeValue = /* @__PURE__ */ new Map();
    } else {
      throw new InterpreterError(`Token value must be a Record or List, got ${typeof value}.`);
    }
    super(safeValue, config);
    this.type = "Token";
    this.value = safeValue;
    this.subType = subType;
  }
  validValue(val) {
    return isMap(val) || isArray(val) || isNull(val);
  }
  toString() {
    if (isMap(this.value)) {
      return DictionaryImpl.toString(this.value);
    }
    return ListImpl.toString(this.value);
  }
  get(keyOrIndex) {
    if (isArray(this.value)) {
      const indexSymbol = typeof keyOrIndex === "number" ? new NumberSymbol(keyOrIndex, this.config) : keyOrIndex;
      if (!(indexSymbol instanceof NumberSymbol)) {
        throw new InterpreterError("List get requires a Number index.");
      }
      return ListImpl.get(this.value, indexSymbol);
    }
    const keySymbol = typeof keyOrIndex === "string" ? new StringSymbol(keyOrIndex, this.config) : keyOrIndex;
    if (!(keySymbol instanceof StringSymbol)) {
      throw new InterpreterError("Dictionary get requires a String key.");
    }
    return DictionaryImpl.get(this.value, keySymbol, this.config);
  }
  set(key, value) {
    if (isArray(this.value)) {
      throw new InterpreterError("Cannot set key on Token with List value.");
    }
    DictionaryImpl.set(this.value, key, value);
    return this;
  }
  keys() {
    if (isArray(this.value)) {
      throw new InterpreterError("Cannot get keys from Token with List value.");
    }
    return DictionaryImpl.keys(this.value, this.config);
  }
  values() {
    if (isMap(this.value)) {
      return DictionaryImpl.values(this.value, this.config);
    }
    return new ListSymbol(this.value, false, this.config);
  }
  length() {
    if (isMap(this.value)) {
      return DictionaryImpl.length(this.value, this.config);
    }
    return ListImpl.length(this.value, this.config);
  }
  // List-specific methods
  append(item) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot append to Token with Dictionary value.");
    }
    ListImpl.append(this.value, item);
    return this;
  }
  extend(...items) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot extend Token with Dictionary value.");
    }
    ListImpl.extend(this.value, ...items);
    return this;
  }
  insert(indexSymbol, item) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot insert into Token with Dictionary value.");
    }
    ListImpl.insert(this.value, indexSymbol, item);
    return this;
  }
  delete(indexSymbol) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot delete from Token with Dictionary value.");
    }
    ListImpl.deleteAt(this.value, indexSymbol);
    return this;
  }
  index(item) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot get index from Token with Dictionary value.");
    }
    return ListImpl.indexOf(this.value, item, this.config);
  }
  update(indexSymbol, item) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot update Token with Dictionary value.");
    }
    ListImpl.update(this.value, indexSymbol, item);
    return this;
  }
  join(separator) {
    if (isMap(this.value)) {
      throw new InterpreterError("Cannot join Token with Dictionary value.");
    }
    return ListImpl.join(this.value, separator, this.config);
  }
  deepCopy() {
    if (isMap(this.value)) {
      return new _TokenSymbol(this.subType, DictionaryImpl.deepCopy(this.value), this.config);
    }
    return new _TokenSymbol(this.subType, ListImpl.deepCopy(this.value), this.config);
  }
  cloneIfMutable() {
    return this.deepCopy();
  }
  static empty() {
    return new _TokenSymbol("unknown", null);
  }
  hasAttribute(attributeName) {
    if (attributeName === "subType" || attributeName === "type") {
      return true;
    }
    if (isMap(this.value)) {
      return DictionaryImpl.hasAttribute(this.value, attributeName);
    }
    return false;
  }
  getAttribute(attributeName) {
    if (attributeName === "subType") {
      return new StringSymbol(this.subType, this.config);
    }
    if (attributeName === "type") {
      return new StringSymbol(this.type, this.config);
    }
    if (isMap(this.value)) {
      return DictionaryImpl.getAttribute(this.value, attributeName);
    }
    return null;
  }
  getTypeName() {
    return typeName(this.type, this.subType);
  }
};
_TokenSymbol.type = "Token";
_TokenSymbol._SUPPORTED_METHODS = {
  get: {
    function: function(keyOrIndex) {
      return this.get(keyOrIndex);
    },
    args: [{ name: "keyOrIndex", type: "String|Number", optional: false }],
    returnType: "any"
  },
  set: {
    function: function(key, value) {
      return this.set(key, value);
    },
    args: [
      { name: "key", type: "String", optional: false },
      { name: "value", type: "any", optional: false }
    ],
    returnType: "Token"
  },
  keys: {
    function: function() {
      return this.keys();
    },
    args: [],
    returnType: "List"
  },
  values: {
    function: function() {
      return this.values();
    },
    args: [],
    returnType: "List"
  },
  length: {
    function: function() {
      return this.length();
    },
    args: [],
    returnType: "Number"
  },
  // List methods (when value is Array)
  append: {
    function: function(item) {
      return this.append(item);
    },
    args: [{ name: "item", type: "any" }],
    returnType: "Token"
  },
  extend: {
    function: function(...items) {
      return this.extend(...items);
    },
    args: [],
    returnType: "Token"
  },
  insert: {
    function: function(index, item) {
      return this.insert(index, item);
    },
    args: [
      { name: "index", type: "Number" },
      { name: "item", type: "any" }
    ],
    returnType: "Token"
  },
  delete: {
    function: function(index) {
      return this.delete(index);
    },
    args: [{ name: "index", type: "Number" }],
    returnType: "Token"
  },
  index: {
    function: function(item) {
      return this.index(item);
    },
    args: [{ name: "item", type: "any" }],
    returnType: "Number"
  },
  update: {
    function: function(index, item) {
      return this.update(index, item);
    },
    args: [
      { name: "index", type: "Number" },
      { name: "item", type: "any" }
    ],
    returnType: "Token"
  },
  join: {
    function: function(separator) {
      return this.join(separator);
    },
    args: [{ name: "separator", type: "String", optional: true }],
    returnType: "String"
  }
};
var TokenSymbol = _TokenSymbol;
var _ColorSymbol = class _ColorSymbol extends BaseSymbolType {
  constructor(value, subType, config) {
    const isHex = (isUndefined(subType) || subType?.toLowerCase() === "hex") && isString(value);
    const isDynamic = isString(subType) && isObject(value);
    const isValid = isNull(value) || isHex || isDynamic;
    if (!isValid) {
      throw new InterpreterError(
        `Value ${value} must be string, attributes record, or null, got ${typeof value}.`
      );
    }
    if (isHex) {
      if (!isValidHex(value)) {
        throw new InterpreterError(`Invalid hex color format: ${value}`);
      }
    }
    super(value, config);
    this.type = "Color";
    this.subType = null;
    this.value = value;
    this.subType = isHex ? "Hex" : subType || null;
  }
  static empty() {
    return new _ColorSymbol(null);
  }
  toStringSymbol() {
    if (this.config?.colorManager) {
      const formatted = this.config.colorManager.formatColorMethod(this);
      return new StringSymbol(formatted, this.config);
    }
    if (isObject(this.value)) {
      return new StringSymbol(formatObjectEntries(this.value), this.config);
    }
    if (isString(this.value)) {
      return new StringSymbol(this.value, this.config);
    }
    return new StringSymbol("", this.config);
  }
  toString() {
    return this.toStringSymbol().toString();
  }
  typeEquals(other) {
    if (!typeEquals(this.type, other.type)) return false;
    const otherColor = other;
    if (!this.subType && otherColor.isHex() || this.isHex() && !otherColor.subType) return true;
    return typeEquals(this.subType, other.subType);
  }
  isHex() {
    return typeEquals(this.subType, "hex");
  }
  validValue(val) {
    return val instanceof _ColorSymbol || isNull(val) || isObject(val) || isValidHex(val);
  }
  deepCopy() {
    if (isObject(this.value)) {
      const copiedValue = {};
      for (const [key, val] of Object.entries(this.value)) {
        copiedValue[key] = val.deepCopy();
      }
      return new _ColorSymbol(copiedValue, this.subType || void 0, this.config);
    }
    return new _ColorSymbol(this.value, this.subType || void 0, this.config);
  }
  cloneIfMutable() {
    if (isObject(this.value)) {
      return this.deepCopy();
    }
    return this;
  }
  hasAttribute(attributeName) {
    if (attributeName === "to") {
      return true;
    }
    if (isObject(this.value)) {
      return attributeName in this.value;
    }
    return false;
  }
  getAttribute(attributeName) {
    if (attributeName === "to") {
      return this;
    }
    if (isObject(this.value)) {
      const attributeValue = this.value[attributeName];
      if (attributeValue !== void 0) {
        return attributeValue;
      }
    }
    throw new InterpreterError(`Attribute '${attributeName}' not found on Color.`);
  }
  hasMethod(methodName, args) {
    if (super.hasMethod?.(methodName, args)) {
      return true;
    }
    if (this.config?.colorManager.hasInitializer(methodName)) {
      return true;
    }
    return false;
  }
  callMethod(methodName, args) {
    const methodDefinition = this.constructor._SUPPORTED_METHODS?.[methodName.toLowerCase()];
    if (methodDefinition && super.hasMethod?.(methodName, args)) {
      return super.callMethod?.(methodName, args);
    }
    if (this.config?.colorManager.hasInitializer(methodName)) {
      return this.config.colorManager.convertToByType(this, methodName);
    }
    throw new InterpreterError(`Method '${methodName}' not found on type '${this.type}'.`);
  }
  getTypeName() {
    return typeName(this.type, nullToUndefined(this.subType));
  }
};
_ColorSymbol.type = "Color";
_ColorSymbol._SUPPORTED_METHODS = {
  to_string: {
    name: "to_string",
    function: function() {
      return this.toStringSymbol();
    },
    args: [],
    returnType: "String"
  }
};
var ColorSymbol = _ColorSymbol;
({
  [NumberSymbol.type.toLowerCase()]: NumberSymbol,
  [StringSymbol.type.toLowerCase()]: StringSymbol,
  [BooleanSymbol.type.toLowerCase()]: BooleanSymbol,
  [NumberWithUnitSymbol.type.toLowerCase()]: NumberWithUnitSymbol,
  [ColorSymbol.type.toLowerCase()]: ColorSymbol,
  [NullSymbol.type.toLowerCase()]: NullSymbol
});
({
  [ListSymbol.type.toLowerCase()]: ListSymbol,
  [DictionarySymbol.type.toLowerCase()]: DictionarySymbol,
  [TokenSymbol.type.toLowerCase()]: TokenSymbol
});

// src/syntax-highlighter/spec.ts
var KEYWORDS = Object.values(ReservedKeyword);
var TYPES = [
  StringSymbol.type,
  NumberSymbol.type,
  NumberWithUnitSymbol.type,
  ColorSymbol.type,
  ListSymbol.type,
  DictionarySymbol.type,
  BooleanSymbol.type
];
var BUILTIN_FUNCTIONS = [
  "rgb",
  "rgba",
  "hsl",
  "hsla",
  "srgb",
  "lrgb",
  "hex",
  "oklch",
  "oklchRamp",
  "lighten",
  "darken",
  "saturate",
  "desaturate",
  "spin",
  "mix",
  "round_to",
  "snap",
  "remap",
  "pow",
  "linear-gradient",
  "type"
];
var UNITS = Object.values(SupportedFormats);
var OPERATORS = [
  ...Object.values(Operations),
  "=",
  ">",
  "<",
  ":",
  "==",
  "<=",
  ">=",
  "!="
];
var numberWithUnit = createUnitPattern(UNITS);
var PATTERNS = {
  /** Single-line comments */
  comment: /\/\/.*/,
  /** String literals (single or double quotes) */
  string: /(["'])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
  /** TokenScript references with curly braces (e.g., {token.path}) */
  reference: /\{[^}]+\}/,
  /** Hex color codes (#RGB, #RRGGBB, #RRGGBBAA) */
  hexColor: /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/,
  /** Numbers with CSS units (e.g., 10px, 1.5em, 45deg) - dynamically constructed from UNITS */
  numberWithUnit,
  /** Plain numbers (integers and floats, including scientific notation) */
  number: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b/,
  /** Float numbers with decimal point */
  float: /\d*\.\d+(?:[eE][-+]?\d+)?/,
  /** Identifiers and keywords */
  identifier: /[a-zA-Z_$][\w$]*/,
  /** Operators */
  operator: /[+\-*/%=<>!&|^~?:]+/,
  /** Punctuation */
  punctuation: /[[\]();,.:]/,
  /** Method calls (e.g., .methodName() ) */
  method: /\.\w+(?=\()/,
  /** Property access (e.g., .propertyName) */
  property: /\.\w+\b(?!\()/,
  /** Color type constructors (e.g., Color, Color.Rgb, Color.Hex) - accepts any subtype */
  colorType: /\bColor(?:\.\w+)?\b/
};
var MONACO_PATTERNS = {
  /** Invalid string (unterminated double quote) - Monaco-specific for error highlighting */
  stringInvalidDouble: /"([^"\\]|\\.)*$/,
  /** Invalid string (unterminated single quote) - Monaco-specific for error highlighting */
  stringInvalidSingle: /'([^'\\]|\\.)*$/,
  /** String start (double quote) - Monaco-specific for state-based tokenization */
  stringStartDouble: /"/,
  /** String start (single quote) - Monaco-specific for state-based tokenization */
  stringStartSingle: /'/,
  /** Number with any unit (captures unit for dynamic validation) - Monaco-specific for unit validation */
  numberWithDynamicUnit: /\d+(\.\d+)?([a-zA-Z%]+)\b/
};
function createKeywordPattern(keywords) {
  return new RegExp(`\\b(?:${keywords.join("|")})\\b`);
}
function createUnitPattern(units) {
  const escapedUnits = units.map((unit) => unit.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
  return new RegExp(`\\b\\d+(?:\\.\\d+)?(?:${escapedUnits.join("|")})(?!\\w)`);
}

// src/syntax-highlighter/monaco.ts
var tokenscriptLanguageDefinition = {
  keywords: [...KEYWORDS],
  types: [...TYPES],
  colorFunctions: [...BUILTIN_FUNCTIONS],
  units: [...UNITS],
  operators: [...OPERATORS],
  symbols: /[=><!~?:&|+\-*/^%]+/,
  tokenizer: {
    root: [
      // Comments - must come first
      [PATTERNS.comment, "comment"],
      // Strings - Monaco requires state-based tokenization for multi-line strings
      // Cannot use PATTERNS.string because Monaco needs separate start/end tokens
      [MONACO_PATTERNS.stringInvalidDouble, "string.invalid"],
      [MONACO_PATTERNS.stringInvalidSingle, "string.invalid"],
      [MONACO_PATTERNS.stringStartDouble, "string", "@string_double"],
      [MONACO_PATTERNS.stringStartSingle, "string", "@string_single"],
      // TokenScript references with curly braces
      [PATTERNS.reference, "reference"],
      // Hex colors
      [PATTERNS.hexColor, "number.hex"],
      // Numbers with units - Monaco requires capture groups for dynamic unit validation
      // Cannot use PATTERNS.numberWithUnit because Monaco needs $2 to validate against @units
      [
        MONACO_PATTERNS.numberWithDynamicUnit,
        {
          cases: {
            "$2@units": "number.unit",
            "@default": "number"
          }
        }
      ],
      // Float numbers - must come before integer pattern to match decimals first
      [PATTERNS.float, "number.float"],
      // Integer numbers
      [PATTERNS.number, "number"],
      // Color types (Color.Hex, Color.Rgb, etc.)
      [PATTERNS.colorType, "type"],
      // Method calls (.method())
      [PATTERNS.method, "method"],
      // Property access (.property)
      [PATTERNS.property, "property"],
      // Identifiers and keywords
      [
        PATTERNS.identifier,
        {
          cases: {
            "@keywords": "keyword",
            "@types": "type",
            "@colorFunctions": "function",
            "@default": "identifier"
          }
        }
      ],
      // Whitespace
      { include: "@whitespace" },
      // Delimiters and operators
      [/[()[\]]/, "delimiter"],
      [/[<>]=?/, "operator"],
      [/[=!]=?/, "operator"],
      [/&&|\|\|/, "operator"],
      [/[+\-*/^%]/, "operator"],
      [/[;:,]/, "delimiter"],
      [/@symbols/, "operator"]
    ],
    // String handling
    string_double: [
      [/[^\\"]+/, "string"],
      [/"/, "string", "@pop"]
    ],
    string_single: [
      [/[^\\']+/, "string"],
      [/'/, "string", "@pop"]
    ],
    // Whitespace
    whitespace: [[/[ \t\r\n]+/, "white"]]
  }
};
var tokenscriptLanguageConfig = {
  comments: {
    lineComment: "//"
  },
  brackets: [
    ["[", "]"],
    ["(", ")"]
  ],
  autoClosingPairs: [
    { open: "[", close: "]" },
    { open: "(", close: ")" },
    { open: '"', close: '"', notIn: ["string"] },
    { open: "'", close: "'", notIn: ["string"] }
  ],
  surroundingPairs: [
    { open: "[", close: "]" },
    { open: "(", close: ")" },
    { open: '"', close: '"' },
    { open: "'", close: "'" }
  ],
  folding: {
    markers: {
      start: /^\s*\/\/\s*#?region\b/,
      end: /^\s*\/\/\s*#?endregion\b/
    }
  },
  wordPattern: /(-?\d*\.\d\w*)|([a-zA-Z_$][\w$]*)/g,
  indentationRules: {
    increaseIndentPattern: /^((?!.*?\/\*).*)*\[[^\]]*$/,
    decreaseIndentPattern: /^((?!.*?\/\*).*)*\].*$/
  }
};

// src/syntax-highlighter/prism.ts
function tokenscriptLanguage(Prism) {
  Prism.languages.tokenscript = {
    comment: {
      pattern: PATTERNS.comment,
      greedy: true
    },
    string: {
      pattern: PATTERNS.string,
      greedy: true
    },
    reference: {
      pattern: PATTERNS.reference,
      greedy: true,
      alias: "variable"
    },
    "hex-color": {
      pattern: PATTERNS.hexColor,
      alias: "number"
    },
    "number-with-unit": {
      pattern: PATTERNS.numberWithUnit,
      alias: "number"
    },
    number: {
      pattern: PATTERNS.number
    },
    keyword: {
      pattern: createKeywordPattern(KEYWORDS)
    },
    type: {
      pattern: createKeywordPattern(TYPES),
      alias: "class-name"
    },
    "color-type": {
      pattern: PATTERNS.colorType,
      alias: "class-name"
    },
    function: {
      pattern: createKeywordPattern([...BUILTIN_FUNCTIONS, "(?=\\()"])
    },
    method: {
      pattern: PATTERNS.method,
      inside: {
        punctuation: /\./
      }
    },
    property: {
      pattern: PATTERNS.property,
      inside: {
        punctuation: /\./
      }
    },
    operator: PATTERNS.operator,
    punctuation: PATTERNS.punctuation
  };
  Prism.languages.ts = Prism.languages.tokenscript;
  return Prism.languages.tokenscript;
}

export { BUILTIN_FUNCTIONS, KEYWORDS, MONACO_PATTERNS, OPERATORS, PATTERNS, TYPES, UNITS, createKeywordPattern, createUnitPattern, tokenscriptLanguage, tokenscriptLanguageConfig, tokenscriptLanguageDefinition };
//# sourceMappingURL=syntax-highlighting.js.map
//# sourceMappingURL=syntax-highlighting.js.map