mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-29 08:21:23 -05:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eac47dab4 | ||
|
|
e7c14d2ee4 | ||
|
|
a90e1296ba | ||
|
|
e2f6a68810 | ||
|
|
47d5d8c1b8 | ||
|
|
e2e8c55ccf | ||
|
|
0570f2ecea | ||
|
|
a3f9ebdce8 | ||
|
|
08a87ad1a3 | ||
|
|
7f361ad244 | ||
|
|
207dada144 | ||
|
|
6cefc94493 | ||
|
|
0d3fe86873 | ||
|
|
e372ae0ccf | ||
|
|
056039b624 | ||
|
|
6455052fa6 | ||
|
|
c43ac9974e | ||
|
|
22443cf0ad |
@@ -1,4 +1,4 @@
|
||||
# The test runner source for UI tests
|
||||
WEB_COMMITID=3120ea384c7a9d1f1ea0c328965951fc06d66900
|
||||
WEB_COMMITID=980964ccafe81cba6742cead151ac2d61408dae3
|
||||
WEB_BRANCH=main
|
||||
|
||||
|
||||
@@ -1263,7 +1263,7 @@ def localApiTestPipeline(ctx):
|
||||
"name": pipeline_name,
|
||||
"steps": evaluateWorkflowStep() + restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
|
||||
(tikaService() if params["tikaNeeded"] else []) +
|
||||
(waitForServices("online-offices", ["collabora:9980", "onlyoffice:443", "fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
|
||||
(waitForWebOffices(["https://collabora:9980", "https://onlyoffice", "http://fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
|
||||
(waitForClamavService() if params["antivirusNeeded"] else []) +
|
||||
(waitForEmailService() if params["emailNeeded"] else []) +
|
||||
(ldapService() if params["ldapNeeded"] else []) +
|
||||
@@ -1550,6 +1550,7 @@ def e2eTestPipeline(ctx):
|
||||
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
|
||||
"BROWSER": "chromium",
|
||||
"REPORT_TRACING": params["reportTracing"],
|
||||
"SLOW_MO": "500",
|
||||
},
|
||||
"commands": [
|
||||
"cd %s/tests/e2e" % dirs["web"],
|
||||
@@ -3470,3 +3471,23 @@ def onlyofficeService():
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
def waitForWebOffices(services = []):
|
||||
commands = []
|
||||
if not services:
|
||||
return []
|
||||
|
||||
for service in services:
|
||||
commands.append(
|
||||
"timeout 300 bash -c " +
|
||||
"'while [ `curl %s/hosting/discovery" % service +
|
||||
" -w \"%{http_code}\" -o /dev/null -sk` != \"200\" ]; do " +
|
||||
"echo \"Waiting...\" && sleep 2; done'",
|
||||
)
|
||||
return [
|
||||
{
|
||||
"name": "wait-for-weboffices",
|
||||
"image": OC_CI_ALPINE,
|
||||
"commands": commands,
|
||||
},
|
||||
]
|
||||
|
||||
98
CHANGELOG.md
98
CHANGELOG.md
@@ -1,5 +1,103 @@
|
||||
# Changelog
|
||||
|
||||
## [5.0.1](https://github.com/opencloud-eu/opencloud/releases/tag/v5.0.1) - 2026-01-28
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@ScharfViktor, @aduffeck, @saw-jan
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- Do not ever set a TTL for the ID cache. It's not supposed to expire. [[#2223](https://github.com/opencloud-eu/opencloud/pull/2223)]
|
||||
|
||||
### ✅ Tests
|
||||
|
||||
- test(api): wait for web-office readiness by checking discovery endpoint [[#2217](https://github.com/opencloud-eu/opencloud/pull/2217)]
|
||||
|
||||
### 📦️ Dependencies
|
||||
|
||||
- reva-bump-2.42.1 [[#2225](https://github.com/opencloud-eu/opencloud/pull/2225)]
|
||||
|
||||
## [5.0.0](https://github.com/opencloud-eu/opencloud/releases/tag/v5.0.0) - 2026-01-26
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
@ScharfViktor, @butonic, @dragonchaser, @flimmy, @fschade, @micbar, @rhafer, @saw-jan
|
||||
|
||||
### 💥 Breaking changes
|
||||
|
||||
- merge ocdav into frontend [[#1958](https://github.com/opencloud-eu/opencloud/pull/1958)]
|
||||
|
||||
### ✅ Tests
|
||||
|
||||
- [test-only] replace exception to assertions [[#2196](https://github.com/opencloud-eu/opencloud/pull/2196)]
|
||||
- test(api): auto-generate test virus files before test run [[#2191](https://github.com/opencloud-eu/opencloud/pull/2191)]
|
||||
- test(api): remove accountsHashDifficulty test suite [[#2190](https://github.com/opencloud-eu/opencloud/pull/2190)]
|
||||
- test(api): update without-remotephp expected-failures list [[#2184](https://github.com/opencloud-eu/opencloud/pull/2184)]
|
||||
- [full-ci] test: use single command to run the containers and the API tests [[#2169](https://github.com/opencloud-eu/opencloud/pull/2169)]
|
||||
- [tests-only] test: setup for running wopi API tests locally [[#2139](https://github.com/opencloud-eu/opencloud/pull/2139)]
|
||||
- fix flaky #2145 [[#2161](https://github.com/opencloud-eu/opencloud/pull/2161)]
|
||||
- Run wopi validator tests localy [[#2151](https://github.com/opencloud-eu/opencloud/pull/2151)]
|
||||
- ci: fix unwanted workflow skip in the cron pipelines [[#2117](https://github.com/opencloud-eu/opencloud/pull/2117)]
|
||||
- [POC] ci: skip previously passed workflows on pipeline restart [[#2099](https://github.com/opencloud-eu/opencloud/pull/2099)]
|
||||
- [tests-only] test: wait post-processing to finish for MKCOL requests [[#2092](https://github.com/opencloud-eu/opencloud/pull/2092)]
|
||||
- [tests-only] test: fix API tests [[#2087](https://github.com/opencloud-eu/opencloud/pull/2087)]
|
||||
- [full-ci] use graph api in the enforcePasswordPublicLink.feature [[#2050](https://github.com/opencloud-eu/opencloud/pull/2050)]
|
||||
- [full-ci][tests-only] test: check last email content with retries as emails can be delayed [[#2038](https://github.com/opencloud-eu/opencloud/pull/2038)]
|
||||
- skip collaborativePosix tests in CI [[#2039](https://github.com/opencloud-eu/opencloud/pull/2039)]
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Update release template [[#2182](https://github.com/opencloud-eu/opencloud/pull/2182)]
|
||||
- Clarify what the two requests are used for [[#2179](https://github.com/opencloud-eu/opencloud/pull/2179)]
|
||||
- fix: markdown links formatting [[#2143](https://github.com/opencloud-eu/opencloud/pull/2143)]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- fix: Show username in unprivileged search results [[#2104](https://github.com/opencloud-eu/opencloud/pull/2104)]
|
||||
- fix(thumbnailer): missing font panic [[#2097](https://github.com/opencloud-eu/opencloud/pull/2097)]
|
||||
- Remove sub-service binary entrypoints and fix antivirus only server cmd [[#2043](https://github.com/opencloud-eu/opencloud/pull/2043)]
|
||||
- fix(thumbnailer): respect image boundaries and text wrappings [[#2062](https://github.com/opencloud-eu/opencloud/pull/2062)]
|
||||
- fix: cobra viper flags and env [[#2047](https://github.com/opencloud-eu/opencloud/pull/2047)]
|
||||
- fix service name in suture logs [[#2052](https://github.com/opencloud-eu/opencloud/pull/2052)]
|
||||
|
||||
### 📈 Enhancement
|
||||
|
||||
- benchmark client enhancements [[#1856](https://github.com/opencloud-eu/opencloud/pull/1856)]
|
||||
- allow http2 connections to proxy [[#2040](https://github.com/opencloud-eu/opencloud/pull/2040)]
|
||||
- migrate from urfave/cli to spf13/cobra [[#1954](https://github.com/opencloud-eu/opencloud/pull/1954)]
|
||||
|
||||
### 📦️ Dependencies
|
||||
|
||||
- reva-bump-2.42.0 [[#2215](https://github.com/opencloud-eu/opencloud/pull/2215)]
|
||||
- build(deps): bump github.com/olekukonko/tablewriter from 1.1.2 to 1.1.3 [[#2186](https://github.com/opencloud-eu/opencloud/pull/2186)]
|
||||
- build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.27.4 to 2.27.5 [[#2204](https://github.com/opencloud-eu/opencloud/pull/2204)]
|
||||
- build(deps): bump github.com/go-resty/resty/v2 from 2.7.0 to 2.17.1 [[#2197](https://github.com/opencloud-eu/opencloud/pull/2197)]
|
||||
- build(deps): bump github.com/open-policy-agent/opa from 1.11.1 to 1.12.3 [[#2166](https://github.com/opencloud-eu/opencloud/pull/2166)]
|
||||
- build(deps): bump github.com/kovidgoyal/imaging from 1.8.18 to 1.8.19 [[#2167](https://github.com/opencloud-eu/opencloud/pull/2167)]
|
||||
- build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 from 2.27.3 to 2.27.4 [[#2164](https://github.com/opencloud-eu/opencloud/pull/2164)]
|
||||
- build(deps): bump github.com/sirupsen/logrus from 1.9.4-0.20230606125235-dd1b4c2e81af to 1.9.4 [[#2163](https://github.com/opencloud-eu/opencloud/pull/2163)]
|
||||
- build(deps): bump github.com/go-chi/chi/v5 from 5.2.3 to 5.2.4 [[#2162](https://github.com/opencloud-eu/opencloud/pull/2162)]
|
||||
- build(deps): bump go.opentelemetry.io/contrib/zpages from 0.63.0 to 0.64.0 [[#2158](https://github.com/opencloud-eu/opencloud/pull/2158)]
|
||||
- build(deps): bump github.com/blevesearch/bleve/v2 from 2.5.5 to 2.5.7 [[#2157](https://github.com/opencloud-eu/opencloud/pull/2157)]
|
||||
- build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace from 1.38.0 to 1.39.0 [[#2154](https://github.com/opencloud-eu/opencloud/pull/2154)]
|
||||
- build(deps): bump golang.org/x/image from 0.34.0 to 0.35.0 [[#2153](https://github.com/opencloud-eu/opencloud/pull/2153)]
|
||||
- build(deps): bump github.com/nats-io/nats.go from 1.47.0 to 1.48.0 [[#2147](https://github.com/opencloud-eu/opencloud/pull/2147)]
|
||||
- build(deps): bump github.com/onsi/ginkgo/v2 from 2.27.2 to 2.27.5 [[#2148](https://github.com/opencloud-eu/opencloud/pull/2148)]
|
||||
- build(deps): bump github.com/olekukonko/tablewriter from 1.1.1 to 1.1.2 [[#2144](https://github.com/opencloud-eu/opencloud/pull/2144)]
|
||||
- build(deps): bump github.com/spf13/cobra from 1.10.1 to 1.10.2 [[#2141](https://github.com/opencloud-eu/opencloud/pull/2141)]
|
||||
- build(deps): bump golang.org/x/net from 0.48.0 to 0.49.0 [[#2140](https://github.com/opencloud-eu/opencloud/pull/2140)]
|
||||
- build(deps): bump github.com/onsi/gomega from 1.38.2 to 1.39.0 [[#2133](https://github.com/opencloud-eu/opencloud/pull/2133)]
|
||||
- build(deps): bump golang.org/x/crypto from 0.46.0 to 0.47.0 [[#2132](https://github.com/opencloud-eu/opencloud/pull/2132)]
|
||||
- build(deps): bump go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from 0.63.0 to 0.64.0 [[#2109](https://github.com/opencloud-eu/opencloud/pull/2109)]
|
||||
- build(deps): bump github.com/kovidgoyal/imaging from 1.8.17 to 1.8.18 [[#2107](https://github.com/opencloud-eu/opencloud/pull/2107)]
|
||||
- build(deps): bump google.golang.org/grpc from 1.77.0 to 1.78.0 [[#2106](https://github.com/opencloud-eu/opencloud/pull/2106)]
|
||||
- build(deps): bump go.opentelemetry.io/otel/sdk from 1.38.0 to 1.39.0 [[#2069](https://github.com/opencloud-eu/opencloud/pull/2069)]
|
||||
- build(deps): bump github.com/opensearch-project/opensearch-go/v4 from 4.5.0 to 4.6.0 [[#2068](https://github.com/opencloud-eu/opencloud/pull/2068)]
|
||||
- build(deps): bump github.com/testcontainers/testcontainers-go/modules/opensearch from 0.39.0 to 0.40.0 [[#1967](https://github.com/opencloud-eu/opencloud/pull/1967)]
|
||||
- build(deps): bump golang.org/x/net from 0.47.0 to 0.48.0 [[#2061](https://github.com/opencloud-eu/opencloud/pull/2061)]
|
||||
- build(deps): bump github.com/open-policy-agent/opa from 1.10.1 to 1.11.0 [[#1930](https://github.com/opencloud-eu/opencloud/pull/1930)]
|
||||
|
||||
## [4.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v4.1.0) - 2025-12-15
|
||||
|
||||
### ❤️ Thanks to all contributors! ❤️
|
||||
|
||||
16
go.mod
16
go.mod
@@ -34,7 +34,7 @@ require (
|
||||
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
|
||||
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/go-resty/resty/v2 v2.17.1
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.7.0
|
||||
@@ -42,7 +42,7 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/config/v2 v2.2.7
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5
|
||||
github.com/invopop/validation v0.8.0
|
||||
github.com/jellydator/ttlcache/v2 v2.11.1
|
||||
github.com/jellydator/ttlcache/v3 v3.4.0
|
||||
@@ -58,14 +58,14 @@ require (
|
||||
github.com/nats-io/nats-server/v2 v2.12.3
|
||||
github.com/nats-io/nats.go v1.48.0
|
||||
github.com/oklog/run v1.2.0
|
||||
github.com/olekukonko/tablewriter v1.1.2
|
||||
github.com/olekukonko/tablewriter v1.1.3
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.27.5
|
||||
github.com/onsi/gomega v1.39.0
|
||||
github.com/open-policy-agent/opa v1.12.3
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76
|
||||
github.com/opencloud-eu/reva/v2 v2.41.1-0.20260120144836-2769c3c07a19
|
||||
github.com/opencloud-eu/reva/v2 v2.42.1
|
||||
github.com/opensearch-project/opensearch-go/v4 v4.6.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
@@ -111,7 +111,7 @@ require (
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/term v0.39.0
|
||||
golang.org/x/text v0.33.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516
|
||||
google.golang.org/grpc v1.78.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@@ -166,7 +166,7 @@ require (
|
||||
github.com/ceph/go-ceph v0.37.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.0 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.2 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
@@ -313,7 +313,7 @@ require (
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
||||
github.com/olekukonko/errors v1.1.0 // indirect
|
||||
github.com/olekukonko/ll v0.1.3 // indirect
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
@@ -396,7 +396,7 @@ require (
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
||||
33
go.sum
33
go.sum
@@ -223,8 +223,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s=
|
||||
github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
|
||||
github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
@@ -461,8 +461,8 @@ github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
|
||||
github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@@ -624,8 +624,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vb
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4 h1:kEISI/Gx67NzH3nJxAmY/dGac80kKZgZt134u7Y/k1s=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4/go.mod h1:6Nz966r3vQYCqIzWsuEl9d7cf7mRhtDmm++sOxlnfxI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5 h1:jP1RStw811EvUDzsUQ9oESqw2e4RqCjSAD9qIL8eMns=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5/go.mod h1:WXNBZ64q3+ZUemCMXD9kYnr56H7CgZxDBHCVwstfl3s=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
@@ -942,11 +942,11 @@ github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
|
||||
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||
github.com/olekukonko/ll v0.1.3 h1:sV2jrhQGq5B3W0nENUISCR6azIPf7UBUpVq0x/y70Fg=
|
||||
github.com/olekukonko/ll v0.1.3/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM=
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/olekukonko/tablewriter v1.1.2 h1:L2kI1Y5tZBct/O/TyZK1zIE9GlBj/TVs+AY5tZDCDSc=
|
||||
github.com/olekukonko/tablewriter v1.1.2/go.mod h1:z7SYPugVqGVavWoA2sGsFIoOVNmEHxUAAMrhXONtfkg=
|
||||
github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA=
|
||||
github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@@ -969,8 +969,8 @@ github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9 h1:dIft
|
||||
github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9/go.mod h1:JWyDC6H+5oZRdUJUgKuaye+8Ph5hEs6HVzVoPKzWSGI=
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 h1:vD/EdfDUrv4omSFjrinT8Mvf+8D7f9g4vgQ2oiDrVUI=
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
|
||||
github.com/opencloud-eu/reva/v2 v2.41.1-0.20260120144836-2769c3c07a19 h1:8loHHe7FYd7zgIcGTlbHwre+bU/AAwREEYVd4SWM9/s=
|
||||
github.com/opencloud-eu/reva/v2 v2.41.1-0.20260120144836-2769c3c07a19/go.mod h1:pv+w23JG0/qJweZbTzNNev//YEvlUML1L/2iXgKGkkg=
|
||||
github.com/opencloud-eu/reva/v2 v2.42.1 h1:QUZOLSfAhb7bw+qsVSFMFY644rUz4/NtnOiJ0QQxj2o=
|
||||
github.com/opencloud-eu/reva/v2 v2.42.1/go.mod h1:pv+w23JG0/qJweZbTzNNev//YEvlUML1L/2iXgKGkkg=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
@@ -1464,7 +1464,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
@@ -1746,10 +1745,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
@@ -34,7 +34,7 @@ var (
|
||||
// LatestTag is the latest released version plus the dev meta version.
|
||||
// Will be overwritten by the release pipeline
|
||||
// Needs a manual change for every tagged release
|
||||
LatestTag = "4.1.0+dev"
|
||||
LatestTag = "5.0.1+dev"
|
||||
|
||||
// Date indicates the build date.
|
||||
// This has been removed, it looks like you can only replace static strings with recent go versions
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-07 00:07+0000\n"
|
||||
"POT-Creation-Date: 2026-01-27 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: ii kaka, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-08 00:08+0000\n"
|
||||
"POT-Creation-Date: 2026-01-28 00:12+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-06 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-26 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Quan Tran, 2025\n"
|
||||
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-07 00:07+0000\n"
|
||||
"POT-Creation-Date: 2026-01-27 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: ii kaka, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-08 00:08+0000\n"
|
||||
"POT-Creation-Date: 2026-01-28 00:12+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
|
||||
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-06 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-26 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Quan Tran, 2025\n"
|
||||
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-03 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-23 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-07 00:07+0000\n"
|
||||
"POT-Creation-Date: 2026-01-27 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: ii kaka, 2025\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
|
||||
|
||||
@@ -12,7 +12,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-08 00:08+0000\n"
|
||||
"POT-Creation-Date: 2026-01-28 00:12+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-03 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-23 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
|
||||
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
|
||||
|
||||
@@ -237,13 +237,12 @@ type FilemetadataCache struct {
|
||||
|
||||
// IDCache holds cache config
|
||||
type IDCache struct {
|
||||
Store string `yaml:"store" env:"OC_CACHE_STORE;STORAGE_USERS_ID_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"1.0.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OC_CACHE_STORE_NODES;STORAGE_USERS_ID_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
|
||||
Database string `yaml:"database" env:"OC_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"1.0.0"`
|
||||
TTL time.Duration `yaml:"ttl" env:"OC_CACHE_TTL;STORAGE_USERS_ID_CACHE_TTL" desc:"Default time to live for user info in the user info cache. Only applied when access tokens have no expiration. Defaults to 300s which is derived from the underlaying package though not explicitly set as default. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;STORAGE_USERS_ID_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
|
||||
AuthUsername string `yaml:"username" env:"OC_CACHE_AUTH_USERNAME;STORAGE_USERS_ID_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
|
||||
AuthPassword string `yaml:"password" env:"OC_CACHE_AUTH_PASSWORD;STORAGE_USERS_ID_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
|
||||
Store string `yaml:"store" env:"OC_CACHE_STORE;STORAGE_USERS_ID_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"1.0.0"`
|
||||
Nodes []string `yaml:"nodes" env:"OC_CACHE_STORE_NODES;STORAGE_USERS_ID_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
|
||||
Database string `yaml:"database" env:"OC_CACHE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"1.0.0"`
|
||||
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;STORAGE_USERS_ID_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
|
||||
AuthUsername string `yaml:"username" env:"OC_CACHE_AUTH_USERNAME;STORAGE_USERS_ID_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
|
||||
AuthPassword string `yaml:"password" env:"OC_CACHE_AUTH_PASSWORD;STORAGE_USERS_ID_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
|
||||
}
|
||||
|
||||
// EOSDriver is the storage driver configuration when using 'eos' storage driver
|
||||
|
||||
@@ -171,7 +171,6 @@ func DefaultConfig() *config.Config {
|
||||
Store: "nats-js-kv",
|
||||
Nodes: []string{"127.0.0.1:9233"},
|
||||
Database: "ids-storage-users",
|
||||
TTL: 24 * 60 * time.Second,
|
||||
},
|
||||
Tasks: config.Tasks{
|
||||
PurgeTrashBin: config.PurgeTrashBin{
|
||||
|
||||
@@ -112,7 +112,6 @@ func Posix(cfg *config.Config, enableFSScan, enableFSWatch bool) map[string]inte
|
||||
"cache_store": cfg.IDCache.Store,
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -218,7 +217,6 @@ func Decomposed(cfg *config.Config) map[string]interface{} {
|
||||
"cache_store": cfg.IDCache.Store,
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -273,7 +271,6 @@ func DecomposedNoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_store": cfg.IDCache.Store,
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -330,7 +327,6 @@ func DecomposedS3(cfg *config.Config) map[string]interface{} {
|
||||
"cache_store": cfg.IDCache.Store,
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
@@ -389,7 +385,6 @@ func DecomposedS3NoEvents(cfg *config.Config) map[string]interface{} {
|
||||
"cache_store": cfg.IDCache.Store,
|
||||
"cache_nodes": cfg.IDCache.Nodes,
|
||||
"cache_database": cfg.IDCache.Database,
|
||||
"cache_ttl": cfg.IDCache.TTL,
|
||||
"cache_disable_persistence": cfg.IDCache.DisablePersistence,
|
||||
"cache_auth_username": cfg.IDCache.AuthUsername,
|
||||
"cache_auth_password": cfg.IDCache.AuthPassword,
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-08 00:08+0000\n"
|
||||
"POT-Creation-Date: 2026-01-28 00:12+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SHELL := bash
|
||||
NAME := web
|
||||
WEB_ASSETS_VERSION = v4.3.0
|
||||
WEB_ASSETS_VERSION = v5.0.0
|
||||
WEB_ASSETS_BRANCH = main
|
||||
|
||||
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
|
||||
|
||||
@@ -77,7 +77,7 @@ class HttpLogger {
|
||||
}
|
||||
|
||||
$logMessage = "\t\t_______________________________________________________________________\n\n";
|
||||
$logMessage .= "\t\t==> REQUEST\n";
|
||||
$logMessage .= "\t\t==> REQUEST [" . self::getCurrentDateTime() . "]\n";
|
||||
$logMessage .= "\t\t$method $path\n";
|
||||
$logMessage .= $query ? "\t\tQUERY: $query\n" : "";
|
||||
$logMessage .= "\t\t$headers";
|
||||
@@ -105,7 +105,7 @@ class HttpLogger {
|
||||
$headers = $key . ": " . $value[0] . "\n";
|
||||
}
|
||||
|
||||
$logMessage = "\t\t<== RESPONSE\n";
|
||||
$logMessage = "\t\t<== RESPONSE [" . self::getCurrentDateTime() . "]\n";
|
||||
$logMessage .= "\t\t$statusCode $statusMessage\n";
|
||||
$logMessage .= "\t\t$headers";
|
||||
|
||||
@@ -121,4 +121,13 @@ class HttpLogger {
|
||||
$logMessage = \rtrim($logMessage) . "\n\n";
|
||||
self::writeLog(self::getScenarioLogPath(), $logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current date and time in format: 1999-01-31T23:01:59
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentDateTime(): string {
|
||||
return date('Y-m-d\TG:i:s');
|
||||
}
|
||||
}
|
||||
|
||||
10
vendor/github.com/clipperhouse/displaywidth/CHANGELOG.md
generated
vendored
10
vendor/github.com/clipperhouse/displaywidth/CHANGELOG.md
generated
vendored
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [0.6.1]
|
||||
|
||||
[Compare](https://github.com/clipperhouse/displaywidth/compare/v0.6.0...v0.6.1)
|
||||
|
||||
### Changed
|
||||
- Perf improvements: replaced the ASCII lookup table with a simple
|
||||
function. A bit more cache-friendly. More inlining.
|
||||
- Bug fix: single regional indicators are now treated as width 2, since that
|
||||
is what actual terminals do.
|
||||
|
||||
## [0.6.0]
|
||||
|
||||
[Compare](https://github.com/clipperhouse/displaywidth/compare/v0.5.0...v0.6.0)
|
||||
|
||||
114
vendor/github.com/clipperhouse/displaywidth/README.md
generated
vendored
114
vendor/github.com/clipperhouse/displaywidth/README.md
generated
vendored
@@ -33,42 +33,82 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
For most purposes, you should use the `String` or `Bytes` methods.
|
||||
For most purposes, you should use the `String` or `Bytes` methods. They sum
|
||||
the widths of grapheme clusters in the string or byte slice.
|
||||
|
||||
> Note: in your application, iterating over runes to measure width is likely incorrect;
|
||||
the smallest unit of display is a grapheme, not a rune.
|
||||
|
||||
### Iterating over graphemes
|
||||
|
||||
If you need the individual graphemes:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/clipperhouse/displaywidth"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g := displaywidth.StringGraphemes("Hello, 世界!")
|
||||
for g.Next() {
|
||||
width := g.Width()
|
||||
value := g.Value()
|
||||
// do something with the width or value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
You can specify East Asian Width settings. When false (default),
|
||||
[East Asian Ambiguous characters](https://www.unicode.org/reports/tr11/#Ambiguous)
|
||||
are treated as width 1. When true, East Asian Ambiguous characters are treated
|
||||
as width 2.
|
||||
There is one option, `displaywidth.Options.EastAsianWidth`, which defines
|
||||
how [East Asian Ambiguous characters](https://www.unicode.org/reports/tr11/#Ambiguous)
|
||||
are treated.
|
||||
|
||||
When `false` (default), East Asian Ambiguous characters are treated as width 1.
|
||||
When `true`, they are treated as width 2.
|
||||
|
||||
You may wish to configure this based on environment variables or locale.
|
||||
`go-runewidth`, for example, does so
|
||||
[during package initialization](https://github.com/mattn/go-runewidth/blob/master/runewidth.go#L26C1-L45C2).
|
||||
|
||||
`displaywidth` does not do this automatically, we prefer to leave it to you.
|
||||
You might do something like:
|
||||
|
||||
```go
|
||||
myOptions := displaywidth.Options{
|
||||
EastAsianWidth: true,
|
||||
var width displaywidth.Options // zero value is default
|
||||
|
||||
func init() {
|
||||
if os.Getenv("EAST_ASIAN_WIDTH") == "true" {
|
||||
width = displaywidth.Options{EastAsianWidth: true}
|
||||
}
|
||||
// or check locale, or any other logic you want
|
||||
}
|
||||
|
||||
width := myOptions.String("Hello, 世界!")
|
||||
fmt.Println(width)
|
||||
// use it in your logic
|
||||
func myApp() {
|
||||
fmt.Println(width.String("Hello, 世界!"))
|
||||
}
|
||||
```
|
||||
|
||||
## Technical details
|
||||
## Technical standards and compatibility
|
||||
|
||||
This package implements the Unicode East Asian Width standard
|
||||
([UAX #11](https://www.unicode.org/reports/tr11/)), and handles
|
||||
([UAX #11](https://www.unicode.org/reports/tr11/tr11-43.html)), and handles
|
||||
[version selectors](https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)),
|
||||
and [regional indicator pairs](https://en.wikipedia.org/wiki/Regional_indicator_symbol)
|
||||
(flags). We implement [Unicode TR51](https://unicode.org/reports/tr51/).
|
||||
(flags). We implement [Unicode TR51](https://www.unicode.org/reports/tr51/tr51-27.html). We are keeping
|
||||
an eye on [emerging standards](https://www.jeffquast.com/post/state-of-terminal-emulation-2025/).
|
||||
|
||||
|
||||
`clipperhouse/displaywidth`, `mattn/go-runewidth`, and `rivo/uniseg` will
|
||||
give the same outputs for most real-world text. See extensive details in the
|
||||
give the same outputs for most real-world text. Extensive details are in the
|
||||
[compatibility analysis](comparison/COMPATIBILITY_ANALYSIS.md).
|
||||
|
||||
If you wish to investigate the core logic, see the `lookupProperties` and `width`
|
||||
functions in [width.go](width.go#L135). The essential trie generation logic is in
|
||||
`buildPropertyBitmap` in [unicode.go](internal/gen/unicode.go#L317).
|
||||
functions in [width.go](width.go#L139). The essential trie generation logic is in
|
||||
`buildPropertyBitmap` in [unicode.go](internal/gen/unicode.go#L316).
|
||||
|
||||
I (@clipperhouse) am keeping an eye on [emerging standards and test suites](https://www.jeffquast.com/post/state-of-terminal-emulation-2025/).
|
||||
|
||||
## Prior Art
|
||||
|
||||
@@ -93,31 +133,33 @@ goarch: arm64
|
||||
pkg: github.com/clipperhouse/displaywidth/comparison
|
||||
cpu: Apple M2
|
||||
|
||||
BenchmarkString_Mixed/clipperhouse/displaywidth-8 10469 ns/op 161.15 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/mattn/go-runewidth-8 14250 ns/op 118.39 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/rivo/uniseg-8 19258 ns/op 87.60 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/clipperhouse/displaywidth-8 10326 ns/op 163.37 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/mattn/go-runewidth-8 14415 ns/op 117.03 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/rivo/uniseg-8 19343 ns/op 87.21 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_EastAsian/clipperhouse/displaywidth-8 10518 ns/op 160.39 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/mattn/go-runewidth-8 23827 ns/op 70.80 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/rivo/uniseg-8 19537 ns/op 86.35 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/clipperhouse/displaywidth-8 10561 ns/op 159.74 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/mattn/go-runewidth-8 23790 ns/op 70.91 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/rivo/uniseg-8 19322 ns/op 87.31 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_ASCII/clipperhouse/displaywidth-8 1027 ns/op 124.61 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/mattn/go-runewidth-8 1166 ns/op 109.78 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/rivo/uniseg-8 1551 ns/op 82.52 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/clipperhouse/displaywidth-8 1033 ns/op 123.88 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/mattn/go-runewidth-8 1168 ns/op 109.59 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/rivo/uniseg-8 1585 ns/op 80.74 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_Emoji/clipperhouse/displaywidth-8 3164 ns/op 228.84 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/mattn/go-runewidth-8 4728 ns/op 153.13 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/rivo/uniseg-8 6489 ns/op 111.57 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/clipperhouse/displaywidth-8 3034 ns/op 238.61 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/mattn/go-runewidth-8 4797 ns/op 150.94 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/rivo/uniseg-8 6612 ns/op 109.50 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_Mixed/clipperhouse/displaywidth-8 3429 ns/op 491.96 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/mattn/go-runewidth-8 5308 ns/op 317.81 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/clipperhouse/displaywidth-8 3343 ns/op 504.67 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/mattn/go-runewidth-8 5414 ns/op 311.62 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_EastAsian/clipperhouse/displaywidth-8 3419 ns/op 493.49 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/mattn/go-runewidth-8 15321 ns/op 110.11 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/clipperhouse/displaywidth-8 3393 ns/op 497.17 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/mattn/go-runewidth-8 15312 ns/op 110.17 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_ASCII/clipperhouse/displaywidth-8 254.4 ns/op 503.19 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/mattn/go-runewidth-8 264.3 ns/op 484.31 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/clipperhouse/displaywidth-8 256.9 ns/op 498.32 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/mattn/go-runewidth-8 265.7 ns/op 481.75 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_Emoji/clipperhouse/displaywidth-8 1374 ns/op 527.02 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/mattn/go-runewidth-8 2210 ns/op 327.66 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/clipperhouse/displaywidth-8 1336 ns/op 541.96 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/mattn/go-runewidth-8 2304 ns/op 314.23 MB/s 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
Here are some notes on [how to make Unicode things fast](https://clipperhouse.com/go-unicode/).
|
||||
|
||||
91
vendor/github.com/clipperhouse/displaywidth/tables.go
generated
vendored
91
vendor/github.com/clipperhouse/displaywidth/tables.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
package displaywidth
|
||||
|
||||
// propertyWidths is a jump table of sorts, instead of a switch
|
||||
var propertyWidths = [5]int{
|
||||
_Default: 1,
|
||||
_Zero_Width: 0,
|
||||
_East_Asian_Wide: 2,
|
||||
_East_Asian_Ambiguous: 1,
|
||||
_Emoji: 2,
|
||||
}
|
||||
|
||||
// asciiWidths is a lookup table for single-byte character widths. Printable
|
||||
// ASCII characters have width 1, control characters have width 0.
|
||||
//
|
||||
// It is intended for valid single-byte UTF-8, which means <128.
|
||||
//
|
||||
// If you look up an index >= 128, that is either:
|
||||
// - invalid UTF-8, or
|
||||
// - a multi-byte UTF-8 sequence, in which case you should be operating on
|
||||
// the grapheme cluster, and not using this table
|
||||
//
|
||||
// We will return a default value of 1 in those cases, so as not to panic.
|
||||
var asciiWidths = [256]int8{
|
||||
// Control characters (0x00-0x1F): width 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Printable ASCII (0x20-0x7E): width 1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
// DEL (0x7F): width 0
|
||||
0,
|
||||
// >= 128
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
}
|
||||
|
||||
// asciiProperties is a lookup table for single-byte character properties.
|
||||
// It is intended for valid single-byte UTF-8, which means <128.
|
||||
//
|
||||
// If you look up an index >= 128, that is either:
|
||||
// - invalid UTF-8, or
|
||||
// - a multi-byte UTF-8 sequence, in which case you should be operating on
|
||||
// the grapheme cluster, and not using this table
|
||||
//
|
||||
// We will return a default value of _Default in those cases, so as not to
|
||||
// panic.
|
||||
var asciiProperties = [256]property{
|
||||
// Control characters (0x00-0x1F): _Zero_Width
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
// Printable ASCII (0x20-0x7E): _Default
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
// DEL (0x7F): _Zero_Width
|
||||
_Zero_Width,
|
||||
// >= 128
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
}
|
||||
502
vendor/github.com/clipperhouse/displaywidth/trie.go
generated
vendored
502
vendor/github.com/clipperhouse/displaywidth/trie.go
generated
vendored
@@ -10,12 +10,10 @@ type property uint8
|
||||
const (
|
||||
// Always 0 width, includes combining marks, control characters, non-printable, etc
|
||||
_Zero_Width property = iota + 1
|
||||
// Always 2 wide (East Asian Wide F/W)
|
||||
_East_Asian_Wide
|
||||
// Always 2 wide (East Asian Wide F/W, Emoji, Regional Indicator)
|
||||
_Wide
|
||||
// Width depends on EastAsianWidth option
|
||||
_East_Asian_Ambiguous
|
||||
// Extended_Pictographic + Emoji_Presentation
|
||||
_Emoji
|
||||
)
|
||||
|
||||
// lookup returns the trie value for the first UTF-8 encoding in s and
|
||||
@@ -81,7 +79,7 @@ func lookup[T stringish.Interface](s T) (v uint8, sz int) {
|
||||
return 0, 1
|
||||
}
|
||||
|
||||
// stringWidthTrie. Total size: 17728 bytes (17.31 KiB). Checksum: b4b51ae347944fdb.
|
||||
// stringWidthTrie. Total size: 17664 bytes (17.25 KiB). Checksum: c77d82ff2d69f0d2.
|
||||
// type stringWidthTrie struct { }
|
||||
|
||||
// func newStringWidthTrie(i int) *stringWidthTrie {
|
||||
@@ -96,9 +94,9 @@ func lookupValue(n uint32, b byte) uint8 {
|
||||
}
|
||||
}
|
||||
|
||||
// stringWidthValues: 247 blocks, 15808 entries, 15808 bytes
|
||||
// stringWidthValues: 246 blocks, 15744 entries, 15744 bytes
|
||||
// The third block is the zero block.
|
||||
var stringWidthValues = [15808]uint8{
|
||||
var stringWidthValues = [15744]uint8{
|
||||
// Block 0x0, offset 0x0
|
||||
// Block 0x1, offset 0x40
|
||||
// Block 0x2, offset 0x80
|
||||
@@ -577,13 +575,13 @@ var stringWidthValues = [15808]uint8{
|
||||
0x167f: 0x0003,
|
||||
// Block 0x5a, offset 0x1680
|
||||
0x1692: 0x0003,
|
||||
0x169a: 0x0004, 0x169b: 0x0004,
|
||||
0x169a: 0x0002, 0x169b: 0x0002,
|
||||
0x16a9: 0x0002,
|
||||
0x16aa: 0x0002,
|
||||
// Block 0x5b, offset 0x16c0
|
||||
0x16e9: 0x0004,
|
||||
0x16ea: 0x0004, 0x16eb: 0x0004, 0x16ec: 0x0004,
|
||||
0x16f0: 0x0004, 0x16f3: 0x0004,
|
||||
0x16e9: 0x0002,
|
||||
0x16ea: 0x0002, 0x16eb: 0x0002, 0x16ec: 0x0002,
|
||||
0x16f0: 0x0002, 0x16f3: 0x0002,
|
||||
// Block 0x5c, offset 0x1700
|
||||
0x1720: 0x0003, 0x1721: 0x0003, 0x1722: 0x0003, 0x1723: 0x0003,
|
||||
0x1724: 0x0003, 0x1725: 0x0003, 0x1726: 0x0003, 0x1727: 0x0003, 0x1728: 0x0003, 0x1729: 0x0003,
|
||||
@@ -642,63 +640,63 @@ var stringWidthValues = [15808]uint8{
|
||||
0x1862: 0x0003, 0x1863: 0x0003,
|
||||
0x1864: 0x0003, 0x1865: 0x0003,
|
||||
0x186f: 0x0003,
|
||||
0x187d: 0x0004, 0x187e: 0x0004,
|
||||
0x187d: 0x0002, 0x187e: 0x0002,
|
||||
// Block 0x62, offset 0x1880
|
||||
0x1885: 0x0003,
|
||||
0x1886: 0x0003, 0x1889: 0x0003,
|
||||
0x188e: 0x0003, 0x188f: 0x0003,
|
||||
0x1894: 0x0004, 0x1895: 0x0004,
|
||||
0x1894: 0x0002, 0x1895: 0x0002,
|
||||
0x189c: 0x0003,
|
||||
0x189e: 0x0003,
|
||||
0x18b0: 0x0002, 0x18b1: 0x0002, 0x18b2: 0x0002, 0x18b3: 0x0002, 0x18b4: 0x0002, 0x18b5: 0x0002,
|
||||
0x18b6: 0x0002, 0x18b7: 0x0002,
|
||||
// Block 0x63, offset 0x18c0
|
||||
0x18c0: 0x0003, 0x18c2: 0x0003,
|
||||
0x18c8: 0x0004, 0x18c9: 0x0004, 0x18ca: 0x0004, 0x18cb: 0x0004,
|
||||
0x18cc: 0x0004, 0x18cd: 0x0004, 0x18ce: 0x0004, 0x18cf: 0x0004, 0x18d0: 0x0004, 0x18d1: 0x0004,
|
||||
0x18d2: 0x0004, 0x18d3: 0x0004,
|
||||
0x18c8: 0x0002, 0x18c9: 0x0002, 0x18ca: 0x0002, 0x18cb: 0x0002,
|
||||
0x18cc: 0x0002, 0x18cd: 0x0002, 0x18ce: 0x0002, 0x18cf: 0x0002, 0x18d0: 0x0002, 0x18d1: 0x0002,
|
||||
0x18d2: 0x0002, 0x18d3: 0x0002,
|
||||
0x18e0: 0x0003, 0x18e1: 0x0003, 0x18e3: 0x0003,
|
||||
0x18e4: 0x0003, 0x18e5: 0x0003, 0x18e7: 0x0003, 0x18e8: 0x0003, 0x18e9: 0x0003,
|
||||
0x18ea: 0x0003, 0x18ec: 0x0003, 0x18ed: 0x0003, 0x18ef: 0x0003,
|
||||
0x18ff: 0x0004,
|
||||
0x18ff: 0x0002,
|
||||
// Block 0x64, offset 0x1900
|
||||
0x190a: 0x0002, 0x190b: 0x0002,
|
||||
0x190c: 0x0002, 0x190d: 0x0002, 0x190e: 0x0002, 0x190f: 0x0002,
|
||||
0x1913: 0x0004,
|
||||
0x191e: 0x0003, 0x191f: 0x0003, 0x1921: 0x0004,
|
||||
0x192a: 0x0004, 0x192b: 0x0004,
|
||||
0x193d: 0x0004, 0x193e: 0x0004, 0x193f: 0x0003,
|
||||
0x1913: 0x0002,
|
||||
0x191e: 0x0003, 0x191f: 0x0003, 0x1921: 0x0002,
|
||||
0x192a: 0x0002, 0x192b: 0x0002,
|
||||
0x193d: 0x0002, 0x193e: 0x0002, 0x193f: 0x0003,
|
||||
// Block 0x65, offset 0x1940
|
||||
0x1944: 0x0004, 0x1945: 0x0004,
|
||||
0x1944: 0x0002, 0x1945: 0x0002,
|
||||
0x1946: 0x0003, 0x1947: 0x0003, 0x1948: 0x0003, 0x1949: 0x0003, 0x194a: 0x0003, 0x194b: 0x0003,
|
||||
0x194c: 0x0003, 0x194d: 0x0003, 0x194e: 0x0004, 0x194f: 0x0003, 0x1950: 0x0003, 0x1951: 0x0003,
|
||||
0x1952: 0x0003, 0x1953: 0x0003, 0x1954: 0x0004, 0x1955: 0x0003, 0x1956: 0x0003, 0x1957: 0x0003,
|
||||
0x194c: 0x0003, 0x194d: 0x0003, 0x194e: 0x0002, 0x194f: 0x0003, 0x1950: 0x0003, 0x1951: 0x0003,
|
||||
0x1952: 0x0003, 0x1953: 0x0003, 0x1954: 0x0002, 0x1955: 0x0003, 0x1956: 0x0003, 0x1957: 0x0003,
|
||||
0x1958: 0x0003, 0x1959: 0x0003, 0x195a: 0x0003, 0x195b: 0x0003, 0x195c: 0x0003, 0x195d: 0x0003,
|
||||
0x195e: 0x0003, 0x195f: 0x0003, 0x1960: 0x0003, 0x1961: 0x0003, 0x1963: 0x0003,
|
||||
0x1968: 0x0003, 0x1969: 0x0003,
|
||||
0x196a: 0x0004, 0x196b: 0x0003, 0x196c: 0x0003, 0x196d: 0x0003, 0x196e: 0x0003, 0x196f: 0x0003,
|
||||
0x1970: 0x0003, 0x1971: 0x0003, 0x1972: 0x0004, 0x1973: 0x0004, 0x1974: 0x0003, 0x1975: 0x0004,
|
||||
0x1976: 0x0003, 0x1977: 0x0003, 0x1978: 0x0003, 0x1979: 0x0003, 0x197a: 0x0004, 0x197b: 0x0003,
|
||||
0x197c: 0x0003, 0x197d: 0x0004, 0x197e: 0x0003, 0x197f: 0x0003,
|
||||
0x196a: 0x0002, 0x196b: 0x0003, 0x196c: 0x0003, 0x196d: 0x0003, 0x196e: 0x0003, 0x196f: 0x0003,
|
||||
0x1970: 0x0003, 0x1971: 0x0003, 0x1972: 0x0002, 0x1973: 0x0002, 0x1974: 0x0003, 0x1975: 0x0002,
|
||||
0x1976: 0x0003, 0x1977: 0x0003, 0x1978: 0x0003, 0x1979: 0x0003, 0x197a: 0x0002, 0x197b: 0x0003,
|
||||
0x197c: 0x0003, 0x197d: 0x0002, 0x197e: 0x0003, 0x197f: 0x0003,
|
||||
// Block 0x66, offset 0x1980
|
||||
0x1985: 0x0004,
|
||||
0x198a: 0x0004, 0x198b: 0x0004,
|
||||
0x19a8: 0x0004,
|
||||
0x1985: 0x0002,
|
||||
0x198a: 0x0002, 0x198b: 0x0002,
|
||||
0x19a8: 0x0002,
|
||||
0x19bd: 0x0003,
|
||||
// Block 0x67, offset 0x19c0
|
||||
0x19cc: 0x0004, 0x19ce: 0x0004,
|
||||
0x19d3: 0x0004, 0x19d4: 0x0004, 0x19d5: 0x0004, 0x19d7: 0x0004,
|
||||
0x19cc: 0x0002, 0x19ce: 0x0002,
|
||||
0x19d3: 0x0002, 0x19d4: 0x0002, 0x19d5: 0x0002, 0x19d7: 0x0002,
|
||||
0x19f6: 0x0003, 0x19f7: 0x0003, 0x19f8: 0x0003, 0x19f9: 0x0003, 0x19fa: 0x0003, 0x19fb: 0x0003,
|
||||
0x19fc: 0x0003, 0x19fd: 0x0003, 0x19fe: 0x0003, 0x19ff: 0x0003,
|
||||
// Block 0x68, offset 0x1a00
|
||||
0x1a15: 0x0004, 0x1a16: 0x0004, 0x1a17: 0x0004,
|
||||
0x1a30: 0x0004,
|
||||
0x1a3f: 0x0004,
|
||||
0x1a15: 0x0002, 0x1a16: 0x0002, 0x1a17: 0x0002,
|
||||
0x1a30: 0x0002,
|
||||
0x1a3f: 0x0002,
|
||||
// Block 0x69, offset 0x1a40
|
||||
0x1a5b: 0x0004, 0x1a5c: 0x0004,
|
||||
0x1a5b: 0x0002, 0x1a5c: 0x0002,
|
||||
// Block 0x6a, offset 0x1a80
|
||||
0x1a90: 0x0004,
|
||||
0x1a95: 0x0004, 0x1a96: 0x0003, 0x1a97: 0x0003,
|
||||
0x1a90: 0x0002,
|
||||
0x1a95: 0x0002, 0x1a96: 0x0003, 0x1a97: 0x0003,
|
||||
0x1a98: 0x0003, 0x1a99: 0x0003,
|
||||
// Block 0x6b, offset 0x1ac0
|
||||
0x1aef: 0x0001,
|
||||
@@ -1273,9 +1271,9 @@ var stringWidthValues = [15808]uint8{
|
||||
0x3604: 0x0001, 0x3605: 0x0001,
|
||||
0x3606: 0x0001, 0x3607: 0x0001, 0x3608: 0x0001, 0x3609: 0x0001, 0x360a: 0x0001,
|
||||
// Block 0xd9, offset 0x3640
|
||||
0x3644: 0x0004,
|
||||
0x3644: 0x0002,
|
||||
// Block 0xda, offset 0x3680
|
||||
0x368f: 0x0004,
|
||||
0x368f: 0x0002,
|
||||
// Block 0xdb, offset 0x36c0
|
||||
0x36c0: 0x0003, 0x36c1: 0x0003, 0x36c2: 0x0003, 0x36c3: 0x0003, 0x36c4: 0x0003, 0x36c5: 0x0003,
|
||||
0x36c6: 0x0003, 0x36c7: 0x0003, 0x36c8: 0x0003, 0x36c9: 0x0003, 0x36ca: 0x0003,
|
||||
@@ -1302,246 +1300,228 @@ var stringWidthValues = [15808]uint8{
|
||||
// Block 0xdd, offset 0x3740
|
||||
0x3740: 0x0003, 0x3741: 0x0003, 0x3742: 0x0003, 0x3743: 0x0003, 0x3744: 0x0003, 0x3745: 0x0003,
|
||||
0x3746: 0x0003, 0x3747: 0x0003, 0x3748: 0x0003, 0x3749: 0x0003, 0x374a: 0x0003, 0x374b: 0x0003,
|
||||
0x374c: 0x0003, 0x374d: 0x0003, 0x374e: 0x0004, 0x374f: 0x0003, 0x3750: 0x0003, 0x3751: 0x0004,
|
||||
0x3752: 0x0004, 0x3753: 0x0004, 0x3754: 0x0004, 0x3755: 0x0004, 0x3756: 0x0004, 0x3757: 0x0004,
|
||||
0x3758: 0x0004, 0x3759: 0x0004, 0x375a: 0x0004, 0x375b: 0x0003, 0x375c: 0x0003, 0x375d: 0x0003,
|
||||
0x374c: 0x0003, 0x374d: 0x0003, 0x374e: 0x0002, 0x374f: 0x0003, 0x3750: 0x0003, 0x3751: 0x0002,
|
||||
0x3752: 0x0002, 0x3753: 0x0002, 0x3754: 0x0002, 0x3755: 0x0002, 0x3756: 0x0002, 0x3757: 0x0002,
|
||||
0x3758: 0x0002, 0x3759: 0x0002, 0x375a: 0x0002, 0x375b: 0x0003, 0x375c: 0x0003, 0x375d: 0x0003,
|
||||
0x375e: 0x0003, 0x375f: 0x0003, 0x3760: 0x0003, 0x3761: 0x0003, 0x3762: 0x0003, 0x3763: 0x0003,
|
||||
0x3764: 0x0003, 0x3765: 0x0003, 0x3766: 0x0003, 0x3767: 0x0003, 0x3768: 0x0003, 0x3769: 0x0003,
|
||||
0x376a: 0x0003, 0x376b: 0x0003, 0x376c: 0x0003,
|
||||
// Block 0xde, offset 0x3780
|
||||
0x3780: 0x0002, 0x3781: 0x0004, 0x3782: 0x0002,
|
||||
0x3790: 0x0002, 0x3791: 0x0002,
|
||||
0x3792: 0x0002, 0x3793: 0x0002, 0x3794: 0x0002, 0x3795: 0x0002, 0x3796: 0x0002, 0x3797: 0x0002,
|
||||
0x3798: 0x0002, 0x3799: 0x0002, 0x379a: 0x0004, 0x379b: 0x0002, 0x379c: 0x0002, 0x379d: 0x0002,
|
||||
0x379e: 0x0002, 0x379f: 0x0002, 0x37a0: 0x0002, 0x37a1: 0x0002, 0x37a2: 0x0002, 0x37a3: 0x0002,
|
||||
0x37a4: 0x0002, 0x37a5: 0x0002, 0x37a6: 0x0002, 0x37a7: 0x0002, 0x37a8: 0x0002, 0x37a9: 0x0002,
|
||||
0x37aa: 0x0002, 0x37ab: 0x0002, 0x37ac: 0x0002, 0x37ad: 0x0002, 0x37ae: 0x0002, 0x37af: 0x0004,
|
||||
0x37b0: 0x0002, 0x37b1: 0x0002, 0x37b2: 0x0004, 0x37b3: 0x0004, 0x37b4: 0x0004, 0x37b5: 0x0004,
|
||||
0x37b6: 0x0004, 0x37b7: 0x0002, 0x37b8: 0x0004, 0x37b9: 0x0004, 0x37ba: 0x0004, 0x37bb: 0x0002,
|
||||
0x37a6: 0x0002, 0x37a7: 0x0002, 0x37a8: 0x0002, 0x37a9: 0x0002,
|
||||
0x37aa: 0x0002, 0x37ab: 0x0002, 0x37ac: 0x0002, 0x37ad: 0x0002, 0x37ae: 0x0002, 0x37af: 0x0002,
|
||||
0x37b0: 0x0002, 0x37b1: 0x0002, 0x37b2: 0x0002, 0x37b3: 0x0002, 0x37b4: 0x0002, 0x37b5: 0x0002,
|
||||
0x37b6: 0x0002, 0x37b7: 0x0002, 0x37b8: 0x0002, 0x37b9: 0x0002, 0x37ba: 0x0002, 0x37bb: 0x0002,
|
||||
0x37bc: 0x0002, 0x37bd: 0x0002, 0x37be: 0x0002, 0x37bf: 0x0002,
|
||||
// Block 0xdf, offset 0x37c0
|
||||
0x37c0: 0x0002, 0x37c1: 0x0002, 0x37c2: 0x0002, 0x37c3: 0x0002, 0x37c4: 0x0002, 0x37c5: 0x0002,
|
||||
0x37c6: 0x0002, 0x37c7: 0x0002, 0x37c8: 0x0002,
|
||||
0x37d0: 0x0004, 0x37d1: 0x0004,
|
||||
0x37e0: 0x0002, 0x37e1: 0x0002, 0x37e2: 0x0002, 0x37e3: 0x0002,
|
||||
0x37e4: 0x0002, 0x37e5: 0x0002,
|
||||
0x37c0: 0x0002, 0x37c1: 0x0002, 0x37c2: 0x0002,
|
||||
0x37d0: 0x0002, 0x37d1: 0x0002,
|
||||
0x37d2: 0x0002, 0x37d3: 0x0002, 0x37d4: 0x0002, 0x37d5: 0x0002, 0x37d6: 0x0002, 0x37d7: 0x0002,
|
||||
0x37d8: 0x0002, 0x37d9: 0x0002, 0x37da: 0x0002, 0x37db: 0x0002, 0x37dc: 0x0002, 0x37dd: 0x0002,
|
||||
0x37de: 0x0002, 0x37df: 0x0002, 0x37e0: 0x0002, 0x37e1: 0x0002, 0x37e2: 0x0002, 0x37e3: 0x0002,
|
||||
0x37e4: 0x0002, 0x37e5: 0x0002, 0x37e6: 0x0002, 0x37e7: 0x0002, 0x37e8: 0x0002, 0x37e9: 0x0002,
|
||||
0x37ea: 0x0002, 0x37eb: 0x0002, 0x37ec: 0x0002, 0x37ed: 0x0002, 0x37ee: 0x0002, 0x37ef: 0x0002,
|
||||
0x37f0: 0x0002, 0x37f1: 0x0002, 0x37f2: 0x0002, 0x37f3: 0x0002, 0x37f4: 0x0002, 0x37f5: 0x0002,
|
||||
0x37f6: 0x0002, 0x37f7: 0x0002, 0x37f8: 0x0002, 0x37f9: 0x0002, 0x37fa: 0x0002, 0x37fb: 0x0002,
|
||||
// Block 0xe0, offset 0x3800
|
||||
0x3800: 0x0004, 0x3801: 0x0004, 0x3802: 0x0004, 0x3803: 0x0004, 0x3804: 0x0004, 0x3805: 0x0004,
|
||||
0x3806: 0x0004, 0x3807: 0x0004, 0x3808: 0x0004, 0x3809: 0x0004, 0x380a: 0x0004, 0x380b: 0x0004,
|
||||
0x380c: 0x0004, 0x380d: 0x0004, 0x380e: 0x0004, 0x380f: 0x0004, 0x3810: 0x0004, 0x3811: 0x0004,
|
||||
0x3812: 0x0004, 0x3813: 0x0004, 0x3814: 0x0004, 0x3815: 0x0004, 0x3816: 0x0004, 0x3817: 0x0004,
|
||||
0x3818: 0x0004, 0x3819: 0x0004, 0x381a: 0x0004, 0x381b: 0x0004, 0x381c: 0x0004, 0x381d: 0x0004,
|
||||
0x381e: 0x0004, 0x381f: 0x0004, 0x3820: 0x0004,
|
||||
0x382d: 0x0004, 0x382e: 0x0004, 0x382f: 0x0004,
|
||||
0x3830: 0x0004, 0x3831: 0x0004, 0x3832: 0x0004, 0x3833: 0x0004, 0x3834: 0x0004, 0x3835: 0x0004,
|
||||
0x3837: 0x0004, 0x3838: 0x0004, 0x3839: 0x0004, 0x383a: 0x0004, 0x383b: 0x0004,
|
||||
0x383c: 0x0004, 0x383d: 0x0004, 0x383e: 0x0004, 0x383f: 0x0004,
|
||||
0x3800: 0x0002, 0x3801: 0x0002, 0x3802: 0x0002, 0x3803: 0x0002, 0x3804: 0x0002, 0x3805: 0x0002,
|
||||
0x3806: 0x0002, 0x3807: 0x0002, 0x3808: 0x0002,
|
||||
0x3810: 0x0002, 0x3811: 0x0002,
|
||||
0x3820: 0x0002, 0x3821: 0x0002, 0x3822: 0x0002, 0x3823: 0x0002,
|
||||
0x3824: 0x0002, 0x3825: 0x0002,
|
||||
// Block 0xe1, offset 0x3840
|
||||
0x3840: 0x0004, 0x3841: 0x0004, 0x3842: 0x0004, 0x3843: 0x0004, 0x3844: 0x0004, 0x3845: 0x0004,
|
||||
0x3846: 0x0004, 0x3847: 0x0004, 0x3848: 0x0004, 0x3849: 0x0004, 0x384a: 0x0004, 0x384b: 0x0004,
|
||||
0x384c: 0x0004, 0x384d: 0x0004, 0x384e: 0x0004, 0x384f: 0x0004, 0x3850: 0x0004, 0x3851: 0x0004,
|
||||
0x3852: 0x0004, 0x3853: 0x0004, 0x3854: 0x0004, 0x3855: 0x0004, 0x3856: 0x0004, 0x3857: 0x0004,
|
||||
0x3858: 0x0004, 0x3859: 0x0004, 0x385a: 0x0004, 0x385b: 0x0004, 0x385c: 0x0004, 0x385d: 0x0004,
|
||||
0x385e: 0x0004, 0x385f: 0x0004, 0x3860: 0x0004, 0x3861: 0x0004, 0x3862: 0x0004, 0x3863: 0x0004,
|
||||
0x3864: 0x0004, 0x3865: 0x0004, 0x3866: 0x0004, 0x3867: 0x0004, 0x3868: 0x0004, 0x3869: 0x0004,
|
||||
0x386a: 0x0004, 0x386b: 0x0004, 0x386c: 0x0004, 0x386d: 0x0004, 0x386e: 0x0004, 0x386f: 0x0004,
|
||||
0x3870: 0x0004, 0x3871: 0x0004, 0x3872: 0x0004, 0x3873: 0x0004, 0x3874: 0x0004, 0x3875: 0x0004,
|
||||
0x3876: 0x0004, 0x3877: 0x0004, 0x3878: 0x0004, 0x3879: 0x0004, 0x387a: 0x0004, 0x387b: 0x0004,
|
||||
0x387c: 0x0004, 0x387e: 0x0004, 0x387f: 0x0004,
|
||||
0x3840: 0x0002, 0x3841: 0x0002, 0x3842: 0x0002, 0x3843: 0x0002, 0x3844: 0x0002, 0x3845: 0x0002,
|
||||
0x3846: 0x0002, 0x3847: 0x0002, 0x3848: 0x0002, 0x3849: 0x0002, 0x384a: 0x0002, 0x384b: 0x0002,
|
||||
0x384c: 0x0002, 0x384d: 0x0002, 0x384e: 0x0002, 0x384f: 0x0002, 0x3850: 0x0002, 0x3851: 0x0002,
|
||||
0x3852: 0x0002, 0x3853: 0x0002, 0x3854: 0x0002, 0x3855: 0x0002, 0x3856: 0x0002, 0x3857: 0x0002,
|
||||
0x3858: 0x0002, 0x3859: 0x0002, 0x385a: 0x0002, 0x385b: 0x0002, 0x385c: 0x0002, 0x385d: 0x0002,
|
||||
0x385e: 0x0002, 0x385f: 0x0002, 0x3860: 0x0002,
|
||||
0x386d: 0x0002, 0x386e: 0x0002, 0x386f: 0x0002,
|
||||
0x3870: 0x0002, 0x3871: 0x0002, 0x3872: 0x0002, 0x3873: 0x0002, 0x3874: 0x0002, 0x3875: 0x0002,
|
||||
0x3877: 0x0002, 0x3878: 0x0002, 0x3879: 0x0002, 0x387a: 0x0002, 0x387b: 0x0002,
|
||||
0x387c: 0x0002, 0x387d: 0x0002, 0x387e: 0x0002, 0x387f: 0x0002,
|
||||
// Block 0xe2, offset 0x3880
|
||||
0x3880: 0x0004, 0x3881: 0x0004, 0x3882: 0x0004, 0x3883: 0x0004, 0x3884: 0x0004, 0x3885: 0x0004,
|
||||
0x3886: 0x0004, 0x3887: 0x0004, 0x3888: 0x0004, 0x3889: 0x0004, 0x388a: 0x0004, 0x388b: 0x0004,
|
||||
0x388c: 0x0004, 0x388d: 0x0004, 0x388e: 0x0004, 0x388f: 0x0004, 0x3890: 0x0004, 0x3891: 0x0004,
|
||||
0x3892: 0x0004, 0x3893: 0x0004,
|
||||
0x38a0: 0x0004, 0x38a1: 0x0004, 0x38a2: 0x0004, 0x38a3: 0x0004,
|
||||
0x38a4: 0x0004, 0x38a5: 0x0004, 0x38a6: 0x0004, 0x38a7: 0x0004, 0x38a8: 0x0004, 0x38a9: 0x0004,
|
||||
0x38aa: 0x0004, 0x38ab: 0x0004, 0x38ac: 0x0004, 0x38ad: 0x0004, 0x38ae: 0x0004, 0x38af: 0x0004,
|
||||
0x38b0: 0x0004, 0x38b1: 0x0004, 0x38b2: 0x0004, 0x38b3: 0x0004, 0x38b4: 0x0004, 0x38b5: 0x0004,
|
||||
0x38b6: 0x0004, 0x38b7: 0x0004, 0x38b8: 0x0004, 0x38b9: 0x0004, 0x38ba: 0x0004, 0x38bb: 0x0004,
|
||||
0x38bc: 0x0004, 0x38bd: 0x0004, 0x38be: 0x0004, 0x38bf: 0x0004,
|
||||
0x3880: 0x0002, 0x3881: 0x0002, 0x3882: 0x0002, 0x3883: 0x0002, 0x3884: 0x0002, 0x3885: 0x0002,
|
||||
0x3886: 0x0002, 0x3887: 0x0002, 0x3888: 0x0002, 0x3889: 0x0002, 0x388a: 0x0002, 0x388b: 0x0002,
|
||||
0x388c: 0x0002, 0x388d: 0x0002, 0x388e: 0x0002, 0x388f: 0x0002, 0x3890: 0x0002, 0x3891: 0x0002,
|
||||
0x3892: 0x0002, 0x3893: 0x0002, 0x3894: 0x0002, 0x3895: 0x0002, 0x3896: 0x0002, 0x3897: 0x0002,
|
||||
0x3898: 0x0002, 0x3899: 0x0002, 0x389a: 0x0002, 0x389b: 0x0002, 0x389c: 0x0002, 0x389d: 0x0002,
|
||||
0x389e: 0x0002, 0x389f: 0x0002, 0x38a0: 0x0002, 0x38a1: 0x0002, 0x38a2: 0x0002, 0x38a3: 0x0002,
|
||||
0x38a4: 0x0002, 0x38a5: 0x0002, 0x38a6: 0x0002, 0x38a7: 0x0002, 0x38a8: 0x0002, 0x38a9: 0x0002,
|
||||
0x38aa: 0x0002, 0x38ab: 0x0002, 0x38ac: 0x0002, 0x38ad: 0x0002, 0x38ae: 0x0002, 0x38af: 0x0002,
|
||||
0x38b0: 0x0002, 0x38b1: 0x0002, 0x38b2: 0x0002, 0x38b3: 0x0002, 0x38b4: 0x0002, 0x38b5: 0x0002,
|
||||
0x38b6: 0x0002, 0x38b7: 0x0002, 0x38b8: 0x0002, 0x38b9: 0x0002, 0x38ba: 0x0002, 0x38bb: 0x0002,
|
||||
0x38bc: 0x0002, 0x38be: 0x0002, 0x38bf: 0x0002,
|
||||
// Block 0xe3, offset 0x38c0
|
||||
0x38c0: 0x0004, 0x38c1: 0x0004, 0x38c2: 0x0004, 0x38c3: 0x0004, 0x38c4: 0x0004, 0x38c5: 0x0004,
|
||||
0x38c6: 0x0004, 0x38c7: 0x0004, 0x38c8: 0x0004, 0x38c9: 0x0004, 0x38ca: 0x0004,
|
||||
0x38cf: 0x0004, 0x38d0: 0x0004, 0x38d1: 0x0004,
|
||||
0x38d2: 0x0004, 0x38d3: 0x0004,
|
||||
0x38e0: 0x0004, 0x38e1: 0x0004, 0x38e2: 0x0004, 0x38e3: 0x0004,
|
||||
0x38e4: 0x0004, 0x38e5: 0x0004, 0x38e6: 0x0004, 0x38e7: 0x0004, 0x38e8: 0x0004, 0x38e9: 0x0004,
|
||||
0x38ea: 0x0004, 0x38eb: 0x0004, 0x38ec: 0x0004, 0x38ed: 0x0004, 0x38ee: 0x0004, 0x38ef: 0x0004,
|
||||
0x38f0: 0x0004, 0x38f4: 0x0004,
|
||||
0x38f8: 0x0004, 0x38f9: 0x0004, 0x38fa: 0x0004, 0x38fb: 0x0002,
|
||||
0x38c0: 0x0002, 0x38c1: 0x0002, 0x38c2: 0x0002, 0x38c3: 0x0002, 0x38c4: 0x0002, 0x38c5: 0x0002,
|
||||
0x38c6: 0x0002, 0x38c7: 0x0002, 0x38c8: 0x0002, 0x38c9: 0x0002, 0x38ca: 0x0002, 0x38cb: 0x0002,
|
||||
0x38cc: 0x0002, 0x38cd: 0x0002, 0x38ce: 0x0002, 0x38cf: 0x0002, 0x38d0: 0x0002, 0x38d1: 0x0002,
|
||||
0x38d2: 0x0002, 0x38d3: 0x0002,
|
||||
0x38e0: 0x0002, 0x38e1: 0x0002, 0x38e2: 0x0002, 0x38e3: 0x0002,
|
||||
0x38e4: 0x0002, 0x38e5: 0x0002, 0x38e6: 0x0002, 0x38e7: 0x0002, 0x38e8: 0x0002, 0x38e9: 0x0002,
|
||||
0x38ea: 0x0002, 0x38eb: 0x0002, 0x38ec: 0x0002, 0x38ed: 0x0002, 0x38ee: 0x0002, 0x38ef: 0x0002,
|
||||
0x38f0: 0x0002, 0x38f1: 0x0002, 0x38f2: 0x0002, 0x38f3: 0x0002, 0x38f4: 0x0002, 0x38f5: 0x0002,
|
||||
0x38f6: 0x0002, 0x38f7: 0x0002, 0x38f8: 0x0002, 0x38f9: 0x0002, 0x38fa: 0x0002, 0x38fb: 0x0002,
|
||||
0x38fc: 0x0002, 0x38fd: 0x0002, 0x38fe: 0x0002, 0x38ff: 0x0002,
|
||||
// Block 0xe4, offset 0x3900
|
||||
0x3900: 0x0004, 0x3901: 0x0004, 0x3902: 0x0004, 0x3903: 0x0004, 0x3904: 0x0004, 0x3905: 0x0004,
|
||||
0x3906: 0x0004, 0x3907: 0x0004, 0x3908: 0x0004, 0x3909: 0x0004, 0x390a: 0x0004, 0x390b: 0x0004,
|
||||
0x390c: 0x0004, 0x390d: 0x0004, 0x390e: 0x0004, 0x390f: 0x0004, 0x3910: 0x0004, 0x3911: 0x0004,
|
||||
0x3912: 0x0004, 0x3913: 0x0004, 0x3914: 0x0004, 0x3915: 0x0004, 0x3916: 0x0004, 0x3917: 0x0004,
|
||||
0x3918: 0x0004, 0x3919: 0x0004, 0x391a: 0x0004, 0x391b: 0x0004, 0x391c: 0x0004, 0x391d: 0x0004,
|
||||
0x391e: 0x0004, 0x391f: 0x0004, 0x3920: 0x0004, 0x3921: 0x0004, 0x3922: 0x0004, 0x3923: 0x0004,
|
||||
0x3924: 0x0004, 0x3925: 0x0004, 0x3926: 0x0004, 0x3927: 0x0004, 0x3928: 0x0004, 0x3929: 0x0004,
|
||||
0x392a: 0x0004, 0x392b: 0x0004, 0x392c: 0x0004, 0x392d: 0x0004, 0x392e: 0x0004, 0x392f: 0x0004,
|
||||
0x3930: 0x0004, 0x3931: 0x0004, 0x3932: 0x0004, 0x3933: 0x0004, 0x3934: 0x0004, 0x3935: 0x0004,
|
||||
0x3936: 0x0004, 0x3937: 0x0004, 0x3938: 0x0004, 0x3939: 0x0004, 0x393a: 0x0004, 0x393b: 0x0004,
|
||||
0x393c: 0x0004, 0x393d: 0x0004, 0x393e: 0x0004,
|
||||
0x3900: 0x0002, 0x3901: 0x0002, 0x3902: 0x0002, 0x3903: 0x0002, 0x3904: 0x0002, 0x3905: 0x0002,
|
||||
0x3906: 0x0002, 0x3907: 0x0002, 0x3908: 0x0002, 0x3909: 0x0002, 0x390a: 0x0002,
|
||||
0x390f: 0x0002, 0x3910: 0x0002, 0x3911: 0x0002,
|
||||
0x3912: 0x0002, 0x3913: 0x0002,
|
||||
0x3920: 0x0002, 0x3921: 0x0002, 0x3922: 0x0002, 0x3923: 0x0002,
|
||||
0x3924: 0x0002, 0x3925: 0x0002, 0x3926: 0x0002, 0x3927: 0x0002, 0x3928: 0x0002, 0x3929: 0x0002,
|
||||
0x392a: 0x0002, 0x392b: 0x0002, 0x392c: 0x0002, 0x392d: 0x0002, 0x392e: 0x0002, 0x392f: 0x0002,
|
||||
0x3930: 0x0002, 0x3934: 0x0002,
|
||||
0x3938: 0x0002, 0x3939: 0x0002, 0x393a: 0x0002, 0x393b: 0x0002,
|
||||
0x393c: 0x0002, 0x393d: 0x0002, 0x393e: 0x0002, 0x393f: 0x0002,
|
||||
// Block 0xe5, offset 0x3940
|
||||
0x3940: 0x0004, 0x3942: 0x0004, 0x3943: 0x0004, 0x3944: 0x0004, 0x3945: 0x0004,
|
||||
0x3946: 0x0004, 0x3947: 0x0004, 0x3948: 0x0004, 0x3949: 0x0004, 0x394a: 0x0004, 0x394b: 0x0004,
|
||||
0x394c: 0x0004, 0x394d: 0x0004, 0x394e: 0x0004, 0x394f: 0x0004, 0x3950: 0x0004, 0x3951: 0x0004,
|
||||
0x3952: 0x0004, 0x3953: 0x0004, 0x3954: 0x0004, 0x3955: 0x0004, 0x3956: 0x0004, 0x3957: 0x0004,
|
||||
0x3958: 0x0004, 0x3959: 0x0004, 0x395a: 0x0004, 0x395b: 0x0004, 0x395c: 0x0004, 0x395d: 0x0004,
|
||||
0x395e: 0x0004, 0x395f: 0x0004, 0x3960: 0x0004, 0x3961: 0x0004, 0x3962: 0x0004, 0x3963: 0x0004,
|
||||
0x3964: 0x0004, 0x3965: 0x0004, 0x3966: 0x0004, 0x3967: 0x0004, 0x3968: 0x0004, 0x3969: 0x0004,
|
||||
0x396a: 0x0004, 0x396b: 0x0004, 0x396c: 0x0004, 0x396d: 0x0004, 0x396e: 0x0004, 0x396f: 0x0004,
|
||||
0x3970: 0x0004, 0x3971: 0x0004, 0x3972: 0x0004, 0x3973: 0x0004, 0x3974: 0x0004, 0x3975: 0x0004,
|
||||
0x3976: 0x0004, 0x3977: 0x0004, 0x3978: 0x0004, 0x3979: 0x0004, 0x397a: 0x0004, 0x397b: 0x0004,
|
||||
0x397c: 0x0004, 0x397d: 0x0004, 0x397e: 0x0004, 0x397f: 0x0004,
|
||||
0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002,
|
||||
0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x0002,
|
||||
0x394c: 0x0002, 0x394d: 0x0002, 0x394e: 0x0002, 0x394f: 0x0002, 0x3950: 0x0002, 0x3951: 0x0002,
|
||||
0x3952: 0x0002, 0x3953: 0x0002, 0x3954: 0x0002, 0x3955: 0x0002, 0x3956: 0x0002, 0x3957: 0x0002,
|
||||
0x3958: 0x0002, 0x3959: 0x0002, 0x395a: 0x0002, 0x395b: 0x0002, 0x395c: 0x0002, 0x395d: 0x0002,
|
||||
0x395e: 0x0002, 0x395f: 0x0002, 0x3960: 0x0002, 0x3961: 0x0002, 0x3962: 0x0002, 0x3963: 0x0002,
|
||||
0x3964: 0x0002, 0x3965: 0x0002, 0x3966: 0x0002, 0x3967: 0x0002, 0x3968: 0x0002, 0x3969: 0x0002,
|
||||
0x396a: 0x0002, 0x396b: 0x0002, 0x396c: 0x0002, 0x396d: 0x0002, 0x396e: 0x0002, 0x396f: 0x0002,
|
||||
0x3970: 0x0002, 0x3971: 0x0002, 0x3972: 0x0002, 0x3973: 0x0002, 0x3974: 0x0002, 0x3975: 0x0002,
|
||||
0x3976: 0x0002, 0x3977: 0x0002, 0x3978: 0x0002, 0x3979: 0x0002, 0x397a: 0x0002, 0x397b: 0x0002,
|
||||
0x397c: 0x0002, 0x397d: 0x0002, 0x397e: 0x0002,
|
||||
// Block 0xe6, offset 0x3980
|
||||
0x3980: 0x0004, 0x3981: 0x0004, 0x3982: 0x0004, 0x3983: 0x0004, 0x3984: 0x0004, 0x3985: 0x0004,
|
||||
0x3986: 0x0004, 0x3987: 0x0004, 0x3988: 0x0004, 0x3989: 0x0004, 0x398a: 0x0004, 0x398b: 0x0004,
|
||||
0x398c: 0x0004, 0x398d: 0x0004, 0x398e: 0x0004, 0x398f: 0x0004, 0x3990: 0x0004, 0x3991: 0x0004,
|
||||
0x3992: 0x0004, 0x3993: 0x0004, 0x3994: 0x0004, 0x3995: 0x0004, 0x3996: 0x0004, 0x3997: 0x0004,
|
||||
0x3998: 0x0004, 0x3999: 0x0004, 0x399a: 0x0004, 0x399b: 0x0004, 0x399c: 0x0004, 0x399d: 0x0004,
|
||||
0x399e: 0x0004, 0x399f: 0x0004, 0x39a0: 0x0004, 0x39a1: 0x0004, 0x39a2: 0x0004, 0x39a3: 0x0004,
|
||||
0x39a4: 0x0004, 0x39a5: 0x0004, 0x39a6: 0x0004, 0x39a7: 0x0004, 0x39a8: 0x0004, 0x39a9: 0x0004,
|
||||
0x39aa: 0x0004, 0x39ab: 0x0004, 0x39ac: 0x0004, 0x39ad: 0x0004, 0x39ae: 0x0004, 0x39af: 0x0004,
|
||||
0x39b0: 0x0004, 0x39b1: 0x0004, 0x39b2: 0x0004, 0x39b3: 0x0004, 0x39b4: 0x0004, 0x39b5: 0x0004,
|
||||
0x39b6: 0x0004, 0x39b7: 0x0004, 0x39b8: 0x0004, 0x39b9: 0x0004, 0x39ba: 0x0004, 0x39bb: 0x0004,
|
||||
0x39bc: 0x0004, 0x39bd: 0x0004, 0x39be: 0x0004, 0x39bf: 0x0004,
|
||||
0x3980: 0x0002, 0x3982: 0x0002, 0x3983: 0x0002, 0x3984: 0x0002, 0x3985: 0x0002,
|
||||
0x3986: 0x0002, 0x3987: 0x0002, 0x3988: 0x0002, 0x3989: 0x0002, 0x398a: 0x0002, 0x398b: 0x0002,
|
||||
0x398c: 0x0002, 0x398d: 0x0002, 0x398e: 0x0002, 0x398f: 0x0002, 0x3990: 0x0002, 0x3991: 0x0002,
|
||||
0x3992: 0x0002, 0x3993: 0x0002, 0x3994: 0x0002, 0x3995: 0x0002, 0x3996: 0x0002, 0x3997: 0x0002,
|
||||
0x3998: 0x0002, 0x3999: 0x0002, 0x399a: 0x0002, 0x399b: 0x0002, 0x399c: 0x0002, 0x399d: 0x0002,
|
||||
0x399e: 0x0002, 0x399f: 0x0002, 0x39a0: 0x0002, 0x39a1: 0x0002, 0x39a2: 0x0002, 0x39a3: 0x0002,
|
||||
0x39a4: 0x0002, 0x39a5: 0x0002, 0x39a6: 0x0002, 0x39a7: 0x0002, 0x39a8: 0x0002, 0x39a9: 0x0002,
|
||||
0x39aa: 0x0002, 0x39ab: 0x0002, 0x39ac: 0x0002, 0x39ad: 0x0002, 0x39ae: 0x0002, 0x39af: 0x0002,
|
||||
0x39b0: 0x0002, 0x39b1: 0x0002, 0x39b2: 0x0002, 0x39b3: 0x0002, 0x39b4: 0x0002, 0x39b5: 0x0002,
|
||||
0x39b6: 0x0002, 0x39b7: 0x0002, 0x39b8: 0x0002, 0x39b9: 0x0002, 0x39ba: 0x0002, 0x39bb: 0x0002,
|
||||
0x39bc: 0x0002, 0x39bd: 0x0002, 0x39be: 0x0002, 0x39bf: 0x0002,
|
||||
// Block 0xe7, offset 0x39c0
|
||||
0x39c0: 0x0004, 0x39c1: 0x0004, 0x39c2: 0x0004, 0x39c3: 0x0004, 0x39c4: 0x0004, 0x39c5: 0x0004,
|
||||
0x39c6: 0x0004, 0x39c7: 0x0004, 0x39c8: 0x0004, 0x39c9: 0x0004, 0x39ca: 0x0004, 0x39cb: 0x0004,
|
||||
0x39cc: 0x0004, 0x39cd: 0x0004, 0x39ce: 0x0004, 0x39cf: 0x0004, 0x39d0: 0x0004, 0x39d1: 0x0004,
|
||||
0x39d2: 0x0004, 0x39d3: 0x0004, 0x39d4: 0x0004, 0x39d5: 0x0004, 0x39d6: 0x0004, 0x39d7: 0x0004,
|
||||
0x39d8: 0x0004, 0x39d9: 0x0004, 0x39da: 0x0004, 0x39db: 0x0004, 0x39dc: 0x0004, 0x39dd: 0x0004,
|
||||
0x39de: 0x0004, 0x39df: 0x0004, 0x39e0: 0x0004, 0x39e1: 0x0004, 0x39e2: 0x0004, 0x39e3: 0x0004,
|
||||
0x39e4: 0x0004, 0x39e5: 0x0004, 0x39e6: 0x0004, 0x39e7: 0x0004, 0x39e8: 0x0004, 0x39e9: 0x0004,
|
||||
0x39ea: 0x0004, 0x39eb: 0x0004, 0x39ec: 0x0004, 0x39ed: 0x0004, 0x39ee: 0x0004, 0x39ef: 0x0004,
|
||||
0x39f0: 0x0004, 0x39f1: 0x0004, 0x39f2: 0x0004, 0x39f3: 0x0004, 0x39f4: 0x0004, 0x39f5: 0x0004,
|
||||
0x39f6: 0x0004, 0x39f7: 0x0004, 0x39f8: 0x0004, 0x39f9: 0x0004, 0x39fa: 0x0004, 0x39fb: 0x0004,
|
||||
0x39fc: 0x0004, 0x39ff: 0x0004,
|
||||
0x39c0: 0x0002, 0x39c1: 0x0002, 0x39c2: 0x0002, 0x39c3: 0x0002, 0x39c4: 0x0002, 0x39c5: 0x0002,
|
||||
0x39c6: 0x0002, 0x39c7: 0x0002, 0x39c8: 0x0002, 0x39c9: 0x0002, 0x39ca: 0x0002, 0x39cb: 0x0002,
|
||||
0x39cc: 0x0002, 0x39cd: 0x0002, 0x39ce: 0x0002, 0x39cf: 0x0002, 0x39d0: 0x0002, 0x39d1: 0x0002,
|
||||
0x39d2: 0x0002, 0x39d3: 0x0002, 0x39d4: 0x0002, 0x39d5: 0x0002, 0x39d6: 0x0002, 0x39d7: 0x0002,
|
||||
0x39d8: 0x0002, 0x39d9: 0x0002, 0x39da: 0x0002, 0x39db: 0x0002, 0x39dc: 0x0002, 0x39dd: 0x0002,
|
||||
0x39de: 0x0002, 0x39df: 0x0002, 0x39e0: 0x0002, 0x39e1: 0x0002, 0x39e2: 0x0002, 0x39e3: 0x0002,
|
||||
0x39e4: 0x0002, 0x39e5: 0x0002, 0x39e6: 0x0002, 0x39e7: 0x0002, 0x39e8: 0x0002, 0x39e9: 0x0002,
|
||||
0x39ea: 0x0002, 0x39eb: 0x0002, 0x39ec: 0x0002, 0x39ed: 0x0002, 0x39ee: 0x0002, 0x39ef: 0x0002,
|
||||
0x39f0: 0x0002, 0x39f1: 0x0002, 0x39f2: 0x0002, 0x39f3: 0x0002, 0x39f4: 0x0002, 0x39f5: 0x0002,
|
||||
0x39f6: 0x0002, 0x39f7: 0x0002, 0x39f8: 0x0002, 0x39f9: 0x0002, 0x39fa: 0x0002, 0x39fb: 0x0002,
|
||||
0x39fc: 0x0002, 0x39ff: 0x0002,
|
||||
// Block 0xe8, offset 0x3a00
|
||||
0x3a00: 0x0004, 0x3a01: 0x0004, 0x3a02: 0x0004, 0x3a03: 0x0004, 0x3a04: 0x0004, 0x3a05: 0x0004,
|
||||
0x3a06: 0x0004, 0x3a07: 0x0004, 0x3a08: 0x0004, 0x3a09: 0x0004, 0x3a0a: 0x0004, 0x3a0b: 0x0004,
|
||||
0x3a0c: 0x0004, 0x3a0d: 0x0004, 0x3a0e: 0x0004, 0x3a0f: 0x0004, 0x3a10: 0x0004, 0x3a11: 0x0004,
|
||||
0x3a12: 0x0004, 0x3a13: 0x0004, 0x3a14: 0x0004, 0x3a15: 0x0004, 0x3a16: 0x0004, 0x3a17: 0x0004,
|
||||
0x3a18: 0x0004, 0x3a19: 0x0004, 0x3a1a: 0x0004, 0x3a1b: 0x0004, 0x3a1c: 0x0004, 0x3a1d: 0x0004,
|
||||
0x3a1e: 0x0004, 0x3a1f: 0x0004, 0x3a20: 0x0004, 0x3a21: 0x0004, 0x3a22: 0x0004, 0x3a23: 0x0004,
|
||||
0x3a24: 0x0004, 0x3a25: 0x0004, 0x3a26: 0x0004, 0x3a27: 0x0004, 0x3a28: 0x0004, 0x3a29: 0x0004,
|
||||
0x3a2a: 0x0004, 0x3a2b: 0x0004, 0x3a2c: 0x0004, 0x3a2d: 0x0004, 0x3a2e: 0x0004, 0x3a2f: 0x0004,
|
||||
0x3a30: 0x0004, 0x3a31: 0x0004, 0x3a32: 0x0004, 0x3a33: 0x0004, 0x3a34: 0x0004, 0x3a35: 0x0004,
|
||||
0x3a36: 0x0004, 0x3a37: 0x0004, 0x3a38: 0x0004, 0x3a39: 0x0004, 0x3a3a: 0x0004, 0x3a3b: 0x0004,
|
||||
0x3a3c: 0x0004, 0x3a3d: 0x0004,
|
||||
0x3a00: 0x0002, 0x3a01: 0x0002, 0x3a02: 0x0002, 0x3a03: 0x0002, 0x3a04: 0x0002, 0x3a05: 0x0002,
|
||||
0x3a06: 0x0002, 0x3a07: 0x0002, 0x3a08: 0x0002, 0x3a09: 0x0002, 0x3a0a: 0x0002, 0x3a0b: 0x0002,
|
||||
0x3a0c: 0x0002, 0x3a0d: 0x0002, 0x3a0e: 0x0002, 0x3a0f: 0x0002, 0x3a10: 0x0002, 0x3a11: 0x0002,
|
||||
0x3a12: 0x0002, 0x3a13: 0x0002, 0x3a14: 0x0002, 0x3a15: 0x0002, 0x3a16: 0x0002, 0x3a17: 0x0002,
|
||||
0x3a18: 0x0002, 0x3a19: 0x0002, 0x3a1a: 0x0002, 0x3a1b: 0x0002, 0x3a1c: 0x0002, 0x3a1d: 0x0002,
|
||||
0x3a1e: 0x0002, 0x3a1f: 0x0002, 0x3a20: 0x0002, 0x3a21: 0x0002, 0x3a22: 0x0002, 0x3a23: 0x0002,
|
||||
0x3a24: 0x0002, 0x3a25: 0x0002, 0x3a26: 0x0002, 0x3a27: 0x0002, 0x3a28: 0x0002, 0x3a29: 0x0002,
|
||||
0x3a2a: 0x0002, 0x3a2b: 0x0002, 0x3a2c: 0x0002, 0x3a2d: 0x0002, 0x3a2e: 0x0002, 0x3a2f: 0x0002,
|
||||
0x3a30: 0x0002, 0x3a31: 0x0002, 0x3a32: 0x0002, 0x3a33: 0x0002, 0x3a34: 0x0002, 0x3a35: 0x0002,
|
||||
0x3a36: 0x0002, 0x3a37: 0x0002, 0x3a38: 0x0002, 0x3a39: 0x0002, 0x3a3a: 0x0002, 0x3a3b: 0x0002,
|
||||
0x3a3c: 0x0002, 0x3a3d: 0x0002,
|
||||
// Block 0xe9, offset 0x3a40
|
||||
0x3a4b: 0x0004,
|
||||
0x3a4c: 0x0004, 0x3a4d: 0x0004, 0x3a4e: 0x0004, 0x3a50: 0x0004, 0x3a51: 0x0004,
|
||||
0x3a52: 0x0004, 0x3a53: 0x0004, 0x3a54: 0x0004, 0x3a55: 0x0004, 0x3a56: 0x0004, 0x3a57: 0x0004,
|
||||
0x3a58: 0x0004, 0x3a59: 0x0004, 0x3a5a: 0x0004, 0x3a5b: 0x0004, 0x3a5c: 0x0004, 0x3a5d: 0x0004,
|
||||
0x3a5e: 0x0004, 0x3a5f: 0x0004, 0x3a60: 0x0004, 0x3a61: 0x0004, 0x3a62: 0x0004, 0x3a63: 0x0004,
|
||||
0x3a64: 0x0004, 0x3a65: 0x0004, 0x3a66: 0x0004, 0x3a67: 0x0004,
|
||||
0x3a7a: 0x0004,
|
||||
0x3a4b: 0x0002,
|
||||
0x3a4c: 0x0002, 0x3a4d: 0x0002, 0x3a4e: 0x0002, 0x3a50: 0x0002, 0x3a51: 0x0002,
|
||||
0x3a52: 0x0002, 0x3a53: 0x0002, 0x3a54: 0x0002, 0x3a55: 0x0002, 0x3a56: 0x0002, 0x3a57: 0x0002,
|
||||
0x3a58: 0x0002, 0x3a59: 0x0002, 0x3a5a: 0x0002, 0x3a5b: 0x0002, 0x3a5c: 0x0002, 0x3a5d: 0x0002,
|
||||
0x3a5e: 0x0002, 0x3a5f: 0x0002, 0x3a60: 0x0002, 0x3a61: 0x0002, 0x3a62: 0x0002, 0x3a63: 0x0002,
|
||||
0x3a64: 0x0002, 0x3a65: 0x0002, 0x3a66: 0x0002, 0x3a67: 0x0002,
|
||||
0x3a7a: 0x0002,
|
||||
// Block 0xea, offset 0x3a80
|
||||
0x3a95: 0x0004, 0x3a96: 0x0004,
|
||||
0x3aa4: 0x0004,
|
||||
0x3a95: 0x0002, 0x3a96: 0x0002,
|
||||
0x3aa4: 0x0002,
|
||||
// Block 0xeb, offset 0x3ac0
|
||||
0x3afb: 0x0004,
|
||||
0x3afc: 0x0004, 0x3afd: 0x0004, 0x3afe: 0x0004, 0x3aff: 0x0004,
|
||||
0x3afb: 0x0002,
|
||||
0x3afc: 0x0002, 0x3afd: 0x0002, 0x3afe: 0x0002, 0x3aff: 0x0002,
|
||||
// Block 0xec, offset 0x3b00
|
||||
0x3b00: 0x0004, 0x3b01: 0x0004, 0x3b02: 0x0004, 0x3b03: 0x0004, 0x3b04: 0x0004, 0x3b05: 0x0004,
|
||||
0x3b06: 0x0004, 0x3b07: 0x0004, 0x3b08: 0x0004, 0x3b09: 0x0004, 0x3b0a: 0x0004, 0x3b0b: 0x0004,
|
||||
0x3b0c: 0x0004, 0x3b0d: 0x0004, 0x3b0e: 0x0004, 0x3b0f: 0x0004,
|
||||
0x3b00: 0x0002, 0x3b01: 0x0002, 0x3b02: 0x0002, 0x3b03: 0x0002, 0x3b04: 0x0002, 0x3b05: 0x0002,
|
||||
0x3b06: 0x0002, 0x3b07: 0x0002, 0x3b08: 0x0002, 0x3b09: 0x0002, 0x3b0a: 0x0002, 0x3b0b: 0x0002,
|
||||
0x3b0c: 0x0002, 0x3b0d: 0x0002, 0x3b0e: 0x0002, 0x3b0f: 0x0002,
|
||||
// Block 0xed, offset 0x3b40
|
||||
0x3b40: 0x0004, 0x3b41: 0x0004, 0x3b42: 0x0004, 0x3b43: 0x0004, 0x3b44: 0x0004, 0x3b45: 0x0004,
|
||||
0x3b4c: 0x0004, 0x3b50: 0x0004, 0x3b51: 0x0004,
|
||||
0x3b52: 0x0004, 0x3b55: 0x0004, 0x3b56: 0x0004, 0x3b57: 0x0004,
|
||||
0x3b5c: 0x0004, 0x3b5d: 0x0004,
|
||||
0x3b5e: 0x0004, 0x3b5f: 0x0004,
|
||||
0x3b6b: 0x0004, 0x3b6c: 0x0004,
|
||||
0x3b74: 0x0004, 0x3b75: 0x0004,
|
||||
0x3b76: 0x0004, 0x3b77: 0x0004, 0x3b78: 0x0004, 0x3b79: 0x0004, 0x3b7a: 0x0004, 0x3b7b: 0x0004,
|
||||
0x3b7c: 0x0004,
|
||||
0x3b40: 0x0002, 0x3b41: 0x0002, 0x3b42: 0x0002, 0x3b43: 0x0002, 0x3b44: 0x0002, 0x3b45: 0x0002,
|
||||
0x3b4c: 0x0002, 0x3b50: 0x0002, 0x3b51: 0x0002,
|
||||
0x3b52: 0x0002, 0x3b55: 0x0002, 0x3b56: 0x0002, 0x3b57: 0x0002,
|
||||
0x3b5c: 0x0002, 0x3b5d: 0x0002,
|
||||
0x3b5e: 0x0002, 0x3b5f: 0x0002,
|
||||
0x3b6b: 0x0002, 0x3b6c: 0x0002,
|
||||
0x3b74: 0x0002, 0x3b75: 0x0002,
|
||||
0x3b76: 0x0002, 0x3b77: 0x0002, 0x3b78: 0x0002, 0x3b79: 0x0002, 0x3b7a: 0x0002, 0x3b7b: 0x0002,
|
||||
0x3b7c: 0x0002,
|
||||
// Block 0xee, offset 0x3b80
|
||||
0x3ba0: 0x0004, 0x3ba1: 0x0004, 0x3ba2: 0x0004, 0x3ba3: 0x0004,
|
||||
0x3ba4: 0x0004, 0x3ba5: 0x0004, 0x3ba6: 0x0004, 0x3ba7: 0x0004, 0x3ba8: 0x0004, 0x3ba9: 0x0004,
|
||||
0x3baa: 0x0004, 0x3bab: 0x0004,
|
||||
0x3bb0: 0x0004,
|
||||
0x3ba0: 0x0002, 0x3ba1: 0x0002, 0x3ba2: 0x0002, 0x3ba3: 0x0002,
|
||||
0x3ba4: 0x0002, 0x3ba5: 0x0002, 0x3ba6: 0x0002, 0x3ba7: 0x0002, 0x3ba8: 0x0002, 0x3ba9: 0x0002,
|
||||
0x3baa: 0x0002, 0x3bab: 0x0002,
|
||||
0x3bb0: 0x0002,
|
||||
// Block 0xef, offset 0x3bc0
|
||||
0x3bcc: 0x0004, 0x3bcd: 0x0004, 0x3bce: 0x0004, 0x3bcf: 0x0004, 0x3bd0: 0x0004, 0x3bd1: 0x0004,
|
||||
0x3bd2: 0x0004, 0x3bd3: 0x0004, 0x3bd4: 0x0004, 0x3bd5: 0x0004, 0x3bd6: 0x0004, 0x3bd7: 0x0004,
|
||||
0x3bd8: 0x0004, 0x3bd9: 0x0004, 0x3bda: 0x0004, 0x3bdb: 0x0004, 0x3bdc: 0x0004, 0x3bdd: 0x0004,
|
||||
0x3bde: 0x0004, 0x3bdf: 0x0004, 0x3be0: 0x0004, 0x3be1: 0x0004, 0x3be2: 0x0004, 0x3be3: 0x0004,
|
||||
0x3be4: 0x0004, 0x3be5: 0x0004, 0x3be6: 0x0004, 0x3be7: 0x0004, 0x3be8: 0x0004, 0x3be9: 0x0004,
|
||||
0x3bea: 0x0004, 0x3beb: 0x0004, 0x3bec: 0x0004, 0x3bed: 0x0004, 0x3bee: 0x0004, 0x3bef: 0x0004,
|
||||
0x3bf0: 0x0004, 0x3bf1: 0x0004, 0x3bf2: 0x0004, 0x3bf3: 0x0004, 0x3bf4: 0x0004, 0x3bf5: 0x0004,
|
||||
0x3bf6: 0x0004, 0x3bf7: 0x0004, 0x3bf8: 0x0004, 0x3bf9: 0x0004, 0x3bfa: 0x0004,
|
||||
0x3bfc: 0x0004, 0x3bfd: 0x0004, 0x3bfe: 0x0004, 0x3bff: 0x0004,
|
||||
0x3bcc: 0x0002, 0x3bcd: 0x0002, 0x3bce: 0x0002, 0x3bcf: 0x0002, 0x3bd0: 0x0002, 0x3bd1: 0x0002,
|
||||
0x3bd2: 0x0002, 0x3bd3: 0x0002, 0x3bd4: 0x0002, 0x3bd5: 0x0002, 0x3bd6: 0x0002, 0x3bd7: 0x0002,
|
||||
0x3bd8: 0x0002, 0x3bd9: 0x0002, 0x3bda: 0x0002, 0x3bdb: 0x0002, 0x3bdc: 0x0002, 0x3bdd: 0x0002,
|
||||
0x3bde: 0x0002, 0x3bdf: 0x0002, 0x3be0: 0x0002, 0x3be1: 0x0002, 0x3be2: 0x0002, 0x3be3: 0x0002,
|
||||
0x3be4: 0x0002, 0x3be5: 0x0002, 0x3be6: 0x0002, 0x3be7: 0x0002, 0x3be8: 0x0002, 0x3be9: 0x0002,
|
||||
0x3bea: 0x0002, 0x3beb: 0x0002, 0x3bec: 0x0002, 0x3bed: 0x0002, 0x3bee: 0x0002, 0x3bef: 0x0002,
|
||||
0x3bf0: 0x0002, 0x3bf1: 0x0002, 0x3bf2: 0x0002, 0x3bf3: 0x0002, 0x3bf4: 0x0002, 0x3bf5: 0x0002,
|
||||
0x3bf6: 0x0002, 0x3bf7: 0x0002, 0x3bf8: 0x0002, 0x3bf9: 0x0002, 0x3bfa: 0x0002,
|
||||
0x3bfc: 0x0002, 0x3bfd: 0x0002, 0x3bfe: 0x0002, 0x3bff: 0x0002,
|
||||
// Block 0xf0, offset 0x3c00
|
||||
0x3c00: 0x0004, 0x3c01: 0x0004, 0x3c02: 0x0004, 0x3c03: 0x0004, 0x3c04: 0x0004, 0x3c05: 0x0004,
|
||||
0x3c07: 0x0004, 0x3c08: 0x0004, 0x3c09: 0x0004, 0x3c0a: 0x0004, 0x3c0b: 0x0004,
|
||||
0x3c0c: 0x0004, 0x3c0d: 0x0004, 0x3c0e: 0x0004, 0x3c0f: 0x0004, 0x3c10: 0x0004, 0x3c11: 0x0004,
|
||||
0x3c12: 0x0004, 0x3c13: 0x0004, 0x3c14: 0x0004, 0x3c15: 0x0004, 0x3c16: 0x0004, 0x3c17: 0x0004,
|
||||
0x3c18: 0x0004, 0x3c19: 0x0004, 0x3c1a: 0x0004, 0x3c1b: 0x0004, 0x3c1c: 0x0004, 0x3c1d: 0x0004,
|
||||
0x3c1e: 0x0004, 0x3c1f: 0x0004, 0x3c20: 0x0004, 0x3c21: 0x0004, 0x3c22: 0x0004, 0x3c23: 0x0004,
|
||||
0x3c24: 0x0004, 0x3c25: 0x0004, 0x3c26: 0x0004, 0x3c27: 0x0004, 0x3c28: 0x0004, 0x3c29: 0x0004,
|
||||
0x3c2a: 0x0004, 0x3c2b: 0x0004, 0x3c2c: 0x0004, 0x3c2d: 0x0004, 0x3c2e: 0x0004, 0x3c2f: 0x0004,
|
||||
0x3c30: 0x0004, 0x3c31: 0x0004, 0x3c32: 0x0004, 0x3c33: 0x0004, 0x3c34: 0x0004, 0x3c35: 0x0004,
|
||||
0x3c36: 0x0004, 0x3c37: 0x0004, 0x3c38: 0x0004, 0x3c39: 0x0004, 0x3c3a: 0x0004, 0x3c3b: 0x0004,
|
||||
0x3c3c: 0x0004, 0x3c3d: 0x0004, 0x3c3e: 0x0004, 0x3c3f: 0x0004,
|
||||
0x3c00: 0x0002, 0x3c01: 0x0002, 0x3c02: 0x0002, 0x3c03: 0x0002, 0x3c04: 0x0002, 0x3c05: 0x0002,
|
||||
0x3c07: 0x0002, 0x3c08: 0x0002, 0x3c09: 0x0002, 0x3c0a: 0x0002, 0x3c0b: 0x0002,
|
||||
0x3c0c: 0x0002, 0x3c0d: 0x0002, 0x3c0e: 0x0002, 0x3c0f: 0x0002, 0x3c10: 0x0002, 0x3c11: 0x0002,
|
||||
0x3c12: 0x0002, 0x3c13: 0x0002, 0x3c14: 0x0002, 0x3c15: 0x0002, 0x3c16: 0x0002, 0x3c17: 0x0002,
|
||||
0x3c18: 0x0002, 0x3c19: 0x0002, 0x3c1a: 0x0002, 0x3c1b: 0x0002, 0x3c1c: 0x0002, 0x3c1d: 0x0002,
|
||||
0x3c1e: 0x0002, 0x3c1f: 0x0002, 0x3c20: 0x0002, 0x3c21: 0x0002, 0x3c22: 0x0002, 0x3c23: 0x0002,
|
||||
0x3c24: 0x0002, 0x3c25: 0x0002, 0x3c26: 0x0002, 0x3c27: 0x0002, 0x3c28: 0x0002, 0x3c29: 0x0002,
|
||||
0x3c2a: 0x0002, 0x3c2b: 0x0002, 0x3c2c: 0x0002, 0x3c2d: 0x0002, 0x3c2e: 0x0002, 0x3c2f: 0x0002,
|
||||
0x3c30: 0x0002, 0x3c31: 0x0002, 0x3c32: 0x0002, 0x3c33: 0x0002, 0x3c34: 0x0002, 0x3c35: 0x0002,
|
||||
0x3c36: 0x0002, 0x3c37: 0x0002, 0x3c38: 0x0002, 0x3c39: 0x0002, 0x3c3a: 0x0002, 0x3c3b: 0x0002,
|
||||
0x3c3c: 0x0002, 0x3c3d: 0x0002, 0x3c3e: 0x0002, 0x3c3f: 0x0002,
|
||||
// Block 0xf1, offset 0x3c40
|
||||
0x3c70: 0x0004, 0x3c71: 0x0004, 0x3c72: 0x0004, 0x3c73: 0x0004, 0x3c74: 0x0004, 0x3c75: 0x0004,
|
||||
0x3c76: 0x0004, 0x3c77: 0x0004, 0x3c78: 0x0004, 0x3c79: 0x0004, 0x3c7a: 0x0004, 0x3c7b: 0x0004,
|
||||
0x3c7c: 0x0004,
|
||||
0x3c70: 0x0002, 0x3c71: 0x0002, 0x3c72: 0x0002, 0x3c73: 0x0002, 0x3c74: 0x0002, 0x3c75: 0x0002,
|
||||
0x3c76: 0x0002, 0x3c77: 0x0002, 0x3c78: 0x0002, 0x3c79: 0x0002, 0x3c7a: 0x0002, 0x3c7b: 0x0002,
|
||||
0x3c7c: 0x0002,
|
||||
// Block 0xf2, offset 0x3c80
|
||||
0x3c80: 0x0004, 0x3c81: 0x0004, 0x3c82: 0x0004, 0x3c83: 0x0004, 0x3c84: 0x0004, 0x3c85: 0x0004,
|
||||
0x3c86: 0x0004, 0x3c87: 0x0004, 0x3c88: 0x0004, 0x3c89: 0x0004,
|
||||
0x3c8f: 0x0004, 0x3c90: 0x0004, 0x3c91: 0x0004,
|
||||
0x3c92: 0x0004, 0x3c93: 0x0004, 0x3c94: 0x0004, 0x3c95: 0x0004, 0x3c96: 0x0004, 0x3c97: 0x0004,
|
||||
0x3c98: 0x0004, 0x3c99: 0x0004, 0x3c9a: 0x0004, 0x3c9b: 0x0004, 0x3c9c: 0x0004, 0x3c9d: 0x0004,
|
||||
0x3c9e: 0x0004, 0x3c9f: 0x0004, 0x3ca0: 0x0004, 0x3ca1: 0x0004, 0x3ca2: 0x0004, 0x3ca3: 0x0004,
|
||||
0x3ca4: 0x0004, 0x3ca5: 0x0004, 0x3ca6: 0x0004, 0x3ca7: 0x0004, 0x3ca8: 0x0004, 0x3ca9: 0x0004,
|
||||
0x3caa: 0x0004, 0x3cab: 0x0004, 0x3cac: 0x0004, 0x3cad: 0x0004, 0x3cae: 0x0004, 0x3caf: 0x0004,
|
||||
0x3cb0: 0x0004, 0x3cb1: 0x0004, 0x3cb2: 0x0004, 0x3cb3: 0x0004, 0x3cb4: 0x0004, 0x3cb5: 0x0004,
|
||||
0x3cb6: 0x0004, 0x3cb7: 0x0004, 0x3cb8: 0x0004, 0x3cb9: 0x0004, 0x3cba: 0x0004, 0x3cbb: 0x0004,
|
||||
0x3cbc: 0x0004, 0x3cbd: 0x0004, 0x3cbe: 0x0004, 0x3cbf: 0x0004,
|
||||
0x3c80: 0x0002, 0x3c81: 0x0002, 0x3c82: 0x0002, 0x3c83: 0x0002, 0x3c84: 0x0002, 0x3c85: 0x0002,
|
||||
0x3c86: 0x0002, 0x3c87: 0x0002, 0x3c88: 0x0002, 0x3c89: 0x0002,
|
||||
0x3c8f: 0x0002, 0x3c90: 0x0002, 0x3c91: 0x0002,
|
||||
0x3c92: 0x0002, 0x3c93: 0x0002, 0x3c94: 0x0002, 0x3c95: 0x0002, 0x3c96: 0x0002, 0x3c97: 0x0002,
|
||||
0x3c98: 0x0002, 0x3c99: 0x0002, 0x3c9a: 0x0002, 0x3c9b: 0x0002, 0x3c9c: 0x0002, 0x3c9d: 0x0002,
|
||||
0x3c9e: 0x0002, 0x3c9f: 0x0002, 0x3ca0: 0x0002, 0x3ca1: 0x0002, 0x3ca2: 0x0002, 0x3ca3: 0x0002,
|
||||
0x3ca4: 0x0002, 0x3ca5: 0x0002, 0x3ca6: 0x0002, 0x3ca7: 0x0002, 0x3ca8: 0x0002, 0x3ca9: 0x0002,
|
||||
0x3caa: 0x0002, 0x3cab: 0x0002, 0x3cac: 0x0002, 0x3cad: 0x0002, 0x3cae: 0x0002, 0x3caf: 0x0002,
|
||||
0x3cb0: 0x0002, 0x3cb1: 0x0002, 0x3cb2: 0x0002, 0x3cb3: 0x0002, 0x3cb4: 0x0002, 0x3cb5: 0x0002,
|
||||
0x3cb6: 0x0002, 0x3cb7: 0x0002, 0x3cb8: 0x0002, 0x3cb9: 0x0002, 0x3cba: 0x0002, 0x3cbb: 0x0002,
|
||||
0x3cbc: 0x0002, 0x3cbd: 0x0002, 0x3cbe: 0x0002, 0x3cbf: 0x0002,
|
||||
// Block 0xf3, offset 0x3cc0
|
||||
0x3cc0: 0x0004, 0x3cc1: 0x0004, 0x3cc2: 0x0004, 0x3cc3: 0x0004, 0x3cc4: 0x0004, 0x3cc5: 0x0004,
|
||||
0x3cc6: 0x0004,
|
||||
0x3cce: 0x0004, 0x3ccf: 0x0004, 0x3cd0: 0x0004, 0x3cd1: 0x0004,
|
||||
0x3cd2: 0x0004, 0x3cd3: 0x0004, 0x3cd4: 0x0004, 0x3cd5: 0x0004, 0x3cd6: 0x0004, 0x3cd7: 0x0004,
|
||||
0x3cd8: 0x0004, 0x3cd9: 0x0004, 0x3cda: 0x0004, 0x3cdb: 0x0004, 0x3cdc: 0x0004,
|
||||
0x3cdf: 0x0004, 0x3ce0: 0x0004, 0x3ce1: 0x0004, 0x3ce2: 0x0004, 0x3ce3: 0x0004,
|
||||
0x3ce4: 0x0004, 0x3ce5: 0x0004, 0x3ce6: 0x0004, 0x3ce7: 0x0004, 0x3ce8: 0x0004, 0x3ce9: 0x0004,
|
||||
0x3cf0: 0x0004, 0x3cf1: 0x0004, 0x3cf2: 0x0004, 0x3cf3: 0x0004, 0x3cf4: 0x0004, 0x3cf5: 0x0004,
|
||||
0x3cf6: 0x0004, 0x3cf7: 0x0004, 0x3cf8: 0x0004,
|
||||
0x3cc0: 0x0002, 0x3cc1: 0x0002, 0x3cc2: 0x0002, 0x3cc3: 0x0002, 0x3cc4: 0x0002, 0x3cc5: 0x0002,
|
||||
0x3cc6: 0x0002,
|
||||
0x3cce: 0x0002, 0x3ccf: 0x0002, 0x3cd0: 0x0002, 0x3cd1: 0x0002,
|
||||
0x3cd2: 0x0002, 0x3cd3: 0x0002, 0x3cd4: 0x0002, 0x3cd5: 0x0002, 0x3cd6: 0x0002, 0x3cd7: 0x0002,
|
||||
0x3cd8: 0x0002, 0x3cd9: 0x0002, 0x3cda: 0x0002, 0x3cdb: 0x0002, 0x3cdc: 0x0002,
|
||||
0x3cdf: 0x0002, 0x3ce0: 0x0002, 0x3ce1: 0x0002, 0x3ce2: 0x0002, 0x3ce3: 0x0002,
|
||||
0x3ce4: 0x0002, 0x3ce5: 0x0002, 0x3ce6: 0x0002, 0x3ce7: 0x0002, 0x3ce8: 0x0002, 0x3ce9: 0x0002,
|
||||
0x3cf0: 0x0002, 0x3cf1: 0x0002, 0x3cf2: 0x0002, 0x3cf3: 0x0002, 0x3cf4: 0x0002, 0x3cf5: 0x0002,
|
||||
0x3cf6: 0x0002, 0x3cf7: 0x0002, 0x3cf8: 0x0002,
|
||||
// Block 0xf4, offset 0x3d00
|
||||
0x3d00: 0x0002, 0x3d01: 0x0002, 0x3d02: 0x0002, 0x3d03: 0x0002, 0x3d04: 0x0002, 0x3d05: 0x0002,
|
||||
0x3d06: 0x0002, 0x3d07: 0x0002, 0x3d08: 0x0002, 0x3d09: 0x0002, 0x3d0a: 0x0002, 0x3d0b: 0x0002,
|
||||
0x3d0c: 0x0002, 0x3d0d: 0x0002, 0x3d0e: 0x0002, 0x3d0f: 0x0002, 0x3d10: 0x0002, 0x3d11: 0x0002,
|
||||
0x3d12: 0x0002, 0x3d13: 0x0002, 0x3d14: 0x0002, 0x3d15: 0x0002, 0x3d16: 0x0002, 0x3d17: 0x0002,
|
||||
0x3d18: 0x0002, 0x3d19: 0x0002, 0x3d1a: 0x0002, 0x3d1b: 0x0002, 0x3d1c: 0x0002, 0x3d1d: 0x0002,
|
||||
0x3d1e: 0x0002, 0x3d1f: 0x0002, 0x3d20: 0x0002, 0x3d21: 0x0002, 0x3d22: 0x0002, 0x3d23: 0x0002,
|
||||
0x3d24: 0x0002, 0x3d25: 0x0002, 0x3d26: 0x0002, 0x3d27: 0x0002, 0x3d28: 0x0002, 0x3d29: 0x0002,
|
||||
0x3d2a: 0x0002, 0x3d2b: 0x0002, 0x3d2c: 0x0002, 0x3d2d: 0x0002, 0x3d2e: 0x0002, 0x3d2f: 0x0002,
|
||||
0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002,
|
||||
0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002, 0x3d3a: 0x0002, 0x3d3b: 0x0002,
|
||||
0x3d3c: 0x0002, 0x3d3d: 0x0002,
|
||||
0x3d01: 0x0001,
|
||||
0x3d20: 0x0001, 0x3d21: 0x0001, 0x3d22: 0x0001, 0x3d23: 0x0001,
|
||||
0x3d24: 0x0001, 0x3d25: 0x0001, 0x3d26: 0x0001, 0x3d27: 0x0001, 0x3d28: 0x0001, 0x3d29: 0x0001,
|
||||
0x3d2a: 0x0001, 0x3d2b: 0x0001, 0x3d2c: 0x0001, 0x3d2d: 0x0001, 0x3d2e: 0x0001, 0x3d2f: 0x0001,
|
||||
0x3d30: 0x0001, 0x3d31: 0x0001, 0x3d32: 0x0001, 0x3d33: 0x0001, 0x3d34: 0x0001, 0x3d35: 0x0001,
|
||||
0x3d36: 0x0001, 0x3d37: 0x0001, 0x3d38: 0x0001, 0x3d39: 0x0001, 0x3d3a: 0x0001, 0x3d3b: 0x0001,
|
||||
0x3d3c: 0x0001, 0x3d3d: 0x0001, 0x3d3e: 0x0001, 0x3d3f: 0x0001,
|
||||
// Block 0xf5, offset 0x3d40
|
||||
0x3d41: 0x0001,
|
||||
0x3d60: 0x0001, 0x3d61: 0x0001, 0x3d62: 0x0001, 0x3d63: 0x0001,
|
||||
0x3d64: 0x0001, 0x3d65: 0x0001, 0x3d66: 0x0001, 0x3d67: 0x0001, 0x3d68: 0x0001, 0x3d69: 0x0001,
|
||||
0x3d6a: 0x0001, 0x3d6b: 0x0001, 0x3d6c: 0x0001, 0x3d6d: 0x0001, 0x3d6e: 0x0001, 0x3d6f: 0x0001,
|
||||
0x3d70: 0x0001, 0x3d71: 0x0001, 0x3d72: 0x0001, 0x3d73: 0x0001, 0x3d74: 0x0001, 0x3d75: 0x0001,
|
||||
0x3d76: 0x0001, 0x3d77: 0x0001, 0x3d78: 0x0001, 0x3d79: 0x0001, 0x3d7a: 0x0001, 0x3d7b: 0x0001,
|
||||
0x3d7c: 0x0001, 0x3d7d: 0x0001, 0x3d7e: 0x0001, 0x3d7f: 0x0001,
|
||||
// Block 0xf6, offset 0x3d80
|
||||
0x3d80: 0x0003, 0x3d81: 0x0003, 0x3d82: 0x0003, 0x3d83: 0x0003, 0x3d84: 0x0003, 0x3d85: 0x0003,
|
||||
0x3d86: 0x0003, 0x3d87: 0x0003, 0x3d88: 0x0003, 0x3d89: 0x0003, 0x3d8a: 0x0003, 0x3d8b: 0x0003,
|
||||
0x3d8c: 0x0003, 0x3d8d: 0x0003, 0x3d8e: 0x0003, 0x3d8f: 0x0003, 0x3d90: 0x0003, 0x3d91: 0x0003,
|
||||
0x3d92: 0x0003, 0x3d93: 0x0003, 0x3d94: 0x0003, 0x3d95: 0x0003, 0x3d96: 0x0003, 0x3d97: 0x0003,
|
||||
0x3d98: 0x0003, 0x3d99: 0x0003, 0x3d9a: 0x0003, 0x3d9b: 0x0003, 0x3d9c: 0x0003, 0x3d9d: 0x0003,
|
||||
0x3d9e: 0x0003, 0x3d9f: 0x0003, 0x3da0: 0x0003, 0x3da1: 0x0003, 0x3da2: 0x0003, 0x3da3: 0x0003,
|
||||
0x3da4: 0x0003, 0x3da5: 0x0003, 0x3da6: 0x0003, 0x3da7: 0x0003, 0x3da8: 0x0003, 0x3da9: 0x0003,
|
||||
0x3daa: 0x0003, 0x3dab: 0x0003, 0x3dac: 0x0003, 0x3dad: 0x0003, 0x3dae: 0x0003, 0x3daf: 0x0003,
|
||||
0x3db0: 0x0003, 0x3db1: 0x0003, 0x3db2: 0x0003, 0x3db3: 0x0003, 0x3db4: 0x0003, 0x3db5: 0x0003,
|
||||
0x3db6: 0x0003, 0x3db7: 0x0003, 0x3db8: 0x0003, 0x3db9: 0x0003, 0x3dba: 0x0003, 0x3dbb: 0x0003,
|
||||
0x3dbc: 0x0003, 0x3dbd: 0x0003,
|
||||
0x3d40: 0x0003, 0x3d41: 0x0003, 0x3d42: 0x0003, 0x3d43: 0x0003, 0x3d44: 0x0003, 0x3d45: 0x0003,
|
||||
0x3d46: 0x0003, 0x3d47: 0x0003, 0x3d48: 0x0003, 0x3d49: 0x0003, 0x3d4a: 0x0003, 0x3d4b: 0x0003,
|
||||
0x3d4c: 0x0003, 0x3d4d: 0x0003, 0x3d4e: 0x0003, 0x3d4f: 0x0003, 0x3d50: 0x0003, 0x3d51: 0x0003,
|
||||
0x3d52: 0x0003, 0x3d53: 0x0003, 0x3d54: 0x0003, 0x3d55: 0x0003, 0x3d56: 0x0003, 0x3d57: 0x0003,
|
||||
0x3d58: 0x0003, 0x3d59: 0x0003, 0x3d5a: 0x0003, 0x3d5b: 0x0003, 0x3d5c: 0x0003, 0x3d5d: 0x0003,
|
||||
0x3d5e: 0x0003, 0x3d5f: 0x0003, 0x3d60: 0x0003, 0x3d61: 0x0003, 0x3d62: 0x0003, 0x3d63: 0x0003,
|
||||
0x3d64: 0x0003, 0x3d65: 0x0003, 0x3d66: 0x0003, 0x3d67: 0x0003, 0x3d68: 0x0003, 0x3d69: 0x0003,
|
||||
0x3d6a: 0x0003, 0x3d6b: 0x0003, 0x3d6c: 0x0003, 0x3d6d: 0x0003, 0x3d6e: 0x0003, 0x3d6f: 0x0003,
|
||||
0x3d70: 0x0003, 0x3d71: 0x0003, 0x3d72: 0x0003, 0x3d73: 0x0003, 0x3d74: 0x0003, 0x3d75: 0x0003,
|
||||
0x3d76: 0x0003, 0x3d77: 0x0003, 0x3d78: 0x0003, 0x3d79: 0x0003, 0x3d7a: 0x0003, 0x3d7b: 0x0003,
|
||||
0x3d7c: 0x0003, 0x3d7d: 0x0003,
|
||||
}
|
||||
|
||||
// stringWidthIndex: 30 blocks, 1920 entries, 1920 bytes
|
||||
@@ -1673,11 +1653,11 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x593: 0xd4,
|
||||
0x5a3: 0xd5, 0x5a5: 0xd6,
|
||||
// Block 0x17, offset 0x5c0
|
||||
0x5c0: 0xd7, 0x5c3: 0xd8, 0x5c4: 0xd9, 0x5c5: 0xda, 0x5c6: 0xdb,
|
||||
0x5c8: 0xdc, 0x5c9: 0xdd, 0x5cc: 0xde, 0x5cd: 0xdf, 0x5ce: 0xe0, 0x5cf: 0xe1,
|
||||
0x5d0: 0xe2, 0x5d1: 0xe3, 0x5d2: 0xe4, 0x5d3: 0xe5, 0x5d4: 0xe6, 0x5d5: 0xe7, 0x5d6: 0xe8, 0x5d7: 0xe9,
|
||||
0x5d8: 0xe4, 0x5d9: 0xea, 0x5da: 0xe4, 0x5db: 0xeb, 0x5df: 0xec,
|
||||
0x5e4: 0xed, 0x5e5: 0xee, 0x5e6: 0xe4, 0x5e7: 0xe4,
|
||||
0x5c0: 0xd7, 0x5c3: 0xd8, 0x5c4: 0xd9, 0x5c5: 0xda, 0x5c6: 0xdb, 0x5c7: 0xdc,
|
||||
0x5c8: 0xdd, 0x5c9: 0xde, 0x5cc: 0xdf, 0x5cd: 0xe0, 0x5ce: 0xe1, 0x5cf: 0xe2,
|
||||
0x5d0: 0xe3, 0x5d1: 0xe4, 0x5d2: 0x39, 0x5d3: 0xe5, 0x5d4: 0xe6, 0x5d5: 0xe7, 0x5d6: 0xe8, 0x5d7: 0xe9,
|
||||
0x5d8: 0x39, 0x5d9: 0xea, 0x5da: 0x39, 0x5db: 0xeb, 0x5df: 0xec,
|
||||
0x5e4: 0xed, 0x5e5: 0xee, 0x5e6: 0x39, 0x5e7: 0x39,
|
||||
0x5e9: 0xef, 0x5ea: 0xf0, 0x5eb: 0xf1,
|
||||
// Block 0x18, offset 0x600
|
||||
0x600: 0x39, 0x601: 0x39, 0x602: 0x39, 0x603: 0x39, 0x604: 0x39, 0x605: 0x39, 0x606: 0x39, 0x607: 0x39,
|
||||
@@ -1687,7 +1667,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x620: 0x39, 0x621: 0x39, 0x622: 0x39, 0x623: 0x39, 0x624: 0x39, 0x625: 0x39, 0x626: 0x39, 0x627: 0x39,
|
||||
0x628: 0x39, 0x629: 0x39, 0x62a: 0x39, 0x62b: 0x39, 0x62c: 0x39, 0x62d: 0x39, 0x62e: 0x39, 0x62f: 0x39,
|
||||
0x630: 0x39, 0x631: 0x39, 0x632: 0x39, 0x633: 0x39, 0x634: 0x39, 0x635: 0x39, 0x636: 0x39, 0x637: 0x39,
|
||||
0x638: 0x39, 0x639: 0x39, 0x63a: 0x39, 0x63b: 0x39, 0x63c: 0x39, 0x63d: 0x39, 0x63e: 0x39, 0x63f: 0xf2,
|
||||
0x638: 0x39, 0x639: 0x39, 0x63a: 0x39, 0x63b: 0x39, 0x63c: 0x39, 0x63d: 0x39, 0x63e: 0x39, 0x63f: 0xe6,
|
||||
// Block 0x19, offset 0x640
|
||||
0x650: 0x0b, 0x651: 0x0c, 0x653: 0x0d, 0x656: 0x0e, 0x657: 0x06,
|
||||
0x658: 0x0f, 0x65a: 0x10, 0x65b: 0x11, 0x65c: 0x12, 0x65d: 0x13, 0x65e: 0x14, 0x65f: 0x15,
|
||||
@@ -1696,7 +1676,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x670: 0x06, 0x671: 0x06, 0x672: 0x06, 0x673: 0x06, 0x674: 0x06, 0x675: 0x06, 0x676: 0x06, 0x677: 0x06,
|
||||
0x678: 0x06, 0x679: 0x06, 0x67a: 0x06, 0x67b: 0x06, 0x67c: 0x06, 0x67d: 0x06, 0x67e: 0x06, 0x67f: 0x16,
|
||||
// Block 0x1a, offset 0x680
|
||||
0x680: 0xf3, 0x681: 0x08, 0x684: 0x08, 0x685: 0x08, 0x686: 0x08, 0x687: 0x09,
|
||||
0x680: 0xf2, 0x681: 0x08, 0x684: 0x08, 0x685: 0x08, 0x686: 0x08, 0x687: 0x09,
|
||||
// Block 0x1b, offset 0x6c0
|
||||
0x6c0: 0x5b, 0x6c1: 0x5b, 0x6c2: 0x5b, 0x6c3: 0x5b, 0x6c4: 0x5b, 0x6c5: 0x5b, 0x6c6: 0x5b, 0x6c7: 0x5b,
|
||||
0x6c8: 0x5b, 0x6c9: 0x5b, 0x6ca: 0x5b, 0x6cb: 0x5b, 0x6cc: 0x5b, 0x6cd: 0x5b, 0x6ce: 0x5b, 0x6cf: 0x5b,
|
||||
@@ -1705,7 +1685,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x6e0: 0x5b, 0x6e1: 0x5b, 0x6e2: 0x5b, 0x6e3: 0x5b, 0x6e4: 0x5b, 0x6e5: 0x5b, 0x6e6: 0x5b, 0x6e7: 0x5b,
|
||||
0x6e8: 0x5b, 0x6e9: 0x5b, 0x6ea: 0x5b, 0x6eb: 0x5b, 0x6ec: 0x5b, 0x6ed: 0x5b, 0x6ee: 0x5b, 0x6ef: 0x5b,
|
||||
0x6f0: 0x5b, 0x6f1: 0x5b, 0x6f2: 0x5b, 0x6f3: 0x5b, 0x6f4: 0x5b, 0x6f5: 0x5b, 0x6f6: 0x5b, 0x6f7: 0x5b,
|
||||
0x6f8: 0x5b, 0x6f9: 0x5b, 0x6fa: 0x5b, 0x6fb: 0x5b, 0x6fc: 0x5b, 0x6fd: 0x5b, 0x6fe: 0x5b, 0x6ff: 0xf4,
|
||||
0x6f8: 0x5b, 0x6f9: 0x5b, 0x6fa: 0x5b, 0x6fb: 0x5b, 0x6fc: 0x5b, 0x6fd: 0x5b, 0x6fe: 0x5b, 0x6ff: 0xf3,
|
||||
// Block 0x1c, offset 0x700
|
||||
0x720: 0x18,
|
||||
0x730: 0x09, 0x731: 0x09, 0x732: 0x09, 0x733: 0x09, 0x734: 0x09, 0x735: 0x09, 0x736: 0x09, 0x737: 0x09,
|
||||
|
||||
128
vendor/github.com/clipperhouse/displaywidth/width.go
generated
vendored
128
vendor/github.com/clipperhouse/displaywidth/width.go
generated
vendored
@@ -34,7 +34,7 @@ func (options Options) String(s string) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
width := 0
|
||||
@@ -60,7 +60,7 @@ func (options Options) Bytes(s []byte) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
width := 0
|
||||
@@ -90,7 +90,7 @@ func Rune(r rune) int {
|
||||
// Iterating over runes to measure width is incorrect in many cases.
|
||||
func (options Options) Rune(r rune) int {
|
||||
if r < utf8.RuneSelf {
|
||||
return int(asciiWidths[byte(r)])
|
||||
return asciiWidth(byte(r))
|
||||
}
|
||||
|
||||
// Surrogates (U+D800-U+DFFF) are invalid UTF-8.
|
||||
@@ -102,9 +102,11 @@ func (options Options) Rune(r rune) int {
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
|
||||
// Skip the grapheme iterator
|
||||
return lookupProperties(buf[:n]).width(options)
|
||||
return graphemeWidth(buf[:n], options)
|
||||
}
|
||||
|
||||
const _Default property = 0
|
||||
|
||||
// graphemeWidth returns the display width of a grapheme cluster.
|
||||
// The passed string must be a single grapheme cluster.
|
||||
func graphemeWidth[T stringish.Interface](s T, options Options) int {
|
||||
@@ -113,16 +115,39 @@ func graphemeWidth[T stringish.Interface](s T, options Options) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
return lookupProperties(s).width(options)
|
||||
p, sz := lookup(s)
|
||||
prop := property(p)
|
||||
|
||||
// Variation Selector 16 (VS16) requests emoji presentation
|
||||
if prop != _Wide && sz > 0 && len(s) >= sz+3 {
|
||||
vs := s[sz : sz+3]
|
||||
if isVS16(vs) {
|
||||
prop = _Wide
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to return the base
|
||||
// character's property.
|
||||
}
|
||||
|
||||
if options.EastAsianWidth && prop == _East_Asian_Ambiguous {
|
||||
prop = _Wide
|
||||
}
|
||||
|
||||
if prop > upperBound {
|
||||
prop = _Default
|
||||
}
|
||||
|
||||
return propertyWidths[prop]
|
||||
}
|
||||
|
||||
// isRIPrefix checks if the slice matches the Regional Indicator prefix
|
||||
// (F0 9F 87). It assumes len(s) >= 3.
|
||||
func isRIPrefix[T stringish.Interface](s T) bool {
|
||||
return s[0] == 0xF0 && s[1] == 0x9F && s[2] == 0x87
|
||||
func asciiWidth(b byte) int {
|
||||
if b <= 0x1F || b == 0x7F {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// isVS16 checks if the slice matches VS16 (U+FE0F) UTF-8 encoding
|
||||
@@ -131,81 +156,12 @@ func isVS16[T stringish.Interface](s T) bool {
|
||||
return s[0] == 0xEF && s[1] == 0xB8 && s[2] == 0x8F
|
||||
}
|
||||
|
||||
// lookupProperties returns the properties for a grapheme.
|
||||
// The passed string must be at least one byte long.
|
||||
//
|
||||
// Callers must handle zero and single-byte strings upstream, both as an
|
||||
// optimization, and to reduce the scope of this function.
|
||||
func lookupProperties[T stringish.Interface](s T) property {
|
||||
l := len(s)
|
||||
|
||||
if s[0] < utf8.RuneSelf {
|
||||
// Check for variation selector after ASCII (e.g., keycap sequences like 1️⃣)
|
||||
if l >= 4 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
vs := s[1:4]
|
||||
if isVS16(vs) {
|
||||
// VS16 requests emoji presentation (width 2)
|
||||
return _Emoji
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to _Default.
|
||||
}
|
||||
return asciiProperties[s[0]]
|
||||
}
|
||||
|
||||
// Regional indicator pair (flag)
|
||||
if l >= 8 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
ri := s[:8]
|
||||
// First rune
|
||||
if isRIPrefix(ri[0:3]) {
|
||||
b3 := ri[3]
|
||||
if b3 >= 0xA6 && b3 <= 0xBF {
|
||||
// Second rune
|
||||
if isRIPrefix(ri[4:7]) {
|
||||
b7 := ri[7]
|
||||
if b7 >= 0xA6 && b7 <= 0xBF {
|
||||
return _Emoji
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p, sz := lookup(s)
|
||||
|
||||
// Variation Selectors
|
||||
if sz > 0 && l >= sz+3 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
vs := s[sz : sz+3]
|
||||
if isVS16(vs) {
|
||||
// VS16 requests emoji presentation (width 2)
|
||||
return _Emoji
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to return the base
|
||||
// character's property.
|
||||
}
|
||||
|
||||
return property(p)
|
||||
// propertyWidths is a jump table of sorts, instead of a switch
|
||||
var propertyWidths = [4]int{
|
||||
_Default: 1,
|
||||
_Zero_Width: 0,
|
||||
_Wide: 2,
|
||||
_East_Asian_Ambiguous: 1,
|
||||
}
|
||||
|
||||
const _Default property = 0
|
||||
const boundsCheck = property(len(propertyWidths) - 1)
|
||||
|
||||
// width determines the display width of a character based on its properties,
|
||||
// and configuration options
|
||||
func (p property) width(options Options) int {
|
||||
if options.EastAsianWidth && p == _East_Asian_Ambiguous {
|
||||
return 2
|
||||
}
|
||||
|
||||
// Bounds check may help the compiler eliminate its bounds check,
|
||||
// and safety of course.
|
||||
if p > boundsCheck {
|
||||
return 1 // default width
|
||||
}
|
||||
|
||||
return propertyWidths[p]
|
||||
}
|
||||
const upperBound = property(len(propertyWidths) - 1)
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
@@ -26,5 +26,6 @@ _testmain.go
|
||||
coverage.out
|
||||
coverage.txt
|
||||
|
||||
# Exclude intellij IDE folders
|
||||
# Exclude IDE folders
|
||||
.idea/*
|
||||
.vscode/*
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
@@ -1,5 +1,5 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
# gazelle:prefix github.com/go-resty/resty/v2
|
||||
# gazelle:go_naming_convention import_alias
|
||||
@@ -9,6 +9,7 @@ go_library(
|
||||
name = "resty",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"digest.go",
|
||||
"middleware.go",
|
||||
"redirect.go",
|
||||
"request.go",
|
||||
@@ -18,11 +19,17 @@ go_library(
|
||||
"trace.go",
|
||||
"transport.go",
|
||||
"transport112.go",
|
||||
"transport_js.go",
|
||||
"transport_other.go",
|
||||
"util.go",
|
||||
"util_curl.go",
|
||||
],
|
||||
importpath = "github.com/go-resty/resty/v2",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
|
||||
deps = [
|
||||
"//shellescape",
|
||||
"@org_golang_x_net//publicsuffix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
@@ -31,6 +38,7 @@ go_test(
|
||||
"client_test.go",
|
||||
"context_test.go",
|
||||
"example_test.go",
|
||||
"middleware_test.go",
|
||||
"request_test.go",
|
||||
"resty_test.go",
|
||||
"retry_test.go",
|
||||
@@ -38,7 +46,10 @@ go_test(
|
||||
],
|
||||
data = glob([".testdata/*"]),
|
||||
embed = [":resty"],
|
||||
deps = ["@org_golang_x_net//proxy:go_default_library"],
|
||||
deps = [
|
||||
"@org_golang_x_net//proxy:go_default_library",
|
||||
"@org_golang_x_time//rate:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
|
||||
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
Copyright (c) 2015-2024 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
@@ -4,16 +4,12 @@
|
||||
<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.7.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<h4 align="center">Resty Communication Channels</h4>
|
||||
<p align="center"><a href="https://gitter.im/go_resty/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/go_resty/community.svg" alt="Chat on Gitter - Resty Community"></a> <a href="https://twitter.com/go_resty"><img src="https://img.shields.io/badge/twitter-@go__resty-55acee.svg" alt="Twitter @go_resty"></a></p>
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Av2"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg?branch=v2" alt="Build Status"></a> <a href="https://app.codecov.io/gh/go-resty/resty/tree/v2"><img src="https://codecov.io/gh/go-resty/resty/branch/v2/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.17.1-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
|
||||
## News
|
||||
|
||||
* v2.7.0 [released](https://github.com/go-resty/resty/releases/tag/v2.7.0) and tagged on Nov 03, 2021.
|
||||
* v2.17.1 [released](https://github.com/go-resty/resty/releases/tag/v2.17.1) and tagged on Dec 15, 2025.
|
||||
* v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
|
||||
* v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
|
||||
* v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
|
||||
@@ -62,9 +58,10 @@
|
||||
* goroutine concurrent safe
|
||||
* Resty Client trace, see [Client.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableTrace) and [Request.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableTrace)
|
||||
* Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute
|
||||
* Supports on-demand CURL command generation, see [Client.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableGenerateCurlOnDebug), [Request.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableGenerateCurlOnDebug). It requires debug mode to be enabled.
|
||||
* Debug mode - clean and informative logging presentation
|
||||
* Gzip - Go does it automatically also resty has fallback handling too
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`, also `HTTP/3` can be used with Resty, see this [comment](https://github.com/go-resty/resty/issues/846#issuecomment-2329696110)
|
||||
* [Bazel support](#bazel-support)
|
||||
* Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library)
|
||||
* Well tested client library
|
||||
@@ -86,6 +83,8 @@
|
||||
|
||||
#### Supported Go Versions
|
||||
|
||||
Recommended to use `go1.23` and above.
|
||||
|
||||
Initially Resty started supporting `go modules` since `v1.10.0` release.
|
||||
|
||||
Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
|
||||
@@ -99,8 +98,6 @@ Starting Resty v2 and higher versions, it fully embraces [go modules](https://gi
|
||||
|
||||
Resty author also published following projects for Go Community.
|
||||
|
||||
* [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework.
|
||||
* [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server.
|
||||
* [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`.
|
||||
|
||||
|
||||
@@ -108,7 +105,7 @@ Resty author also published following projects for Go Community.
|
||||
|
||||
```bash
|
||||
# Go Modules
|
||||
require github.com/go-resty/resty/v2 v2.7.0
|
||||
require github.com/go-resty/resty/v2 v2.16.5
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -265,7 +262,7 @@ resp, err := client.R().
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST of raw bytes for file upload. For example: upload file to Dropbox
|
||||
fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
|
||||
// See we are not setting content-type header, since go-resty automatically detects Content-Type for you
|
||||
resp, err := client.R().
|
||||
@@ -369,13 +366,13 @@ import jsoniter "github.com/json-iterator/go"
|
||||
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
client := resty.New()
|
||||
client.JSONMarshal = json.Marshal
|
||||
client.JSONUnmarshal = json.Unmarshal
|
||||
client := resty.New().
|
||||
SetJSONMarshaler(json.Marshal).
|
||||
SetJSONUnmarshaler(json.Unmarshal)
|
||||
|
||||
// similarly user could do for XML too with -
|
||||
client.XMLMarshal
|
||||
client.XMLUnmarshal
|
||||
client.SetXMLMarshaler(xml.Marshal).
|
||||
SetXMLUnmarshaler(xml.Unmarshal)
|
||||
```
|
||||
|
||||
### Multipart File(s) upload
|
||||
@@ -383,8 +380,8 @@ client.XMLUnmarshal
|
||||
#### Using io.Reader
|
||||
|
||||
```go
|
||||
profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt")
|
||||
profileImgBytes, _ := os.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := os.ReadFile("/Users/jeeva/text-file.txt")
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
@@ -475,7 +472,7 @@ resp, err := client.R().
|
||||
client := resty.New()
|
||||
|
||||
// Setting output directory path, If directory not exists then resty creates one!
|
||||
// This is optional one, if you're planning using absoule path in
|
||||
// This is optional one, if you're planning using absolute path in
|
||||
// `Request.SetOutput` and can used together.
|
||||
client.SetOutputDirectory("/Users/jeeva/Downloads")
|
||||
|
||||
@@ -556,6 +553,30 @@ client.OnError(func(req *resty.Request, err error) {
|
||||
})
|
||||
```
|
||||
|
||||
#### Generate CURL Command
|
||||
>Refer: [curl_cmd_test.go](https://github.com/go-resty/resty/blob/v2/curl_cmd_test.go)
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetDebug(true).
|
||||
EnableGenerateCurlOnDebug(). // CURL command generated when debug mode enabled with this option
|
||||
SetBody(map[string]string{"name": "Alex"}).
|
||||
Post("https://httpbin.org/post")
|
||||
|
||||
curlCmdExecuted := resp.Request.GenerateCurlCommand()
|
||||
|
||||
// Explore curl command
|
||||
fmt.Println("Curl Command:\n ", curlCmdExecuted+"\n")
|
||||
|
||||
/* Output
|
||||
Curl Command:
|
||||
curl -X POST -H 'Content-Type: application/json' -H 'User-Agent: go-resty/2.14.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' https://httpbin.org/post
|
||||
*/
|
||||
```
|
||||
|
||||
#### Redirect Policy
|
||||
|
||||
Resty provides few ready to use redirect policy(s) also it supports multiple policies together.
|
||||
@@ -635,7 +656,7 @@ client.SetCertificates(cert1, cert2, cert3)
|
||||
|
||||
```go
|
||||
// Custom Root certificates from string
|
||||
// You can pass you certificates throught env variables as strings
|
||||
// You can pass you certificates through env variables as strings
|
||||
// you can add one or more root certificates, its get appended
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
@@ -654,7 +675,7 @@ if err != nil {
|
||||
client.SetCertificates(cert1, cert2, cert3)
|
||||
```
|
||||
|
||||
#### Proxy Settings - Client as well as at Request Level
|
||||
#### Proxy Settings
|
||||
|
||||
Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`.
|
||||
Choose as per your need.
|
||||
@@ -700,8 +721,9 @@ client.
|
||||
})
|
||||
```
|
||||
|
||||
Above setup will result in resty retrying requests returned non nil error up to
|
||||
3 times with delay increased after each attempt.
|
||||
By default, resty will retry requests that return a non-nil error during execution.
|
||||
Therefore, the above setup will result in resty retrying requests with non-nil errors up to 3 times,
|
||||
with the delay increasing after each attempt.
|
||||
|
||||
You can optionally provide client with [custom retry conditions](https://pkg.go.dev/github.com/go-resty/resty/v2#RetryConditionFunc):
|
||||
|
||||
@@ -718,10 +740,26 @@ client.AddRetryCondition(
|
||||
)
|
||||
```
|
||||
|
||||
Above example will make resty retry requests ended with `429 Too Many Requests`
|
||||
status code.
|
||||
The above example will make resty retry requests that end with a `429 Too Many Requests` status code.
|
||||
It's important to note that when you specify conditions using `AddRetryCondition`,
|
||||
it will override the default retry behavior, which retries on errors encountered during the request.
|
||||
If you want to retry on errors encountered during the request, similar to the default behavior,
|
||||
you'll need to configure it as follows:
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.AddRetryCondition(
|
||||
func(r *resty.Response, err error) bool {
|
||||
// Including "err != nil" emulates the default retry behavior for errors encountered during the request.
|
||||
return err != nil || r.StatusCode() == http.StatusTooManyRequests
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Multiple retry conditions can be added.
|
||||
Note that if multiple conditions are specified, a retry will occur if any of the conditions are met.
|
||||
|
||||
It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios
|
||||
implemented. [Reference](retry_test.go).
|
||||
@@ -778,7 +816,7 @@ client.SetTimeout(1 * time.Minute)
|
||||
// You can override all below settings and options at request level if you want to
|
||||
//--------------------------------------------------------------------------------
|
||||
// Host URL for all request. So you can use relative URL in the request
|
||||
client.SetHostURL("http://httpbin.org")
|
||||
client.SetBaseURL("http://httpbin.org")
|
||||
|
||||
// Headers for all request
|
||||
client.SetHeader("Accept", "application/json")
|
||||
@@ -803,7 +841,7 @@ client.SetCookies(cookies)
|
||||
client.SetQueryParam("user_id", "00001")
|
||||
client.SetQueryParams(map[string]string{ // sample of those who use this manner
|
||||
"api_key": "api-key-here",
|
||||
"api_secert": "api-secert",
|
||||
"api_secret": "api-secret",
|
||||
})
|
||||
client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
|
||||
|
||||
@@ -842,10 +880,10 @@ client := resty.New()
|
||||
|
||||
// Set the previous transport that we created, set the scheme of the communication to the
|
||||
// socket and set the unixSocket as the HostURL.
|
||||
client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket)
|
||||
client.SetTransport(&transport).SetScheme("http").SetBaseURL(unixSocket)
|
||||
|
||||
// No need to write the host's URL on the request, just the path.
|
||||
client.R().Get("/index.html")
|
||||
client.R().Get("http://localhost/index.html")
|
||||
```
|
||||
|
||||
#### Bazel Support
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
@@ -4,10 +4,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b",
|
||||
sha256 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(version = "1.16")
|
||||
go_register_toolchains(version = "1.19")
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
|
||||
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2023 Segev Dagan (https://github.com/segevda)
|
||||
// 2024 Philipp Wolfer (https://github.com/phw)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDigestBadChallenge = errors.New("digest: challenge is bad")
|
||||
ErrDigestCharset = errors.New("digest: unsupported charset")
|
||||
ErrDigestAlgNotSupported = errors.New("digest: algorithm is not supported")
|
||||
ErrDigestQopNotSupported = errors.New("digest: no supported qop in list")
|
||||
ErrDigestNoQop = errors.New("digest: qop must be specified")
|
||||
)
|
||||
|
||||
var hashFuncs = map[string]func() hash.Hash{
|
||||
"": md5.New,
|
||||
"MD5": md5.New,
|
||||
"MD5-sess": md5.New,
|
||||
"SHA-256": sha256.New,
|
||||
"SHA-256-sess": sha256.New,
|
||||
"SHA-512-256": sha512.New,
|
||||
"SHA-512-256-sess": sha512.New,
|
||||
}
|
||||
|
||||
type digestCredentials struct {
|
||||
username, password string
|
||||
}
|
||||
|
||||
type digestTransport struct {
|
||||
digestCredentials
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (dt *digestTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
// Copy the request, so we don't modify the input.
|
||||
req2 := new(http.Request)
|
||||
*req2 = *req
|
||||
req2.Header = make(http.Header)
|
||||
for k, s := range req.Header {
|
||||
req2.Header[k] = s
|
||||
}
|
||||
|
||||
// Fix http: ContentLength=xxx with Body length 0
|
||||
if req2.Body == nil {
|
||||
req2.ContentLength = 0
|
||||
} else if req2.GetBody != nil {
|
||||
var err error
|
||||
req2.Body, err = req2.GetBody()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Make a request to get the 401 that contains the challenge.
|
||||
resp, err := dt.transport.RoundTrip(req)
|
||||
if err != nil || resp.StatusCode != http.StatusUnauthorized {
|
||||
return resp, err
|
||||
}
|
||||
chal := resp.Header.Get(hdrWwwAuthenticateKey)
|
||||
if chal == "" {
|
||||
return resp, ErrDigestBadChallenge
|
||||
}
|
||||
|
||||
c, err := parseChallenge(chal)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Form credentials based on the challenge
|
||||
cr := dt.newCredentials(req2, c)
|
||||
auth, err := cr.authorize()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Make authenticated request
|
||||
req2.Header.Set(hdrAuthorizationKey, auth)
|
||||
return dt.transport.RoundTrip(req2)
|
||||
}
|
||||
|
||||
func (dt *digestTransport) newCredentials(req *http.Request, c *challenge) *credentials {
|
||||
return &credentials{
|
||||
username: dt.username,
|
||||
userhash: c.userhash,
|
||||
realm: c.realm,
|
||||
nonce: c.nonce,
|
||||
digestURI: req.URL.RequestURI(),
|
||||
algorithm: c.algorithm,
|
||||
sessionAlg: strings.HasSuffix(c.algorithm, "-sess"),
|
||||
opaque: c.opaque,
|
||||
messageQop: c.qop,
|
||||
nc: 0,
|
||||
method: req.Method,
|
||||
password: dt.password,
|
||||
}
|
||||
}
|
||||
|
||||
type challenge struct {
|
||||
realm string
|
||||
domain string
|
||||
nonce string
|
||||
opaque string
|
||||
stale string
|
||||
algorithm string
|
||||
qop string
|
||||
userhash string
|
||||
}
|
||||
|
||||
func (c *challenge) setValue(k, v string) error {
|
||||
switch k {
|
||||
case "realm":
|
||||
c.realm = v
|
||||
case "domain":
|
||||
c.domain = v
|
||||
case "nonce":
|
||||
c.nonce = v
|
||||
case "opaque":
|
||||
c.opaque = v
|
||||
case "stale":
|
||||
c.stale = v
|
||||
case "algorithm":
|
||||
c.algorithm = v
|
||||
case "qop":
|
||||
c.qop = v
|
||||
case "charset":
|
||||
if strings.ToUpper(v) != "UTF-8" {
|
||||
return ErrDigestCharset
|
||||
}
|
||||
case "userhash":
|
||||
c.userhash = v
|
||||
default:
|
||||
return ErrDigestBadChallenge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseChallenge(input string) (*challenge, error) {
|
||||
const ws = " \n\r\t"
|
||||
s := strings.Trim(input, ws)
|
||||
if !strings.HasPrefix(s, "Digest ") {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
s = strings.Trim(s[7:], ws)
|
||||
c := &challenge{}
|
||||
b := strings.Builder{}
|
||||
key := ""
|
||||
quoted := false
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case '"':
|
||||
quoted = !quoted
|
||||
case ',':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = ""
|
||||
}
|
||||
case '=':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
key = strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
}
|
||||
default:
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
if quoted || (key == "" && b.Len() > 0) {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
if key != "" {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
username string
|
||||
userhash string
|
||||
realm string
|
||||
nonce string
|
||||
digestURI string
|
||||
algorithm string
|
||||
sessionAlg bool
|
||||
cNonce string
|
||||
opaque string
|
||||
messageQop string
|
||||
nc int
|
||||
method string
|
||||
password string
|
||||
}
|
||||
|
||||
func (c *credentials) authorize() (string, error) {
|
||||
if _, ok := hashFuncs[c.algorithm]; !ok {
|
||||
return "", ErrDigestAlgNotSupported
|
||||
}
|
||||
|
||||
if err := c.validateQop(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := c.resp()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sl := make([]string, 0, 10)
|
||||
if c.userhash == "true" {
|
||||
// RFC 7616 3.4.4
|
||||
c.username = c.h(fmt.Sprintf("%s:%s", c.username, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`userhash=%s`, c.userhash))
|
||||
}
|
||||
sl = append(sl, fmt.Sprintf(`username="%s"`, c.username))
|
||||
sl = append(sl, fmt.Sprintf(`realm="%s"`, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`nonce="%s"`, c.nonce))
|
||||
sl = append(sl, fmt.Sprintf(`uri="%s"`, c.digestURI))
|
||||
sl = append(sl, fmt.Sprintf(`response="%s"`, resp))
|
||||
sl = append(sl, fmt.Sprintf(`algorithm=%s`, c.algorithm))
|
||||
if c.opaque != "" {
|
||||
sl = append(sl, fmt.Sprintf(`opaque="%s"`, c.opaque))
|
||||
}
|
||||
if c.messageQop != "" {
|
||||
sl = append(sl, fmt.Sprintf("qop=%s", c.messageQop))
|
||||
sl = append(sl, fmt.Sprintf("nc=%08x", c.nc))
|
||||
sl = append(sl, fmt.Sprintf(`cnonce="%s"`, c.cNonce))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Digest %s", strings.Join(sl, ", ")), nil
|
||||
}
|
||||
|
||||
func (c *credentials) validateQop() error {
|
||||
// Currently only supporting auth quality of protection. TODO: add auth-int support
|
||||
// NOTE: cURL support auth-int qop for requests other than POST and PUT (i.e. w/o body) by hashing an empty string
|
||||
// is this applicable for resty? see: https://github.com/curl/curl/blob/307b7543ea1e73ab04e062bdbe4b5bb409eaba3a/lib/vauth/digest.c#L774
|
||||
if c.messageQop == "" {
|
||||
return ErrDigestNoQop
|
||||
}
|
||||
possibleQops := strings.Split(c.messageQop, ",")
|
||||
var authSupport bool
|
||||
for _, qop := range possibleQops {
|
||||
qop = strings.TrimSpace(qop)
|
||||
if qop == "auth" {
|
||||
authSupport = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !authSupport {
|
||||
return ErrDigestQopNotSupported
|
||||
}
|
||||
|
||||
c.messageQop = "auth"
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *credentials) h(data string) string {
|
||||
hfCtor := hashFuncs[c.algorithm]
|
||||
hf := hfCtor()
|
||||
_, _ = hf.Write([]byte(data)) // Hash.Write never returns an error
|
||||
return fmt.Sprintf("%x", hf.Sum(nil))
|
||||
}
|
||||
|
||||
func (c *credentials) resp() (string, error) {
|
||||
c.nc++
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := io.ReadFull(rand.Reader, b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.cNonce = fmt.Sprintf("%x", b)[:32]
|
||||
|
||||
ha1 := c.ha1()
|
||||
ha2 := c.ha2()
|
||||
|
||||
return c.kd(ha1, fmt.Sprintf("%s:%08x:%s:%s:%s",
|
||||
c.nonce, c.nc, c.cNonce, c.messageQop, ha2)), nil
|
||||
}
|
||||
|
||||
func (c *credentials) kd(secret, data string) string {
|
||||
return c.h(fmt.Sprintf("%s:%s", secret, data))
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.2
|
||||
func (c *credentials) ha1() string {
|
||||
ret := c.h(fmt.Sprintf("%s:%s:%s", c.username, c.realm, c.password))
|
||||
if c.sessionAlg {
|
||||
return c.h(fmt.Sprintf("%s:%s:%s", ret, c.nonce, c.cNonce))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.3
|
||||
func (c *credentials) ha2() string {
|
||||
// currently no auth-int support
|
||||
return c.h(fmt.Sprintf("%s:%s", c.method, c.digestURI))
|
||||
}
|
||||
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -27,15 +27,76 @@ const debugRequestLogKey = "__restyDebugRequestLog"
|
||||
//_______________________________________________________________________
|
||||
|
||||
func parseRequestURL(c *Client, r *Request) error {
|
||||
// GitHub #103 Path Params
|
||||
if len(r.PathParams) > 0 {
|
||||
if l := len(c.PathParams) + len(c.RawPathParams) + len(r.PathParams) + len(r.RawPathParams); l > 0 {
|
||||
params := make(map[string]string, l)
|
||||
|
||||
// GitHub #103 Path Params
|
||||
for p, v := range r.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
if len(c.PathParams) > 0 {
|
||||
for p, v := range c.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #663 Raw Path Params
|
||||
for p, v := range r.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
for p, v := range c.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
|
||||
if len(params) > 0 {
|
||||
var prev int
|
||||
buf := acquireBuffer()
|
||||
defer releaseBuffer(buf)
|
||||
// search for the next or first opened curly bracket
|
||||
for curr := strings.Index(r.URL, "{"); curr == 0 || curr >= prev; curr = prev + strings.Index(r.URL[prev:], "{") {
|
||||
// write everything from the previous position up to the current
|
||||
if curr > prev {
|
||||
buf.WriteString(r.URL[prev:curr])
|
||||
}
|
||||
// search for the closed curly bracket from current position
|
||||
next := curr + strings.Index(r.URL[curr:], "}")
|
||||
// if not found, then write the remainder and exit
|
||||
if next < curr {
|
||||
buf.WriteString(r.URL[curr:])
|
||||
prev = len(r.URL)
|
||||
break
|
||||
}
|
||||
// special case for {}, without parameter's name
|
||||
if next == curr+1 {
|
||||
buf.WriteString("{}")
|
||||
} else {
|
||||
// check for the replacement
|
||||
key := r.URL[curr+1 : next]
|
||||
value, ok := params[key]
|
||||
/// keep the original string if the replacement not found
|
||||
if !ok {
|
||||
value = r.URL[curr : next+1]
|
||||
}
|
||||
buf.WriteString(value)
|
||||
}
|
||||
|
||||
// set the previous position after the closed curly bracket
|
||||
prev = next + 1
|
||||
if prev >= len(r.URL) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 {
|
||||
// write remainder
|
||||
if prev < len(r.URL) {
|
||||
buf.WriteString(r.URL[prev:])
|
||||
}
|
||||
r.URL = buf.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +114,12 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
r.URL = "/" + r.URL
|
||||
}
|
||||
|
||||
reqURL, err = url.Parse(c.HostURL + r.URL)
|
||||
// TODO: change to use c.BaseURL only in v3.0.0
|
||||
baseURL := c.BaseURL
|
||||
if len(baseURL) == 0 {
|
||||
baseURL = c.HostURL
|
||||
}
|
||||
reqURL, err = url.Parse(baseURL + r.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,33 +131,36 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
// Adding Query Param
|
||||
query := make(url.Values)
|
||||
for k, v := range c.QueryParam {
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
if len(c.QueryParam)+len(r.QueryParam) > 0 {
|
||||
for k, v := range c.QueryParam {
|
||||
// skip query parameter if it was set in request
|
||||
if _, ok := r.QueryParam[k]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
r.QueryParam[k] = v[:]
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(r.QueryParam) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = r.QueryParam.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + r.QueryParam.Encode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.QueryParam {
|
||||
// remove query param from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
query.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(query) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = query.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
|
||||
}
|
||||
// GH#797 Unescape query parameters
|
||||
if r.unescapeQueryParams && len(reqURL.RawQuery) > 0 {
|
||||
// at this point, all errors caught up in the above operations
|
||||
// so ignore the return error on query unescape; I realized
|
||||
// while writing the unit test
|
||||
unescapedQuery, _ := url.QueryUnescape(reqURL.RawQuery)
|
||||
reqURL.RawQuery = strings.ReplaceAll(unescapedQuery, " ", "+") // otherwise request becomes bad request
|
||||
}
|
||||
|
||||
r.URL = reqURL.String()
|
||||
@@ -100,71 +169,61 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
func parseRequestHeader(c *Client, r *Request) error {
|
||||
hdr := make(http.Header)
|
||||
for k := range c.Header {
|
||||
hdr[k] = append(hdr[k], c.Header[k]...)
|
||||
for k, v := range c.Header {
|
||||
if _, ok := r.Header[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.Header[k] = v[:]
|
||||
}
|
||||
|
||||
for k := range r.Header {
|
||||
hdr.Del(k)
|
||||
hdr[k] = append(hdr[k], r.Header[k]...)
|
||||
if IsStringEmpty(r.Header.Get(hdrUserAgentKey)) {
|
||||
r.Header.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
}
|
||||
|
||||
if IsStringEmpty(hdr.Get(hdrUserAgentKey)) {
|
||||
hdr.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
if ct := r.Header.Get(hdrContentTypeKey); IsStringEmpty(r.Header.Get(hdrAcceptKey)) && !IsStringEmpty(ct) && (IsJSONType(ct) || IsXMLType(ct)) {
|
||||
r.Header.Set(hdrAcceptKey, r.Header.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
ct := hdr.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(hdr.Get(hdrAcceptKey)) && !IsStringEmpty(ct) &&
|
||||
(IsJSONType(ct) || IsXMLType(ct)) {
|
||||
hdr.Set(hdrAcceptKey, hdr.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
r.Header = hdr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRequestBody(c *Client, r *Request) (err error) {
|
||||
func parseRequestBody(c *Client, r *Request) error {
|
||||
if isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
// Handling Multipart
|
||||
if r.isMultiPart && !(r.Method == MethodPatch) {
|
||||
if err = handleMultipart(c, r); err != nil {
|
||||
return
|
||||
switch {
|
||||
case r.isMultiPart: // Handling Multipart
|
||||
if err := handleMultipart(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Form Data
|
||||
if len(c.FormData) > 0 || len(r.FormData) > 0 {
|
||||
case len(c.FormData) > 0 || len(r.FormData) > 0: // Handling Form Data
|
||||
handleFormData(c, r)
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Request body
|
||||
if r.Body != nil {
|
||||
case r.Body == nil && r.bodyBuf == nil: // Handling Request body when nil body
|
||||
// Go http library omits Content-Length if body is nil; use http.NoBody to force it if SetContentLength is true
|
||||
r.Body = http.NoBody
|
||||
fallthrough
|
||||
case r.Body != nil: // Handling Request body
|
||||
handleContentType(c, r)
|
||||
|
||||
if err = handleRequestBody(c, r); err != nil {
|
||||
return
|
||||
if err := handleRequestBody(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CL:
|
||||
// by default resty won't set content length, you can if you want to :)
|
||||
if (c.setContentLength || r.setContentLength) && r.bodyBuf != nil {
|
||||
r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len()))
|
||||
if c.setContentLength || r.setContentLength {
|
||||
if r.bodyBuf == nil {
|
||||
r.Header.Set(hdrContentLengthKey, "0")
|
||||
} else {
|
||||
r.Header.Set(hdrContentLengthKey, strconv.Itoa(r.bodyBuf.Len()))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
if r.bodyBuf == nil {
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
if reader, ok := r.Body.(io.Reader); ok && isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, reader)
|
||||
} else if c.setContentLength || r.setContentLength {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, http.NoBody)
|
||||
@@ -172,7 +231,9 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
|
||||
}
|
||||
} else {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
|
||||
// fix data race: must deep copy.
|
||||
bodyBuf := bytes.NewBuffer(append([]byte{}, r.bodyBuf.Bytes()...))
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, bodyBuf)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -206,17 +267,19 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest = r.RawRequest.WithContext(r.ctx)
|
||||
}
|
||||
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// assign get body func for the underlying raw request instance
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
if bodyCopy != nil {
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil
|
||||
if r.RawRequest.GetBody == nil {
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bodyCopy != nil {
|
||||
buf := bodyCopy.Bytes()
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
b := bytes.NewReader(buf)
|
||||
return io.NopCloser(b), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return
|
||||
@@ -235,43 +298,60 @@ func addCredentials(c *Client, r *Request) error {
|
||||
|
||||
if !c.DisableWarn {
|
||||
if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
|
||||
c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
r.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Authorization Header Scheme
|
||||
var authScheme string
|
||||
if !IsStringEmpty(r.AuthScheme) {
|
||||
authScheme = r.AuthScheme
|
||||
} else if !IsStringEmpty(c.AuthScheme) {
|
||||
authScheme = c.AuthScheme
|
||||
} else {
|
||||
authScheme = "Bearer"
|
||||
// Build the token Auth header
|
||||
if !IsStringEmpty(r.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+r.Token))
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+c.Token))
|
||||
}
|
||||
|
||||
// Build the Token Auth header
|
||||
if !IsStringEmpty(r.Token) { // takes precedence
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+r.Token)
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+c.Token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createCurlCmd(c *Client, r *Request) (err error) {
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
if r.resultCurlCmd == nil {
|
||||
r.resultCurlCmd = new(string)
|
||||
}
|
||||
*r.resultCurlCmd = buildCurlRequest(r.RawRequest, c.httpClient.Jar)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func requestLogger(c *Client, r *Request) error {
|
||||
if c.Debug {
|
||||
if r.Debug {
|
||||
rr := r.RawRequest
|
||||
rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
rh := copyHeaders(rr.Header)
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, cookie := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
s := fmt.Sprintf("%s=%s", cookie.Name, cookie.Value)
|
||||
if c := rh.Get("Cookie"); c != "" {
|
||||
rh.Set("Cookie", c+"; "+s)
|
||||
} else {
|
||||
rh.Set("Cookie", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
rl := &RequestLog{Header: rh, Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.requestLog != nil {
|
||||
if err := c.requestLog(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// fmt.Sprintf("COOKIES:\n%s\n", composeCookies(c.GetClient().Jar, *rr.URL)) +
|
||||
|
||||
reqLog := "\n==============================================================================\n" +
|
||||
"~~~ REQUEST ~~~\n" +
|
||||
reqLog := "\n==============================================================================\n"
|
||||
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
reqLog += "~~~ REQUEST(CURL) ~~~\n" +
|
||||
fmt.Sprintf(" %v\n", *r.resultCurlCmd)
|
||||
}
|
||||
|
||||
reqLog += "~~~ REQUEST ~~~\n" +
|
||||
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
|
||||
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
|
||||
fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) +
|
||||
@@ -290,7 +370,7 @@ func requestLogger(c *Client, r *Request) error {
|
||||
//_______________________________________________________________________
|
||||
|
||||
func responseLogger(c *Client, res *Response) error {
|
||||
if c.Debug {
|
||||
if res.Request.Debug {
|
||||
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.responseLog != nil {
|
||||
if err := c.responseLog(rl); err != nil {
|
||||
@@ -301,7 +381,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
debugLog := res.Request.values[debugRequestLogKey].(string)
|
||||
debugLog += "~~~ RESPONSE ~~~\n" +
|
||||
fmt.Sprintf("STATUS : %s\n", res.Status()) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.Proto()) +
|
||||
fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) +
|
||||
fmt.Sprintf("TIME DURATION: %v\n", res.Time()) +
|
||||
"HEADERS :\n" +
|
||||
@@ -313,7 +393,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
}
|
||||
debugLog += "==============================================================================\n"
|
||||
|
||||
c.log.Debugf("%s", debugLog)
|
||||
res.Request.log.Debugf("%s", debugLog)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -321,6 +401,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
|
||||
func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
if res.StatusCode() == http.StatusNoContent {
|
||||
res.Request.Error = nil
|
||||
return
|
||||
}
|
||||
// Handles only JSON or XML content type
|
||||
@@ -343,7 +424,10 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
}
|
||||
|
||||
if res.Request.Error != nil {
|
||||
err = Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
unmarshalErr := Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
if unmarshalErr != nil {
|
||||
c.log.Warnf("Cannot unmarshal response body: %s", unmarshalErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,13 +435,20 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func handleMultipart(c *Client, r *Request) (err error) {
|
||||
func handleMultipart(c *Client, r *Request) error {
|
||||
r.bodyBuf = acquireBuffer()
|
||||
w := multipart.NewWriter(r.bodyBuf)
|
||||
|
||||
// Set boundary if not set by user
|
||||
if r.multipartBoundary != "" {
|
||||
if err := w.SetBoundary(r.multipartBoundary); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -366,12 +457,11 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
for k, v := range r.FormData {
|
||||
for _, iv := range v {
|
||||
if strings.HasPrefix(k, "@") { // file
|
||||
err = addFile(w, k[1:], iv)
|
||||
if err != nil {
|
||||
return
|
||||
if err := addFile(w, k[1:], iv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else { // form value
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -379,55 +469,41 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
}
|
||||
|
||||
// #21 - adding io.Reader support
|
||||
if len(r.multipartFiles) > 0 {
|
||||
for _, f := range r.multipartFiles {
|
||||
err = addFileReader(w, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, f := range r.multipartFiles {
|
||||
if err := addFileReader(w, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #130 adding multipart field support with content type
|
||||
if len(r.multipartFields) > 0 {
|
||||
for _, mf := range r.multipartFields {
|
||||
if err = addMultipartFormField(w, mf); err != nil {
|
||||
return
|
||||
}
|
||||
for _, mf := range r.multipartFields {
|
||||
if err := addMultipartFormField(w, mf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Header.Set(hdrContentTypeKey, w.FormDataContentType())
|
||||
err = w.Close()
|
||||
|
||||
return
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
func handleFormData(c *Client, r *Request) {
|
||||
formData := url.Values{}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
if _, ok := r.FormData[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.FormData[k] = v[:]
|
||||
}
|
||||
|
||||
for k, v := range r.FormData {
|
||||
// remove form data field from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
formData.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode()))
|
||||
r.bodyBuf = acquireBuffer()
|
||||
r.bodyBuf.WriteString(r.FormData.Encode())
|
||||
r.Header.Set(hdrContentTypeKey, formContentType)
|
||||
r.isFormData = true
|
||||
}
|
||||
|
||||
func handleContentType(c *Client, r *Request) {
|
||||
if r.Body == http.NoBody {
|
||||
return
|
||||
}
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(contentType) {
|
||||
contentType = DetectContentType(r.Body)
|
||||
@@ -435,45 +511,42 @@ func handleContentType(c *Client, r *Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
func handleRequestBody(c *Client, r *Request) error {
|
||||
var bodyBytes []byte
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
r.bodyBuf = nil
|
||||
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
switch body := r.Body.(type) {
|
||||
case io.Reader:
|
||||
if c.setContentLength || r.setContentLength { // keep backward compatibility
|
||||
r.bodyBuf = acquireBuffer()
|
||||
_, err = r.bodyBuf.ReadFrom(reader)
|
||||
if _, err := r.bodyBuf.ReadFrom(body); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Body = nil
|
||||
} else {
|
||||
// Otherwise buffer less processing for `io.Reader`, sounds good.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
} else if b, ok := r.Body.([]byte); ok {
|
||||
bodyBytes = b
|
||||
} else if s, ok := r.Body.(string); ok {
|
||||
bodyBytes = []byte(s)
|
||||
} else if IsJSONType(contentType) &&
|
||||
(kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
case []byte:
|
||||
bodyBytes = body
|
||||
case string:
|
||||
bodyBytes = []byte(body)
|
||||
default:
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
var err error
|
||||
if IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
}
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if bodyBytes == nil && r.bodyBuf == nil {
|
||||
err = errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// if any errors during body bytes handling, return it
|
||||
if err != nil {
|
||||
return
|
||||
return errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// []byte into Buffer
|
||||
@@ -482,7 +555,7 @@ func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
_, _ = r.bodyBuf.Write(bodyBytes)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
@@ -521,20 +594,25 @@ func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
func getBodyCopy(r *Request) (*bytes.Buffer, error) {
|
||||
// If r.bodyBuf present, return the copy
|
||||
if r.bodyBuf != nil {
|
||||
return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
|
||||
bodyCopy := acquireBuffer()
|
||||
if _, err := io.Copy(bodyCopy, bytes.NewReader(r.bodyBuf.Bytes())); err != nil {
|
||||
// cannot use io.Copy(bodyCopy, r.bodyBuf) because io.Copy reset r.bodyBuf
|
||||
return nil, err
|
||||
}
|
||||
return bodyCopy, nil
|
||||
}
|
||||
|
||||
// Maybe body is `io.Reader`.
|
||||
// Note: Resty user have to watchout for large body size of `io.Reader`
|
||||
if r.RawRequest.Body != nil {
|
||||
b, err := ioutil.ReadAll(r.RawRequest.Body)
|
||||
b, err := io.ReadAll(r.RawRequest.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Restore the Body
|
||||
closeq(r.RawRequest.Body)
|
||||
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
||||
r.RawRequest.Body = io.NopCloser(bytes.NewBuffer(b))
|
||||
|
||||
// Return the Body bytes
|
||||
return bytes.NewBuffer(b), nil
|
||||
|
||||
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -12,18 +12,23 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAutoRedirectDisabled = errors.New("auto redirect is disabled")
|
||||
)
|
||||
|
||||
type (
|
||||
// RedirectPolicy to regulate the redirects in the resty client.
|
||||
// Objects implementing the RedirectPolicy interface can be registered as
|
||||
// RedirectPolicy to regulate the redirects in the Resty client.
|
||||
// Objects implementing the [RedirectPolicy] interface can be registered as
|
||||
//
|
||||
// Apply function should return nil to continue the redirect jounery, otherwise
|
||||
// Apply function should return nil to continue the redirect journey; otherwise
|
||||
// return error to stop the redirect.
|
||||
RedirectPolicy interface {
|
||||
Apply(req *http.Request, via []*http.Request) error
|
||||
}
|
||||
|
||||
// The RedirectPolicyFunc type is an adapter to allow the use of ordinary functions as RedirectPolicy.
|
||||
// If f is a function with the appropriate signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls f.
|
||||
// The [RedirectPolicyFunc] type is an adapter to allow the use of ordinary
|
||||
// functions as [RedirectPolicy]. If `f` is a function with the appropriate
|
||||
// signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls `f`.
|
||||
RedirectPolicyFunc func(*http.Request, []*http.Request) error
|
||||
)
|
||||
|
||||
@@ -32,16 +37,18 @@ func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Request) error
|
||||
return f(req, via)
|
||||
}
|
||||
|
||||
// NoRedirectPolicy is used to disable redirects in the HTTP client
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
// NoRedirectPolicy is used to disable redirects in the Resty client
|
||||
//
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
func NoRedirectPolicy() RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return errors.New("auto redirect is disabled")
|
||||
return ErrAutoRedirectDisabled
|
||||
})
|
||||
}
|
||||
|
||||
// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client.
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
// FlexibleRedirectPolicy method is convenient for creating several redirect policies for Resty clients.
|
||||
//
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= noOfRedirect {
|
||||
@@ -52,9 +59,10 @@ func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
})
|
||||
}
|
||||
|
||||
// DomainCheckRedirectPolicy is convenient method to define domain name redirect rule in resty client.
|
||||
// Redirect is allowed for only mentioned host in the policy.
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
// DomainCheckRedirectPolicy method is convenient for defining domain name redirect rules in Resty clients.
|
||||
// Redirect is allowed only for the host mentioned in the policy.
|
||||
//
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
hosts := make(map[string]bool)
|
||||
for _, h := range hostnames {
|
||||
@@ -72,10 +80,6 @@ func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
return fn
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func getHostname(host string) (hostname string) {
|
||||
if strings.Index(host, ":") > 0 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
@@ -84,10 +88,11 @@ func getHostname(host string) (hostname string) {
|
||||
return
|
||||
}
|
||||
|
||||
// By default Golang will not redirect request headers
|
||||
// after go throughing various discussion comments from thread
|
||||
// By default, Golang will not redirect request headers.
|
||||
// After reading through the various discussion comments from the thread -
|
||||
// https://github.com/golang/go/issues/4800
|
||||
// Resty will add all the headers during a redirect for the same host
|
||||
// Resty will add all the headers during a redirect for the same host and
|
||||
// adds library user-agent if the Host is different.
|
||||
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
|
||||
curHostname := getHostname(cur.URL.Host)
|
||||
preHostname := getHostname(pre.URL.Host)
|
||||
|
||||
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
File diff suppressed because it is too large
Load Diff
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// Response struct and methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Response struct holds response values of executed request.
|
||||
// Response struct holds response values of executed requests.
|
||||
type Response struct {
|
||||
Request *Request
|
||||
RawResponse *http.Response
|
||||
@@ -27,9 +27,10 @@ type Response struct {
|
||||
receivedAt time.Time
|
||||
}
|
||||
|
||||
// Body method returns HTTP response as []byte array for the executed request.
|
||||
// Body method returns the HTTP response as `[]byte` slice for the executed request.
|
||||
//
|
||||
// Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
|
||||
// NOTE: [Response.Body] might be nil if [Request.SetOutput] is used.
|
||||
// Also see [Request.SetDoNotParseResponse], [Client.SetDoNotParseResponse]
|
||||
func (r *Response) Body() []byte {
|
||||
if r.RawResponse == nil {
|
||||
return []byte{}
|
||||
@@ -37,7 +38,18 @@ func (r *Response) Body() []byte {
|
||||
return r.body
|
||||
}
|
||||
|
||||
// SetBody method sets [Response] body in byte slice. Typically,
|
||||
// It is helpful for test cases.
|
||||
//
|
||||
// resp.SetBody([]byte("This is test body content"))
|
||||
// resp.SetBody(nil)
|
||||
func (r *Response) SetBody(b []byte) *Response {
|
||||
r.body = b
|
||||
return r
|
||||
}
|
||||
|
||||
// Status method returns the HTTP status string for the executed request.
|
||||
//
|
||||
// Example: 200 OK
|
||||
func (r *Response) Status() string {
|
||||
if r.RawResponse == nil {
|
||||
@@ -47,6 +59,7 @@ func (r *Response) Status() string {
|
||||
}
|
||||
|
||||
// StatusCode method returns the HTTP status code for the executed request.
|
||||
//
|
||||
// Example: 200
|
||||
func (r *Response) StatusCode() int {
|
||||
if r.RawResponse == nil {
|
||||
@@ -64,11 +77,15 @@ func (r *Response) Proto() string {
|
||||
}
|
||||
|
||||
// Result method returns the response value as an object if it has one
|
||||
//
|
||||
// See [Request.SetResult]
|
||||
func (r *Response) Result() interface{} {
|
||||
return r.Request.Result
|
||||
}
|
||||
|
||||
// Error method returns the error object if it has one
|
||||
//
|
||||
// See [Request.SetError], [Client.SetError]
|
||||
func (r *Response) Error() interface{} {
|
||||
return r.Request.Error
|
||||
}
|
||||
@@ -81,7 +98,7 @@ func (r *Response) Header() http.Header {
|
||||
return r.RawResponse.Header
|
||||
}
|
||||
|
||||
// Cookies method to access all the response cookies
|
||||
// Cookies method to returns all the response cookies
|
||||
func (r *Response) Cookies() []*http.Cookie {
|
||||
if r.RawResponse == nil {
|
||||
return make([]*http.Cookie, 0)
|
||||
@@ -89,18 +106,20 @@ func (r *Response) Cookies() []*http.Cookie {
|
||||
return r.RawResponse.Cookies()
|
||||
}
|
||||
|
||||
// String method returns the body of the server response as String.
|
||||
// String method returns the body of the HTTP response as a `string`.
|
||||
// It returns an empty string if it is nil or the body is zero length.
|
||||
func (r *Response) String() string {
|
||||
if r.body == nil {
|
||||
if len(r.body) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(r.body))
|
||||
}
|
||||
|
||||
// Time method returns the time of HTTP response time that from request we sent and received a request.
|
||||
// Time method returns the duration of HTTP response time from the request we sent
|
||||
// and received a request.
|
||||
//
|
||||
// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
|
||||
// when client sent a request.
|
||||
// See [Response.ReceivedAt] to know when the client received a response and see
|
||||
// `Response.Request.Time` to know when the client sent a request.
|
||||
func (r *Response) Time() time.Duration {
|
||||
if r.Request.clientTrace != nil {
|
||||
return r.Request.TraceInfo().TotalTime
|
||||
@@ -108,23 +127,25 @@ func (r *Response) Time() time.Duration {
|
||||
return r.receivedAt.Sub(r.Request.Time)
|
||||
}
|
||||
|
||||
// ReceivedAt method returns when response got received from server for the request.
|
||||
// ReceivedAt method returns the time we received a response from the server for the request.
|
||||
func (r *Response) ReceivedAt() time.Time {
|
||||
return r.receivedAt
|
||||
}
|
||||
|
||||
// Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header,
|
||||
// however it won't be good for chucked transfer/compressed response. Since Resty calculates response size
|
||||
// at the client end. You will get actual size of the http response.
|
||||
// Size method returns the HTTP response size in bytes. Yeah, you can rely on HTTP `Content-Length`
|
||||
// header, however it won't be available for chucked transfer/compressed response.
|
||||
// Since Resty captures response size details when processing the response body
|
||||
// when possible. So that users get the actual size of response bytes.
|
||||
func (r *Response) Size() int64 {
|
||||
return r.size
|
||||
}
|
||||
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse`
|
||||
// option otherwise you get an error as `read err: http: read on closed response body`.
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in conjunction with
|
||||
// [Client.SetDoNotParseResponse] or [Request.SetDoNotParseResponse]
|
||||
// option; otherwise, you get an error as `read err: http: read on closed response body.`
|
||||
//
|
||||
// Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse.
|
||||
// Basically you have taken over the control of response parsing from `Resty`.
|
||||
// You have taken over the control of response parsing from Resty.
|
||||
func (r *Response) RawBody() io.ReadCloser {
|
||||
if r.RawResponse == nil {
|
||||
return nil
|
||||
@@ -142,10 +163,6 @@ func (r *Response) IsError() bool {
|
||||
return r.StatusCode() > 399
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (r *Response) setReceivedAt() {
|
||||
r.receivedAt = time.Now()
|
||||
if r.Request.clientTrace != nil {
|
||||
@@ -154,7 +171,10 @@ func (r *Response) setReceivedAt() {
|
||||
}
|
||||
|
||||
func (r *Response) fmtBodyString(sl int64) string {
|
||||
if r.body != nil {
|
||||
if r.Request.client.notParseResponse || r.Request.notParseResponse {
|
||||
return "***** DO NOT PARSE RESPONSE - Enabled *****"
|
||||
}
|
||||
if len(r.body) > 0 {
|
||||
if int64(len(r.body)) > sl {
|
||||
return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// Version # of resty
|
||||
const Version = "2.7.0"
|
||||
const Version = "2.17.1"
|
||||
|
||||
// New method creates a new Resty client.
|
||||
func New() *Client {
|
||||
@@ -24,12 +24,12 @@ func New() *Client {
|
||||
})
|
||||
}
|
||||
|
||||
// NewWithClient method creates a new Resty client with given `http.Client`.
|
||||
// NewWithClient method creates a new Resty client with given [http.Client].
|
||||
func NewWithClient(hc *http.Client) *Client {
|
||||
return createClient(hc)
|
||||
}
|
||||
|
||||
// NewWithLocalAddr method creates a new Resty client with given Local Address
|
||||
// NewWithLocalAddr method creates a new Resty client with the given Local Address.
|
||||
// to dial from.
|
||||
func NewWithLocalAddr(localAddr net.Addr) *Client {
|
||||
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
|
||||
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync"
|
||||
@@ -22,7 +23,7 @@ type (
|
||||
// Option is to create convenient retry options like wait time, max retries, etc.
|
||||
Option func(*Options)
|
||||
|
||||
// RetryConditionFunc type is for retry condition function
|
||||
// RetryConditionFunc type is for the retry condition function
|
||||
// input: non-nil Response OR request execution error
|
||||
RetryConditionFunc func(*Response, error) bool
|
||||
|
||||
@@ -32,8 +33,8 @@ type (
|
||||
// RetryAfterFunc returns time to wait before retry
|
||||
// For example, it can parse HTTP Retry-After header
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
// Non-nil error is returned if it is found that request is not retryable
|
||||
// (0, nil) is a special result means 'use default algorithm'
|
||||
// Non-nil error is returned if it is found that the request is not retryable
|
||||
// (0, nil) is a special result that means 'use default algorithm'
|
||||
RetryAfterFunc func(*Client, *Response) (time.Duration, error)
|
||||
|
||||
// Options struct is used to hold retry settings.
|
||||
@@ -43,6 +44,7 @@ type (
|
||||
maxWaitTime time.Duration
|
||||
retryConditions []RetryConditionFunc
|
||||
retryHooks []OnRetryFunc
|
||||
resetReaders bool
|
||||
}
|
||||
)
|
||||
|
||||
@@ -67,7 +69,7 @@ func MaxWaitTime(value time.Duration) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// RetryConditions sets the conditions that will be checked for retry.
|
||||
// RetryConditions sets the conditions that will be checked for retry
|
||||
func RetryConditions(conditions []RetryConditionFunc) Option {
|
||||
return func(o *Options) {
|
||||
o.retryConditions = conditions
|
||||
@@ -81,6 +83,14 @@ func RetryHooks(hooks []OnRetryFunc) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// ResetMultipartReaders sets a boolean value which will lead the start being seeked out
|
||||
// on all multipart file readers if they implement [io.ReadSeeker]
|
||||
func ResetMultipartReaders(value bool) Option {
|
||||
return func(o *Options) {
|
||||
o.resetReaders = value
|
||||
}
|
||||
}
|
||||
|
||||
// Backoff retries with increasing timeout duration up until X amount of retries
|
||||
// (Default is 3 attempts, Override with option Retries(n))
|
||||
func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
@@ -125,6 +135,15 @@ func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.resetReaders {
|
||||
if err := resetFileReaders(resp.Request.multipartFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := resetFieldReaders(resp.Request.multipartFields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, hook := range opts.retryHooks {
|
||||
hook(resp, err)
|
||||
}
|
||||
@@ -186,13 +205,16 @@ func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Du
|
||||
}
|
||||
|
||||
// Return capped exponential backoff with jitter
|
||||
// http://www.awsarchitectureblog.com/2015/03/backoff.html
|
||||
// https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
||||
func jitterBackoff(min, max time.Duration, attempt int) time.Duration {
|
||||
base := float64(min)
|
||||
capLevel := float64(max)
|
||||
|
||||
temp := math.Min(capLevel, base*math.Exp2(float64(attempt)))
|
||||
ri := time.Duration(temp / 2)
|
||||
if ri == 0 {
|
||||
ri = time.Nanosecond
|
||||
}
|
||||
result := randDuration(ri)
|
||||
|
||||
if result < min {
|
||||
@@ -219,3 +241,27 @@ func newRnd() *rand.Rand {
|
||||
var src = rand.NewSource(seed)
|
||||
return rand.New(src)
|
||||
}
|
||||
|
||||
func resetFileReaders(files []*File) error {
|
||||
for _, f := range files {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resetFieldReaders(fields []*MultipartField) error {
|
||||
for _, f := range fields {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "shellescape",
|
||||
srcs = ["shellescape.go"],
|
||||
importpath = "github.com/go-resty/resty/v2/shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "go_default_library",
|
||||
actual = ":shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-present Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2024 Ahuigo (https://github.com/ahuigo)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package shellescape provides the methods to escape arbitrary
|
||||
strings for a safe use as command line arguments in the most common
|
||||
POSIX shells.
|
||||
|
||||
The original Python package which this work was inspired by can be found
|
||||
at https://pypi.python.org/pypi/shellescape.
|
||||
*/
|
||||
package shellescape
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var pattern *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
pattern = regexp.MustCompile(`[^\w@%+=:,./-]`)
|
||||
}
|
||||
|
||||
// Quote method returns a shell-escaped version of the string. The returned value
|
||||
// can safely be used as one token in a shell command line.
|
||||
func Quote(s string) string {
|
||||
if len(s) == 0 {
|
||||
return "''"
|
||||
}
|
||||
|
||||
if pattern.MatchString(s) {
|
||||
return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http/httptrace"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,32 +17,30 @@ import (
|
||||
// TraceInfo struct
|
||||
//_______________________________________________________________________
|
||||
|
||||
// TraceInfo struct is used provide request trace info such as DNS lookup
|
||||
// TraceInfo struct is used to provide request trace info such as DNS lookup
|
||||
// duration, Connection obtain duration, Server processing duration, etc.
|
||||
//
|
||||
// Since v2.0.0
|
||||
type TraceInfo struct {
|
||||
// DNSLookup is a duration that transport took to perform
|
||||
// DNSLookup is the duration that transport took to perform
|
||||
// DNS lookup.
|
||||
DNSLookup time.Duration
|
||||
|
||||
// ConnTime is a duration that took to obtain a successful connection.
|
||||
// ConnTime is the duration it took to obtain a successful connection.
|
||||
ConnTime time.Duration
|
||||
|
||||
// TCPConnTime is a duration that took to obtain the TCP connection.
|
||||
// TCPConnTime is the duration it took to obtain the TCP connection.
|
||||
TCPConnTime time.Duration
|
||||
|
||||
// TLSHandshake is a duration that TLS handshake took place.
|
||||
// TLSHandshake is the duration of the TLS handshake.
|
||||
TLSHandshake time.Duration
|
||||
|
||||
// ServerTime is a duration that server took to respond first byte.
|
||||
// ServerTime is the server's duration for responding to the first byte.
|
||||
ServerTime time.Duration
|
||||
|
||||
// ResponseTime is a duration since first response byte from server to
|
||||
// ResponseTime is the duration since the first response byte from the server to
|
||||
// request completion.
|
||||
ResponseTime time.Duration
|
||||
|
||||
// TotalTime is a duration that total request took end-to-end.
|
||||
// TotalTime is the duration of the total time request taken end-to-end.
|
||||
TotalTime time.Duration
|
||||
|
||||
// IsConnReused is whether this connection has been previously
|
||||
@@ -52,7 +51,7 @@ type TraceInfo struct {
|
||||
// idle pool.
|
||||
IsConnWasIdle bool
|
||||
|
||||
// ConnIdleTime is a duration how long the connection was previously
|
||||
// ConnIdleTime is the duration how long the connection that was previously
|
||||
// idle, if IsConnWasIdle is true.
|
||||
ConnIdleTime time.Duration
|
||||
|
||||
@@ -68,10 +67,11 @@ type TraceInfo struct {
|
||||
// ClientTrace struct and its methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// tracer struct maps the `httptrace.ClientTrace` hooks into Fields
|
||||
// with same naming for easy understanding. Plus additional insights
|
||||
// Request.
|
||||
// clientTrace struct maps the [httptrace.ClientTrace] hooks into Fields
|
||||
// with the same naming for easy understanding. Plus additional insights
|
||||
// [Request].
|
||||
type clientTrace struct {
|
||||
lock sync.RWMutex
|
||||
getConn time.Time
|
||||
dnsStart time.Time
|
||||
dnsDone time.Time
|
||||
@@ -84,46 +84,60 @@ type clientTrace struct {
|
||||
gotConnInfo httptrace.GotConnInfo
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Trace unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (t *clientTrace) createContext(ctx context.Context) context.Context {
|
||||
return httptrace.WithClientTrace(
|
||||
ctx,
|
||||
&httptrace.ClientTrace{
|
||||
DNSStart: func(_ httptrace.DNSStartInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectStart: func(_, _ string) {
|
||||
t.lock.Lock()
|
||||
if t.dnsDone.IsZero() {
|
||||
t.dnsDone = time.Now()
|
||||
}
|
||||
if t.dnsStart.IsZero() {
|
||||
t.dnsStart = t.dnsDone
|
||||
}
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectDone: func(net, addr string, err error) {
|
||||
t.lock.Lock()
|
||||
t.connectDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GetConn: func(_ string) {
|
||||
t.lock.Lock()
|
||||
t.getConn = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotConn: func(ci httptrace.GotConnInfo) {
|
||||
t.lock.Lock()
|
||||
t.gotConn = time.Now()
|
||||
t.gotConnInfo = ci
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotFirstResponseByte: func() {
|
||||
t.lock.Lock()
|
||||
t.gotFirstResponseByte = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeStart: func() {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -24,7 +25,7 @@ func createTransport(localAddr net.Addr) *http.Transport {
|
||||
}
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialer.DialContext,
|
||||
DialContext: transportDialContext(dialer),
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return nil
|
||||
}
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !(js && wasm)
|
||||
// +build !js !wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return dialer.DialContext
|
||||
}
|
||||
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -18,7 +19,6 @@ import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
@@ -64,6 +64,16 @@ func (l *logger) output(format string, v ...interface{}) {
|
||||
l.l.Printf(format, v...)
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Rate Limiter interface
|
||||
//_______________________________________________________________________
|
||||
|
||||
type RateLimiter interface {
|
||||
Allow() bool
|
||||
}
|
||||
|
||||
var ErrRateLimitExceeded = errors.New("rate limit exceeded")
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Helper methods
|
||||
//_______________________________________________________________________
|
||||
@@ -134,10 +144,6 @@ type ResponseLog struct {
|
||||
Body string
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// way to disable the HTML escape as opt-in
|
||||
func jsonMarshal(c *Client, r *Request, d interface{}) (*bytes.Buffer, error) {
|
||||
if !r.jsonEscapeHTML || !c.jsonEscapeHTML {
|
||||
@@ -205,7 +211,7 @@ func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r i
|
||||
return err
|
||||
}
|
||||
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf)))
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf[:size])))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -279,7 +285,13 @@ func functionName(i interface{}) string {
|
||||
}
|
||||
|
||||
func acquireBuffer() *bytes.Buffer {
|
||||
return bufPool.Get().(*bytes.Buffer)
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
if buf.Len() == 0 {
|
||||
buf.Reset()
|
||||
return buf
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
return new(bytes.Buffer)
|
||||
}
|
||||
|
||||
func releaseBuffer(buf *bytes.Buffer) {
|
||||
@@ -289,32 +301,10 @@ func releaseBuffer(buf *bytes.Buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
// requestBodyReleaser wraps requests's body and implements custom Close for it.
|
||||
// The Close method closes original body and releases request body back to sync.Pool.
|
||||
type requestBodyReleaser struct {
|
||||
releaseOnce sync.Once
|
||||
reqBuf *bytes.Buffer
|
||||
io.ReadCloser
|
||||
}
|
||||
|
||||
func newRequestBodyReleaser(respBody io.ReadCloser, reqBuf *bytes.Buffer) io.ReadCloser {
|
||||
if reqBuf == nil {
|
||||
return respBody
|
||||
func backToBufPool(buf *bytes.Buffer) {
|
||||
if buf != nil {
|
||||
bufPool.Put(buf)
|
||||
}
|
||||
|
||||
return &requestBodyReleaser{
|
||||
reqBuf: reqBuf,
|
||||
ReadCloser: respBody,
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *requestBodyReleaser) Close() error {
|
||||
err := rr.ReadCloser.Close()
|
||||
rr.releaseOnce.Do(func() {
|
||||
releaseBuffer(rr.reqBuf)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func closeq(v interface{}) {
|
||||
@@ -328,25 +318,7 @@ func silently(_ ...interface{}) {}
|
||||
func composeHeaders(c *Client, r *Request, hdrs http.Header) string {
|
||||
str := make([]string, 0, len(hdrs))
|
||||
for _, k := range sortHeaderKeys(hdrs) {
|
||||
var v string
|
||||
if k == "Cookie" {
|
||||
cv := strings.TrimSpace(strings.Join(hdrs[k], ", "))
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, c := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
if cv != "" {
|
||||
cv = cv + "; " + c.String()
|
||||
} else {
|
||||
cv = c.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, cv))
|
||||
} else {
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", ")))
|
||||
}
|
||||
if v != "" {
|
||||
str = append(str, "\t"+v)
|
||||
}
|
||||
str = append(str, "\t"+strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", "))))
|
||||
}
|
||||
return strings.Join(str, "\n")
|
||||
}
|
||||
@@ -368,6 +340,32 @@ func copyHeaders(hdrs http.Header) http.Header {
|
||||
return nh
|
||||
}
|
||||
|
||||
func wrapErrors(n error, inner error) error {
|
||||
if inner == nil {
|
||||
return n
|
||||
}
|
||||
if n == nil {
|
||||
return inner
|
||||
}
|
||||
return &restyError{
|
||||
err: n,
|
||||
inner: inner,
|
||||
}
|
||||
}
|
||||
|
||||
type restyError struct {
|
||||
err error
|
||||
inner error
|
||||
}
|
||||
|
||||
func (e *restyError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func (e *restyError) Unwrap() error {
|
||||
return e.inner
|
||||
}
|
||||
|
||||
type noRetryErr struct {
|
||||
err error
|
||||
}
|
||||
|
||||
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-resty/resty/v2/shellescape"
|
||||
)
|
||||
|
||||
func buildCurlRequest(req *http.Request, httpCookiejar http.CookieJar) (curl string) {
|
||||
// 1. Generate curl raw headers
|
||||
|
||||
curl = "curl -X " + req.Method + " "
|
||||
// req.Host + req.URL.Path + "?" + req.URL.RawQuery + " " + req.Proto + " "
|
||||
headers := dumpCurlHeaders(req)
|
||||
for _, kv := range *headers {
|
||||
curl += `-H ` + shellescape.Quote(kv[0]+": "+kv[1]) + ` `
|
||||
}
|
||||
|
||||
// 2. Generate curl cookies
|
||||
// TODO validate this block of code, I think its not required since cookie captured via Headers
|
||||
if cookieJar, ok := httpCookiejar.(*cookiejar.Jar); ok {
|
||||
cookies := cookieJar.Cookies(req.URL)
|
||||
if len(cookies) > 0 {
|
||||
curl += `-H ` + shellescape.Quote(dumpCurlCookies(cookies)) + " "
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Generate curl body
|
||||
if req.Body != nil {
|
||||
buf, _ := io.ReadAll(req.Body)
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf)) // important!!
|
||||
curl += `-d ` + shellescape.Quote(string(buf)) + " "
|
||||
}
|
||||
|
||||
urlString := shellescape.Quote(req.URL.String())
|
||||
if urlString == "''" {
|
||||
urlString = "'http://unexecuted-request'"
|
||||
}
|
||||
curl += urlString
|
||||
return curl
|
||||
}
|
||||
|
||||
// dumpCurlCookies dumps cookies to curl format
|
||||
func dumpCurlCookies(cookies []*http.Cookie) string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("Cookie: ")
|
||||
for _, cookie := range cookies {
|
||||
sb.WriteString(cookie.Name + "=" + url.QueryEscape(cookie.Value) + "&")
|
||||
}
|
||||
return strings.TrimRight(sb.String(), "&")
|
||||
}
|
||||
|
||||
// dumpCurlHeaders dumps headers to curl format
|
||||
func dumpCurlHeaders(req *http.Request) *[][2]string {
|
||||
headers := [][2]string{}
|
||||
for k, vs := range req.Header {
|
||||
for _, v := range vs {
|
||||
headers = append(headers, [2]string{k, v})
|
||||
}
|
||||
}
|
||||
n := len(headers)
|
||||
for i := 0; i < n; i++ {
|
||||
for j := n - 1; j > i; j-- {
|
||||
jj := j - 1
|
||||
h1, h2 := headers[j], headers[jj]
|
||||
if h1[0] < h2[0] {
|
||||
headers[jj], headers[j] = headers[j], headers[jj]
|
||||
}
|
||||
}
|
||||
}
|
||||
return &headers
|
||||
}
|
||||
5
vendor/github.com/olekukonko/ll/global.go
generated
vendored
5
vendor/github.com/olekukonko/ll/global.go
generated
vendored
@@ -667,3 +667,8 @@ func Inspect(values ...interface{}) {
|
||||
o := NewInspector(defaultLogger)
|
||||
o.Log(2, values...)
|
||||
}
|
||||
|
||||
func Apply(opts ...Option) *Logger {
|
||||
return defaultLogger.Apply(opts...)
|
||||
|
||||
}
|
||||
|
||||
20
vendor/github.com/olekukonko/ll/lh/colorized.go
generated
vendored
20
vendor/github.com/olekukonko/ll/lh/colorized.go
generated
vendored
@@ -29,6 +29,7 @@ type Palette struct {
|
||||
Info string // Color for Info level messages
|
||||
Warn string // Color for Warn level messages
|
||||
Error string // Color for Error level messages
|
||||
Fatal string // Color for Fatal level messages
|
||||
Title string // Color for dump titles (BEGIN/END separators)
|
||||
}
|
||||
|
||||
@@ -47,10 +48,11 @@ var darkPalette = Palette{
|
||||
Hex: "\033[38;5;156m", // Light green for hex values
|
||||
Ascii: "\033[38;5;224m", // Light pink for ASCII values
|
||||
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Red for Error level
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Standard red
|
||||
Fatal: "\033[1;31m", // Bold red - stands out more
|
||||
}
|
||||
|
||||
// lightPalette defines colors optimized for light terminal backgrounds.
|
||||
@@ -68,10 +70,11 @@ var lightPalette = Palette{
|
||||
Hex: "\033[38;5;156m", // Light green for hex values
|
||||
Ascii: "\033[38;5;224m", // Light pink for ASCII values
|
||||
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Red for Error level
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Standard red
|
||||
Fatal: "\033[1;31m", // Bold red - stands out more
|
||||
}
|
||||
|
||||
// ColorizedHandler is a handler that outputs log entries with ANSI color codes.
|
||||
@@ -250,6 +253,7 @@ func (h *ColorizedHandler) formatLevel(b *strings.Builder, e *lx.Entry) {
|
||||
lx.LevelInfo: h.palette.Info, // Green
|
||||
lx.LevelWarn: h.palette.Warn, // Yellow
|
||||
lx.LevelError: h.palette.Error, // Red
|
||||
lx.LevelFatal: h.palette.Fatal, // Bold Red
|
||||
}[e.Level]
|
||||
|
||||
b.WriteString(color)
|
||||
|
||||
13
vendor/github.com/olekukonko/ll/lh/multi.go
generated
vendored
13
vendor/github.com/olekukonko/ll/lh/multi.go
generated
vendored
@@ -3,6 +3,7 @@ package lh
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/olekukonko/ll/lx"
|
||||
)
|
||||
|
||||
@@ -30,6 +31,18 @@ func NewMultiHandler(h ...lx.Handler) *MultiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of handlers in the MultiHandler.
|
||||
func (h *MultiHandler) Len() int {
|
||||
return len(h.Handlers)
|
||||
}
|
||||
|
||||
// Append adds one or more lx.Handler instances to the MultiHandler's list of handlers.
|
||||
func (h *MultiHandler) Append(handlers ...lx.Handler) {
|
||||
for _, e := range handlers {
|
||||
h.Handlers = append(h.Handlers, e)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle implements the Handler interface, calling Handle on each handler in sequence.
|
||||
// It collects any errors from handlers and combines them into a single error using errors.Join.
|
||||
// If no errors occur, it returns nil. Thread-safe if the underlying handlers are thread-safe.
|
||||
|
||||
5
vendor/github.com/olekukonko/ll/lh/slog.go
generated
vendored
5
vendor/github.com/olekukonko/ll/lh/slog.go
generated
vendored
@@ -2,8 +2,9 @@ package lh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/olekukonko/ll/lx"
|
||||
"log/slog"
|
||||
|
||||
"github.com/olekukonko/ll/lx"
|
||||
)
|
||||
|
||||
// SlogHandler adapts a slog.Handler to implement lx.Handler.
|
||||
@@ -81,7 +82,7 @@ func toSlogLevel(level lx.LevelType) slog.Level {
|
||||
return slog.LevelInfo
|
||||
case lx.LevelWarn:
|
||||
return slog.LevelWarn
|
||||
case lx.LevelError:
|
||||
case lx.LevelError, lx.LevelFatal:
|
||||
return slog.LevelError
|
||||
default:
|
||||
return slog.LevelInfo // Default for unknown levels
|
||||
|
||||
128
vendor/github.com/olekukonko/ll/ll.go
generated
vendored
128
vendor/github.com/olekukonko/ll/ll.go
generated
vendored
@@ -39,6 +39,8 @@ type Logger struct {
|
||||
stackBufferSize int // Buffer size for capturing stack traces
|
||||
separator string // Separator for namespace paths (e.g., "/")
|
||||
entries atomic.Int64 // Tracks total log entries sent to handler
|
||||
fatalExits bool
|
||||
fatalStack bool
|
||||
}
|
||||
|
||||
// New creates a new Logger with the given namespace and optional configurations.
|
||||
@@ -71,22 +73,71 @@ func New(namespace string, opts ...Option) *Logger {
|
||||
return logger
|
||||
}
|
||||
|
||||
// AddContext adds a key-value pair to the logger's context, modifying it directly.
|
||||
// Unlike Context, it mutates the existing context. It is thread-safe using a write lock.
|
||||
// Apply applies one or more functional options to the default/global logger.
|
||||
// Useful for late configuration (e.g., after migration, attach VictoriaLogs handler,
|
||||
// set level, add middleware, etc.) without changing existing New() calls.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app").Enable()
|
||||
// logger.AddContext("user", "alice")
|
||||
// logger.Info("Action") // Output: [app] INFO: Action [user=alice]
|
||||
func (l *Logger) AddContext(key string, value interface{}) *Logger {
|
||||
// // In main() or init(), after setting up handler
|
||||
// ll.Apply(
|
||||
// ll.Handler(vlBatched),
|
||||
// ll.Level(ll.LevelInfo),
|
||||
// ll.Use(rateLimiterMiddleware),
|
||||
// )
|
||||
//
|
||||
// Returns the default logger for chaining (if needed).
|
||||
func (l *Logger) Apply(opts ...Option) *Logger {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(l)
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// AddContext adds one or more key-value pairs to the logger's persistent context.
|
||||
// These fields will be included in **every** subsequent log message from this logger
|
||||
// (and its child namespace loggers).
|
||||
//
|
||||
// It supports variadic key-value pairs (string key, any value).
|
||||
// Non-string keys or uneven number of arguments will be safely ignored/logged.
|
||||
//
|
||||
// Returns the logger for chaining.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// logger.AddContext("user", "alice", "env", "prod")
|
||||
// logger.AddContext("request_id", reqID, "trace_id", traceID)
|
||||
// logger.AddContext("service", "payment") // single pair
|
||||
func (l *Logger) AddContext(pairs ...any) *Logger {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
// Initialize context map if nil
|
||||
// Lazy initialization of context map
|
||||
if l.context == nil {
|
||||
l.context = make(map[string]interface{})
|
||||
}
|
||||
l.context[key] = value
|
||||
|
||||
// Process key-value pairs
|
||||
for i := 0; i < len(pairs)-1; i += 2 {
|
||||
key, ok := pairs[i].(string)
|
||||
if !ok {
|
||||
l.Warnf("AddContext: non-string key at index %d: %v", i, pairs[i])
|
||||
continue
|
||||
}
|
||||
|
||||
value := pairs[i+1]
|
||||
l.context[key] = value
|
||||
}
|
||||
|
||||
// Optional: warn about uneven number of arguments
|
||||
if len(pairs)%2 != 0 {
|
||||
l.Warn("AddContext: uneven number of arguments, last value ignored")
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
@@ -357,6 +408,7 @@ func (l *Logger) Output(values ...interface{}) {
|
||||
l.output(2, values...)
|
||||
}
|
||||
|
||||
// mark logs the caller's file and line number along with an optional custom name label for tracing execution flow.
|
||||
func (l *Logger) output(skip int, values ...interface{}) {
|
||||
if !l.shouldLog(lx.LevelInfo) {
|
||||
return
|
||||
@@ -536,8 +588,10 @@ func (l *Logger) Fatal(args ...any) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
l.log(lx.LevelError, lx.ClassText, cat.Space(args...), nil, false)
|
||||
os.Exit(1)
|
||||
l.log(lx.LevelFatal, lx.ClassText, cat.Space(args...), nil, l.fatalStack)
|
||||
if l.fatalExits {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatalf logs a formatted message at Error level with a stack trace and exits the program.
|
||||
@@ -795,6 +849,7 @@ func (l *Logger) Mark(name ...string) {
|
||||
l.mark(2, name...)
|
||||
}
|
||||
|
||||
// mark logs the caller's file and line number along with an optional custom name label for tracing execution flow.
|
||||
func (l *Logger) mark(skip int, names ...string) {
|
||||
// Skip logging if Info level is not enabled
|
||||
if !l.shouldLog(lx.LevelInfo) {
|
||||
@@ -978,7 +1033,7 @@ func (l *Logger) Panic(args ...any) {
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
l.log(lx.LevelError, lx.ClassText, msg, nil, true)
|
||||
l.log(lx.LevelFatal, lx.ClassText, msg, nil, true)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
@@ -1459,54 +1514,3 @@ func (l *Logger) shouldLog(level lx.LevelType) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// WithHandler sets the handler for the logger as a functional option for configuring
|
||||
// a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithHandler(lh.NewJSONHandler(os.Stdout)))
|
||||
func WithHandler(handler lx.Handler) Option {
|
||||
return func(l *Logger) {
|
||||
l.handler = handler
|
||||
}
|
||||
}
|
||||
|
||||
// WithTimestamped returns an Option that configures timestamp settings for the logger's existing handler.
|
||||
// It enables or disables timestamp logging and optionally sets the timestamp format if the handler
|
||||
// supports the lx.Timestamper interface. If no handler is set, the function has no effect.
|
||||
// Parameters:
|
||||
//
|
||||
// enable: Boolean to enable or disable timestamp logging
|
||||
// format: Optional string(s) to specify the timestamp format
|
||||
func WithTimestamped(enable bool, format ...string) Option {
|
||||
return func(l *Logger) {
|
||||
if l.handler != nil { // Check if a handler is set
|
||||
// Verify if the handler supports the lx.Timestamper interface
|
||||
if h, ok := l.handler.(lx.Timestamper); ok {
|
||||
h.Timestamped(enable, format...) // Apply timestamp settings to the handler
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLevel sets the minimum log level for the logger as a functional option for
|
||||
// configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithLevel(lx.LevelWarn))
|
||||
func WithLevel(level lx.LevelType) Option {
|
||||
return func(l *Logger) {
|
||||
l.level = level
|
||||
}
|
||||
}
|
||||
|
||||
// WithStyle sets the namespace formatting style for the logger as a functional option
|
||||
// for configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithStyle(lx.NestedPath))
|
||||
func WithStyle(style lx.StyleType) Option {
|
||||
return func(l *Logger) {
|
||||
l.style = style
|
||||
}
|
||||
}
|
||||
|
||||
7
vendor/github.com/olekukonko/ll/lx/lx.go
generated
vendored
7
vendor/github.com/olekukonko/ll/lx/lx.go
generated
vendored
@@ -36,6 +36,7 @@ const (
|
||||
LevelInfo // Info level for general operational messages
|
||||
LevelWarn // Warn level for warning conditions
|
||||
LevelError // Error level for error conditions requiring attention
|
||||
LevelFatal // Fatal level for critical error conditions
|
||||
LevelDebug // None level for logs without a specific severity (e.g., raw output)
|
||||
LevelUnknown // None level for logs without a specific severity (e.g., raw output)
|
||||
)
|
||||
@@ -45,7 +46,9 @@ const (
|
||||
DebugString = "DEBUG"
|
||||
InfoString = "INFO"
|
||||
WarnString = "WARN"
|
||||
WarningString = "WARNING"
|
||||
ErrorString = "ERROR"
|
||||
FatalString = "FATAL"
|
||||
NoneString = "NONE"
|
||||
UnknownString = "UNKNOWN"
|
||||
|
||||
@@ -98,6 +101,8 @@ func (l LevelType) String() string {
|
||||
return WarnString
|
||||
case LevelError:
|
||||
return ErrorString
|
||||
case LevelFatal:
|
||||
return FatalString
|
||||
case LevelNone:
|
||||
return NoneString
|
||||
default:
|
||||
@@ -114,7 +119,7 @@ func LevelParse(s string) LevelType {
|
||||
return LevelDebug
|
||||
case InfoString:
|
||||
return LevelInfo
|
||||
case WarnString, "WARNING": // Allow both "WARN" and "WARNING"
|
||||
case WarnString, WarningString: // Allow both "WARN" and "WARNING"
|
||||
return LevelWarn
|
||||
case ErrorString:
|
||||
return LevelError
|
||||
|
||||
67
vendor/github.com/olekukonko/ll/options.go
generated
vendored
Normal file
67
vendor/github.com/olekukonko/ll/options.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package ll
|
||||
|
||||
import "github.com/olekukonko/ll/lx"
|
||||
|
||||
// WithHandler sets the handler for the logger as a functional option for configuring
|
||||
// a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithHandler(lh.NewJSONHandler(os.Stdout)))
|
||||
func WithHandler(handler lx.Handler) Option {
|
||||
return func(l *Logger) {
|
||||
l.handler = handler
|
||||
}
|
||||
}
|
||||
|
||||
// WithTimestamped returns an Option that configures timestamp settings for the logger's existing handler.
|
||||
// It enables or disables timestamp logging and optionally sets the timestamp format if the handler
|
||||
// supports the lx.Timestamper interface. If no handler is set, the function has no effect.
|
||||
// Parameters:
|
||||
//
|
||||
// enable: Boolean to enable or disable timestamp logging
|
||||
// format: Optional string(s) to specify the timestamp format
|
||||
func WithTimestamped(enable bool, format ...string) Option {
|
||||
return func(l *Logger) {
|
||||
if l.handler != nil { // Check if a handler is set
|
||||
// Verify if the handler supports the lx.Timestamper interface
|
||||
if h, ok := l.handler.(lx.Timestamper); ok {
|
||||
h.Timestamped(enable, format...) // Apply timestamp settings to the handler
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLevel sets the minimum log level for the logger as a functional option for
|
||||
// configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithLevel(lx.LevelWarn))
|
||||
func WithLevel(level lx.LevelType) Option {
|
||||
return func(l *Logger) {
|
||||
l.level = level
|
||||
}
|
||||
}
|
||||
|
||||
// WithStyle sets the namespace formatting style for the logger as a functional option
|
||||
// for configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithStyle(lx.NestedPath))
|
||||
func WithStyle(style lx.StyleType) Option {
|
||||
return func(l *Logger) {
|
||||
l.style = style
|
||||
}
|
||||
}
|
||||
|
||||
// Functional options (can be passed to New() or applied later)
|
||||
func WithFatalExits(enabled bool) Option {
|
||||
return func(l *Logger) {
|
||||
l.fatalExits = enabled
|
||||
}
|
||||
}
|
||||
|
||||
func WithFatalStack(enabled bool) Option {
|
||||
return func(l *Logger) {
|
||||
l.fatalStack = enabled
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
6
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
@@ -28,7 +28,7 @@ go get github.com/olekukonko/tablewriter@v0.0.5
|
||||
#### Latest Version
|
||||
The latest stable version
|
||||
```bash
|
||||
go get github.com/olekukonko/tablewriter@v1.1.2
|
||||
go get github.com/olekukonko/tablewriter@v1.1.3
|
||||
```
|
||||
|
||||
**Warning:** Version `v1.0.0` contains missing functionality and should not be used.
|
||||
@@ -62,7 +62,7 @@ func main() {
|
||||
data := [][]string{
|
||||
{"Package", "Version", "Status"},
|
||||
{"tablewriter", "v0.0.5", "legacy"},
|
||||
{"tablewriter", "v1.1.2", "latest"},
|
||||
{"tablewriter", "v1.1.3", "latest"},
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
@@ -77,7 +77,7 @@ func main() {
|
||||
│ PACKAGE │ VERSION │ STATUS │
|
||||
├─────────────┼─────────┼────────┤
|
||||
│ tablewriter │ v0.0.5 │ legacy │
|
||||
│ tablewriter │ v1.1.2 │ latest │
|
||||
│ tablewriter │ v1.1.3 │ latest │
|
||||
└─────────────┴─────────┴────────┘
|
||||
```
|
||||
|
||||
|
||||
424
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/ea.go
generated
vendored
Normal file
424
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/ea.go
generated
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
Package twwidth provides intelligent East Asian width detection.
|
||||
|
||||
In 2025/2026, most modern terminal emulators (VSCode, Windows Terminal, iTerm2,
|
||||
Alacritty) and modern monospace fonts (Hack, Fira Code, Cascadia Code) treat
|
||||
box-drawing characters as Single Width, regardless of the underlying OS Locale.
|
||||
|
||||
Detection Logic (in order of priority):
|
||||
- RUNEWIDTH_EASTASIAN environment variable (explicit user override)
|
||||
- Force Legacy Mode (programmatic override for backward compatibility)
|
||||
- Modern environment detection (VSCode, Windows Terminal, etc. -> Narrow)
|
||||
- Locale-based detection (CJK locales in traditional terminals -> Wide)
|
||||
|
||||
This prioritization ensures that:
|
||||
- Users can always override behavior using RUNEWIDTH_EASTASIAN
|
||||
- Modern development environments work correctly by default
|
||||
- Traditional CJK terminals maintain compatibility via locale checks
|
||||
|
||||
Examples:
|
||||
|
||||
// Force narrow borders (for Hack font in zh_CN)
|
||||
RUNEWIDTH_EASTASIAN=0 go run .
|
||||
|
||||
// Force wide borders (for legacy CJK terminals)
|
||||
RUNEWIDTH_EASTASIAN=1 go run .
|
||||
*/
|
||||
package twwidth
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Environment Variable Constants
|
||||
const (
|
||||
EnvLCAll = "LC_ALL"
|
||||
EnvLCCtype = "LC_CTYPE"
|
||||
EnvLang = "LANG"
|
||||
EnvRuneWidthEastAsian = "RUNEWIDTH_EASTASIAN"
|
||||
EnvTerm = "TERM"
|
||||
EnvTermProgram = "TERM_PROGRAM"
|
||||
EnvTermProgramWsl = "TERM_PROGRAM_WSL"
|
||||
EnvWTProfile = "WT_PROFILE_ID" // Windows Terminal
|
||||
EnvConEmuANSI = "ConEmuANSI" // ConEmu
|
||||
EnvAlacritty = "ALACRITTY_LOG" // Alacritty
|
||||
EnvVTEVersion = "VTE_VERSION" // GNOME/VTE
|
||||
)
|
||||
|
||||
const (
|
||||
overwriteOn = "override_on"
|
||||
overwriteOff = "override_off"
|
||||
|
||||
envModern = "modern_env"
|
||||
envCjk = "locale_cjk"
|
||||
envAscii = "default_ascii"
|
||||
)
|
||||
|
||||
// CJK Language Codes (Prefixes)
|
||||
// Covers ISO 639-1 (2-letter) and common full names used in some systems.
|
||||
var cjkPrefixes = []string{
|
||||
"zh", "ja", "ko", // Standard: Chinese, Japanese, Korean
|
||||
"chi", "zho", // ISO 639-2/B and T for Chinese
|
||||
"jpn", "kor", // ISO 639-2 for Japanese, Korean
|
||||
"chinese", "japanese", "korean", // Full names (rare but possible in some legacy systems)
|
||||
}
|
||||
|
||||
// CJK Region Codes
|
||||
// Checks for specific regions that imply CJK font usage (e.g., en_HK).
|
||||
var cjkRegions = map[string]bool{
|
||||
"cn": true, // China
|
||||
"tw": true, // Taiwan
|
||||
"hk": true, // Hong Kong
|
||||
"mo": true, // Macau
|
||||
"jp": true, // Japan
|
||||
"kr": true, // South Korea
|
||||
"kp": true, // North Korea
|
||||
"sg": true, // Singapore (Often uses CJK fonts)
|
||||
}
|
||||
|
||||
// Modern environments that should use narrow borders (1-width box chars)
|
||||
var modernEnvironments = map[string]bool{
|
||||
// Terminal programs
|
||||
"vscode": true, "visual studio code": true,
|
||||
"iterm.app": true, "iterm2": true,
|
||||
"windows terminal": true, "windowsterminal": true,
|
||||
"alacritty": true, "kitty": true,
|
||||
"hyper": true, "tabby": true, "terminus": true, "fluentterminal": true,
|
||||
"warp": true, "ghostty": true, "rio": true,
|
||||
"jetbrains-jediterm": true,
|
||||
|
||||
// Terminal types (TERM signatures)
|
||||
"xterm-kitty": true, "xterm-ghostty": true, "wezterm": true,
|
||||
}
|
||||
|
||||
var (
|
||||
eastAsianOnce sync.Once
|
||||
eastAsianVal bool
|
||||
|
||||
// Legacy override control
|
||||
// Renamed to cfgMu to avoid conflict with width.go's mu
|
||||
cfgMu sync.RWMutex
|
||||
forceLegacyEastAsian = false
|
||||
)
|
||||
|
||||
type Enviroment struct {
|
||||
GOOS string `json:"goos"`
|
||||
LC_ALL string `json:"lc_all"`
|
||||
LC_CTYPE string `json:"lc_ctype"`
|
||||
LANG string `json:"lang"`
|
||||
RUNEWIDTH_EASTASIAN string `json:"runewidth_eastasian"`
|
||||
TERM string `json:"term"`
|
||||
TERM_PROGRAM string `json:"term_program"`
|
||||
}
|
||||
|
||||
// State captures the calculated internal state.
|
||||
type State struct {
|
||||
NormalizedLocale string `json:"normalized_locale"`
|
||||
IsCJKLocale bool `json:"is_cjk_locale"`
|
||||
IsModernEnv bool `json:"is_modern_env"`
|
||||
LegacyOverrideMode bool `json:"legacy_override_mode"`
|
||||
}
|
||||
|
||||
// Detection aggregates all debug information regarding East Asian width detection.
|
||||
type Detection struct {
|
||||
AutoUseEastAsian bool `json:"auto_use_east_asian"`
|
||||
DetectionMode string `json:"detection_mode"`
|
||||
Raw Enviroment `json:"raw"`
|
||||
Derived State `json:"derived"`
|
||||
}
|
||||
|
||||
// EastAsianForceLegacy forces the detection logic to ignore modern environment checks.
|
||||
// It relies solely on Locale detection. This is useful for applications that need
|
||||
// strict backward compatibility.
|
||||
//
|
||||
// Note: This does NOT override RUNEWIDTH_EASTASIAN. User environment variables take precedence.
|
||||
// This should be called before the first table render.
|
||||
func EastAsianForceLegacy(force bool) {
|
||||
cfgMu.Lock()
|
||||
defer cfgMu.Unlock()
|
||||
forceLegacyEastAsian = force
|
||||
}
|
||||
|
||||
// EastAsianDetect checks the environment variables to determine if
|
||||
// East Asian width calculations should be enabled.
|
||||
func EastAsianDetect() bool {
|
||||
eastAsianOnce.Do(func() {
|
||||
eastAsianVal = detectEastAsian()
|
||||
})
|
||||
return eastAsianVal
|
||||
}
|
||||
|
||||
// EastAsianConservative is a stricter version that only defaults to Narrow
|
||||
// if the terminal is definitely known to be modern (e.g. VSCode, iTerm2).
|
||||
// It avoids heuristics like checking "xterm" in the TERM variable.
|
||||
func EastAsianConservative() bool {
|
||||
// Check overrides first
|
||||
if val, found := checkOverrides(); found {
|
||||
return val
|
||||
}
|
||||
|
||||
// Stricter modern environment detection
|
||||
if isConservativeModernEnvironment() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Fall back to locale
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// EastAsianMode returns the decision path used for the current environment.
|
||||
// Useful for debugging why a specific width was chosen.
|
||||
func EastAsianMode() string {
|
||||
// Check override
|
||||
if val, found := checkOverrides(); found {
|
||||
if val {
|
||||
return overwriteOn
|
||||
}
|
||||
return overwriteOff
|
||||
}
|
||||
|
||||
cfgMu.RLock()
|
||||
legacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
if legacy {
|
||||
if checkLocale() {
|
||||
return envCjk
|
||||
}
|
||||
return envAscii
|
||||
}
|
||||
|
||||
if isModernEnvironment() {
|
||||
return envModern
|
||||
}
|
||||
|
||||
if checkLocale() {
|
||||
return envCjk
|
||||
}
|
||||
|
||||
return envAscii
|
||||
}
|
||||
|
||||
// Debugging returns detailed information about the detection decision.
|
||||
// Useful for users to include in Github issues.
|
||||
func Debugging() Detection {
|
||||
locale := getNormalizedLocale()
|
||||
|
||||
cfgMu.RLock()
|
||||
legacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
return Detection{
|
||||
AutoUseEastAsian: EastAsianDetect(),
|
||||
DetectionMode: EastAsianMode(),
|
||||
Raw: Enviroment{
|
||||
GOOS: runtime.GOOS,
|
||||
LC_ALL: os.Getenv(EnvLCAll),
|
||||
LC_CTYPE: os.Getenv(EnvLCCtype),
|
||||
LANG: os.Getenv(EnvLang),
|
||||
RUNEWIDTH_EASTASIAN: os.Getenv(EnvRuneWidthEastAsian),
|
||||
TERM: os.Getenv(EnvTerm),
|
||||
TERM_PROGRAM: os.Getenv(EnvTermProgram),
|
||||
},
|
||||
Derived: State{
|
||||
NormalizedLocale: locale,
|
||||
IsCJKLocale: isCJKLocale(locale),
|
||||
IsModernEnv: isModernEnvironment(),
|
||||
LegacyOverrideMode: legacy,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// detectEastAsian evaluates the environment and locale settings to determine if East Asian width rules should apply.
|
||||
func detectEastAsian() bool {
|
||||
// User Override check (Highest Priority)
|
||||
if val, found := checkOverrides(); found {
|
||||
return val
|
||||
}
|
||||
|
||||
// Force Legacy Mode check
|
||||
cfgMu.RLock()
|
||||
isLegacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
if isLegacy {
|
||||
// Legacy mode ignores modern environment checks,
|
||||
// relying solely on locale.
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// Modern Environment Detection
|
||||
// If modern, we assume Single Width (return false)
|
||||
if isModernEnvironment() {
|
||||
return false
|
||||
}
|
||||
|
||||
// 4. Locale Fallback
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// checkOverrides looks for RUNEWIDTH_EASTASIAN
|
||||
func checkOverrides() (bool, bool) {
|
||||
if rw := os.Getenv(EnvRuneWidthEastAsian); rw != "" {
|
||||
rw = strings.ToLower(rw)
|
||||
if rw == "0" || rw == "off" || rw == "false" || rw == "no" {
|
||||
return false, true
|
||||
}
|
||||
if rw == "1" || rw == "on" || rw == "true" || rw == "yes" {
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// checkLocale performs the string analysis on LANG/LC_ALL
|
||||
func checkLocale() bool {
|
||||
locale := getNormalizedLocale()
|
||||
if locale == "" {
|
||||
return false
|
||||
}
|
||||
return isCJKLocale(locale)
|
||||
}
|
||||
|
||||
// isModernEnvironment performs comprehensive checks for modern terminal capabilities.
|
||||
func isModernEnvironment() bool {
|
||||
// Check TERM_PROGRAM (Most reliable)
|
||||
if termProg := os.Getenv(EnvTermProgram); termProg != "" {
|
||||
termProgLower := strings.ToLower(termProg)
|
||||
if modernEnvironments[termProgLower] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check WSL specific variable
|
||||
if os.Getenv(EnvTermProgramWsl) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Windows Specifics
|
||||
if runtime.GOOS == "windows" {
|
||||
// Windows Terminal
|
||||
if os.Getenv(EnvWTProfile) != "" {
|
||||
return true
|
||||
}
|
||||
// ConEmu/Cmder
|
||||
if os.Getenv(EnvConEmuANSI) == "ON" {
|
||||
return true
|
||||
}
|
||||
// Modern Windows console (Windows 10+) check via TERM
|
||||
if term := os.Getenv(EnvTerm); term != "" {
|
||||
termLower := strings.ToLower(term)
|
||||
if strings.Contains(termLower, "xterm") ||
|
||||
strings.Contains(termLower, "vt") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VTE-based terminals (GNOME Terminal, Tilix, etc.)
|
||||
if os.Getenv(EnvVTEVersion) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check for Alacritty specifically
|
||||
if os.Getenv(EnvAlacritty) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check TERM for modern terminal signatures
|
||||
if term := os.Getenv(EnvTerm); term != "" {
|
||||
termLower := strings.ToLower(term)
|
||||
// Specific modern terminals often put their name in TERM
|
||||
if modernEnvironments[termLower] {
|
||||
return true
|
||||
}
|
||||
// Heuristics for standard modern-capable descriptors
|
||||
if strings.Contains(termLower, "xterm") && !strings.Contains(termLower, "xterm-mono") {
|
||||
return true
|
||||
}
|
||||
if strings.Contains(termLower, "screen") ||
|
||||
strings.Contains(termLower, "tmux") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// isConservativeModernEnvironment performs strict checks only for known modern terminals.
|
||||
func isConservativeModernEnvironment() bool {
|
||||
termProg := strings.ToLower(os.Getenv(EnvTermProgram))
|
||||
|
||||
// Allow-list of definitely modern terminals
|
||||
switch termProg {
|
||||
case "vscode", "visual studio code":
|
||||
return true
|
||||
case "iterm.app", "iterm2":
|
||||
return true
|
||||
case "windows terminal", "windowsterminal":
|
||||
return true
|
||||
case "alacritty", "wezterm", "kitty", "ghostty":
|
||||
return true
|
||||
case "warp", "tabby", "hyper":
|
||||
return true
|
||||
}
|
||||
|
||||
// Windows Terminal via specific Env
|
||||
if os.Getenv(EnvWTProfile) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// isCJKLocale determines if a given locale string corresponds to a CJK (Chinese, Japanese, Korean) language or region.
|
||||
func isCJKLocale(locale string) bool {
|
||||
// Check Language Prefix
|
||||
for _, prefix := range cjkPrefixes {
|
||||
if strings.HasPrefix(locale, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check Regions
|
||||
parts := strings.Split(locale, "_")
|
||||
if len(parts) > 1 {
|
||||
for _, part := range parts[1:] {
|
||||
if cjkRegions[part] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// getNormalizedLocale returns the normalized locale by inspecting environment variables LC_ALL, LC_CTYPE, and LANG.
|
||||
func getNormalizedLocale() string {
|
||||
var locale string
|
||||
if loc := os.Getenv(EnvLCAll); loc != "" {
|
||||
locale = loc
|
||||
} else if loc := os.Getenv(EnvLCCtype); loc != "" {
|
||||
locale = loc
|
||||
} else if loc := os.Getenv(EnvLang); loc != "" {
|
||||
locale = loc
|
||||
}
|
||||
|
||||
// Fast fail for empty or standard C/POSIX locales
|
||||
if locale == "" || locale == "C" || locale == "POSIX" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Strip encoding and modifiers
|
||||
if idx := strings.IndexByte(locale, '.'); idx != -1 {
|
||||
locale = locale[:idx]
|
||||
}
|
||||
if idx := strings.IndexByte(locale, '@'); idx != -1 {
|
||||
locale = locale[:idx]
|
||||
}
|
||||
|
||||
return strings.ToLower(locale)
|
||||
}
|
||||
237
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
237
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
// width.go
|
||||
package twwidth
|
||||
|
||||
import (
|
||||
@@ -21,6 +22,10 @@ const (
|
||||
// Options allows for configuring width calculation on a per-call basis.
|
||||
type Options struct {
|
||||
EastAsianWidth bool
|
||||
|
||||
// Explicitly force box drawing chars to be narrow
|
||||
// regardless of EastAsianWidth setting.
|
||||
ForceNarrowBorders bool
|
||||
}
|
||||
|
||||
// globalOptions holds the global displaywidth configuration, including East Asian width settings.
|
||||
@@ -36,12 +41,25 @@ var widthCache *twcache.LRU[string, int]
|
||||
var ansi = Filter()
|
||||
|
||||
func init() {
|
||||
// Initialize global options by detecting from the environment,
|
||||
// which is the one key feature we get from go-runewidth.
|
||||
isEastAsian := EastAsianDetect()
|
||||
|
||||
cond := runewidth.NewCondition()
|
||||
cond.EastAsianWidth = isEastAsian
|
||||
|
||||
globalOptions = Options{
|
||||
EastAsianWidth: cond.EastAsianWidth,
|
||||
EastAsianWidth: isEastAsian,
|
||||
|
||||
// Auto-enable ForceNarrowBorders for edge cases.
|
||||
// If EastAsianWidth is ON (e.g. forced via Env Var), but we detect
|
||||
// a modern environment, we might technically want to narrow borders
|
||||
// while keeping text wide.
|
||||
//
|
||||
// Note: In the standard EastAsian logic, isEastAsian will
|
||||
// ALREADY be false for modern environments, so this boolean implies
|
||||
// a specific "Forced On" scenario.
|
||||
ForceNarrowBorders: isEastAsian && isModernEnvironment(),
|
||||
}
|
||||
|
||||
widthCache = twcache.NewLRU[string, int](cacheCapacity)
|
||||
}
|
||||
|
||||
@@ -55,6 +73,14 @@ func makeCacheKey(str string, eastAsianWidth bool) string {
|
||||
return cachePrefix + str
|
||||
}
|
||||
|
||||
// Display calculates the visual width of a string using a specific runewidth.Condition.
|
||||
// Deprecated: use WidthWithOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func Display(cond *runewidth.Condition, str string) int {
|
||||
opts := Options{EastAsianWidth: cond.EastAsianWidth}
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// Filter compiles and returns a regular expression for matching ANSI escape sequences,
|
||||
// including CSI (Control Sequence Introducer) and OSC (Operating System Command) sequences.
|
||||
// The returned regex can be used to strip ANSI codes from strings.
|
||||
@@ -73,25 +99,15 @@ func Filter() *regexp.Regexp {
|
||||
return regexp.MustCompile("(" + regCSI + "|" + regOSC + ")")
|
||||
}
|
||||
|
||||
// SetOptions sets the global options for width calculation.
|
||||
// This function is thread-safe.
|
||||
func SetOptions(opts Options) {
|
||||
// GetCacheStats returns current cache statistics
|
||||
func GetCacheStats() (size, capacity int, hitRate float64) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if globalOptions.EastAsianWidth != opts.EastAsianWidth {
|
||||
globalOptions = opts
|
||||
widthCache.Purge()
|
||||
}
|
||||
}
|
||||
|
||||
// SetEastAsian enables or disables East Asian width handling globally.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// twdw.SetEastAsian(true) // Enable East Asian width handling
|
||||
func SetEastAsian(enable bool) {
|
||||
SetOptions(Options{EastAsianWidth: enable})
|
||||
if widthCache == nil {
|
||||
return 0, 0, 0
|
||||
}
|
||||
return widthCache.Len(), widthCache.Cap(), widthCache.HitRate()
|
||||
}
|
||||
|
||||
// IsEastAsian returns the current East Asian width setting.
|
||||
@@ -108,6 +124,22 @@ func IsEastAsian() bool {
|
||||
return globalOptions.EastAsianWidth
|
||||
}
|
||||
|
||||
// SetCacheCapacity changes the cache size dynamically
|
||||
// If capacity <= 0, disables caching entirely
|
||||
func SetCacheCapacity(capacity int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if capacity <= 0 {
|
||||
widthCache = nil // nil = fully disabled
|
||||
return
|
||||
}
|
||||
|
||||
newCache := twcache.NewLRU[string, int](capacity)
|
||||
widthCache = newCache
|
||||
}
|
||||
|
||||
// SetCondition sets the global East Asian width setting based on a runewidth.Condition.
|
||||
// Deprecated: use SetOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func SetCondition(cond *runewidth.Condition) {
|
||||
@@ -120,55 +152,33 @@ func SetCondition(cond *runewidth.Condition) {
|
||||
}
|
||||
}
|
||||
|
||||
// Width calculates the visual width of a string using the global cache for performance.
|
||||
// It excludes ANSI escape sequences and accounts for the global East Asian width setting.
|
||||
// SetEastAsian enables or disables East Asian width handling globally.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.Width("Hello\x1b[31mWorld") // Returns 10
|
||||
func Width(str string) int {
|
||||
currentEA := IsEastAsian()
|
||||
key := makeCacheKey(str, currentEA)
|
||||
// twdw.SetEastAsian(true) // Enable East Asian width handling
|
||||
func SetEastAsian(enable bool) {
|
||||
SetOptions(Options{EastAsianWidth: enable})
|
||||
}
|
||||
|
||||
if w, found := widthCache.Get(key); found {
|
||||
return w
|
||||
// SetForceNarrow to preserve the new flag, or create a new setter
|
||||
func SetForceNarrow(enable bool) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
globalOptions.ForceNarrowBorders = enable
|
||||
widthCache.Purge() // Clear cache because widths might change
|
||||
}
|
||||
|
||||
// SetOptions sets the global options for width calculation.
|
||||
// This function is thread-safe.
|
||||
func SetOptions(opts Options) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if globalOptions.EastAsianWidth != opts.EastAsianWidth || globalOptions.ForceNarrowBorders != opts.ForceNarrowBorders {
|
||||
globalOptions = opts
|
||||
widthCache.Purge()
|
||||
}
|
||||
|
||||
opts := displaywidth.Options{EastAsianWidth: currentEA}
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := opts.String(stripped)
|
||||
|
||||
widthCache.Add(key, calculatedWidth)
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// WidthWithOptions calculates the visual width of a string with specific options,
|
||||
// bypassing the global settings and cache. This is useful for one-shot calculations
|
||||
// where global state is not desired.
|
||||
func WidthWithOptions(str string, opts Options) int {
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: opts.EastAsianWidth}
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
return dwOpts.String(stripped)
|
||||
}
|
||||
|
||||
// WidthNoCache calculates the visual width of a string without using the global cache.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.WidthNoCache("Hello\x1b[31mWorld") // Returns 10
|
||||
func WidthNoCache(str string) int {
|
||||
// This function's behavior is equivalent to a one-shot calculation
|
||||
// using the current global options. The WidthWithOptions function
|
||||
// does not interact with the cache, thus fulfilling the requirement.
|
||||
return WidthWithOptions(str, Options{EastAsianWidth: IsEastAsian()})
|
||||
}
|
||||
|
||||
// Deprecated: use WidthWithOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func Display(cond *runewidth.Condition, str string) int {
|
||||
opts := Options{EastAsianWidth: cond.EastAsianWidth}
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// Truncate shortens a string to fit within a specified visual width, optionally
|
||||
@@ -235,11 +245,13 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
|
||||
// Case 4: String needs truncation (sDisplayWidth > maxWidth).
|
||||
// maxWidth is the total budget for the final string (content + suffix).
|
||||
currentGlobalEastAsianWidth := IsEastAsian()
|
||||
mu.Lock()
|
||||
currentOpts := globalOptions
|
||||
mu.Unlock()
|
||||
|
||||
// Special case for EastAsian true: if only suffix fits, return suffix.
|
||||
// Special case for EastAsianDetect true: if only suffix fits, return suffix.
|
||||
// This was derived from previous test behavior.
|
||||
if len(suffixStr) > 0 && currentGlobalEastAsianWidth {
|
||||
if len(suffixStr) > 0 && currentOpts.EastAsianWidth {
|
||||
provisionalContentWidth := maxWidth - suffixDisplayWidth
|
||||
if provisionalContentWidth == 0 { // Exactly enough space for suffix only
|
||||
return suffixStr
|
||||
@@ -271,8 +283,6 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
inAnsiSequence := false
|
||||
ansiWrittenToContent := false
|
||||
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: currentGlobalEastAsianWidth}
|
||||
|
||||
for _, r := range s {
|
||||
if r == '\x1b' {
|
||||
inAnsiSequence = true
|
||||
@@ -305,7 +315,7 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
ansiSeqBuf.Reset()
|
||||
}
|
||||
} else { // Normal character
|
||||
runeDisplayWidth := dwOpts.Rune(r)
|
||||
runeDisplayWidth := calculateRunewidth(r, currentOpts)
|
||||
if targetContentForIteration == 0 { // No budget for content at all
|
||||
break
|
||||
}
|
||||
@@ -342,28 +352,81 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
return result
|
||||
}
|
||||
|
||||
// SetCacheCapacity changes the cache size dynamically
|
||||
// If capacity <= 0, disables caching entirely
|
||||
func SetCacheCapacity(capacity int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if capacity <= 0 {
|
||||
widthCache = nil // nil = fully disabled
|
||||
return
|
||||
// Width calculates the visual width of a string using the global cache for performance.
|
||||
// It excludes ANSI escape sequences and accounts for the global East Asian width setting.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.Width("Hello\x1b[31mWorld") // Returns 10
|
||||
func Width(str string) int {
|
||||
// Fast path ASCII (Optimization)
|
||||
if len(str) == 1 && str[0] < 0x80 {
|
||||
return 1
|
||||
}
|
||||
|
||||
newCache := twcache.NewLRU[string, int](capacity)
|
||||
widthCache = newCache
|
||||
}
|
||||
|
||||
// GetCacheStats returns current cache statistics
|
||||
func GetCacheStats() (size, capacity int, hitRate float64) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
currentOpts := globalOptions
|
||||
mu.Unlock()
|
||||
|
||||
if widthCache == nil {
|
||||
return 0, 0, 0
|
||||
key := makeCacheKey(str, currentOpts.EastAsianWidth)
|
||||
|
||||
// Check Cache (Optimization)
|
||||
if w, found := widthCache.Get(key); found {
|
||||
return w
|
||||
}
|
||||
return widthCache.Len(), widthCache.Cap(), widthCache.HitRate()
|
||||
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := 0
|
||||
|
||||
for _, r := range stripped {
|
||||
calculatedWidth += calculateRunewidth(r, currentOpts)
|
||||
}
|
||||
|
||||
// Store in Cache
|
||||
widthCache.Add(key, calculatedWidth)
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// WidthNoCache calculates the visual width of a string without using the global cache.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.WidthNoCache("Hello\x1b[31mWorld") // Returns 10
|
||||
func WidthNoCache(str string) int {
|
||||
// This function's behavior is equivalent to a one-shot calculation
|
||||
// using the current global options. The WidthWithOptions function
|
||||
// does not interact with the cache, thus fulfilling the requirement.
|
||||
mu.Lock()
|
||||
opts := globalOptions
|
||||
mu.Unlock()
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// WidthWithOptions calculates the visual width of a string with specific options,
|
||||
// bypassing the global settings and cache. This is useful for one-shot calculations
|
||||
// where global state is not desired.
|
||||
func WidthWithOptions(str string, opts Options) int {
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := 0
|
||||
for _, r := range stripped {
|
||||
calculatedWidth += calculateRunewidth(r, opts)
|
||||
}
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// calculateRunewidth calculates the width of a single rune based on the provided options.
|
||||
// It applies narrow overrides for box drawing characters if configured.
|
||||
func calculateRunewidth(r rune, opts Options) int {
|
||||
if opts.ForceNarrowBorders && isBoxDrawingChar(r) {
|
||||
return 1
|
||||
}
|
||||
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: opts.EastAsianWidth}
|
||||
return dwOpts.Rune(r)
|
||||
}
|
||||
|
||||
// isBoxDrawingChar checks if a rune is within the Unicode Box Drawing range.
|
||||
func isBoxDrawingChar(r rune) bool {
|
||||
return r >= 0x2500 && r <= 0x257F
|
||||
}
|
||||
|
||||
23
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
23
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
@@ -24,28 +23,6 @@ type ColorizedConfig struct {
|
||||
Symbols tw.Symbols // Symbols for table drawing (e.g., corners, lines)
|
||||
}
|
||||
|
||||
// Colors is a slice of color attributes for use with fatih/color, such as color.FgWhite or color.Bold.
|
||||
type Colors []color.Attribute
|
||||
|
||||
// Tint defines foreground and background color settings for table elements, with optional per-column overrides.
|
||||
type Tint struct {
|
||||
FG Colors // Foreground color attributes
|
||||
BG Colors // Background color attributes
|
||||
Columns []Tint // Per-column color settings
|
||||
}
|
||||
|
||||
// Apply applies the Tint's foreground and background colors to the given text, returning the text unchanged if no colors are set.
|
||||
func (t Tint) Apply(text string) string {
|
||||
if len(t.FG) == 0 && len(t.BG) == 0 {
|
||||
return text
|
||||
}
|
||||
// Combine foreground and background colors
|
||||
combinedColors := append(t.FG, t.BG...)
|
||||
// Create a color function and apply it to the text
|
||||
c := color.New(combinedColors...).SprintFunc()
|
||||
return c(text)
|
||||
}
|
||||
|
||||
// Colorized renders colored ASCII tables with customizable borders, colors, and alignments.
|
||||
type Colorized struct {
|
||||
config ColorizedConfig // Renderer configuration
|
||||
|
||||
25
vendor/github.com/olekukonko/tablewriter/renderer/tint.go
generated
vendored
Normal file
25
vendor/github.com/olekukonko/tablewriter/renderer/tint.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package renderer
|
||||
|
||||
import "github.com/fatih/color"
|
||||
|
||||
// Colors is a slice of color attributes for use with fatih/color, such as color.FgWhite or color.Bold.
|
||||
type Colors []color.Attribute
|
||||
|
||||
// Tint defines foreground and background color settings for table elements, with optional per-column overrides.
|
||||
type Tint struct {
|
||||
FG Colors // Foreground color attributes
|
||||
BG Colors // Background color attributes
|
||||
Columns []Tint // Per-column color settings
|
||||
}
|
||||
|
||||
// Apply applies the Tint's foreground and background colors to the given text, returning the text unchanged if no colors are set.
|
||||
func (t Tint) Apply(text string) string {
|
||||
if len(t.FG) == 0 && len(t.BG) == 0 {
|
||||
return text
|
||||
}
|
||||
// Combine foreground and background colors
|
||||
combinedColors := append(t.FG, t.BG...)
|
||||
// Create a color function and apply it to the text
|
||||
c := color.New(combinedColors...).SprintFunc()
|
||||
return c(text)
|
||||
}
|
||||
25
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
25
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -419,7 +418,6 @@ func (t *Table) Options(opts ...Option) *Table {
|
||||
}
|
||||
|
||||
// force debugging mode if set
|
||||
// This should be move away form WithDebug
|
||||
if t.config.Debug {
|
||||
t.logger.Enable()
|
||||
t.logger.Resume()
|
||||
@@ -434,11 +432,28 @@ func (t *Table) Options(opts ...Option) *Table {
|
||||
goArch := runtime.GOARCH
|
||||
numCPU := runtime.NumCPU()
|
||||
|
||||
t.logger.Infof("Environment: LC_CTYPE=%s, LANG=%s, TERM=%s", os.Getenv("LC_CTYPE"), os.Getenv("LANG"), os.Getenv("TERM"))
|
||||
t.logger.Infof("Go Runtime: Version=%s, OS=%s, Arch=%s, CPUs=%d", goVersion, goOS, goArch, numCPU)
|
||||
// Use the new struct-based info.
|
||||
// No type assertions or magic strings needed.
|
||||
info := twwidth.Debugging()
|
||||
|
||||
t.logger.Infof("Go Runtime: Version=%s, OS=%s, Arch=%s, CPUs=%d",
|
||||
goVersion, goOS, goArch, numCPU)
|
||||
|
||||
t.logger.Infof("Environment: LC_CTYPE=%s, LANG=%s, TERM=%s, TERM_PROGRAM=%s",
|
||||
info.Raw.LC_CTYPE,
|
||||
info.Raw.LANG,
|
||||
info.Raw.TERM,
|
||||
info.Raw.TERM_PROGRAM,
|
||||
)
|
||||
|
||||
t.logger.Infof("East Asian Detection: Auto=%v, Mode=%s, ModernEnv=%v, CJKLocale=%v",
|
||||
info.AutoUseEastAsian,
|
||||
info.DetectionMode,
|
||||
info.Derived.IsModernEnv,
|
||||
info.Derived.IsCJKLocale,
|
||||
)
|
||||
|
||||
// send logger to renderer
|
||||
// this will overwrite the default logger
|
||||
t.renderer.Logger(t.logger)
|
||||
return t
|
||||
}
|
||||
|
||||
22
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
22
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
@@ -991,7 +991,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
constraintTotalCellWidth := 0
|
||||
hasConstraint := false
|
||||
|
||||
// 1. Check new Widths.PerColumn (highest priority)
|
||||
// Check new Widths.PerColumn (highest priority)
|
||||
if t.config.Widths.Constrained() {
|
||||
|
||||
if colWidth, ok := t.config.Widths.PerColumn.OK(colIdx); ok && colWidth > 0 {
|
||||
@@ -1001,7 +1001,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
colIdx, constraintTotalCellWidth)
|
||||
}
|
||||
|
||||
// 2. Check new Widths.Global
|
||||
// Check new Widths.Global
|
||||
if !hasConstraint && t.config.Widths.Global > 0 {
|
||||
constraintTotalCellWidth = t.config.Widths.Global
|
||||
hasConstraint = true
|
||||
@@ -1009,7 +1009,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fall back to legacy ColMaxWidths.PerColumn (backward compatibility)
|
||||
// Fall back to legacy ColMaxWidths.PerColumn (backward compatibility)
|
||||
if !hasConstraint && config.ColMaxWidths.PerColumn != nil {
|
||||
if colMax, ok := config.ColMaxWidths.PerColumn.OK(colIdx); ok && colMax > 0 {
|
||||
constraintTotalCellWidth = colMax
|
||||
@@ -1019,7 +1019,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Fall back to legacy ColMaxWidths.Global
|
||||
// Fall back to legacy ColMaxWidths.Global
|
||||
if !hasConstraint && config.ColMaxWidths.Global > 0 {
|
||||
constraintTotalCellWidth = config.ColMaxWidths.Global
|
||||
hasConstraint = true
|
||||
@@ -1027,7 +1027,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
constraintTotalCellWidth)
|
||||
}
|
||||
|
||||
// 5. Fall back to table MaxWidth if auto-wrapping
|
||||
// Fall back to table MaxWidth if auto-wrapping
|
||||
if !hasConstraint && t.config.MaxWidth > 0 && config.Formatting.AutoWrap != tw.WrapNone {
|
||||
constraintTotalCellWidth = t.config.MaxWidth
|
||||
hasConstraint = true
|
||||
@@ -1217,14 +1217,10 @@ func (t *Table) convertToString(value interface{}) string {
|
||||
// convertItemToCells is responsible for converting a single input item (which could be
|
||||
// a struct, a basic type, or an item implementing Stringer/Formatter) into a slice
|
||||
// of strings, where each string represents a cell for the table row.
|
||||
// zoo.go
|
||||
|
||||
// convertItemToCells is responsible for converting a single input item into a slice of strings.
|
||||
// It now uses the unified struct parser for structs.
|
||||
func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
t.logger.Debugf("convertItemToCells: Converting item of type %T", item)
|
||||
|
||||
// 1. User-defined table-wide stringer (t.stringer) takes highest precedence.
|
||||
// User-defined table-wide stringer (t.stringer) takes highest precedence.
|
||||
if t.stringer != nil {
|
||||
res, err := t.convertToStringer(item)
|
||||
if err == nil {
|
||||
@@ -1234,13 +1230,13 @@ func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
t.logger.Warnf("convertItemToCells: Custom table stringer was set but incompatible for type %T: %v. Will attempt other methods.", item, err)
|
||||
}
|
||||
|
||||
// 2. Handle untyped nil directly.
|
||||
// Handle untyped nil directly.
|
||||
if item == nil {
|
||||
t.logger.Debugf("convertItemToCells: Item is untyped nil. Returning single empty cell.")
|
||||
return []string{""}, nil
|
||||
}
|
||||
|
||||
// 3. Use the new unified struct parser. It handles pointers and embedding.
|
||||
// Use the new unified struct parser. It handles pointers and embedding.
|
||||
// We only care about the values it returns.
|
||||
_, values := t.extractFieldsAndValuesFromStruct(item)
|
||||
if values != nil {
|
||||
@@ -1248,7 +1244,7 @@ func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// 4. Fallback for any other single item (e.g., basic types, or types that implement Stringer/Formatter).
|
||||
// Fallback for any other single item (e.g., basic types, or types that implement Stringer/Formatter).
|
||||
// This code path is now for non-struct types.
|
||||
if formatter, ok := item.(tw.Formatter); ok {
|
||||
t.logger.Debugf("convertItemToCells: Item (non-struct, type %T) is tw.Formatter. Using Format().", item)
|
||||
|
||||
12
vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/copy.go
generated
vendored
12
vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/copy.go
generated
vendored
@@ -517,13 +517,15 @@ func (s *svc) executeSpacesCopy(ctx context.Context, w http.ResponseWriter, sele
|
||||
return err
|
||||
}
|
||||
defer httpDownloadRes.Body.Close()
|
||||
if httpDownloadRes.StatusCode == http.StatusForbidden {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
b, err := errors.Marshal(http.StatusForbidden, http.StatusText(http.StatusForbidden), "", strconv.Itoa(http.StatusForbidden))
|
||||
switch httpDownloadRes.StatusCode {
|
||||
case http.StatusForbidden, http.StatusTooEarly:
|
||||
w.WriteHeader(httpDownloadRes.StatusCode)
|
||||
b, err := errors.Marshal(http.StatusForbidden, http.StatusText(httpDownloadRes.StatusCode), "", strconv.Itoa(httpDownloadRes.StatusCode))
|
||||
errors.HandleWebdavError(log, w, b, err)
|
||||
return nil
|
||||
}
|
||||
if httpDownloadRes.StatusCode != http.StatusOK {
|
||||
case http.StatusOK:
|
||||
// ok
|
||||
default:
|
||||
return fmt.Errorf("status code %d", httpDownloadRes.StatusCode)
|
||||
}
|
||||
|
||||
|
||||
3
vendor/github.com/opencloud-eu/reva/v2/pkg/rhttp/datatx/utils/download/download.go
generated
vendored
3
vendor/github.com/opencloud-eu/reva/v2/pkg/rhttp/datatx/utils/download/download.go
generated
vendored
@@ -275,6 +275,9 @@ func handleError(w http.ResponseWriter, log *zerolog.Logger, err error, action s
|
||||
case errtypes.Aborted:
|
||||
log.Debug().Err(err).Str("action", action).Msg("etags do not match")
|
||||
w.WriteHeader(http.StatusPreconditionFailed)
|
||||
case errtypes.TooEarly:
|
||||
log.Debug().Err(err).Str("action", action).Msg("file is still being processed")
|
||||
w.WriteHeader(http.StatusTooEarly)
|
||||
default:
|
||||
log.Error().Err(err).Str("action", action).Msg("unexpected error")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
||||
4
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
4
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
@@ -1089,6 +1089,10 @@ func (fs *Decomposedfs) Download(ctx context.Context, ref *provider.Reference, o
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if n.IsProcessing(ctx) {
|
||||
return nil, nil, errtypes.TooEarly("file is still being processed")
|
||||
}
|
||||
|
||||
rp, err := fs.p.AssemblePermissions(ctx, n)
|
||||
switch {
|
||||
case err != nil:
|
||||
|
||||
67
vendor/github.com/opencloud-eu/reva/v2/pkg/store/store.go
generated
vendored
67
vendor/github.com/opencloud-eu/reva/v2/pkg/store/store.go
generated
vendored
@@ -21,6 +21,7 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -32,6 +33,7 @@ import (
|
||||
"github.com/opencloud-eu/reva/v2/pkg/store/etcd"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/store/memory"
|
||||
"go-micro.dev/v4/logger"
|
||||
"go-micro.dev/v4/store"
|
||||
microstore "go-micro.dev/v4/store"
|
||||
)
|
||||
|
||||
@@ -125,19 +127,33 @@ func Create(opts ...microstore.Option) microstore.Store {
|
||||
return *ocMemStore
|
||||
case TypeNatsJS:
|
||||
opts, ttl, natsOptions := natsConfig(options.Logger, options.Context, opts)
|
||||
return natsjs.NewStore(
|
||||
store := natsjs.NewStore(
|
||||
append(opts,
|
||||
natsjs.NatsOptions(natsOptions), // always pass in properly initialized default nats options
|
||||
natsjs.DefaultTTL(ttl))..., // nats needs a DefaultTTL option as it does not support per Write TTL
|
||||
)
|
||||
|
||||
err := updateNatsStore(opts, ttl, natsOptions)
|
||||
if err != nil {
|
||||
options.Logger.Logf(logger.ErrorLevel, "failed to update nats-js store: '%s'", err.Error())
|
||||
}
|
||||
|
||||
return store
|
||||
case TypeNatsJSKV:
|
||||
opts, ttl, natsOptions := natsConfig(options.Logger, options.Context, opts)
|
||||
return natsjskv.NewStore(
|
||||
store := natsjskv.NewStore(
|
||||
append(opts,
|
||||
natsjskv.NatsOptions(natsOptions), // always pass in properly initialized default nats options
|
||||
natsjskv.EncodeKeys(), // nats has restrictions on the key, we cannot use slashes
|
||||
natsjskv.DefaultTTL(ttl))..., // nats needs a DefaultTTL option as it does not support per Write TTL
|
||||
)
|
||||
|
||||
err := updateNatsStore(opts, ttl, natsOptions)
|
||||
if err != nil {
|
||||
options.Logger.Logf(logger.ErrorLevel, "failed to update nats-js-kv store: '%s'", err.Error())
|
||||
}
|
||||
|
||||
return store
|
||||
case TypeMemory, "mem", "": // allow existing short form and use as default
|
||||
return microstore.NewMemoryStore(opts...)
|
||||
default:
|
||||
@@ -146,13 +162,58 @@ func Create(opts ...microstore.Option) microstore.Store {
|
||||
}
|
||||
}
|
||||
|
||||
func updateNatsStore(opts []store.Option, ttl time.Duration, natsOptions nats.Options) error {
|
||||
options := store.Options{}
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
bucketName := options.Database
|
||||
if bucketName == "" {
|
||||
return fmt.Errorf("bucket name (database) must be set")
|
||||
}
|
||||
|
||||
if len(options.Nodes) > 0 {
|
||||
natsOptions.Servers = options.Nodes
|
||||
}
|
||||
nc, err := natsOptions.Connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not connect to nats: %w", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
js, err := nc.JetStream()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// NATS KV buckets are actually streams named "KV_<bucket_name>"
|
||||
info, err := js.StreamInfo("KV_" + bucketName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get bucket info: %w", err)
|
||||
}
|
||||
|
||||
config := info.Config
|
||||
config.MaxAge = ttl
|
||||
|
||||
_, err = js.UpdateStream(&config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update bucket TTL: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func natsConfig(log logger.Logger, ctx context.Context, opts []microstore.Option) ([]microstore.Option, time.Duration, nats.Options) {
|
||||
|
||||
if mem, _ := ctx.Value(disablePersistanceContextKey{}).(bool); mem {
|
||||
opts = append(opts, natsjs.DefaultMemory())
|
||||
}
|
||||
|
||||
ttl, _ := ctx.Value(ttlContextKey{}).(time.Duration)
|
||||
ttl := time.Duration(0)
|
||||
if d, ok := ctx.Value(ttlContextKey{}).(time.Duration); ok {
|
||||
ttl = d
|
||||
}
|
||||
|
||||
// preparing natsOptions before the switch to reuse the same code
|
||||
natsOptions := nats.GetDefaultOptions()
|
||||
|
||||
19
vendor/modules.txt
vendored
19
vendor/modules.txt
vendored
@@ -255,7 +255,7 @@ github.com/cespare/xxhash/v2
|
||||
# github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73
|
||||
## explicit
|
||||
github.com/cevaris/ordered_map
|
||||
# github.com/clipperhouse/displaywidth v0.6.0
|
||||
# github.com/clipperhouse/displaywidth v0.6.2
|
||||
## explicit; go 1.18
|
||||
github.com/clipperhouse/displaywidth
|
||||
# github.com/clipperhouse/stringish v0.1.1
|
||||
@@ -637,9 +637,10 @@ github.com/go-redis/redis/v8/internal/pool
|
||||
github.com/go-redis/redis/v8/internal/proto
|
||||
github.com/go-redis/redis/v8/internal/rand
|
||||
github.com/go-redis/redis/v8/internal/util
|
||||
# github.com/go-resty/resty/v2 v2.7.0
|
||||
## explicit; go 1.11
|
||||
# github.com/go-resty/resty/v2 v2.17.1
|
||||
## explicit; go 1.23.0
|
||||
github.com/go-resty/resty/v2
|
||||
github.com/go-resty/resty/v2/shellescape
|
||||
# github.com/go-sql-driver/mysql v1.9.3
|
||||
## explicit; go 1.21.0
|
||||
github.com/go-sql-driver/mysql
|
||||
@@ -805,7 +806,7 @@ github.com/gorilla/schema
|
||||
## explicit; go 1.14
|
||||
github.com/grpc-ecosystem/go-grpc-middleware
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/recovery
|
||||
# github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4
|
||||
# github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5
|
||||
## explicit; go 1.24.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options
|
||||
@@ -1202,12 +1203,12 @@ github.com/olekukonko/cat
|
||||
# github.com/olekukonko/errors v1.1.0
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/errors
|
||||
# github.com/olekukonko/ll v0.1.3
|
||||
# github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/ll
|
||||
github.com/olekukonko/ll/lh
|
||||
github.com/olekukonko/ll/lx
|
||||
# github.com/olekukonko/tablewriter v1.1.2
|
||||
# github.com/olekukonko/tablewriter v1.1.3
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/tablewriter
|
||||
github.com/olekukonko/tablewriter/pkg/twcache
|
||||
@@ -1375,7 +1376,7 @@ github.com/opencloud-eu/icap-client
|
||||
# github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76
|
||||
## explicit; go 1.18
|
||||
github.com/opencloud-eu/libre-graph-api-go
|
||||
# github.com/opencloud-eu/reva/v2 v2.41.1-0.20260120144836-2769c3c07a19
|
||||
# github.com/opencloud-eu/reva/v2 v2.42.1
|
||||
## explicit; go 1.24.1
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/runtime
|
||||
@@ -2593,12 +2594,12 @@ golang.org/x/tools/internal/versions
|
||||
# google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb
|
||||
## explicit; go 1.23.0
|
||||
google.golang.org/genproto/protobuf/field_mask
|
||||
# google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b
|
||||
# google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516
|
||||
## explicit; go 1.24.0
|
||||
google.golang.org/genproto/googleapis/api
|
||||
google.golang.org/genproto/googleapis/api/annotations
|
||||
google.golang.org/genproto/googleapis/api/httpbody
|
||||
# google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b
|
||||
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516
|
||||
## explicit; go 1.24.0
|
||||
google.golang.org/genproto/googleapis/rpc/errdetails
|
||||
google.golang.org/genproto/googleapis/rpc/status
|
||||
|
||||
Reference in New Issue
Block a user