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

using json = nlohmann::json;

int main()
{
    // create JSON values
    json array = {1, 2, 3, 4, 5};
    json null;

    // print values
    std::cout << array << '\n';
    std::cout << null << '\n';

    // add values
    array.emplace_back(6);
    null.emplace_back("first");
    null.emplace_back(3, "second");

    // print values
    std::cout << array << '\n';
    std::cout << null << '\n';
}


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

using json = nlohmann::json;
using namespace nlohmann::literals;

int main()
{
    // create a JSON value
    const json j =
    {
        {"number", 1}, {"string", "foo"}, {"array", {1, 2}}
    };

    // read-only access

    // output element with JSON pointer "/number"
    std::cout << j["/number"_json_pointer] << '\n';
    // output element with JSON pointer "/string"
    std::cout << j["/string"_json_pointer] << '\n';
    // output element with JSON pointer "/array"
    std::cout << j["/array"_json_pointer] << '\n';
    // output element with JSON pointer "/array/1"
    std::cout << j["/array/1"_json_pointer] << '\n';
}


# Sponsors

You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).

## Priority Sponsor

- [Martti Laine](https://github.com/codeclown)
- [Paul Harrington](https://github.com/phrrngtn)

## Named Sponsors

- [Michael Hartmann](https://github.com/reFX-Mike)
- [Stefan Hagen](https://github.com/sthagen)
- [Steve Sperandeo](https://github.com/homer6)
- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)
- [Steve Wagner](https://github.com/ciroque)

Thanks everyone!


import path from 'node:path'
import fsp from 'node:fs/promises'
import colors from 'picocolors'
import type { ExistingRawSourceMap } from 'rolldown'
import type { Connect } from '#dep-types/connect'
import type { ViteDevServer } from '..'
import {
  createDebugger,
  fsPathFromId,
  injectQuery,
  isCSSRequest,
  isImportRequest,
  isJSRequest,
  normalizePath,
  prettifyUrl,
  removeImportQuery,
  removeTimestampQuery,
} from '../../utils'
import { send } from '../send'
import { ERR_DENIED_ID, ERR_LOAD_URL } from '../transformRequest'
import { applySourcemapIgnoreList } from '../sourcemap'
import { isHTMLProxy } from '../../plugins/html'
import {
  DEP_VERSION_RE,
  ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR,
  ERR_OPTIMIZE_DEPS_PROCESSING_ERROR,
  FS_PREFIX,
} from '../../constants'
import { isDirectCSSRequest, isDirectRequest } from '../../plugins/css'
import { ERR_CLOSED_SERVER } from '../pluginContainer'
import { cleanUrl, unwrapId, withTrailingSlash } from '../../../shared/utils'
import {
  ERR_OUTDATED_OPTIMIZED_DEP,
  NULL_BYTE_PLACEHOLDER,
} from '../../../shared/constants'
import type { ResolvedConfig } from '../../config'
import { checkLoadingAccess, respondWithAccessDenied } from './static'

const debugCache = createDebugger('vite:cache')

const knownIgnoreList = new Set(['/', '/favicon.ico'])

const documentFetchDests = new Set([
  'document',
  'iframe',
  'frame',
  'fencedframe',
])
function isDocumentFetchDest(req: Connect.IncomingMessage) {
  const fetchDest = req.headers['sec-fetch-dest']
  return fetchDest !== undefined && documentFetchDests.has(fetchDest)
}

// TODO: consolidate this regex pattern with the url, raw, and inline checks in plugins
const urlRE = /[?&]url\b/
const rawRE = /[?&]raw\b/
const inlineRE = /[?&]inline\b/
const svgRE = /\.svg\b/

export function isServerAccessDeniedForTransform(
  config: ResolvedConfig,
  id: string,
): boolean {
  if (rawRE.test(id) || urlRE.test(id) || inlineRE.test(id) || svgRE.test(id)) {
    return (
      checkLoadingAccess(config, cleanUrl(id)) !== 'allowed' ||
      checkLoadingAccess(config, id) !== 'allowed'
    )
  }
  return false
}

/**
 * A middleware that short-circuits the middleware chain to serve cached transformed modules
 */
export function cachedTransformMiddleware(
  server: ViteDevServer,
): Connect.NextHandleFunction {
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
  return function viteCachedTransformMiddleware(req, res, next) {
    const environment = server.environments.client

    if (isDocumentFetchDest(req)) {
      res.appendHeader('Vary', 'Sec-Fetch-Dest')
      return next()
    }

    // check if we can return 304 early
    const ifNoneMatch = req.headers['if-none-match']
    if (ifNoneMatch) {
      const moduleByEtag = environment.moduleGraph.getModuleByEtag(ifNoneMatch)
      if (
        moduleByEtag?.transformResult?.etag === ifNoneMatch &&
        moduleByEtag.url === req.url
      ) {
        // For CSS requests, if the same CSS file is imported in a module,
        // the browser sends the request for the direct CSS request with the etag
        // from the imported CSS module. We ignore the etag in this case.
        const maybeMixedEtag = isCSSRequest(req.url!)
        if (!maybeMixedEtag) {
          debugCache?.(`[304] ${prettifyUrl(req.url!, server.config.root)}`)
          res.statusCode = 304
          return res.end()
        }
      }
    }

    next()
  }
}

export function transformMiddleware(
  server: ViteDevServer,
): Connect.NextHandleFunction {
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`

  // check if public dir is inside root dir
  const { root, publicDir } = server.config
  const publicDirInRoot = publicDir.startsWith(withTrailingSlash(root))
  const publicPath = `${publicDir.slice(root.length)}/`

  return async function viteTransformMiddleware(req, res, next) {
    const environment = server.environments.client

    if (
      (req.method !== 'GET' && req.method !== 'HEAD') ||
      knownIgnoreList.has(req.url!) ||
      isDocumentFetchDest(req)
    ) {
      return next()
    }

    let url: string
    try {
      url = decodeURI(removeTimestampQuery(req.url!)).replace(
        NULL_BYTE_PLACEHOLDER,
        '\0',
      )
    } catch (e) {
      if (e instanceof URIError) {
        server.config.logger.warn(
          colors.yellow(
            `Malformed URI sequence in request URL: ${removeTimestampQuery(req.url!)}`,
          ),
        )
        return next()
      }
      return next(e)
    }

    const withoutQuery = cleanUrl(url)

    try {
      const isSourceMap = withoutQuery.endsWith('.map')
      // since we generate source map references, handle those requests here
      if (isSourceMap) {
        const depsOptimizer = environment.depsOptimizer
        if (depsOptimizer?.isOptimizedDepUrl(url)) {
          // If the browser is requesting a source map for an optimized dep, it
          // means that the dependency has already been pre-bundled and loaded
          const sourcemapPath = url.startsWith(FS_PREFIX)
            ? fsPathFromId(url)
            : normalizePath(path.resolve(server.config.root, url.slice(1)))
          // url may contain relative path that may resolve outside of the optimized deps directory
          if (!depsOptimizer.isOptimizedDepFile(sourcemapPath)) {
            return next()
          }
          try {
            const map = JSON.parse(
              await fsp.readFile(sourcemapPath, 'utf-8'),
            ) as ExistingRawSourceMap

            applySourcemapIgnoreList(
              map,
              sourcemapPath,
              server.config.server.sourcemapIgnoreList,
              server.config.logger,
            )

            return send(req, res, JSON.stringify(map), 'json', {
              headers: server.config.server.headers,
            })
          } catch {
            // Outdated source map request for optimized deps, this isn't an error
            // but part of the normal flow when re-optimizing after missing deps
            // Send back an empty source map so the browser doesn't issue warnings
            const dummySourceMap = {
              version: 3,
              file: sourcemapPath.replace(/\.map$/, ''),
              sources: [],
              sourcesContent: [],
              names: [],
              mappings: ';;;;;;;;;',
            }
            return send(req, res, JSON.stringify(dummySourceMap), 'json', {
              cacheControl: 'no-cache',
              headers: server.config.server.headers,
            })
          }
        } else {
          const originalUrl = url.replace(/\.map($|\?)/, '$1')
          const map = (
            await environment.moduleGraph.getModuleByUrl(originalUrl)
          )?.transformResult?.map
          if (map) {
            return send(req, res, JSON.stringify(map), 'json', {
              headers: server.config.server.headers,
            })
          } else {
            return next()
          }
        }
      }

      if (publicDirInRoot && url.startsWith(publicPath)) {
        warnAboutExplicitPublicPathInUrl(url)
      }

      if (
        req.headers['sec-fetch-dest'] === 'script' ||
        isJSRequest(url) ||
        isImportRequest(url) ||
        isCSSRequest(url) ||
        isHTMLProxy(url)
      ) {
        // strip ?import
        url = removeImportQuery(url)
        // Strip valid id prefix. This is prepended to resolved Ids that are
        // not valid browser import specifiers by the importAnalysis plugin.
        url = unwrapId(url)

        // for CSS, we differentiate between normal CSS requests and imports
        if (isCSSRequest(url)) {
          if (
            req.headers.accept?.includes('text/css') &&
            !isDirectRequest(url)
          ) {
            url = injectQuery(url, 'direct')
          }

          // check if we can return 304 early for CSS requests. These aren't handled
          // by the cachedTransformMiddleware due to the browser possibly mixing the
          // etags of direct and imported CSS
          const ifNoneMatch = req.headers['if-none-match']
          if (
            ifNoneMatch &&
            (await environment.moduleGraph.getModuleByUrl(url))?.transformResult
              ?.etag === ifNoneMatch
          ) {
            debugCache?.(`[304] ${prettifyUrl(url, server.config.root)}`)
            res.statusCode = 304
            return res.end()
          }
        }

        // resolve, load and transform using the plugin container
        const result = await environment.transformRequest(url)
        if (result) {
          const depsOptimizer = environment.depsOptimizer
          const type = isDirectCSSRequest(url) ? 'css' : 'js'
          const isDep =
            DEP_VERSION_RE.test(url) || depsOptimizer?.isOptimizedDepUrl(url)
          return send(req, res, result.code, type, {
            etag: result.etag,
            // allow browser to cache npm deps!
            cacheControl: isDep ? 'max-age=31536000,immutable' : 'no-cache',
            headers: server.config.server.headers,
            map: result.map,
          })
        }
      }
    } catch (e) {
      if (e?.code === ERR_OPTIMIZE_DEPS_PROCESSING_ERROR) {
        // Skip if response has already been sent
        if (!res.writableEnded) {
          res.statusCode = 504 // status code request timeout
          res.statusMessage = 'Optimize Deps Processing Error'
          res.end()
        }
        // This timeout is unexpected
        server.config.logger.error(e.message)
        return
      }
      if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) {
        // Skip if response has already been sent
        if (!res.writableEnded) {
          res.statusCode = 504 // status code request timeout
          res.statusMessage = 'Outdated Optimize Dep'
          res.end()
        }
        // We don't need to log an error in this case, the request
        // is outdated because new dependencies were discovered and
        // the new pre-bundle dependencies have changed.
        // A full-page reload has been issued, and these old requests
        // can't be properly fulfilled. This isn't an unexpected
        // error but a normal part of the missing deps discovery flow
        return
      }
      if (e?.code === ERR_CLOSED_SERVER) {
        // Skip if response has already been sent
        if (!res.writableEnded) {
          res.statusCode = 504 // status code request timeout
          res.statusMessage = 'Outdated Request'
          res.end()
        }
        // We don't need to log an error in this case, the request
        // is outdated because new dependencies were discovered and
        // the new pre-bundle dependencies have changed.
        // A full-page reload has been issued, and these old requests
        // can't be properly fulfilled. This isn't an unexpected
        // error but a normal part of the missing deps discovery flow
        return
      }
      if (e?.code === ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR) {
        // Skip if response has already been sent
        if (!res.writableEnded) {
          res.statusCode = 404
          res.end()
        }
        server.config.logger.warn(colors.yellow(e.message))
        return
      }
      if (e?.code === ERR_LOAD_URL) {
        // Let other middleware handle if we can't load the url via transformRequest
        return next()
      }
      if (e?.code === ERR_DENIED_ID) {
        const id: string = e.id
        let servingAccessResult = checkLoadingAccess(
          server.config,
          cleanUrl(id),
        )
        if (servingAccessResult === 'allowed') {
          servingAccessResult = checkLoadingAccess(server.config, id)
        }
        if (servingAccessResult === 'denied') {
          respondWithAccessDenied(id, server, res)
          return true
        }
        if (servingAccessResult === 'fallback') {
          next()
          return true
        }
        servingAccessResult satisfies 'allowed'
        throw new Error(`Unexpected access result for id ${id}`)
      }
      return next(e)
    }

    next()
  }

  function warnAboutExplicitPublicPathInUrl(url: string) {
    let warning: string

    if (isImportRequest(url)) {
      const rawUrl = removeImportQuery(url)
      if (urlRE.test(url)) {
        warning =
          `Assets in the public directory are served at the root path.\n` +
          `Instead of ${colors.cyan(rawUrl)}, use ${colors.cyan(
            rawUrl.replace(publicPath, '/'),
          )}.`
      } else {
        warning =
          'Assets in public directory cannot be imported from JavaScript.\n' +
          `If you intend to import that asset, put the file in the src directory, and use ${colors.cyan(
            rawUrl.replace(publicPath, '/src/'),
          )} instead of ${colors.cyan(rawUrl)}.\n` +
          `If you intend to use the URL of that asset, use ${colors.cyan(
            injectQuery(rawUrl.replace(publicPath, '/'), 'url'),
          )}.`
      }
    } else {
      warning =
        `Files in the public directory are served at the root path.\n` +
        `Instead of ${colors.cyan(url)}, use ${colors.cyan(
          url.replace(publicPath, '/'),
        )}.`
    }

    server.config.logger.warn(colors.yellow(warning))
  }
}


// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
#include <cstdint>
#include <cstdlib>
#include <cstddef>
#include <iostream>

static volatile int Sink;
static volatile int *Null = 0;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  if (Size > 0 && Data[0] == 'H') {
    Sink = 1;
    if (Size > 1 && Data[1] == 'i') {
      Sink = 2;
      if (Size > 2 && Data[2] == '!') {
        std::cout << "Found the target, dereferencing NULL\n";
        *Null = 1;
      }
    }
  }
  return 0;
}


# <small>nlohmann::basic_json::</small>diff

```cpp
static basic_json diff(const basic_json& source,
                       const basic_json& target);
```

Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling
[`patch`](patch.md) function.

For two JSON values `source` and `target`, the following code yields always `#!cpp true`:
```cpp
source.patch(diff(source, target)) == target;
```

## Parameters

`source` (in)
:   JSON value to compare from

`target` (in)
:   JSON value to compare against

## Return value

a JSON patch to convert the `source` to `target`

## Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

## Complexity

Linear in the lengths of `source` and `target`.

## Notes

Currently, only `remove`, `add`, and `replace` operations are generated.

## Examples

??? example

    The following code shows how a JSON patch is created as a diff for two JSON values.

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

    Output:

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

## See also

- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
- [patch](patch.md) applies a JSON Patch
- [patch_inplace](patch_inplace.md) applies a JSON Patch in place
- [merge_patch](merge_patch.md) applies a JSON Merge Patch

## Version history

- Added in version 2.0.0.


// @ts-check
import fs from 'node:fs'
import path from 'node:path'
import express from 'express'

const isTest = process.env.VITEST

export async function createServer(root = process.cwd(), hmrPort) {
  const resolve = (p) => path.resolve(import.meta.dirname, p)

  const app = express()

  /**
   * @type {import('vite').ViteDevServer}
   */
  const vite = await (
    await import('vite')
  ).createServer({
    root,
    logLevel: isTest ? 'error' : 'info',
    server: {
      middlewareMode: true,
      hmr: {
        port: hmrPort,
      },
    },
    appType: 'custom',
  })
  app.use(vite.middlewares)

  app.use('*all', async (req, res) => {
    try {
      let template = fs.readFileSync(resolve('index.html'), 'utf-8')
      template = await vite.transformIndexHtml(req.originalUrl, template)

      // `main.js` imports dependencies that are yet to be discovered and optimized, aka "missing" deps.
      // Loading `main.js` in SSR should not trigger optimizing the "missing" deps
      const { name } = await vite.ssrLoadModule('./main.js')

      // Loading `main.js` in the client should trigger optimizing the "missing" deps
      const appHtml = `
${name}

`

      const html = template.replace(`<!--app-html-->`, appHtml)

      res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
    } catch (e) {
      vite.ssrFixStacktrace(e)
      console.log(e.stack)
      res.status(500).end(e.stack)
    }
  })

  return { app, vite }
}

if (!isTest) {
  createServer().then(({ app }) =>
    app.listen(5173, () => {
      console.log('http://localhost:5173')
    }),
  )
}


use crate::hay::SHERLOCK;
use crate::util::{Dir, TestCommand, cmd_exists, sort_lines};

// This file contains "miscellaneous" tests that were either written before
// features were tracked more explicitly, or were simply written without
// linking them to a specific issue number. We should try to minimize the
// addition of more tests in this file and instead add them to either the
// regression test suite or the feature test suite (found in regression.rs and
// feature.rs, respectively).

rgtest!(single_file, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.arg("Sherlock").arg("sherlock").stdout());
});

rgtest!(dir, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.arg("Sherlock").stdout());
});

rgtest!(line_numbers, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);

    let expected = "\
1:For the Doctor Watsons of this world, as opposed to the Sherlock
3:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.arg("-n").arg("Sherlock").arg("sherlock").stdout());
});

rgtest!(columns, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--column").arg("Sherlock").arg("sherlock");

    let expected = "\
1:57:For the Doctor Watsons of this world, as opposed to the Sherlock
3:49:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(with_filename, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-H").arg("Sherlock").arg("sherlock");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(with_heading, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&[
        // This forces the issue since --with-filename is disabled by default
        // when searching one file.
        "--with-filename",
        "--heading",
        "Sherlock",
        "sherlock",
    ]);

    let expected = "\
sherlock
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(with_heading_default, |dir: Dir, mut cmd: TestCommand| {
    // Search two or more and get --with-filename enabled by default.
    // Use -j1 to get deterministic results.
    dir.create("sherlock", SHERLOCK);
    dir.create("foo", "Sherlock Holmes lives on Baker Street.");
    cmd.arg("-j1").arg("--heading").arg("Sherlock");

    let expected = "\
foo
Sherlock Holmes lives on Baker Street.

sherlock
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(sort_lines(expected), sort_lines(&cmd.stdout()));
});

rgtest!(inverted, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-v").arg("Sherlock").arg("sherlock");

    let expected = "\
Holmeses, success in the province of detective work must always
can extract a clew from a wisp of straw or a flake of cigar ash;
but Doctor Watson has to have it taken out for him and dusted,
and exhibited clearly, with a label attached.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(inverted_line_numbers, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-n").arg("-v").arg("Sherlock").arg("sherlock");

    let expected = "\
2:Holmeses, success in the province of detective work must always
4:can extract a clew from a wisp of straw or a flake of cigar ash;
5:but Doctor Watson has to have it taken out for him and dusted,
6:and exhibited clearly, with a label attached.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(case_insensitive, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-i").arg("sherlock").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(word, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-w").arg("as").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(word_period, |dir: Dir, mut cmd: TestCommand| {
    dir.create("haystack", "...");
    cmd.arg("-ow").arg(".").arg("haystack");

    let expected = "\
.
.
.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(line, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&[
        "-x",
        "Watson|and exhibited clearly, with a label attached.",
        "sherlock",
    ]);

    let expected = "\
and exhibited clearly, with a label attached.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(literal, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file", "blib\n()\nblab\n");
    cmd.arg("-F").arg("()").arg("file");

    eqnice!("()\n", cmd.stdout());
});

rgtest!(quiet, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-q").arg("Sherlock").arg("sherlock");

    assert!(cmd.stdout().is_empty());
});

rgtest!(replace, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-r").arg("FooBar").arg("Sherlock").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the FooBar
be, to a very large extent, the result of luck. FooBar Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(replace_groups, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&["-r", "$2, $1", "([A-Z][a-z]+) ([A-Z][a-z]+)", "sherlock"]);

    let expected = "\
For the Watsons, Doctor of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Holmes, Sherlock
but Watson, Doctor has to have it taken out for him and dusted,
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(replace_named_groups, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&[
        "-r",
        "$last, $first",
        "(?P<first>[A-Z][a-z]+) (?P<last>[A-Z][a-z]+)",
        "sherlock",
    ]);

    let expected = "\
For the Watsons, Doctor of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Holmes, Sherlock
but Watson, Doctor has to have it taken out for him and dusted,
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(replace_with_only_matching, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-o").arg("-r").arg("$1").arg(r"of (\w+)").arg("sherlock");

    let expected = "\
this
detective
luck
straw
cigar
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(file_types, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    cmd.arg("-t").arg("rust").arg("Sherlock");

    eqnice!("file.rs:Sherlock\n", cmd.stdout());
});

rgtest!(file_types_all, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    cmd.arg("-t").arg("all").arg("Sherlock");

    eqnice!("file.py:Sherlock\n", cmd.stdout());
});

rgtest!(file_types_negate, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.remove("sherlock");
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    cmd.arg("-T").arg("rust").arg("Sherlock");

    eqnice!("file.py:Sherlock\n", cmd.stdout());
});

rgtest!(file_types_negate_all, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    cmd.arg("-T").arg("all").arg("Sherlock");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(file_type_clear, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    cmd.arg("--type-clear").arg("rust").arg("-t").arg("rust").arg("Sherlock");

    cmd.assert_non_empty_stderr();
});

rgtest!(file_type_add, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    dir.create("file.wat", "Sherlock");
    cmd.args(&["--type-add", "wat:*.wat", "-t", "wat", "Sherlock"]);

    eqnice!("file.wat:Sherlock\n", cmd.stdout());
});

rgtest!(file_type_add_compose, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    dir.create("file.wat", "Sherlock");
    cmd.args(&[
        "--type-add",
        "wat:*.wat",
        "--type-add",
        "combo:include:wat,py",
        "-t",
        "combo",
        "Sherlock",
    ]);

    let expected = "\
file.py:Sherlock
file.wat:Sherlock
";
    eqnice!(expected, sort_lines(&cmd.stdout()));
});

rgtest!(glob, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    cmd.arg("-g").arg("*.rs").arg("Sherlock");

    eqnice!("file.rs:Sherlock\n", cmd.stdout());
});

rgtest!(glob_negate, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.remove("sherlock");
    dir.create("file.py", "Sherlock");
    dir.create("file.rs", "Sherlock");
    cmd.arg("-g").arg("!*.rs").arg("Sherlock");

    eqnice!("file.py:Sherlock\n", cmd.stdout());
});

rgtest!(glob_case_insensitive, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.HTML", "Sherlock");
    cmd.arg("--iglob").arg("*.html").arg("Sherlock");

    eqnice!("file.HTML:Sherlock\n", cmd.stdout());
});

rgtest!(glob_case_sensitive, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file1.HTML", "Sherlock");
    dir.create("file2.html", "Sherlock");
    cmd.arg("--glob").arg("*.html").arg("Sherlock");

    eqnice!("file2.html:Sherlock\n", cmd.stdout());
});

rgtest!(glob_always_case_insensitive, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.HTML", "Sherlock");
    cmd.args(&["--glob-case-insensitive", "--glob", "*.html", "Sherlock"]);

    eqnice!("file.HTML:Sherlock\n", cmd.stdout());
});

rgtest!(byte_offset_only_matching, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-b").arg("-o").arg("Sherlock");

    let expected = "\
sherlock:56:Sherlock
sherlock:177:Sherlock
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(count, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--count").arg("Sherlock");

    let expected = "sherlock:2\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(count_matches, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--count-matches").arg("the");

    let expected = "sherlock:4\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(count_matches_inverted, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--count-matches").arg("--invert-match").arg("Sherlock");

    let expected = "sherlock:4\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(count_matches_via_only, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--count").arg("--only-matching").arg("the");

    let expected = "sherlock:4\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(include_zero, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&["--count", "--include-zero", "nada"]);
    cmd.assert_err();

    let output = cmd.raw_output();
    let stdout = String::from_utf8_lossy(&output.stdout);
    let expected = "sherlock:0\n";

    eqnice!(expected, stdout);
});

rgtest!(include_zero_override, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.args(&["--count", "--include-zero", "--no-include-zero", "nada"]);
    cmd.assert_err();

    let output = cmd.raw_output();
    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(stdout.is_empty());
});

rgtest!(files_with_matches, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--files-with-matches").arg("Sherlock");

    let expected = "sherlock\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(files_without_match, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("file.py", "foo");
    cmd.arg("--files-without-match").arg("Sherlock");

    let expected = "file.py\n";
    eqnice!(expected, cmd.stdout());
});

rgtest!(after_context, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-A").arg("1").arg("Sherlock").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
Holmeses, success in the province of detective work must always
be, to a very large extent, the result of luck. Sherlock Holmes
can extract a clew from a wisp of straw or a flake of cigar ash;
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(after_context_line_numbers, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-A").arg("1").arg("-n").arg("Sherlock").arg("sherlock");

    let expected = "\
1:For the Doctor Watsons of this world, as opposed to the Sherlock
2-Holmeses, success in the province of detective work must always
3:be, to a very large extent, the result of luck. Sherlock Holmes
4-can extract a clew from a wisp of straw or a flake of cigar ash;
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(before_context, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-B").arg("1").arg("Sherlock").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
Holmeses, success in the province of detective work must always
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(before_context_line_numbers, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-B").arg("1").arg("-n").arg("Sherlock").arg("sherlock");

    let expected = "\
1:For the Doctor Watsons of this world, as opposed to the Sherlock
2-Holmeses, success in the province of detective work must always
3:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(context, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-C").arg("1").arg("world|attached").arg("sherlock");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
Holmeses, success in the province of detective work must always
--
but Doctor Watson has to have it taken out for him and dusted,
and exhibited clearly, with a label attached.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(context_line_numbers, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("-C").arg("1").arg("-n").arg("world|attached").arg("sherlock");

    let expected = "\
1:For the Doctor Watsons of this world, as opposed to the Sherlock
2-Holmeses, success in the province of detective work must always
--
5-but Doctor Watson has to have it taken out for him and dusted,
6:and exhibited clearly, with a label attached.
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(max_filesize_parse_error_length, |_: Dir, mut cmd: TestCommand| {
    cmd.arg("--max-filesize").arg("44444444444444444444");
    cmd.assert_non_empty_stderr();
});

rgtest!(max_filesize_parse_error_suffix, |_: Dir, mut cmd: TestCommand| {
    cmd.arg("--max-filesize").arg("45k");
    cmd.assert_non_empty_stderr();
});

rgtest!(max_filesize_parse_no_suffix, |dir: Dir, mut cmd: TestCommand| {
    dir.create_size("foo", 40);
    dir.create_size("bar", 60);
    cmd.arg("--max-filesize").arg("50").arg("--files");

    eqnice!("foo\n", cmd.stdout());
});

rgtest!(max_filesize_parse_k_suffix, |dir: Dir, mut cmd: TestCommand| {
    dir.create_size("foo", 3048);
    dir.create_size("bar", 4100);
    cmd.arg("--max-filesize").arg("4K").arg("--files");

    eqnice!("foo\n", cmd.stdout());
});

rgtest!(max_filesize_parse_m_suffix, |dir: Dir, mut cmd: TestCommand| {
    dir.create_size("foo", 1000000);
    dir.create_size("bar", 1400000);
    cmd.arg("--max-filesize").arg("1M").arg("--files");

    eqnice!("foo\n", cmd.stdout());
});

rgtest!(max_filesize_suffix_overflow, |dir: Dir, mut cmd: TestCommand| {
    dir.create_size("foo", 1000000);

    // 2^35 * 2^30 would otherwise overflow
    cmd.arg("--max-filesize").arg("34359738368G").arg("--files");
    cmd.assert_non_empty_stderr();
});

rgtest!(ignore_hidden, |dir: Dir, mut cmd: TestCommand| {
    dir.create(".sherlock", SHERLOCK);
    cmd.arg("Sherlock").assert_err();
});

rgtest!(no_ignore_hidden, |dir: Dir, mut cmd: TestCommand| {
    dir.create(".sherlock", SHERLOCK);
    cmd.arg("--hidden").arg("Sherlock");

    let expected = "\
.sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
.sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(ignore_git, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create_dir(".git");
    dir.create(".gitignore", "sherlock\n");
    cmd.arg("Sherlock");

    cmd.assert_err();
});

rgtest!(ignore_generic, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create(".ignore", "sherlock\n");
    cmd.arg("Sherlock");

    cmd.assert_err();
});

rgtest!(ignore_ripgrep, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create(".rgignore", "sherlock\n");
    cmd.arg("Sherlock");

    cmd.assert_err();
});

rgtest!(no_ignore, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create(".gitignore", "sherlock\n");
    cmd.arg("--no-ignore").arg("Sherlock");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(ignore_git_parent, |dir: Dir, mut cmd: TestCommand| {
    dir.create_dir(".git");
    dir.create(".gitignore", "sherlock\n");
    dir.create_dir("foo");
    dir.create("foo/sherlock", SHERLOCK);
    cmd.arg("Sherlock");

    // Even though we search in foo/, which has no .gitignore, ripgrep will
    // traverse parent directories and respect the gitignore files found.
    cmd.current_dir("foo");
    cmd.assert_err();
});

rgtest!(ignore_git_parent_stop, |dir: Dir, mut cmd: TestCommand| {
    // This tests that searching parent directories for .gitignore files stops
    // after it sees a .git directory. To test this, we create this directory
    // hierarchy:
    //
    // .gitignore (contains `sherlock`)
    // foo/
    //   .git/
    //   bar/
    //      sherlock
    //
    // And we perform the search inside `foo/bar/`. ripgrep will stop looking
    // for .gitignore files after it sees `foo/.git/`, and therefore not
    // respect the top-level `.gitignore` containing `sherlock`.
    dir.create(".gitignore", "sherlock\n");
    dir.create_dir("foo");
    dir.create_dir("foo/.git");
    dir.create_dir("foo/bar");
    dir.create("foo/bar/sherlock", SHERLOCK);
    cmd.arg("Sherlock");
    cmd.current_dir("foo/bar");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

// Like ignore_git_parent_stop, but with a .git file instead of a .git
// directory.
rgtest!(ignore_git_parent_stop_file, |dir: Dir, mut cmd: TestCommand| {
    // This tests that searching parent directories for .gitignore files stops
    // after it sees a .git *file*. A .git file is used for submodules. To test
    // this, we create this directory hierarchy:
    //
    // .gitignore (contains `sherlock`)
    // foo/
    //   .git
    //   bar/
    //      sherlock
    //
    // And we perform the search inside `foo/bar/`. ripgrep will stop looking
    // for .gitignore files after it sees `foo/.git`, and therefore not
    // respect the top-level `.gitignore` containing `sherlock`.
    dir.create(".gitignore", "sherlock\n");
    dir.create_dir("foo");
    dir.create("foo/.git", "");
    dir.create_dir("foo/bar");
    dir.create("foo/bar/sherlock", SHERLOCK);
    cmd.arg("Sherlock");
    cmd.current_dir("foo/bar");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(ignore_ripgrep_parent_no_stop, |dir: Dir, mut cmd: TestCommand| {
    // This is like the `ignore_git_parent_stop` test, except it checks that
    // ripgrep *doesn't* stop checking for .rgignore files.
    dir.create(".rgignore", "sherlock\n");
    dir.create_dir("foo");
    dir.create_dir("foo/.git");
    dir.create_dir("foo/bar");
    dir.create("foo/bar/sherlock", SHERLOCK);
    cmd.arg("Sherlock");
    cmd.current_dir("foo/bar");

    // The top-level .rgignore applies.
    cmd.assert_err();
});

rgtest!(no_parent_ignore_git, |dir: Dir, mut cmd: TestCommand| {
    // Set up a directory hierarchy like this:
    //
    // .git/
    // .gitignore
    // foo/
    //   .gitignore
    //   sherlock
    //   watson
    //
    // Where `.gitignore` contains `sherlock` and `foo/.gitignore` contains
    // `watson`.
    //
    // Now *do the search* from the foo directory. By default, ripgrep will
    // search parent directories for .gitignore files. The --no-ignore-parent
    // flag should prevent that. At the same time, the `foo/.gitignore` file
    // will still be respected (since the search is happening in `foo/`).
    //
    // In other words, we should only see results from `sherlock`, not from
    // `watson`.
    dir.create_dir(".git");
    dir.create(".gitignore", "sherlock\n");
    dir.create_dir("foo");
    dir.create("foo/.gitignore", "watson\n");
    dir.create("foo/sherlock", SHERLOCK);
    dir.create("foo/watson", SHERLOCK);
    cmd.arg("--no-ignore-parent").arg("Sherlock");
    cmd.current_dir("foo");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

// Multiple explicit search roots must apply parent .gitignore rules using each
// root's own path base. Searching `src` before `tests` used to leak the wrong
// absolute base into cached parent matchers so `src/invalid` was not ignored.
// See: https://github.com/BurntSushi/ripgrep/issues/3376
rgtest!(ignore_git_multi_root_order, |dir: Dir, mut cmd: TestCommand| {
    dir.create_dir(".git");
    dir.create(".gitignore", "src/invalid\n");
    dir.create_dir("src");
    dir.create_dir("tests");
    dir.create("src/invalid", "this\n");
    dir.create("src/valid", "this\n");
    dir.create("tests/valid", "this\n");

    cmd.args(&["--files-with-matches", "this", "src", "tests"]);
    let got = cmd.stdout();
    assert!(
        !got.contains("invalid"),
        "src/invalid must stay ignored with multiple roots, got:\n{}",
        got
    );
    assert!(got.contains("src/valid"), "missing src/valid in:\n{}", got);
    assert!(got.contains("tests/valid"), "missing tests/valid in:\n{}", got);

    // Reverse CLI order should behave the same.
    let mut cmd = dir.command();
    cmd.args(&["--files-with-matches", "this", "tests", "src"]);
    let got = cmd.stdout();
    assert!(
        !got.contains("invalid"),
        "src/invalid must stay ignored with roots reversed, got:\n{}",
        got
    );
});

// Same multi-root path-base issue for `.rgignore`.
// See: https://github.com/BurntSushi/ripgrep/issues/3320
rgtest!(ignore_rgignore_multi_root_order, |dir: Dir, mut cmd: TestCommand| {
    dir.create(".rgignore", "beta/**/*.svg\n");
    dir.create_dir("alpha");
    dir.create_dir("beta");
    dir.create("alpha/a.txt", "AWS\n");
    dir.create("beta/x.svg", "AWS\n");

    cmd.args(&["--files-with-matches", "AWS", "alpha", "beta"]);
    let got = cmd.stdout();
    assert!(
        !got.contains("x.svg"),
        "beta/x.svg must be ignored with multiple roots, got:\n{}",
        got
    );
    assert!(got.contains("alpha/a.txt"), "missing alpha/a.txt in:\n{}", got);

    let mut cmd = dir.command();
    cmd.args(&["--files-with-matches", "AWS", "beta", "alpha"]);
    let got = cmd.stdout();
    assert!(
        !got.contains("x.svg"),
        "beta/x.svg must be ignored with roots reversed, got:\n{}",
        got
    );
});

rgtest!(symlink_nofollow, |dir: Dir, mut cmd: TestCommand| {
    dir.create_dir("foo");
    dir.create_dir("foo/bar");
    dir.link_dir("foo/baz", "foo/bar/baz");
    dir.create_dir("foo/baz");
    dir.create("foo/baz/sherlock", SHERLOCK);
    cmd.arg("Sherlock");
    cmd.current_dir("foo/bar");

    cmd.assert_err();
});

#[cfg(not(windows))]
rgtest!(symlink_follow, |dir: Dir, mut cmd: TestCommand| {
    dir.create_dir("foo");
    dir.create_dir("foo/bar");
    dir.create_dir("foo/baz");
    dir.create("foo/baz/sherlock", SHERLOCK);
    dir.link_dir("foo/baz", "foo/bar/baz");
    cmd.arg("-L").arg("Sherlock");
    cmd.current_dir("foo/bar");

    let expected = "\
baz/sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
baz/sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(unrestricted1, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create(".gitignore", "sherlock\n");
    cmd.arg("-u").arg("Sherlock");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(unrestricted2, |dir: Dir, mut cmd: TestCommand| {
    dir.create(".sherlock", SHERLOCK);
    cmd.arg("-uu").arg("Sherlock");

    let expected = "\
.sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
.sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(unrestricted3, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    dir.create("hay", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("-uuu").arg("foo");

    let expected = "\
hay: binary file matches (found \"\\0\" byte around offset 3)
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(vimgrep, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--vimgrep").arg("Sherlock|Watson");

    let expected = "\
sherlock:1:16:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:1:57:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:3:49:be, to a very large extent, the result of luck. Sherlock Holmes
sherlock:5:12:but Doctor Watson has to have it taken out for him and dusted,
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(vimgrep_no_line, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--vimgrep").arg("-N").arg("Sherlock|Watson");

    let expected = "\
sherlock:16:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:57:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:49:be, to a very large extent, the result of luck. Sherlock Holmes
sherlock:12:but Doctor Watson has to have it taken out for him and dusted,
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(vimgrep_no_line_no_column, |dir: Dir, mut cmd: TestCommand| {
    dir.create("sherlock", SHERLOCK);
    cmd.arg("--vimgrep").arg("-N").arg("--no-column").arg("Sherlock|Watson");

    let expected = "\
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
sherlock:but Doctor Watson has to have it taken out for him and dusted,
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(preprocessing, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("xzcat") {
        return;
    }

    dir.create_bytes("sherlock.xz", include_bytes!("./data/sherlock.xz"));
    cmd.arg("--pre").arg("xzcat").arg("Sherlock").arg("sherlock.xz");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(preprocessing_glob, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("xzcat") {
        return;
    }

    dir.create("sherlock", SHERLOCK);
    dir.create_bytes("sherlock.xz", include_bytes!("./data/sherlock.xz"));
    cmd.args(&["--pre", "xzcat", "--pre-glob", "*.xz", "Sherlock"]);

    let expected = "\
sherlock.xz:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock.xz:be, to a very large extent, the result of luck. Sherlock Holmes
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(sort_lines(expected), sort_lines(&cmd.stdout()));
});

rgtest!(compressed_gzip, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("gzip") {
        return;
    }

    dir.create_bytes("sherlock.gz", include_bytes!("./data/sherlock.gz"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.gz");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_bzip2, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("bzip2") {
        return;
    }

    dir.create_bytes("sherlock.bz2", include_bytes!("./data/sherlock.bz2"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.bz2");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_xz, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("xz") {
        return;
    }

    dir.create_bytes("sherlock.xz", include_bytes!("./data/sherlock.xz"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.xz");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_lz4, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("lz4") {
        return;
    }

    dir.create_bytes("sherlock.lz4", include_bytes!("./data/sherlock.lz4"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.lz4");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_lzma, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("xz") {
        return;
    }

    dir.create_bytes("sherlock.lzma", include_bytes!("./data/sherlock.lzma"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.lzma");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_brotli, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("brotli") {
        return;
    }

    dir.create_bytes("sherlock.br", include_bytes!("./data/sherlock.br"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.br");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_zstd, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("zstd") {
        return;
    }

    dir.create_bytes("sherlock.zst", include_bytes!("./data/sherlock.zst"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.zst");

    let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_uncompress, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("uncompress") {
        return;
    }

    dir.create_bytes("sherlock.Z", include_bytes!("./data/sherlock.Z"));
    cmd.arg("-z").arg("Sherlock").arg("sherlock.Z");

    let expected = "\
    For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(compressed_failing_gzip, |dir: Dir, mut cmd: TestCommand| {
    if !cmd_exists("gzip") {
        return;
    }

    dir.create("sherlock.gz", SHERLOCK);
    cmd.arg("-z").arg("Sherlock").arg("sherlock.gz");

    cmd.assert_non_empty_stderr();
});

rgtest!(binary_convert, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("--no-mmap").arg("foo").arg("file");

    let expected = "\
binary file matches (found \"\\0\" byte around offset 3)
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(binary_convert_mmap, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("--mmap").arg("foo").arg("file");

    let expected = "\
binary file matches (found \"\\0\" byte around offset 3)
";
    eqnice!(expected, cmd.stdout());
});

rgtest!(binary_quit, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("--no-mmap").arg("foo").arg("-gfile");
    cmd.assert_err();
});

rgtest!(binary_quit_mmap, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("--mmap").arg("foo").arg("-gfile");
    cmd.assert_err();
});

// The following two tests show a discrepancy in search results between
// searching with memory mapped files and stream searching. Stream searching
// uses a heuristic (that GNU grep also uses) where NUL bytes are replaced with
// the EOL terminator, which tends to avoid allocating large amounts of memory
// for really long "lines." The memory map searcher has no need to worry about
// such things, and more than that, it would be pretty hard for it to match the
// semantics of streaming search in this case.
//
// Binary files with lots of NULs aren't really part of the use case of ripgrep
// (or any other grep-like tool for that matter), so we shouldn't feel too bad
// about it.
rgtest!(binary_search_mmap, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("-a").arg("--mmap").arg("foo").arg("file");
    eqnice!("foo\x00bar\nfoo\x00baz\n", cmd.stdout());
});

rgtest!(binary_search_no_mmap, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "foo\x00bar\nfoo\x00baz\n");
    cmd.arg("-a").arg("--no-mmap").arg("foo").arg("file");
    eqnice!("foo\x00bar\nfoo\x00baz\n", cmd.stdout());
});

rgtest!(files, |dir: Dir, mut cmd: TestCommand| {
    dir.create("file", "");
    dir.create_dir("dir");
    dir.create("dir/file", "");
    cmd.arg("--files");

    eqnice!(sort_lines("file\ndir/file\n"), sort_lines(&cmd.stdout()));
});

rgtest!(type_list, |_: Dir, mut cmd: TestCommand| {
    cmd.arg("--type-list");
    // This can change over time, so just make sure we print something.
    assert!(!cmd.stdout().is_empty());
});

// The following series of tests seeks to test all permutations of ripgrep's
// sorted queries.
//
// They all rely on this setup function, which sets up this particular file
// structure with a particular creation order:
//  ├── a             # 1
//  ├── b             # 4
//  └── dir           # 2
//     ├── c          # 3
//     └── d          # 5
//
// This order is important when sorting them by system time-stamps.
fn sort_setup(dir: Dir) {
    use std::{thread::sleep, time::Duration};
    // As reported in https://github.com/BurntSushi/ripgrep/issues/3071
    // this test fails if sufficient delay is not given on Windows/Aarch64.
    let delay = if cfg!(all(windows, target_arch = "aarch64")) {
        Duration::from_millis(1000)
    } else {
        Duration::from_millis(100)
    };
    let sub_dir = dir.path().join("dir");
    dir.create("a", "test");
    sleep(delay);
    dir.create_dir(&sub_dir);
    sleep(delay);
    dir.create(sub_dir.join("c"), "test");
    sleep(delay);
    dir.create("b", "test");
    sleep(delay);
    dir.create(sub_dir.join("d"), "test");
}

rgtest!(sort_files, |dir: Dir, mut cmd: TestCommand| {
    sort_setup(dir);
    let expected = "a:test\nb:test\ndir/c:test\ndir/d:test\n";
    eqnice!(expected, cmd.args(["--sort", "path", "test"]).stdout());
});

rgtest!(sort_accessed, |dir: Dir, mut cmd: TestCommand| {
    if crate::util::is_cross() {
        return;
    }
    sort_setup(dir);
    let expected = "a:test\ndir/c:test\nb:test\ndir/d:test\n";
    eqnice!(expected, cmd.args(["--sort", "accessed", "test"]).stdout());
});

rgtest!(sortr_accessed, |dir: Dir, mut cmd: TestCommand| {
    if crate::util::is_cross() {
        return;
    }
    sort_setup(dir);
    let expected = "dir/d:test\nb:test\ndir/c:test\na:test\n";
    eqnice!(expected, cmd.args(["--sortr", "accessed", "test"]).stdout());
});


# <small>nlohmann::basic_json::</small>is_primitive

```cpp
constexpr bool is_primitive() const noexcept;
```

This function returns `#!cpp true` if and only if the JSON type is primitive (string, number, boolean, `#!json null`,
binary).

## Return value

`#!cpp true` if type is primitive (string, number, boolean, `#!json null`, or binary), `#!cpp false` otherwise.

## Exception safety

No-throw guarantee: this member function never throws exceptions.

## Complexity

Constant.

## Possible implementation

```cpp
constexpr bool is_primitive() const noexcept
{
    return is_null() || is_string() || is_boolean() || is_number() || is_binary();
}
```

## Notes

The term *primitive* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259):

> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and
> arrays).

This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence,
`is_primitive()` returns `#!cpp true` for binary values.

## Examples

??? example

    The following code exemplifies `is_primitive()` for all JSON types.

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

    Output:

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

## See also

- [is_structured()](is_structured.md) returns whether the JSON value is structured
- [is_null()](is_null.md) returns whether the JSON value is `null`
- [is_string()](is_string.md) returns whether the JSON value is a string
- [is_boolean()](is_boolean.md) returns whether the JSON value is a boolean
- [is_number()](is_number.md) returns whether the JSON value is a number
- [is_binary()](is_binary.md) returns whether the JSON value is a binary array

## Version history

- Added in version 1.0.0.
- Extended to return `#!cpp true` for binary types in version 3.8.0.


//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
//! case of the source (e.g. `my-field`, `MY_FIELD`).

use self::RenameRule::*;
use std::fmt::{self, Debug, Display};

/// The different possible ways to change case of fields in a struct, or variants in an enum.
#[derive(Copy, Clone, PartialEq)]
pub enum RenameRule {
    /// Don't apply a default rename rule.
    None,
    /// Rename direct children to "lowercase" style.
    LowerCase,
    /// Rename direct children to "UPPERCASE" style.
    UpperCase,
    /// Rename direct children to "PascalCase" style, as typically used for
    /// enum variants.
    PascalCase,
    /// Rename direct children to "camelCase" style.
    CamelCase,
    /// Rename direct children to "snake_case" style, as commonly used for
    /// fields.
    SnakeCase,
    /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
    /// used for constants.
    ScreamingSnakeCase,
    /// Rename direct children to "kebab-case" style.
    KebabCase,
    /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
    ScreamingKebabCase,
}

static RENAME_RULES: &[(&str, RenameRule)] = &[
    ("lowercase", LowerCase),
    ("UPPERCASE", UpperCase),
    ("PascalCase", PascalCase),
    ("camelCase", CamelCase),
    ("snake_case", SnakeCase),
    ("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
    ("kebab-case", KebabCase),
    ("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
];

impl RenameRule {
    pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
        for (name, rule) in RENAME_RULES {
            if rename_all_str == *name {
                return Ok(*rule);
            }
        }
        Err(ParseError {
            unknown: rename_all_str,
        })
    }

    /// Apply a renaming rule to an enum variant, returning the version expected in the source.
    pub fn apply_to_variant(self, variant: &str) -> String {
        match self {
            None | PascalCase => variant.to_owned(),
            LowerCase => variant.to_ascii_lowercase(),
            UpperCase => variant.to_ascii_uppercase(),
            CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
            SnakeCase => {
                let mut snake = String::new();
                for (i, ch) in variant.char_indices() {
                    if i > 0 && ch.is_uppercase() {
                        snake.push('_');
                    }
                    snake.push(ch.to_ascii_lowercase());
                }
                snake
            }
            ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
            KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
            ScreamingKebabCase => ScreamingSnakeCase
                .apply_to_variant(variant)
                .replace('_', "-"),
        }
    }

    /// Apply a renaming rule to a struct field, returning the version expected in the source.
    pub fn apply_to_field(self, field: &str) -> String {
        match self {
            None | LowerCase | SnakeCase => field.to_owned(),
            UpperCase => field.to_ascii_uppercase(),
            PascalCase => {
                let mut pascal = String::new();
                let mut capitalize = true;
                for ch in field.chars() {
                    if ch == '_' {
                        capitalize = true;
                    } else if capitalize {
                        pascal.push(ch.to_ascii_uppercase());
                        capitalize = false;
                    } else {
                        pascal.push(ch);
                    }
                }
                pascal
            }
            CamelCase => {
                let pascal = PascalCase.apply_to_field(field);
                pascal[..1].to_ascii_lowercase() + &pascal[1..]
            }
            ScreamingSnakeCase => field.to_ascii_uppercase(),
            KebabCase => field.replace('_', "-"),
            ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
        }
    }

    /// Returns the `RenameRule` if it is not `None`, `rule_b` otherwise.
    pub fn or(self, rule_b: Self) -> Self {
        match self {
            None => rule_b,
            _ => self,
        }
    }
}

pub struct ParseError<'a> {
    unknown: &'a str,
}

impl<'a> Display for ParseError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("unknown rename rule `rename_all = ")?;
        Debug::fmt(self.unknown, f)?;
        f.write_str("`, expected one of ")?;
        for (i, (name, _rule)) in RENAME_RULES.iter().enumerate() {
            if i > 0 {
                f.write_str(", ")?;
            }
            Debug::fmt(name, f)?;
        }
        Ok(())
    }
}

#[test]
fn rename_variants() {
    for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
        (
            "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
        ),
        (
            "VeryTasty",
            "verytasty",
            "VERYTASTY",
            "veryTasty",
            "very_tasty",
            "VERY_TASTY",
            "very-tasty",
            "VERY-TASTY",
        ),
        ("A", "a", "A", "a", "a", "A", "a", "A"),
        ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
    ] {
        assert_eq!(None.apply_to_variant(original), original);
        assert_eq!(LowerCase.apply_to_variant(original), lower);
        assert_eq!(UpperCase.apply_to_variant(original), upper);
        assert_eq!(PascalCase.apply_to_variant(original), original);
        assert_eq!(CamelCase.apply_to_variant(original), camel);
        assert_eq!(SnakeCase.apply_to_variant(original), snake);
        assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
        assert_eq!(KebabCase.apply_to_variant(original), kebab);
        assert_eq!(
            ScreamingKebabCase.apply_to_variant(original),
            screaming_kebab
        );
    }
}

#[test]
fn rename_fields() {
    for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
        (
            "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
        ),
        (
            "very_tasty",
            "VERY_TASTY",
            "VeryTasty",
            "veryTasty",
            "VERY_TASTY",
            "very-tasty",
            "VERY-TASTY",
        ),
        ("a", "A", "A", "a", "A", "a", "A"),
        ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
    ] {
        assert_eq!(None.apply_to_field(original), original);
        assert_eq!(UpperCase.apply_to_field(original), upper);
        assert_eq!(PascalCase.apply_to_field(original), pascal);
        assert_eq!(CamelCase.apply_to_field(original), camel);
        assert_eq!(SnakeCase.apply_to_field(original), original);
        assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
        assert_eq!(KebabCase.apply_to_field(original), kebab);
        assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
    }
}


// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Test for signed-integer-overflow.
#include <assert.h>
#include <cstdint>
#include <cstdlib>
#include <cstddef>
#include <iostream>
#include <climits>

static volatile int Sink;
static int Large = INT_MAX;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  assert(Data);
  if (Size > 0 && Data[0] == 'H') {
    Sink = 1;
    if (Size > 1 && Data[1] == 'i') {
      Sink = 2;
      if (Size > 2 && Data[2] == '!') {
        Large++;  // int overflow.
      }
    }
  }
  return 0;
}


import { setTimeout } from 'node:timers/promises'
import { expect, test } from 'vitest'
import {
  editFile,
  findAssetFile,
  isBuild,
  notifyRebuildComplete,
  readManifest,
  watcher,
} from '~utils'

test.runIf(isBuild)('rebuilds styles only entry on change', async () => {
  expect(findAssetFile(/style-only-entry-.+\.css/, 'watch')).toContain(
    '#ff69b4',
  )
  expect(findAssetFile(/style-only-entry-legacy-.+\.js/, 'watch')).toContain(
    '#ff69b4',
  )
  expect(findAssetFile(/polyfills-legacy-.+\.js/, 'watch')).toBeTruthy()
  const numberOfManifestEntries = Object.keys(readManifest('watch')).length
  expect(numberOfManifestEntries).toBe(3)

  editFile('style-only-entry.css', (originalContents) =>
    originalContents.replace('#ff69b4', '#ffb6c1 '),
  )
  await notifyRebuildComplete(watcher)
  // wait for both "output" to complete, workaround for https://github.com/rolldown/rolldown/issues/10613
  await Promise.race([notifyRebuildComplete(watcher), setTimeout(100)])

  const updatedManifest = readManifest('watch')
  expect(Object.keys(updatedManifest)).toHaveLength(numberOfManifestEntries)

  // We must use the file referenced in the manifest here,
  // since there'll be different versions of the file with different hashes.
  const reRenderedCssFile = findAssetFile(
    updatedManifest['style-only-entry.css']!.file.substring('assets/'.length),
    'watch',
  )
  expect(reRenderedCssFile).toContain('#ffb6c1')
  const reRenderedCssLegacyFile = findAssetFile(
    updatedManifest['style-only-entry-legacy.css']!.file.substring(
      'assets/'.length,
    ),
    'watch',
  )
  expect(reRenderedCssLegacyFile).toContain('#ffb6c1')
  expect(findAssetFile(/polyfills-legacy-.+\.js/, 'watch')).toBeTruthy()
})


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Empty Attr</title>
  </head>
  <body>
    <img src="" alt="" />
  </body>
</html>


import path from 'node:path'
import { type Plugin, normalizePath } from 'vite'

// use plugin to simulate server rendered css link
export function TestCssLinkPlugin(): Plugin {
  return {
    name: 'test-css-link',
    transformIndexHtml: {
      handler(_html, ctx) {
        if (!ctx.filename.endsWith('/css-link/index.html')) return
        return [
          {
            tag: 'link',
            attrs: {
              rel: 'stylesheet',
              href: '/css-link/styles.css',
              'data-vite-dev-id': normalizePath(
                path.resolve(import.meta.dirname, 'styles.css'),
              ),
            },
          },
        ]
      },
    },
  }
}


## Usage

```bash
$ npm install # or pnpm install or yarn install
```

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev`

Runs the app in the development mode.

Open [http://localhost:5173](http://localhost:5173) to view it in the browser.

### `npm run build`

Builds the app for production to the `dist` folder.

It correctly bundles Solid in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.

Your app is ready to be deployed!

## Deployment

Learn more about deploying your application with the [documentations](https://vite.dev/guide/static-deploy.html)


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

```cpp
// (1)
json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs);

// (2)
json_pointer operator/(const json_pointer& lhs, string_t token);

// (3)
json_pointer operator/(const json_pointer& lhs, std::size_t array_idx);
```

1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer

## Parameters

`lhs` (in)
:    JSON pointer

`rhs` (in)
:    JSON pointer to append

`token` (in)
:    reference token to append

`array_idx` (in)
:    array index to append

## Return value

1. a new JSON pointer with `rhs` appended to `lhs`
2. a new JSON pointer with unescaped `token` appended to `lhs`
3. a new JSON pointer with `array_idx` appended to `lhs`

## Complexity

1. Linear in the length of `lhs` and `rhs`.
2. Linear in the length of `lhs`.
3. Linear in the length of `lhs`.

## Examples

??? example

    The example shows the usage of `operator/`.

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

    Output:

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

## Version history

1. Added in version 3.6.0.
2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0.
3. Added in version 3.6.0.


# <small>nlohmann::basic_json::</small>patch

```cpp
basic_json patch(const basic_json& json_patch) const;
```

[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to
a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from
the patch.

## Parameters

`json_patch` (in)
:   JSON patch document

## Return value

patched document

## Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

## Exceptions

- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of
  an array of objects.
- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g.,
  mandatory attributes are missing); example: `"operation add must have member path"`.
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range.
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch
  could not be resolved successfully in the current JSON value; example: `"key baz not found"`.
- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent
  ("add", "remove", "move")
- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target
  location has a parent that is neither an object nor an array.
- Throws [`other_error.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was
  unsuccessful.

## Complexity

Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of
the JSON value, the complexity can usually be neglected.

## Notes

The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception
is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value.

## Examples

??? example

    The following code shows how a JSON patch is applied to a value.

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

    Output:

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

## See also

- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
- [patch_inplace](patch_inplace.md) applies a JSON Patch without creating a copy of the document
- [merge_patch](merge_patch.md) applies a JSON Merge Patch

## Version history

- Added in version 2.0.0.
- Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's
  target location has a non-object/non-array parent in version 3.13.0.


import { describe, expect, it } from 'vitest'
import { parseImportGlob } from '../../../plugins/importMetaGlob'

async function run(input: string) {
  const items = await parseImportGlob(
    input,
    process.cwd(),
    process.cwd(),
    (id) => id,
  )
  return items.map((i) => ({
    globs: i.globs,
    options: i.options,
    start: i.start,
  }))
}

async function runError(input: string) {
  try {
    await run(input)
  } catch (e) {
    return e
  }
}

describe('parse positives', async () => {
  it('basic', async () => {
    expect(
      await run(`
    import.meta.glob('./modules/*.ts')
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "./modules/*.ts",
          ],
          "options": {},
          "start": 5,
        },
      ]
    `)
  })

  it('array', async () => {
    expect(
      await run(`
    import.meta.glob(['./modules/*.ts', './dir/*.{js,ts}'])
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "./modules/*.ts",
            "./dir/*.{js,ts}",
          ],
          "options": {},
          "start": 5,
        },
      ]
    `)
  })

  it('options with multilines', async () => {
    expect(
      await run(`
    import.meta.glob([
      './modules/*.ts',
      "!./dir/*.{js,ts}"
    ], {
      eager: true,
      import: 'named'
    })
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "./modules/*.ts",
            "!./dir/*.{js,ts}",
          ],
          "options": {
            "eager": true,
            "import": "named",
          },
          "start": 5,
        },
      ]
    `)
  })

  it('options with multilines', async () => {
    expect(
      await run(`
    const modules = import.meta.glob(
      '/dir/**'
      // for test: annotation contain ")"
      /*
       * for test: annotation contain ")"
       * */
    )
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "/dir/**",
          ],
          "options": {},
          "start": 21,
        },
      ]
    `)
  })

  it('options query', async () => {
    expect(
      await run(`
    const modules = import.meta.glob(
      '/dir/**',
      {
        query: {
          foo: 'bar',
          raw: true,
        }
      }
    )
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "/dir/**",
          ],
          "options": {
            "query": "?foo=bar&raw=true",
          },
          "start": 21,
        },
      ]
    `)
  })

  it('options with base', async () => {
    expect(
      await run(`
    import.meta.glob('./**/dir/*.md', {
      base: './path/to/base'
    })
    `),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "./**/dir/*.md",
          ],
          "options": {
            "base": "./path/to/base",
          },
          "start": 5,
        },
      ]
    `)
  })

  it('object properties - 1', async () => {
    expect(
      await run(`
    export const pageFiles = {
      '.page': import.meta.glob('/**/*.page.*([a-zA-Z0-9])')
};`),
    ).toMatchInlineSnapshot(`
  [
    {
      "globs": [
        "/**/*.page.*([a-zA-Z0-9])",
      ],
      "options": {},
      "start": 47,
    },
  ]
`)
  })

  it('object properties - 2', async () => {
    expect(
      await run(`
    export const pageFiles = {
      '.page': import.meta.glob('/**/*.page.*([a-zA-Z0-9])'),
};`),
    ).toMatchInlineSnapshot(`
  [
    {
      "globs": [
        "/**/*.page.*([a-zA-Z0-9])",
      ],
      "options": {},
      "start": 47,
    },
  ]
`)
  })

  it('object properties - 3', async () => {
    expect(
      await run(`
    export const pageFiles = {
      '.page.client': import.meta.glob('/**/*.page.client.*([a-zA-Z0-9])'),
      '.page.server': import.meta.glob('/**/*.page.server.*([a-zA-Z0-9])'),
};`),
    ).toMatchInlineSnapshot(`
  [
    {
      "globs": [
        "/**/*.page.client.*([a-zA-Z0-9])",
      ],
      "options": {},
      "start": 54,
    },
    {
      "globs": [
        "/**/*.page.server.*([a-zA-Z0-9])",
      ],
      "options": {},
      "start": 130,
    },
  ]
`)
  })

  it('array item', async () => {
    expect(
      await run(`
    export const pageFiles = [
      import.meta.glob('/**/*.page.client.*([a-zA-Z0-9])'),
      import.meta.glob('/**/*.page.server.*([a-zA-Z0-9])'),
    ]`),
    ).toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "/**/*.page.client.*([a-zA-Z0-9])",
          ],
          "options": {},
          "start": 38,
        },
        {
          "globs": [
            "/**/*.page.server.*([a-zA-Z0-9])",
          ],
          "options": {},
          "start": 98,
        },
      ]
    `)
  })
})

describe('parse negatives', async () => {
  it('syntax error', async () => {
    expect(await runError('import.meta.glob(')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Close parenthesis not found]',
    )
  })

  it('empty', async () => {
    expect(await runError('import.meta.glob()')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected 1-2 arguments, but got 0]',
    )
  })

  it('3 args', async () => {
    expect(
      await runError('import.meta.glob("", {}, {})'),
    ).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected 1-2 arguments, but got 3]',
    )
  })

  it('in string', async () => {
    expect(await runError('"import.meta.glob()"')).toBeUndefined()
  })

  it('variable', async () => {
    expect(await runError('import.meta.glob(hey)')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Could only use literals]',
    )
  })

  it('template', async () => {
    expect(
      await runError('import.meta.glob(`hi ${hey}`)'),
    ).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected glob to be a string, but got dynamic template literal]',
    )
  })

  it('template with unicode', async () => {
    expect(await run('import.meta.glob(`/\u0068\u0065\u006c\u006c\u006f`)'))
      .toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "/hello",
          ],
          "options": {},
          "start": 0,
        },
      ]
    `)
  })

  it('template without expressions', async () => {
    expect(await run('import.meta.glob(`/**/*.page.client.*([a-zA-Z0-9])`)'))
      .toMatchInlineSnapshot(`
      [
        {
          "globs": [
            "/**/*.page.client.*([a-zA-Z0-9])",
          ],
          "options": {},
          "start": 0,
        },
      ]
    `)
  })

  it('be string', async () => {
    expect(await runError('import.meta.glob(1)')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected glob to be a string, but got "number"]',
    )
  })

  it('be array variable', async () => {
    expect(await runError('import.meta.glob([hey])')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Could only use literals]',
    )
    expect(
      await runError('import.meta.glob(["1", hey])'),
    ).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Could only use literals]',
    )
  })

  it('options', async () => {
    expect(
      await runError('import.meta.glob("hey", hey)'),
    ).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected the second argument to be an object literal, but got "Identifier"]',
    )
    expect(await runError('import.meta.glob("hey", [])')).toMatchInlineSnapshot(
      '[Error: Invalid glob import syntax: Expected the second argument to be an object literal, but got "ArrayExpression"]',
    )
  })

  it('options props', async () => {
    expect(
      await runError('import.meta.glob("hey", { hey: 1 })'),
    ).toMatchInlineSnapshot('[Error: Unknown glob option "hey"]')
    expect(
      await runError('import.meta.glob("hey", { import: hey })'),
    ).toMatchInlineSnapshot(
      '[Error: Vite is unable to parse the glob options as the value is not static]',
    )
    expect(
      await runError('import.meta.glob("hey", { eager: 123 })'),
    ).toMatchInlineSnapshot(
      '[Error: Expected glob option "eager" to be of type boolean, but got number]',
    )
  })

  it('options query', async () => {
    expect(
      await runError('import.meta.glob("./*.js", { as: "raw", query: "hi" })'),
    ).toMatchInlineSnapshot(
      '[Error: Options "as" and "query" cannot be used together]',
    )
    expect(
      await runError('import.meta.glob("./*.js", { query: 123 })'),
    ).toMatchInlineSnapshot(
      '[Error: Expected glob option "query" to be of type object or string, but got number]',
    )
    expect(
      await runError('import.meta.glob("./*.js", { query: { foo: {} } })'),
    ).toMatchInlineSnapshot(
      '[Error: Expected glob option "query.foo" to be of type string, number, or boolean, but got object]',
    )
    expect(
      await runError('import.meta.glob("./*.js", { query: { foo: hey } })'),
    ).toMatchInlineSnapshot(
      '[Error: Vite is unable to parse the glob options as the value is not static]',
    )
    expect(
      await runError(
        'import.meta.glob("./*.js", { query: { foo: 123, ...a } })',
      ),
    ).toMatchInlineSnapshot(
      '[Error: Vite is unable to parse the glob options as the value is not static]',
    )
  })

  it('options base', async () => {
    expect(
      await runError('import.meta.glob("./*.js", { base: 1 })'),
    ).toMatchInlineSnapshot(
      '[Error: Expected glob option "base" to be of type string, but got number]',
    )
    expect(
      await runError('import.meta.glob("./*.js", { base: "foo" })'),
    ).toMatchInlineSnapshot(
      "[Error: Option \"base\" must start with '/', './' or '../', but got \"foo\"]",
    )
    expect(
      await runError('import.meta.glob("./*.js", { base: "!/foo" })'),
    ).toMatchInlineSnapshot('[Error: Option "base" cannot start with "!"]')
  })
})


// `stream` is used as the package name for `@vitejs/test-dep-esm-dummy-node-builtin` so that it is treated like a Node builtin
// eslint-disable-next-line n/prefer-node-protocol
let externalDummyNodeBuiltin = require('stream')
// NOTE: plugin-commonjs adds some compat code (`requireReturnsDefault`), but rolldown doesn't
if (process.env.NODE_ENV === 'production') {
  const mod = externalDummyNodeBuiltin
  externalDummyNodeBuiltin = mod.default
  for (const key in mod) {
    externalDummyNodeBuiltin[key] = mod[key]
  }
}
const external = require('@vitejs/test-dep-esm-external')
// eslint-disable-next-line no-prototype-builtins
const externalResult = external.hasOwnProperty('foo') ? 'ok' : 'error'
const externalDummyNodeBuiltinResult = `${externalDummyNodeBuiltin()} ${externalDummyNodeBuiltin.bar}`
module.exports = { externalResult, externalDummyNodeBuiltinResult }


// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Simple test for a cutom mutator.
#include <assert.h>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <random>
#include <string.h>

#include "FuzzerInterface.h"

static const char *Separator = "-_^_-";
static const char *Target = "012-_^_-abc";

static volatile int sink;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  assert(Data);
  std::string Str(reinterpret_cast<const char *>(Data), Size);

  // Ensure that two different elements exist in the corpus.
  if (Size && Data[0] == '0') sink++;
  if (Size && Data[0] == 'a') sink--;

  if (Str.find(Target) != std::string::npos) {
    std::cout << "BINGO; Found the target, exiting\n";
    exit(1);
  }
  return 0;
}

extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
                                            const uint8_t *Data2, size_t Size2,
                                            uint8_t *Out, size_t MaxOutSize,
                                            unsigned int Seed) {
  static bool Printed;
  static size_t SeparatorLen = strlen(Separator);

  if (!Printed) {
    std::cerr << "In LLVMFuzzerCustomCrossover\n";
    Printed = true;
  }

  std::mt19937 R(Seed);

  size_t Offset1 = 0;
  size_t Len1 = R() % (Size1 - Offset1);
  size_t Offset2 = 0;
  size_t Len2 = R() % (Size2 - Offset2);
  size_t Size = Len1 + Len2 + SeparatorLen;

  if (Size > MaxOutSize)
    return 0;

  memcpy(Out, Data1 + Offset1, Len1);
  memcpy(Out + Len1, Separator, SeparatorLen);
  memcpy(Out + Len1 + SeparatorLen, Data2 + Offset2, Len2);

  return Len1 + Len2 + SeparatorLen;
}


import './style.css'
import typescriptLogo from './assets/typescript.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import { setupCounter } from './counter.ts'

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `

Get started

Edit src/main.ts and save to test HMR

  <button id="counter" type="button" class="counter"></button>

    <svg class="icon" role="presentation" aria-hidden="true"><use href="/icons.svg#documentation-icon"></use></svg>

Documentation

Your questions, answered

          Explore Vite

          Learn more

    <svg class="icon" role="presentation" aria-hidden="true"><use href="/icons.svg#social-icon"></use></svg>

Connect with us

Join the Vite community

<svg class="button-icon" role="presentation" aria-hidden="true"><use href="/icons.svg#github-icon"></use></svg>GitHub

<svg class="button-icon" role="presentation" aria-hidden="true"><use href="/icons.svg#discord-icon"></use></svg>Discord

<svg class="button-icon" role="presentation" aria-hidden="true"><use href="/icons.svg#x-icon"></use></svg>X.com

<svg class="button-icon" role="presentation" aria-hidden="true"><use href="/icons.svg#bluesky-icon"></use></svg>Bluesky

`

setupCounter(document.querySelector<HTMLButtonElement>('#counter')!)


from flaskr import create_app

def test_config():
    """Test create_app without passing test config."""
    assert not create_app().testing
    assert create_app({"TESTING": True}).testing

def test_hello(client):
    response = client.get("/hello")
    assert response.data == b"Hello, World!"


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

using json = nlohmann::json;

int main()
{
    // create two JSON objects
    json j1 = {{"one", "eins"}, {"two", "zwei"}};
    json j2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};

    // output objects
    std::cout << j1 << '\n';
    std::cout << j2 << '\n';

    // insert range from j2 to j1
    j1.insert(j2.begin(), j2.end());

    // output result of insert call
    std::cout << j1 << '\n';
}


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

using namespace std::string_view_literals;
using json = nlohmann::json;

int main()
{
    // create JSON object
    json object =
    {
        {"the good", "il buono"},
        {"the bad", "il cattivo"},
        {"the ugly", "il brutto"}
    };

    // output element with key "the ugly" using string_view
    std::cout << object.at("the ugly"sv) << '\n';

    // change element with key "the bad" using string_view
    object.at("the bad"sv) = "il cattivo";

    // output changed array
    std::cout << object << '\n';

    // exception type_error.304
    try
    {
        // use at() with string_view on a non-object type
        json str = "I am a string";
        str.at("the good"sv) = "Another string";
    }
    catch (const json::type_error& e)
    {
        std::cout << e.what() << '\n';
    }

    // exception out_of_range.401
    try
    {
        // try to write at a nonexisting key using string_view
        object.at("the fast"sv) = "il rapido";
    }
    catch (const json::out_of_range& e)
    {
        std::cout << e.what() << '\n';
    }
}


// This is used to setup a test scenario, where dep scanner
// could not determine all of the used dependencies on first
// pass, e.g., a dependency that is aliased using an absolute
// path, in which case it used to trigger unnecessary "full
// reloads" invalidating all modules in a module graph.
export { default } from '@vitejs/test-dep-alias-using-absolute-path'


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

```cpp
// since C++20
class basic_json {
    std::partial_ordering operator<=>(const_reference rhs) const noexcept;  // (1)

    template<typename ScalarType>
    std::partial_ordering operator<=>(const ScalarType rhs) const noexcept; // (2)
};
```

1. 3-way compares two JSON values producing a result of type `std::partial_ordering` according to the following rules:
    - Two JSON values compare with a result of `std::partial_ordering::unordered` if either value is discarded.
    - If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using
      their respective `operator<=>`.
    - Integer and floating-point numbers are converted to their common type and then 3-way compared using their
      respective `operator<=>`.
      For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to
      floating-point with the second value.
    - Otherwise, yields a result by comparing the type (see [`value_t`](value_t.md)).

2. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and
   3-way comparing both JSON values (see 1).

## Template parameters

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

## Parameters

`rhs` (in)
:   second value to consider

## Return value

the `std::partial_ordering` of the 3-way comparison of `*this` and `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 `std::partial_ordering::unordered`:
        1. Comparing a `NaN` with itself.
        2. Comparing a `NaN` with another `NaN`.
        3. Comparing a `NaN` and any other number.

## Examples

??? example "Example: (1) comparing JSON values"

    The example demonstrates comparing several JSON values.

    ```cpp
    --8<-- "examples/operator_spaceship__const_reference.c++20.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/operator_spaceship__const_reference.c++20.output"
    ```

??? example "Example: (2) comparing JSON values and scalars"

    The example demonstrates comparing several JSON values and scalars.

    ```cpp
    --8<-- "examples/operator_spaceship__scalartype.c++20.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/operator_spaceship__scalartype.c++20.output"
    ```

## See also

- [**operator==**](operator_eq.md) - comparison: equal
- [**operator!=**](operator_ne.md) - comparison: not equal
- [**operator<**](operator_lt.md) - comparison: less than
- [**operator<=**](operator_le.md) - comparison: less than or equal
- [**operator>**](operator_gt.md) - comparison: greater than
- [**operator>=**](operator_ge.md) - comparison: greater than or equal

## Version history

1. Added in version 3.11.0.
2. Added in version 3.11.0.


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

using json = nlohmann::json;

int main()
{
    // a JSON text given as std::vector
    std::vector<std::uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\0'};

    // parse and serialize JSON
    json j_complete = json::parse(text);
    std::cout << std::setw(4) << j_complete << "\n\n";
}