#![deny(trivial_numeric_casts)]
#![allow(
    clippy::derive_partial_eq_without_eq,
    clippy::enum_variant_names,
    clippy::redundant_field_names,
    clippy::too_many_lines
)]

mod bytes;

use serde_derive::{Deserialize, Serialize};
use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
use std::collections::BTreeMap;

#[test]
fn complex() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    enum Untagged {
        A { a: u8 },
        B { b: u8 },
        C,
        D(u8),
        E(String),
        F(u8, u8),
    }

    assert_tokens(
        &Untagged::A { a: 1 },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("a"),
            Token::U8(1),
            Token::StructEnd,
        ],
    );

    assert_tokens(
        &Untagged::B { b: 2 },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("b"),
            Token::U8(2),
            Token::StructEnd,
        ],
    );

    // Serializes to unit, deserializes from either depending on format's
    // preference.
    assert_tokens(&Untagged::C, &[Token::Unit]);
    assert_de_tokens(&Untagged::C, &[Token::None]);

    assert_tokens(&Untagged::D(4), &[Token::U8(4)]);
    assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]);

    assert_tokens(
        &Untagged::F(1, 2),
        &[
            Token::Tuple { len: 2 },
            Token::U8(1),
            Token::U8(2),
            Token::TupleEnd,
        ],
    );

    assert_de_tokens_error::<Untagged>(
        &[Token::Tuple { len: 1 }, Token::U8(1), Token::TupleEnd],
        "data did not match any variant of untagged enum Untagged",
    );

    assert_de_tokens_error::<Untagged>(
        &[
            Token::Tuple { len: 3 },
            Token::U8(1),
            Token::U8(2),
            Token::U8(3),
            Token::TupleEnd,
        ],
        "data did not match any variant of untagged enum Untagged",
    );
}

#[test]
fn newtype_unit_and_empty_map() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    struct Unit;

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    enum Message {
        Unit(Unit),
        Map(BTreeMap<String, String>),
    }

    assert_tokens(
        &Message::Map(BTreeMap::new()),
        &[Token::Map { len: Some(0) }, Token::MapEnd],
    );
}

// Reaches crate::private::de::content::ContentRefDeserializer::deserialize_newtype_struct
#[test]
fn newtype_struct() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    struct NewtypeStruct(u32);

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    enum E {
        Newtype(NewtypeStruct),
        Null,
    }

    let value = E::Newtype(NewtypeStruct(5));

    // Content::Newtype case
    assert_tokens(
        &value,
        &[
            Token::NewtypeStruct {
                name: "NewtypeStruct",
            },
            Token::U32(5),
        ],
    );

    // _ case
    assert_de_tokens(&value, &[Token::U32(5)]);
}

mod newtype_enum {
    use super::*;

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    enum Outer {
        Inner(Inner),
    }

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    enum Inner {
        Unit,
        Newtype(u8),
        Tuple0(),
        Tuple2(u8, u8),
        Struct { f: u8 },
        EmptyStruct {},
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::unit_variant
    #[test]
    fn unit() {
        assert_tokens(
            &Outer::Inner(Inner::Unit),
            &[Token::UnitVariant {
                name: "Inner",
                variant: "Unit",
            }],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::newtype_variant_seed
    #[test]
    fn newtype() {
        assert_tokens(
            &Outer::Inner(Inner::Newtype(1)),
            &[
                Token::NewtypeVariant {
                    name: "Inner",
                    variant: "Newtype",
                },
                Token::U8(1),
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::tuple_variant
    #[test]
    fn tuple0() {
        assert_tokens(
            &Outer::Inner(Inner::Tuple0()),
            &[
                Token::TupleVariant {
                    name: "Inner",
                    variant: "Tuple0",
                    len: 0,
                },
                Token::TupleVariantEnd,
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::tuple_variant
    #[test]
    fn tuple2() {
        assert_tokens(
            &Outer::Inner(Inner::Tuple2(1, 1)),
            &[
                Token::TupleVariant {
                    name: "Inner",
                    variant: "Tuple2",
                    len: 2,
                },
                Token::U8(1),
                Token::U8(1),
                Token::TupleVariantEnd,
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::struct_variant
    // Content::Map case
    #[test]
    fn struct_from_map() {
        assert_tokens(
            &Outer::Inner(Inner::Struct { f: 1 }),
            &[
                Token::StructVariant {
                    name: "Inner",
                    variant: "Struct",
                    len: 1,
                },
                Token::Str("f"),
                Token::U8(1),
                Token::StructVariantEnd,
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::struct_variant
    // Content::Seq case
    #[test]
    fn struct_from_seq() {
        assert_de_tokens(
            &Outer::Inner(Inner::Struct { f: 1 }),
            &[
                Token::Map { len: Some(1) },
                // tag
                Token::Str("Struct"),
                // content
                Token::Seq { len: Some(1) },
                Token::U8(1),
                Token::SeqEnd,
                Token::MapEnd,
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::struct_variant
    // Content::Map case
    // Special case - empty map
    #[test]
    fn empty_struct_from_map() {
        assert_de_tokens(
            &Outer::Inner(Inner::EmptyStruct {}),
            &[
                Token::Map { len: Some(1) },
                // tag
                Token::Str("EmptyStruct"),
                // content
                Token::Map { len: Some(0) },
                Token::MapEnd,
                Token::MapEnd,
            ],
        );
    }

    // Reaches crate::private::de::content::VariantRefDeserializer::struct_variant
    // Content::Seq case
    // Special case - empty seq
    #[test]
    fn empty_struct_from_seq() {
        assert_de_tokens(
            &Outer::Inner(Inner::EmptyStruct {}),
            &[
                Token::Map { len: Some(1) },
                // tag
                Token::Str("EmptyStruct"),
                // content
                Token::Seq { len: Some(0) },
                Token::SeqEnd,
                Token::MapEnd,
            ],
        );
    }
}

// Reaches crate::private::de::content::ContentRefDeserializer::deserialize_option
mod with_optional_field {
    use super::*;

    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    enum Enum {
        Struct { optional: Option<u32> },
        Null,
    }

    #[test]
    fn some() {
        assert_tokens(
            &Enum::Struct { optional: Some(42) },
            &[
                Token::Struct {
                    name: "Enum",
                    len: 1,
                },
                Token::Str("optional"),
                Token::Some,
                Token::U32(42),
                Token::StructEnd,
            ],
        );
    }

    #[test]
    fn some_without_marker() {
        assert_de_tokens(
            &Enum::Struct { optional: Some(42) },
            &[
                Token::Struct {
                    name: "Enum",
                    len: 1,
                },
                Token::Str("optional"),
                Token::U32(42),
                Token::StructEnd,
            ],
        );
    }

    #[test]
    fn none() {
        assert_tokens(
            &Enum::Struct { optional: None },
            &[
                Token::Struct {
                    name: "Enum",
                    len: 1,
                },
                Token::Str("optional"),
                Token::None,
                Token::StructEnd,
            ],
        );
    }

    #[test]
    fn unit() {
        assert_de_tokens(
            &Enum::Struct { optional: None },
            &[
                Token::Map { len: None },
                Token::Str("optional"),
                Token::Unit,
                Token::MapEnd,
            ],
        );
    }
}

#[test]
fn string_and_bytes() {
    #[derive(Debug, PartialEq, Deserialize)]
    #[serde(untagged)]
    enum Untagged {
        String {
            string: String,
        },
        Bytes {
            #[serde(with = "bytes")]
            bytes: Vec<u8>,
        },
    }

    assert_de_tokens(
        &Untagged::String {
            string: "\0".to_owned(),
        },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("string"),
            Token::Str("\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::String {
            string: "\0".to_owned(),
        },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("string"),
            Token::String("\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::String {
            string: "\0".to_owned(),
        },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("string"),
            Token::Bytes(b"\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::String {
            string: "\0".to_owned(),
        },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("string"),
            Token::ByteBuf(b"\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::Bytes { bytes: vec![0] },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("bytes"),
            Token::Str("\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::Bytes { bytes: vec![0] },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("bytes"),
            Token::String("\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::Bytes { bytes: vec![0] },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("bytes"),
            Token::Bytes(b"\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::Bytes { bytes: vec![0] },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("bytes"),
            Token::ByteBuf(b"\0"),
            Token::StructEnd,
        ],
    );

    assert_de_tokens(
        &Untagged::Bytes { bytes: vec![0] },
        &[
            Token::Struct {
                name: "Untagged",
                len: 1,
            },
            Token::Str("bytes"),
            Token::Seq { len: Some(1) },
            Token::U8(0),
            Token::SeqEnd,
            Token::StructEnd,
        ],
    );
}

#[test]
fn contains_flatten() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    #[serde(untagged)]
    enum Data {
        A {
            a: i32,
            #[serde(flatten)]
            flat: Flat,
        },
    }

    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Flat {
        b: i32,
    }

    let data = Data::A {
        a: 0,
        flat: Flat { b: 0 },
    };

    assert_tokens(
        &data,
        &[
            Token::Map { len: None },
            Token::Str("a"),
            Token::I32(0),
            Token::Str("b"),
            Token::I32(0),
            Token::MapEnd,
        ],
    );
}

#[test]
fn contains_flatten_with_integer_key() {
    #[derive(Debug, PartialEq, Serialize, Deserialize)]
    #[serde(untagged)]
    pub enum Untagged {
        Variant {
            #[serde(flatten)]
            map: BTreeMap<u64, String>,
        },
    }

    assert_tokens(
        &Untagged::Variant {
            map: {
                let mut map = BTreeMap::new();
                map.insert(100, "BTreeMap".to_owned());
                map
            },
        },
        &[
            Token::Map { len: None },
            Token::U64(100),
            Token::Str("BTreeMap"),
            Token::MapEnd,
        ],
    );
}

#[test]
fn expecting_message() {
    #[derive(Deserialize)]
    #[serde(untagged)]
    #[serde(expecting = "something strange...")]
    enum Enum {
        Untagged,
    }

    assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], "something strange...");
}


import type { OriginalMapping } from '@jridgewell/trace-mapping'
import { originalPositionFor } from '@jridgewell/trace-mapping'
import { posixDirname, posixResolve } from '../utils'

interface SourceMapLike {
  version: number
  mappings?: string
  names?: string[]
  sources?: string[]
  sourcesContent?: string[]
}

type Needle = {
  line: number
  column: number
}

export class DecodedMap {
  _encoded: string
  _decoded: undefined | number[][][]
  _decodedMemo: Stats
  url: string
  file: string
  version: number
  names: string[] = []
  resolvedSources: string[]

  constructor(
    public map: SourceMapLike,
    from: string,
  ) {
    const { mappings, names, sources } = map
    this.version = map.version
    this.names = names || []
    this._encoded = mappings || ''
    this._decodedMemo = memoizedState()
    this.url = from
    this.file = from
    const originDir = posixDirname(from)
    this.resolvedSources = (sources || []).map((s) =>
      posixResolve(originDir, s || ''),
    )
  }
}

interface Stats {
  lastKey: number
  lastNeedle: number
  lastIndex: number
}
function memoizedState(): Stats {
  return {
    lastKey: -1,
    lastNeedle: -1,
    lastIndex: -1,
  }
}
export function getOriginalPosition(
  map: DecodedMap,
  needle: Needle,
): OriginalMapping | null {
  const result = originalPositionFor(map as any, needle)
  if (result.column == null) {
    return null
  }
  return result
}


import type { OriginalMapping } from '@jridgewell/trace-mapping'
import type { ModuleRunner } from '../runner'
import { decodeBase64, posixDirname, posixResolve } from '../utils'
import type { EvaluatedModules } from '../evaluatedModules'
import { slash } from '../../shared/utils'
import { DecodedMap, getOriginalPosition } from './decoder'

interface RetrieveFileHandler {
  (path: string): string | null | undefined | false
}

interface RetrieveSourceMapHandler {
  (path: string): null | { url: string; map: any }
}

export interface InterceptorOptions {
  retrieveFile?: RetrieveFileHandler
  retrieveSourceMap?: RetrieveSourceMapHandler
}

const sourceMapCache: Record<string, CachedMapEntry> = {}
const fileContentsCache: Record<string, string> = {}

const evaluatedModulesCache = new Set<EvaluatedModules>()
const retrieveFileHandlers = new Set<RetrieveFileHandler>()
const retrieveSourceMapHandlers = new Set<RetrieveSourceMapHandler>()

const createExecHandlers = <T extends (...args: any) => any>(
  handlers: Set<T>,
) => {
  return ((...args: Parameters<T>) => {
    for (const handler of handlers) {
      const result = handler(...args)
      if (result) return result
    }
    return null
  }) as T
}

const retrieveFileFromHandlers = createExecHandlers(retrieveFileHandlers)
const retrieveSourceMapFromHandlers = createExecHandlers(
  retrieveSourceMapHandlers,
)

let overridden = false
const originalPrepare = Error.prepareStackTrace

function resetInterceptor(runner: ModuleRunner, options: InterceptorOptions) {
  evaluatedModulesCache.delete(runner.evaluatedModules)
  if (options.retrieveFile) retrieveFileHandlers.delete(options.retrieveFile)
  if (options.retrieveSourceMap)
    retrieveSourceMapHandlers.delete(options.retrieveSourceMap)
  if (evaluatedModulesCache.size === 0) {
    Error.prepareStackTrace = originalPrepare
    overridden = false
  }
}

export function interceptStackTrace(
  runner: ModuleRunner,
  options: InterceptorOptions = {},
): () => void {
  if (!overridden) {
    Error.prepareStackTrace = prepareStackTrace
    overridden = true
  }
  evaluatedModulesCache.add(runner.evaluatedModules)
  if (options.retrieveFile) retrieveFileHandlers.add(options.retrieveFile)
  if (options.retrieveSourceMap)
    retrieveSourceMapHandlers.add(options.retrieveSourceMap)
  return () => resetInterceptor(runner, options)
}

interface CallSite extends NodeJS.CallSite {
  getScriptNameOrSourceURL(): string
}

interface State {
  nextPosition: null | OriginalMapping
  curPosition: null | OriginalMapping
}

interface CachedMapEntry {
  url: string | null
  map: DecodedMap | null
  vite?: boolean
}

// Support URLs relative to a directory, but be careful about a protocol prefix
function supportRelativeURL(file: string, url: string) {
  if (!file) return url
  const dir = posixDirname(slash(file))
  const match = /^\w+:\/\/[^/]*/.exec(dir)
  let protocol = match ? match[0] : ''
  const startPath = dir.slice(protocol.length)
  if (protocol && /^\/\w:/.test(startPath)) {
    // handle file:///C:/ paths
    protocol += '/'
    return protocol + slash(posixResolve(startPath, url))
  }
  return protocol + posixResolve(startPath, url)
}

function getRunnerSourceMap(position: OriginalMapping): CachedMapEntry | null {
  for (const moduleGraph of evaluatedModulesCache) {
    const sourceMap = moduleGraph.getModuleSourceMapById(position.source!)
    if (sourceMap) {
      return {
        url: position.source,
        map: sourceMap,
        vite: true,
      }
    }
  }
  return null
}

function retrieveFile(path: string): string | null | undefined | false {
  if (path in fileContentsCache) return fileContentsCache[path]
  const content = retrieveFileFromHandlers(path)
  if (typeof content === 'string') {
    fileContentsCache[path] = content
    return content
  }
  return null
}

function retrieveSourceMapURL(source: string) {
  // Get the URL of the source map
  const fileData = retrieveFile(source)
  if (!fileData) return null
  const re =
    /\/\/[@#]\s*sourceMappingURL=([^\s'"]+)\s*$|\/\*[@#]\s*sourceMappingURL=[^\s*'"]+\s*\*\/\s*$/gm
  // Keep executing the search to find the *last* sourceMappingURL to avoid
  // picking up sourceMappingURLs from comments, strings, etc.
  let lastMatch, match

  while ((match = re.exec(fileData))) lastMatch = match
  if (!lastMatch) return null
  return lastMatch[1]
}

const reSourceMap = /^data:application\/json[^,]+base64,/

function retrieveSourceMap(source: string) {
  const urlAndMap = retrieveSourceMapFromHandlers(source)
  if (urlAndMap) return urlAndMap

  let sourceMappingURL = retrieveSourceMapURL(source)
  if (!sourceMappingURL) return null

  // Read the contents of the source map
  let sourceMapData
  if (reSourceMap.test(sourceMappingURL)) {
    // Support source map URL as a data url
    const rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
    sourceMapData = decodeBase64(rawData)
    sourceMappingURL = source
  } else {
    // Support source map URLs relative to the source URL
    sourceMappingURL = supportRelativeURL(source, sourceMappingURL)
    sourceMapData = retrieveFile(sourceMappingURL)
  }

  if (!sourceMapData) return null

  return {
    url: sourceMappingURL,
    map: sourceMapData,
  }
}

function mapSourcePosition(position: OriginalMapping) {
  if (!position.source) return position
  let sourceMap = getRunnerSourceMap(position)
  if (!sourceMap) sourceMap = sourceMapCache[position.source]
  if (!sourceMap) {
    // Call the (overridable) retrieveSourceMap function to get the source map.
    const urlAndMap = retrieveSourceMap(position.source)
    if (urlAndMap && urlAndMap.map) {
      const url = urlAndMap.url
      sourceMap = sourceMapCache[position.source] = {
        url,
        map: new DecodedMap(
          typeof urlAndMap.map === 'string'
            ? JSON.parse(urlAndMap.map)
            : urlAndMap.map,
          url,
        ),
      }

      const contents = sourceMap.map?.map.sourcesContent
      // Load all sources stored inline with the source map into the file cache
      // to pretend like they are already loaded. They may not exist on disk.
      if (sourceMap.map && contents) {
        sourceMap.map.resolvedSources.forEach((source, i) => {
          const content = contents[i]
          if (content && source && url) {
            const contentUrl = supportRelativeURL(url, source)
            fileContentsCache[contentUrl] = content
          }
        })
      }
    } else {
      sourceMap = sourceMapCache[position.source] = {
        url: null,
        map: null,
      }
    }
  }

  // Resolve the source URL relative to the URL of the source map
  if (sourceMap.map && sourceMap.url) {
    const originalPosition = getOriginalPosition(sourceMap.map, position)

    // Only return the original position if a matching line was found. If no
    // matching line is found then we return position instead, which will cause
    // the stack trace to print the path and line for the compiled file. It is
    // better to give a precise location in the compiled file than a vague
    // location in the original file.
    if (originalPosition && originalPosition.source != null) {
      originalPosition.source = supportRelativeURL(
        sourceMap.url,
        originalPosition.source,
      )
      if (sourceMap.vite) {
        // @ts-expect-error vite is not defined
        originalPosition._vite = true
      }
      return originalPosition
    }
  }

  return position
}

// Parses code generated by FormatEvalOrigin(), a function inside V8:
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
function mapEvalOrigin(origin: string): string {
  // Most eval() calls are in this format
  let match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin)
  if (match) {
    const position = mapSourcePosition({
      name: null,
      source: match[2],
      line: +match[3],
      column: +match[4] - 1,
    })
    return `eval at ${match[1]} (${position.source}:${position.line}:${position.column + 1})`
  }

  // Parse nested eval() calls using recursion
  match = /^eval at ([^(]+) \((.+)\)$/.exec(origin)
  if (match) return `eval at ${match[1]} (${mapEvalOrigin(match[2])})`

  // Make sure we still return useful information if we didn't find anything
  return origin
}

// This is copied almost verbatim from the V8 source code at
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
// implementation of wrapCallSite() used to just forward to the actual source
// code of CallSite.prototype.toString but unfortunately a new release of V8
// did something to the prototype chain and broke the shim. The only fix I
// could find was copy/paste.
function CallSiteToString(this: CallSite) {
  let fileName
  let fileLocation = ''
  if (this.isNative()) {
    fileLocation = 'native'
  } else {
    fileName = this.getScriptNameOrSourceURL()
    if (!fileName && this.isEval()) {
      fileLocation = this.getEvalOrigin()!
      fileLocation += ', ' // Expecting source position to follow.
    }

    if (fileName) {
      fileLocation += fileName
    } else {
      // Source code does not originate from a file and is not native, but we
      // can still get the source position inside the source string, e.g. in
      // an eval string.
      fileLocation += '<anonymous>'
    }
    const lineNumber = this.getLineNumber()
    if (lineNumber != null) {
      fileLocation += `:${lineNumber}`
      const columnNumber = this.getColumnNumber()
      if (columnNumber) fileLocation += `:${columnNumber}`
    }
  }

  let line = ''
  const functionName = this.getFunctionName()
  let addSuffix = true
  const isConstructor = this.isConstructor()
  const isMethodCall = !(this.isToplevel() || isConstructor)
  if (isMethodCall) {
    let typeName = this.getTypeName()
    // Fixes shim to be backward compatible with Node v0 to v4
    if (typeName === '[object Object]') typeName = 'null'

    const methodName = this.getMethodName()
    if (functionName) {
      if (typeName && functionName.indexOf(typeName) !== 0)
        line += `${typeName}.`

      line += functionName
      if (
        methodName &&
        functionName.indexOf(`.${methodName}`) !==
          functionName.length - methodName.length - 1
      )
        line += ` [as ${methodName}]`
    } else {
      line += `${typeName}.${methodName || '<anonymous>'}`
    }
  } else if (isConstructor) {
    line += `new ${functionName || '<anonymous>'}`
  } else if (functionName) {
    line += functionName
  } else {
    line += fileLocation
    addSuffix = false
  }
  if (addSuffix) line += ` (${fileLocation})`

  return line
}

function cloneCallSite(frame: CallSite) {
  // null prototype so assigning `constructor` below doesn't throw
  // when user code has frozen `Object.prototype`
  const object = Object.create(null) as CallSite
  Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach((name) => {
    const key = name as keyof CallSite
    // @ts-expect-error difficult to type
    object[key] = /^(?:is|get)/.test(name)
      ? function () {
          return frame[key].call(frame)
        }
      : frame[key]
  })
  object.toString = CallSiteToString
  return object
}

function wrapCallSite(frame: CallSite, state: State) {
  // provides interface backward compatibility
  if (state === undefined) state = { nextPosition: null, curPosition: null }

  if (frame.isNative()) {
    state.curPosition = null
    return frame
  }

  // Most call sites will return the source file from getFileName(), but code
  // passed to eval() ending in "//# sourceURL=..." will return the source file
  // from getScriptNameOrSourceURL() instead
  const source = frame.getFileName() || frame.getScriptNameOrSourceURL()
  if (source) {
    const line = frame.getLineNumber() ?? 0
    const column = (frame.getColumnNumber() ?? 1) - 1

    const position = mapSourcePosition({
      name: null,
      source,
      line,
      column,
    })
    state.curPosition = position
    frame = cloneCallSite(frame)
    const originalFunctionName = frame.getFunctionName
    frame.getFunctionName = function () {
      const name = (() => {
        if (state.nextPosition == null) return originalFunctionName()

        return state.nextPosition.name || originalFunctionName()
      })()
      return name === 'eval' && '_vite' in position ? null : name
    }
    frame.getFileName = function () {
      return position.source ?? null
    }
    frame.getLineNumber = function () {
      return position.line
    }
    frame.getColumnNumber = function () {
      return position.column + 1
    }
    frame.getScriptNameOrSourceURL = function () {
      return position.source!
    }
    return frame
  }

  // Code called using eval() needs special handling
  let origin = frame.isEval() && frame.getEvalOrigin()
  if (origin) {
    origin = mapEvalOrigin(origin)
    frame = cloneCallSite(frame)
    frame.getEvalOrigin = function () {
      return origin || undefined
    }
    return frame
  }

  // If we get here then we were unable to change the source position
  return frame
}

function prepareStackTrace(error: Error, stack: CallSite[]) {
  const name = error.name || 'Error'
  const message = error.message || ''
  const errorString = `${name}: ${message}`

  const state = { nextPosition: null, curPosition: null }
  const processedStack = []
  for (let i = stack.length - 1; i >= 0; i--) {
    processedStack.push(`\n    at ${wrapCallSite(stack[i], state)}`)
    state.nextPosition = state.curPosition
  }
  state.curPosition = state.nextPosition = null
  return errorString + processedStack.reverse().join('')
}


import { msg as msgJs } from './hello.js'
import { msgJsx } from './hellojsx.jsx'
import { msgTsx } from './hellotsx.js'
import { msgCjs } from './hellocjs.cjs'
import { msgMjs } from './hellomjs.mjs'

export const msg =
  msgJs && msgJsx && msgTsx && msgCjs && msgMjs
    ? '[success] use .js / .jsx / .cjs / .mjs extension to import a TS modules'
    : '[fail]'


//     __ _____ _____ _____
//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
// |  |  |__   |  |  | | | |  version 3.12.0
// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT

#include "doctest_compatibility.h"
#undef WIN32_LEAN_AND_MEAN
#undef NOMINMAX

#ifdef _WIN32
    #include <windows.h>
#endif

#include <nlohmann/json.hpp>
using nlohmann::json;

TEST_CASE("include windows.h")
{
    CHECK(true);
}


/*
The code is licensed under the MIT License <http://opensource.org/licenses/MIT>:

Copyright (c) 2015-2017 Niels Lohmann.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#ifndef NLOHMANN_FIFO_MAP_HPP
#define NLOHMANN_FIFO_MAP_HPP

#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

/*!
@brief namespace for Niels Lohmann
@see https://github.com/nlohmann
*/
namespace nlohmann
{

template<class Key>
class fifo_map_compare
{
  public:
    /// constructor given a pointer to a key storage
    fifo_map_compare(std::unordered_map<Key, std::size_t>* k) : keys(k) {}

    /*!
    This function compares two keys with respect to the order in which they
    were added to the container. For this, the mapping keys is used.
    */
    bool operator()(const Key& lhs, const Key& rhs) const
    {
        // look up timestamps for both keys
        const auto timestamp_lhs = keys->find(lhs);
        const auto timestamp_rhs = keys->find(rhs);

        if (timestamp_lhs == keys->end())
        {
            // timestamp for lhs not found - cannot be smaller than for rhs
            return false;
        }

        if (timestamp_rhs == keys->end())
        {
            // timestamp for rhs not found - timestamp for lhs is smaller
            return true;
        }

        // compare timestamps
        return timestamp_lhs->second < timestamp_rhs->second;
    }

    void add_key(const Key& key)
    {
        keys->insert({key, timestamp++});
    }

    void remove_key(const Key& key)
    {
        keys->erase(key);
    }

  private:
    /// pointer to a mapping from keys to insertion timestamps
    std::unordered_map<Key, std::size_t>* keys = nullptr;
    /// the next valid insertion timestamp
    size_t timestamp = 1;
};

template <
    class Key,
    class T,
    class Compare = fifo_map_compare<Key>,
    class Allocator = std::allocator<std::pair<const Key, T>>
    > class fifo_map // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions,-warnings-as-errors)
{
  public:
    using key_type = Key;
    using mapped_type = T;
    using value_type = std::pair<const Key, T>;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using key_compare = Compare;
    using allocator_type = Allocator;
    using reference = value_type&;
    using const_reference = const value_type&;
    using pointer = typename std::allocator_traits<Allocator>::pointer;
    using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;

    using internal_map_type = std::map<Key, T, Compare, Allocator>;

    using iterator = typename internal_map_type::iterator;
    using const_iterator = typename internal_map_type::const_iterator;
    using reverse_iterator = typename internal_map_type::reverse_iterator;
    using const_reverse_iterator = typename internal_map_type::const_reverse_iterator;

  public:
    /// default constructor
    fifo_map() : m_keys(), m_compare(&m_keys), m_map(m_compare) {}

    /// copy constructor
    fifo_map(const fifo_map &f) : m_keys(f.m_keys), m_compare(&m_keys), m_map(f.m_map.begin(), f.m_map.end(), m_compare) {}

    /// constructor for a range of elements
    template<class InputIterator>
    fifo_map(InputIterator first, InputIterator last)
        : m_keys(), m_compare(&m_keys), m_map(m_compare)
    {
        for (auto it = first; it != last; ++it)
        {
            insert(*it);
        }
    }

    /// constructor for a list of elements
    fifo_map(std::initializer_list<value_type> init) : fifo_map()
    {
        for (auto x : init)
        {
            insert(x);
        }
    }

    /*
     * Element access
     */

    /// access specified element with bounds checking
    T& at(const Key& key)
    {
        return m_map.at(key);
    }

    /// access specified element with bounds checking
    const T& at(const Key& key) const
    {
        return m_map.at(key);
    }

    /// access specified element
    T& operator[](const Key& key)
    {
        m_compare.add_key(key);
        return m_map[key];
    }

    /// access specified element
    T& operator[](Key&& key)
    {
        m_compare.add_key(key);
        return m_map[key];
    }

    /*
     * Iterators
     */

    /// returns an iterator to the beginning
    iterator begin() noexcept
    {
        return m_map.begin();
    }

    /// returns an iterator to the end
    iterator end() noexcept
    {
        return m_map.end();
    }

    /// returns an iterator to the beginning
    const_iterator begin() const noexcept
    {
        return m_map.begin();
    }

    /// returns an iterator to the end
    const_iterator end() const noexcept
    {
        return m_map.end();
    }

    /// returns an iterator to the beginning
    const_iterator cbegin() const noexcept
    {
        return m_map.cbegin();
    }

    /// returns an iterator to the end
    const_iterator cend() const noexcept
    {
        return m_map.cend();
    }

    /// returns a reverse iterator to the beginning
    reverse_iterator rbegin() noexcept
    {
        return m_map.rbegin();
    }

    /// returns a reverse iterator to the end
    reverse_iterator rend() noexcept
    {
        return m_map.rend();
    }

    /// returns a reverse iterator to the beginning
    const_reverse_iterator rbegin() const noexcept
    {
        return m_map.rbegin();
    }

    /// returns a reverse iterator to the end
    const_reverse_iterator rend() const noexcept
    {
        return m_map.rend();
    }

    /// returns a reverse iterator to the beginning
    const_reverse_iterator crbegin() const noexcept
    {
        return m_map.crbegin();
    }

    /// returns a reverse iterator to the end
    const_reverse_iterator crend() const noexcept
    {
        return m_map.crend();
    }

    /*
     * Capacity
     */

    /// checks whether the container is empty
    bool empty() const noexcept
    {
        return m_map.empty();
    }

    /// returns the number of elements
    size_type size() const noexcept
    {
        return m_map.size();
    }

    /// returns the maximum possible number of elements
    size_type max_size() const noexcept
    {
        return m_map.max_size();
    }

    /*
     * Modifiers
     */

    /// clears the contents
    void clear() noexcept
    {
        m_map.clear();
        m_keys.clear();
    }

    /// insert value
    std::pair<iterator, bool> insert(const value_type& value)
    {
        m_compare.add_key(value.first);
        return m_map.insert(value);
    }

    /// insert value
    template<class P>
    std::pair<iterator, bool> insert( P&& value ) // NOLINT(cppcoreguidelines-missing-std-forward)
    {
        m_compare.add_key(value.first);
        return m_map.insert(value);
    }

    /// insert value with hint
    iterator insert(const_iterator hint, const value_type& value)
    {
        m_compare.add_key(value.first);
        return m_map.insert(hint, value);
    }

    /// insert value with hint
    iterator insert(const_iterator hint, value_type&& value)
    {
        m_compare.add_key(value.first);
        return m_map.insert(hint, value);
    }

    /// insert value range
    template<class InputIt>
    void insert(InputIt first, InputIt last)
    {
        for (const_iterator it = first; it != last; ++it)
        {
            m_compare.add_key(it->first);
        }

        m_map.insert(first, last);
    }

    /// insert value list
    void insert(std::initializer_list<value_type> ilist)
    {
        for (auto value : ilist)
        {
            m_compare.add_key(value.first);
        }

        m_map.insert(ilist);
    }

    /// constructs element in-place
    template<class... Args>
    std::pair<iterator, bool> emplace(Args&& ... args)
    {
        typename fifo_map::value_type value(std::forward<Args>(args)...);
        m_compare.add_key(value.first);
        return m_map.emplace(std::move(value));
    }

    /// constructs element in-place with hint
    template<class... Args>
    iterator emplace_hint(const_iterator hint, Args&& ... args)
    {
        typename fifo_map::value_type value(std::forward<Args>(args)...);
        m_compare.add_key(value.first);
        return m_map.emplace_hint(hint, std::move(value));
    }

    /// remove element at position
    iterator erase(const_iterator pos)
    {
        m_compare.remove_key(pos->first);
        return m_map.erase(pos);
    }

    /// remove elements in range
    iterator erase(const_iterator first, const_iterator last)
    {
        for (const_iterator it = first; it != last; ++it)
        {
            m_compare.remove_key(it->first);
        }

        return m_map.erase(first, last);
    }

    /// remove elements with key
    size_type erase(const key_type& key)
    {
        size_type res = m_map.erase(key);

        if (res > 0)
        {
            m_compare.remove_key(key);
        }

        return res;
    }

    /// swaps the contents
    void swap(fifo_map& other) // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
    {
        std::swap(m_map, other.m_map);
        std::swap(m_compare, other.m_compare);
        std::swap(m_keys, other.m_keys);
    }

    /*
     * Lookup
     */

    /// returns the number of elements matching specific key
    size_type count(const Key& key) const
    {
        return m_map.count(key);
    }

    /// finds element with specific key
    iterator find(const Key& key)
    {
        return m_map.find(key);
    }

    /// finds element with specific key
    const_iterator find(const Key& key) const
    {
        return m_map.find(key);
    }

    /// returns range of elements matching a specific key
    std::pair<iterator, iterator> equal_range(const Key& key)
    {
        return m_map.equal_range(key);
    }

    /// returns range of elements matching a specific key
    std::pair<const_iterator, const_iterator> equal_range(const Key& key) const
    {
        return m_map.equal_range(key);
    }

    /// returns an iterator to the first element not less than the given key
    iterator lower_bound(const Key& key)
    {
        return m_map.lower_bound(key);
    }

    /// returns an iterator to the first element not less than the given key
    const_iterator lower_bound(const Key& key) const
    {
        return m_map.lower_bound(key);
    }

    /// returns an iterator to the first element greater than the given key
    iterator upper_bound(const Key& key)
    {
        return m_map.upper_bound(key);
    }

    /// returns an iterator to the first element greater than the given key
    const_iterator upper_bound(const Key& key) const
    {
        return m_map.upper_bound(key);
    }

    /*
     * Observers
     */

    /// returns the function that compares keys
    key_compare key_comp() const
    {
        return m_compare;
    }

    /*
     * Non-member functions
     */

    friend bool operator==(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map == rhs.m_map;
    }

    friend bool operator!=(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map != rhs.m_map;
    }

    friend bool operator<(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map < rhs.m_map;
    }

    friend bool operator<=(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map <= rhs.m_map;
    }

    friend bool operator>(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map > rhs.m_map;
    }

    friend bool operator>=(const fifo_map& lhs, const fifo_map& rhs)
    {
        return lhs.m_map >= rhs.m_map;
    }

  private:
    /// the keys
    std::unordered_map<Key, std::size_t> m_keys;
    /// the comparison object
    Compare m_compare;
    /// the internal data structure
    internal_map_type m_map;
};

} // namespace nlohmann

// specialization of std::swap
namespace std // NOLINT(cert-dcl58-cpp,-warnings-as-errors)
{
template <class Key, class T, class Compare, class Allocator>
inline void swap(nlohmann::fifo_map<Key, T, Compare, Allocator>& m1, // NOLINT(cert-dcl58-cpp,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
                 nlohmann::fifo_map<Key, T, Compare, Allocator>& m2)
{
    m1.swap(m2);
}
} // namespace std

#endif


//     __ _____ _____ _____
//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
// |  |  |__   |  |  | | | |  version 3.12.0
// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT

#include "Foo.hpp"

class Foo;


# <small>nlohmann::basic_json::</small>operator>=

```cpp
// until C++20
bool operator>=(const_reference lhs, const_reference rhs) noexcept;   // (1)

template<typename ScalarType>
bool operator>=(const_reference lhs, const ScalarType rhs) noexcept;  // (2)

template<typename ScalarType>
bool operator>=(ScalarType lhs, const const_reference rhs) noexcept;  // (2)
```

1. Compares whether one JSON value `lhs` is greater than or equal to another JSON value `rhs` according to the following
   rules:
    - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either operand is `NaN` and
      the other operand is either `NaN` or any other number.
    - Otherwise, returns the result of `#!cpp !(lhs < rhs)` (see [**operator<**](operator_lt.md)).

2. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON
   value by converting the scalar to a JSON value and comparing both JSON values according to 1.

## Template parameters

`ScalarType`
:   a scalar type according to `std::is_scalar<ScalarType>::value`

## Parameters

`lhs` (in)
:   first value to consider

`rhs` (in)
:   second value to consider

## Return value

whether `lhs` is greater than or equal to `rhs`

## Exception safety

No-throw guarantee: this function never throws exceptions.

## Complexity

Linear.

## Notes

!!! note "Comparing `NaN`"

    `NaN` values are unordered within the domain of numbers.
    The following comparisons all yield `#!cpp false`:
      1. Comparing a `NaN` with itself.
      2. Comparing a `NaN` with another `NaN`.
      3. Comparing a `NaN` and any other number.

!!! note "Operator overload resolution"

    Since C++20 overload resolution will consider the _rewritten candidate_ generated from
    [`operator<=>`](operator_spaceship.md).

## Examples

??? example

    The example demonstrates comparing several JSON types.

    ```cpp
    --8<-- "examples/operator__greaterequal.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/operator__greaterequal.output"
    ```

## See also

- [**operator<=>**](operator_spaceship.md) comparison: 3-way

## Version history

1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.


/*!
An implementation of `grep-matcher`'s `Matcher` trait for Rust's regex engine.
*/
#![deny(missing_docs)]

pub use crate::{
    error::{Error, ErrorKind},
    matcher::{RegexCaptures, RegexMatcher, RegexMatcherBuilder},
};

mod ast;
mod ban;
mod config;
mod error;
mod literal;
mod matcher;
mod non_matching;
mod strip;


import { BroadcastChannel, Worker } from 'node:worker_threads'
import path from 'node:path'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
import type { BirpcReturn } from 'birpc'
import { createBirpc } from 'birpc'
import { DevEnvironment } from '../../..'
import { type ViteDevServer, createServer } from '../../../server'

describe('running module runner inside a worker and using the ModuleRunnerTransport#invoke API', () => {
  let worker: Worker
  let server: ViteDevServer
  let rpc: BirpcReturn<
    unknown,
    { invoke: (data: any) => Promise<{ result: any } | { error: any }> }
  >
  let handleInvoke: (data: any) => Promise<{ result: any } | { error: any }>

  beforeAll(async () => {
    worker = new Worker(
      new URL('./fixtures/worker.invoke.mjs', import.meta.url),
      {
        stdout: true,
      },
    )
    await new Promise<void>((resolve, reject) => {
      worker.on('message', () => resolve())
      worker.on('error', reject)
    })
    server = await createServer({
      root: import.meta.dirname,
      logLevel: 'error',
      server: {
        middlewareMode: true,
        watch: null,
        hmr: {
          port: 9610,
        },
        fs: {
          allow: [path.resolve(import.meta.dirname, './fixtures')],
        },
      },
      environments: {
        worker: {
          dev: {
            createEnvironment: (name, config) => {
              return new DevEnvironment(name, config, {
                hot: false,
              })
            },
          },
        },
      },
    })
    handleInvoke = (data: any) =>
      server.environments.worker.hot.handleInvoke(data)
    rpc = createBirpc(
      {
        invoke: (data: any) => handleInvoke(data),
      },
      {
        post: (data) => worker.postMessage(data),
        on: (data) => worker.on('message', data),
      },
    )
  })

  afterAll(async () => {
    await Promise.allSettled([server.close(), worker.terminate()])
    rpc.$close()
  })

  async function run(id: string) {
    const channel = new BroadcastChannel('vite-worker:invoke')
    return new Promise<any>((resolve, reject) => {
      channel.onmessage = (event) => {
        try {
          resolve(event.data)
        } catch (e) {
          reject(e)
        }
      }
      channel.postMessage({ id })
    })
  }

  it('correctly runs ssr code', async () => {
    const output = await run('./fixtures/default-string.ts')
    expect(output).toStrictEqual({
      result: 'hello world',
    })
  })

  it('triggers an error', async () => {
    handleInvoke = async () => ({ error: new Error('This is an Invoke Error') })
    const output = await run('dummy')
    expect(output).not.toHaveProperty('result')
    expect(output.error).toContain('Error: This is an Invoke Error')
  })

  it('triggers an unknown error', async () => {
    handleInvoke = async () => ({ error: 'a string instead of an error' })
    const output = await run('dummy')
    expect(output).not.toHaveProperty('result')
    expect(output.error).toContain('Error: Unknown invoke error')
  })

  it('resolves builtin module without server round-trip', async () => {
    handleInvoke = (data: any) =>
      server.environments.worker.hot.handleInvoke(data)

    const output = await run('./fixtures/builtin-import.ts')
    expect(output).toHaveProperty('result')
    expect(output.result).toBe('baz.txt')
    expect(output.error).toBeUndefined()
  })

  it('server.fs check is applied to the custom transport by default', async () => {
    handleInvoke = (data: any) =>
      server.environments.worker.hot.handleInvoke(data)

    const output = await run('./fixture-outside.js')
    expect(output).toHaveProperty('error')
    expect(output.error).toContain('Failed to load url')
  })
})


import { fileURLToPath } from 'node:url'
import babel from '@babel/core'
import MagicString from 'magic-string'
import { Visitor, parseSync } from 'oxc-parser'
import { defineConfig } from 'vite'
import transformFooWithInlineSourceMap from './foo-with-sourcemap-plugin.ts'

export default defineConfig({
  plugins: [
    transformFooWithInlineSourceMap(),
    {
      name: 'test-babel-transformed-optimized-dep',
      async transform(code, id) {
        if (
          !id.includes('/deps/') ||
          !id.includes('@vitejs_test-dep-class-field-sourcemap-babel.js')
        ) {
          return
        }

        return babel.transformAsync(code, {
          filename: id,
          configFile: false,
          babelrc: false,
          ast: false,
          sourceMaps: true,
          plugins: [() => ({ visitor: { Program() {} } })],
        })
      },
    },
    {
      name: 'test-oxc-transformed-optimized-dep',
      transform(code, id) {
        if (
          !id.includes('/deps/') ||
          !id.includes('@vitejs_test-dep-class-field-sourcemap-oxc.js')
        ) {
          return
        }

        const parsed = parseSync(id, code, { range: true })
        const s = new MagicString(code)
        const visitor = new Visitor({
          Identifier(node) {
            s.overwrite(node.start, node.end, `${node.name}$$$`, {
              storeName: true,
            })
          },
        })
        visitor.visit(parsed.program)

        return {
          code: s.toString(),
          map: s.generateMap({
            hires: true,
            source: id,
            includeContent: true,
          }),
        }
      },
    },
  ],
  resolve: {
    alias: {
      '@vitejs/test-dep-class-field-sourcemap-babel': fileURLToPath(
        new URL('./dep-class-field-sourcemap-babel/index.js', import.meta.url),
      ),
      '@vitejs/test-dep-class-field-sourcemap-oxc': fileURLToPath(
        new URL('./dep-class-field-sourcemap-oxc/index.js', import.meta.url),
      ),
    },
  },
  optimizeDeps: {
    exclude: ['@vitejs/test-dep-malicious-sourcemap'],
    include: [
      '@vitejs/test-dep-class-field-sourcemap-babel',
      '@vitejs/test-dep-class-field-sourcemap-oxc',
    ],
    // Force class fields to be downleveled so the optimized deps get the
    // constructor parameter rename shape some of these sourcemap tests assert on.
    rolldownOptions: {
      transform: {
        target: 'es2015',
      },
    },
  },
  build: {
    sourcemap: true,
    rolldownOptions: {
      output: {
        // manualChunks(name) {
        //   if (name.endsWith('after-preload-dynamic.js')) {
        //     return 'after-preload-dynamic'
        //   }
        //   if (name.endsWith('after-preload-dynamic-hashbang.js')) {
        //     return 'after-preload-dynamic-hashbang'
        //   }
        //   if (name.endsWith('after-preload-dynamic-no-dep.js')) {
        //     return 'after-preload-dynamic-no-dep'
        //   }
        //   if (name.includes('with-define-object')) {
        //     return 'with-define-object'
        //   }
        // },
        codeSplitting: {
          groups: [
            { name: 'after-preload-dynamic', test: 'after-preload-dynamic.js' },
            {
              name: 'after-preload-dynamic-hashbang',
              test: 'after-preload-dynamic-hashbang.js',
            },
            {
              name: 'after-preload-dynamic-no-dep',
              test: 'after-preload-dynamic-no-dep.js',
            },
            { name: 'with-define-object', test: 'with-define-object' },
          ],
        },
        banner(chunk) {
          if (chunk.name.endsWith('after-preload-dynamic-hashbang')) {
            return '#!/usr/bin/env node'
          }
        },
        sourcemapDebugIds: true,
      },
    },
  },
  define: {
    __testDefineObject: '{ "hello": "test" }',
  },
})


import { expect, test } from 'vitest'
import {
  editFile,
  getBg,
  getColor,
  isBuild,
  isBundled,
  page,
  viteTestUrl,
} from '~utils'

export const sassTest = () => {
  test('sass', async () => {
    const imported = await page.$('.sass')
    const atImport = await page.$('.sass-at-import')
    const atImportAlias = await page.$('.sass-at-import-alias')
    const atImportRelative = await page.$('.sass-at-import-relative')
    const atImportReplacementAlias = await page.$(
      '.sass-at-import-replacement-alias',
    )
    const urlStartsWithVariable = await page.$('.sass-url-starts-with-variable')
    const urlStartsWithVariableInterpolation1 = await page.$(
      '.sass-url-starts-with-interpolation1',
    )
    const urlStartsWithVariableInterpolation2 = await page.$(
      '.sass-url-starts-with-interpolation2',
    )
    const urlStartsWithVariableConcat = await page.$(
      '.sass-url-starts-with-variable-concat',
    )
    const urlStartsWithFunctionCall = await page.$(
      '.sass-url-starts-with-function-call',
    )
    const partialImport = await page.$('.sass-partial')

    expect(await getColor(imported)).toBe('orange')
    expect(await getColor(atImport)).toBe('olive')
    expect(await getBg(atImport)).toMatch(
      isBundled ? /base64/ : '/nested/icon.png',
    )
    expect(await getColor(atImportAlias)).toBe('olive')
    expect(await getBg(atImportAlias)).toMatch(
      isBundled ? /base64/ : '/nested/icon.png',
    )
    expect(await getColor(atImportRelative)).toBe('olive')
    expect(await getBg(atImportRelative)).toMatch(
      isBundled ? /base64/ : '/nested/icon.png',
    )
    expect(await getColor(atImportReplacementAlias)).toBe('olive')
    expect(await getBg(urlStartsWithVariable)).toMatch(
      isBundled ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
    )
    expect(await getBg(urlStartsWithVariableInterpolation1)).toMatch(
      isBundled ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
    )
    expect(await getBg(urlStartsWithVariableInterpolation2)).toMatch(
      isBundled ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
    )
    expect(await getBg(urlStartsWithVariableConcat)).toMatch(
      isBundled ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
    )
    expect(await getBg(urlStartsWithFunctionCall)).toMatch(
      isBundled ? /ok-[-\w]+\.png/ : `${viteTestUrl}/ok.png`,
    )
    expect(await getColor(partialImport)).toBe('orchid')
    expect(await getColor(await page.$('.sass-file-absolute'))).toBe('orange')
    expect(await getColor(await page.$('.sass-dir-index'))).toBe('orange')
    expect(await getColor(await page.$('.sass-root-relative'))).toBe('orange')

    if (isBuild) return

    editFile('sass.scss', (code) =>
      code.replace('color: $injectedColor', 'color: red'),
    )
    await expect.poll(() => getColor(imported)).toBe('red')

    editFile('nested/_index.scss', (code) =>
      code.replace('color: olive', 'color: blue'),
    )
    await expect.poll(() => getColor(atImport)).toBe('blue')

    editFile('nested/_partial.scss', (code) =>
      code.replace('color: orchid', 'color: green'),
    )
    await expect.poll(() => getColor(partialImport)).toBe('green')
  })
}

export const sassModuleTests = (enableHmrTests = false) => {
  test('sass modules composes/from path resolving', async () => {
    const imported = await page.$('.path-resolved-modules-sass')
    expect(await getColor(imported)).toBe('orangered')

    // check if the generated CSS module class name is indeed using the
    // format specified in vite.config.js
    expect(await imported.getAttribute('class')).toMatch(
      /.composed-module__apply-color___[\w-]{5}/,
    )

    expect(await imported.getAttribute('class')).toMatch(
      /.composes-path-resolving-module__path-resolving-sass___[\w-]{5}/,
    )

    // @todo HMR is not working on this situation.
    // editFile('composed.module.scss', (code) =>
    //   code.replace('color: orangered', 'color: red')
    // )
    // await expect.poll(() => getColor(imported)).toMatch('red')
  })

  test('css modules w/ sass', async () => {
    const imported = await page.$('.modules-sass')
    expect(await getColor(imported)).toBe('orangered')
    expect(await imported.getAttribute('class')).toMatch(
      /.mod-module__apply-color___[\w-]{5}/,
    )

    if (isBuild) return

    editFile('mod.module.scss', (code) =>
      code.replace('color: orangered', 'color: blue'),
    )
    await expect.poll(() => getColor(imported)).toBe('blue')
  })
}

export const sassOtherTests = () => {
  test('@import dependency w/ sass entry', async () => {
    expect(await getColor('.css-dep-sass')).toBe('orange')
  })

  test('@import dependency w/ sass export mapping', async () => {
    expect(await getColor('.css-dep-exports-sass')).toBe('orange')
  })

  test('@import dependency w/ sass export mapping (deep)', async () => {
    expect(await getColor('.css-dep-exports-deep-sass')).toBe('orange')
  })

  test('@import dependency w/ sass export wildcard to `_partial.scss`', async () => {
    expect(await getColor('.css-dep-exports-partial-sass')).toBe('orange')
  })

  test('@import dependency w/out package scss', async () => {
    expect(await getColor('.sass-dep')).toBe('lavender')
  })
}


# <small>nlohmann::json_pointer::</small>empty

```cpp
bool empty() const noexcept;
```

Return whether the pointer points to the root document.

## Return value

`#!cpp true` iff the JSON pointer points to the root document.

## Exception safety

No-throw guarantee: this function never throws exceptions.

## Complexity

Constant.

## Examples

??? example

    The example shows the result of `empty` for different JSON Pointers.

    ```cpp
    --8<-- "examples/json_pointer__empty.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/json_pointer__empty.output"
    ```

## Version history

Added in version 3.6.0.


.counter {
  font-size: 16px;
  padding: 5px 10px;
  border-radius: 5px;
  color: var(--accent);
  background: var(--accent-bg);
  border: 2px solid transparent;
  transition: border-color 0.3s;
  margin-bottom: 24px;

  &:hover {
    border-color: var(--accent-border);
  }
  &:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
}

.hero {
  position: relative;

  .base,
  .framework,
  .vite {
    inset-inline: 0;
    margin: 0 auto;
  }

  .base {
    width: 170px;
    position: relative;
    z-index: 0;
  }

  .framework,
  .vite {
    position: absolute;
  }

  .framework {
    z-index: 1;
    top: 34px;
    height: 28px;
    transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
      scale(1.4);
  }

  .vite {
    z-index: 0;
    top: 107px;
    height: 26px;
    width: auto;
    transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
      scale(0.8);
  }
}

#center {
  display: flex;
  flex-direction: column;
  gap: 25px;
  place-content: center;
  place-items: center;
  flex-grow: 1;

  @media (max-width: 1024px) {
    padding: 32px 20px 24px;
    gap: 18px;
  }
}

#next-steps {
  display: flex;
  border-top: 1px solid var(--border);
  text-align: left;

  & > div {
    flex: 1 1 0;
    padding: 32px;
    @media (max-width: 1024px) {
      padding: 24px 20px;
    }
  }

  .icon {
    margin-bottom: 16px;
    width: 22px;
    height: 22px;
  }

  @media (max-width: 1024px) {
    flex-direction: column;
    text-align: center;
  }
}

#docs {
  border-right: 1px solid var(--border);

  @media (max-width: 1024px) {
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
}

#next-steps ul {
  list-style: none;
  padding: 0;
  display: flex;
  gap: 8px;
  margin: 32px 0 0;

  .logo {
    height: 18px;
  }

  a {
    color: var(--text-h);
    font-size: 16px;
    border-radius: 6px;
    background: var(--social-bg);
    display: flex;
    padding: 6px 12px;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    transition: box-shadow 0.3s;

    &:hover {
      box-shadow: var(--shadow);
    }
    .button-icon {
      height: 18px;
      width: 18px;
    }
  }

  @media (max-width: 1024px) {
    margin-top: 20px;
    flex-wrap: wrap;
    justify-content: center;

    li {
      flex: 1 1 calc(50% - 8px);
    }

    a {
      width: 100%;
      justify-content: center;
      box-sizing: border-box;
    }
  }
}

#spacer {
  height: 88px;
  border-top: 1px solid var(--border);
  @media (max-width: 1024px) {
    height: 48px;
  }
}

.ticks {
  position: relative;
  width: 100%;

  &::before,
  &::after {
    content: '';
    position: absolute;
    top: -4.5px;
    border: 5px solid transparent;
  }

  &::before {
    left: 0;
    border-left-color: var(--border);
  }
  &::after {
    right: 0;
    border-right-color: var(--border);
  }
}


#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
    // create byte vector
    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,
                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,
                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,
                                   0x00, 0x00, 0x00
                                  };

    // deserialize it with BSON
    json j = json::from_bson(v);

    // print the deserialized JSON value
    std::cout << std::setw(2) << j << std::endl;
}


# JSON_BRACE_INIT_COPY_SEMANTICS

```cpp
#define JSON_BRACE_INIT_COPY_SEMANTICS /* value */
```

When defined to `1`, single-element brace initialization of a `basic_json` value is treated as a copy/move of the
element rather than wrapping it in a single-element array.

## Default definition

The default value is `0` (disabled — existing behavior is preserved).

```cpp
#define JSON_BRACE_INIT_COPY_SEMANTICS 0
```

## Notes

!!! note "Background"

    C++ always prefers the `initializer_list` constructor over the copy/move constructor for brace initialization. This
    means that code like

    ```cpp
    json obj = {{"key", "value"}};
    json j{obj};
    ```

    creates a single-element **array** `[{"key":"value"}]` instead of a copy of `obj`. This behavior is
    compiler-dependent for older compilers (GCC wrapped, Clang did not), but starting from Clang 20, both compilers
    behave the same way.

    Enabling this macro opts into copy/move semantics for this case
    (see [#5074](https://github.com/nlohmann/json/issues/5074)).

!!! warning "Opt-in only"

    This macro must be defined **before** including `<nlohmann/json.hpp>`. Defining it after the include has no effect.

!!! tip "Workaround without the macro"

    To explicitly create a single-element array without enabling this macro, use `json::array()`:

    ```cpp
    json j = json::array({obj});  // always creates [obj]
    ```

## Examples

??? example "Default behavior (macro not defined)"

    Without the macro, single-element brace initialization wraps the value in an array:

    ```cpp
    #include <nlohmann/json.hpp>

    using json = nlohmann::json;

    int main()
    {
        json obj = {{"key", "value"}};

        json j{obj};
        // j is [{"key":"value"}]  -- single-element array, NOT a copy of obj
    }
    ```

??? example "Opt-in copy semantics (macro defined to 1)"

    With the macro, single-element brace initialization copies/moves the value:

    ```cpp
    #define JSON_BRACE_INIT_COPY_SEMANTICS 1
    #include <nlohmann/json.hpp>

    using json = nlohmann::json;

    int main()
    {
        json obj = {{"key", "value"}};

        json j{obj};
        // j is {"key":"value"}  -- copy of obj
    }
    ```

## See also

- [FAQ: Brace initialization yields arrays](../../home/faq.md#brace-initialization-yields-arrays)
- [**basic_json(initializer_list_t)**](../basic_json/basic_json.md) - the affected constructor

## Version history

- Added in version 3.13.0.


# <small>nlohmann::basic_json::</small>operator<=

```cpp
// until C++20
bool operator<=(const_reference lhs, const_reference rhs) noexcept;   // (1)

template<typename ScalarType>
bool operator<=(const_reference lhs, const ScalarType rhs) noexcept;  // (2)

template<typename ScalarType>
bool operator<=(ScalarType lhs, const const_reference rhs) noexcept;  // (2)
```

1. Compares whether one JSON value `lhs` is less than or equal to another JSON value `rhs`
   according to the following rules:
    - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either
      operand is `NaN` and the other operand is either `NaN` or any other number.
    - Otherwise, returns the result of `#!cpp !(rhs < lhs)` (see [**operator<**](operator_lt.md)).

2. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal
   to a JSON value by converting the scalar to a JSON value and comparing both JSON values according
   to 1.

## Template parameters

`ScalarType`
:   a scalar type according to `std::is_scalar<ScalarType>::value`

## Parameters

`lhs` (in)
:   first value to consider

`rhs` (in)
:   second value to consider

## Return value

whether `lhs` is less than or equal to `rhs`

## Exception safety

No-throw guarantee: this function never throws exceptions.

## Complexity

Linear.

## Notes

!!! note "Comparing `NaN`"

    `NaN` values are unordered within the domain of numbers.
    The following comparisons all yield `#!cpp false`:
      1. Comparing a `NaN` with itself.
      2. Comparing a `NaN` with another `NaN`.
      3. Comparing a `NaN` and any other number.

!!! note "Operator overload resolution"

    Since C++20 overload resolution will consider the _rewritten candidate_ generated from
    [`operator<=>`](operator_spaceship.md).

## Examples

??? example

    The example demonstrates comparing several JSON types.

    ```cpp
    --8<-- "examples/operator__lessequal.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/operator__lessequal.output"
    ```

## See also

- [**operator<=>**](operator_spaceship.md) comparison: 3-way

## Version history

1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.


// test importing both default and named exports from a CommonJS module
// React is the ultimate test of this because its dynamic exports assignments
// are not statically detectable by @rollup/plugin-commonjs.
import React, { useState } from 'react'
import ReactDOM from 'react-dom/client'
import { Socket } from 'phoenix'
import clip from 'clipboard'
import m from '@vitejs/test-dep-cjs-with-es-module-flag'
import cjsFromESM from '@vitejs/test-dep-cjs-compiled-from-esm'
import cjsFromCJS from '@vitejs/test-dep-cjs-compiled-from-cjs'
import * as cjsFromCJSNamespace from '@vitejs/test-dep-cjs-compiled-from-cjs'

// Test exporting a name that was already imported
export { useState } from 'react'
export { useState as anotherNameForUseState } from 'react'
export { default as React } from 'react'

if (typeof clip === 'function') {
  text('.cjs-clipboard', 'ok')
}

if (typeof Socket === 'function') {
  text('.cjs-phoenix', 'ok')
}

text('.cjs-with-es-module-flag', m.info)

if (typeof cjsFromESM.default === 'function') {
  text('.cjs-dep-cjs-compiled-from-esm', 'ok')
}

if (
  typeof cjsFromCJS === 'function' &&
  typeof cjsFromCJSNamespace !== 'function' &&
  cjsFromCJSNamespace.bar === 'bar'
) {
  text('.cjs-dep-cjs-compiled-from-cjs', 'ok')
}

function App() {
  const [count, setCount] = useState(0)

  return React.createElement(
    'button',
    {
      onClick() {
        setCount(count + 1)
      },
    },
    `count is ${count}`,
  )
}

ReactDOM.createRoot(document.querySelector('.cjs')).render(
  React.createElement(App),
)

function text(el, text) {
  document.querySelector(el).textContent = text
}


/// An error that can occur in this crate.
///
/// Generally, this error corresponds to problems building a regular
/// expression, whether it's in parsing, compilation or a problem with
/// guaranteeing a configured optimization.
#[derive(Clone, Debug)]
pub struct Error {
    kind: ErrorKind,
}

impl Error {
    pub(crate) fn regex<E: std::error::Error>(err: E) -> Error {
        Error { kind: ErrorKind::Regex(err.to_string()) }
    }

    /// Return the kind of this error.
    pub fn kind(&self) -> &ErrorKind {
        &self.kind
    }
}

/// The kind of an error that can occur.
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum ErrorKind {
    /// An error that occurred as a result of parsing a regular expression.
    /// This can be a syntax error or an error that results from attempting to
    /// compile a regular expression that is too big.
    ///
    /// The string here is the underlying error converted to a string.
    Regex(String),
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match self.kind {
            ErrorKind::Regex(_) => "regex error",
        }
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self.kind {
            ErrorKind::Regex(ref s) => write!(f, "{}", s),
        }
    }
}


# This is impossible to read, but these encodings rarely if ever change, so
# it probably does not matter. They are derived from the list given here:
# https://encoding.spec.whatwg.org/#concept-encoding-get
#
# The globbing here works in both fish and zsh (though they expand it in
# different orders). It may work in other shells too.

{{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
866 ibm{819,866} csibm866
big5{,-hkscs} {cn-,cs}big5 x-x-big5
cp{819,866,125{0,1,2,3,4,5,6,7,8}} x-cp125{0,1,2,3,4,5,6,7,8}
csiso2022{jp,kr} csiso8859{6,8}{e,i}
csisolatin{1,2,3,4,5,6,9} csisolatin{arabic,cyrillic,greek,hebrew}
ecma-{114,118} asmo-708 elot_928 sun_eu_greek
euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
{,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
iso-2022-{cn,cn-ext,jp,kr}
iso8859{,-}{1,2,3,4,5,6,7,8,9,10,11,13,14,15}
iso-8859-{1,2,3,4,5,6,7,8,9,10,11,{6,8}-{e,i},13,14,15,16} iso_8859-{1,2,3,4,5,6,7,8,9,15}
iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
latin{1,2,3,4,5,6} l{1,2,3,4,5,6,9}
shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
windows-{31j,874,949,125{0,1,2,3,4,5,6,7,8}} dos-874 tis-620 ansi_x3.4-1968
x-user-defined auto none


<!doctype html>
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

Flaskr

    {% if g.user %}

{{ g.user['username'] }}

Log Out
    {% else %}

Register

Log In
    {% endif %}

    {% block header %}{% endblock %}

  {% for message in get_flashed_messages() %}

{{ message }}

  {% endfor %}
  {% block content %}{% endblock %}