PageSourceSearch

https://docs.mia-platform.eu/assets/js/e2955795.a1ceb2f0.js

js mia-platform.eu collected 2026-10-02 06:07:02 UTC 22,484 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkmia_platform_docs=self.webpackChunkmia_platform_docs||[]).push([["14915"],{899203(e,n,t){t.r(n),t.d(n,{metadata:()=>i,default:()=>h,frontMatter:()=>a,contentTitle:()=>o,toc:()=>l,assets:()=>c});var i=JSON.parse('{"id":"runtime-components/plugins/http-proxy-manager/configuration","title":"Proxy Manager","description":"This service proxies HTTP calls to external services.","source":"@site/versioned_docs/version-15.0.1/runtime-components/plugins/http-proxy-manager/30_configuration.md","sourceDirName":"runtime-components/plugins/http-proxy-manager","slug":"/runtime-components/plugins/http-proxy-manager/configuration","permalink":"/docs/15.0.1/runtime-components/plugins/http-proxy-manager/configuration","draft":false,"unlisted":false,"tags":[],"version":"15.0.1","sidebarPosition":30,"frontMatter":{"id":"configuration","title":"Proxy Manager","sidebar_label":"Configuration"},"sidebar":"marketplace","previous":{"title":"How to use","permalink":"/docs/15.0.1/runtime-components/plugins/http-proxy-manager/how_to_use"},"next":{"title":"CHANGELOG","permalink":"/docs/15.0.1/runtime-components/plugins/http-proxy-manager/changelog"}}'),r=t(474848),s=t(28453);let a={id:"configuration",title:"Proxy Manager",sidebar_label:"Configuration"},o,c={},l=[{value:"Environment variables",id:"environment-variables",level:2},{value:"Static configuration",id:"static-configuration",level:2},{value:"Configuration schema",id:"configuration-schema",level:3},{value:"Dynamic configuration",id:"dynamic-configuration",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"Configuration example",id:"configuration-example",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"This service proxies HTTP calls to external services."}),"\n",(0,r.jsx)(n.h2,{id:"environment-variables",children:"Environment variables"}),"\n",(0,r.jsx)(n.p,{children:"The service use the following environment variables:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CONFIGURATION_PATH"})," (required for ",(0,r.jsx)(n.em,{children:"static"})," configuration): the file path of the service configuration file;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CONFIGURATION_FILE_NAME"})," (required for ",(0,r.jsx)(n.em,{children:"static"})," configuration): the filename of the service configuration file (without the extension);"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CONFIGURATION_URL"})," (required for ",(0,r.jsx)(n.em,{children:"dynamic"})," configuration): the url of the CRUD collection with the service configuration;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"PROXY_CACHE_TTL"})," (optional, default to ",(0,r.jsx)(n.code,{children:"0"}),"): the time to live (in seconds) of cached proxy configurations. This is used only with ",(0,r.jsx)(n.em,{children:"dynamic"})," configuration."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"LOG_LEVEL"})," (optional, default to ",(0,r.jsx)(n.code,{children:"info"}),"): level of the log. It could be trace, debug, info, warn, error, fatal;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"HTTP_PORT"})," (optional, default to ",(0,r.jsx)(n.code,{children:"8080"}),"): port where the web server is exposed;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SERVICE_PREFIX"})," (optional): path prefix for all the specified endpoints (different from the status routes);"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"EXPOSE_MANAGEMENT_APIS"})," (optional, default ",(0,r.jsx)(n.code,{children:"false"}),"): allows to control whether or not ",(0,r.jsx)(n.a,{href:"/docs/15.0.1/runtime-components/plugins/http-proxy-manager/how_to_use#management-api",children:"management APIs"})," are exposed by the service (please note that this flag can be used only when running in dynamic configuration mode);"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"ALLOW_PROXY_OPTIMIZER"})," (optional, default to ",(0,r.jsx)(n.code,{children:"true"}),"): boolean that enables optimized proxy using reverse proxy and preventing saving body request in memory. Be careful, this optimization does not perform any retry, thus it is strongly suggested to configure the token validation endpoint in y
1our proxy configuration;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"DELAY_SHUTDOWN_SECONDS"})," (optional, default to ",(0,r.jsx)(n.code,{children:"10"})," seconds): seconds to wait before starting the graceful shutdown. This delay is required in k8s to await for the DNS rotation;"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"DISABLE_PROXY_CACHE"})," (optional, default ",(0,r.jsx)(n.code,{children:"false"}),"): allows to disable the in-memory proxy cache. Such cache is used to prevent excessive CRUD invocations (useful when you want to prevent any possible out-dated cache hit whenever the service is using Dynamic Configuration in the context of a scaled HA architecture)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"BASE_PATH_MATCHERS"})," (optional): comma-separated list of paths that are used to let the service handle complex base paths when using dynamic proxy configuration (note: this function is not compatible with the non-optimized proxy configuration, make sure to set ",(0,r.jsx)(n.code,{children:"ALLOW_PROXY_OPTIMIZER=true"}),")."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"ADDITIONAL_HEADERS_TO_REDACT"})," (optional): comma separated values of additional headers to redact when logging. The following headers are always redacted: ",(0,r.jsx)(n.code,{children:"Authorization"}),", ",(0,r.jsx)(n.code,{children:"Cookie"}),", ",(0,r.jsx)(n.code,{children:"Proxy-Authorization"}),", ",(0,r.jsx)(n.code,{children:"Set-Cookie"})," and ",(0,r.jsx)(n.code,{children:"Www-Authenticate"}),";"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"caution",children:(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"ALLOW_PROXY_OPTIMIZER"})," will be dismissed with the next major release. The not optimized proxy functionality and the retry feature is deprecated and will be dismissed too."]})}),"\n",(0,r.jsx)(n.h2,{id:"static-configuration",children:"Static configuration"}),"\n",(0,r.jsxs)(n.p,{children:["This service requires a configuration file that provides all the different details regarding the external services to be proxied.\nThe configuration file can be mou
1nted into the service either as a ",(0,r.jsx)(n.em,{children:"ConfigMap"})," or as a ",(0,r.jsx)(n.em,{children:"Secret"})," (for more details, please refer to this ",(0,r.jsx)(n.a,{href:"/docs/15.0.1/products/console/api-console/api-design/services#custom-configuration",children:"documentation"}),")."]}),"\n",(0,r.jsxs)(n.admonition,{type:"caution",children:[(0,r.jsxs)(n.p,{children:["In case the former method (",(0,r.jsx)(n.em,{children:"Config Map"}),") is selected, please use ",(0,r.jsx)(n.a,{href:"/docs/15.0.1/products/console/api-console/api-design/services#environment-variable-configuration",children:"variables interpolation"})," for sensitive data, such as:"]}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"username"}),"\n",(0,r.jsx)(n.li,{children:"password"}),"\n",(0,r.jsx)(n.li,{children:"clientId"}),"\n",(0,r.jsx)(n.li,{children:"clientSecret"}),"\n"]}),(0,r.jsx)(n.p,{children:"This prevents to store those sensitive values as plain text in the project repository."})]}),"\n",(0,r.jsx)(n.h3,{id:"configuration-schema",children:"Configuration schema"}),"\n",(0,r.jsx)(n.p,{children:"The configuration must follow this schema:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "type": "object",\n  "properties": {\n    "proxies": {\n      "type": "array",\n      "items": {\n        "type": "object",\n        "required": ["targetBaseUrl","basePath"],\n        "properties": {\n          "authentication": {\n            "type": "string",\n            "enum": ["none","oauth2"],\n            "default": "none"\n          },\n          "username": {\n            "type": "string"\n          },\n          "password": {\n            "type": "string"\n          },\n          "clientId": {\n            "type": "string"\n          },\n          "clientSecret": {\n            "type": "string"\n          },\n          "tokenIssuerUrl": {\n            "type": "string"\n          },\n          "tokenIssuerValidationPath": {\n            "type": "string"\n          },\n          "targetBaseUrl": {\n            "type": "string",\n            "pattern": "^https?:\\\\/\\\\/[a-zA-Z0-9.:_-]+(\\\\/((\\\\{[a-zA-Z0-9_-]+\\\\})|[a-zA-Z0-9_-]+))*\\\\/?$"\n          },\n          "basePath": {\n            "type": "string",\n            "pattern": "^\\\\/[a-zA-Z0-9_-]+(\\\\/((\\\\{[a-zA-Z0-9_-]+\\\\})|[a-zA-Z0-9_-]+))*\\\\/?$"\n          },\n          "grantType": {\n            "type": "string",\n            "enum": ["client_credentials","password"],\n            "default": "client_credentials"\n          },\n          "authType": {\n            "type": "string",\n            "enum": ["client_secret_basic"],\n            "default": "client_secret_basic"\n          },\n          "additionalAuthFields": {\n            "type": "object",\n            "default": null\n          },\n          "headersToProxy": {\n            "type": "array",\n            "items": {\n              "type": "string"\n            },\n            "default": []\n          },\n          "additionalHeaders": {\n            "type": "array",\n            "items": {\n              "type": "object",\n              "properties": {\n                "name": {\n                  "type": "string"\n                },\n                "value": {\n                  "type": "string"\n                }\n              },\n              "required": ["name","value"]\n            },\n            "default": []\n          }\n        }\n      }\n    }\n  }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.strong,{children:"proxies"})," array contains one item for each external service that has to by proxied."]}),"\n",(0,r.jsx)(n.p,{children:"A proxy can have the following fields:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"targetBaseUrl"}),": the url of the external service. This is a required field and has to start with an ",(0,r.jsx)(n.em,{children:"http"})," or ",(0,r.jsx)(n.em,{children:"https"})," scheme. Possible path parameters from the base path can be referenced and added to the url with the ",(0,r.jsx)(n.code,{children:"{param-name}"})," syntax (",(0,r.jsx)(n.strong,{children:"only for static configuration"}),")."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"basePath"}),": the name of the related endpoint exposed by the ",(0,r.jsx)(n.em,{children:"Proxy Manager"}),". This is a required field and has to start with a ",(0,r.jsx)(n.code,{children:"/"}),".\nPath parameter can be specified with the ",(0,r.jsx)(n.code,{children:"{param-name}"})," syntax and eventually forwarded to the external service in the ",(0,r.jsx)(n.em,{children:"targetBaseUrl"})," using the same name (",(0,r.jsx)(n.strong,{children:"only for static configuration"}),")."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"authentication"}),": the type of authentication done by the proxy, which can either be ",(0,r.jsx)(n.code,{children:"oauth2"})," or ",(0,r.jsx)(n.code,{children:"none"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"username"}),": the user identifier for the OAuth2 authentication (only ",(0,r.jsx)(n.a,{href:"https://oauth.net/2/grant-types/password/",children:"Password Grant"})," flow)."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"password"}),": the user password used in case of OAuth2 authentication (only ",(0,r.jsx)(n.a,{href:"https://oauth.net/2/grant-types/password/",children:"Password Grant"})," flow)."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"clientId"}),": the client identifier used in case of OAuth2 authentication."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"clientSecret"}),": the client secret used in case of OAuth2 authentication."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"tokenIssuerUrl"}),": the authorization server url that has to be called to obtain an access token."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"tokenIssuerValidationUrl"}),": the authorization server url that has to be called to validate an access token. This validation is performed at each API call. If not provided, the validation is skipped and the proxy only checks for token expiration."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"grantType"}),": the type of procedure used to retrieve an access token. At the moment, the service supports the following OAuth2 Grant Types:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://oauth.net/2/grant-types/client-credentials/",children:(0,r.jsx)(n.em,{children:"client_credentials"})})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://oauth.net/2/grant-types/password/",children:(0,r.jsx)(n.em,{children:"password"})})}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"authType"}),": the method used to stuff the client credentials in the request when asking for a new access token. This is required only for the Client Credential Grant flow. At the moment, the service only supports the ",(0,r.jsx)(n.em,{children:"client_secret_basic"})," type."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"additionalAuthFields"}
1),": an object containing additional fields to be used in the authentication request. These fields are added in the request body performed to acquire the access token. Both object keys and values must be of type string."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"headersToProxy"}),": a list of headers that must be forwarded when calling the external service. The default behavior, triggered when this field is not provided, is to forward all the headers of original request. In case the list is empty, no header from original request is proxied."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"additionalHeaders"}),": a list of headers the must be added to the request when calling the external service, after authentication is successful.\nA use case of additionalHeaders is api keys management (e.g. x-api-key header)."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"caution",children:(0,r.jsxs)(n.p,{children:["Path parameters inside ",(0,r.jsx)(n.strong,{children:"targetBaseUrl"})," and ",(0,r.jsx)(n.strong,{children:"basePath"})," are only allowed for the static configuration."]})}),"\n",(0,r.jsx)(n.h2,{id:"dynamic-configuration",children:"Dynamic configuration"}),"\n",(0,r.jsxs)(n.p,{children:["The service requires a CRUD collection (named as you prefer) that provides all the different details regarding the external services to be proxied: each document ",(0,r.jsx)(n.strong,{children:"must"})," match the ",(0,r.jsx)(n.em,{children:"proxy"})," schema specified in the ",(0,r.jsx)(n.a,{href:"#configuration-schema",children:"configuration schema"}),"."]}),"\n",(0,r.jsxs)(n.admonition,{type:"tip",children:[(0,r.jsxs)(n.p,{children:["By default, when using the ",(0,r.jsx)(n.em,{children:"dynamic configuration"})," only the first segment of the invoked path is used as base path to extract configurations from the database; in this scenario path parameters are not supported."]}),(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"E.g."}),": without ",(0,r.jsx)(n.code,{children:"BASE_PATH_MATCHERS"}),", given a request with path ",(0,r.jsx)(n.code,{children:"/one/two/three"}),", the ",(0,r.jsx)(n.strong,{children:"basePath"})," searched on CRUD is ",(0,r.jsx)(n.code,{children:"/one"}),"."]}),(0,r.jsxs)(n.p,{children:["Use the ",(0,r.jsx)(n.code,{children:"BASE_PATH_MATCHERS"}),"\xa0environment variable to provide one ore more base path matchers and let the service be able to extract more complex\nbase paths from the database."]}),(0,r.jsxs)(n.p,{children:["Assuming you set ",(0,r.jsx)(n.code,{children:"BASE_PATH_MATCHERS=/my-path/:param,/another-path/test-api"})," and then invoke ",(0,r.jsx)(n.code,{children:"/my-path/123/some-other-api"}),", the ",(0,r.jsx)(n.strong,{children:"basePath"})," searched on CRUD will be ",(0,r.jsx)(n.code,{children:"/my-path/123"}),"."]})]}),"\n",(0,r.jsxs)(n.p,{children:["In order to configure correctly the CRUD collection, you can ",(0,r.jsx)(n.strong,{children:"import"})," the fields from this ",(0,r.jsx)("a",{download:!0,target:"_blank",href:"/docs_files_to_download/http-proxy-manager/crud.fields.json",children:"file"}),". This file already enables the Client Side Field Level Encryption (CSFLE) for those fields with sensitive data."]}),"\n",(0,r.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,r.jsx)(n.p,{children:"It is recommended to add the following indexes to your CRUD collection:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["a ",(0,r.jsx)(n.em,{children:"unique"})," index for field ",(0,r.jsx)(n.strong,{children:"basePath"})," (to guarantee proxy uniqueness),"]}),"\n",(0,r.jsxs)(n.li,{children:["a search index for fields ",(0,r.jsx)(n.strong,{children:"basePath"})," and ",(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.strong,{children:"STATE"})})," (to improve performances)."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"configuration-example",children:"Configuration example"}),"\n",(0,r.jsxs)(n.p,{children:["In this example, the ",(0,r.jsx)(n.em,{children:"Proxy Manager"})," is configured to proxy requests to three external services."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The first one is located at ",(0,r.jsx)(n.code,{children:"external-service.com"}),", requires OAuth2 authentication (",(0,r.jsx)(n.em,{children:"client_credentials"})," grant type) and can be reached through the proxy with a call to the ",(0,r.jsx)(n.code,{children:"/external-service"})," endpoint."]}),"\n",(0,r.jsxs)(n.li,{children:["The second one is located at ",(0,r.jsx)(n.code,{children:"mia-client-credentials.com"}),", requires OAuth2 authentication (",(0,r.jsx)(n.em,{children:"client_credentials"})," grant type) and can be reached through the proxy with a call to the ",(0,r.jsx)(n.code,{children:"/mia-service"})," endpoint. It employs additional fields that are added in the request to retrieve an access token."]}),"\n",(0,r.jsxs)(n.li,{children:["The third one is located at ",(0,r.jsx)(n.code,{children:"legacy-service.com"}),", requires OAuth2 authentication (",(0,r.jsx)(n.em,{children:"password"})," grant type) and can be reached through the proxy with a call to the ",(0,r.jsx)(n.code,{children:"/legacy-service"})," endpoint."]}),"\n",(0,r.jsxs)(n.li,{children:["The forth service is located at ",(0,r.jsx)(n.code,{children:"other-service.com/{id}"}),", requires no authentication and can be reached with a call to the ",(0,r.jsx)(n.code,{children:"/other-service/{id}"})," endpoint. For example, with a call to the ",(0,r.jsx)(n.code,{children:"/other-service/page-id/additional-path"})," endpoint will be called the target service ",(0,r.jsx)(n.code,{children:"other-service.com/page-id/additional-path"}),". Path parameters can be used only with static configuration."]}),"\n",(0,r.jsxs)(n.li,{children:["The latter service is located at ",(0,r.jsx)(n.code,{children:"another-service.com"}),", requires no authentication, can be reached with a call to the ",(0,r.jsx)(n.code,{children:"/another-service"})," endpoint, only selected headers are forwarded to it and the additional header ",(0,r.jsx)(n.code,{children:"x-api-key"})," with ",(0,r.jsx)(n.code,{children:"header-value"})," is sent."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "proxies": [\n    {\n      "authentication": "oauth2",\n      "clientId": "6779ef20e75817b79602",\n      "clientSecret": "GBAyfVL7YWtP6gudLIjbRZV_N0dW",\n      "tokenIssuerUrl": "http://external-service.com/auth/oauth/token",\n      "targetBaseUrl": "https://external-service.com",\n      "basePath": "/external-service",\n      "grantType": "client_credentials"\n    },\n    {\n      "authentication": "oauth2",\n      "clientId": "6739ef20e75817a79c02",\n      "clientSecret": "GBAweVL7YWtP6gudLIjbRZV_NdW",\n      "tokenIssuerUrl": "http://mia-client-credentials.com/auth/oauth/token",\n      "tokenIssuerValidationPath": "/token-info",\n      "targetBaseUrl": "https://mia-service.com",\n      "basePath": "/mia-service",\n      "grantType": "client_credentials",\n      "additionalAuthFields": {\n        "audience": "mia-audience"\n      }\n    },\n    {\n      "authentication": "oauth2",\n      "username": "username",\n      "password": "password",\n      "clientId": "0fbd65b60ca0388f2069",\n      "clientSecret": "ZUogSDuesC6VpZM9P2_mPTX4",\n      "tokenIssuerUrl": "http://legacy-service.com/auth/oauth/token",\n      "targetBaseUrl": "http://legacy-service.com",\n      "basePath": "/legacy-service",\n      "grantType": "password"\n    }
1,\n    {\n      "targetBaseUrl": "http://other-service.com/{id}",\n      "basePath": "/other-service/{id}"\n    },\n    {\n      "targetBaseUrl": "http://another-service.com",\n      "basePath": "/another-service",\n      "headersToProxy": [\n        "Accept",\n        "Content-Type"\n      ],\n      "additionalHeaders": [\n        {\n          "name": "x-api-key", \n          "value": "header-value"\n        }\n      ]\n    }\n  ]\n}\n'})})]})}function h(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453(e,n,t){t.d(n,{R:()=>a,x:()=>o});var i=t(296540);let r={},s=i.createContext(r);function a(e){let n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.