diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 468b13f62ac3..5998aad49340 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,4 @@ { ".": "3.0.0", - "operator": "0.6.0" + "operator": "0.6.1" } diff --git a/clients/cmd/promtail/promtail-local-config.yaml b/clients/cmd/promtail/promtail-local-config.yaml index 3b9256537ec8..fed2e1256a05 100644 --- a/clients/cmd/promtail/promtail-local-config.yaml +++ b/clients/cmd/promtail/promtail-local-config.yaml @@ -16,3 +16,4 @@ scrape_configs: labels: job: varlogs __path__: /var/log/*log + stream: stdout diff --git a/cmd/loki-canary/main.go b/cmd/loki-canary/main.go index 061b98321047..304bb1b1c3e9 100644 --- a/cmd/loki-canary/main.go +++ b/cmd/loki-canary/main.go @@ -79,6 +79,10 @@ func main() { metricTestQueryRange := flag.Duration("metric-test-range", 24*time.Hour, "The range value [24h] used in the metric test instant-query."+ " Note: this value is truncated to the running time of the canary until this value is reached") + cacheTestInterval := flag.Duration("cache-test-interval", 15*time.Minute, "The interval the cache test query should be run") + cacheTestQueryRange := flag.Duration("cache-test-range", 24*time.Hour, "The range value [24h] used in the cache test instant-query.") + cacheTestQueryNow := flag.Duration("cache-test-now", 1*time.Hour, "duration how far back from current time the execution time (--now) should be set for running this query in the cache test instant-query.") + spotCheckInterval := flag.Duration("spot-check-interval", 15*time.Minute, "Interval that a single result will be kept from sent entries and spot-checked against Loki, "+ "e.g. 15min default one entry every 15 min will be saved and then queried again every 15min until spot-check-max is reached") spotCheckMax := flag.Duration("spot-check-max", 4*time.Hour, "How far back to check a spot check entry before dropping it") @@ -189,7 +193,7 @@ func main() { _, _ = fmt.Fprintf(os.Stderr, "Unable to create reader for Loki querier, check config: %s", err) os.Exit(1) } - c.comparator = comparator.NewComparator(os.Stderr, *wait, *maxWait, *pruneInterval, *spotCheckInterval, *spotCheckMax, *spotCheckQueryRate, *spotCheckWait, *metricTestInterval, *metricTestQueryRange, *interval, *buckets, sentChan, receivedChan, c.reader, true) + c.comparator = comparator.NewComparator(os.Stderr, *wait, *maxWait, *pruneInterval, *spotCheckInterval, *spotCheckMax, *spotCheckQueryRate, *spotCheckWait, *metricTestInterval, *metricTestQueryRange, *cacheTestInterval, *cacheTestQueryRange, *cacheTestQueryNow, *interval, *buckets, sentChan, receivedChan, c.reader, true) } startCanary() diff --git a/cmd/loki/loki-local-config.yaml b/cmd/loki/loki-local-config.yaml index 03b579647753..913b9a4c1873 100644 --- a/cmd/loki/loki-local-config.yaml +++ b/cmd/loki/loki-local-config.yaml @@ -33,6 +33,11 @@ schema_config: prefix: index_ period: 24h +pattern_ingester: + enabled: true + metric_aggregation: + enabled: true + ruler: alertmanager_url: http://localhost:9093 diff --git a/cmd/lokitool/main.go b/cmd/lokitool/main.go index 6b52fb0a3d65..0bdff6614f5f 100644 --- a/cmd/lokitool/main.go +++ b/cmd/lokitool/main.go @@ -12,12 +12,14 @@ import ( ) var ( - ruleCommand commands.RuleCommand + ruleCommand commands.RuleCommand + auditCommand commands.AuditCommand ) func main() { app := kingpin.New("lokitool", "A command-line tool to manage Loki.") ruleCommand.Register(app) + auditCommand.Register(app) app.Command("version", "Get the version of the lokitool CLI").Action(func(k *kingpin.ParseContext) error { fmt.Println(version.Print("loki")) diff --git a/docs/sources/reference/loki-http-api.md b/docs/sources/reference/loki-http-api.md index e72a03ba51b0..c9df1a2896d7 100644 --- a/docs/sources/reference/loki-http-api.md +++ b/docs/sources/reference/loki-http-api.md @@ -627,6 +627,7 @@ It accepts the following query parameters in the URL: - `start`: The start time for the query as a nanosecond Unix epoch. Defaults to 6 hours ago. - `end`: The end time for the query as a nanosecond Unix epoch. Defaults to now. - `since`: A `duration` used to calculate `start` relative to `end`. If `end` is in the future, `start` is calculated as this duration before now. Any value specified for `start` supersedes this parameter. +- `query`: A set of log stream selector that selects the streams to match and return label names. Example: `{"app": "myapp", "environment": "dev"}` In microservices mode, `/loki/api/v1/labels` is exposed by the querier. diff --git a/docs/sources/shared/configuration.md b/docs/sources/shared/configuration.md index aa045ce1f977..9894cfa2ead6 100644 --- a/docs/sources/shared/configuration.md +++ b/docs/sources/shared/configuration.md @@ -316,6 +316,13 @@ pattern_ingester: # CLI flag: -pattern-ingester.flush-check-period [flush_check_period: | default = 30s] + # Configures the metric aggregation and storage behavior of the pattern + # ingester. + metric_aggregation: + # Whether the pattern ingester metric aggregation is enabled. + # CLI flag: -pattern-ingester.metric-aggregation.enabled + [enabled: | default = false] + # The index_gateway block configures the Loki index gateway server, responsible # for serving index queries without the need to constantly interact with the # object store. diff --git a/examples/README.md b/examples/README.md index fd0f1ee4cf00..fbaa1b6aa705 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,7 @@ You can use [Grafana Cloud](https://grafana.com/products/cloud/features/#cloud-l ## Getting started with Loki -Configuration files in the `getting-started` directory are used by the [Loki getting started guide](https://grafana.com/docs/loki/latest/getting-started/). +Configuration files in the `getting-started` directory are used by the [Loki getting started guide](https://grafana.com/docs/loki/latest/get-started/). ## Sending logs from Heroku to Loki diff --git a/go.mod b/go.mod index 470934fedcaf..37f075e62e3b 100644 --- a/go.mod +++ b/go.mod @@ -134,6 +134,7 @@ require ( github.com/prometheus/alertmanager v0.27.0 github.com/prometheus/common/sigv4 v0.1.0 github.com/richardartoul/molecule v1.0.0 + github.com/schollz/progressbar/v3 v3.14.2 github.com/shirou/gopsutil/v4 v4.24.0-alpha.1 github.com/thanos-io/objstore v0.0.0-20230829152104-1b257a36f9a3 github.com/willf/bloom v2.0.3+incompatible @@ -153,6 +154,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect @@ -286,7 +288,7 @@ require ( github.com/leodido/ragel-machinery v0.0.0-20181214104525-299bdde78165 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.58 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect diff --git a/go.sum b/go.sum index 76288a35335a..94ff46caf02f 100644 --- a/go.sum +++ b/go.sum @@ -1259,6 +1259,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= @@ -1355,8 +1356,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1625,6 +1626,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/richardartoul/molecule v1.0.0 h1:+LFA9cT7fn8KF39zy4dhOnwcOwRoqKiBkPqKqya+8+U= github.com/richardartoul/molecule v1.0.0/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+uGV8BrTv8W/SIwk= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1650,6 +1653,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 h1:/8rfZAdFfafRXOgz+ZpMZZWZ5pYggCY9t7e/BvjaBHM= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/schollz/progressbar/v3 v3.14.2 h1:EducH6uNLIWsr560zSV1KrTeUb/wZGAHqyMFIEa99ks= +github.com/schollz/progressbar/v3 v3.14.2/go.mod h1:aQAZQnhF4JGFtRJiw/eobaXpsqpVQAftEQ+hLGXaRc4= github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -2257,6 +2262,7 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -2266,6 +2272,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/operator/CHANGELOG.md b/operator/CHANGELOG.md index cf21948497dd..2651831719e4 100644 --- a/operator/CHANGELOG.md +++ b/operator/CHANGELOG.md @@ -1,5 +1,22 @@ ## Main +## [0.6.1](https://github.com/grafana/loki/compare/operator/v0.6.0...operator/v0.6.1) (2024-06-03) + + +### Features + +* prepare 3.0.0 release candidate ([#12348](https://github.com/grafana/loki/issues/12348)) ([664e569](https://github.com/grafana/loki/commit/664e569e14ef55a79cd77bdb49e9ffbe0c55bc37)) + + +### Bug Fixes + +* **operator:** Bump golang builder to 1.21.9 ([#12503](https://github.com/grafana/loki/issues/12503)) ([f680ee0](https://github.com/grafana/loki/commit/f680ee0453d1b7d315774591293927b988bca223)) +* **operator:** Configure Loki to use virtual-host-style URLs for S3 AWS endpoints ([#12469](https://github.com/grafana/loki/issues/12469)) ([0084262](https://github.com/grafana/loki/commit/0084262269f4e2cb94d04e0cc0d40e9666177f06)) +* **operator:** Improve validation of provided S3 storage configuration ([#12181](https://github.com/grafana/loki/issues/12181)) ([f9350d6](https://github.com/grafana/loki/commit/f9350d6415d45c3cc2f9c0b4f7cd6f8f219907f2)) +* **operator:** Use a minimum value for replay memory ceiling ([#13066](https://github.com/grafana/loki/issues/13066)) ([4f3ed77](https://github.com/grafana/loki/commit/4f3ed77cb92c2ffd605743237e609c28f7841728)) +* update to build image 0.33.2, fixes bug with promtail windows DNS resolution ([#12732](https://github.com/grafana/loki/issues/12732)) ([759f42d](https://github.com/grafana/loki/commit/759f42dd50bb4896f5e568691ef32245bb8fb25a)) +* updated all dockerfiles go1.22 ([#12708](https://github.com/grafana/loki/issues/12708)) ([71a8f2c](https://github.com/grafana/loki/commit/71a8f2c2b11b419bd8c0af1f859671e5d8730448)) + ## 0.6.0 (2024-03-19) - [12228](https://github.com/grafana/loki/pull/12228) **xperimental**: Restructure LokiStack metrics diff --git a/operator/Makefile b/operator/Makefile index 94be0bfa3dba..3be618f551b1 100644 --- a/operator/Makefile +++ b/operator/Makefile @@ -21,7 +21,7 @@ LOKI_OPERATOR_NS ?= kubernetes-operators # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.6.0 +VERSION ?= 0.6.1 CHANNELS ?= "alpha" DEFAULT_CHANNEL ?= "alpha" diff --git a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml index f70abb4d999e..d15e930efe88 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml @@ -3,9 +3,9 @@ kind: ServiceAccount metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-metrics-reader diff --git a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml index b327a8201909..03115d44fdad 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml @@ -6,11 +6,11 @@ metadata: creationTimestamp: null labels: app.kubernetes.io/component: metrics - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-metrics-service spec: ports: diff --git a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-token_v1_secret.yaml b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-token_v1_secret.yaml index 0f36a8cdaa48..109b3393f998 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-token_v1_secret.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-metrics-token_v1_secret.yaml @@ -4,10 +4,10 @@ metadata: annotations: kubernetes.io/service-account.name: loki-operator-controller-manager-metrics-reader labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-metrics-token type: kubernetes.io/service-account-token diff --git a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml index 533ff774c834..97d00df9c4ef 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml @@ -3,11 +3,11 @@ kind: ClusterRoleBinding metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-read-metrics roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/operator/bundle/community-openshift/manifests/loki-operator-manager-config_v1_configmap.yaml b/operator/bundle/community-openshift/manifests/loki-operator-manager-config_v1_configmap.yaml index 75f9981dbd18..4cc96b7926fc 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-manager-config_v1_configmap.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-manager-config_v1_configmap.yaml @@ -60,9 +60,9 @@ data: kind: ConfigMap metadata: labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-manager-config diff --git a/operator/bundle/community-openshift/manifests/loki-operator-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml b/operator/bundle/community-openshift/manifests/loki-operator-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml index 56302724d3e6..53b6d9edb87e 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml @@ -2,11 +2,11 @@ apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator name: loki-operator-metrics-monitor spec: diff --git a/operator/bundle/community-openshift/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/operator/bundle/community-openshift/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index cf0bd9ff0eb8..6b4e2e91a201 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -3,11 +3,11 @@ kind: ClusterRole metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-metrics-reader rules: - nonResourceURLs: diff --git a/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml b/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml index 1537ebf1e0d8..79175acf5583 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml @@ -6,11 +6,11 @@ metadata: include.release.openshift.io/single-node-developer: "true" creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-prometheus rules: - apiGroups: diff --git a/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml b/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml index 9e5f02aa8112..32cc55393781 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml @@ -6,11 +6,11 @@ metadata: include.release.openshift.io/single-node-developer: "true" creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-prometheus roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/operator/bundle/community-openshift/manifests/loki-operator-webhook-service_v1_service.yaml b/operator/bundle/community-openshift/manifests/loki-operator-webhook-service_v1_service.yaml index c26fdd1ec852..2fe1edca6fd2 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator-webhook-service_v1_service.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator-webhook-service_v1_service.yaml @@ -3,11 +3,11 @@ kind: Service metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-webhook-service spec: ports: diff --git a/operator/bundle/community-openshift/manifests/loki-operator.clusterserviceversion.yaml b/operator/bundle/community-openshift/manifests/loki-operator.clusterserviceversion.yaml index f61858e23410..fdd8b98c0e3b 100644 --- a/operator/bundle/community-openshift/manifests/loki-operator.clusterserviceversion.yaml +++ b/operator/bundle/community-openshift/manifests/loki-operator.clusterserviceversion.yaml @@ -149,8 +149,8 @@ metadata: capabilities: Full Lifecycle categories: OpenShift Optional, Logging & Tracing certified: "false" - containerImage: docker.io/grafana/loki-operator:0.6.0 - createdAt: "2024-05-03T11:49:48Z" + containerImage: docker.io/grafana/loki-operator:0.6.1 + createdAt: "2024-06-03T10:01:23Z" description: The Community Loki Operator provides Kubernetes native deployment and management of Loki and related logging components. features.operators.openshift.io/disconnected: "true" @@ -167,7 +167,7 @@ metadata: labels: operatorframework.io/arch.amd64: supported operatorframework.io/arch.arm64: supported - name: loki-operator.v0.6.0 + name: loki-operator.v0.6.1 namespace: placeholder spec: apiservicedefinitions: {} @@ -1681,11 +1681,11 @@ spec: serviceAccountName: loki-operator-controller-manager deployments: - label: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 control-plane: controller-manager name: loki-operator-controller-manager spec: @@ -1719,7 +1719,7 @@ spec: value: quay.io/observatorium/api:latest - name: RELATED_IMAGE_OPA value: quay.io/observatorium/opa-openshift:latest - image: docker.io/grafana/loki-operator:0.6.0 + image: docker.io/grafana/loki-operator:0.6.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -1844,8 +1844,8 @@ spec: name: gateway - image: quay.io/observatorium/opa-openshift:latest name: opa - replaces: loki-operator.v0.5.0 - version: 0.6.0 + replaces: loki-operator.v0.6.0 + version: 0.6.1 webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/operator/bundle/community-openshift/manifests/loki.grafana.com_alertingrules.yaml b/operator/bundle/community-openshift/manifests/loki.grafana.com_alertingrules.yaml index 5b1874582938..64298e8d5062 100644 --- a/operator/bundle/community-openshift/manifests/loki.grafana.com_alertingrules.yaml +++ b/operator/bundle/community-openshift/manifests/loki.grafana.com_alertingrules.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: alertingrules.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community-openshift/manifests/loki.grafana.com_lokistacks.yaml b/operator/bundle/community-openshift/manifests/loki.grafana.com_lokistacks.yaml index 9264012b4657..b5ca838eff14 100644 --- a/operator/bundle/community-openshift/manifests/loki.grafana.com_lokistacks.yaml +++ b/operator/bundle/community-openshift/manifests/loki.grafana.com_lokistacks.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: lokistacks.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community-openshift/manifests/loki.grafana.com_recordingrules.yaml b/operator/bundle/community-openshift/manifests/loki.grafana.com_recordingrules.yaml index 134fe3c5700e..cdef169a4ced 100644 --- a/operator/bundle/community-openshift/manifests/loki.grafana.com_recordingrules.yaml +++ b/operator/bundle/community-openshift/manifests/loki.grafana.com_recordingrules.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: recordingrules.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community-openshift/manifests/loki.grafana.com_rulerconfigs.yaml b/operator/bundle/community-openshift/manifests/loki.grafana.com_rulerconfigs.yaml index 21446c58925d..1969480f8437 100644 --- a/operator/bundle/community-openshift/manifests/loki.grafana.com_rulerconfigs.yaml +++ b/operator/bundle/community-openshift/manifests/loki.grafana.com_rulerconfigs.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: rulerconfigs.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml b/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml index f70abb4d999e..d15e930efe88 100644 --- a/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml +++ b/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-reader_v1_serviceaccount.yaml @@ -3,9 +3,9 @@ kind: ServiceAccount metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-metrics-reader diff --git a/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml b/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml index 7c323ddde05f..8738be99aa87 100644 --- a/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml +++ b/operator/bundle/community/manifests/loki-operator-controller-manager-metrics-service_v1_service.yaml @@ -4,11 +4,11 @@ metadata: creationTimestamp: null labels: app.kubernetes.io/component: metrics - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-metrics-service spec: ports: diff --git a/operator/bundle/community/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml b/operator/bundle/community/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml index 871537f3d2e7..242c0978035a 100644 --- a/operator/bundle/community/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml +++ b/operator/bundle/community/manifests/loki-operator-controller-manager-read-metrics_rbac.authorization.k8s.io_v1_clusterrolebinding.yaml @@ -3,11 +3,11 @@ kind: ClusterRoleBinding metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-controller-manager-read-metrics roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/operator/bundle/community/manifests/loki-operator-manager-config_v1_configmap.yaml b/operator/bundle/community/manifests/loki-operator-manager-config_v1_configmap.yaml index d55b089593ed..56c15b0fca2c 100644 --- a/operator/bundle/community/manifests/loki-operator-manager-config_v1_configmap.yaml +++ b/operator/bundle/community/manifests/loki-operator-manager-config_v1_configmap.yaml @@ -24,9 +24,9 @@ data: kind: ConfigMap metadata: labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-manager-config diff --git a/operator/bundle/community/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/operator/bundle/community/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index cf0bd9ff0eb8..6b4e2e91a201 100644 --- a/operator/bundle/community/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/operator/bundle/community/manifests/loki-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -3,11 +3,11 @@ kind: ClusterRole metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-metrics-reader rules: - nonResourceURLs: diff --git a/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml b/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml index 1537ebf1e0d8..79175acf5583 100644 --- a/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml +++ b/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml @@ -6,11 +6,11 @@ metadata: include.release.openshift.io/single-node-developer: "true" creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-prometheus rules: - apiGroups: diff --git a/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml b/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml index 9e5f02aa8112..32cc55393781 100644 --- a/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml +++ b/operator/bundle/community/manifests/loki-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml @@ -6,11 +6,11 @@ metadata: include.release.openshift.io/single-node-developer: "true" creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-prometheus roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/operator/bundle/community/manifests/loki-operator-webhook-service_v1_service.yaml b/operator/bundle/community/manifests/loki-operator-webhook-service_v1_service.yaml index c26fdd1ec852..2fe1edca6fd2 100644 --- a/operator/bundle/community/manifests/loki-operator-webhook-service_v1_service.yaml +++ b/operator/bundle/community/manifests/loki-operator-webhook-service_v1_service.yaml @@ -3,11 +3,11 @@ kind: Service metadata: creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: loki-operator-webhook-service spec: ports: diff --git a/operator/bundle/community/manifests/loki-operator.clusterserviceversion.yaml b/operator/bundle/community/manifests/loki-operator.clusterserviceversion.yaml index bc7d9388745b..4a91115484c9 100644 --- a/operator/bundle/community/manifests/loki-operator.clusterserviceversion.yaml +++ b/operator/bundle/community/manifests/loki-operator.clusterserviceversion.yaml @@ -149,8 +149,8 @@ metadata: capabilities: Full Lifecycle categories: OpenShift Optional, Logging & Tracing certified: "false" - containerImage: docker.io/grafana/loki-operator:0.6.0 - createdAt: "2024-05-03T11:49:46Z" + containerImage: docker.io/grafana/loki-operator:0.6.1 + createdAt: "2024-06-03T10:01:22Z" description: The Community Loki Operator provides Kubernetes native deployment and management of Loki and related logging components. operators.operatorframework.io/builder: operator-sdk-unknown @@ -160,7 +160,7 @@ metadata: labels: operatorframework.io/arch.amd64: supported operatorframework.io/arch.arm64: supported - name: loki-operator.v0.6.0 + name: loki-operator.v0.6.1 namespace: placeholder spec: apiservicedefinitions: {} @@ -1661,11 +1661,11 @@ spec: serviceAccountName: loki-operator-controller-manager deployments: - label: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 control-plane: controller-manager name: loki-operator-controller-manager spec: @@ -1699,7 +1699,7 @@ spec: value: quay.io/observatorium/api:latest - name: RELATED_IMAGE_OPA value: quay.io/observatorium/opa-openshift:latest - image: docker.io/grafana/loki-operator:0.6.0 + image: docker.io/grafana/loki-operator:0.6.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -1812,8 +1812,8 @@ spec: name: gateway - image: quay.io/observatorium/opa-openshift:latest name: opa - replaces: loki-operator.v0.5.0 - version: 0.6.0 + replaces: loki-operator.v0.6.0 + version: 0.6.1 webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/operator/bundle/community/manifests/loki.grafana.com_alertingrules.yaml b/operator/bundle/community/manifests/loki.grafana.com_alertingrules.yaml index 3cbb4d71c8ec..6a8d8c78d103 100644 --- a/operator/bundle/community/manifests/loki.grafana.com_alertingrules.yaml +++ b/operator/bundle/community/manifests/loki.grafana.com_alertingrules.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: alertingrules.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community/manifests/loki.grafana.com_lokistacks.yaml b/operator/bundle/community/manifests/loki.grafana.com_lokistacks.yaml index 47094ec29958..f2ccf71f8c23 100644 --- a/operator/bundle/community/manifests/loki.grafana.com_lokistacks.yaml +++ b/operator/bundle/community/manifests/loki.grafana.com_lokistacks.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: lokistacks.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community/manifests/loki.grafana.com_recordingrules.yaml b/operator/bundle/community/manifests/loki.grafana.com_recordingrules.yaml index bb79347b58cd..8018b4a15207 100644 --- a/operator/bundle/community/manifests/loki.grafana.com_recordingrules.yaml +++ b/operator/bundle/community/manifests/loki.grafana.com_recordingrules.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: recordingrules.loki.grafana.com spec: conversion: diff --git a/operator/bundle/community/manifests/loki.grafana.com_rulerconfigs.yaml b/operator/bundle/community/manifests/loki.grafana.com_rulerconfigs.yaml index 80177cd5097b..1057ece6a2ed 100644 --- a/operator/bundle/community/manifests/loki.grafana.com_rulerconfigs.yaml +++ b/operator/bundle/community/manifests/loki.grafana.com_rulerconfigs.yaml @@ -5,11 +5,11 @@ metadata: controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: - app.kubernetes.io/instance: loki-operator-v0.6.0 + app.kubernetes.io/instance: loki-operator-v0.6.1 app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: loki-operator app.kubernetes.io/part-of: loki-operator - app.kubernetes.io/version: 0.6.0 + app.kubernetes.io/version: 0.6.1 name: rulerconfigs.loki.grafana.com spec: conversion: diff --git a/operator/bundle/openshift/manifests/loki-operator.clusterserviceversion.yaml b/operator/bundle/openshift/manifests/loki-operator.clusterserviceversion.yaml index ec55ffc71732..a5b77fdc6e23 100644 --- a/operator/bundle/openshift/manifests/loki-operator.clusterserviceversion.yaml +++ b/operator/bundle/openshift/manifests/loki-operator.clusterserviceversion.yaml @@ -150,7 +150,7 @@ metadata: categories: OpenShift Optional, Logging & Tracing certified: "false" containerImage: quay.io/openshift-logging/loki-operator:0.1.0 - createdAt: "2024-05-03T11:49:50Z" + createdAt: "2024-06-03T10:01:25Z" description: | The Loki Operator for OCP provides a means for configuring and managing a Loki stack for cluster logging. ## Prerequisites and Requirements diff --git a/operator/config/manifests/community-openshift/bases/loki-operator.clusterserviceversion.yaml b/operator/config/manifests/community-openshift/bases/loki-operator.clusterserviceversion.yaml index 55e7c2b3cde5..649b8d0739ec 100644 --- a/operator/config/manifests/community-openshift/bases/loki-operator.clusterserviceversion.yaml +++ b/operator/config/manifests/community-openshift/bases/loki-operator.clusterserviceversion.yaml @@ -6,7 +6,7 @@ metadata: capabilities: Full Lifecycle categories: OpenShift Optional, Logging & Tracing certified: "false" - containerImage: docker.io/grafana/loki-operator:0.6.0 + containerImage: docker.io/grafana/loki-operator:0.6.1 createdAt: "2022-12-22T13:28:40+00:00" description: The Community Loki Operator provides Kubernetes native deployment and management of Loki and related logging components. @@ -2259,5 +2259,5 @@ spec: minKubeVersion: 1.21.1 provider: name: Grafana Loki SIG Operator - replaces: loki-operator.v0.5.0 + replaces: loki-operator.v0.6.0 version: 0.0.0 diff --git a/operator/config/manifests/community/bases/loki-operator.clusterserviceversion.yaml b/operator/config/manifests/community/bases/loki-operator.clusterserviceversion.yaml index c3f139d8fb7b..24f52dc2acd0 100644 --- a/operator/config/manifests/community/bases/loki-operator.clusterserviceversion.yaml +++ b/operator/config/manifests/community/bases/loki-operator.clusterserviceversion.yaml @@ -6,7 +6,7 @@ metadata: capabilities: Full Lifecycle categories: OpenShift Optional, Logging & Tracing certified: "false" - containerImage: docker.io/grafana/loki-operator:0.6.0 + containerImage: docker.io/grafana/loki-operator:0.6.1 createdAt: "2022-12-22T13:28:40+00:00" description: The Community Loki Operator provides Kubernetes native deployment and management of Loki and related logging components. @@ -2239,5 +2239,5 @@ spec: minKubeVersion: 1.21.1 provider: name: Grafana Loki SIG Operator - replaces: loki-operator.v0.5.0 + replaces: loki-operator.v0.6.0 version: 0.0.0 diff --git a/operator/config/overlays/community-openshift/kustomization.yaml b/operator/config/overlays/community-openshift/kustomization.yaml index c0d952afd73f..bf76d87727c8 100644 --- a/operator/config/overlays/community-openshift/kustomization.yaml +++ b/operator/config/overlays/community-openshift/kustomization.yaml @@ -11,8 +11,8 @@ labels: app.kubernetes.io/managed-by: operator-lifecycle-manager includeSelectors: true - pairs: - app.kubernetes.io/instance: loki-operator-v0.6.0 - app.kubernetes.io/version: "0.6.0" + app.kubernetes.io/instance: loki-operator-v0.6.1 + app.kubernetes.io/version: "0.6.1" configMapGenerator: - files: @@ -27,4 +27,4 @@ patchesStrategicMerge: images: - name: controller newName: docker.io/grafana/loki-operator - newTag: 0.6.0 + newTag: 0.6.1 diff --git a/operator/config/overlays/community/kustomization.yaml b/operator/config/overlays/community/kustomization.yaml index 7caaab03255c..c6db762d38a5 100644 --- a/operator/config/overlays/community/kustomization.yaml +++ b/operator/config/overlays/community/kustomization.yaml @@ -22,8 +22,8 @@ labels: app.kubernetes.io/managed-by: operator-lifecycle-manager includeSelectors: true - pairs: - app.kubernetes.io/instance: loki-operator-v0.6.0 - app.kubernetes.io/version: "0.6.0" + app.kubernetes.io/instance: loki-operator-v0.6.1 + app.kubernetes.io/version: "0.6.1" generatorOptions: disableNameSuffixHash: true @@ -43,7 +43,7 @@ patchesStrategicMerge: images: - name: controller newName: docker.io/grafana/loki-operator - newTag: 0.6.0 + newTag: 0.6.1 # the following config is for teaching kustomize how to do var substitution vars: diff --git a/operator/internal/manifests/internal/config/build_test.go b/operator/internal/manifests/internal/config/build_test.go index fa20c45a0226..1d9a0287b398 100644 --- a/operator/internal/manifests/internal/config/build_test.go +++ b/operator/internal/manifests/internal/config/build_test.go @@ -69,7 +69,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 536870912 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -240,7 +240,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 0, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -327,7 +327,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -588,7 +588,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -673,7 +673,7 @@ func TestBuild_ConfigAndRuntimeConfig_CreateLokiConfigFailed(t *testing.T) { }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -754,7 +754,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -1026,7 +1026,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -1113,7 +1113,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -1386,7 +1386,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -1473,7 +1473,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -1776,7 +1776,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -1866,7 +1866,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -2112,7 +2112,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -2202,7 +2202,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -2535,7 +2535,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -2635,7 +2635,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -2881,7 +2881,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -2967,7 +2967,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -3377,7 +3377,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -3465,7 +3465,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -3638,7 +3638,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -3727,7 +3727,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -3901,7 +3901,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -3990,7 +3990,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -4162,7 +4162,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -4254,7 +4254,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -4460,7 +4460,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -4554,7 +4554,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -4760,7 +4760,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -4852,7 +4852,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -5019,7 +5019,7 @@ overrides: }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -5109,7 +5109,7 @@ func defaultOptions() Options { }, WriteAheadLog: WriteAheadLog{ Directory: "/tmp/wal", - IngesterMemoryRequest: 5000, + IngesterMemoryRequest: 4 * 1024 * 1024 * 1024, }, ObjectStorage: storage.Options{ SharedStore: lokiv1.ObjectStorageSecretS3, @@ -5343,7 +5343,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 @@ -5518,7 +5518,7 @@ ingester: wal: enabled: true dir: /tmp/wal - replay_memory_ceiling: 2500 + replay_memory_ceiling: 2147483648 ingester_client: grpc_client_config: max_recv_msg_size: 67108864 diff --git a/operator/internal/manifests/internal/config/options.go b/operator/internal/manifests/internal/config/options.go index 110bce9ee8df..e19d4c34f326 100644 --- a/operator/internal/manifests/internal/config/options.go +++ b/operator/internal/manifests/internal/config/options.go @@ -223,10 +223,20 @@ type WriteAheadLog struct { IngesterMemoryRequest int64 } +const ( + // minimumReplayCeiling contains the minimum value that will be used for the replay_memory_ceiling. + // It is set, so that even when the ingester has a low memory request, the replay will not flush each block + // on its own. + minimumReplayCeiling = 512 * 1024 * 1024 +) + // ReplayMemoryCeiling calculates 50% of the ingester memory // for the ingester to use for the write-ahead-log capbability. func (w WriteAheadLog) ReplayMemoryCeiling() string { value := int64(math.Ceil(float64(w.IngesterMemoryRequest) * float64(0.5))) + if value < minimumReplayCeiling { + value = minimumReplayCeiling + } return fmt.Sprintf("%d", value) } diff --git a/pkg/canary/comparator/comparator.go b/pkg/canary/comparator/comparator.go index 8f57af09ba78..a575c74eccd8 100644 --- a/pkg/canary/comparator/comparator.go +++ b/pkg/canary/comparator/comparator.go @@ -3,6 +3,7 @@ package comparator import ( "fmt" "io" + "math" "math/rand" "sync" "time" @@ -24,6 +25,8 @@ const ( DebugWebsocketMissingEntry = "websocket missing entry: %v\n" DebugQueryResult = "confirmation query result: %v\n" DebugEntryFound = "missing websocket entry %v was found %v seconds after it was originally sent\n" + + floatDiffTolerance = 1e-6 ) var ( @@ -90,6 +93,16 @@ var ( Help: "how long the spot check test query execution took in seconds.", Buckets: instrument.DefBuckets, }) + queryResultsDiff = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: "loki_canary", + Name: "cache_test_query_results_diff_total", + Help: "counts number of times the query results was different with and without cache ", + }) + queryResultsTotal = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "loki_canary", + Name: "cache_test_query_results_total", + Help: "counts number of times the query results test requests are done ", + }, []string{"status"}) // status=success/failure ) type Comparator struct { @@ -98,6 +111,7 @@ type Comparator struct { spotEntMtx sync.Mutex // Locks access to []spotCheck spotMtx sync.Mutex // Locks spotcheckRunning for single threaded but async spotCheck() metTestMtx sync.Mutex // Locks metricTestRunning for single threaded but async metricTest() + cacheTestMtx sync.Mutex // Locks cacheTestRunning for single threaded but async cacheTest() pruneMtx sync.Mutex // Locks pruneEntriesRunning for single threaded but async pruneEntries() w io.Writer entries []*time.Time @@ -116,14 +130,19 @@ type Comparator struct { metricTestInterval time.Duration metricTestRange time.Duration metricTestRunning bool - writeInterval time.Duration - confirmAsync bool - startTime time.Time - sent chan time.Time - recv chan time.Time - rdr reader.LokiReader - quit chan struct{} - done chan struct{} + cacheTestInterval time.Duration + cacheTestRange time.Duration + // how far back from current time the execution time (--now) should be set for running this query. + cacheTestNow time.Duration + cacheTestRunning bool + writeInterval time.Duration + confirmAsync bool + startTime time.Time + sent chan time.Time + recv chan time.Time + rdr reader.LokiReader + quit chan struct{} + done chan struct{} } func NewComparator(writer io.Writer, @@ -133,6 +152,9 @@ func NewComparator(writer io.Writer, spotCheckInterval, spotCheckMax, spotCheckQueryRate, spotCheckWait time.Duration, metricTestInterval time.Duration, metricTestRange time.Duration, + cacheTestInterval time.Duration, + cacheTestRange time.Duration, + cacheTestNow time.Duration, writeInterval time.Duration, buckets int, sentChan chan time.Time, @@ -155,6 +177,10 @@ func NewComparator(writer io.Writer, metricTestInterval: metricTestInterval, metricTestRange: metricTestRange, metricTestRunning: false, + cacheTestInterval: cacheTestInterval, + cacheTestRange: cacheTestRange, + cacheTestNow: cacheTestNow, + cacheTestRunning: false, writeInterval: writeInterval, confirmAsync: confirmAsync, startTime: time.Now(), @@ -252,10 +278,12 @@ func (c *Comparator) run() { randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano())) mt := time.NewTicker(time.Duration(randomGenerator.Int63n(c.metricTestInterval.Nanoseconds()))) sc := time.NewTicker(c.spotCheckQueryRate) + ct := time.NewTicker(c.cacheTestInterval) defer func() { t.Stop() mt.Stop() sc.Stop() + ct.Stop() close(c.done) }() @@ -294,12 +322,65 @@ func (c *Comparator) run() { firstMt = false mt.Reset(c.metricTestInterval) } + case <-ct.C: + // Only run one instance of cache tests at a time. + c.cacheTestMtx.Lock() + if !c.cacheTestRunning { + c.cacheTestRunning = true + go c.cacheTest(time.Now()) + } + c.cacheTestMtx.Unlock() + case <-c.quit: return } } } +func (c *Comparator) cacheTest(currTime time.Time) { + defer func() { + c.cacheTestMtx.Lock() + c.cacheTestRunning = false + c.cacheTestMtx.Unlock() + }() + + // cacheTest is currently run using `reader.CountOverTime()` which is an instant query. + // We make the query with and without cache over the data that is not changing (e.g: --now="1hr ago") instead of on latest data that is a moving target. + queryStartTime := currTime.Add(-c.cacheTestNow) + + // We cannot query for range before the pod even started. + if queryStartTime.Before(c.startTime) { + // we wait. + fmt.Fprintf(c.w, "cacheTest not run. still waiting for query start range(%s) to past the process start time(%s).\n", queryStartTime, c.startTime) + return + } + + rangeDuration := c.cacheTestRange + rng := fmt.Sprintf("%.0fs", rangeDuration.Seconds()) + + // with cache + countCache, err := c.rdr.QueryCountOverTime(rng, queryStartTime, true) + if err != nil { + fmt.Fprintf(c.w, "error running cache query test with cache: %s\n", err.Error()) + queryResultsTotal.WithLabelValues("failure").Inc() + return + } + + // without cache + countNocache, err := c.rdr.QueryCountOverTime(rng, queryStartTime, false) + if err != nil { + fmt.Fprintf(c.w, "error running cache query test without cache: %s\n", err.Error()) + queryResultsTotal.WithLabelValues("failure").Inc() + return + } + + queryResultsTotal.WithLabelValues("success").Inc() + if math.Abs(countNocache-countCache) > floatDiffTolerance { + queryResultsDiff.Inc() + fmt.Fprintf(c.w, "found a diff in instant query results time: %s, result_with_cache: %v, result_without_cache: %v\n", queryStartTime, countCache, countNocache) + } +} + // check that the expected # of log lines have been written to Loki func (c *Comparator) metricTest(currTime time.Time) { // Always make sure to set the running state back to false @@ -317,7 +398,7 @@ func (c *Comparator) metricTest(currTime time.Time) { adjustedRange = currTime.Sub(c.startTime) } begin := time.Now() - actualCount, err := c.rdr.QueryCountOverTime(fmt.Sprintf("%.0fs", adjustedRange.Seconds())) + actualCount, err := c.rdr.QueryCountOverTime(fmt.Sprintf("%.0fs", adjustedRange.Seconds()), begin, true) metricTestLatency.Observe(time.Since(begin).Seconds()) if err != nil { fmt.Fprintf(c.w, "error running metric query test: %s\n", err.Error()) diff --git a/pkg/canary/comparator/comparator_test.go b/pkg/canary/comparator/comparator_test.go index 39c868fb0dd3..db28545397e3 100644 --- a/pkg/canary/comparator/comparator_test.go +++ b/pkg/canary/comparator/comparator_test.go @@ -19,7 +19,7 @@ func TestComparatorEntryReceivedOutOfOrder(t *testing.T) { duplicateEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) t1 := time.Now() t2 := t1.Add(1 * time.Second) @@ -60,7 +60,7 @@ func TestComparatorEntryReceivedNotExpected(t *testing.T) { duplicateEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) t1 := time.Now() t2 := t1.Add(1 * time.Second) @@ -101,7 +101,7 @@ func TestComparatorEntryReceivedDuplicate(t *testing.T) { duplicateEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) t1 := time.Unix(0, 0) t2 := t1.Add(1 * time.Second) @@ -159,7 +159,7 @@ func TestEntryNeverReceived(t *testing.T) { wait := 60 * time.Second maxWait := 300 * time.Second //We set the prune interval timer to a huge value here so that it never runs, instead we call pruneEntries manually below - c := NewComparator(actual, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) + c := NewComparator(actual, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) c.entrySent(t1) c.entrySent(t2) @@ -232,7 +232,7 @@ func TestConcurrentConfirmMissing(t *testing.T) { wait := 30 * time.Millisecond maxWait := 30 * time.Millisecond - c := NewComparator(output, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) + c := NewComparator(output, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) for _, t := range found { tCopy := t @@ -263,7 +263,7 @@ func TestPruneAckdEntires(t *testing.T) { wait := 30 * time.Millisecond maxWait := 30 * time.Millisecond //We set the prune interval timer to a huge value here so that it never runs, instead we call pruneEntries manually below - c := NewComparator(actual, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) + c := NewComparator(actual, wait, maxWait, 50*time.Hour, 15*time.Minute, 4*time.Hour, 4*time.Hour, 0, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), nil, false) t1 := time.Unix(0, 0) t2 := t1.Add(1 * time.Millisecond) @@ -320,7 +320,7 @@ func TestSpotCheck(t *testing.T) { spotCheck := 10 * time.Millisecond spotCheckMax := 20 * time.Millisecond //We set the prune interval timer to a huge value here so that it never runs, instead we call spotCheckEntries manually below - c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 50*time.Hour, spotCheck, spotCheckMax, 4*time.Hour, 3*time.Millisecond, 1*time.Minute, 0, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 50*time.Hour, spotCheck, spotCheckMax, 4*time.Hour, 3*time.Millisecond, 1*time.Minute, 0, 1*time.Hour, 3*time.Hour, 30*time.Minute, 0, 1, make(chan time.Time), make(chan time.Time), mr, false) // Send all the entries for i := range entries { @@ -360,6 +360,42 @@ func TestSpotCheck(t *testing.T) { prometheus.Unregister(responseLatency) } +func TestCacheTest(t *testing.T) { + actual := &bytes.Buffer{} + mr := &mockReader{} + now := time.Now() + cacheTestInterval := 500 * time.Millisecond + cacheTestRange := 30 * time.Second + cacheTestNow := 2 * time.Second + + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 50*time.Hour, 0, 0, 4*time.Hour, 0, 10*time.Minute, 0, cacheTestInterval, cacheTestRange, cacheTestNow, 1*time.Hour, 1, make(chan time.Time), make(chan time.Time), mr, false) + // Force the start time to a known value + c.startTime = time.Unix(10, 0) + + queryResultsDiff = &mockCounter{} + mr.countOverTime = 2.3 + mr.noCacheCountOvertime = mr.countOverTime // same value for both with and without cache + c.cacheTest(now) + assert.Equal(t, 0, queryResultsDiff.(*mockCounter).count) + + queryResultsDiff = &mockCounter{} // reset counter + mr.countOverTime = 2.3 // value not important + mr.noCacheCountOvertime = 2.5 // different than `countOverTime` value. + c.cacheTest(now) + assert.Equal(t, 1, queryResultsDiff.(*mockCounter).count) + + queryResultsDiff = &mockCounter{} // reset counter + mr.countOverTime = 2.3 // value not important + mr.noCacheCountOvertime = 2.30000005 // different than `countOverTime` value but withing tolerance + c.cacheTest(now) + assert.Equal(t, 0, queryResultsDiff.(*mockCounter).count) + + // This avoids a panic on subsequent test execution, + // seems ugly but was easy, and multiple instantiations + // of the comparator should be an error + prometheus.Unregister(responseLatency) +} + func TestMetricTest(t *testing.T) { metricTestActual = &mockGauge{} metricTestExpected = &mockGauge{} @@ -371,7 +407,7 @@ func TestMetricTest(t *testing.T) { mr := &mockReader{} metricTestRange := 30 * time.Second //We set the prune interval timer to a huge value here so that it never runs, instead we call spotCheckEntries manually below - c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 50*time.Hour, 0, 0, 4*time.Hour, 0, 10*time.Minute, metricTestRange, writeInterval, 1, make(chan time.Time), make(chan time.Time), mr, false) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 50*time.Hour, 0, 0, 4*time.Hour, 0, 10*time.Minute, metricTestRange, 1*time.Hour, 3*time.Hour, 30*time.Minute, writeInterval, 1, make(chan time.Time), make(chan time.Time), mr, false) // Force the start time to a known value c.startTime = time.Unix(10, 0) @@ -456,6 +492,42 @@ func (m *mockCounter) Inc() { m.count++ } +type mockCounterVec struct { + mockCounter + labels []string +} + +func (m *mockCounterVec) WithLabelValues(lvs ...string) prometheus.Counter { + m.labels = lvs + return &m.mockCounter +} + +func (m *mockCounterVec) Desc() *prometheus.Desc { + panic("implement me") +} + +func (m *mockCounterVec) Write(*io_prometheus_client.Metric) error { + panic("implement me") +} + +func (m *mockCounterVec) Describe(chan<- *prometheus.Desc) { + panic("implement me") +} + +func (m *mockCounterVec) Collect(chan<- prometheus.Metric) { + panic("implement me") +} + +func (m *mockCounterVec) Add(float64) { + panic("implement me") +} + +func (m *mockCounterVec) Inc() { + m.cLck.Lock() + defer m.cLck.Unlock() + m.count++ +} + type mockGauge struct { cLck sync.Mutex val float64 @@ -507,13 +579,20 @@ type mockReader struct { resp []time.Time countOverTime float64 queryRange string + + // return this value if called without cache. + noCacheCountOvertime float64 } func (r *mockReader) Query(_ time.Time, _ time.Time) ([]time.Time, error) { return r.resp, nil } -func (r *mockReader) QueryCountOverTime(queryRange string) (float64, error) { +func (r *mockReader) QueryCountOverTime(queryRange string, _ time.Time, cache bool) (float64, error) { r.queryRange = queryRange - return r.countOverTime, nil + res := r.countOverTime + if !cache { + res = r.noCacheCountOvertime + } + return res, nil } diff --git a/pkg/canary/reader/reader.go b/pkg/canary/reader/reader.go index 4576ca7a70ed..c323fc999dd0 100644 --- a/pkg/canary/reader/reader.go +++ b/pkg/canary/reader/reader.go @@ -45,7 +45,7 @@ var ( type LokiReader interface { Query(start time.Time, end time.Time) ([]time.Time, error) - QueryCountOverTime(queryRange string) (float64, error) + QueryCountOverTime(queryRange string, now time.Time, cache bool) (float64, error) } type Reader struct { @@ -180,7 +180,7 @@ func (r *Reader) Stop() { // QueryCountOverTime will ask Loki for a count of logs over the provided range e.g. 5m // QueryCountOverTime blocks if a previous query has failed until the appropriate backoff time has been reached. -func (r *Reader) QueryCountOverTime(queryRange string) (float64, error) { +func (r *Reader) QueryCountOverTime(queryRange string, now time.Time, cache bool) (float64, error) { r.backoffMtx.RLock() next := r.nextQuery r.backoffMtx.RUnlock() @@ -201,10 +201,10 @@ func (r *Reader) QueryCountOverTime(queryRange string) (float64, error) { Host: r.addr, Path: "/loki/api/v1/query", RawQuery: "query=" + url.QueryEscape(fmt.Sprintf("count_over_time({%v=\"%v\",%v=\"%v\"}[%s])", r.sName, r.sValue, r.lName, r.lVal, queryRange)) + - fmt.Sprintf("&time=%d", time.Now().UnixNano()) + + fmt.Sprintf("&time=%d", now.UnixNano()) + "&limit=1000", } - fmt.Fprintf(r.w, "Querying loki for metric count with query: %v\n", u.String()) + fmt.Fprintf(r.w, "Querying loki for metric count with query: %v, cache: %v\n", u.String(), cache) ctx, cancel := context.WithTimeout(context.Background(), r.queryTimeout) defer cancel() @@ -221,6 +221,9 @@ func (r *Reader) QueryCountOverTime(queryRange string) (float64, error) { req.Header.Set("X-Scope-OrgID", r.tenantID) } req.Header.Set("User-Agent", userAgent) + if !cache { + req.Header.Set("Cache-Control", "no-cache") + } resp, err := r.httpClient.Do(req) if err != nil { diff --git a/pkg/indexgateway/gateway.go b/pkg/indexgateway/gateway.go index 81f98662a1c3..e2850e8c9317 100644 --- a/pkg/indexgateway/gateway.go +++ b/pkg/indexgateway/gateway.go @@ -292,7 +292,22 @@ func (g *Gateway) LabelNamesForMetricName(ctx context.Context, req *logproto.Lab if err != nil { return nil, err } - names, err := g.indexQuerier.LabelNamesForMetricName(ctx, instanceID, req.From, req.Through, req.MetricName) + var matchers []*labels.Matcher + // An empty matchers string cannot be parsed, + // therefore we check the string representation of the matchers. + if req.Matchers != syntax.EmptyMatchers { + expr, err := syntax.ParseExprWithoutValidation(req.Matchers) + if err != nil { + return nil, err + } + + matcherExpr, ok := expr.(*syntax.MatchersExpr) + if !ok { + return nil, fmt.Errorf("invalid label matchers found of type %T", expr) + } + matchers = matcherExpr.Mts + } + names, err := g.indexQuerier.LabelNamesForMetricName(ctx, instanceID, req.From, req.Through, req.MetricName, matchers...) if err != nil { return nil, err } @@ -308,7 +323,7 @@ func (g *Gateway) LabelValuesForMetricName(ctx context.Context, req *logproto.La } var matchers []*labels.Matcher // An empty matchers string cannot be parsed, - // therefore we check the string representation of the the matchers. + // therefore we check the string representation of the matchers. if req.Matchers != syntax.EmptyMatchers { expr, err := syntax.ParseExprWithoutValidation(req.Matchers) if err != nil { diff --git a/pkg/ingester/ingester.go b/pkg/ingester/ingester.go index f23e1de227f6..41b358906e0a 100644 --- a/pkg/ingester/ingester.go +++ b/pkg/ingester/ingester.go @@ -1147,7 +1147,7 @@ func (i *Ingester) Label(ctx context.Context, req *logproto.LabelRequest) (*logp return } } else { - storeValues, err = cs.LabelNamesForMetricName(ctx, userID, from, through, "logs") + storeValues, err = cs.LabelNamesForMetricName(ctx, userID, from, through, "logs", matchers...) if err != nil { return } diff --git a/pkg/ingester/ingester_test.go b/pkg/ingester/ingester_test.go index 035a62e5a641..1c438bd6bf2c 100644 --- a/pkg/ingester/ingester_test.go +++ b/pkg/ingester/ingester_test.go @@ -465,7 +465,7 @@ func (s *mockStore) LabelValuesForMetricName(_ context.Context, _ string, _, _ m return []string{"val1", "val2"}, nil } -func (s *mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (s *mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil } diff --git a/pkg/loghttp/samples.go b/pkg/loghttp/samples.go new file mode 100644 index 000000000000..9266dc228501 --- /dev/null +++ b/pkg/loghttp/samples.go @@ -0,0 +1,35 @@ +package loghttp + +import ( + "net/http" + + "github.com/grafana/loki/v3/pkg/logproto" +) + +func ParseSamplesQuery(r *http.Request) (*logproto.QuerySamplesRequest, error) { + req := &logproto.QuerySamplesRequest{} + + req.Query = query(r) + start, end, err := bounds(r) + if err != nil { + return nil, err + } + req.Start = start + req.End = end + + calculatedStep, err := step(r, start, end) + if err != nil { + return nil, err + } + if calculatedStep <= 0 { + return nil, errZeroOrNegativeStep + } + // For safety, limit the number of returned points per timeseries. + // This is sufficient for 60s resolution for a week or 1h resolution for a year. + if (req.End.Sub(req.Start) / calculatedStep) > 11000 { + return nil, errStepTooSmall + } + req.Step = calculatedStep.Milliseconds() + + return req, nil +} diff --git a/pkg/loghttp/samples_test.go b/pkg/loghttp/samples_test.go new file mode 100644 index 000000000000..971b009045b1 --- /dev/null +++ b/pkg/loghttp/samples_test.go @@ -0,0 +1,122 @@ +package loghttp + +import ( + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/logproto" +) + +func TestParseSamplesQuery(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + path string + want *logproto.QuerySamplesRequest + wantErr bool + }{ + { + name: "should correctly parse valid params", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=5s", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(3600, 0), + Step: (5 * time.Second).Milliseconds(), + }, + }, + { + name: "should default empty step param to sensible step for the range", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(3600, 0), + Step: (14 * time.Second).Milliseconds(), + }, + }, + { + name: "should default start to zero for empty start param", + path: "/loki/api/v1/patterns?query={}&end=3600000000000", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(0, 0), + End: time.Unix(3600, 0), + Step: (14 * time.Second).Milliseconds(), + }, + }, + { + name: "should accept step with no units as seconds", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=10", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(3600, 0), + Step: (10 * time.Second).Milliseconds(), + }, + }, + { + name: "should accept step as string duration in seconds", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=15s", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(3600, 0), + Step: (15 * time.Second).Milliseconds(), + }, + }, + { + name: "should correctly parse long duration for step", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=10h", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(3600, 0), + Step: (10 * time.Hour).Milliseconds(), + }, + }, + { + name: "should reject negative step value", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=-5s", + want: nil, + wantErr: true, + }, + { + name: "should reject very small step for big range", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=3600000000000&step=50ms", + want: nil, + wantErr: true, + }, + { + name: "should accept very small step for small range", + path: "/loki/api/v1/patterns?query={}&start=100000000000&end=110000000000&step=50ms", + want: &logproto.QuerySamplesRequest{ + Query: "{}", + Start: time.Unix(100, 0), + End: time.Unix(110, 0), + Step: (50 * time.Millisecond).Milliseconds(), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, tt.path, nil) + require.NoError(t, err) + err = req.ParseForm() + require.NoError(t, err) + + got, err := ParseSamplesQuery(req) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equalf(t, tt.want, got, "Incorrect response from input path: %s", tt.path) + }) + } +} diff --git a/pkg/logproto/compat.go b/pkg/logproto/compat.go index a11467584b58..0ebbe1c7c024 100644 --- a/pkg/logproto/compat.go +++ b/pkg/logproto/compat.go @@ -82,6 +82,10 @@ func FromMetricsToLabelAdapters(metric model.Metric) []LabelAdapter { return result } +func FromMetricsToLabels(metric model.Metric) labels.Labels { + return FromLabelAdaptersToLabels(FromMetricsToLabelAdapters(metric)) +} + type byLabel []LabelAdapter func (s byLabel) Len() int { return len(s) } @@ -534,3 +538,32 @@ func (m *QueryPatternsRequest) LogToSpan(sp opentracing.Span) { } sp.LogFields(fields...) } + +func (m *QuerySamplesRequest) GetCachingOptions() (res definitions.CachingOptions) { return } + +func (m *QuerySamplesRequest) WithStartEnd(start, end time.Time) definitions.Request { + clone := *m + clone.Start = start + clone.End = end + return &clone +} + +func (m *QuerySamplesRequest) WithQuery(query string) definitions.Request { + clone := *m + clone.Query = query + return &clone +} + +func (m *QuerySamplesRequest) WithStartEndForCache(start, end time.Time) resultscache.Request { + return m.WithStartEnd(start, end).(resultscache.Request) +} + +func (m *QuerySamplesRequest) LogToSpan(sp opentracing.Span) { + fields := []otlog.Field{ + otlog.String("query", m.GetQuery()), + otlog.String("start", m.Start.String()), + otlog.String("end", m.End.String()), + otlog.String("step", time.Duration(m.Step).String()), + } + sp.LogFields(fields...) +} diff --git a/pkg/logproto/extensions.go b/pkg/logproto/extensions.go index 3de5c0fd7580..284ac792ebb9 100644 --- a/pkg/logproto/extensions.go +++ b/pkg/logproto/extensions.go @@ -1,10 +1,12 @@ package logproto import ( + "encoding/json" "sort" "strings" "sync/atomic" //lint:ignore faillint we can't use go.uber.org/atomic with a protobuf struct without wrapping it. + "github.com/buger/jsonparser" "github.com/cespare/xxhash/v2" "github.com/dustin/go-humanize" jsoniter "github.com/json-iterator/go" @@ -188,3 +190,47 @@ func (m *ShardsResponse) Merge(other *ShardsResponse) { m.ChunkGroups = append(m.ChunkGroups, other.ChunkGroups...) m.Statistics.Merge(other.Statistics) } + +func NewPatternSeries(pattern string, samples []*PatternSample) *PatternSeries { + return &PatternSeries{Pattern: pattern, Samples: samples} +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// QuerySamplesResponse json representation is different from the proto +func (r *QuerySamplesResponse) UnmarshalJSON(data []byte) error { + return jsonparser.ObjectEach( + data, + func(key, value []byte, dataType jsonparser.ValueType, offset int) error { + if string(key) == "data" { + var m []model.SampleStream + if err := json.Unmarshal(value, &m); err != nil { + return err + } + series := make([]Series, len(m)) + + for i, s := range m { + lbls := FromMetricsToLabels(s.Metric) + + newSeries := Series{ + Labels: s.Metric.String(), + StreamHash: lbls.Hash(), + Samples: make([]Sample, len(s.Values)), + } + + for j, samplePair := range s.Values { + newSeries.Samples[j] = Sample{ + Timestamp: samplePair.Timestamp.UnixNano(), + Value: float64(samplePair.Value), + } + } + + series[i] = newSeries + } + + r.Series = series + } + + return nil + }, + ) +} diff --git a/pkg/logproto/extensions_test.go b/pkg/logproto/extensions_test.go index d1c96c76bbed..35823d3ca554 100644 --- a/pkg/logproto/extensions_test.go +++ b/pkg/logproto/extensions_test.go @@ -3,7 +3,10 @@ package logproto import ( "testing" + "github.com/prometheus/common/model" "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/logql/syntax" ) func TestShard_SpaceFor(t *testing.T) { @@ -40,3 +43,91 @@ func TestShard_SpaceFor(t *testing.T) { }) } } + +func TestQueryPatternsResponse_UnmarshalJSON(t *testing.T) { + mockData := []byte(`{ + "status": "success", + "data": [ + { + "pattern": "foo <*> bar", + "samples": [[1609459200, 10], [1609545600, 15]] + }, + { + "pattern": "foo <*> buzz", + "samples": [[1609459200, 20], [1609545600, 25]] + } + ] + }`) + + expectedSeries := []*PatternSeries{ + NewPatternSeries("foo <*> bar", []*PatternSample{ + {Timestamp: model.TimeFromUnix(1609459200), Value: 10}, + {Timestamp: model.TimeFromUnix(1609545600), Value: 15}, + }), + NewPatternSeries("foo <*> buzz", []*PatternSample{ + {Timestamp: model.TimeFromUnix(1609459200), Value: 20}, + {Timestamp: model.TimeFromUnix(1609545600), Value: 25}, + }), + } + + r := &QueryPatternsResponse{} + err := r.UnmarshalJSON(mockData) + + require.Nil(t, err) + require.Equal(t, expectedSeries, r.Series) +} + +func TestQuerySamplesResponse_UnmarshalJSON(t *testing.T) { + mockData := []byte(`{ + "status": "success", + "data": [{ + "metric": { + "foo": "bar" + }, + "values": [ + [0.001, "1"], + [0.002, "2"] + ] + }, + { + "metric": { + "foo": "baz", + "bar": "qux" + }, + "values": [ + [0.003, "3"], + [0.004, "4"] + ] + }] + }`) + + lbls1, err := syntax.ParseLabels(`{foo="bar"}`) + require.NoError(t, err) + lbls2, err := syntax.ParseLabels(`{bar="qux", foo="baz"}`) + require.NoError(t, err) + + expectedSamples := []Series{ + { + Labels: lbls1.String(), + Samples: []Sample{ + {Timestamp: 1e6, Value: 1}, // 1ms after epoch in ns + {Timestamp: 2e6, Value: 2}, // 2ms after epoch in ns + }, + StreamHash: lbls1.Hash(), + }, + { + Labels: lbls2.String(), + Samples: []Sample{ + {Timestamp: 3e6, Value: 3}, // 3ms after epoch in ns + {Timestamp: 4e6, Value: 4}, // 4ms after epoch in ns + }, + StreamHash: lbls2.Hash(), + }, + } + + r := &QuerySamplesResponse{} + err = r.UnmarshalJSON(mockData) + + require.Nil(t, err) + require.Equal(t, expectedSamples, r.Series) +} diff --git a/pkg/logproto/logproto.pb.go b/pkg/logproto/logproto.pb.go index 0d0827f5a094..e1c54358897e 100644 --- a/pkg/logproto/logproto.pb.go +++ b/pkg/logproto/logproto.pb.go @@ -1866,6 +1866,7 @@ type LabelNamesForMetricNameRequest struct { MetricName string `protobuf:"bytes,1,opt,name=metric_name,json=metricName,proto3" json:"metric_name,omitempty"` From github_com_prometheus_common_model.Time `protobuf:"varint,2,opt,name=from,proto3,customtype=github.com/prometheus/common/model.Time" json:"from"` Through github_com_prometheus_common_model.Time `protobuf:"varint,3,opt,name=through,proto3,customtype=github.com/prometheus/common/model.Time" json:"through"` + Matchers string `protobuf:"bytes,4,opt,name=matchers,proto3" json:"matchers,omitempty"` } func (m *LabelNamesForMetricNameRequest) Reset() { *m = LabelNamesForMetricNameRequest{} } @@ -1907,6 +1908,13 @@ func (m *LabelNamesForMetricNameRequest) GetMetricName() string { return "" } +func (m *LabelNamesForMetricNameRequest) GetMatchers() string { + if m != nil { + return m.Matchers + } + return "" +} + // TODO(owen-d): fix. This will break rollouts as soon as the internal repr is changed. type LineFilter struct { Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` @@ -3113,174 +3121,175 @@ func init() { func init() { proto.RegisterFile("pkg/logproto/logproto.proto", fileDescriptor_c28a5f14f1f4c79a) } var fileDescriptor_c28a5f14f1f4c79a = []byte{ - // 2671 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0x4d, 0x6c, 0x1b, 0xc7, - 0xd5, 0x5c, 0x72, 0xf9, 0xf7, 0x48, 0xc9, 0xf2, 0x88, 0xb6, 0x09, 0xd9, 0xe1, 0x2a, 0x83, 0xef, - 0x4b, 0xdc, 0xd8, 0x11, 0x63, 0xa7, 0x49, 0x1d, 0xa7, 0x69, 0x6a, 0x4a, 0xb1, 0x63, 0x47, 0x71, - 0x9c, 0x91, 0xe3, 0xa4, 0x45, 0x83, 0x60, 0x4d, 0x8e, 0xa8, 0x85, 0xc9, 0x5d, 0x7a, 0x77, 0x18, - 0x47, 0xb7, 0x02, 0x3d, 0x17, 0x0d, 0xd0, 0x43, 0xdb, 0x4b, 0x81, 0x02, 0x05, 0x5a, 0xb4, 0xc8, - 0xa5, 0xe8, 0xa9, 0x28, 0xda, 0x4b, 0x0f, 0xe9, 0x2d, 0xbd, 0x05, 0x39, 0xb0, 0x8d, 0x72, 0x29, - 0x74, 0x0a, 0x50, 0xa0, 0x87, 0x9c, 0x8a, 0xf9, 0xdb, 0x9d, 0x5d, 0x91, 0x75, 0xe8, 0xb8, 0x48, - 0x7c, 0x21, 0x67, 0xde, 0xbc, 0x79, 0x33, 0xef, 0x67, 0xde, 0x1f, 0x09, 0xc7, 0x47, 0xb7, 0xfa, - 0xed, 0x41, 0xd0, 0x1f, 0x85, 0x01, 0x0b, 0xe2, 0xc1, 0x9a, 0xf8, 0x44, 0x15, 0x3d, 0x5f, 0x69, - 0xf4, 0x83, 0x7e, 0x20, 0x71, 0xf8, 0x48, 0xae, 0xaf, 0x38, 0xfd, 0x20, 0xe8, 0x0f, 0x68, 0x5b, - 0xcc, 0x6e, 0x8e, 0xb7, 0xdb, 0xcc, 0x1b, 0xd2, 0x88, 0xb9, 0xc3, 0x91, 0x42, 0x58, 0x55, 0xd4, - 0x6f, 0x0f, 0x86, 0x41, 0x8f, 0x0e, 0xda, 0x11, 0x73, 0x59, 0x24, 0x3f, 0x15, 0xc6, 0x32, 0xc7, - 0x18, 0x8d, 0xa3, 0x1d, 0xf1, 0x21, 0x81, 0xf8, 0xf7, 0x16, 0x1c, 0xd9, 0x74, 0x6f, 0xd2, 0xc1, - 0xf5, 0xe0, 0x86, 0x3b, 0x18, 0xd3, 0x88, 0xd0, 0x68, 0x14, 0xf8, 0x11, 0x45, 0xeb, 0x50, 0x1a, - 0xf0, 0x85, 0xa8, 0x69, 0xad, 0x16, 0x4e, 0xd6, 0xce, 0x9e, 0x5a, 0x8b, 0xaf, 0x3c, 0x75, 0x83, - 0x84, 0x46, 0x2f, 0xf8, 0x2c, 0xdc, 0x25, 0x6a, 0xeb, 0xca, 0x0d, 0xa8, 0x19, 0x60, 0xb4, 0x04, - 0x85, 0x5b, 0x74, 0xb7, 0x69, 0xad, 0x5a, 0x27, 0xab, 0x84, 0x0f, 0xd1, 0x19, 0x28, 0xbe, 0xcd, - 0xc9, 0x34, 0xf3, 0xab, 0xd6, 0xc9, 0xda, 0xd9, 0xe3, 0xc9, 0x21, 0xaf, 0xf9, 0xde, 0xed, 0x31, - 0x15, 0xbb, 0xd5, 0x41, 0x12, 0xf3, 0x7c, 0xfe, 0x9c, 0x85, 0x4f, 0xc1, 0xe1, 0x03, 0xeb, 0xe8, - 0x28, 0x94, 0x04, 0x86, 0xbc, 0x71, 0x95, 0xa8, 0x19, 0x6e, 0x00, 0xda, 0x62, 0x21, 0x75, 0x87, - 0xc4, 0x65, 0xfc, 0xbe, 0xb7, 0xc7, 0x34, 0x62, 0xf8, 0x65, 0x58, 0x4e, 0x41, 0x15, 0xdb, 0x4f, - 0x43, 0x2d, 0x4a, 0xc0, 0x8a, 0xf7, 0x46, 0x72, 0xad, 0x64, 0x0f, 0x31, 0x11, 0xf1, 0xcf, 0x2d, - 0x80, 0x64, 0x0d, 0xb5, 0x00, 0xe4, 0xea, 0x8b, 0x6e, 0xb4, 0x23, 0x18, 0xb6, 0x89, 0x01, 0x41, - 0xa7, 0xe1, 0x70, 0x32, 0xbb, 0x1a, 0x6c, 0xed, 0xb8, 0x61, 0x4f, 0xc8, 0xc0, 0x26, 0x07, 0x17, - 0x10, 0x02, 0x3b, 0x74, 0x19, 0x6d, 0x16, 0x56, 0xad, 0x93, 0x05, 0x22, 0xc6, 0x9c, 0x5b, 0x46, - 0x7d, 0xd7, 0x67, 0x4d, 0x5b, 0x88, 0x53, 0xcd, 0x38, 0x9c, 0xeb, 0x97, 0x46, 0xcd, 0xe2, 0xaa, - 0x75, 0x72, 0x81, 0xa8, 0x19, 0xfe, 0x77, 0x01, 0xea, 0xaf, 0x8e, 0x69, 0xb8, 0xab, 0x04, 0x80, - 0x5a, 0x50, 0x89, 0xe8, 0x80, 0x76, 0x59, 0x10, 0x4a, 0x8d, 0x74, 0xf2, 0x4d, 0x8b, 0xc4, 0x30, - 0xd4, 0x80, 0xe2, 0xc0, 0x1b, 0x7a, 0x4c, 0x5c, 0x6b, 0x81, 0xc8, 0x09, 0x3a, 0x0f, 0xc5, 0x88, - 0xb9, 0x21, 0x13, 0x77, 0xa9, 0x9d, 0x5d, 0x59, 0x93, 0x86, 0xb9, 0xa6, 0x0d, 0x73, 0xed, 0xba, - 0x36, 0xcc, 0x4e, 0xe5, 0xfd, 0x89, 0x93, 0x7b, 0xf7, 0xef, 0x8e, 0x45, 0xe4, 0x16, 0xf4, 0x34, - 0x14, 0xa8, 0xdf, 0x13, 0xf7, 0xfd, 0xbc, 0x3b, 0xf9, 0x06, 0x74, 0x06, 0xaa, 0x3d, 0x2f, 0xa4, - 0x5d, 0xe6, 0x05, 0xbe, 0xe0, 0x6a, 0xf1, 0xec, 0x72, 0xa2, 0x91, 0x0d, 0xbd, 0x44, 0x12, 0x2c, - 0x74, 0x1a, 0x4a, 0x11, 0x17, 0x5d, 0xd4, 0x2c, 0x73, 0x5b, 0xe8, 0x34, 0xf6, 0x27, 0xce, 0x92, - 0x84, 0x9c, 0x0e, 0x86, 0x1e, 0xa3, 0xc3, 0x11, 0xdb, 0x25, 0x0a, 0x07, 0x3d, 0x06, 0xe5, 0x1e, - 0x1d, 0x50, 0xae, 0xf0, 0x8a, 0x50, 0xf8, 0x92, 0x41, 0x5e, 0x2c, 0x10, 0x8d, 0x80, 0xde, 0x04, - 0x7b, 0x34, 0x70, 0xfd, 0x66, 0x55, 0x70, 0xb1, 0x98, 0x20, 0x5e, 0x1b, 0xb8, 0x7e, 0xe7, 0x99, - 0x8f, 0x26, 0xce, 0x53, 0x7d, 0x8f, 0xed, 0x8c, 0x6f, 0xae, 0x75, 0x83, 0x61, 0xbb, 0x1f, 0xba, - 0xdb, 0xae, 0xef, 0xb6, 0x07, 0xc1, 0x2d, 0xaf, 0xfd, 0xf6, 0x93, 0x6d, 0xfe, 0x06, 0x6f, 0x8f, - 0x69, 0xe8, 0xd1, 0xb0, 0xcd, 0xc9, 0xac, 0x09, 0x95, 0xf0, 0xad, 0x44, 0x90, 0x45, 0x57, 0xb8, - 0xfd, 0x05, 0x21, 0x5d, 0xdf, 0x19, 0xfb, 0xb7, 0xa2, 0x26, 0x88, 0x53, 0x8e, 0x25, 0xa7, 0x08, - 0x38, 0xa1, 0xdb, 0x97, 0xc2, 0x60, 0x3c, 0xea, 0x1c, 0xda, 0x9f, 0x38, 0x26, 0x3e, 0x31, 0x27, - 0x57, 0xec, 0x4a, 0x69, 0xa9, 0x8c, 0xdf, 0x2b, 0x00, 0xda, 0x72, 0x87, 0xa3, 0x01, 0x9d, 0x4b, - 0xfd, 0xb1, 0xa2, 0xf3, 0xf7, 0xac, 0xe8, 0xc2, 0xbc, 0x8a, 0x4e, 0xb4, 0x66, 0xcf, 0xa7, 0xb5, - 0xe2, 0xe7, 0xd5, 0x5a, 0xe9, 0x2b, 0xaf, 0x35, 0xdc, 0x04, 0x9b, 0x53, 0xe6, 0xce, 0x32, 0x74, - 0xef, 0x08, 0xdd, 0xd4, 0x09, 0x1f, 0xe2, 0x4d, 0x28, 0x49, 0xbe, 0xd0, 0x4a, 0x56, 0x79, 0xe9, - 0x77, 0x9b, 0x28, 0xae, 0xa0, 0x55, 0xb2, 0x94, 0xa8, 0xa4, 0x20, 0x84, 0x8d, 0xff, 0x68, 0xc1, - 0x82, 0xb2, 0x08, 0xe5, 0xfb, 0x6e, 0x42, 0x59, 0xfa, 0x1e, 0xed, 0xf7, 0x8e, 0x65, 0xfd, 0xde, - 0x85, 0x9e, 0x3b, 0x62, 0x34, 0xec, 0xb4, 0xdf, 0x9f, 0x38, 0xd6, 0x47, 0x13, 0xe7, 0xd1, 0x59, - 0x42, 0xd3, 0xb1, 0x46, 0xfb, 0x4b, 0x4d, 0x18, 0x9d, 0x12, 0xb7, 0x63, 0x91, 0x32, 0xab, 0x43, - 0x6b, 0x32, 0x44, 0x5d, 0xf6, 0xfb, 0x34, 0xe2, 0x94, 0x6d, 0x6e, 0x11, 0x44, 0xe2, 0x70, 0x36, - 0xef, 0xb8, 0xa1, 0xef, 0xf9, 0xfd, 0xa8, 0x59, 0x10, 0x3e, 0x3d, 0x9e, 0xe3, 0x9f, 0x5a, 0xb0, - 0x9c, 0x32, 0x6b, 0xc5, 0xc4, 0x39, 0x28, 0x45, 0x5c, 0x53, 0x9a, 0x07, 0xc3, 0x28, 0xb6, 0x04, - 0xbc, 0xb3, 0xa8, 0x2e, 0x5f, 0x92, 0x73, 0xa2, 0xf0, 0xef, 0xdf, 0xd5, 0xfe, 0x62, 0x41, 0x5d, - 0x04, 0x26, 0xfd, 0xd6, 0x10, 0xd8, 0xbe, 0x3b, 0xa4, 0x4a, 0x55, 0x62, 0x6c, 0x44, 0x2b, 0x7e, - 0x5c, 0x45, 0x47, 0xab, 0x79, 0x1d, 0xac, 0x75, 0xcf, 0x0e, 0xd6, 0x4a, 0xde, 0x5d, 0x03, 0x8a, - 0xdc, 0xbc, 0x77, 0x85, 0x73, 0xad, 0x12, 0x39, 0xc1, 0x8f, 0xc2, 0x82, 0xe2, 0x42, 0x89, 0x76, - 0x56, 0x80, 0x1d, 0x42, 0x49, 0x6a, 0x02, 0xfd, 0x1f, 0x54, 0xe3, 0xc4, 0x44, 0x70, 0x5b, 0xe8, - 0x94, 0xf6, 0x27, 0x4e, 0x9e, 0x45, 0x24, 0x59, 0x40, 0x8e, 0x19, 0xf4, 0xad, 0x4e, 0x75, 0x7f, - 0xe2, 0x48, 0x80, 0x0a, 0xf1, 0xe8, 0x04, 0xd8, 0x3b, 0x3c, 0x6e, 0x72, 0x11, 0xd8, 0x9d, 0xca, - 0xfe, 0xc4, 0x11, 0x73, 0x22, 0x3e, 0xf1, 0x25, 0xa8, 0x6f, 0xd2, 0xbe, 0xdb, 0xdd, 0x55, 0x87, - 0x36, 0x34, 0x39, 0x7e, 0xa0, 0xa5, 0x69, 0x3c, 0x0c, 0xf5, 0xf8, 0xc4, 0xb7, 0x86, 0x91, 0x7a, - 0x0d, 0xb5, 0x18, 0xf6, 0x72, 0x84, 0x7f, 0x66, 0x81, 0xb2, 0x01, 0x84, 0x8d, 0x6c, 0x87, 0xfb, - 0x42, 0xd8, 0x9f, 0x38, 0x0a, 0xa2, 0x93, 0x19, 0xf4, 0x2c, 0x94, 0x23, 0x71, 0x22, 0x27, 0x96, - 0x35, 0x2d, 0xb1, 0xd0, 0x39, 0xc4, 0x4d, 0x64, 0x7f, 0xe2, 0x68, 0x44, 0xa2, 0x07, 0x68, 0x2d, - 0x95, 0x10, 0x48, 0xc6, 0x16, 0xf7, 0x27, 0x8e, 0x01, 0x35, 0x13, 0x04, 0xfc, 0x99, 0x05, 0xb5, - 0xeb, 0xae, 0x17, 0x9b, 0x50, 0x53, 0xab, 0x28, 0xf1, 0xd5, 0x12, 0xc0, 0x2d, 0xb1, 0x47, 0x07, - 0xee, 0xee, 0xc5, 0x20, 0x14, 0x74, 0x17, 0x48, 0x3c, 0x4f, 0x62, 0xb8, 0x3d, 0x35, 0x86, 0x17, - 0xe7, 0x77, 0xed, 0xff, 0x5b, 0x47, 0x7a, 0xc5, 0xae, 0xe4, 0x97, 0x0a, 0xf8, 0x3d, 0x0b, 0xea, - 0x92, 0x79, 0x65, 0x79, 0xdf, 0x83, 0x92, 0x94, 0x8d, 0x60, 0xff, 0xbf, 0x38, 0xa6, 0x53, 0xf3, - 0x38, 0x25, 0x45, 0x13, 0x3d, 0x0f, 0x8b, 0xbd, 0x30, 0x18, 0x8d, 0x68, 0x6f, 0x4b, 0xb9, 0xbf, - 0x7c, 0xd6, 0xfd, 0x6d, 0x98, 0xeb, 0x24, 0x83, 0x8e, 0xff, 0x6a, 0xc1, 0x82, 0x72, 0x26, 0x4a, - 0x5d, 0xb1, 0x88, 0xad, 0x7b, 0x8e, 0x9e, 0xf9, 0x79, 0xa3, 0xe7, 0x51, 0x28, 0xf5, 0x79, 0x7c, - 0xd1, 0x0e, 0x49, 0xcd, 0xe6, 0x8b, 0xaa, 0xf8, 0x0a, 0x2c, 0x6a, 0x56, 0x66, 0x78, 0xd4, 0x95, - 0xac, 0x47, 0xbd, 0xdc, 0xa3, 0x3e, 0xf3, 0xb6, 0xbd, 0xd8, 0x47, 0x2a, 0x7c, 0xfc, 0x23, 0x0b, - 0x96, 0xb2, 0x28, 0x68, 0x23, 0x53, 0x58, 0x3c, 0x32, 0x9b, 0x9c, 0x59, 0x53, 0x68, 0xd2, 0xaa, - 0xb2, 0x78, 0xea, 0x6e, 0x95, 0x45, 0xc3, 0x74, 0x32, 0x55, 0xe5, 0x15, 0xf0, 0x4f, 0x2c, 0x58, - 0x48, 0xe9, 0x12, 0x9d, 0x03, 0x7b, 0x3b, 0x0c, 0x86, 0x73, 0x29, 0x4a, 0xec, 0x40, 0x5f, 0x87, - 0x3c, 0x0b, 0xe6, 0x52, 0x53, 0x9e, 0x05, 0x5c, 0x4b, 0x8a, 0xfd, 0x82, 0xcc, 0xdb, 0xe5, 0x0c, - 0x3f, 0x05, 0x55, 0xc1, 0xd0, 0x35, 0xd7, 0x0b, 0xa7, 0x06, 0x8c, 0xe9, 0x0c, 0x3d, 0x0b, 0x87, - 0xa4, 0x33, 0x9c, 0xbe, 0xb9, 0x3e, 0x6d, 0x73, 0x5d, 0x6f, 0x3e, 0x0e, 0x45, 0x91, 0x74, 0xf0, - 0x2d, 0x3d, 0x97, 0xb9, 0x7a, 0x0b, 0x1f, 0xe3, 0x23, 0xb0, 0xcc, 0xdf, 0x20, 0x0d, 0xa3, 0xf5, - 0x60, 0xec, 0x33, 0x5d, 0x37, 0x9d, 0x86, 0x46, 0x1a, 0xac, 0xac, 0xa4, 0x01, 0xc5, 0x2e, 0x07, - 0x08, 0x1a, 0x0b, 0x44, 0x4e, 0xf0, 0x2f, 0x2d, 0x40, 0x97, 0x28, 0x13, 0xa7, 0x5c, 0xde, 0x88, - 0x9f, 0xc7, 0x0a, 0x54, 0x86, 0x2e, 0xeb, 0xee, 0xd0, 0x30, 0xd2, 0xf9, 0x8b, 0x9e, 0x7f, 0x19, - 0x89, 0x27, 0x3e, 0x03, 0xcb, 0xa9, 0x5b, 0x2a, 0x9e, 0x56, 0xa0, 0xd2, 0x55, 0x30, 0x15, 0xf2, - 0xe2, 0x39, 0xfe, 0x5d, 0x1e, 0x2a, 0x3a, 0xad, 0x43, 0x67, 0xa0, 0xb6, 0xed, 0xf9, 0x7d, 0x1a, - 0x8e, 0x42, 0x4f, 0x89, 0xc0, 0x96, 0x69, 0x9e, 0x01, 0x26, 0xe6, 0x04, 0x3d, 0x0e, 0xe5, 0x71, - 0x44, 0xc3, 0xb7, 0x3c, 0xf9, 0xd2, 0xab, 0x9d, 0xc6, 0xde, 0xc4, 0x29, 0xbd, 0x16, 0xd1, 0xf0, - 0xf2, 0x06, 0x0f, 0x3e, 0x63, 0x31, 0x22, 0xf2, 0xbb, 0x87, 0x5e, 0x52, 0x66, 0x2a, 0x12, 0xb8, - 0xce, 0x37, 0xf8, 0xf5, 0x33, 0xae, 0x6e, 0x14, 0x06, 0x43, 0xca, 0x76, 0xe8, 0x38, 0x6a, 0x77, - 0x83, 0xe1, 0x30, 0xf0, 0xdb, 0xa2, 0x13, 0x20, 0x98, 0xe6, 0x11, 0x94, 0x6f, 0x57, 0x96, 0x7b, - 0x1d, 0xca, 0x6c, 0x27, 0x0c, 0xc6, 0xfd, 0x1d, 0x11, 0x18, 0x0a, 0x9d, 0xf3, 0xf3, 0xd3, 0xd3, - 0x14, 0x88, 0x1e, 0xa0, 0x87, 0xb9, 0xb4, 0x68, 0xf7, 0x56, 0x34, 0x1e, 0xca, 0xda, 0xb3, 0x53, - 0xdc, 0x9f, 0x38, 0xd6, 0xe3, 0x24, 0x06, 0xe3, 0x0b, 0xb0, 0x90, 0x4a, 0x85, 0xd1, 0x13, 0x60, - 0x87, 0x74, 0x5b, 0xbb, 0x02, 0x74, 0x30, 0x63, 0x96, 0xd1, 0x9f, 0xe3, 0x10, 0xf1, 0x89, 0x7f, - 0x98, 0x07, 0xc7, 0xa8, 0xfa, 0x2f, 0x06, 0xe1, 0xcb, 0x94, 0x85, 0x5e, 0xf7, 0xaa, 0x3b, 0xa4, - 0xda, 0xbc, 0x1c, 0xa8, 0x0d, 0x05, 0xf0, 0x2d, 0xe3, 0x15, 0xc1, 0x30, 0xc6, 0x43, 0x0f, 0x01, - 0x88, 0x67, 0x27, 0xd7, 0xe5, 0x83, 0xaa, 0x0a, 0x88, 0x58, 0x5e, 0x4f, 0x09, 0xbb, 0x3d, 0xa7, - 0x70, 0x94, 0x90, 0x2f, 0x67, 0x85, 0x3c, 0x37, 0x9d, 0x58, 0xb2, 0xe6, 0x73, 0x29, 0xa6, 0x9f, - 0x0b, 0xfe, 0x9b, 0x05, 0xad, 0x4d, 0x7d, 0xf3, 0x7b, 0x14, 0x87, 0xe6, 0x37, 0x7f, 0x9f, 0xf8, - 0x2d, 0x7c, 0x31, 0x7e, 0x71, 0x0b, 0x60, 0xd3, 0xf3, 0xe9, 0x45, 0x6f, 0xc0, 0x68, 0x38, 0xa5, - 0x10, 0xfa, 0x71, 0x21, 0xf1, 0x2a, 0x84, 0x6e, 0x6b, 0x3e, 0xd7, 0x0d, 0x57, 0x7e, 0x3f, 0xd8, - 0xc8, 0xdf, 0x47, 0xb5, 0x15, 0x32, 0x5e, 0xce, 0x87, 0xf2, 0xb6, 0x60, 0x4f, 0x46, 0xe5, 0x54, - 0x8f, 0x29, 0xe1, 0xbd, 0xf3, 0x2d, 0x75, 0xf8, 0xd3, 0x77, 0x49, 0xaa, 0x44, 0xe7, 0xaf, 0x1d, - 0xed, 0xfa, 0xcc, 0x7d, 0xc7, 0xd8, 0x4f, 0xf4, 0x21, 0xc8, 0x55, 0x79, 0x5b, 0x71, 0x6a, 0xde, - 0xf6, 0x9c, 0x3a, 0xe6, 0x8b, 0xe4, 0x6e, 0xf8, 0xb9, 0xc4, 0x89, 0x0a, 0xa5, 0x28, 0x27, 0xfa, - 0xc8, 0xdd, 0x9e, 0xb8, 0x7a, 0xd8, 0x7f, 0xb2, 0x60, 0xe9, 0x12, 0x65, 0xe9, 0x3c, 0xea, 0x01, - 0x52, 0x29, 0x7e, 0x11, 0x0e, 0x1b, 0xf7, 0x57, 0xdc, 0x3f, 0x99, 0x49, 0x9e, 0x8e, 0x24, 0xfc, - 0x5f, 0xf6, 0x7b, 0xf4, 0x1d, 0x55, 0x93, 0xa6, 0xf3, 0xa6, 0x6b, 0x50, 0x33, 0x16, 0xd1, 0x85, - 0x4c, 0xc6, 0xb4, 0x9c, 0x69, 0xc5, 0xf2, 0xa8, 0xdf, 0x69, 0x28, 0x9e, 0x64, 0xe5, 0xa9, 0xf2, - 0xe1, 0x38, 0xbb, 0xd8, 0x02, 0x24, 0xd4, 0x25, 0xc8, 0x9a, 0xf1, 0x4d, 0x40, 0x5f, 0x8a, 0x53, - 0xa7, 0x78, 0x8e, 0x1e, 0x06, 0x3b, 0x0c, 0xee, 0xe8, 0x54, 0x78, 0x21, 0x39, 0x92, 0x04, 0x77, - 0x88, 0x58, 0xc2, 0xcf, 0x42, 0x81, 0x04, 0x77, 0x50, 0x0b, 0x20, 0x74, 0xfd, 0x3e, 0xbd, 0x11, - 0x17, 0x61, 0x75, 0x62, 0x40, 0x66, 0xe4, 0x1e, 0xeb, 0x70, 0xd8, 0xbc, 0x91, 0x54, 0xf7, 0x1a, - 0x94, 0x5f, 0x1d, 0x9b, 0xe2, 0x6a, 0x64, 0xc4, 0x25, 0x6b, 0x7d, 0x8d, 0xc4, 0x6d, 0x06, 0x12, - 0x38, 0x3a, 0x01, 0x55, 0xe6, 0xde, 0x1c, 0xd0, 0xab, 0x89, 0x9b, 0x4b, 0x00, 0x7c, 0x95, 0xd7, - 0x8f, 0x37, 0x8c, 0x24, 0x2a, 0x01, 0xa0, 0xc7, 0x60, 0x29, 0xb9, 0xf3, 0xb5, 0x90, 0x6e, 0x7b, - 0xef, 0x08, 0x0d, 0xd7, 0xc9, 0x01, 0x38, 0x3a, 0x09, 0x87, 0x12, 0xd8, 0x96, 0x48, 0x56, 0x6c, - 0x81, 0x9a, 0x05, 0x73, 0xd9, 0x08, 0x76, 0x5f, 0xb8, 0x3d, 0x76, 0x07, 0xe2, 0xf1, 0xd5, 0x89, - 0x01, 0xc1, 0x7f, 0xb6, 0xe0, 0xb0, 0x54, 0x35, 0x73, 0xd9, 0x03, 0x69, 0xf5, 0xbf, 0xb2, 0x00, - 0x99, 0x1c, 0x28, 0xd3, 0xfa, 0x7f, 0xb3, 0x97, 0xc4, 0xb3, 0xa1, 0x9a, 0x28, 0x8b, 0x25, 0x28, - 0x69, 0x07, 0x61, 0x28, 0x75, 0x65, 0xcf, 0x4c, 0x34, 0xbf, 0x65, 0xdd, 0x2d, 0x21, 0x44, 0x7d, - 0x23, 0x07, 0x8a, 0x37, 0x77, 0x19, 0x8d, 0x54, 0xd5, 0x2c, 0xda, 0x05, 0x02, 0x40, 0xe4, 0x17, - 0x3f, 0x8b, 0xfa, 0x4c, 0x58, 0x8d, 0x9d, 0x9c, 0xa5, 0x40, 0x44, 0x0f, 0xf0, 0x6f, 0xf3, 0xb0, - 0x70, 0x23, 0x18, 0x8c, 0x93, 0xc0, 0xf8, 0x20, 0x05, 0x8c, 0x54, 0x29, 0x5f, 0xd4, 0xa5, 0x3c, - 0x02, 0x3b, 0x62, 0x74, 0x24, 0x2c, 0xab, 0x40, 0xc4, 0x18, 0x61, 0xa8, 0x33, 0x37, 0xec, 0x53, - 0x26, 0x0b, 0xa4, 0x66, 0x49, 0x64, 0xae, 0x29, 0x18, 0x5a, 0x85, 0x9a, 0xdb, 0xef, 0x87, 0xb4, - 0xef, 0x32, 0xda, 0xd9, 0x6d, 0x96, 0xc5, 0x61, 0x26, 0x08, 0xbf, 0x01, 0x8b, 0x5a, 0x58, 0x4a, - 0xa5, 0x4f, 0x40, 0xf9, 0x6d, 0x01, 0x99, 0xd2, 0x5a, 0x93, 0xa8, 0xca, 0x8d, 0x69, 0xb4, 0xf4, - 0x4f, 0x08, 0xfa, 0xce, 0xf8, 0x0a, 0x94, 0x24, 0x3a, 0x3a, 0x61, 0x96, 0x39, 0x32, 0xd3, 0xe3, - 0x73, 0x55, 0xb3, 0x60, 0x28, 0x49, 0x42, 0x4a, 0xf1, 0xc2, 0x36, 0x24, 0x84, 0xa8, 0x6f, 0xfc, - 0x2f, 0x0b, 0x8e, 0x6c, 0x50, 0x46, 0xbb, 0x8c, 0xf6, 0x2e, 0x7a, 0x74, 0xd0, 0xfb, 0x52, 0x2b, - 0xf0, 0xb8, 0x8f, 0x56, 0x30, 0xfa, 0x68, 0xdc, 0xef, 0x0c, 0x3c, 0x9f, 0x6e, 0x1a, 0x8d, 0x98, - 0x04, 0xc0, 0x3d, 0xc4, 0x36, 0xbf, 0xb8, 0x5c, 0x96, 0xbf, 0xd9, 0x18, 0x90, 0x58, 0xc3, 0xa5, - 0x44, 0xc3, 0xf8, 0x07, 0x16, 0x1c, 0xcd, 0x72, 0xad, 0x94, 0xd4, 0x86, 0x92, 0xd8, 0x3c, 0xa5, - 0x85, 0x9b, 0xda, 0x41, 0x14, 0x1a, 0x3a, 0x97, 0x3a, 0x5f, 0xfc, 0xd6, 0xd3, 0x69, 0xee, 0x4f, - 0x9c, 0x46, 0x02, 0x35, 0xba, 0x04, 0x06, 0x2e, 0xfe, 0x03, 0xaf, 0xa5, 0x4d, 0x9a, 0x42, 0xdf, - 0xdc, 0xbe, 0x94, 0xef, 0x95, 0x13, 0xf4, 0x35, 0xb0, 0xd9, 0xee, 0x48, 0xb9, 0xdc, 0xce, 0x91, - 0xcf, 0x26, 0xce, 0xe1, 0xd4, 0xb6, 0xeb, 0xbb, 0x23, 0x4a, 0x04, 0x0a, 0x37, 0xcb, 0xae, 0x1b, - 0xf6, 0x3c, 0xdf, 0x1d, 0x78, 0x4c, 0x8a, 0xd1, 0x26, 0x26, 0x08, 0x35, 0xa1, 0x3c, 0x72, 0xc3, - 0x48, 0xe7, 0x4d, 0x55, 0xa2, 0xa7, 0xa2, 0xcd, 0x71, 0x8b, 0xb2, 0xee, 0x8e, 0x74, 0xb3, 0xaa, - 0xcd, 0x21, 0x20, 0xa9, 0x36, 0x87, 0x80, 0xe0, 0x5f, 0x18, 0x86, 0x23, 0xdf, 0xc4, 0x57, 0xce, - 0x70, 0xf0, 0x77, 0x12, 0x2d, 0xeb, 0x2b, 0x2a, 0x2d, 0x3f, 0x0f, 0x8b, 0xbd, 0xd4, 0xca, 0x6c, - 0x6d, 0xcb, 0x16, 0x6e, 0x06, 0x1d, 0x8f, 0x13, 0xd5, 0x09, 0xc8, 0x0c, 0xd5, 0x65, 0xf4, 0x91, - 0x3f, 0xa8, 0x8f, 0x44, 0xea, 0x85, 0xbb, 0x4b, 0xfd, 0xb1, 0x47, 0xa0, 0x1a, 0xff, 0x5c, 0x87, - 0x6a, 0x50, 0xbe, 0xf8, 0x0a, 0x79, 0xfd, 0x02, 0xd9, 0x58, 0xca, 0xa1, 0x3a, 0x54, 0x3a, 0x17, - 0xd6, 0x5f, 0x12, 0x33, 0xeb, 0xec, 0x6f, 0x4a, 0x3a, 0x11, 0x08, 0xd1, 0x37, 0xa1, 0x28, 0xa3, - 0xfb, 0xd1, 0x84, 0x39, 0xf3, 0x97, 0xac, 0x95, 0x63, 0x07, 0xe0, 0x52, 0x4a, 0x38, 0xf7, 0x84, - 0x85, 0xae, 0x42, 0x4d, 0x00, 0x55, 0xaf, 0xf8, 0x44, 0xb6, 0x65, 0x9b, 0xa2, 0xf4, 0xd0, 0x8c, - 0x55, 0x83, 0xde, 0x79, 0x28, 0x4a, 0x81, 0x1d, 0xcd, 0x24, 0x61, 0x53, 0x6e, 0x93, 0xea, 0x9e, - 0xe3, 0x1c, 0x7a, 0x06, 0xec, 0xeb, 0xae, 0x37, 0x40, 0x46, 0x0e, 0x68, 0xb4, 0x78, 0x57, 0x8e, - 0x66, 0xc1, 0xc6, 0xb1, 0xcf, 0xc5, 0x9d, 0xea, 0x63, 0xd9, 0x76, 0x99, 0xde, 0xde, 0x3c, 0xb8, - 0x10, 0x9f, 0xfc, 0x8a, 0xec, 0xa7, 0xea, 0xa6, 0x0d, 0x7a, 0x28, 0x7d, 0x54, 0xa6, 0xc7, 0xb3, - 0xd2, 0x9a, 0xb5, 0x1c, 0x13, 0xdc, 0x84, 0x9a, 0xd1, 0x30, 0x31, 0xc5, 0x7a, 0xb0, 0xdb, 0x63, - 0x8a, 0x75, 0x4a, 0x97, 0x05, 0xe7, 0xd0, 0x25, 0xa8, 0xf0, 0xcc, 0x59, 0xfc, 0xb0, 0x72, 0x3c, - 0x9b, 0x20, 0x1b, 0x89, 0xd1, 0xca, 0x89, 0xe9, 0x8b, 0x31, 0xa1, 0x6f, 0x43, 0xf5, 0x12, 0x65, - 0x2a, 0xba, 0x1c, 0xcb, 0x86, 0xa7, 0x29, 0x92, 0x4a, 0x87, 0x38, 0x9c, 0x43, 0x6f, 0x88, 0x24, - 0x3e, 0xed, 0x5c, 0x91, 0x33, 0xc3, 0x89, 0xc6, 0xf7, 0x5a, 0x9d, 0x8d, 0x10, 0x53, 0x7e, 0x3d, - 0x45, 0x59, 0xc5, 0x61, 0x67, 0xc6, 0x83, 0x8d, 0x29, 0x3b, 0x77, 0xf9, 0xdb, 0x05, 0xce, 0x9d, - 0x7d, 0x53, 0xff, 0xf3, 0x60, 0xc3, 0x65, 0x2e, 0x7a, 0x05, 0x16, 0x85, 0x2c, 0xe3, 0xbf, 0x26, - 0xa4, 0x6c, 0xfe, 0xc0, 0xff, 0x20, 0x52, 0x36, 0x7f, 0xf0, 0xff, 0x10, 0x38, 0xd7, 0x79, 0xf3, - 0x83, 0x8f, 0x5b, 0xb9, 0x0f, 0x3f, 0x6e, 0xe5, 0x3e, 0xfd, 0xb8, 0x65, 0x7d, 0x7f, 0xaf, 0x65, - 0xfd, 0x7a, 0xaf, 0x65, 0xbd, 0xbf, 0xd7, 0xb2, 0x3e, 0xd8, 0x6b, 0x59, 0xff, 0xd8, 0x6b, 0x59, - 0xff, 0xdc, 0x6b, 0xe5, 0x3e, 0xdd, 0x6b, 0x59, 0xef, 0x7e, 0xd2, 0xca, 0x7d, 0xf0, 0x49, 0x2b, - 0xf7, 0xe1, 0x27, 0xad, 0xdc, 0x77, 0x1f, 0xbd, 0x7b, 0xc1, 0x2a, 0xdd, 0x62, 0x49, 0x7c, 0x3d, - 0xf9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xd4, 0xcd, 0x88, 0x1f, 0x23, 0x00, 0x00, + // 2673 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0x4d, 0x8c, 0x5b, 0x47, + 0xd9, 0xcf, 0x7e, 0xfe, 0xfb, 0xec, 0xdd, 0x6c, 0x66, 0x9d, 0xc4, 0xda, 0xa4, 0x7e, 0xdb, 0x11, + 0xb4, 0xa1, 0x49, 0xd7, 0x4d, 0x4a, 0x4b, 0x9a, 0x52, 0x4a, 0xbc, 0xdb, 0xa4, 0x49, 0xb7, 0x69, + 0x3a, 0x9b, 0xa6, 0x05, 0x51, 0x55, 0x2f, 0xf6, 0xac, 0xf7, 0x29, 0xf6, 0x7b, 0xce, 0x7b, 0xe3, + 0xa6, 0x7b, 0x43, 0xe2, 0x8c, 0xa8, 0xc4, 0x01, 0xb8, 0x20, 0x21, 0x21, 0x81, 0x40, 0xbd, 0x20, + 0x4e, 0x08, 0xc1, 0x85, 0x43, 0xb9, 0xf5, 0x58, 0xf5, 0x60, 0xe8, 0xf6, 0x82, 0x56, 0x42, 0xaa, + 0x84, 0xc4, 0xa1, 0x27, 0x34, 0x7f, 0xef, 0xcd, 0x7b, 0x6b, 0x93, 0x3a, 0x04, 0xb5, 0xb9, 0xd8, + 0xf3, 0x7d, 0xf3, 0xcd, 0x37, 0xf3, 0xfd, 0xcc, 0xf7, 0x7d, 0xf3, 0xd9, 0x70, 0x7c, 0x74, 0xab, + 0xdf, 0x1e, 0x04, 0xfd, 0x51, 0x18, 0xb0, 0x20, 0x1e, 0xac, 0x89, 0x4f, 0x54, 0xd1, 0xf0, 0x4a, + 0xa3, 0x1f, 0xf4, 0x03, 0x49, 0xc3, 0x47, 0x72, 0x7e, 0xc5, 0xe9, 0x07, 0x41, 0x7f, 0x40, 0xdb, + 0x02, 0xba, 0x39, 0xde, 0x6e, 0x33, 0x6f, 0x48, 0x23, 0xe6, 0x0e, 0x47, 0x8a, 0x60, 0x55, 0x71, + 0xbf, 0x3d, 0x18, 0x06, 0x3d, 0x3a, 0x68, 0x47, 0xcc, 0x65, 0x91, 0xfc, 0x54, 0x14, 0xcb, 0x9c, + 0x62, 0x34, 0x8e, 0x76, 0xc4, 0x87, 0x44, 0xe2, 0xdf, 0x5b, 0x70, 0x64, 0xd3, 0xbd, 0x49, 0x07, + 0xd7, 0x83, 0x1b, 0xee, 0x60, 0x4c, 0x23, 0x42, 0xa3, 0x51, 0xe0, 0x47, 0x14, 0xad, 0x43, 0x69, + 0xc0, 0x27, 0xa2, 0xa6, 0xb5, 0x5a, 0x38, 0x59, 0x3b, 0x7b, 0x6a, 0x2d, 0x3e, 0xf2, 0xd4, 0x05, + 0x12, 0x1b, 0xbd, 0xe0, 0xb3, 0x70, 0x97, 0xa8, 0xa5, 0x2b, 0x37, 0xa0, 0x66, 0xa0, 0xd1, 0x12, + 0x14, 0x6e, 0xd1, 0xdd, 0xa6, 0xb5, 0x6a, 0x9d, 0xac, 0x12, 0x3e, 0x44, 0x67, 0xa0, 0xf8, 0x36, + 0x67, 0xd3, 0xcc, 0xaf, 0x5a, 0x27, 0x6b, 0x67, 0x8f, 0x27, 0x9b, 0xbc, 0xe6, 0x7b, 0xb7, 0xc7, + 0x54, 0xac, 0x56, 0x1b, 0x49, 0xca, 0xf3, 0xf9, 0x73, 0x16, 0x3e, 0x05, 0x87, 0x0f, 0xcc, 0xa3, + 0xa3, 0x50, 0x12, 0x14, 0xf2, 0xc4, 0x55, 0xa2, 0x20, 0xdc, 0x00, 0xb4, 0xc5, 0x42, 0xea, 0x0e, + 0x89, 0xcb, 0xf8, 0x79, 0x6f, 0x8f, 0x69, 0xc4, 0xf0, 0xcb, 0xb0, 0x9c, 0xc2, 0x2a, 0xb1, 0x9f, + 0x86, 0x5a, 0x94, 0xa0, 0x95, 0xec, 0x8d, 0xe4, 0x58, 0xc9, 0x1a, 0x62, 0x12, 0xe2, 0x9f, 0x5b, + 0x00, 0xc9, 0x1c, 0x6a, 0x01, 0xc8, 0xd9, 0x17, 0xdd, 0x68, 0x47, 0x08, 0x6c, 0x13, 0x03, 0x83, + 0x4e, 0xc3, 0xe1, 0x04, 0xba, 0x1a, 0x6c, 0xed, 0xb8, 0x61, 0x4f, 0xe8, 0xc0, 0x26, 0x07, 0x27, + 0x10, 0x02, 0x3b, 0x74, 0x19, 0x6d, 0x16, 0x56, 0xad, 0x93, 0x05, 0x22, 0xc6, 0x5c, 0x5a, 0x46, + 0x7d, 0xd7, 0x67, 0x4d, 0x5b, 0xa8, 0x53, 0x41, 0x1c, 0xcf, 0xed, 0x4b, 0xa3, 0x66, 0x71, 0xd5, + 0x3a, 0xb9, 0x40, 0x14, 0x84, 0xff, 0x5d, 0x80, 0xfa, 0xab, 0x63, 0x1a, 0xee, 0x2a, 0x05, 0xa0, + 0x16, 0x54, 0x22, 0x3a, 0xa0, 0x5d, 0x16, 0x84, 0xd2, 0x22, 0x9d, 0x7c, 0xd3, 0x22, 0x31, 0x0e, + 0x35, 0xa0, 0x38, 0xf0, 0x86, 0x1e, 0x13, 0xc7, 0x5a, 0x20, 0x12, 0x40, 0xe7, 0xa1, 0x18, 0x31, + 0x37, 0x64, 0xe2, 0x2c, 0xb5, 0xb3, 0x2b, 0x6b, 0xd2, 0x31, 0xd7, 0xb4, 0x63, 0xae, 0x5d, 0xd7, + 0x8e, 0xd9, 0xa9, 0xbc, 0x3f, 0x71, 0x72, 0xef, 0xfe, 0xcd, 0xb1, 0x88, 0x5c, 0x82, 0x9e, 0x86, + 0x02, 0xf5, 0x7b, 0xe2, 0xbc, 0x9f, 0x77, 0x25, 0x5f, 0x80, 0xce, 0x40, 0xb5, 0xe7, 0x85, 0xb4, + 0xcb, 0xbc, 0xc0, 0x17, 0x52, 0x2d, 0x9e, 0x5d, 0x4e, 0x2c, 0xb2, 0xa1, 0xa7, 0x48, 0x42, 0x85, + 0x4e, 0x43, 0x29, 0xe2, 0xaa, 0x8b, 0x9a, 0x65, 0xee, 0x0b, 0x9d, 0xc6, 0xfe, 0xc4, 0x59, 0x92, + 0x98, 0xd3, 0xc1, 0xd0, 0x63, 0x74, 0x38, 0x62, 0xbb, 0x44, 0xd1, 0xa0, 0xc7, 0xa0, 0xdc, 0xa3, + 0x03, 0xca, 0x0d, 0x5e, 0x11, 0x06, 0x5f, 0x32, 0xd8, 0x8b, 0x09, 0xa2, 0x09, 0xd0, 0x9b, 0x60, + 0x8f, 0x06, 0xae, 0xdf, 0xac, 0x0a, 0x29, 0x16, 0x13, 0xc2, 0x6b, 0x03, 0xd7, 0xef, 0x3c, 0xf3, + 0xd1, 0xc4, 0x79, 0xaa, 0xef, 0xb1, 0x9d, 0xf1, 0xcd, 0xb5, 0x6e, 0x30, 0x6c, 0xf7, 0x43, 0x77, + 0xdb, 0xf5, 0xdd, 0xf6, 0x20, 0xb8, 0xe5, 0xb5, 0xdf, 0x7e, 0xb2, 0xcd, 0xef, 0xe0, 0xed, 0x31, + 0x0d, 0x3d, 0x1a, 0xb6, 0x39, 0x9b, 0x35, 0x61, 0x12, 0xbe, 0x94, 0x08, 0xb6, 0xe8, 0x0a, 0xf7, + 0xbf, 0x20, 0xa4, 0xeb, 0x3b, 0x63, 0xff, 0x56, 0xd4, 0x04, 0xb1, 0xcb, 0xb1, 0x64, 0x17, 0x81, + 0x27, 0x74, 0xfb, 0x52, 0x18, 0x8c, 0x47, 0x9d, 0x43, 0xfb, 0x13, 0xc7, 0xa4, 0x27, 0x26, 0x70, + 0xc5, 0xae, 0x94, 0x96, 0xca, 0xf8, 0xbd, 0x02, 0xa0, 0x2d, 0x77, 0x38, 0x1a, 0xd0, 0xb9, 0xcc, + 0x1f, 0x1b, 0x3a, 0x7f, 0xcf, 0x86, 0x2e, 0xcc, 0x6b, 0xe8, 0xc4, 0x6a, 0xf6, 0x7c, 0x56, 0x2b, + 0x7e, 0x5e, 0xab, 0x95, 0xbe, 0xf4, 0x56, 0xc3, 0x4d, 0xb0, 0x39, 0x67, 0x1e, 0x2c, 0x43, 0xf7, + 0x8e, 0xb0, 0x4d, 0x9d, 0xf0, 0x21, 0xde, 0x84, 0x92, 0x94, 0x0b, 0xad, 0x64, 0x8d, 0x97, 0xbe, + 0xb7, 0x89, 0xe1, 0x0a, 0xda, 0x24, 0x4b, 0x89, 0x49, 0x0a, 0x42, 0xd9, 0xf8, 0x8f, 0x16, 0x2c, + 0x28, 0x8f, 0x50, 0xb1, 0xef, 0x26, 0x94, 0x65, 0xec, 0xd1, 0x71, 0xef, 0x58, 0x36, 0xee, 0x5d, + 0xe8, 0xb9, 0x23, 0x46, 0xc3, 0x4e, 0xfb, 0xfd, 0x89, 0x63, 0x7d, 0x34, 0x71, 0x1e, 0x9d, 0xa5, + 0x34, 0x9d, 0x6b, 0x74, 0xbc, 0xd4, 0x8c, 0xd1, 0x29, 0x71, 0x3a, 0x16, 0x29, 0xb7, 0x3a, 0xb4, + 0x26, 0x53, 0xd4, 0x65, 0xbf, 0x4f, 0x23, 0xce, 0xd9, 0xe6, 0x1e, 0x41, 0x24, 0x0d, 0x17, 0xf3, + 0x8e, 0x1b, 0xfa, 0x9e, 0xdf, 0x8f, 0x9a, 0x05, 0x11, 0xd3, 0x63, 0x18, 0xff, 0xd4, 0x82, 0xe5, + 0x94, 0x5b, 0x2b, 0x21, 0xce, 0x41, 0x29, 0xe2, 0x96, 0xd2, 0x32, 0x18, 0x4e, 0xb1, 0x25, 0xf0, + 0x9d, 0x45, 0x75, 0xf8, 0x92, 0x84, 0x89, 0xa2, 0xbf, 0x7f, 0x47, 0xfb, 0x8b, 0x05, 0x75, 0x91, + 0x98, 0xf4, 0x5d, 0x43, 0x60, 0xfb, 0xee, 0x90, 0x2a, 0x53, 0x89, 0xb1, 0x91, 0xad, 0xf8, 0x76, + 0x15, 0x9d, 0xad, 0xe6, 0x0d, 0xb0, 0xd6, 0x3d, 0x07, 0x58, 0x2b, 0xb9, 0x77, 0x0d, 0x28, 0x72, + 0xf7, 0xde, 0x15, 0xc1, 0xb5, 0x4a, 0x24, 0x80, 0x1f, 0x85, 0x05, 0x25, 0x85, 0x52, 0xed, 0xac, + 0x04, 0x3b, 0x84, 0x92, 0xb4, 0x04, 0xfa, 0x0a, 0x54, 0xe3, 0xc2, 0x44, 0x48, 0x5b, 0xe8, 0x94, + 0xf6, 0x27, 0x4e, 0x9e, 0x45, 0x24, 0x99, 0x40, 0x8e, 0x99, 0xf4, 0xad, 0x4e, 0x75, 0x7f, 0xe2, + 0x48, 0x84, 0x4a, 0xf1, 0xe8, 0x04, 0xd8, 0x3b, 0x3c, 0x6f, 0x72, 0x15, 0xd8, 0x9d, 0xca, 0xfe, + 0xc4, 0x11, 0x30, 0x11, 0x9f, 0xf8, 0x12, 0xd4, 0x37, 0x69, 0xdf, 0xed, 0xee, 0xaa, 0x4d, 0x1b, + 0x9a, 0x1d, 0xdf, 0xd0, 0xd2, 0x3c, 0x1e, 0x86, 0x7a, 0xbc, 0xe3, 0x5b, 0xc3, 0x48, 0xdd, 0x86, + 0x5a, 0x8c, 0x7b, 0x39, 0xc2, 0x3f, 0xb3, 0x40, 0xf9, 0x00, 0xc2, 0x46, 0xb5, 0xc3, 0x63, 0x21, + 0xec, 0x4f, 0x1c, 0x85, 0xd1, 0xc5, 0x0c, 0x7a, 0x16, 0xca, 0x91, 0xd8, 0x91, 0x33, 0xcb, 0xba, + 0x96, 0x98, 0xe8, 0x1c, 0xe2, 0x2e, 0xb2, 0x3f, 0x71, 0x34, 0x21, 0xd1, 0x03, 0xb4, 0x96, 0x2a, + 0x08, 0xa4, 0x60, 0x8b, 0xfb, 0x13, 0xc7, 0xc0, 0x9a, 0x05, 0x02, 0xfe, 0xcc, 0x82, 0xda, 0x75, + 0xd7, 0x8b, 0x5d, 0xa8, 0xa9, 0x4d, 0x94, 0xc4, 0x6a, 0x89, 0xe0, 0x9e, 0xd8, 0xa3, 0x03, 0x77, + 0xf7, 0x62, 0x10, 0x0a, 0xbe, 0x0b, 0x24, 0x86, 0x93, 0x1c, 0x6e, 0x4f, 0xcd, 0xe1, 0xc5, 0xf9, + 0x43, 0xfb, 0xff, 0x37, 0x90, 0x5e, 0xb1, 0x2b, 0xf9, 0xa5, 0x02, 0x7e, 0xcf, 0x82, 0xba, 0x14, + 0x5e, 0x79, 0xde, 0xf7, 0xa0, 0x24, 0x75, 0x23, 0xc4, 0xff, 0x2f, 0x81, 0xe9, 0xd4, 0x3c, 0x41, + 0x49, 0xf1, 0x44, 0xcf, 0xc3, 0x62, 0x2f, 0x0c, 0x46, 0x23, 0xda, 0xdb, 0x52, 0xe1, 0x2f, 0x9f, + 0x0d, 0x7f, 0x1b, 0xe6, 0x3c, 0xc9, 0x90, 0xe3, 0xbf, 0x5a, 0xb0, 0xa0, 0x82, 0x89, 0x32, 0x57, + 0xac, 0x62, 0xeb, 0x9e, 0xb3, 0x67, 0x7e, 0xde, 0xec, 0x79, 0x14, 0x4a, 0x7d, 0x9e, 0x5f, 0x74, + 0x40, 0x52, 0xd0, 0x7c, 0x59, 0x15, 0x5f, 0x81, 0x45, 0x2d, 0xca, 0x8c, 0x88, 0xba, 0x92, 0x8d, + 0xa8, 0x97, 0x7b, 0xd4, 0x67, 0xde, 0xb6, 0x17, 0xc7, 0x48, 0x45, 0x8f, 0x7f, 0x64, 0xc1, 0x52, + 0x96, 0x04, 0x6d, 0x64, 0x1e, 0x16, 0x8f, 0xcc, 0x66, 0x67, 0xbe, 0x29, 0x34, 0x6b, 0xf5, 0xb2, + 0x78, 0xea, 0x6e, 0x2f, 0x8b, 0x86, 0x19, 0x64, 0xaa, 0x2a, 0x2a, 0xe0, 0x9f, 0x58, 0xb0, 0x90, + 0xb2, 0x25, 0x3a, 0x07, 0xf6, 0x76, 0x18, 0x0c, 0xe7, 0x32, 0x94, 0x58, 0x81, 0xbe, 0x0e, 0x79, + 0x16, 0xcc, 0x65, 0xa6, 0x3c, 0x0b, 0xb8, 0x95, 0x94, 0xf8, 0x05, 0x59, 0xb7, 0x4b, 0x08, 0x3f, + 0x05, 0x55, 0x21, 0xd0, 0x35, 0xd7, 0x0b, 0xa7, 0x26, 0x8c, 0xe9, 0x02, 0x3d, 0x0b, 0x87, 0x64, + 0x30, 0x9c, 0xbe, 0xb8, 0x3e, 0x6d, 0x71, 0x5d, 0x2f, 0x3e, 0x0e, 0x45, 0x51, 0x74, 0xf0, 0x25, + 0x3d, 0x97, 0xb9, 0x7a, 0x09, 0x1f, 0xe3, 0x23, 0xb0, 0xcc, 0xef, 0x20, 0x0d, 0xa3, 0xf5, 0x60, + 0xec, 0x33, 0xfd, 0x6e, 0x3a, 0x0d, 0x8d, 0x34, 0x5a, 0x79, 0x49, 0x03, 0x8a, 0x5d, 0x8e, 0x10, + 0x3c, 0x16, 0x88, 0x04, 0xf0, 0x2f, 0x2d, 0x40, 0x97, 0x28, 0x13, 0xbb, 0x5c, 0xde, 0x88, 0xaf, + 0xc7, 0x0a, 0x54, 0x86, 0x2e, 0xeb, 0xee, 0xd0, 0x30, 0xd2, 0xf5, 0x8b, 0x86, 0xbf, 0x88, 0xc2, + 0x13, 0x9f, 0x81, 0xe5, 0xd4, 0x29, 0x95, 0x4c, 0x2b, 0x50, 0xe9, 0x2a, 0x9c, 0x4a, 0x79, 0x31, + 0x8c, 0x7f, 0x97, 0x87, 0x8a, 0x2e, 0xeb, 0xd0, 0x19, 0xa8, 0x6d, 0x7b, 0x7e, 0x9f, 0x86, 0xa3, + 0xd0, 0x53, 0x2a, 0xb0, 0x65, 0x99, 0x67, 0xa0, 0x89, 0x09, 0xa0, 0xc7, 0xa1, 0x3c, 0x8e, 0x68, + 0xf8, 0x96, 0x27, 0x6f, 0x7a, 0xb5, 0xd3, 0xd8, 0x9b, 0x38, 0xa5, 0xd7, 0x22, 0x1a, 0x5e, 0xde, + 0xe0, 0xc9, 0x67, 0x2c, 0x46, 0x44, 0x7e, 0xf7, 0xd0, 0x4b, 0xca, 0x4d, 0x45, 0x01, 0xd7, 0xf9, + 0x06, 0x3f, 0x7e, 0x26, 0xd4, 0x8d, 0xc2, 0x60, 0x48, 0xd9, 0x0e, 0x1d, 0x47, 0xed, 0x6e, 0x30, + 0x1c, 0x06, 0x7e, 0x5b, 0x74, 0x02, 0x84, 0xd0, 0x3c, 0x83, 0xf2, 0xe5, 0xca, 0x73, 0xaf, 0x43, + 0x99, 0xed, 0x84, 0xc1, 0xb8, 0xbf, 0x23, 0x12, 0x43, 0xa1, 0x73, 0x7e, 0x7e, 0x7e, 0x9a, 0x03, + 0xd1, 0x03, 0xf4, 0x30, 0xd7, 0x16, 0xed, 0xde, 0x8a, 0xc6, 0x43, 0xf9, 0xf6, 0xec, 0x14, 0xf7, + 0x27, 0x8e, 0xf5, 0x38, 0x89, 0xd1, 0xf8, 0x02, 0x2c, 0xa4, 0x4a, 0x61, 0xf4, 0x04, 0xd8, 0x21, + 0xdd, 0xd6, 0xa1, 0x00, 0x1d, 0xac, 0x98, 0x65, 0xf6, 0xe7, 0x34, 0x44, 0x7c, 0xe2, 0x1f, 0xe6, + 0xc1, 0x31, 0x5e, 0xfd, 0x17, 0x83, 0xf0, 0x65, 0xca, 0x42, 0xaf, 0x7b, 0xd5, 0x1d, 0x52, 0xed, + 0x5e, 0x0e, 0xd4, 0x86, 0x02, 0xf9, 0x96, 0x71, 0x8b, 0x60, 0x18, 0xd3, 0xa1, 0x87, 0x00, 0xc4, + 0xb5, 0x93, 0xf3, 0xf2, 0x42, 0x55, 0x05, 0x46, 0x4c, 0xaf, 0xa7, 0x94, 0xdd, 0x9e, 0x53, 0x39, + 0x4a, 0xc9, 0x97, 0xb3, 0x4a, 0x9e, 0x9b, 0x4f, 0xac, 0x59, 0xf3, 0xba, 0x14, 0xd3, 0xd7, 0x05, + 0xff, 0xd3, 0x82, 0xd6, 0xa6, 0x3e, 0xf9, 0x3d, 0xaa, 0x43, 0xcb, 0x9b, 0xbf, 0x4f, 0xf2, 0x16, + 0xee, 0xa3, 0xbc, 0x76, 0x46, 0xde, 0x16, 0xc0, 0xa6, 0xe7, 0xd3, 0x8b, 0xde, 0x80, 0xd1, 0x70, + 0xca, 0x23, 0xe9, 0xc7, 0x85, 0x24, 0xe2, 0x10, 0xba, 0xad, 0x75, 0xb0, 0x6e, 0x84, 0xf9, 0xfb, + 0x21, 0x62, 0xfe, 0x3e, 0x8a, 0x58, 0xc8, 0x44, 0x40, 0x1f, 0xca, 0xdb, 0x42, 0x3c, 0x99, 0xb1, + 0x53, 0xfd, 0xa7, 0x44, 0xf6, 0xce, 0xb7, 0xd4, 0xe6, 0x4f, 0xdf, 0xa5, 0xe0, 0x12, 0x5d, 0xc1, + 0x76, 0xb4, 0xeb, 0x33, 0xf7, 0x1d, 0x63, 0x3d, 0xd1, 0x9b, 0x20, 0x57, 0xd5, 0x74, 0xc5, 0xa9, + 0x35, 0xdd, 0x73, 0x6a, 0x9b, 0xff, 0xa5, 0xae, 0xc3, 0xcf, 0x25, 0x01, 0x56, 0x18, 0x45, 0x05, + 0xd8, 0x47, 0xee, 0x76, 0xfd, 0xd5, 0xa5, 0xff, 0x93, 0x05, 0x4b, 0x97, 0x28, 0x4b, 0xd7, 0x58, + 0x0f, 0x90, 0x49, 0xf1, 0x8b, 0x70, 0xd8, 0x38, 0xbf, 0x92, 0xfe, 0xc9, 0x4c, 0x61, 0x75, 0x24, + 0x91, 0xff, 0xb2, 0xdf, 0xa3, 0xef, 0xa8, 0xf7, 0x6a, 0xba, 0xa6, 0xba, 0x06, 0x35, 0x63, 0x12, + 0x5d, 0xc8, 0x54, 0x53, 0xcb, 0x99, 0x36, 0x2d, 0xaf, 0x08, 0x3a, 0x0d, 0x25, 0x93, 0x7c, 0x95, + 0xaa, 0x5a, 0x39, 0xae, 0x3c, 0xb6, 0x00, 0x09, 0x73, 0x09, 0xb6, 0x66, 0xee, 0x13, 0xd8, 0x97, + 0xe2, 0xb2, 0x2a, 0x86, 0xd1, 0xc3, 0x60, 0x87, 0xc1, 0x1d, 0x5d, 0x26, 0x2f, 0x24, 0x5b, 0x92, + 0xe0, 0x0e, 0x11, 0x53, 0xf8, 0x59, 0x28, 0x90, 0xe0, 0x0e, 0x6a, 0x01, 0x84, 0xae, 0xdf, 0xa7, + 0x37, 0xe2, 0x07, 0x5a, 0x9d, 0x18, 0x98, 0x19, 0x75, 0xc9, 0x3a, 0x1c, 0x36, 0x4f, 0x24, 0xcd, + 0xbd, 0x06, 0xe5, 0x57, 0xc7, 0xa6, 0xba, 0x1a, 0x19, 0x75, 0xc9, 0x3e, 0x80, 0x26, 0xe2, 0x3e, + 0x03, 0x09, 0x1e, 0x9d, 0x80, 0x2a, 0x73, 0x6f, 0x0e, 0xe8, 0xd5, 0x24, 0x04, 0x26, 0x08, 0x3e, + 0xcb, 0xdf, 0x96, 0x37, 0x8c, 0x02, 0x2b, 0x41, 0xa0, 0xc7, 0x60, 0x29, 0x39, 0xf3, 0xb5, 0x90, + 0x6e, 0x7b, 0xef, 0x08, 0x0b, 0xd7, 0xc9, 0x01, 0x3c, 0x3a, 0x09, 0x87, 0x12, 0xdc, 0x96, 0x28, + 0x64, 0x6c, 0x41, 0x9a, 0x45, 0x73, 0xdd, 0x08, 0x71, 0x5f, 0xb8, 0x3d, 0x76, 0x07, 0xe2, 0xf2, + 0xd5, 0x89, 0x81, 0xc1, 0x7f, 0xb6, 0xe0, 0xb0, 0x34, 0x35, 0x73, 0xd9, 0x03, 0xe9, 0xf5, 0xbf, + 0xb2, 0x00, 0x99, 0x12, 0x28, 0xd7, 0xfa, 0xaa, 0xd9, 0x67, 0xe2, 0x95, 0x52, 0x4d, 0x3c, 0x99, + 0x25, 0x2a, 0x69, 0x15, 0x61, 0x28, 0x75, 0x65, 0x3f, 0x4d, 0x34, 0xc6, 0xe5, 0x9b, 0x5c, 0x62, + 0x88, 0xfa, 0x46, 0x0e, 0x14, 0x6f, 0xee, 0x32, 0x1a, 0xa9, 0x17, 0xb5, 0x68, 0x25, 0x08, 0x04, + 0x91, 0x5f, 0x7c, 0x2f, 0xea, 0x33, 0xe1, 0x35, 0x76, 0xb2, 0x97, 0x42, 0x11, 0x3d, 0xc0, 0xbf, + 0xcd, 0xc3, 0xc2, 0x8d, 0x60, 0x30, 0x4e, 0x92, 0xe6, 0x83, 0x94, 0x30, 0x52, 0xcf, 0xfc, 0xa2, + 0x7e, 0xe6, 0x23, 0xb0, 0x23, 0x46, 0x47, 0xc2, 0xb3, 0x0a, 0x44, 0x8c, 0x11, 0x86, 0x3a, 0x73, + 0xc3, 0x3e, 0x65, 0xf2, 0xf1, 0xd4, 0x2c, 0x89, 0xaa, 0x36, 0x85, 0x43, 0xab, 0x50, 0x73, 0xfb, + 0xfd, 0x90, 0xf6, 0x5d, 0x46, 0x3b, 0xbb, 0xcd, 0xb2, 0xd8, 0xcc, 0x44, 0xe1, 0x37, 0x60, 0x51, + 0x2b, 0x4b, 0x99, 0xf4, 0x09, 0x28, 0xbf, 0x2d, 0x30, 0x53, 0xda, 0x6e, 0x92, 0x54, 0x85, 0x31, + 0x4d, 0x96, 0xfe, 0x79, 0x41, 0x9f, 0x19, 0x5f, 0x81, 0x92, 0x24, 0x47, 0x27, 0xcc, 0x27, 0x90, + 0xac, 0x02, 0x39, 0xac, 0xde, 0x33, 0x18, 0x4a, 0x92, 0x91, 0x32, 0xbc, 0xf0, 0x0d, 0x89, 0x21, + 0xea, 0x1b, 0xff, 0xcb, 0x82, 0x23, 0x1b, 0x94, 0xd1, 0x2e, 0xa3, 0xbd, 0x8b, 0x1e, 0x1d, 0xf4, + 0xbe, 0xd0, 0xd7, 0x79, 0xdc, 0x63, 0x2b, 0x18, 0x3d, 0x36, 0x1e, 0x77, 0x06, 0x9e, 0x4f, 0x37, + 0x8d, 0x26, 0x4d, 0x82, 0xe0, 0x11, 0x62, 0x9b, 0x1f, 0x5c, 0x4e, 0xcb, 0xdf, 0x73, 0x0c, 0x4c, + 0x6c, 0xe1, 0x52, 0x62, 0x61, 0xfc, 0x03, 0x0b, 0x8e, 0x66, 0xa5, 0x56, 0x46, 0x6a, 0x43, 0x49, + 0x2c, 0x9e, 0xd2, 0xde, 0x4d, 0xad, 0x20, 0x8a, 0x0c, 0x9d, 0x4b, 0xed, 0x2f, 0x7e, 0x07, 0xea, + 0x34, 0xf7, 0x27, 0x4e, 0x23, 0xc1, 0x1a, 0x1d, 0x04, 0x83, 0x16, 0xff, 0x81, 0xbf, 0xb3, 0x4d, + 0x9e, 0xc2, 0xde, 0xdc, 0xbf, 0x54, 0xec, 0x95, 0x00, 0xfa, 0x1a, 0xd8, 0x6c, 0x77, 0xa4, 0x42, + 0x6e, 0xe7, 0xc8, 0x67, 0x13, 0xe7, 0x70, 0x6a, 0xd9, 0xf5, 0xdd, 0x11, 0x25, 0x82, 0x84, 0xbb, + 0x65, 0xd7, 0x0d, 0x7b, 0x9e, 0xef, 0x0e, 0x3c, 0x26, 0xd5, 0x68, 0x13, 0x13, 0x85, 0x9a, 0x50, + 0x1e, 0xb9, 0x61, 0xa4, 0xeb, 0xa6, 0x2a, 0xd1, 0xa0, 0x68, 0x81, 0xdc, 0xa2, 0xac, 0xbb, 0x23, + 0xc3, 0xac, 0x6a, 0x81, 0x08, 0x4c, 0xaa, 0x05, 0x22, 0x30, 0xf8, 0x17, 0x86, 0xe3, 0xc8, 0x3b, + 0xf1, 0xa5, 0x73, 0x1c, 0xfc, 0x9d, 0xc4, 0xca, 0xfa, 0x88, 0xca, 0xca, 0xcf, 0xc3, 0x62, 0x2f, + 0x35, 0x33, 0xdb, 0xda, 0xb2, 0xbd, 0x9b, 0x21, 0xc7, 0xe3, 0xc4, 0x74, 0x02, 0x33, 0xc3, 0x74, + 0x19, 0x7b, 0xe4, 0x0f, 0xda, 0x23, 0xd1, 0x7a, 0xe1, 0xee, 0x5a, 0x7f, 0xec, 0x11, 0xa8, 0xc6, + 0x3f, 0xe5, 0xa1, 0x1a, 0x94, 0x2f, 0xbe, 0x42, 0x5e, 0xbf, 0x40, 0x36, 0x96, 0x72, 0xa8, 0x0e, + 0x95, 0xce, 0x85, 0xf5, 0x97, 0x04, 0x64, 0x9d, 0xfd, 0x4d, 0x49, 0x17, 0x02, 0x21, 0xfa, 0x26, + 0x14, 0x65, 0x76, 0x3f, 0x9a, 0x08, 0x67, 0xfe, 0xca, 0xb5, 0x72, 0xec, 0x00, 0x5e, 0x6a, 0x09, + 0xe7, 0x9e, 0xb0, 0xd0, 0x55, 0xa8, 0x09, 0xa4, 0xea, 0x23, 0x9f, 0xc8, 0xb6, 0x73, 0x53, 0x9c, + 0x1e, 0x9a, 0x31, 0x6b, 0xf0, 0x3b, 0x0f, 0x45, 0xa9, 0xb0, 0xa3, 0x99, 0x22, 0x6c, 0xca, 0x69, + 0x52, 0x9d, 0x75, 0x9c, 0x43, 0xcf, 0x80, 0x7d, 0xdd, 0xf5, 0x06, 0xc8, 0xa8, 0x01, 0x8d, 0xf6, + 0xef, 0xca, 0xd1, 0x2c, 0xda, 0xd8, 0xf6, 0xb9, 0xb8, 0x8b, 0x7d, 0x2c, 0xdb, 0x4a, 0xd3, 0xcb, + 0x9b, 0x07, 0x27, 0xe2, 0x9d, 0x5f, 0x91, 0xbd, 0x56, 0xdd, 0xd0, 0x41, 0x0f, 0xa5, 0xb7, 0xca, + 0xf4, 0x7f, 0x56, 0x5a, 0xb3, 0xa6, 0x63, 0x86, 0x9b, 0x50, 0x33, 0x9a, 0x29, 0xa6, 0x5a, 0x0f, + 0x76, 0x82, 0x4c, 0xb5, 0x4e, 0xe9, 0xc0, 0xe0, 0x1c, 0xba, 0x04, 0x15, 0x5e, 0x39, 0x8b, 0x1f, + 0x5d, 0x8e, 0x67, 0x0b, 0x64, 0xa3, 0x30, 0x5a, 0x39, 0x31, 0x7d, 0x32, 0x66, 0xf4, 0x6d, 0xa8, + 0x5e, 0xa2, 0x4c, 0x65, 0x97, 0x63, 0xd9, 0xf4, 0x34, 0x45, 0x53, 0xe9, 0x14, 0x87, 0x73, 0xe8, + 0x0d, 0x51, 0xc4, 0xa7, 0x83, 0x2b, 0x72, 0x66, 0x04, 0xd1, 0xf8, 0x5c, 0xab, 0xb3, 0x09, 0x62, + 0xce, 0xaf, 0xa7, 0x38, 0xab, 0x3c, 0xec, 0xcc, 0xb8, 0xb0, 0x31, 0x67, 0xe7, 0x2e, 0x7f, 0xc9, + 0xc0, 0xb9, 0xb3, 0x6f, 0xea, 0x7f, 0x25, 0x6c, 0xb8, 0xcc, 0x45, 0xaf, 0xc0, 0xa2, 0xd0, 0x65, + 0xfc, 0xb7, 0x85, 0x94, 0xcf, 0x1f, 0xf8, 0x8f, 0x44, 0xca, 0xe7, 0x0f, 0xfe, 0x57, 0x02, 0xe7, + 0x3a, 0x6f, 0x7e, 0xf0, 0x71, 0x2b, 0xf7, 0xe1, 0xc7, 0xad, 0xdc, 0xa7, 0x1f, 0xb7, 0xac, 0xef, + 0xef, 0xb5, 0xac, 0x5f, 0xef, 0xb5, 0xac, 0xf7, 0xf7, 0x5a, 0xd6, 0x07, 0x7b, 0x2d, 0xeb, 0xef, + 0x7b, 0x2d, 0xeb, 0x1f, 0x7b, 0xad, 0xdc, 0xa7, 0x7b, 0x2d, 0xeb, 0xdd, 0x4f, 0x5a, 0xb9, 0x0f, + 0x3e, 0x69, 0xe5, 0x3e, 0xfc, 0xa4, 0x95, 0xfb, 0xee, 0xa3, 0x77, 0x7f, 0xb0, 0xca, 0xb0, 0x58, + 0x12, 0x5f, 0x4f, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x55, 0xf6, 0x50, 0x3b, 0x23, 0x00, + 0x00, } func (x Direction) String() string { @@ -4396,6 +4405,9 @@ func (this *LabelNamesForMetricNameRequest) Equal(that interface{}) bool { if !this.Through.Equal(that1.Through) { return false } + if this.Matchers != that1.Matchers { + return false + } return true } func (this *LineFilter) Equal(that interface{}) bool { @@ -5506,11 +5518,12 @@ func (this *LabelNamesForMetricNameRequest) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 7) + s := make([]string, 0, 8) s = append(s, "&logproto.LabelNamesForMetricNameRequest{") s = append(s, "MetricName: "+fmt.Sprintf("%#v", this.MetricName)+",\n") s = append(s, "From: "+fmt.Sprintf("%#v", this.From)+",\n") s = append(s, "Through: "+fmt.Sprintf("%#v", this.Through)+",\n") + s = append(s, "Matchers: "+fmt.Sprintf("%#v", this.Matchers)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -7903,6 +7916,13 @@ func (m *LabelNamesForMetricNameRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.Matchers) > 0 { + i -= len(m.Matchers) + copy(dAtA[i:], m.Matchers) + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Matchers))) + i-- + dAtA[i] = 0x22 + } if m.Through != 0 { i = encodeVarintLogproto(dAtA, i, uint64(m.Through)) i-- @@ -9525,6 +9545,10 @@ func (m *LabelNamesForMetricNameRequest) Size() (n int) { if m.Through != 0 { n += 1 + sovLogproto(uint64(m.Through)) } + l = len(m.Matchers) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } return n } @@ -10395,6 +10419,7 @@ func (this *LabelNamesForMetricNameRequest) String() string { `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, `From:` + fmt.Sprintf("%v", this.From) + `,`, `Through:` + fmt.Sprintf("%v", this.Through) + `,`, + `Matchers:` + fmt.Sprintf("%v", this.Matchers) + `,`, `}`, }, "") return s @@ -15166,6 +15191,38 @@ func (m *LabelNamesForMetricNameRequest) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Matchers", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Matchers = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogproto(dAtA[iNdEx:]) diff --git a/pkg/logproto/logproto.proto b/pkg/logproto/logproto.proto index 189cec5d948c..949861ee8ae4 100644 --- a/pkg/logproto/logproto.proto +++ b/pkg/logproto/logproto.proto @@ -320,6 +320,7 @@ message LabelNamesForMetricNameRequest { (gogoproto.customtype) = "github.com/prometheus/common/model.Time", (gogoproto.nullable) = false ]; + string matchers = 4; } // TODO(owen-d): fix. This will break rollouts as soon as the internal repr is changed. diff --git a/pkg/logproto/pattern.pb.go b/pkg/logproto/pattern.pb.go index a666a3285012..eb3cfce9e03e 100644 --- a/pkg/logproto/pattern.pb.go +++ b/pkg/logproto/pattern.pb.go @@ -11,6 +11,7 @@ import ( _ "github.com/gogo/protobuf/types" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" push "github.com/grafana/loki/pkg/push" + stats "github.com/grafana/loki/v3/pkg/logqlmodel/stats" github_com_prometheus_common_model "github.com/prometheus/common/model" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -240,48 +241,176 @@ func (m *PatternSample) GetValue() int64 { return 0 } +type QuerySamplesRequest struct { + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Start time.Time `protobuf:"bytes,2,opt,name=start,proto3,stdtime" json:"start"` + End time.Time `protobuf:"bytes,3,opt,name=end,proto3,stdtime" json:"end"` + Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` +} + +func (m *QuerySamplesRequest) Reset() { *m = QuerySamplesRequest{} } +func (*QuerySamplesRequest) ProtoMessage() {} +func (*QuerySamplesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf4192acc66a4ea, []int{4} +} +func (m *QuerySamplesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySamplesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySamplesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySamplesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySamplesRequest.Merge(m, src) +} +func (m *QuerySamplesRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySamplesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySamplesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySamplesRequest proto.InternalMessageInfo + +func (m *QuerySamplesRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (m *QuerySamplesRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +func (m *QuerySamplesRequest) GetEnd() time.Time { + if m != nil { + return m.End + } + return time.Time{} +} + +func (m *QuerySamplesRequest) GetStep() int64 { + if m != nil { + return m.Step + } + return 0 +} + +type QuerySamplesResponse struct { + Series []Series `protobuf:"bytes,1,rep,name=series,proto3,customtype=Series" json:"series,omitempty"` + Stats stats.Ingester `protobuf:"bytes,2,opt,name=stats,proto3" json:"stats"` + Warnings []string `protobuf:"bytes,3,rep,name=warnings,proto3" json:"warnings,omitempty"` +} + +func (m *QuerySamplesResponse) Reset() { *m = QuerySamplesResponse{} } +func (*QuerySamplesResponse) ProtoMessage() {} +func (*QuerySamplesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf4192acc66a4ea, []int{5} +} +func (m *QuerySamplesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySamplesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySamplesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySamplesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySamplesResponse.Merge(m, src) +} +func (m *QuerySamplesResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySamplesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySamplesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySamplesResponse proto.InternalMessageInfo + +func (m *QuerySamplesResponse) GetStats() stats.Ingester { + if m != nil { + return m.Stats + } + return stats.Ingester{} +} + +func (m *QuerySamplesResponse) GetWarnings() []string { + if m != nil { + return m.Warnings + } + return nil +} + func init() { proto.RegisterType((*QueryPatternsRequest)(nil), "logproto.QueryPatternsRequest") proto.RegisterType((*QueryPatternsResponse)(nil), "logproto.QueryPatternsResponse") proto.RegisterType((*PatternSeries)(nil), "logproto.PatternSeries") proto.RegisterType((*PatternSample)(nil), "logproto.PatternSample") + proto.RegisterType((*QuerySamplesRequest)(nil), "logproto.QuerySamplesRequest") + proto.RegisterType((*QuerySamplesResponse)(nil), "logproto.QuerySamplesResponse") } func init() { proto.RegisterFile("pkg/logproto/pattern.proto", fileDescriptor_aaf4192acc66a4ea) } var fileDescriptor_aaf4192acc66a4ea = []byte{ - // 483 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xb1, 0x6e, 0xd3, 0x40, - 0x18, 0xf6, 0xd5, 0x49, 0xd3, 0x5e, 0xc5, 0x72, 0xa4, 0x60, 0x19, 0xe9, 0x1c, 0x79, 0x21, 0x93, - 0x0f, 0x52, 0x09, 0x24, 0xc6, 0x4c, 0x0c, 0x20, 0x15, 0xc3, 0x84, 0x60, 0x70, 0xda, 0xbf, 0xb6, - 0x55, 0xdb, 0xe7, 0xfa, 0xee, 0x2a, 0xb1, 0xf1, 0x08, 0x79, 0x0c, 0x1e, 0x80, 0x87, 0xe8, 0x98, - 0xb1, 0x62, 0x28, 0xc4, 0x59, 0x18, 0xfb, 0x08, 0xc8, 0x77, 0x76, 0x93, 0x56, 0x74, 0xe8, 0x92, - 0xdc, 0xff, 0x7f, 0xdf, 0xff, 0xf9, 0xbb, 0xff, 0x3b, 0xec, 0x96, 0xa7, 0x31, 0xcb, 0x78, 0x5c, - 0x56, 0x5c, 0x72, 0x56, 0x46, 0x52, 0x42, 0x55, 0x04, 0xba, 0x22, 0x3b, 0x5d, 0xdf, 0x1d, 0xc6, - 0x3c, 0xe6, 0x86, 0xd2, 0x9c, 0x0c, 0xee, 0x7a, 0x31, 0xe7, 0x71, 0x06, 0x4c, 0x57, 0x33, 0x75, - 0xc2, 0x64, 0x9a, 0x83, 0x90, 0x51, 0x5e, 0xb6, 0x84, 0x67, 0xb7, 0xc4, 0xbb, 0x43, 0x0b, 0x3e, - 0x6e, 0xc0, 0x52, 0x89, 0x44, 0xff, 0x98, 0xa6, 0xff, 0x13, 0xe1, 0xe1, 0x07, 0x05, 0xd5, 0xb7, - 0x43, 0xe3, 0x44, 0x84, 0x70, 0xa6, 0x40, 0x48, 0x32, 0xc4, 0xfd, 0xb3, 0xa6, 0xef, 0xa0, 0x11, - 0x1a, 0xef, 0x86, 0xa6, 0x20, 0x6f, 0x70, 0x5f, 0xc8, 0xa8, 0x92, 0xce, 0xd6, 0x08, 0x8d, 0xf7, - 0x26, 0x6e, 0x60, 0x1c, 0x05, 0x9d, 0xa3, 0xe0, 0x53, 0xe7, 0x68, 0xba, 0x73, 0x71, 0xe5, 0x59, - 0xf3, 0xdf, 0x1e, 0x0a, 0xcd, 0x08, 0x79, 0x85, 0x6d, 0x28, 0x8e, 0x1d, 0xfb, 0x01, 0x93, 0xcd, - 0x00, 0x21, 0xb8, 0x27, 0x24, 0x94, 0x4e, 0x6f, 0x84, 0xc6, 0x76, 0xa8, 0xcf, 0xfe, 0x5b, 0xbc, - 0x7f, 0xc7, 0xb5, 0x28, 0x79, 0x21, 0x80, 0x30, 0xbc, 0x2d, 0xa0, 0x4a, 0x41, 0x38, 0x68, 0x64, - 0x8f, 0xf7, 0x26, 0x4f, 0x83, 0x9b, 0x2d, 0xb4, 0xdc, 0x8f, 0x1a, 0x0e, 0x5b, 0x9a, 0xff, 0x05, - 0x3f, 0xba, 0x05, 0x10, 0x07, 0x0f, 0xda, 0x54, 0xda, 0xab, 0x77, 0x25, 0x79, 0x89, 0x07, 0x22, - 0xca, 0xcb, 0x0c, 0x84, 0xb3, 0x75, 0x9f, 0xb8, 0xc6, 0xc3, 0x8e, 0xe7, 0xcb, 0xb5, 0xba, 0xee, - 0x90, 0xf7, 0x78, 0xf7, 0x26, 0x34, 0xad, 0x6f, 0x4f, 0x59, 0x73, 0xdd, 0x5f, 0x57, 0xde, 0xf3, - 0x38, 0x95, 0x89, 0x9a, 0x05, 0x47, 0x3c, 0x6f, 0x12, 0xce, 0x41, 0x26, 0xa0, 0x04, 0x3b, 0xe2, - 0x79, 0xce, 0x0b, 0x96, 0xf3, 0x63, 0xc8, 0xf4, 0x92, 0xc2, 0xb5, 0x42, 0x93, 0xd2, 0x79, 0x94, - 0x29, 0xd0, 0x79, 0xd8, 0xa1, 0x29, 0x26, 0x73, 0x84, 0x07, 0xed, 0x67, 0xc9, 0x6b, 0xdc, 0x3b, - 0x54, 0x22, 0x21, 0xfb, 0x1b, 0x5e, 0x95, 0x48, 0xda, 0x98, 0xdd, 0x27, 0x77, 0xdb, 0x66, 0x8f, - 0xbe, 0x45, 0xde, 0xe1, 0xbe, 0x5e, 0x31, 0xa1, 0x6b, 0xca, 0xff, 0x5e, 0x8a, 0xeb, 0xdd, 0x8b, - 0x77, 0x5a, 0x2f, 0xd0, 0xf4, 0xeb, 0x62, 0x49, 0xad, 0xcb, 0x25, 0xb5, 0xae, 0x97, 0x14, 0x7d, - 0xaf, 0x29, 0xfa, 0x51, 0x53, 0x74, 0x51, 0x53, 0xb4, 0xa8, 0x29, 0xfa, 0x53, 0x53, 0xf4, 0xb7, - 0xa6, 0xd6, 0x75, 0x4d, 0xd1, 0x7c, 0x45, 0xad, 0xc5, 0x8a, 0x5a, 0x97, 0x2b, 0x6a, 0x7d, 0xde, - 0x5c, 0x49, 0x5c, 0x45, 0x27, 0x51, 0x11, 0xb1, 0x8c, 0x9f, 0xa6, 0xec, 0xfc, 0x80, 0x6d, 0x3e, - 0xf5, 0xd9, 0xb6, 0xfe, 0x3b, 0xf8, 0x17, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x4f, 0x5c, 0x50, 0x5e, - 0x03, 0x00, 0x00, + // 597 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xbb, 0x8e, 0xd3, 0x40, + 0x14, 0xf5, 0xac, 0xb3, 0xaf, 0x59, 0xf1, 0xd0, 0xec, 0x2e, 0x58, 0x46, 0x8c, 0x2d, 0x37, 0x44, + 0x42, 0xf2, 0x40, 0x56, 0x02, 0x44, 0x99, 0x0a, 0x24, 0x90, 0x82, 0xa1, 0x42, 0x50, 0x38, 0xbb, + 0xb3, 0x4e, 0xb4, 0xb6, 0xc7, 0xf1, 0x8c, 0x17, 0xd1, 0xf1, 0x09, 0xdb, 0xf2, 0x07, 0xf4, 0xf0, + 0x11, 0x29, 0x53, 0xae, 0xb6, 0x08, 0xc4, 0x69, 0x28, 0xf7, 0x13, 0x90, 0x67, 0xc6, 0x79, 0x89, + 0x14, 0x94, 0x34, 0xce, 0xdc, 0x7b, 0xce, 0xbd, 0x39, 0xf7, 0x9e, 0xb1, 0xa1, 0x9d, 0x9d, 0x45, + 0x24, 0x66, 0x51, 0x96, 0x33, 0xc1, 0x48, 0x16, 0x0a, 0x41, 0xf3, 0xd4, 0x97, 0x11, 0xda, 0xa9, + 0xf3, 0xf6, 0x41, 0xc4, 0x22, 0xa6, 0x28, 0xd5, 0x49, 0xe1, 0xb6, 0x13, 0x31, 0x16, 0xc5, 0x94, + 0xc8, 0xa8, 0x5b, 0x9c, 0x12, 0xd1, 0x4f, 0x28, 0x17, 0x61, 0x92, 0x69, 0xc2, 0xbd, 0xa5, 0xe6, + 0xf5, 0x41, 0x83, 0xae, 0x06, 0x07, 0x71, 0xc2, 0x4e, 0x68, 0x4c, 0xb8, 0x08, 0x05, 0x57, 0x4f, + 0xcd, 0xd8, 0xaf, 0x18, 0x59, 0xc1, 0x7b, 0xf2, 0xa1, 0x92, 0xde, 0x0f, 0x00, 0x0f, 0xde, 0x14, + 0x34, 0xff, 0xdc, 0x51, 0x5a, 0x79, 0x40, 0x07, 0x05, 0xe5, 0x02, 0x1d, 0xc0, 0xcd, 0x41, 0x95, + 0xb7, 0x80, 0x0b, 0x9a, 0xbb, 0x81, 0x0a, 0xd0, 0x73, 0xb8, 0xc9, 0x45, 0x98, 0x0b, 0x6b, 0xc3, + 0x05, 0xcd, 0xbd, 0x96, 0xed, 0x2b, 0xcd, 0x7e, 0xad, 0xd9, 0x7f, 0x57, 0x6b, 0x6e, 0xef, 0x0c, + 0xc7, 0x8e, 0x71, 0xf1, 0xd3, 0x01, 0x81, 0x2a, 0x41, 0x4f, 0xa0, 0x49, 0xd3, 0x13, 0xcb, 0xfc, + 0x87, 0xca, 0xaa, 0x00, 0x21, 0xd8, 0xe0, 0x82, 0x66, 0x56, 0xc3, 0x05, 0x4d, 0x33, 0x90, 0x67, + 0xef, 0x05, 0x3c, 0x5c, 0x51, 0xcd, 0x33, 0x96, 0x72, 0x8a, 0x08, 0xdc, 0xe2, 0x34, 0xef, 0x53, + 0x6e, 0x01, 0xd7, 0x6c, 0xee, 0xb5, 0xee, 0xfa, 0xb3, 0x3d, 0x69, 0xee, 0x5b, 0x09, 0x07, 0x9a, + 0xe6, 0x7d, 0x80, 0x37, 0x96, 0x00, 0x64, 0xc1, 0x6d, 0xed, 0x9b, 0x1e, 0xbd, 0x0e, 0xd1, 0x63, + 0xb8, 0xcd, 0xc3, 0x24, 0x8b, 0x29, 0xb7, 0x36, 0xd6, 0x35, 0x97, 0x78, 0x50, 0xf3, 0x3c, 0x31, + 0xef, 0x2e, 0x33, 0xe8, 0x35, 0xdc, 0x9d, 0xd9, 0x2a, 0xfb, 0x9b, 0x6d, 0x52, 0x8d, 0x7b, 0x35, + 0x76, 0x1e, 0x44, 0x7d, 0xd1, 0x2b, 0xba, 0xfe, 0x31, 0x4b, 0xaa, 0x3b, 0x90, 0x50, 0xd1, 0xa3, + 0x05, 0x27, 0xc7, 0x2c, 0x49, 0x58, 0x4a, 0xa4, 0xab, 0x72, 0x49, 0xc1, 0xbc, 0x43, 0xe5, 0xd2, + 0x79, 0x18, 0x17, 0x54, 0xfa, 0x61, 0x06, 0x2a, 0xf0, 0xbe, 0x03, 0xb8, 0x2f, 0xd7, 0xa3, 0xfe, + 0xf4, 0x3f, 0xf1, 0xf4, 0x6b, 0x7d, 0x15, 0x67, 0xaa, 0xb5, 0xa7, 0xcf, 0x56, 0x3c, 0xbd, 0x3d, + 0x5f, 0xbb, 0xf2, 0xac, 0x7d, 0x73, 0x38, 0x76, 0xc0, 0xd5, 0xd8, 0xd9, 0x5a, 0x36, 0x17, 0x3d, + 0x94, 0xa3, 0x09, 0xae, 0x47, 0xbb, 0xe5, 0xab, 0xf7, 0xe1, 0x65, 0x1a, 0x51, 0x2e, 0x68, 0xde, + 0x6e, 0x54, 0xaa, 0x02, 0xc5, 0x41, 0x36, 0xdc, 0xf9, 0x14, 0xe6, 0x69, 0x3f, 0x8d, 0xb8, 0x65, + 0xba, 0x66, 0x73, 0x37, 0x98, 0xc5, 0xad, 0x12, 0xc0, 0x6d, 0x6d, 0x24, 0x7a, 0x0a, 0x1b, 0x9d, + 0x82, 0xf7, 0xd0, 0xe1, 0x82, 0xfb, 0x05, 0xef, 0xe9, 0x25, 0xdb, 0x77, 0x56, 0xd3, 0x6a, 0x0a, + 0xcf, 0x40, 0xaf, 0xe0, 0xa6, 0x9c, 0x0f, 0xe1, 0x39, 0xe5, 0x6f, 0xef, 0x9e, 0xed, 0xac, 0xc5, + 0xeb, 0x5e, 0x8f, 0x00, 0xea, 0xc0, 0xbd, 0x85, 0x6d, 0xa1, 0xfb, 0x2b, 0x35, 0xcb, 0xd6, 0xdb, + 0x78, 0x1d, 0x3c, 0xef, 0xd8, 0xfe, 0x38, 0x9a, 0x60, 0xe3, 0x72, 0x82, 0x8d, 0xeb, 0x09, 0x06, + 0x5f, 0x4a, 0x0c, 0xbe, 0x95, 0x18, 0x0c, 0x4b, 0x0c, 0x46, 0x25, 0x06, 0xbf, 0x4a, 0x0c, 0x7e, + 0x97, 0xd8, 0xb8, 0x2e, 0x31, 0xb8, 0x98, 0x62, 0x63, 0x34, 0xc5, 0xc6, 0xe5, 0x14, 0x1b, 0xef, + 0x17, 0xaf, 0x6d, 0x94, 0x87, 0xa7, 0x61, 0x1a, 0x92, 0x98, 0x9d, 0xf5, 0xc9, 0xf9, 0x11, 0x59, + 0xfc, 0x60, 0x75, 0xb7, 0xe4, 0xcf, 0xd1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xa2, 0x72, + 0x12, 0x24, 0x05, 0x00, 0x00, } func (this *QueryPatternsRequest) Equal(that interface{}) bool { @@ -405,6 +534,79 @@ func (this *PatternSample) Equal(that interface{}) bool { } return true } +func (this *QuerySamplesRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QuerySamplesRequest) + if !ok { + that2, ok := that.(QuerySamplesRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Query != that1.Query { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + if !this.End.Equal(that1.End) { + return false + } + if this.Step != that1.Step { + return false + } + return true +} +func (this *QuerySamplesResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QuerySamplesResponse) + if !ok { + that2, ok := that.(QuerySamplesResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Series) != len(that1.Series) { + return false + } + for i := range this.Series { + if !this.Series[i].Equal(that1.Series[i]) { + return false + } + } + if !this.Stats.Equal(&that1.Stats) { + return false + } + if len(this.Warnings) != len(that1.Warnings) { + return false + } + for i := range this.Warnings { + if this.Warnings[i] != that1.Warnings[i] { + return false + } + } + return true +} func (this *QueryPatternsRequest) GoString() string { if this == nil { return "nil" @@ -454,6 +656,31 @@ func (this *PatternSample) GoString() string { s = append(s, "}") return strings.Join(s, "") } +func (this *QuerySamplesRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&logproto.QuerySamplesRequest{") + s = append(s, "Query: "+fmt.Sprintf("%#v", this.Query)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "Step: "+fmt.Sprintf("%#v", this.Step)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *QuerySamplesResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&logproto.QuerySamplesResponse{") + s = append(s, "Series: "+fmt.Sprintf("%#v", this.Series)+",\n") + s = append(s, "Stats: "+strings.Replace(this.Stats.GoString(), `&`, ``, 1)+",\n") + s = append(s, "Warnings: "+fmt.Sprintf("%#v", this.Warnings)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func valueToGoStringPattern(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -477,6 +704,7 @@ const _ = grpc.SupportPackageIsVersion4 type PatternClient interface { Push(ctx context.Context, in *push.PushRequest, opts ...grpc.CallOption) (*push.PushResponse, error) Query(ctx context.Context, in *QueryPatternsRequest, opts ...grpc.CallOption) (Pattern_QueryClient, error) + QuerySample(ctx context.Context, in *QuerySamplesRequest, opts ...grpc.CallOption) (Pattern_QuerySampleClient, error) } type patternClient struct { @@ -528,10 +756,43 @@ func (x *patternQueryClient) Recv() (*QueryPatternsResponse, error) { return m, nil } +func (c *patternClient) QuerySample(ctx context.Context, in *QuerySamplesRequest, opts ...grpc.CallOption) (Pattern_QuerySampleClient, error) { + stream, err := c.cc.NewStream(ctx, &_Pattern_serviceDesc.Streams[1], "/logproto.Pattern/QuerySample", opts...) + if err != nil { + return nil, err + } + x := &patternQuerySampleClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Pattern_QuerySampleClient interface { + Recv() (*QuerySamplesResponse, error) + grpc.ClientStream +} + +type patternQuerySampleClient struct { + grpc.ClientStream +} + +func (x *patternQuerySampleClient) Recv() (*QuerySamplesResponse, error) { + m := new(QuerySamplesResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // PatternServer is the server API for Pattern service. type PatternServer interface { Push(context.Context, *push.PushRequest) (*push.PushResponse, error) Query(*QueryPatternsRequest, Pattern_QueryServer) error + QuerySample(*QuerySamplesRequest, Pattern_QuerySampleServer) error } // UnimplementedPatternServer can be embedded to have forward compatible implementations. @@ -544,6 +805,9 @@ func (*UnimplementedPatternServer) Push(ctx context.Context, req *push.PushReque func (*UnimplementedPatternServer) Query(req *QueryPatternsRequest, srv Pattern_QueryServer) error { return status.Errorf(codes.Unimplemented, "method Query not implemented") } +func (*UnimplementedPatternServer) QuerySample(req *QuerySamplesRequest, srv Pattern_QuerySampleServer) error { + return status.Errorf(codes.Unimplemented, "method QuerySample not implemented") +} func RegisterPatternServer(s *grpc.Server, srv PatternServer) { s.RegisterService(&_Pattern_serviceDesc, srv) @@ -588,6 +852,27 @@ func (x *patternQueryServer) Send(m *QueryPatternsResponse) error { return x.ServerStream.SendMsg(m) } +func _Pattern_QuerySample_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(QuerySamplesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(PatternServer).QuerySample(m, &patternQuerySampleServer{stream}) +} + +type Pattern_QuerySampleServer interface { + Send(*QuerySamplesResponse) error + grpc.ServerStream +} + +type patternQuerySampleServer struct { + grpc.ServerStream +} + +func (x *patternQuerySampleServer) Send(m *QuerySamplesResponse) error { + return x.ServerStream.SendMsg(m) +} + var _Pattern_serviceDesc = grpc.ServiceDesc{ ServiceName: "logproto.Pattern", HandlerType: (*PatternServer)(nil), @@ -603,6 +888,11 @@ var _Pattern_serviceDesc = grpc.ServiceDesc{ Handler: _Pattern_Query_Handler, ServerStreams: true, }, + { + StreamName: "QuerySample", + Handler: _Pattern_QuerySample_Handler, + ServerStreams: true, + }, }, Metadata: "pkg/logproto/pattern.proto", } @@ -772,51 +1062,158 @@ func (m *PatternSample) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintPattern(dAtA []byte, offset int, v uint64) int { - offset -= sovPattern(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *QuerySamplesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *QueryPatternsRequest) Size() (n int) { - if m == nil { - return 0 - } + +func (m *QuerySamplesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySamplesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Query) - if l > 0 { - n += 1 + l + sovPattern(uint64(l)) - } - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) - n += 1 + l + sovPattern(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) - n += 1 + l + sovPattern(uint64(l)) if m.Step != 0 { - n += 1 + sovPattern(uint64(m.Step)) + i = encodeVarintPattern(dAtA, i, uint64(m.Step)) + i-- + dAtA[i] = 0x20 } - return n -} - -func (m *QueryPatternsResponse) Size() (n int) { - if m == nil { - return 0 + n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.End, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.End):]) + if err3 != nil { + return 0, err3 } - var l int - _ = l - if len(m.Series) > 0 { - for _, e := range m.Series { - l = e.Size() - n += 1 + l + sovPattern(uint64(l)) - } + i -= n3 + i = encodeVarintPattern(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x1a + n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + if err4 != nil { + return 0, err4 } - return n -} + i -= n4 + i = encodeVarintPattern(dAtA, i, uint64(n4)) + i-- + dAtA[i] = 0x12 + if len(m.Query) > 0 { + i -= len(m.Query) + copy(dAtA[i:], m.Query) + i = encodeVarintPattern(dAtA, i, uint64(len(m.Query))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySamplesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySamplesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySamplesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Warnings) > 0 { + for iNdEx := len(m.Warnings) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Warnings[iNdEx]) + copy(dAtA[i:], m.Warnings[iNdEx]) + i = encodeVarintPattern(dAtA, i, uint64(len(m.Warnings[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + { + size, err := m.Stats.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPattern(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Series) > 0 { + for iNdEx := len(m.Series) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Series[iNdEx].Size() + i -= size + if _, err := m.Series[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPattern(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintPattern(dAtA []byte, offset int, v uint64) int { + offset -= sovPattern(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryPatternsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Query) + if l > 0 { + n += 1 + l + sovPattern(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovPattern(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovPattern(uint64(l)) + if m.Step != 0 { + n += 1 + sovPattern(uint64(m.Step)) + } + return n +} + +func (m *QueryPatternsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Series) > 0 { + for _, e := range m.Series { + l = e.Size() + n += 1 + l + sovPattern(uint64(l)) + } + } + return n +} func (m *PatternSeries) Size() (n int) { if m == nil { @@ -852,6 +1249,49 @@ func (m *PatternSample) Size() (n int) { return n } +func (m *QuerySamplesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Query) + if l > 0 { + n += 1 + l + sovPattern(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovPattern(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovPattern(uint64(l)) + if m.Step != 0 { + n += 1 + sovPattern(uint64(m.Step)) + } + return n +} + +func (m *QuerySamplesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Series) > 0 { + for _, e := range m.Series { + l = e.Size() + n += 1 + l + sovPattern(uint64(l)) + } + } + l = m.Stats.Size() + n += 1 + l + sovPattern(uint64(l)) + if len(m.Warnings) > 0 { + for _, s := range m.Warnings { + l = len(s) + n += 1 + l + sovPattern(uint64(l)) + } + } + return n +} + func sovPattern(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -913,6 +1353,31 @@ func (this *PatternSample) String() string { }, "") return s } +func (this *QuerySamplesRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QuerySamplesRequest{`, + `Query:` + fmt.Sprintf("%v", this.Query) + `,`, + `Start:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Start), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `End:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.End), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Step:` + fmt.Sprintf("%v", this.Step) + `,`, + `}`, + }, "") + return s +} +func (this *QuerySamplesResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QuerySamplesResponse{`, + `Series:` + fmt.Sprintf("%v", this.Series) + `,`, + `Stats:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Stats), "Ingester", "stats.Ingester", 1), `&`, ``, 1) + `,`, + `Warnings:` + fmt.Sprintf("%v", this.Warnings) + `,`, + `}`, + }, "") + return s +} func valueToStringPattern(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -1388,6 +1853,328 @@ func (m *PatternSample) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySamplesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySamplesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySamplesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Step", wireType) + } + m.Step = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Step |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPattern(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPattern + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPattern + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySamplesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySamplesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySamplesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Series", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Series = append(m.Series, Series{}) + if err := m.Series[len(m.Series)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Stats.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Warnings", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPattern + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPattern + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPattern + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Warnings = append(m.Warnings, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPattern(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPattern + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPattern + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPattern(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pkg/logproto/pattern.proto b/pkg/logproto/pattern.proto index e92a201b3a8b..c3e4caaffc5c 100644 --- a/pkg/logproto/pattern.proto +++ b/pkg/logproto/pattern.proto @@ -5,6 +5,7 @@ package logproto; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; import "pkg/logproto/logproto.proto"; +import "pkg/logqlmodel/stats/stats.proto"; import "pkg/push/push.proto"; option go_package = "github.com/grafana/loki/v3/pkg/logproto"; @@ -12,6 +13,7 @@ option go_package = "github.com/grafana/loki/v3/pkg/logproto"; service Pattern { rpc Push(PushRequest) returns (PushResponse) {} rpc Query(QueryPatternsRequest) returns (stream QueryPatternsResponse) {} + rpc QuerySample(QuerySamplesRequest) returns (stream QuerySamplesResponse) {} } message QueryPatternsRequest { @@ -43,3 +45,25 @@ message PatternSample { ]; int64 value = 2; } + +message QuerySamplesRequest { + string query = 1; + google.protobuf.Timestamp start = 2 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; + google.protobuf.Timestamp end = 3 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; + int64 step = 4; +} + +message QuerySamplesResponse { + repeated Series series = 1 [ + (gogoproto.customtype) = "Series", + (gogoproto.nullable) = true + ]; + stats.Ingester stats = 2 [(gogoproto.nullable) = false]; + repeated string warnings = 3; +} diff --git a/pkg/logql/evaluator.go b/pkg/logql/evaluator.go index e50d8739c30a..b44b134c8bdd 100644 --- a/pkg/logql/evaluator.go +++ b/pkg/logql/evaluator.go @@ -410,6 +410,20 @@ type VectorAggEvaluator struct { lb *labels.Builder } +func NewVectorAggEvaluator( + nextEvaluator StepEvaluator, + expr *syntax.VectorAggregationExpr, + buf []byte, + lb *labels.Builder, +) *VectorAggEvaluator { + return &VectorAggEvaluator{ + nextEvaluator: nextEvaluator, + expr: expr, + buf: buf, + lb: lb, + } +} + func (e *VectorAggEvaluator) Next() (bool, int64, StepResult) { next, ts, r := e.nextEvaluator.Next() @@ -684,9 +698,7 @@ func newRangeAggEvaluator( return nil, err } - return &RangeVectorEvaluator{ - iter: iter, - }, nil + return NewRangeVectorEvaluator(iter), nil } } @@ -696,6 +708,12 @@ type RangeVectorEvaluator struct { err error } +func NewRangeVectorEvaluator(iter RangeVectorIterator) *RangeVectorEvaluator { + return &RangeVectorEvaluator{ + iter: iter, + } +} + func (r *RangeVectorEvaluator) Next() (bool, int64, StepResult) { next := r.iter.Next() if !next { diff --git a/pkg/logql/range_vector.go b/pkg/logql/range_vector.go index 44a865157754..180a1bde27ca 100644 --- a/pkg/logql/range_vector.go +++ b/pkg/logql/range_vector.go @@ -75,21 +75,18 @@ func newRangeVectorIterator( if err != nil { return nil, err } - return &batchRangeVectorIterator{ - iter: it, - step: step, - end: end, - selRange: selRange, - metrics: map[string]labels.Labels{}, - window: map[string]*promql.Series{}, - agg: vectorAggregator, - current: start - step, // first loop iteration will set it to start - offset: offset, - }, nil -} - -//batch - + return NewBatchRangeVectorIterator( + it, + selRange, + step, + start, + end, + offset, + vectorAggregator, + ), nil +} + +// batch type batchRangeVectorIterator struct { iter iter.PeekingSampleIterator selRange, step, end, current, offset int64 @@ -99,6 +96,24 @@ type batchRangeVectorIterator struct { agg BatchRangeVectorAggregator } +func NewBatchRangeVectorIterator( + it iter.PeekingSampleIterator, + selRange, step, start, end, offset int64, + agg BatchRangeVectorAggregator, +) RangeVectorIterator { + return &batchRangeVectorIterator{ + iter: it, + selRange: selRange, + step: step, + end: end, + current: start - step, // first loop iteration will set it to start + offset: offset, + metrics: map[string]labels.Labels{}, + window: map[string]*promql.Series{}, + agg: agg, + } +} + func (r *batchRangeVectorIterator) Next() bool { // slides the range window to the next position r.current = r.current + r.step @@ -178,6 +193,7 @@ func (r *batchRangeVectorIterator) load(start, end int64) { series.Metric = metric r.window[lbs] = series } + // TODO(twhitney): Everywhere else, an FPoint.T is in milliseconds, but here it's in nanoseconds. p := promql.FPoint{ T: sample.Timestamp, F: sample.Value, diff --git a/pkg/loki/loki.go b/pkg/loki/loki.go index 9446b351aab8..ce826f0752d4 100644 --- a/pkg/loki/loki.go +++ b/pkg/loki/loki.go @@ -331,7 +331,7 @@ type Loki struct { distributor *distributor.Distributor Ingester ingester.Interface PatternIngester *pattern.Ingester - PatternRingClient *pattern.RingClient + PatternRingClient pattern.RingClient Querier querier.Querier cacheGenerationLoader queryrangebase.CacheGenNumberLoader querierAPI *querier.QuerierAPI diff --git a/pkg/loki/modules.go b/pkg/loki/modules.go index e73369aca2d7..27df97e8f90b 100644 --- a/pkg/loki/modules.go +++ b/pkg/loki/modules.go @@ -521,6 +521,7 @@ func (t *Loki) initQuerier() (services.Service, error) { router.Path("/loki/api/v1/index/volume").Methods("GET", "POST").Handler(volumeHTTPMiddleware.Wrap(httpHandler)) router.Path("/loki/api/v1/index/volume_range").Methods("GET", "POST").Handler(volumeRangeHTTPMiddleware.Wrap(httpHandler)) router.Path("/loki/api/v1/patterns").Methods("GET", "POST").Handler(httpHandler) + router.Path("/loki/api/v1/explore/query_range").Methods("GET", "POST").Handler(httpHandler) router.Path("/api/prom/query").Methods("GET", "POST").Handler( middleware.Merge( @@ -1105,6 +1106,7 @@ func (t *Loki) initQueryFrontend() (_ services.Service, err error) { t.Server.HTTP.Path("/loki/api/v1/label/{name}/values").Methods("GET", "POST").Handler(frontendHandler) t.Server.HTTP.Path("/loki/api/v1/series").Methods("GET", "POST").Handler(frontendHandler) t.Server.HTTP.Path("/loki/api/v1/patterns").Methods("GET", "POST").Handler(frontendHandler) + t.Server.HTTP.Path("/loki/api/v1/explore/query_range").Methods("GET", "POST").Handler(frontendHandler) t.Server.HTTP.Path("/loki/api/v1/detected_labels").Methods("GET", "POST").Handler(frontendHandler) t.Server.HTTP.Path("/loki/api/v1/detected_fields").Methods("GET", "POST").Handler(frontendHandler) t.Server.HTTP.Path("/loki/api/v1/index/stats").Methods("GET", "POST").Handler(frontendHandler) diff --git a/pkg/pattern/chunk/util.go b/pkg/pattern/chunk/util.go new file mode 100644 index 000000000000..8cbde3fb0474 --- /dev/null +++ b/pkg/pattern/chunk/util.go @@ -0,0 +1,14 @@ +package chunk + +import ( + "time" + + "github.com/prometheus/common/model" +) + +const ( + TimeResolution = model.Time(int64(time.Second*10) / 1e6) + MaxChunkTime = 1 * time.Hour +) + +func TruncateTimestamp(ts, step model.Time) model.Time { return ts - ts%step } diff --git a/pkg/pattern/drain/chunk.go b/pkg/pattern/drain/chunk.go index 133329946758..cf5192bf8b63 100644 --- a/pkg/pattern/drain/chunk.go +++ b/pkg/pattern/drain/chunk.go @@ -7,15 +7,12 @@ import ( "github.com/prometheus/common/model" "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/pattern/chunk" "github.com/grafana/loki/v3/pkg/pattern/iter" ) const ( - TimeResolution = model.Time(int64(time.Second*10) / 1e6) - defaultVolumeSize = 500 - - maxChunkTime = 1 * time.Hour ) type Chunks []Chunk @@ -25,7 +22,7 @@ type Chunk struct { } func newChunk(ts model.Time) Chunk { - maxSize := int(maxChunkTime.Nanoseconds()/TimeResolution.UnixNano()) + 1 + maxSize := int(chunk.MaxChunkTime.Nanoseconds()/chunk.TimeResolution.UnixNano()) + 1 v := Chunk{Samples: make([]logproto.PatternSample, 1, maxSize)} v.Samples[0] = logproto.PatternSample{ Timestamp: ts, @@ -39,7 +36,7 @@ func (c Chunk) spaceFor(ts model.Time) bool { return true } - return ts.Sub(c.Samples[0].Timestamp) < maxChunkTime + return ts.Sub(c.Samples[0].Timestamp) < chunk.MaxChunkTime } // ForRange returns samples with only the values @@ -71,12 +68,12 @@ func (c Chunk) ForRange(start, end, step model.Time) []logproto.PatternSample { return nil } - if step == TimeResolution { + if step == chunk.TimeResolution { return c.Samples[lo:hi] } // Re-scale samples into step-sized buckets - currentStep := truncateTimestamp(c.Samples[lo].Timestamp, step) + currentStep := chunk.TruncateTimestamp(c.Samples[lo].Timestamp, step) aggregatedSamples := make([]logproto.PatternSample, 0, ((c.Samples[hi-1].Timestamp-currentStep)/step)+1) aggregatedSamples = append(aggregatedSamples, logproto.PatternSample{ Timestamp: currentStep, @@ -84,7 +81,7 @@ func (c Chunk) ForRange(start, end, step model.Time) []logproto.PatternSample { }) for _, sample := range c.Samples[lo:hi] { if sample.Timestamp >= currentStep+step { - stepForSample := truncateTimestamp(sample.Timestamp, step) + stepForSample := chunk.TruncateTimestamp(sample.Timestamp, step) for i := currentStep + step; i <= stepForSample; i += step { aggregatedSamples = append(aggregatedSamples, logproto.PatternSample{ Timestamp: i, @@ -100,7 +97,7 @@ func (c Chunk) ForRange(start, end, step model.Time) []logproto.PatternSample { } func (c *Chunks) Add(ts model.Time) { - t := truncateTimestamp(ts, TimeResolution) + t := chunk.TruncateTimestamp(ts, chunk.TimeResolution) if len(*c) == 0 { *c = append(*c, newChunk(t)) @@ -205,5 +202,3 @@ func (c *Chunks) size() int { } return size } - -func truncateTimestamp(ts, step model.Time) model.Time { return ts - ts%step } diff --git a/pkg/pattern/drain/chunk_test.go b/pkg/pattern/drain/chunk_test.go index 17429da594e1..7f3cb4066b2c 100644 --- a/pkg/pattern/drain/chunk_test.go +++ b/pkg/pattern/drain/chunk_test.go @@ -9,31 +9,32 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/pattern/chunk" ) func TestAdd(t *testing.T) { cks := Chunks{} - cks.Add(TimeResolution + 1) - cks.Add(TimeResolution + 2) - cks.Add(2*TimeResolution + 1) + cks.Add(chunk.TimeResolution + 1) + cks.Add(chunk.TimeResolution + 2) + cks.Add(2*chunk.TimeResolution + 1) require.Equal(t, 1, len(cks)) require.Equal(t, 2, len(cks[0].Samples)) - cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) + TimeResolution + 1) + cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) + chunk.TimeResolution + 1) require.Equal(t, 2, len(cks)) require.Equal(t, 1, len(cks[1].Samples)) - cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) - TimeResolution) + cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) - chunk.TimeResolution) require.Equal(t, 2, len(cks)) require.Equalf(t, 1, len(cks[1].Samples), "Older samples should not be added if they arrive out of order") } func TestIterator(t *testing.T) { cks := Chunks{} - cks.Add(TimeResolution + 1) - cks.Add(TimeResolution + 2) - cks.Add(2*TimeResolution + 1) - cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) + TimeResolution + 1) + cks.Add(chunk.TimeResolution + 1) + cks.Add(chunk.TimeResolution + 2) + cks.Add(2*chunk.TimeResolution + 1) + cks.Add(model.TimeFromUnixNano(time.Hour.Nanoseconds()) + chunk.TimeResolution + 1) - it := cks.Iterator("test", model.Time(0), model.Time(time.Hour.Nanoseconds()), TimeResolution) + it := cks.Iterator("test", model.Time(0), model.Time(time.Hour.Nanoseconds()), chunk.TimeResolution) require.NotNil(t, it) var samples []logproto.PatternSample diff --git a/pkg/pattern/ingester.go b/pkg/pattern/ingester.go index 1cb91a1cda29..755ad668af6a 100644 --- a/pkg/pattern/ingester.go +++ b/pkg/pattern/ingester.go @@ -21,10 +21,14 @@ import ( ring_client "github.com/grafana/dskit/ring/client" "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql/syntax" "github.com/grafana/loki/v3/pkg/pattern/clientpool" - "github.com/grafana/loki/v3/pkg/pattern/iter" + "github.com/grafana/loki/v3/pkg/pattern/metric" "github.com/grafana/loki/v3/pkg/util" util_log "github.com/grafana/loki/v3/pkg/util/log" + + loki_iter "github.com/grafana/loki/v3/pkg/iter" + pattern_iter "github.com/grafana/loki/v3/pkg/pattern/iter" ) const readBatchSize = 1024 @@ -36,6 +40,7 @@ type Config struct { ConcurrentFlushes int `yaml:"concurrent_flushes"` FlushCheckPeriod time.Duration `yaml:"flush_check_period"` + MetricAggregation metric.AggregationConfig `yaml:"metric_aggregation,omitempty" doc:"description=Configures the metric aggregation and storage behavior of the pattern ingester."` // For testing. factory ring_client.PoolFactory `yaml:"-"` } @@ -44,6 +49,8 @@ type Config struct { func (cfg *Config) RegisterFlags(fs *flag.FlagSet) { cfg.LifecyclerConfig.RegisterFlagsWithPrefix("pattern-ingester.", fs, util_log.Logger) cfg.ClientConfig.RegisterFlags(fs) + cfg.MetricAggregation.RegisterFlagsWithPrefix(fs, "pattern-ingester.") + fs.BoolVar(&cfg.Enabled, "pattern-ingester.enabled", false, "Flag to enable or disable the usage of the pattern-ingester component.") fs.IntVar(&cfg.ConcurrentFlushes, "pattern-ingester.concurrent-flushes", 32, "How many flushes can happen concurrently from each stream.") fs.DurationVar(&cfg.FlushCheckPeriod, "pattern-ingester.flush-check-period", 30*time.Second, "How often should the ingester see if there are any blocks to flush. The first flush check is delayed by a random time up to 0.8x the flush check period. Additionally, there is +/- 1% jitter added to the interval.") @@ -246,9 +253,76 @@ func (i *Ingester) Query(req *logproto.QueryPatternsRequest, stream logproto.Pat return sendPatternSample(ctx, iterator, stream) } -func sendPatternSample(ctx context.Context, it iter.Iterator, stream logproto.Pattern_QueryServer) error { +func (i *Ingester) QuerySample( + req *logproto.QuerySamplesRequest, + stream logproto.Pattern_QuerySampleServer, +) error { + ctx := stream.Context() + instanceID, err := tenant.TenantID(ctx) + if err != nil { + return err + } + instance, err := i.GetOrCreateInstance(instanceID) + if err != nil { + return err + } + + expr, err := syntax.ParseSampleExpr(req.Query) + if err != nil { + return err + } + + iterator, err := instance.QuerySample(ctx, expr, req) // this is returning a first value of 0,0 + if err != nil { + return err + } + + // TODO(twhitney): query store + // if start, end, ok := buildStoreRequest(i.cfg, req.Start, req.End, time.Now()); ok { + // storeReq := logql.SelectSampleParams{SampleQueryRequest: &logproto.SampleQueryRequest{ + // Start: start, + // End: end, + // Selector: req.Selector, + // Shards: req.Shards, + // Deletes: req.Deletes, + // Plan: req.Plan, + // }} + // storeItr, err := i.store.SelectSamples(ctx, storeReq) + // if err != nil { + // util.LogErrorWithContext(ctx, "closing iterator", it.Close) + // return err + // } + + // it = iter.NewMergeSampleIterator(ctx, []iter.SampleIterator{it, storeItr}) + // } + + defer util.LogErrorWithContext(ctx, "closing iterator", iterator.Close) + return sendMetricSamples(ctx, iterator, stream) +} + +func sendPatternSample(ctx context.Context, it pattern_iter.Iterator, stream logproto.Pattern_QueryServer) error { + for ctx.Err() == nil { + batch, err := pattern_iter.ReadBatch(it, readBatchSize) + if err != nil { + return err + } + if err := stream.Send(batch); err != nil && err != context.Canceled { + return err + } + if len(batch.Series) == 0 { + return nil + } + } + return nil +} + +func sendMetricSamples( + ctx context.Context, + it loki_iter.SampleIterator, + stream logproto.Pattern_QuerySampleServer, +) error { for ctx.Err() == nil { - batch, err := iter.ReadBatch(it, readBatchSize) + batch, err := pattern_iter.ReadMetricsBatch(it, readBatchSize) if err != nil { return err } @@ -273,7 +347,7 @@ func (i *Ingester) GetOrCreateInstance(instanceID string) (*instance, error) { / inst, ok = i.instances[instanceID] if !ok { var err error - inst, err = newInstance(instanceID, i.logger, i.metrics) + inst, err = newInstance(instanceID, i.logger, i.metrics, i.cfg.MetricAggregation) if err != nil { return nil, err } diff --git a/pkg/pattern/ingester_querier.go b/pkg/pattern/ingester_querier.go index 13315b0a13f1..b021ce4d645c 100644 --- a/pkg/pattern/ingester_querier.go +++ b/pkg/pattern/ingester_querier.go @@ -2,6 +2,7 @@ package pattern import ( "context" + "errors" "math" "net/http" @@ -13,24 +14,28 @@ import ( "github.com/grafana/loki/v3/pkg/logproto" "github.com/grafana/loki/v3/pkg/logql/syntax" "github.com/grafana/loki/v3/pkg/pattern/drain" - "github.com/grafana/loki/v3/pkg/pattern/iter" + + loki_iter "github.com/grafana/loki/v3/pkg/iter" + pattern_iter "github.com/grafana/loki/v3/pkg/pattern/iter" ) // TODO(kolesnikovae): parametrise QueryPatternsRequest const minClusterSize = 30 +var ErrParseQuery = errors.New("only byte_over_time and count_over_time queries without filters are supported") + type IngesterQuerier struct { cfg Config logger log.Logger - ringClient *RingClient + ringClient RingClient registerer prometheus.Registerer } func NewIngesterQuerier( cfg Config, - ringClient *RingClient, + ringClient RingClient, metricsNamespace string, registerer prometheus.Registerer, logger log.Logger, @@ -54,22 +59,93 @@ func (q *IngesterQuerier) Patterns(ctx context.Context, req *logproto.QueryPatte if err != nil { return nil, err } - iterators := make([]iter.Iterator, len(resps)) + iterators := make([]pattern_iter.Iterator, len(resps)) for i := range resps { - iterators[i] = iter.NewQueryClientIterator(resps[i].response.(logproto.Pattern_QueryClient)) + iterators[i] = pattern_iter.NewQueryClientIterator(resps[i].response.(logproto.Pattern_QueryClient)) } // TODO(kolesnikovae): Incorporate with pruning - resp, err := iter.ReadBatch(iter.NewMerge(iterators...), math.MaxInt32) + resp, err := pattern_iter.ReadBatch(pattern_iter.NewMerge(iterators...), math.MaxInt32) if err != nil { return nil, err } return prunePatterns(resp, minClusterSize), nil } -func prunePatterns(resp *logproto.QueryPatternsResponse, minClusterSize int) *logproto.QueryPatternsResponse { +func (q *IngesterQuerier) Samples( + ctx context.Context, + req *logproto.QuerySamplesRequest, +) (*logproto.QuerySamplesResponse, error) { + expr, err := syntax.ParseSampleExpr(req.Query) + if err != nil { + return nil, err + } + + var selector syntax.LogSelectorExpr + switch e := expr.(type) { + case *syntax.VectorAggregationExpr: + selector, err = e.Selector() + case *syntax.RangeAggregationExpr: + selector, err = e.Selector() + default: + return nil, ErrParseQuery + } + + if err != nil { + return nil, err + } + + if selector == nil || selector.HasFilter() { + return nil, ErrParseQuery + } + + iterators, err := q.querySample(ctx, req) + if err != nil { + return nil, err + } + + // TODO(twhitney): what should batch size be here? + resp, err := pattern_iter.ReadMetricsBatch(loki_iter.NewSortSampleIterator(iterators), math.MaxInt32) + if err != nil { + return nil, err + } + return resp, nil +} + +func (q *IngesterQuerier) queryPattern(ctx context.Context, req *logproto.QueryPatternsRequest) ([]pattern_iter.Iterator, error) { + resps, err := q.forAllIngesters(ctx, func(_ context.Context, client logproto.PatternClient) (interface{}, error) { + return client.Query(ctx, req) + }) + if err != nil { + return nil, err + } + iterators := make([]pattern_iter.Iterator, len(resps)) + for i := range resps { + iterators[i] = pattern_iter.NewQueryClientIterator(resps[i].response.(logproto.Pattern_QueryClient)) + } + return iterators, nil +} + +func (q *IngesterQuerier) querySample(ctx context.Context, req *logproto.QuerySamplesRequest) ([]loki_iter.SampleIterator, error) { + resps, err := q.forAllIngesters(ctx, func(_ context.Context, client logproto.PatternClient) (interface{}, error) { + return client.QuerySample(ctx, req) + }) + if err != nil { + return nil, err + } + iterators := make([]loki_iter.SampleIterator, len(resps)) + for i := range resps { + iterators[i] = pattern_iter.NewQuerySamplesClientIterator(resps[i].response.(logproto.Pattern_QuerySampleClient)) + } + return iterators, nil +} + +func prunePatterns( + resp *logproto.QueryPatternsResponse, + minClusterSize int, +) *logproto.QueryPatternsResponse { d := drain.New(drain.DefaultConfig(), nil) for _, p := range resp.Series { - d.TrainPattern(p.Pattern, p.Samples) + d.TrainPattern(p.GetPattern(), p.Samples) } resp.Series = resp.Series[:0] @@ -81,17 +157,15 @@ func prunePatterns(resp *logproto.QueryPatternsResponse, minClusterSize int) *lo if pattern == "" { continue } - resp.Series = append(resp.Series, &logproto.PatternSeries{ - Pattern: pattern, - Samples: cluster.Samples(), - }) + resp.Series = append(resp.Series, + logproto.NewPatternSeries(pattern, cluster.Samples())) } return resp } // ForAllIngesters runs f, in parallel, for all ingesters func (q *IngesterQuerier) forAllIngesters(ctx context.Context, f func(context.Context, logproto.PatternClient) (interface{}, error)) ([]ResponseFromIngesters, error) { - replicationSet, err := q.ringClient.ring.GetReplicationSetForOperation(ring.Read) + replicationSet, err := q.ringClient.Ring().GetReplicationSetForOperation(ring.Read) if err != nil { return nil, err } @@ -110,7 +184,7 @@ func (q *IngesterQuerier) forGivenIngesters(ctx context.Context, replicationSet // Nothing here } results, err := ring.DoUntilQuorum(ctx, replicationSet, cfg, func(ctx context.Context, ingester *ring.InstanceDesc) (ResponseFromIngesters, error) { - client, err := q.ringClient.pool.GetClientFor(ingester.Addr) + client, err := q.ringClient.Pool().GetClientFor(ingester.Addr) if err != nil { return ResponseFromIngesters{addr: ingester.Addr}, err } diff --git a/pkg/pattern/ingester_querier_test.go b/pkg/pattern/ingester_querier_test.go index 9d23662d419e..a40a1ba5c2dd 100644 --- a/pkg/pattern/ingester_querier_test.go +++ b/pkg/pattern/ingester_querier_test.go @@ -2,13 +2,21 @@ package pattern import ( "bufio" + "context" "os" "testing" + "time" + "github.com/go-kit/log" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" + "github.com/grafana/dskit/ring" + ring_client "github.com/grafana/dskit/ring/client" + "github.com/grafana/dskit/services" + "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/pattern/metric" ) func Test_prunePatterns(t *testing.T) { @@ -19,9 +27,7 @@ func Test_prunePatterns(t *testing.T) { resp := new(logproto.QueryPatternsResponse) scanner := bufio.NewScanner(file) for scanner.Scan() { - resp.Series = append(resp.Series, &logproto.PatternSeries{ - Pattern: scanner.Text(), - }) + resp.Series = append(resp.Series, logproto.NewPatternSeries(scanner.Text(), []*logproto.PatternSample{})) } require.NoError(t, scanner.Err()) prunePatterns(resp, 0) @@ -38,9 +44,192 @@ func Test_prunePatterns(t *testing.T) { patterns := make([]string, 0, len(resp.Series)) for _, p := range resp.Series { - patterns = append(patterns, p.Pattern) + patterns = append(patterns, p.GetPattern()) } slices.Sort(patterns) require.Equal(t, expectedPatterns, patterns) } + +func Test_Samples(t *testing.T) { + t.Run("it rejects metric queries with filters", func(t *testing.T) { + q := &IngesterQuerier{ + cfg: Config{ + MetricAggregation: metric.AggregationConfig{ + Enabled: true, + }, + }, + logger: log.NewNopLogger(), + ringClient: &fakeRingClient{}, + registerer: nil, + } + for _, query := range []string{ + `count_over_time({foo="bar"} |= "baz" [5m])`, + `count_over_time({foo="bar"} != "baz" [5m])`, + `count_over_time({foo="bar"} |~ "baz" [5m])`, + `count_over_time({foo="bar"} !~ "baz" [5m])`, + `count_over_time({foo="bar"} | logfmt | color="blue" [5m])`, + `sum(count_over_time({foo="bar"} |= "baz" [5m]))`, + `sum by (label)(count_over_time({foo="bar"} |= "baz" [5m]))`, + `bytes_over_time({foo="bar"} |= "baz" [5m])`, + } { + _, err := q.Samples( + context.Background(), + &logproto.QuerySamplesRequest{ + Query: query, + }, + ) + require.Error(t, err, query) + require.ErrorIs(t, err, ErrParseQuery, query) + } + }) + + t.Run("it rejects log selector queries", func(t *testing.T) { + q := &IngesterQuerier{ + cfg: Config{ + MetricAggregation: metric.AggregationConfig{ + Enabled: true, + }, + }, + logger: log.NewNopLogger(), + ringClient: &fakeRingClient{}, + registerer: nil, + } + for _, query := range []string{ + `{foo="bar"}`, + } { + _, err := q.Samples( + context.Background(), + &logproto.QuerySamplesRequest{ + Query: query, + }, + ) + require.Error(t, err, query) + require.Equal(t, "only sample expression supported", err.Error(), query) + } + }) + + t.Run("accepts count and bytes metric queries", func(t *testing.T) { + q := &IngesterQuerier{ + cfg: Config{ + MetricAggregation: metric.AggregationConfig{ + Enabled: true, + }, + }, + logger: log.NewNopLogger(), + ringClient: &fakeRingClient{}, + registerer: nil, + } + for _, query := range []string{ + `count_over_time({foo="bar"}[5m])`, + `bytes_over_time({foo="bar"}[5m])`, + `sum(count_over_time({foo="bar"}[5m]))`, + `sum(bytes_over_time({foo="bar"}[5m]))`, + `sum by (level)(count_over_time({foo="bar"}[5m]))`, + `sum by (level)(bytes_over_time({foo="bar"}[5m]))`, + } { + _, err := q.Samples( + context.Background(), + &logproto.QuerySamplesRequest{ + Query: query, + }, + ) + require.NoError(t, err, query) + } + }) +} + +type fakeRingClient struct{} + +func (f *fakeRingClient) Pool() *ring_client.Pool { + panic("not implemented") +} + +func (f *fakeRingClient) StartAsync(_ context.Context) error { + panic("not implemented") +} + +func (f *fakeRingClient) AwaitRunning(_ context.Context) error { + panic("not implemented") +} + +func (f *fakeRingClient) StopAsync() { + panic("not implemented") +} + +func (f *fakeRingClient) AwaitTerminated(_ context.Context) error { + panic("not implemented") +} + +func (f *fakeRingClient) FailureCase() error { + panic("not implemented") +} + +func (f *fakeRingClient) State() services.State { + panic("not implemented") +} + +func (f *fakeRingClient) AddListener(_ services.Listener) { + panic("not implemented") +} + +func (f *fakeRingClient) Ring() ring.ReadRing { + return &fakeRing{} +} + +type fakeRing struct{} + +func (f *fakeRing) Get( + _ uint32, + _ ring.Operation, + _ []ring.InstanceDesc, + _ []string, + _ []string, +) (ring.ReplicationSet, error) { + panic("not implemented") +} + +func (f *fakeRing) GetAllHealthy(_ ring.Operation) (ring.ReplicationSet, error) { + panic("not implemented") +} + +func (f *fakeRing) GetReplicationSetForOperation(_ ring.Operation) (ring.ReplicationSet, error) { + return ring.ReplicationSet{}, nil +} + +func (f *fakeRing) ReplicationFactor() int { + panic("not implemented") +} + +func (f *fakeRing) InstancesCount() int { + panic("not implemented") +} + +func (f *fakeRing) ShuffleShard(_ string, _ int) ring.ReadRing { + panic("not implemented") +} + +func (f *fakeRing) GetInstanceState(_ string) (ring.InstanceState, error) { + panic("not implemented") +} + +func (f *fakeRing) ShuffleShardWithLookback( + _ string, + _ int, + _ time.Duration, + _ time.Time, +) ring.ReadRing { + panic("not implemented") +} + +func (f *fakeRing) HasInstance(_ string) bool { + panic("not implemented") +} + +func (f *fakeRing) CleanupShuffleShardCache(_ string) { + panic("not implemented") +} + +func (f *fakeRing) GetTokenRangesForInstance(_ string) (ring.TokenRanges, error) { + panic("not implemented") +} diff --git a/pkg/pattern/ingester_test.go b/pkg/pattern/ingester_test.go index eff054b9ec04..35fb37577e80 100644 --- a/pkg/pattern/ingester_test.go +++ b/pkg/pattern/ingester_test.go @@ -11,20 +11,30 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql/syntax" "github.com/grafana/loki/v3/pkg/pattern/iter" + "github.com/grafana/loki/v3/pkg/pattern/metric" "github.com/grafana/loki/pkg/push" ) -func TestInstancePushQuery(t *testing.T) { - lbs := labels.New(labels.Label{Name: "test", Value: "test"}) - inst, err := newInstance("foo", log.NewNopLogger(), newIngesterMetrics(nil, "test")) +var lbls = labels.New(labels.Label{Name: "test", Value: "test"}) + +func setup(t *testing.T) *instance { + inst, err := newInstance("foo", log.NewNopLogger(), newIngesterMetrics(nil, "test"), metric.AggregationConfig{ + Enabled: true, + }) require.NoError(t, err) - err = inst.Push(context.Background(), &push.PushRequest{ + return inst +} + +func TestInstancePushQuery(t *testing.T) { + inst := setup(t) + err := inst.Push(context.Background(), &push.PushRequest{ Streams: []push.Stream{ { - Labels: lbs.String(), + Labels: lbls.String(), Entries: []push.Entry{ { Timestamp: time.Unix(20, 0), @@ -34,14 +44,31 @@ func TestInstancePushQuery(t *testing.T) { }, }, }) + require.NoError(t, err) + + err = inst.Push(context.Background(), &push.PushRequest{ + Streams: []push.Stream{ + { + Labels: lbls.String(), + Entries: []push.Entry{ + { + Timestamp: time.Unix(30, 0), + Line: "ts=2 msg=hello", + }, + }, + }, + }, + }) + require.NoError(t, err) + for i := 0; i <= 30; i++ { err = inst.Push(context.Background(), &push.PushRequest{ Streams: []push.Stream{ { - Labels: lbs.String(), + Labels: lbls.String(), Entries: []push.Entry{ { - Timestamp: time.Unix(20, 0), + Timestamp: time.Unix(30, 0), Line: "foo bar foo bar", }, }, @@ -50,7 +77,7 @@ func TestInstancePushQuery(t *testing.T) { }) require.NoError(t, err) } - require.NoError(t, err) + it, err := inst.Iterator(context.Background(), &logproto.QueryPatternsRequest{ Query: "{test=\"test\"}", Start: time.Unix(0, 0), @@ -61,3 +88,180 @@ func TestInstancePushQuery(t *testing.T) { require.NoError(t, err) require.Equal(t, 2, len(res.Series)) } + +func TestInstancePushQuerySamples(t *testing.T) { + t.Run("test count_over_time samples", func(t *testing.T) { + inst := setup(t) + err := inst.Push(context.Background(), &push.PushRequest{ + Streams: []push.Stream{ + { + Labels: lbls.String(), + Entries: []push.Entry{ + { + Timestamp: time.Unix(0, 0), + Line: "ts=1 msg=hello", + }, + }, + }, + }, + }) + for i := 1; i <= 30; i++ { + err = inst.Push(context.Background(), &push.PushRequest{ + Streams: []push.Stream{ + { + Labels: lbls.String(), + Entries: []push.Entry{ + { + Timestamp: time.Unix(int64(20*i), 0), + Line: "foo bar foo bar", + }, + }, + }, + }, + }) + require.NoError(t, err) + } + require.NoError(t, err) + + expr, err := syntax.ParseSampleExpr(`count_over_time({test="test"}[20s])`) + require.NoError(t, err) + + it, err := inst.QuerySample(context.Background(), expr, &logproto.QuerySamplesRequest{ + Query: expr.String(), + Start: time.Unix(0, 0), + End: time.Unix(int64(20*30), 0), + Step: 10000, + }) + require.NoError(t, err) + res, err := iter.ReadAllSamples(it) + require.NoError(t, err) + require.Equal(t, 1, len(res.Series)) + + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + + // end - start / step -- (start is 0, step is 10s) + expectedDataPoints := ((20 * 30) / 10) + require.Equal(t, expectedDataPoints, len(res.Series[0].Samples)) + require.Equal(t, float64(1), res.Series[0].Samples[0].Value) + + expr, err = syntax.ParseSampleExpr(`count_over_time({test="test"}[80s])`) + require.NoError(t, err) + + it, err = inst.QuerySample(context.Background(), expr, &logproto.QuerySamplesRequest{ + Query: expr.String(), + Start: time.Unix(0, 0), + End: time.Unix(int64(20*30), 0), + Step: 10000, + }) + require.NoError(t, err) + res, err = iter.ReadAllSamples(it) + require.NoError(t, err) + require.Equal(t, 1, len(res.Series)) + + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + + // end - start / step -- (start is 0, step is 10s) + expectedDataPoints = ((20 * 30) / 10) + require.Equal(t, expectedDataPoints, len(res.Series[0].Samples)) + + // with a larger selection range of 80s, we expect to eventually get up to 4 per datapoint + // our pushes are spaced 20s apart, and there's 10s step, so we ecpect to see the value increase + // every 2 samples, maxing out and staying at 4 after 6 samples (since it starts a 1, not 0) + require.Equal(t, float64(1), res.Series[0].Samples[0].Value) + require.Equal(t, float64(1), res.Series[0].Samples[1].Value) + require.Equal(t, float64(2), res.Series[0].Samples[2].Value) + require.Equal(t, float64(2), res.Series[0].Samples[3].Value) + require.Equal(t, float64(3), res.Series[0].Samples[4].Value) + require.Equal(t, float64(3), res.Series[0].Samples[5].Value) + require.Equal(t, float64(4), res.Series[0].Samples[6].Value) + require.Equal(t, float64(4), res.Series[0].Samples[expectedDataPoints-1].Value) + }) + + t.Run("test bytes_over_time samples", func(t *testing.T) { + inst := setup(t) + err := inst.Push(context.Background(), &push.PushRequest{ + Streams: []push.Stream{ + { + Labels: lbls.String(), + Entries: []push.Entry{ + { + Timestamp: time.Unix(0, 0), + Line: "foo bar foo bars", + }, + }, + }, + }, + }) + for i := 1; i <= 30; i++ { + err = inst.Push(context.Background(), &push.PushRequest{ + Streams: []push.Stream{ + { + Labels: lbls.String(), + Entries: []push.Entry{ + { + Timestamp: time.Unix(int64(20*i), 0), + Line: "foo bar foo bars", + }, + }, + }, + }, + }) + require.NoError(t, err) + } + require.NoError(t, err) + + expr, err := syntax.ParseSampleExpr(`bytes_over_time({test="test"}[20s])`) + require.NoError(t, err) + + it, err := inst.QuerySample(context.Background(), expr, &logproto.QuerySamplesRequest{ + Query: expr.String(), + Start: time.Unix(0, 0), + End: time.Unix(int64(20*30), 0), + Step: 10000, + }) + require.NoError(t, err) + res, err := iter.ReadAllSamples(it) + require.NoError(t, err) + require.Equal(t, 1, len(res.Series)) + + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + + // end - start / step -- (start is 0, step is 10s) + expectedDataPoints := ((20 * 30) / 10) + require.Equal(t, expectedDataPoints, len(res.Series[0].Samples)) + require.Equal(t, float64(16), res.Series[0].Samples[0].Value) + + expr, err = syntax.ParseSampleExpr(`bytes_over_time({test="test"}[80s])`) + require.NoError(t, err) + + it, err = inst.QuerySample(context.Background(), expr, &logproto.QuerySamplesRequest{ + Query: expr.String(), + Start: time.Unix(0, 0), + End: time.Unix(int64(20*30), 0), + Step: 10000, + }) + require.NoError(t, err) + res, err = iter.ReadAllSamples(it) + require.NoError(t, err) + require.Equal(t, 1, len(res.Series)) + + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + + // end - start / step -- (start is 0, step is 10s) + expectedDataPoints = ((20 * 30) / 10) + require.Equal(t, expectedDataPoints, len(res.Series[0].Samples)) + + // with a larger selection range of 80s, we expect to eventually get up to 64 bytes + // as each pushe is 16 bytes and are spaced 20s apart. We query with 10s step, + // so we ecpect to see the value increase by 16 bytes every 2 samples, + // maxing out and staying at 64 after 6 samples (since it starts a 1, not 0) + require.Equal(t, float64(16), res.Series[0].Samples[0].Value) + require.Equal(t, float64(16), res.Series[0].Samples[1].Value) + require.Equal(t, float64(32), res.Series[0].Samples[2].Value) + require.Equal(t, float64(32), res.Series[0].Samples[3].Value) + require.Equal(t, float64(48), res.Series[0].Samples[4].Value) + require.Equal(t, float64(48), res.Series[0].Samples[5].Value) + require.Equal(t, float64(64), res.Series[0].Samples[6].Value) + require.Equal(t, float64(64), res.Series[0].Samples[expectedDataPoints-1].Value) + }) +} diff --git a/pkg/pattern/instance.go b/pkg/pattern/instance.go index f6efa7de0443..63c716967840 100644 --- a/pkg/pattern/instance.go +++ b/pkg/pattern/instance.go @@ -15,36 +15,41 @@ import ( "github.com/grafana/loki/v3/pkg/ingester/index" "github.com/grafana/loki/v3/pkg/logproto" "github.com/grafana/loki/v3/pkg/logql/syntax" - "github.com/grafana/loki/v3/pkg/pattern/drain" - "github.com/grafana/loki/v3/pkg/pattern/iter" + "github.com/grafana/loki/v3/pkg/pattern/chunk" + "github.com/grafana/loki/v3/pkg/pattern/metric" "github.com/grafana/loki/v3/pkg/util" + + loki_iter "github.com/grafana/loki/v3/pkg/iter" + pattern_iter "github.com/grafana/loki/v3/pkg/pattern/iter" ) const indexShards = 32 // instance is a tenant instance of the pattern ingester. type instance struct { - instanceID string - buf []byte // buffer used to compute fps. - mapper *ingester.FpMapper // using of mapper no longer needs mutex because reading from streams is lock-free - streams *streamsMap - index *index.BitPrefixInvertedIndex - logger log.Logger - metrics *ingesterMetrics + instanceID string + buf []byte // buffer used to compute fps. + mapper *ingester.FpMapper // using of mapper no longer needs mutex because reading from streams is lock-free + streams *streamsMap + index *index.BitPrefixInvertedIndex + logger log.Logger + metrics *ingesterMetrics + aggregationCfg metric.AggregationConfig } -func newInstance(instanceID string, logger log.Logger, metrics *ingesterMetrics) (*instance, error) { +func newInstance(instanceID string, logger log.Logger, metrics *ingesterMetrics, aggCfg metric.AggregationConfig) (*instance, error) { index, err := index.NewBitPrefixWithShards(indexShards) if err != nil { return nil, err } i := &instance{ - buf: make([]byte, 0, 1024), - logger: logger, - instanceID: instanceID, - streams: newStreamsMap(), - index: index, - metrics: metrics, + buf: make([]byte, 0, 1024), + logger: logger, + instanceID: instanceID, + streams: newStreamsMap(), + index: index, + metrics: metrics, + aggregationCfg: aggCfg, } i.mapper = ingester.NewFPMapper(i.getLabelsFromFingerprint) return i, nil @@ -75,18 +80,18 @@ func (i *instance) Push(ctx context.Context, req *logproto.PushRequest) error { } // Iterator returns an iterator of pattern samples matching the given query patterns request. -func (i *instance) Iterator(ctx context.Context, req *logproto.QueryPatternsRequest) (iter.Iterator, error) { +func (i *instance) Iterator(ctx context.Context, req *logproto.QueryPatternsRequest) (pattern_iter.Iterator, error) { matchers, err := syntax.ParseMatchers(req.Query, true) if err != nil { return nil, httpgrpc.Errorf(http.StatusBadRequest, err.Error()) } from, through := util.RoundToMilliseconds(req.Start, req.End) step := model.Time(req.Step) - if step < drain.TimeResolution { - step = drain.TimeResolution + if step < chunk.TimeResolution { + step = chunk.TimeResolution } - var iters []iter.Iterator + var iters []pattern_iter.Iterator err = i.forMatchingStreams(matchers, func(s *stream) error { iter, err := s.Iterator(ctx, from, through, step) if err != nil { @@ -98,7 +103,51 @@ func (i *instance) Iterator(ctx context.Context, req *logproto.QueryPatternsRequ if err != nil { return nil, err } - return iter.NewMerge(iters...), nil + return pattern_iter.NewMerge(iters...), nil +} + +func (i *instance) QuerySample( + ctx context.Context, + expr syntax.SampleExpr, + req *logproto.QuerySamplesRequest, +) (loki_iter.SampleIterator, error) { + if !i.aggregationCfg.Enabled { + // Should never get here, but this will prevent nil pointer panics in test + return loki_iter.NoopIterator, nil + } + + from, through := util.RoundToMilliseconds(req.Start, req.End) + step := model.Time(req.Step) + if step < chunk.TimeResolution { + step = chunk.TimeResolution + } + + selector, err := expr.Selector() + if err != nil { + return nil, err + } + + var iters []loki_iter.SampleIterator + err = i.forMatchingStreams( + selector.Matchers(), + func(stream *stream) error { + var iter loki_iter.SampleIterator + var err error + iter, err = stream.SampleIterator(ctx, expr, from, through, step) + + if err != nil { + return err + } + + iters = append(iters, iter) + return nil + }, + ) + if err != nil { + return nil, err + } + + return loki_iter.NewSortSampleIterator(iters), nil } // forMatchingStreams will execute a function for each stream that matches the given matchers. @@ -140,7 +189,7 @@ func (i *instance) createStream(_ context.Context, pushReqStream logproto.Stream } fp := i.getHashForLabels(labels) sortedLabels := i.index.Add(logproto.FromLabelsToLabelAdapters(labels), fp) - s, err := newStream(fp, sortedLabels, i.metrics) + s, err := newStream(fp, sortedLabels, i.metrics, i.aggregationCfg.Enabled) if err != nil { return nil, fmt.Errorf("failed to create stream: %w", err) } diff --git a/pkg/pattern/instance_test.go b/pkg/pattern/instance_test.go new file mode 100644 index 000000000000..974e17403ce5 --- /dev/null +++ b/pkg/pattern/instance_test.go @@ -0,0 +1,128 @@ +package pattern + +import ( + "context" + "testing" + "time" + + "github.com/go-kit/log" + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql/syntax" + "github.com/grafana/loki/v3/pkg/pattern/metric" + + "github.com/grafana/loki/pkg/push" +) + +func TestInstance_QuerySample(t *testing.T) { + ctx := context.Background() + + thirtySeconds := int64(30000) + oneMin := int64(60000) + fiveMin := oneMin * 5 + now := fiveMin + then := int64(0) + + mockReq := &logproto.QuerySamplesRequest{ + Start: time.UnixMilli(then), + End: time.UnixMilli(now + 1e4), + Step: oneMin, + } + + instance, err := newInstance("test", log.NewNopLogger(), newIngesterMetrics(nil, "test"), metric.AggregationConfig{ + Enabled: true, + }) + require.NoError(t, err) + + labels := model.LabelSet{ + model.LabelName("foo"): model.LabelValue("bar"), + } + + lastTsMilli := (then + oneMin + thirtySeconds) // 0 + 60000 + 30000 = 90000 + + err = instance.Push(ctx, &logproto.PushRequest{ + Streams: []push.Stream{ + { + Labels: labels.String(), + Entries: []push.Entry{ + { + Timestamp: time.UnixMilli(then), + Line: "this=that color=blue", + }, + { + Timestamp: time.UnixMilli(then + thirtySeconds), + Line: "this=that color=blue", + }, + { + Timestamp: time.UnixMilli(then + oneMin), + Line: "this=that color=blue", + }, + { + Timestamp: time.UnixMilli(lastTsMilli), + Line: "this=that color=blue", + }, + }, + Hash: uint64(labels.Fingerprint()), + }, + }, + }) + require.NoError(t, err) + + // 5 min query range + // 1 min step + // 1 min selection range + + // first: -60000 to 0 + // second: 0 to 60000 + // third: 60000 to 120000 + // fourth: 120000 to 180000 + // fifth: 180000 to 240000 + // sixth: 240000 to 300000 + + // lastTsMilli is 90000 + // would expect it in the 3rd bucket + start := then + secondPoint := start + oneMin + thirdPoint := secondPoint + oneMin + + t.Run("successful count over time query", func(t *testing.T) { + expr, err := syntax.ParseSampleExpr(`count_over_time({foo="bar"}[60s])`) + require.NoError(t, err) + + iter, err := instance.QuerySample(ctx, expr, mockReq) + assert.NoError(t, err) + assert.NotNil(t, iter) + + next := iter.Next() + require.True(t, next) + + sample := iter.Sample() + require.Equal(t, float64(4), sample.Value) + require.Equal(t, model.Time(thirdPoint).UnixNano(), sample.Timestamp) + + next = iter.Next() + require.False(t, next) + }) + + t.Run("successful bytes over time query", func(t *testing.T) { + expr, err := syntax.ParseSampleExpr(`bytes_over_time({foo="bar"}[60s])`) + require.NoError(t, err) + + iter, err := instance.QuerySample(ctx, expr, mockReq) + assert.NoError(t, err) + assert.NotNil(t, iter) + + next := iter.Next() + require.True(t, next) + + sample := iter.Sample() + require.Equal(t, float64(80), sample.Value) + require.Equal(t, model.Time(thirdPoint).UnixNano(), sample.Timestamp) + + next = iter.Next() + require.False(t, next) + }) +} diff --git a/pkg/pattern/iter/batch.go b/pkg/pattern/iter/batch.go index 80ad1197c80a..fee835d16208 100644 --- a/pkg/pattern/iter/batch.go +++ b/pkg/pattern/iter/batch.go @@ -3,6 +3,7 @@ package iter import ( "math" + "github.com/grafana/loki/v3/pkg/iter" "github.com/grafana/loki/v3/pkg/logproto" ) @@ -32,3 +33,37 @@ func ReadBatch(it Iterator, batchSize int) (*logproto.QueryPatternsResponse, err func ReadAll(it Iterator) (*logproto.QueryPatternsResponse, error) { return ReadBatch(it, math.MaxInt32) } + +func ReadMetricsBatch(it iter.SampleIterator, batchSize int) (*logproto.QuerySamplesResponse, error) { + var ( + series = map[uint64]*logproto.Series{} + respSize int + ) + + for ; respSize < batchSize && it.Next(); respSize++ { + hash := it.StreamHash() + s, ok := series[hash] + if !ok { + s = &logproto.Series{ + Labels: it.Labels(), + Samples: []logproto.Sample{}, + StreamHash: hash, + } + series[hash] = s + } + + s.Samples = append(s.Samples, it.Sample()) + } + + result := logproto.QuerySamplesResponse{ + Series: make([]logproto.Series, 0, len(series)), + } + for _, s := range series { + result.Series = append(result.Series, *s) + } + return &result, it.Error() +} + +func ReadAllSamples(it iter.SampleIterator) (*logproto.QuerySamplesResponse, error) { + return ReadMetricsBatch(it, math.MaxInt32) +} diff --git a/pkg/pattern/iter/batch_test.go b/pkg/pattern/iter/batch_test.go index 7f544e23f417..3ee565892da4 100644 --- a/pkg/pattern/iter/batch_test.go +++ b/pkg/pattern/iter/batch_test.go @@ -32,13 +32,13 @@ func TestReadBatch(t *testing.T) { batchSize: 2, expected: &logproto.QueryPatternsResponse{ Series: []*logproto.PatternSeries{ - { - Pattern: "foo", - Samples: []*logproto.PatternSample{ + logproto.NewPatternSeries( + "foo", + []*logproto.PatternSample{ {Timestamp: 10, Value: 2}, {Timestamp: 20, Value: 4}, }, - }, + ), }, }, }, @@ -49,14 +49,14 @@ func TestReadBatch(t *testing.T) { batchSize: 4, expected: &logproto.QueryPatternsResponse{ Series: []*logproto.PatternSeries{ - { - Pattern: "foo", - Samples: []*logproto.PatternSample{ + logproto.NewPatternSeries( + "foo", + []*logproto.PatternSample{ {Timestamp: 10, Value: 2}, {Timestamp: 20, Value: 4}, {Timestamp: 30, Value: 6}, }, - }, + ), }, }, }, diff --git a/pkg/pattern/iter/query_client.go b/pkg/pattern/iter/query_client.go index f6c5c4fa9774..f471999d62e3 100644 --- a/pkg/pattern/iter/query_client.go +++ b/pkg/pattern/iter/query_client.go @@ -3,6 +3,7 @@ package iter import ( "io" + "github.com/grafana/loki/v3/pkg/iter" "github.com/grafana/loki/v3/pkg/logproto" ) @@ -62,3 +63,55 @@ func NewQueryResponseIterator(resp *logproto.QueryPatternsResponse) Iterator { } return NewMerge(iters...) } + +type querySamplesClientIterator struct { + client logproto.Pattern_QuerySampleClient + err error + curr iter.SampleIterator +} + +// NewQueryClientIterator returns an iterator over a QueryClient. +func NewQuerySamplesClientIterator(client logproto.Pattern_QuerySampleClient) iter.SampleIterator { + return &querySamplesClientIterator{ + client: client, + } +} + +func (i *querySamplesClientIterator) Next() bool { + for i.curr == nil || !i.curr.Next() { + batch, err := i.client.Recv() + if err == io.EOF { + return false + } else if err != nil { + i.err = err + return false + } + i.curr = NewQuerySamplesResponseIterator(batch) + } + + return true +} + +func (i *querySamplesClientIterator) Sample() logproto.Sample { + return i.curr.Sample() +} + +func (i *querySamplesClientIterator) StreamHash() uint64 { + return i.curr.StreamHash() +} + +func (i *querySamplesClientIterator) Labels() string { + return i.curr.Labels() +} + +func (i *querySamplesClientIterator) Error() error { + return i.err +} + +func (i *querySamplesClientIterator) Close() error { + return i.client.CloseSend() +} + +func NewQuerySamplesResponseIterator(resp *logproto.QuerySamplesResponse) iter.SampleIterator { + return iter.NewMultiSeriesIterator(resp.Series) +} diff --git a/pkg/pattern/metric/chunk.go b/pkg/pattern/metric/chunk.go new file mode 100644 index 000000000000..c48a3c78924b --- /dev/null +++ b/pkg/pattern/metric/chunk.go @@ -0,0 +1,225 @@ +package metric + +import ( + "fmt" + "slices" + "sort" + "time" + + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + + "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql/syntax" + "github.com/grafana/loki/v3/pkg/pattern/chunk" + + "github.com/grafana/loki/v3/pkg/iter" +) + +type Type int + +const ( + Bytes Type = iota + Count + Unsupported +) + +type Chunks struct { + chunks []Chunk + labels labels.Labels +} + +func NewChunks(labels labels.Labels) *Chunks { + return &Chunks{ + chunks: make([]Chunk, 0), + labels: labels, + } +} + +func (c *Chunks) Observe(bytes, count float64, ts model.Time) { + if len(c.chunks) == 0 { + c.chunks = append(c.chunks, newChunk(bytes, count, ts)) + return + } + + last := &(c.chunks)[len(c.chunks)-1] + if !last.spaceFor(ts) { + c.chunks = append(c.chunks, newChunk(bytes, count, ts)) + return + } + + last.AddSample(newSample(bytes, count, ts)) +} + +func (c *Chunks) Iterator( + typ Type, + grouping *syntax.Grouping, + from, through, step model.Time, +) (iter.SampleIterator, error) { + if typ == Unsupported { + return nil, fmt.Errorf("unsupported metric type") + } + + lbls := c.labels + if grouping != nil { + sort.Strings(grouping.Groups) + lbls = make(labels.Labels, 0, len(grouping.Groups)) + for _, group := range grouping.Groups { + value := c.labels.Get(group) + lbls = append(lbls, labels.Label{Name: group, Value: value}) + } + } + + // could have up to through-from/step steps for each chunk + maximumSteps := int64(((through-from)/step)+1) * int64(len(c.chunks)) + samples := make([]logproto.Sample, 0, maximumSteps) + for _, chunk := range c.chunks { + ss, err := chunk.ForTypeAndRange(typ, from, through) + if err != nil { + return nil, err + } + + if len(ss) == 0 { + continue + } + + samples = append(samples, ss...) + } + + slices.SortFunc(samples, func(i, j logproto.Sample) int { + if i.Timestamp < j.Timestamp { + return -1 + } + + if i.Timestamp > j.Timestamp { + return 1 + } + return 0 + }) + + series := logproto.Series{Labels: lbls.String(), Samples: samples, StreamHash: lbls.Hash()} + return iter.NewSeriesIterator(series), nil +} + +type Sample struct { + Timestamp model.Time + Bytes float64 + Count float64 +} + +func newSample(bytes, count float64, ts model.Time) Sample { + return Sample{ + Timestamp: ts, + Bytes: bytes, + Count: count, + } +} + +type Samples []Sample + +type Chunk struct { + Samples Samples + mint, maxt int64 +} + +func (c *Chunk) Bounds() (fromT, toT time.Time) { + return time.Unix(0, c.mint), time.Unix(0, c.maxt) +} + +func (c *Chunk) AddSample(s Sample) { + c.Samples = append(c.Samples, s) + ts := int64(s.Timestamp) + + if ts < c.mint { + c.mint = ts + } + + if ts > c.maxt { + c.maxt = ts + } +} + +func newChunk(bytes, count float64, ts model.Time) Chunk { + maxSize := int(chunk.MaxChunkTime.Nanoseconds()/chunk.TimeResolution.UnixNano()) + 1 + v := Chunk{Samples: make(Samples, 1, maxSize)} + v.Samples[0] = newSample(bytes, count, ts) + return v +} + +func (c *Chunk) spaceFor(ts model.Time) bool { + if len(c.Samples) == 0 { + return true + } + + return ts.Sub(c.Samples[0].Timestamp) < chunk.MaxChunkTime +} + +// ForTypeAndRange returns samples with only the values +// in the given range [start:end), with no aggregation as that will be done in +// the step evaluator. start and end are in milliseconds since epoch. +// step is a duration in milliseconds. +func (c *Chunk) ForTypeAndRange( + typ Type, + start, end model.Time, +) ([]logproto.Sample, error) { + if typ == Unsupported { + return nil, fmt.Errorf("unsupported metric type") + } + + if len(c.Samples) == 0 { + return nil, nil + } + + first := c.Samples[0].Timestamp + last := c.Samples[len(c.Samples)-1].Timestamp + startBeforeEnd := start >= end + samplesAreAfterRange := first >= end + samplesAreBeforeRange := last < start + if startBeforeEnd || samplesAreAfterRange || samplesAreBeforeRange { + return nil, nil + } + + lo := 0 + hi := len(c.Samples) + + for i, sample := range c.Samples { + if first >= start { + break + } + + if first < start && sample.Timestamp >= start { + lo = i + first = sample.Timestamp + } + } + + for i := hi - 1; i >= 0; i-- { + if last < end { + break + } + + sample := c.Samples[i] + if last >= end && sample.Timestamp < end { + hi = i + 1 + last = sample.Timestamp + } + } + + aggregatedSamples := make([]logproto.Sample, len(c.Samples[lo:hi])) + for i, sample := range c.Samples[lo:hi] { + if sample.Timestamp >= start && sample.Timestamp < end { + var v float64 + if typ == Bytes { + v = sample.Bytes + } else { + v = sample.Count + } + aggregatedSamples[i] = logproto.Sample{ + Timestamp: sample.Timestamp.UnixNano(), + Value: v, + } + } + } + + return aggregatedSamples, nil +} diff --git a/pkg/pattern/metric/chunk_test.go b/pkg/pattern/metric/chunk_test.go new file mode 100644 index 000000000000..0affcd197e14 --- /dev/null +++ b/pkg/pattern/metric/chunk_test.go @@ -0,0 +1,403 @@ +package metric + +import ( + "reflect" + "testing" + + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql/syntax" + "github.com/grafana/loki/v3/pkg/pattern/iter" +) + +func TestForTypeAndRange(t *testing.T) { + testCases := []struct { + name string + c *Chunk + metricType Type + start model.Time + end model.Time + expected []logproto.Sample + }{ + { + name: "Empty count", + c: &Chunk{}, + metricType: Count, + start: 1, + end: 10, + expected: nil, + }, + { + name: "Empty bytes", + c: &Chunk{}, + metricType: Bytes, + start: 1, + end: 10, + expected: nil, + }, + { + name: "No Overlap -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 10, + end: 20, + expected: nil, + }, + { + name: "No Overlap -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 10, + end: 20, + expected: nil, + }, + { + name: "Complete Overlap -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 0, + end: 10, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + {Timestamp: 6 * 1e6, Value: 6}, + }, + }, + { + name: "Complete Overlap -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 0, + end: 10, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + {Timestamp: 6 * 1e6, Value: 6}, + }, + }, + { + name: "Partial Overlap -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 2, + end: 5, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "Partial Overlap -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 2, + end: 5, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "Single Element in Range -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 4, + end: 5, + expected: []logproto.Sample{{Timestamp: 4 * 1e6, Value: 4}}, + }, + { + name: "Single Element in Range -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 4, + end: 5, + expected: []logproto.Sample{{Timestamp: 4 * 1e6, Value: 4}}, + }, + { + name: "Start Before First Element -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 0, + end: 5, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "Start Before First Element -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 0, + end: 5, + expected: []logproto.Sample{ + {Timestamp: 2 * 1e6, Value: 2}, + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "End After Last Element -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 5, + end: 10, + expected: []logproto.Sample{ + {Timestamp: 6 * 1e6, Value: 6}, + }, + }, + { + name: "End After Last Element -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 5, + end: 10, + expected: []logproto.Sample{ + {Timestamp: 6 * 1e6, Value: 6}, + }, + }, + { + name: "End Exclusive -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 4, + end: 6, + expected: []logproto.Sample{ + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "End Exclusive -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 4, + end: 6, + expected: []logproto.Sample{ + {Timestamp: 4 * 1e6, Value: 4}, + }, + }, + { + name: "Start before First and End Inclusive of First Element -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 0, + end: 3, + expected: []logproto.Sample{{Timestamp: 2 * 1e6, Value: 2}}, + }, + { + name: "Start before First and End Inclusive of First Element -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 0, + end: 3, + expected: []logproto.Sample{{Timestamp: 2 * 1e6, Value: 2}}, + }, + { + name: "Start and End before First Element -- count", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Count: 2}, + {Timestamp: 4, Count: 4}, + {Timestamp: 6, Count: 6}, + }}, + metricType: Count, + start: 0, + end: 1, + expected: nil, + }, + { + name: "Start and End before First Element -- bytes", + c: &Chunk{Samples: Samples{ + {Timestamp: 2, Bytes: 2}, + {Timestamp: 4, Bytes: 4}, + {Timestamp: 6, Bytes: 6}, + }}, + metricType: Bytes, + start: 0, + end: 1, + expected: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result, err := tc.c.ForTypeAndRange(tc.metricType, tc.start, tc.end) + require.NoError(t, err) + if !reflect.DeepEqual(result, tc.expected) { + t.Errorf("Expected %v, got %v", tc.expected, result) + } + require.Equal(t, len(result), cap(result), "Returned slice wasn't created at the correct capacity") + }) + } +} + +// TODO(twhitney): test the maximum steps logic +func Test_Chunks_Iterator(t *testing.T) { + lbls := labels.Labels{ + labels.Label{Name: "foo", Value: "bar"}, + labels.Label{Name: "container", Value: "jar"}, + } + chunks := Chunks{ + chunks: []Chunk{ + { + Samples: []Sample{ + {Timestamp: 2, Bytes: 2, Count: 1}, + {Timestamp: 4, Bytes: 4, Count: 3}, + {Timestamp: 6, Bytes: 6, Count: 5}, + }, + mint: 2, + maxt: 6, + }, + }, + labels: lbls, + } + + t.Run("without grouping", func(t *testing.T) { + it, err := chunks.Iterator(Bytes, nil, 0, 10, 2) + require.NoError(t, err) + + res, err := iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + + it, err = chunks.Iterator(Count, nil, 0, 10, 2) + require.NoError(t, err) + + res, err = iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, lbls.String(), res.Series[0].GetLabels()) + }) + + t.Run("grouping", func(t *testing.T) { + grouping := &syntax.Grouping{ + Groups: []string{"container"}, + Without: false, + } + + expectedLabels := labels.Labels{ + labels.Label{ + Name: "container", + Value: "jar", + }, + } + + it, err := chunks.Iterator(Bytes, grouping, 0, 10, 2) + require.NoError(t, err) + + res, err := iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, expectedLabels.String(), res.Series[0].GetLabels()) + + it, err = chunks.Iterator(Count, grouping, 0, 10, 2) + require.NoError(t, err) + + res, err = iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, expectedLabels.String(), res.Series[0].GetLabels()) + }) + + t.Run("grouping by a missing label", func(t *testing.T) { + grouping := &syntax.Grouping{ + Groups: []string{"missing"}, + Without: false, + } + + expectedLabels := labels.Labels{ + labels.Label{ + Name: "missing", + Value: "", + }, + } + + it, err := chunks.Iterator(Bytes, grouping, 0, 10, 2) + require.NoError(t, err) + + res, err := iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, expectedLabels.String(), res.Series[0].GetLabels()) + + it, err = chunks.Iterator(Count, grouping, 0, 10, 2) + require.NoError(t, err) + + res, err = iter.ReadAllSamples(it) + require.NoError(t, err) + + require.Equal(t, 1, len(res.Series)) + require.Equal(t, expectedLabels.String(), res.Series[0].GetLabels()) + }) +} diff --git a/pkg/pattern/metric/config.go b/pkg/pattern/metric/config.go new file mode 100644 index 000000000000..8bdf85cdcb64 --- /dev/null +++ b/pkg/pattern/metric/config.go @@ -0,0 +1,16 @@ +package metric + +import "flag" + +type AggregationConfig struct { + Enabled bool `yaml:"enabled,omitempty" doc:"description=Whether the pattern ingester metric aggregation is enabled."` +} + +// RegisterFlags registers pattern ingester related flags. +func (cfg *AggregationConfig) RegisterFlags(fs *flag.FlagSet) { + cfg.RegisterFlagsWithPrefix(fs, "") +} + +func (cfg *AggregationConfig) RegisterFlagsWithPrefix(fs *flag.FlagSet, prefix string) { + fs.BoolVar(&cfg.Enabled, prefix+"metric-aggregation.enabled", false, "Flag to enable or disable metric aggregation.") +} diff --git a/pkg/pattern/metric/evaluator.go b/pkg/pattern/metric/evaluator.go new file mode 100644 index 000000000000..eb8bd4ac2d35 --- /dev/null +++ b/pkg/pattern/metric/evaluator.go @@ -0,0 +1,306 @@ +package metric + +import ( + "context" + "fmt" + "sort" + "time" + + "github.com/pkg/errors" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/promql" + + loki_iter "github.com/grafana/loki/v3/pkg/iter" + "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql" + "github.com/grafana/loki/v3/pkg/logql/syntax" + "github.com/grafana/loki/v3/pkg/storage/chunk/cache/resultscache" +) + +// TODO(twhitney): duplication with code in NewStepEvaluator +func extractMetricType(expr syntax.SampleExpr) (Type, error) { + var typ Type + switch e := expr.(type) { + case *syntax.VectorAggregationExpr: + if rangeExpr, ok := e.Left.(*syntax.RangeAggregationExpr); ok && e.Operation == syntax.OpTypeSum { + if rangeExpr.Operation == syntax.OpRangeTypeCount { + typ = Count + } else if rangeExpr.Operation == syntax.OpRangeTypeBytes { + typ = Bytes + } else { + return Unsupported, fmt.Errorf("unsupported aggregation operation %s", e.Operation) + } + } else { + return Unsupported, fmt.Errorf("unsupported aggregation operation %s", e.Operation) + } + case *syntax.RangeAggregationExpr: + if e.Operation == syntax.OpRangeTypeCount { + typ = Count + } else if e.Operation == syntax.OpRangeTypeBytes { + typ = Bytes + } else { + return Unsupported, fmt.Errorf("unsupported aggregation operation %s", e.Operation) + } + default: + return Unsupported, fmt.Errorf("unexpected expression type %T", e) + } + return typ, nil +} + +type SampleEvaluatorFactory interface { + // NewStepEvaluator returns a NewStepEvaluator for a given SampleExpr. + // It's explicitly passed another NewStepEvaluator + // in order to enable arbitrary computation of embedded expressions. This allows more modular & extensible + // NewStepEvaluator implementations which can be composed. + NewStepEvaluator( + ctx context.Context, + nextEvaluatorFactory SampleEvaluatorFactory, + expr syntax.SampleExpr, + from, through, step model.Time, + ) (logql.StepEvaluator, error) +} + +type SampleEvaluatorFunc func( + ctx context.Context, + nextEvaluatorFactory SampleEvaluatorFactory, + expr syntax.SampleExpr, + from, through, step model.Time, +) (logql.StepEvaluator, error) + +func (s SampleEvaluatorFunc) NewStepEvaluator( + ctx context.Context, + nextEvaluatorFactory SampleEvaluatorFactory, + expr syntax.SampleExpr, + from, through, step model.Time, +) (logql.StepEvaluator, error) { + return s(ctx, nextEvaluatorFactory, expr, from, through, step) +} + +type DefaultEvaluatorFactory struct { + chunks *Chunks +} + +func NewDefaultEvaluatorFactory(chunks *Chunks) *DefaultEvaluatorFactory { + return &DefaultEvaluatorFactory{ + chunks: chunks, + } +} + +func (ev *DefaultEvaluatorFactory) NewStepEvaluator( + ctx context.Context, + evFactory SampleEvaluatorFactory, + expr syntax.SampleExpr, + from, through, step model.Time, +) (logql.StepEvaluator, error) { + metricType, err := extractMetricType(expr) + if err != nil || metricType == Unsupported { + return nil, err + } + + switch e := expr.(type) { + case *syntax.VectorAggregationExpr: + if rangExpr, ok := e.Left.(*syntax.RangeAggregationExpr); ok && e.Operation == syntax.OpTypeSum { + // if range expression is wrapped with a vector expression + // we should send the vector expression for allowing reducing labels at the source. + evFactory = SampleEvaluatorFunc( + func(ctx context.Context, + _ SampleEvaluatorFactory, + _ syntax.SampleExpr, + from, through, step model.Time, + ) (logql.StepEvaluator, error) { + fromWithRangeAndOffset := from.Add(-rangExpr.Left.Interval).Add(-rangExpr.Left.Offset) + throughWithOffset := through.Add(-rangExpr.Left.Offset) + it, err := ev.chunks.Iterator(metricType, e.Grouping, fromWithRangeAndOffset, throughWithOffset, step) + if err != nil { + return nil, err + } + + params := NewParams( + e, + from, + through, + step, + ) + return NewSampleRangeAggEvaluator(loki_iter.NewPeekingSampleIterator(it), rangExpr, params, rangExpr.Left.Offset) + }) + } + + if e.Grouping == nil { + return nil, errors.Errorf("aggregation operator '%q' without grouping", e.Operation) + } + nextEvaluator, err := evFactory.NewStepEvaluator(ctx, evFactory, e.Left, from, through, step) + if err != nil { + return nil, err + } + sort.Strings(e.Grouping.Groups) + + return logql.NewVectorAggEvaluator( + nextEvaluator, + e, + make([]byte, 0, 1024), + labels.NewBuilder(labels.Labels{}), + ), nil + + case *syntax.RangeAggregationExpr: + fromWithRangeAndOffset := from.Add(-e.Left.Interval).Add(-e.Left.Offset) + throughWithOffset := through.Add(-e.Left.Offset) + it, err := ev.chunks.Iterator(metricType, e.Grouping, fromWithRangeAndOffset, throughWithOffset, step) + if err != nil { + return nil, err + } + + params := NewParams( + e, + from, + through, + step, + ) + return NewSampleRangeAggEvaluator(loki_iter.NewPeekingSampleIterator(it), e, params, e.Left.Offset) + default: + return nil, errors.Errorf("unexpected expr type (%T)", e) + } +} + +// Need to create our own StepEvaluator since we only support bytes and count over time, +// and always sum to get those values. In order to accomplish this we need control over the +// aggregation operation.. +func NewSampleRangeAggEvaluator( + it loki_iter.PeekingSampleIterator, + expr *syntax.RangeAggregationExpr, + q logql.Params, + o time.Duration, +) (logql.StepEvaluator, error) { + iter, err := newRangeVectorIterator( + it, + expr.Left.Interval.Nanoseconds(), + q.Step().Nanoseconds(), + q.Start().UnixNano(), q.End().UnixNano(), o.Nanoseconds(), + ) + if err != nil { + return nil, err + } + + return logql.NewRangeVectorEvaluator(iter), nil +} + +func newRangeVectorIterator( + it loki_iter.PeekingSampleIterator, + selRange, step, start, end, offset int64, +) (logql.RangeVectorIterator, error) { + // forces at least one step. + if step == 0 { + step = 1 + } + if offset != 0 { + start = start - offset + end = end - offset + } + // TODO(twhitney): do I need a streaming aggregator? + // if so the aggregator is going to make this + // a bit of a bad time, as there's currently no + // way to provide a custom one. + // + // var overlap bool + // if selRange >= step && start != end { + // overlap = true + // } + // if !overlap { + // _, err := streamingAggregator(expr) + // if err != nil { + // return nil, err + // } + // return &streamRangeVectorIterator{ + // iter: it, + // step: step, + // end: end, + // selRange: selRange, + // metrics: map[string]labels.Labels{}, + // r: expr, + // current: start - step, // first loop iteration will set it to start + // offset: offset, + // }, nil + // } + + // always sum + aggregator := logql.BatchRangeVectorAggregator(func(samples []promql.FPoint) float64 { + sum := 0.0 + for _, v := range samples { + sum += v.F + } + return sum + }) + + return logql.NewBatchRangeVectorIterator( + it, + selRange, + step, + start, + end, + offset, + aggregator, + ), nil +} + +type ParamCompat struct { + expr syntax.SampleExpr + from model.Time + through model.Time + step model.Time +} + +func NewParams( + expr syntax.SampleExpr, + from, through, step model.Time, +) *ParamCompat { + return &ParamCompat{ + expr: expr, + from: from, + through: through, + step: step, + } +} + +func (p *ParamCompat) QueryString() string { + return p.expr.String() +} + +func (p *ParamCompat) Start() time.Time { + return p.from.Time() +} + +func (p *ParamCompat) End() time.Time { + return p.through.Time() +} + +func (p *ParamCompat) Step() time.Duration { + return time.Duration(p.step.UnixNano()) +} + +func (p *ParamCompat) Interval() time.Duration { + return time.Duration(0) +} + +func (p *ParamCompat) Limit() uint32 { + return 0 +} + +func (p *ParamCompat) Direction() logproto.Direction { + return logproto.BACKWARD +} + +func (p *ParamCompat) Shards() []string { + return []string{} +} + +func (p *ParamCompat) GetExpression() syntax.Expr { + return p.expr +} + +func (p *ParamCompat) GetStoreChunks() *logproto.ChunkRefGroup { + return nil +} + +func (p *ParamCompat) CachingOptions() (res resultscache.CachingOptions) { + return +} diff --git a/pkg/pattern/metric/evaluator_test.go b/pkg/pattern/metric/evaluator_test.go new file mode 100644 index 000000000000..1f9683d214b3 --- /dev/null +++ b/pkg/pattern/metric/evaluator_test.go @@ -0,0 +1,427 @@ +package metric + +import ( + "context" + "testing" + + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/logql" + "github.com/grafana/loki/v3/pkg/logql/syntax" +) + +func Test_SampleEvaluator(t *testing.T) { + fiveMinMs := int64(300000) + tenSecMs := int64(1e4) + stream := labels.Labels{ + labels.Label{ + Name: "foo", + Value: "bar", + }, + labels.Label{ + Name: "level", + Value: "debug", + }, + } + + setup := func(chunks Chunks, from, through, step int64, query string) logql.StepEvaluator { + factory := NewDefaultEvaluatorFactory(&chunks) + + expr, err := syntax.ParseSampleExpr(query) + require.NoError(t, err) + + evaluator, err := factory.NewStepEvaluator( + context.Background(), + factory, + expr, + // add 10s to the end to include chunks @ now + model.Time(from), model.Time(through), model.Time(fiveMinMs), + ) + + require.NoError(t, err) + return evaluator + } + + chunks := func(now, then, beforeThen int64) Chunks { + nowTime := model.Time(now) + thenTime := model.Time(then) + beforeThenTime := model.Time(beforeThen) + return Chunks{ + chunks: []Chunk{ + { + Samples: []Sample{ + { + Timestamp: beforeThenTime, + Bytes: 1, + Count: 1, + }, + { + Timestamp: thenTime, + Bytes: 3, + Count: 2, + }, + { + Timestamp: nowTime, + Bytes: 5, + Count: 3, + }, + }, + mint: thenTime.Unix(), + maxt: nowTime.Unix(), + }, + }, + labels: stream, + } + } + + t.Run("grouping", func(t *testing.T) { + group := labels.Labels{ + labels.Label{ + Name: "level", + Value: "debug", + }, + } + t.Run("evenly aligned, non-overlapping timestamps", func(t *testing.T) { + now := int64(600000) // 10 minutes after 0 + then := now - fiveMinMs // 300000, 5m before now + beforeThen := then - fiveMinMs // 0, 5m before then + chks := chunks(now, then, beforeThen) + + t.Run("count", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+1e4, fiveMinMs, `sum by (level)(count_over_time({foo="bar"}[5m]))`) + + resultTs := make([]int64, 3) + resultVals := make([]float64, 3) + + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, then-fiveMinMs <= ts && ts <= now) + + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + vec := r.SampleVector() + require.Equal(t, 1, len(vec)) + resultTs[i] = r.SampleVector()[0].T + resultVals[i] = r.SampleVector()[0].F + + require.Equal(t, group, r.SampleVector()[0].Metric) + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + require.Equal(t, beforeThen, resultTs[0]) + require.Equal(t, then, resultTs[1]) + require.Equal(t, now, resultTs[2]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(2), resultVals[1]) + require.Equal(t, float64(3), resultVals[2]) + }) + + t.Run("bytes", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+tenSecMs, fiveMinMs, `sum by (level)(bytes_over_time({foo="bar"}[5m]))`) + + resultTs := make([]int64, 3) + resultVals := make([]float64, 3) + + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, then-fiveMinMs <= ts && ts <= now) + + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + resultTs[i] = r.SampleVector()[0].T + resultVals[i] = r.SampleVector()[0].F + + require.Equal(t, group, r.SampleVector()[0].Metric) + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + require.Equal(t, beforeThen, resultTs[0]) + require.Equal(t, then, resultTs[1]) + require.Equal(t, now, resultTs[2]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(3), resultVals[1]) // TODO: got 2, expected 3 + require.Equal(t, float64(5), resultVals[2]) + }) + }) + + t.Run("evenly aligned, overlapping timestamps", func(t *testing.T) { + now := int64(150000 + 450000) // 600000, 10m after 0 + then := now - 150000 // 450000 -- 2.5m before now + beforeThen := then - 450000 // 0 -- 7.5m before then, 10m before now + chks := chunks(now, then, beforeThen) + + t.Run("count", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+1e4, fiveMinMs, `sum by (level)(count_over_time({foo="bar"}[5m]))`) + + resultTs := make([]int64, 0, 2) + resultVals := make([]float64, 0, 2) + + start := (beforeThen - fiveMinMs) // from - step + + // Datapoints(ts -> val): + // 0 -> 1 + // 450000 -> 2 + // 600000 -> 3 + // + // the selection range logic is (start, end] so we expect the + // second window of 0 to 300000 to be empty + // + // 0 -> range -30000 to 0, ts: 0, val: 1 + // 1 -> range 0 to 300000, val: empty + // 2 -> range 30000 to 610000, val: 5 (includes last 2 datapoints) + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, start <= ts && ts < now+tenSecMs) + + if i == 1 { + require.Equal(t, 0, len(r.SampleVector())) + } else { + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + resultTs = append(resultTs, r.SampleVector()[0].T) + resultVals = append(resultVals, r.SampleVector()[0].F) + require.Equal(t, group, r.SampleVector()[0].Metric) + } + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + // Because of the 5m step and 5m lookback, the first window will be + // -300000 to 0, the second 0 to 300000, and the third 300000 to 600000. + // We don't expect the 2nd to have any data, so below we check results of the 1st and 3rd. + require.Equal(t, beforeThen, resultTs[0]) + require.Equal(t, beforeThen+fiveMinMs+fiveMinMs, resultTs[1]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(5), resultVals[1]) + }) + + t.Run("bytes", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+1e4, fiveMinMs, `sum by (level)(bytes_over_time({foo="bar"}[5m]))`) + + resultTs := make([]int64, 0, 2) + resultVals := make([]float64, 0, 2) + + start := (beforeThen - fiveMinMs) // from - step + + // Datapoints(ts -> val): + // 0 -> 1 + // 450000 -> 3 + // 600000 -> 5 + // + // the selection range logic is (start, end] so we expect the + // second window of 0 to 300000 to be empty + // + // 0 -> range -30000 to 0, ts: 0, val: 1 + // 1 -> range 0 to 300000, val: empty + // 2 -> range 30000 to 610000, val: 8 (includes last 2 datapoints) + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, start <= ts && ts <= now) + + if i == 1 { + require.Equal(t, 0, len(r.SampleVector())) + } else { + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + resultTs = append(resultTs, r.SampleVector()[0].T) + resultVals = append(resultVals, r.SampleVector()[0].F) + require.Equal(t, group, r.SampleVector()[0].Metric) + } + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + // Because of the 5m step and 5m lookback, the first window will be + // -300000 to 0, the second 0 to 300000, and the third 300000 to 600000. + // We don't expect the 2nd to have any data, so below we check results of the 1st and 3rd. + require.Equal(t, now-600000, resultTs[0]) + require.Equal(t, now, resultTs[1]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(8), resultVals[1]) + }) + }) + }) + + t.Run("without grouping", func(t *testing.T) { + t.Run("evenly aligned, non-overlapping timestamps", func(t *testing.T) { + now := int64(600000) // 10 minutes after 0 + then := now - fiveMinMs // 300000, 5m before now + beforeThen := then - fiveMinMs // 0, 5m before then + chks := chunks(now, then, beforeThen) + + t.Run("count", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+tenSecMs, fiveMinMs, `count_over_time({foo="bar"}[5m])`) + + resultTs := make([]int64, 3) + resultVals := make([]float64, 3) + + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, then-fiveMinMs <= ts && ts <= now) + + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + samples := r.SampleVector() + resultTs[i] = samples[0].T + resultVals[i] = samples[0].F + + require.Equal(t, stream, samples[0].Metric) + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + require.Equal(t, beforeThen, resultTs[0]) + require.Equal(t, then, resultTs[1]) + require.Equal(t, now, resultTs[2]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(2), resultVals[1]) + require.Equal(t, float64(3), resultVals[2]) + }) + + t.Run("bytes", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+1e4, fiveMinMs, `bytes_over_time({foo="bar"}[5m])`) + + resultTs := make([]int64, 3) + resultVals := make([]float64, 3) + + start := beforeThen - fiveMinMs // from - step + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, start <= ts && ts < now+fiveMinMs) + + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + samples := r.SampleVector() + resultTs[i] = samples[0].T + resultVals[i] = samples[0].F + + require.Equal(t, stream, samples[0].Metric) + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + require.Equal(t, beforeThen, resultTs[0]) + require.Equal(t, then, resultTs[1]) + require.Equal(t, now, resultTs[2]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(3), resultVals[1]) + require.Equal(t, float64(5), resultVals[2]) + }) + }) + + t.Run("evenly aligned, overlapping timestamps", func(t *testing.T) { + now := int64(150000 + 450000) // 600000 + then := now - 150000 // 450000 -- 2.5m before now + beforeThen := then - 450000 // 0 -- 7.5m before then, 10m before now + chks := chunks(now, then, beforeThen) + + t.Run("count", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+tenSecMs, fiveMinMs, `count_over_time({foo="bar"}[5m])`) + + resultTs := make([]int64, 0, 2) + resultVals := make([]float64, 0, 2) + + start := beforeThen - fiveMinMs // from - step + // Datapoints(ts -> val): + // 0 -> 1 + // 450000 -> 2 + // 600000 -> 3 + // + // the selection range logic is (start, end] so we expect the + // second window of 0 to 300000 to be empty + // + // 0 -> range -30000 to 0, ts: 0, val: 1 + // 1 -> range 0 to 300000, val: empty + // 2 -> range 30000 to 610000, val: 5 (includes last 2 datapoints) + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, start <= ts && ts < now+tenSecMs) + + if i == 1 { + require.Equal(t, 0, len(r.SampleVector())) + } else { + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + resultTs = append(resultTs, r.SampleVector()[0].T) + resultVals = append(resultVals, r.SampleVector()[0].F) + require.Equal(t, stream, r.SampleVector()[0].Metric) + } + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + // Because of the 5m step and 5m lookback, the first window will be + // -300000 to 0, the second 0 to 300000, and the third 300000 to 600000. + // We don't expect the 2nd to have any data, so below we check results of the 1st and 3rd. + require.Equal(t, now-600000, resultTs[0]) + require.Equal(t, now, resultTs[1]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(5), resultVals[1]) + }) + + t.Run("bytes", func(t *testing.T) { + evaluator := setup(chks, beforeThen, now+tenSecMs, fiveMinMs, `bytes_over_time({foo="bar"}[5m])`) + + resultTs := make([]int64, 0, 2) + resultVals := make([]float64, 0, 2) + + start := beforeThen - fiveMinMs // from - step + // Datapoints(ts -> val): + // 0 -> 1 + // 450000 -> 3 + // 600000 -> 5 + // + // the selection range logic is (start, end] so we expect the + // second window of 0 to 300000 to be empty + // + // 0 -> range -30000 to 0, ts: 0, val: 1 + // 1 -> range 0 to 300000, val: empty + // 2 -> range 30000 to 610000, val: 8 (includes last 2 datapoints) + for i := 0; i < 3; i++ { + ok, ts, r := evaluator.Next() + require.True(t, ok) + require.True(t, start <= ts && ts < now+tenSecMs) + + if i == 1 { + require.Equal(t, 0, len(r.SampleVector())) + } else { + // The []promqlSample in the Vector is reused, so we need to copy the value and timestamp. + resultTs = append(resultTs, r.SampleVector()[0].T) + resultVals = append(resultVals, r.SampleVector()[0].F) + require.Equal(t, stream, r.SampleVector()[0].Metric) + } + } + + ok, _, _ := evaluator.Next() + require.False(t, ok) + + // Because of the 5m step and 5m lookback, the first window will be + // -300000 to 0, the second 0 to 300000, and the third 300000 to 600000. + // We don't expect the 2nd to have any data, so below we check results of the 1st and 3rd. + require.Equal(t, now-600000, resultTs[0]) + require.Equal(t, now, resultTs[1]) + + require.Equal(t, float64(1), resultVals[0]) + require.Equal(t, float64(8), resultVals[1]) + }) + }) + }) +} diff --git a/pkg/pattern/ring_client.go b/pkg/pattern/ring_client.go index 3ceaf481a3b9..0d49cfe42379 100644 --- a/pkg/pattern/ring_client.go +++ b/pkg/pattern/ring_client.go @@ -13,7 +13,13 @@ import ( "github.com/grafana/loki/v3/pkg/pattern/clientpool" ) -type RingClient struct { +type RingClient interface { + services.Service + Ring() ring.ReadRing + Pool() *ring_client.Pool +} + +type ringClient struct { cfg Config logger log.Logger @@ -29,10 +35,10 @@ func NewRingClient( metricsNamespace string, registerer prometheus.Registerer, logger log.Logger, -) (*RingClient, error) { +) (RingClient, error) { var err error registerer = prometheus.WrapRegistererWithPrefix(metricsNamespace+"_", registerer) - ringClient := &RingClient{ + ringClient := &ringClient{ logger: log.With(logger, "component", "pattern-ring-client"), cfg: cfg, } @@ -59,19 +65,55 @@ func NewRingClient( return ringClient, nil } -func (q *RingClient) starting(ctx context.Context) error { - return services.StartManagerAndAwaitHealthy(ctx, q.subservices) +func (r *ringClient) starting(ctx context.Context) error { + return services.StartManagerAndAwaitHealthy(ctx, r.subservices) } -func (q *RingClient) running(ctx context.Context) error { +func (r *ringClient) running(ctx context.Context) error { select { case <-ctx.Done(): return nil - case err := <-q.subservicesWatcher.Chan(): + case err := <-r.subservicesWatcher.Chan(): return fmt.Errorf("pattern tee subservices failed: %w", err) } } -func (q *RingClient) stopping(_ error) error { - return services.StopManagerAndAwaitStopped(context.Background(), q.subservices) +func (r *ringClient) stopping(_ error) error { + return services.StopManagerAndAwaitStopped(context.Background(), r.subservices) +} + +func (r *ringClient) Ring() ring.ReadRing { + return r.ring +} + +func (r *ringClient) Pool() *ring_client.Pool { + return r.pool +} + +func (r *ringClient) StartAsync(ctx context.Context) error { + return r.ring.StartAsync(ctx) +} + +func (r *ringClient) AwaitRunning(ctx context.Context) error { + return r.ring.AwaitRunning(ctx) +} + +func (r *ringClient) StopAsync() { + r.ring.StopAsync() +} + +func (r *ringClient) AwaitTerminated(ctx context.Context) error { + return r.ring.AwaitTerminated(ctx) +} + +func (r *ringClient) FailureCase() error { + return r.ring.FailureCase() +} + +func (r *ringClient) State() services.State { + return r.ring.State() +} + +func (r *ringClient) AddListener(listener services.Listener) { + r.ring.AddListener(listener) } diff --git a/pkg/pattern/stream.go b/pkg/pattern/stream.go index f3aad280250d..52f539a5f7b0 100644 --- a/pkg/pattern/stream.go +++ b/pkg/pattern/stream.go @@ -2,15 +2,23 @@ package pattern import ( "context" + "math" "sync" "time" "github.com/grafana/loki/v3/pkg/logproto" + "github.com/grafana/loki/v3/pkg/logql" + "github.com/grafana/loki/v3/pkg/logql/syntax" + "github.com/grafana/loki/v3/pkg/logqlmodel" "github.com/grafana/loki/v3/pkg/pattern/drain" - "github.com/grafana/loki/v3/pkg/pattern/iter" + "github.com/grafana/loki/v3/pkg/pattern/metric" + + loki_iter "github.com/grafana/loki/v3/pkg/iter" + pattern_iter "github.com/grafana/loki/v3/pkg/pattern/iter" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/promql" ) type stream struct { @@ -21,6 +29,11 @@ type stream struct { patterns *drain.Drain mtx sync.Mutex + aggregateMetrics bool + metrics *metric.Chunks + + evaluator metric.SampleEvaluatorFactory + lastTs int64 } @@ -28,8 +41,9 @@ func newStream( fp model.Fingerprint, labels labels.Labels, metrics *ingesterMetrics, + aggregateMetrics bool, ) (*stream, error) { - return &stream{ + stream := &stream{ fp: fp, labels: labels, labelsString: labels.String(), @@ -38,7 +52,16 @@ func newStream( PatternsEvictedTotal: metrics.patternsDiscardedTotal, PatternsDetectedTotal: metrics.patternsDetectedTotal, }), - }, nil + aggregateMetrics: aggregateMetrics, + } + + if aggregateMetrics { + chunks := metric.NewChunks(labels) + stream.metrics = chunks + stream.evaluator = metric.NewDefaultEvaluatorFactory(chunks) + } + + return stream, nil } func (s *stream) Push( @@ -48,23 +71,32 @@ func (s *stream) Push( s.mtx.Lock() defer s.mtx.Unlock() + bytes := float64(0) + count := float64(len(entries)) for _, entry := range entries { if entry.Timestamp.UnixNano() < s.lastTs { continue } + + bytes += float64(len(entry.Line)) + s.lastTs = entry.Timestamp.UnixNano() s.patterns.Train(entry.Line, entry.Timestamp.UnixNano()) } + + if s.aggregateMetrics && s.metrics != nil { + s.metrics.Observe(bytes, count, model.TimeFromUnixNano(s.lastTs)) + } return nil } -func (s *stream) Iterator(_ context.Context, from, through, step model.Time) (iter.Iterator, error) { +func (s *stream) Iterator(_ context.Context, from, through, step model.Time) (pattern_iter.Iterator, error) { // todo we should improve locking. s.mtx.Lock() defer s.mtx.Unlock() clusters := s.patterns.Clusters() - iters := make([]iter.Iterator, 0, len(clusters)) + iters := make([]pattern_iter.Iterator, 0, len(clusters)) for _, cluster := range clusters { if cluster.String() == "" { @@ -72,7 +104,115 @@ func (s *stream) Iterator(_ context.Context, from, through, step model.Time) (it } iters = append(iters, cluster.Iterator(from, through, step)) } - return iter.NewMerge(iters...), nil + return pattern_iter.NewMerge(iters...), nil +} + +func (s *stream) SampleIterator( + ctx context.Context, + expr syntax.SampleExpr, + from, through, step model.Time, +) (loki_iter.SampleIterator, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + stepEvaluator, err := s.evaluator.NewStepEvaluator( + ctx, + s.evaluator, + expr, + from, + through, + step, + ) + if err != nil { + return nil, err + } + + next, ts, r := stepEvaluator.Next() + if stepEvaluator.Error() != nil { + return nil, stepEvaluator.Error() + } + + // TODO(twhitney): actually get max series from limits + // this is only 1 series since we're already on a stream + // this this limit needs to also be enforced higher up + maxSeries := 1000 + matrix, err := s.JoinSampleVectors( + next, + ts, + r, + stepEvaluator, + maxSeries, + from, through, step) + if err != nil { + return nil, err + } + + return loki_iter.NewMultiSeriesIterator(matrix), nil +} + +func (s *stream) JoinSampleVectors( + next bool, + ts int64, + r logql.StepResult, + stepEvaluator logql.StepEvaluator, + maxSeries int, + from, through, step model.Time, +) ([]logproto.Series, error) { + stepCount := int(math.Ceil(float64(through.Sub(from).Nanoseconds()) / float64(step.UnixNano()))) + if stepCount <= 0 { + stepCount = 1 + } + + vec := promql.Vector{} + if next { + vec = r.SampleVector() + } + + // fail fast for the first step or instant query + if len(vec) > maxSeries { + return nil, logqlmodel.NewSeriesLimitError(maxSeries) + } + + series := map[uint64]*logproto.Series{} + + // step evaluator logic is slightly different than the normal contract in Loki + // when evaluating a selection range, it's counts datapoints within (start, end] + // so an additional condition of ts < through is needed to make sure this loop + // doesn't go beyond the through time. the contract for Loki queries is [start, end), + // and the samples to evaluate are selected based on [start, end) so the last result + // is likely incorrect anyway + for next && ts < int64(through) { + vec = r.SampleVector() + for _, p := range vec { + hash := p.Metric.Hash() + s, ok := series[hash] + if !ok { + s = &logproto.Series{ + Labels: p.Metric.String(), + Samples: make([]logproto.Sample, 0, stepCount), + StreamHash: hash, + } + series[hash] = s + } + + s.Samples = append(s.Samples, logproto.Sample{ + Timestamp: ts * 1e6, // convert milliseconds to nanoseconds + Value: p.F, + }) + } + + next, ts, r = stepEvaluator.Next() + if stepEvaluator.Error() != nil { + return nil, stepEvaluator.Error() + } + } + + matrix := make([]logproto.Series, 0, len(series)) + for _, s := range series { + matrix = append(matrix, *s) + } + + return matrix, stepEvaluator.Error() } func (s *stream) prune(olderThan time.Duration) bool { diff --git a/pkg/pattern/stream_test.go b/pkg/pattern/stream_test.go index f2218816b111..65da8dc497a5 100644 --- a/pkg/pattern/stream_test.go +++ b/pkg/pattern/stream_test.go @@ -16,7 +16,7 @@ import ( func TestAddStream(t *testing.T) { lbs := labels.New(labels.Label{Name: "test", Value: "test"}) - stream, err := newStream(model.Fingerprint(lbs.Hash()), lbs, newIngesterMetrics(nil, "test")) + stream, err := newStream(model.Fingerprint(lbs.Hash()), lbs, newIngesterMetrics(nil, "test"), false) require.NoError(t, err) err = stream.Push(context.Background(), []push.Entry{ @@ -44,7 +44,12 @@ func TestAddStream(t *testing.T) { func TestPruneStream(t *testing.T) { lbs := labels.New(labels.Label{Name: "test", Value: "test"}) - stream, err := newStream(model.Fingerprint(lbs.Hash()), lbs, newIngesterMetrics(nil, "test")) + stream, err := newStream( + model.Fingerprint(lbs.Hash()), + lbs, + newIngesterMetrics(nil, "test"), + false, + ) require.NoError(t, err) err = stream.Push(context.Background(), []push.Entry{ diff --git a/pkg/pattern/tee.go b/pkg/pattern/tee.go index 70fb37e1b692..04d2bf7595fc 100644 --- a/pkg/pattern/tee.go +++ b/pkg/pattern/tee.go @@ -18,14 +18,14 @@ import ( type Tee struct { cfg Config logger log.Logger - ringClient *RingClient + ringClient RingClient ingesterAppends *prometheus.CounterVec } func NewTee( cfg Config, - ringClient *RingClient, + ringClient RingClient, metricsNamespace string, registerer prometheus.Registerer, logger log.Logger, @@ -58,7 +58,7 @@ func (t *Tee) Duplicate(tenant string, streams []distributor.KeyedStream) { func (t *Tee) sendStream(tenant string, stream distributor.KeyedStream) error { var descs [1]ring.InstanceDesc - replicationSet, err := t.ringClient.ring.Get(stream.HashKey, ring.WriteNoExtend, descs[:0], nil, nil) + replicationSet, err := t.ringClient.Ring().Get(stream.HashKey, ring.WriteNoExtend, descs[:0], nil, nil) if err != nil { return err } @@ -66,7 +66,7 @@ func (t *Tee) sendStream(tenant string, stream distributor.KeyedStream) error { return errors.New("no instances found") } addr := replicationSet.Instances[0].Addr - client, err := t.ringClient.pool.GetClientFor(addr) + client, err := t.ringClient.Pool().GetClientFor(addr) if err != nil { return err } diff --git a/pkg/querier/handler.go b/pkg/querier/handler.go index bb01a0e3754b..3fa77e1f5fb7 100644 --- a/pkg/querier/handler.go +++ b/pkg/querier/handler.go @@ -131,6 +131,14 @@ func (h *Handler) Do(ctx context.Context, req queryrangebase.Request) (queryrang } return &queryrange.DetectedLabelsResponse{Response: result}, nil + case *logproto.QuerySamplesRequest: + result, err := h.api.SamplesHandler(ctx, concrete) + if err != nil { + return nil, err + } + return &queryrange.QuerySamplesResponse{ + Response: result, + }, nil default: return nil, fmt.Errorf("unsupported query type %T", req) } diff --git a/pkg/querier/http.go b/pkg/querier/http.go index d4e629153203..021cbbfe7ea4 100644 --- a/pkg/querier/http.go +++ b/pkg/querier/http.go @@ -406,6 +406,19 @@ func (q *QuerierAPI) PatternsHandler(ctx context.Context, req *logproto.QueryPat return resp, nil } +func (q *QuerierAPI) SamplesHandler(ctx context.Context, req *logproto.QuerySamplesRequest) (*logproto.QuerySamplesResponse, error) { + resp, err := q.querier.SelectMetricSamples(ctx, req) + if err != nil { + return nil, err + } + if resp == nil { // Some stores don't implement this + return &logproto.QuerySamplesResponse{ + Series: []logproto.Series{}, + }, nil + } + return resp, nil +} + func (q *QuerierAPI) validateMaxEntriesLimits(ctx context.Context, expr syntax.Expr, limit uint32) error { tenantIDs, err := tenant.TenantIDs(ctx) if err != nil { diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index f2fe80566b46..905124fb7c30 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -52,9 +52,7 @@ const ( tailerWaitEntryThrottle = time.Second / 2 ) -var ( - nowFunc = func() time.Time { return time.Now() } -) +var nowFunc = func() time.Time { return time.Now() } type interval struct { start, end time.Time @@ -107,6 +105,7 @@ type Querier interface { DetectedFields(ctx context.Context, req *logproto.DetectedFieldsRequest) (*logproto.DetectedFieldsResponse, error) Patterns(ctx context.Context, req *logproto.QueryPatternsRequest) (*logproto.QueryPatternsResponse, error) DetectedLabels(ctx context.Context, req *logproto.DetectedLabelsRequest) (*logproto.DetectedLabelsResponse, error) + SelectMetricSamples(ctx context.Context, req *logproto.QuerySamplesRequest) (*logproto.QuerySamplesResponse, error) } type Limits querier_limits.Limits @@ -431,7 +430,7 @@ func (q *SingleTenantQuerier) Label(ctx context.Context, req *logproto.LabelRequ if req.Values { storeValues, err = q.store.LabelValuesForMetricName(ctx, userID, from, through, "logs", req.Name, matchers...) } else { - storeValues, err = q.store.LabelNamesForMetricName(ctx, userID, from, through, "logs") + storeValues, err = q.store.LabelNamesForMetricName(ctx, userID, from, through, "logs", matchers...) } return err }) @@ -1036,6 +1035,7 @@ func countLabelsAndCardinality(storeLabelsMap map[string][]string, ingesterLabel type PatterQuerier interface { Patterns(ctx context.Context, req *logproto.QueryPatternsRequest) (*logproto.QueryPatternsResponse, error) + Samples(ctx context.Context, req *logproto.QuerySamplesRequest) (*logproto.QuerySamplesResponse, error) } func (q *SingleTenantQuerier) WithPatternQuerier(pq PatterQuerier) { @@ -1047,6 +1047,22 @@ func (q *SingleTenantQuerier) Patterns(ctx context.Context, req *logproto.QueryP return nil, httpgrpc.Errorf(http.StatusNotFound, "") } res, err := q.patternQuerier.Patterns(ctx, req) + if err != nil { + return nil, httpgrpc.Errorf(http.StatusBadRequest, err.Error()) + } + + return res, err +} + +func (q *SingleTenantQuerier) SelectMetricSamples(ctx context.Context, req *logproto.QuerySamplesRequest) (*logproto.QuerySamplesResponse, error) { + if q.patternQuerier == nil { + return nil, httpgrpc.Errorf(http.StatusNotFound, "") + } + res, err := q.patternQuerier.Samples(ctx, req) + if err != nil { + return nil, httpgrpc.Errorf(http.StatusBadRequest, err.Error()) + } + return res, err } diff --git a/pkg/querier/querier_mock_test.go b/pkg/querier/querier_mock_test.go index 51e4a6a9d8dd..296694fee5ff 100644 --- a/pkg/querier/querier_mock_test.go +++ b/pkg/querier/querier_mock_test.go @@ -352,7 +352,7 @@ func (s *storeMock) LabelValuesForMetricName(ctx context.Context, userID string, return args.Get(0).([]string), args.Error(1) } -func (s *storeMock) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (s *storeMock) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, _ ...*labels.Matcher) ([]string, error) { args := s.Called(ctx, userID, from, through, metricName) return args.Get(0).([]string), args.Error(1) } @@ -626,6 +626,21 @@ func (q *querierMock) DetectedLabels(ctx context.Context, req *logproto.Detected return resp.(*logproto.DetectedLabelsResponse), err } +func (q *querierMock) SelectMetricSamples( + ctx context.Context, + req *logproto.QuerySamplesRequest, +) (*logproto.QuerySamplesResponse, error) { + args := q.MethodCalled("SelectMetricSamples", ctx, req) + + resp := args.Get(0) + err := args.Error(1) + if resp == nil { + return nil, err + } + + return resp.(*logproto.QuerySamplesResponse), err +} + type engineMock struct { util.ExtendedMock } diff --git a/pkg/querier/queryrange/codec.go b/pkg/querier/queryrange/codec.go index 7bab6f6c5d05..d39f678aa2f1 100644 --- a/pkg/querier/queryrange/codec.go +++ b/pkg/querier/queryrange/codec.go @@ -459,6 +459,12 @@ func (Codec) DecodeRequest(_ context.Context, r *http.Request, _ []string) (quer DetectedLabelsRequest: *req, path: r.URL.Path, }, nil + case SamplesQueryOp: + req, err := loghttp.ParseSamplesQuery(r) + if err != nil { + return nil, httpgrpc.Errorf(http.StatusBadRequest, err.Error()) + } + return req, nil default: return nil, httpgrpc.Errorf(http.StatusNotFound, fmt.Sprintf("unknown request path: %s", r.URL.Path)) } @@ -644,6 +650,12 @@ func (Codec) DecodeHTTPGrpcRequest(ctx context.Context, r *httpgrpc.HTTPRequest) DetectedLabelsRequest: *req, path: httpReq.URL.Path, }, ctx, err + case SamplesQueryOp: + req, err := loghttp.ParseSamplesQuery(httpReq) + if err != nil { + return nil, ctx, httpgrpc.Errorf(http.StatusBadRequest, err.Error()) + } + return req, ctx, nil default: return nil, ctx, httpgrpc.Errorf(http.StatusBadRequest, fmt.Sprintf("unknown request path in HTTP gRPC decode: %s", r.Url)) } @@ -975,6 +987,27 @@ func (c Codec) EncodeRequest(ctx context.Context, r queryrangebase.Request) (*ht Header: header, } + return req.WithContext(ctx), nil + case *logproto.QuerySamplesRequest: + params := url.Values{ + "query": []string{request.GetQuery()}, + "start": []string{fmt.Sprintf("%d", request.Start.UnixNano())}, + "end": []string{fmt.Sprintf("%d", request.End.UnixNano())}, + "step": []string{fmt.Sprintf("%d", request.GetStep())}, + } + + u := &url.URL{ + Path: "/loki/api/v1/explore/query_range", + RawQuery: params.Encode(), + } + req := &http.Request{ + Method: "GET", + RequestURI: u.String(), // This is what the httpgrpc code looks at. + URL: u, + Body: http.NoBody, + Header: header, + } + return req.WithContext(ctx), nil default: return nil, httpgrpc.Errorf(http.StatusInternalServerError, fmt.Sprintf("invalid request format, got (%T)", r)) @@ -1007,6 +1040,8 @@ func (c Codec) Path(r queryrangebase.Request) string { return "/loki/api/v1/patterns" case *DetectedLabelsRequest: return "/loki/api/v1/detected_labels" + case *logproto.QuerySamplesRequest: + return "/loki/api/v1/explore/query_range" } return "other" @@ -1134,6 +1169,15 @@ func decodeResponseJSONFrom(buf []byte, req queryrangebase.Request, headers http Response: &resp, Headers: httpResponseHeadersToPromResponseHeaders(headers), }, nil + case *logproto.QuerySamplesRequest: + var resp logproto.QuerySamplesResponse + if err := json.Unmarshal(buf, &resp); err != nil { + return nil, httpgrpc.Errorf(http.StatusInternalServerError, "error decoding response: %v", err) + } + return &QuerySamplesResponse{ + Response: &resp, + Headers: httpResponseHeadersToPromResponseHeaders(headers), + }, nil default: var resp loghttp.QueryResponse if err := resp.UnmarshalJSON(buf); err != nil { @@ -1364,6 +1408,10 @@ func encodeResponseJSONTo(version loghttp.Version, res queryrangebase.Response, if err := marshal.WriteDetectedLabelsResponseJSON(response.Response, w); err != nil { return err } + case *QuerySamplesResponse: + if err := marshal.WriteQuerySamplesResponseJSON(response.Response, w); err != nil { + return err + } default: return httpgrpc.Errorf(http.StatusInternalServerError, fmt.Sprintf("invalid response format, got (%T)", res)) } diff --git a/pkg/querier/queryrange/codec_test.go b/pkg/querier/queryrange/codec_test.go index 136379292238..af047d8e84e1 100644 --- a/pkg/querier/queryrange/codec_test.go +++ b/pkg/querier/queryrange/codec_test.go @@ -115,8 +115,8 @@ func Test_codec_EncodeDecodeRequest(t *testing.T) { }, false}, {"labels", func() (*http.Request, error) { return http.NewRequest(http.MethodGet, - fmt.Sprintf(`/label?start=%d&end=%d`, start.UnixNano(), end.UnixNano()), nil) - }, NewLabelRequest(start, end, "", "", "/label"), + fmt.Sprintf(`/label?start=%d&end=%d&query={foo="bar"}`, start.UnixNano(), end.UnixNano()), nil) + }, NewLabelRequest(start, end, `{foo="bar"}`, "", "/label"), false}, {"label_values", func() (*http.Request, error) { req, err := http.NewRequest(http.MethodGet, @@ -875,22 +875,26 @@ func Test_codec_series_EncodeRequest(t *testing.T) { func Test_codec_labels_EncodeRequest(t *testing.T) { ctx := user.InjectOrgID(context.Background(), "1") - toEncode := NewLabelRequest(start, end, "", "", "/loki/api/v1/labels") + + // Test labels endpoint + toEncode := NewLabelRequest(start, end, `{foo="bar"}`, "", "/loki/api/v1/labels") got, err := DefaultCodec.EncodeRequest(ctx, toEncode) require.NoError(t, err) require.Equal(t, ctx, got.Context()) require.Equal(t, "/loki/api/v1/labels", got.URL.Path) require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) + require.Equal(t, `{foo="bar"}`, got.URL.Query().Get("query")) // testing a full roundtrip req, err := DefaultCodec.DecodeRequest(context.TODO(), got, nil) require.NoError(t, err) require.Equal(t, toEncode.Start, req.(*LabelRequest).Start) require.Equal(t, toEncode.End, req.(*LabelRequest).End) + require.Equal(t, toEncode.Query, req.(*LabelRequest).Query) require.Equal(t, "/loki/api/v1/labels", req.(*LabelRequest).Path()) - // Test labels values endpoint + // Test label values endpoint toEncode = NewLabelRequest(start, end, `{foo="bar"}`, "__name__", "/loki/api/v1/label/__name__/values") got, err = DefaultCodec.EncodeRequest(ctx, toEncode) require.NoError(t, err) @@ -912,21 +916,43 @@ func Test_codec_labels_EncodeRequest(t *testing.T) { func Test_codec_labels_DecodeRequest(t *testing.T) { ctx := user.InjectOrgID(context.Background(), "1") - u, err := url.Parse(`/loki/api/v1/label/__name__/values?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) + + // Test labels endpoint + u, err := url.Parse(`/loki/api/v1/labels?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) require.NoError(t, err) r := &http.Request{URL: u} - r = mux.SetURLVars(r, map[string]string{"name": "__name__"}) req, err := DefaultCodec.DecodeRequest(context.TODO(), r, nil) require.NoError(t, err) require.Equal(t, start, *req.(*LabelRequest).Start) require.Equal(t, end, *req.(*LabelRequest).End) require.Equal(t, `{foo="bar"}`, req.(*LabelRequest).Query) - require.Equal(t, "/loki/api/v1/label/__name__/values", req.(*LabelRequest).Path()) + require.Equal(t, "/loki/api/v1/labels", req.(*LabelRequest).Path()) got, err := DefaultCodec.EncodeRequest(ctx, req) require.NoError(t, err) require.Equal(t, ctx, got.Context()) + require.Equal(t, "/loki/api/v1/labels", got.URL.Path) + require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) + require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) + require.Equal(t, `{foo="bar"}`, got.URL.Query().Get("query")) + + // Test label values endpoint + u, err = url.Parse(`/loki/api/v1/label/__name__/values?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) + require.NoError(t, err) + + r = &http.Request{URL: u} + r = mux.SetURLVars(r, map[string]string{"name": "__name__"}) + req, err = DefaultCodec.DecodeRequest(context.TODO(), r, nil) + require.NoError(t, err) + require.Equal(t, start, *req.(*LabelRequest).Start) + require.Equal(t, end, *req.(*LabelRequest).End) + require.Equal(t, `{foo="bar"}`, req.(*LabelRequest).Query) + require.Equal(t, "/loki/api/v1/label/__name__/values", req.(*LabelRequest).Path()) + + got, err = DefaultCodec.EncodeRequest(ctx, req) + require.NoError(t, err) + require.Equal(t, ctx, got.Context()) require.Equal(t, "/loki/api/v1/label/__name__/values", got.URL.Path) require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) diff --git a/pkg/querier/queryrange/extensions.go b/pkg/querier/queryrange/extensions.go index ec5fa25ae308..2aa9842e7548 100644 --- a/pkg/querier/queryrange/extensions.go +++ b/pkg/querier/queryrange/extensions.go @@ -262,6 +262,15 @@ func (m *QueryPatternsResponse) GetHeaders() []*queryrangebase.PrometheusRespons return nil } +func (m *QueryPatternsResponse) SetHeader(name, value string) { + m.Headers = setHeader(m.Headers, name, value) +} + +func (m *QueryPatternsResponse) WithHeaders(h []queryrangebase.PrometheusResponseHeader) queryrangebase.Response { + m.Headers = h + return m +} + // GetHeaders returns the HTTP headers in the response. func (m *DetectedLabelsResponse) GetHeaders() []*queryrangebase.PrometheusResponseHeader { if m != nil { @@ -270,20 +279,30 @@ func (m *DetectedLabelsResponse) GetHeaders() []*queryrangebase.PrometheusRespon return nil } -func (m *QueryPatternsResponse) SetHeader(name, value string) { +func (m *DetectedLabelsResponse) SetHeader(name, value string) { m.Headers = setHeader(m.Headers, name, value) } -func (m *QueryPatternsResponse) WithHeaders(h []queryrangebase.PrometheusResponseHeader) queryrangebase.Response { +func (m *DetectedLabelsResponse) WithHeaders(h []queryrangebase.PrometheusResponseHeader) queryrangebase.Response { m.Headers = h return m } -func (m *DetectedLabelsResponse) SetHeader(name, value string) { +// GetHeaders returns the HTTP headers in the response. +func (m *QuerySamplesResponse) GetHeaders() []*queryrangebase.PrometheusResponseHeader { + if m != nil { + return convertPrometheusResponseHeadersToPointers(m.Headers) + } + return nil +} + +func (m *QuerySamplesResponse) SetHeader(name, value string) { m.Headers = setHeader(m.Headers, name, value) } -func (m *DetectedLabelsResponse) WithHeaders(h []queryrangebase.PrometheusResponseHeader) queryrangebase.Response { +func (m *QuerySamplesResponse) WithHeaders( + h []queryrangebase.PrometheusResponseHeader, +) queryrangebase.Response { m.Headers = h return m } diff --git a/pkg/querier/queryrange/labels_cache.go b/pkg/querier/queryrange/labels_cache.go index 5979a0c2f91e..2b946760aa1f 100644 --- a/pkg/querier/queryrange/labels_cache.go +++ b/pkg/querier/queryrange/labels_cache.go @@ -61,7 +61,7 @@ func (i cacheKeyLabels) GenerateCacheKey(ctx context.Context, userID string, r r return fmt.Sprintf("labelvalues:%s:%s:%s:%d:%d", userID, lr.GetName(), lr.GetQuery(), currentInterval, split) } - return fmt.Sprintf("labels:%s:%d:%d", userID, currentInterval, split) + return fmt.Sprintf("labels:%s:%s:%d:%d", userID, lr.GetQuery(), currentInterval, split) } type labelsExtractor struct{} diff --git a/pkg/querier/queryrange/labels_cache_test.go b/pkg/querier/queryrange/labels_cache_test.go index 22e967a11376..d73f90cb6309 100644 --- a/pkg/querier/queryrange/labels_cache_test.go +++ b/pkg/querier/queryrange/labels_cache_test.go @@ -43,13 +43,17 @@ func TestCacheKeyLabels_GenerateCacheKey(t *testing.T) { expectedInterval := testTime.UnixMilli() / time.Hour.Milliseconds() t.Run("labels", func(t *testing.T) { - require.Equal(t, fmt.Sprintf(`labels:fake:%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) + require.Equal(t, fmt.Sprintf(`labels:fake::%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) + + req.Query = `{cluster="eu-west1"}` + require.Equal(t, fmt.Sprintf(`labels:fake:{cluster="eu-west1"}:%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) }) t.Run("label values", func(t *testing.T) { req := req req.Name = "foo" req.Values = true + req.Query = `` require.Equal(t, fmt.Sprintf(`labelvalues:fake:foo::%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) req.Query = `{cluster="eu-west1"}` @@ -361,20 +365,20 @@ func TestLabelQueryCacheKey(t *testing.T) { t.Run(fmt.Sprintf("%s (values: %v)", tc.name, values), func(t *testing.T) { keyGen := cacheKeyLabels{tc.limits, nil} + const labelName = "foo" + const query = `{cluster="eu-west1"}` + r := &LabelRequest{ LabelRequest: logproto.LabelRequest{ Start: &tc.start, End: &tc.end, + Query: query, }, } - const labelName = "foo" - const query = `{cluster="eu-west1"}` - if values { r.LabelRequest.Values = true r.LabelRequest.Name = labelName - r.LabelRequest.Query = query } // we use regex here because cache key always refers to the current time to get the ingester query window, @@ -383,7 +387,7 @@ func TestLabelQueryCacheKey(t *testing.T) { if values { pattern = regexp.MustCompile(fmt.Sprintf(`labelvalues:%s:%s:%s:(\d+):%d`, tenantID, labelName, regexp.QuoteMeta(query), tc.expectedSplit)) } else { - pattern = regexp.MustCompile(fmt.Sprintf(`labels:%s:(\d+):%d`, tenantID, tc.expectedSplit)) + pattern = regexp.MustCompile(fmt.Sprintf(`labels:%s:%s:(\d+):%d`, tenantID, regexp.QuoteMeta(query), tc.expectedSplit)) } require.Regexp(t, pattern, keyGen.GenerateCacheKey(context.Background(), tenantID, r)) diff --git a/pkg/querier/queryrange/marshal.go b/pkg/querier/queryrange/marshal.go index b3920e00a666..7f81563ebdfb 100644 --- a/pkg/querier/queryrange/marshal.go +++ b/pkg/querier/queryrange/marshal.go @@ -403,6 +403,8 @@ func (Codec) QueryRequestWrap(ctx context.Context, r queryrangebase.Request) (*Q result.Request = &QueryRequest_DetectedLabels{DetectedLabels: &req.DetectedLabelsRequest} case *DetectedFieldsRequest: result.Request = &QueryRequest_DetectedFields{DetectedFields: &req.DetectedFieldsRequest} + case *logproto.QuerySamplesRequest: + result.Request = &QueryRequest_SamplesRequest{SamplesRequest: req} default: return nil, fmt.Errorf("unsupported request type while wrapping, got (%T)", r) } diff --git a/pkg/querier/queryrange/queryrange.pb.go b/pkg/querier/queryrange/queryrange.pb.go index ae2dddee539a..5db2c2ce0df6 100644 --- a/pkg/querier/queryrange/queryrange.pb.go +++ b/pkg/querier/queryrange/queryrange.pb.go @@ -1040,6 +1040,43 @@ func (m *DetectedLabelsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_DetectedLabelsResponse proto.InternalMessageInfo +type QuerySamplesResponse struct { + Response *github_com_grafana_loki_v3_pkg_logproto.QuerySamplesResponse `protobuf:"bytes,1,opt,name=response,proto3,customtype=github.com/grafana/loki/v3/pkg/logproto.QuerySamplesResponse" json:"response,omitempty"` + Headers []github_com_grafana_loki_v3_pkg_querier_queryrange_queryrangebase_definitions.PrometheusResponseHeader `protobuf:"bytes,2,rep,name=Headers,proto3,customtype=github.com/grafana/loki/v3/pkg/querier/queryrange/queryrangebase/definitions.PrometheusResponseHeader" json:"-"` +} + +func (m *QuerySamplesResponse) Reset() { *m = QuerySamplesResponse{} } +func (*QuerySamplesResponse) ProtoMessage() {} +func (*QuerySamplesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_51b9d53b40d11902, []int{17} +} +func (m *QuerySamplesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySamplesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySamplesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySamplesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySamplesResponse.Merge(m, src) +} +func (m *QuerySamplesResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySamplesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySamplesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySamplesResponse proto.InternalMessageInfo + type QueryResponse struct { Status *rpc.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` // Types that are valid to be assigned to Response: @@ -1055,13 +1092,14 @@ type QueryResponse struct { // *QueryResponse_DetectedFields // *QueryResponse_PatternsResponse // *QueryResponse_DetectedLabels + // *QueryResponse_SamplesResponse Response isQueryResponse_Response `protobuf_oneof:"response"` } func (m *QueryResponse) Reset() { *m = QueryResponse{} } func (*QueryResponse) ProtoMessage() {} func (*QueryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_51b9d53b40d11902, []int{17} + return fileDescriptor_51b9d53b40d11902, []int{18} } func (m *QueryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1133,6 +1171,9 @@ type QueryResponse_PatternsResponse struct { type QueryResponse_DetectedLabels struct { DetectedLabels *DetectedLabelsResponse `protobuf:"bytes,13,opt,name=detectedLabels,proto3,oneof"` } +type QueryResponse_SamplesResponse struct { + SamplesResponse *QuerySamplesResponse `protobuf:"bytes,14,opt,name=samplesResponse,proto3,oneof"` +} func (*QueryResponse_Series) isQueryResponse_Response() {} func (*QueryResponse_Labels) isQueryResponse_Response() {} @@ -1146,6 +1187,7 @@ func (*QueryResponse_ShardsResponse) isQueryResponse_Response() {} func (*QueryResponse_DetectedFields) isQueryResponse_Response() {} func (*QueryResponse_PatternsResponse) isQueryResponse_Response() {} func (*QueryResponse_DetectedLabels) isQueryResponse_Response() {} +func (*QueryResponse_SamplesResponse) isQueryResponse_Response() {} func (m *QueryResponse) GetResponse() isQueryResponse_Response { if m != nil { @@ -1245,6 +1287,13 @@ func (m *QueryResponse) GetDetectedLabels() *DetectedLabelsResponse { return nil } +func (m *QueryResponse) GetSamplesResponse() *QuerySamplesResponse { + if x, ok := m.GetResponse().(*QueryResponse_SamplesResponse); ok { + return x.SamplesResponse + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*QueryResponse) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -1260,6 +1309,7 @@ func (*QueryResponse) XXX_OneofWrappers() []interface{} { (*QueryResponse_DetectedFields)(nil), (*QueryResponse_PatternsResponse)(nil), (*QueryResponse_DetectedLabels)(nil), + (*QueryResponse_SamplesResponse)(nil), } } @@ -1275,6 +1325,7 @@ type QueryRequest struct { // *QueryRequest_DetectedFields // *QueryRequest_PatternsRequest // *QueryRequest_DetectedLabels + // *QueryRequest_SamplesRequest Request isQueryRequest_Request `protobuf_oneof:"request"` Metadata map[string]string `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -1282,7 +1333,7 @@ type QueryRequest struct { func (m *QueryRequest) Reset() { *m = QueryRequest{} } func (*QueryRequest) ProtoMessage() {} func (*QueryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_51b9d53b40d11902, []int{18} + return fileDescriptor_51b9d53b40d11902, []int{19} } func (m *QueryRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1348,6 +1399,9 @@ type QueryRequest_PatternsRequest struct { type QueryRequest_DetectedLabels struct { DetectedLabels *logproto.DetectedLabelsRequest `protobuf:"bytes,11,opt,name=detectedLabels,proto3,oneof"` } +type QueryRequest_SamplesRequest struct { + SamplesRequest *logproto.QuerySamplesRequest `protobuf:"bytes,12,opt,name=samplesRequest,proto3,oneof"` +} func (*QueryRequest_Series) isQueryRequest_Request() {} func (*QueryRequest_Labels) isQueryRequest_Request() {} @@ -1359,6 +1413,7 @@ func (*QueryRequest_ShardsRequest) isQueryRequest_Request() {} func (*QueryRequest_DetectedFields) isQueryRequest_Request() {} func (*QueryRequest_PatternsRequest) isQueryRequest_Request() {} func (*QueryRequest_DetectedLabels) isQueryRequest_Request() {} +func (*QueryRequest_SamplesRequest) isQueryRequest_Request() {} func (m *QueryRequest) GetRequest() isQueryRequest_Request { if m != nil { @@ -1437,6 +1492,13 @@ func (m *QueryRequest) GetDetectedLabels() *logproto.DetectedLabelsRequest { return nil } +func (m *QueryRequest) GetSamplesRequest() *logproto.QuerySamplesRequest { + if x, ok := m.GetRequest().(*QueryRequest_SamplesRequest); ok { + return x.SamplesRequest + } + return nil +} + func (m *QueryRequest) GetMetadata() map[string]string { if m != nil { return m.Metadata @@ -1457,6 +1519,7 @@ func (*QueryRequest) XXX_OneofWrappers() []interface{} { (*QueryRequest_DetectedFields)(nil), (*QueryRequest_PatternsRequest)(nil), (*QueryRequest_DetectedLabels)(nil), + (*QueryRequest_SamplesRequest)(nil), } } @@ -1478,6 +1541,7 @@ func init() { proto.RegisterType((*DetectedFieldsResponse)(nil), "queryrange.DetectedFieldsResponse") proto.RegisterType((*QueryPatternsResponse)(nil), "queryrange.QueryPatternsResponse") proto.RegisterType((*DetectedLabelsResponse)(nil), "queryrange.DetectedLabelsResponse") + proto.RegisterType((*QuerySamplesResponse)(nil), "queryrange.QuerySamplesResponse") proto.RegisterType((*QueryResponse)(nil), "queryrange.QueryResponse") proto.RegisterType((*QueryRequest)(nil), "queryrange.QueryRequest") proto.RegisterMapType((map[string]string)(nil), "queryrange.QueryRequest.MetadataEntry") @@ -1488,128 +1552,133 @@ func init() { } var fileDescriptor_51b9d53b40d11902 = []byte{ - // 1935 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcb, 0x6f, 0x23, 0x49, - 0x19, 0x77, 0xfb, 0x19, 0x7f, 0x79, 0x4c, 0xa8, 0x09, 0xd9, 0x26, 0x3b, 0xeb, 0x36, 0x96, 0xd8, - 0x0d, 0x08, 0xec, 0x1d, 0x67, 0x77, 0xd8, 0x0d, 0xc3, 0x68, 0xa7, 0x27, 0x33, 0x64, 0x86, 0x59, - 0x76, 0xb6, 0x13, 0x71, 0xe0, 0x82, 0x2a, 0x76, 0xc5, 0x6e, 0x62, 0x77, 0xf7, 0x74, 0x97, 0x33, - 0x13, 0x09, 0xa1, 0xfd, 0x07, 0x56, 0xec, 0x5f, 0x81, 0xb8, 0x71, 0xe1, 0xc4, 0x89, 0xe3, 0xee, - 0x01, 0x69, 0x8e, 0x2b, 0x4b, 0x34, 0x8c, 0x07, 0x21, 0x94, 0xd3, 0x4a, 0x5c, 0x39, 0xa0, 0x7a, - 0x74, 0xbb, 0xca, 0x76, 0x18, 0x27, 0x20, 0xa4, 0xc0, 0x5e, 0x92, 0x7a, 0x7c, 0xbf, 0xea, 0xaa, - 0xdf, 0xf7, 0xfb, 0xbe, 0x7a, 0x18, 0xde, 0x08, 0x8e, 0x3a, 0x8d, 0xc7, 0x03, 0x12, 0xba, 0x24, - 0xe4, 0xff, 0x4f, 0x42, 0xec, 0x75, 0x88, 0x52, 0xac, 0x07, 0xa1, 0x4f, 0x7d, 0x04, 0xe3, 0x96, - 0x8d, 0x66, 0xc7, 0xa5, 0xdd, 0xc1, 0x41, 0xbd, 0xe5, 0xf7, 0x1b, 0x1d, 0xbf, 0xe3, 0x37, 0x3a, - 0xbe, 0xdf, 0xe9, 0x11, 0x1c, 0xb8, 0x91, 0x2c, 0x36, 0xc2, 0xa0, 0xd5, 0x88, 0x28, 0xa6, 0x83, - 0x48, 0xe0, 0x37, 0xd6, 0x98, 0x21, 0x2f, 0x72, 0x88, 0x6c, 0xb5, 0xa4, 0x39, 0xaf, 0x1d, 0x0c, - 0x0e, 0x1b, 0xd4, 0xed, 0x93, 0x88, 0xe2, 0x7e, 0x90, 0x18, 0xb0, 0xf9, 0xf5, 0xfc, 0x8e, 0x40, - 0xba, 0x5e, 0x9b, 0x3c, 0xed, 0x60, 0x4a, 0x9e, 0xe0, 0x13, 0x69, 0xf0, 0xaa, 0x66, 0x90, 0x14, - 0x64, 0xe7, 0x86, 0xd6, 0x19, 0x60, 0x4a, 0x49, 0xe8, 0xc9, 0xbe, 0xaf, 0x69, 0x7d, 0xd1, 0x11, - 0xa1, 0xad, 0xae, 0xec, 0xaa, 0xca, 0xae, 0xc7, 0xbd, 0xbe, 0xdf, 0x26, 0x3d, 0xbe, 0x90, 0x48, - 0xfc, 0x95, 0x16, 0x57, 0x99, 0x45, 0x30, 0x88, 0xba, 0xfc, 0x8f, 0x6c, 0xbc, 0xf3, 0x52, 0x2e, - 0x0f, 0x70, 0x44, 0x1a, 0x6d, 0x72, 0xe8, 0x7a, 0x2e, 0x75, 0x7d, 0x2f, 0x52, 0xcb, 0x72, 0x90, - 0x1b, 0xf3, 0x0d, 0x32, 0xe9, 0x9f, 0x8d, 0x37, 0x19, 0x2e, 0xa2, 0x7e, 0x88, 0x3b, 0xa4, 0xd1, - 0xea, 0x0e, 0xbc, 0xa3, 0x46, 0x0b, 0xb7, 0xba, 0xa4, 0x11, 0x92, 0x68, 0xd0, 0xa3, 0x91, 0xa8, - 0xd0, 0x93, 0x80, 0xc8, 0x2f, 0xd5, 0x3e, 0xcb, 0xc3, 0xe2, 0x43, 0xff, 0xc8, 0x75, 0xc8, 0xe3, - 0x01, 0x89, 0x28, 0x5a, 0x83, 0x02, 0x1f, 0xd5, 0x34, 0xaa, 0xc6, 0x66, 0xd9, 0x11, 0x15, 0xd6, - 0xda, 0x73, 0xfb, 0x2e, 0x35, 0xb3, 0x55, 0x63, 0x73, 0xd9, 0x11, 0x15, 0x84, 0x20, 0x1f, 0x51, - 0x12, 0x98, 0xb9, 0xaa, 0xb1, 0x99, 0x73, 0x78, 0x19, 0x6d, 0xc0, 0x82, 0xeb, 0x51, 0x12, 0x1e, - 0xe3, 0x9e, 0x59, 0xe6, 0xed, 0x69, 0x1d, 0xdd, 0x82, 0x52, 0x44, 0x71, 0x48, 0xf7, 0x23, 0x33, - 0x5f, 0x35, 0x36, 0x17, 0x9b, 0x1b, 0x75, 0xe1, 0xf9, 0x7a, 0xe2, 0xf9, 0xfa, 0x7e, 0xe2, 0x79, - 0x7b, 0xe1, 0xd3, 0xd8, 0xca, 0x7c, 0xf2, 0x27, 0xcb, 0x70, 0x12, 0x10, 0xda, 0x86, 0x02, 0xf1, - 0xda, 0xfb, 0x91, 0x59, 0x38, 0x07, 0x5a, 0x40, 0xd0, 0x75, 0x28, 0xb7, 0xdd, 0x90, 0xb4, 0x18, - 0xcb, 0x66, 0xb1, 0x6a, 0x6c, 0xae, 0x34, 0xaf, 0xd6, 0x53, 0xa1, 0xec, 0x24, 0x5d, 0xce, 0xd8, - 0x8a, 0x2d, 0x2f, 0xc0, 0xb4, 0x6b, 0x96, 0x38, 0x13, 0xbc, 0x8c, 0x6a, 0x50, 0x8c, 0xba, 0x38, - 0x6c, 0x47, 0xe6, 0x42, 0x35, 0xb7, 0x59, 0xb6, 0xe1, 0x34, 0xb6, 0x64, 0x8b, 0x23, 0xff, 0xa3, - 0x9f, 0x42, 0x3e, 0xe8, 0x61, 0xcf, 0x04, 0x3e, 0xcb, 0xd5, 0xba, 0xe2, 0xa5, 0x47, 0x3d, 0xec, - 0xd9, 0xef, 0x0e, 0x63, 0xeb, 0x6d, 0x35, 0x78, 0x42, 0x7c, 0x88, 0x3d, 0xdc, 0xe8, 0xf9, 0x47, - 0x6e, 0xe3, 0x78, 0xab, 0xa1, 0xfa, 0x9e, 0x0d, 0x54, 0xff, 0x90, 0x0d, 0xc0, 0xa0, 0x0e, 0x1f, - 0x18, 0x3d, 0x80, 0x45, 0xe6, 0x63, 0x72, 0x87, 0x39, 0x38, 0x32, 0x17, 0xf9, 0x77, 0x5e, 0x19, - 0xaf, 0x86, 0xb7, 0x3b, 0xe4, 0xf0, 0x07, 0xa1, 0x3f, 0x08, 0xec, 0x2b, 0xa7, 0xb1, 0xa5, 0xda, - 0x3b, 0x6a, 0x05, 0x3d, 0x80, 0x15, 0x26, 0x0a, 0xd7, 0xeb, 0x7c, 0x10, 0x70, 0x05, 0x9a, 0x4b, - 0x7c, 0xb8, 0x6b, 0x75, 0x55, 0x32, 0xf5, 0x3b, 0x9a, 0x8d, 0x9d, 0x67, 0xf4, 0x3a, 0x13, 0xc8, - 0xda, 0x28, 0x07, 0x88, 0x69, 0xe9, 0xbe, 0x17, 0x51, 0xec, 0xd1, 0x8b, 0x48, 0xea, 0x26, 0x14, - 0x59, 0xf0, 0xef, 0x47, 0x5c, 0x54, 0xf3, 0xfa, 0x58, 0x62, 0x74, 0x27, 0xe7, 0xcf, 0xe5, 0xe4, - 0xc2, 0x4c, 0x27, 0x17, 0x5f, 0xea, 0xe4, 0xd2, 0x7f, 0xc9, 0xc9, 0x0b, 0xff, 0x59, 0x27, 0x97, - 0x2f, 0xec, 0x64, 0x13, 0xf2, 0x6c, 0x96, 0x68, 0x15, 0x72, 0x21, 0x7e, 0xc2, 0x7d, 0xba, 0xe4, - 0xb0, 0x62, 0x6d, 0x94, 0x87, 0x25, 0x91, 0x4a, 0xa2, 0xc0, 0xf7, 0x22, 0xc2, 0x78, 0xdc, 0xe3, - 0xd9, 0x5f, 0x78, 0x5e, 0xf2, 0xc8, 0x5b, 0x1c, 0xd9, 0x83, 0xde, 0x83, 0xfc, 0x0e, 0xa6, 0x98, - 0xab, 0x60, 0xb1, 0xb9, 0xa6, 0xf2, 0xc8, 0xc6, 0x62, 0x7d, 0xf6, 0x3a, 0x9b, 0xc8, 0x69, 0x6c, - 0xad, 0xb4, 0x31, 0xc5, 0xdf, 0xf6, 0xfb, 0x2e, 0x25, 0xfd, 0x80, 0x9e, 0x38, 0x1c, 0x89, 0xde, - 0x86, 0xf2, 0xdd, 0x30, 0xf4, 0xc3, 0xfd, 0x93, 0x80, 0x70, 0xd5, 0x94, 0xed, 0x57, 0x4e, 0x63, - 0xeb, 0x2a, 0x49, 0x1a, 0x15, 0xc4, 0xd8, 0x12, 0x7d, 0x13, 0x0a, 0xbc, 0xc2, 0x75, 0x52, 0xb6, - 0xaf, 0x9e, 0xc6, 0xd6, 0x15, 0x0e, 0x51, 0xcc, 0x85, 0x85, 0x2e, 0xab, 0xc2, 0x5c, 0xb2, 0x4a, - 0xd5, 0x5d, 0x54, 0xd5, 0x6d, 0x42, 0xe9, 0x98, 0x84, 0x11, 0x1b, 0xa6, 0xc4, 0xdb, 0x93, 0x2a, - 0xba, 0x0d, 0xc0, 0x88, 0x71, 0x23, 0xea, 0xb6, 0x12, 0x67, 0x2f, 0xd7, 0xc5, 0x66, 0xe3, 0x70, - 0x1f, 0xd9, 0x48, 0xb2, 0xa0, 0x18, 0x3a, 0x4a, 0x19, 0xfd, 0xc6, 0x80, 0xd2, 0x2e, 0xc1, 0x6d, - 0x12, 0x32, 0xf7, 0xe6, 0x36, 0x17, 0x9b, 0xdf, 0xa8, 0xab, 0x3b, 0xcb, 0xa3, 0xd0, 0xef, 0x13, - 0xda, 0x25, 0x83, 0x28, 0x71, 0x90, 0xb0, 0xb6, 0xbd, 0x61, 0x6c, 0x91, 0x39, 0xa5, 0x3a, 0xd7, - 0x86, 0x76, 0xe6, 0xa7, 0x4e, 0x63, 0xcb, 0xf8, 0x8e, 0x93, 0xcc, 0x12, 0x35, 0x61, 0xe1, 0x09, - 0x0e, 0x3d, 0xd7, 0xeb, 0x44, 0x26, 0xf0, 0x48, 0x5b, 0x3f, 0x8d, 0x2d, 0x94, 0xb4, 0x29, 0x8e, - 0x48, 0xed, 0x6a, 0x7f, 0x34, 0xe0, 0x2b, 0x4c, 0x18, 0x7b, 0x6c, 0x3e, 0x91, 0x92, 0x62, 0xfa, - 0x98, 0xb6, 0xba, 0xa6, 0xc1, 0x86, 0x71, 0x44, 0x45, 0xdd, 0x6f, 0xb2, 0xff, 0xd6, 0x7e, 0x93, - 0x3b, 0xff, 0x7e, 0x93, 0xe4, 0x95, 0xfc, 0xcc, 0xbc, 0x52, 0x38, 0x2b, 0xaf, 0xd4, 0x7e, 0x29, - 0x73, 0x68, 0xb2, 0xbe, 0x73, 0x84, 0xd2, 0xbd, 0x34, 0x94, 0x72, 0x7c, 0xb6, 0xa9, 0x42, 0xc5, - 0x58, 0xf7, 0xdb, 0xc4, 0xa3, 0xee, 0xa1, 0x4b, 0xc2, 0x97, 0x04, 0x94, 0xa2, 0xd2, 0x9c, 0xae, - 0x52, 0x55, 0x62, 0xf9, 0x4b, 0x21, 0x31, 0x3d, 0xae, 0x0a, 0x17, 0x88, 0xab, 0xda, 0xdf, 0xb3, - 0xb0, 0xce, 0x3c, 0xf2, 0x10, 0x1f, 0x90, 0xde, 0x8f, 0x70, 0xff, 0x9c, 0x5e, 0x79, 0x5d, 0xf1, - 0x4a, 0xd9, 0x46, 0x5f, 0xb2, 0x3e, 0x1f, 0xeb, 0xbf, 0x32, 0x60, 0x21, 0xd9, 0x00, 0x50, 0x1d, - 0x40, 0xc0, 0x78, 0x8e, 0x17, 0x5c, 0xaf, 0x30, 0x70, 0x98, 0xb6, 0x3a, 0x8a, 0x05, 0xfa, 0x19, - 0x14, 0x45, 0x4d, 0xc6, 0x82, 0xb2, 0x6d, 0xee, 0xd1, 0x90, 0xe0, 0xfe, 0xed, 0x36, 0x0e, 0x28, - 0x09, 0xed, 0x77, 0xd9, 0x2c, 0x86, 0xb1, 0xf5, 0xc6, 0x59, 0x2c, 0x25, 0x27, 0x7c, 0x89, 0x63, - 0xfe, 0x15, 0xdf, 0x74, 0xe4, 0x17, 0x6a, 0x1f, 0x1b, 0xb0, 0xca, 0x26, 0xca, 0xa8, 0x49, 0x85, - 0xb1, 0x03, 0x0b, 0xa1, 0x2c, 0xf3, 0xe9, 0x2e, 0x36, 0x6b, 0x75, 0x9d, 0xd6, 0x19, 0x54, 0xf2, - 0x0d, 0xd7, 0x70, 0x52, 0x24, 0xda, 0xd2, 0x68, 0xcc, 0xce, 0xa2, 0x51, 0xec, 0xd1, 0x2a, 0x71, - 0xbf, 0xcf, 0x02, 0xba, 0xcf, 0x6e, 0x48, 0x4c, 0x7f, 0x63, 0xa9, 0x3e, 0x9d, 0x9a, 0xd1, 0xb5, - 0x31, 0x29, 0xd3, 0xf6, 0xf6, 0xad, 0x61, 0x6c, 0x6d, 0xbf, 0x44, 0x3b, 0xff, 0x02, 0xaf, 0xac, - 0x42, 0x95, 0x6f, 0xf6, 0x32, 0xc8, 0xb7, 0xf6, 0xdb, 0x2c, 0xac, 0xfc, 0xd8, 0xef, 0x0d, 0xfa, - 0x24, 0xa5, 0x2f, 0x98, 0xa2, 0xcf, 0x1c, 0xd3, 0xa7, 0xdb, 0xda, 0xdb, 0xc3, 0xd8, 0xba, 0x31, - 0x2f, 0x75, 0x3a, 0xf6, 0x52, 0xd3, 0xf6, 0xd7, 0x2c, 0xac, 0xed, 0xfb, 0xc1, 0x0f, 0xf7, 0xf8, - 0x2d, 0x5a, 0x49, 0x93, 0xdd, 0x29, 0xf2, 0xd6, 0xc6, 0xe4, 0x31, 0xc4, 0xfb, 0x98, 0x86, 0xee, - 0x53, 0xfb, 0xc6, 0x30, 0xb6, 0x9a, 0xf3, 0x12, 0x37, 0xc6, 0x5d, 0x66, 0xd2, 0xb4, 0x33, 0x50, - 0x6e, 0xce, 0x33, 0xd0, 0x3f, 0xb2, 0xb0, 0xfe, 0xe1, 0x00, 0x7b, 0xd4, 0xed, 0x11, 0x41, 0x76, - 0x4a, 0xf5, 0xcf, 0xa7, 0xa8, 0xae, 0x8c, 0xa9, 0xd6, 0x31, 0x92, 0xf4, 0xf7, 0x86, 0xb1, 0x75, - 0x73, 0x5e, 0xd2, 0x67, 0x8d, 0xf0, 0x7f, 0x47, 0xff, 0xef, 0xb2, 0xb0, 0xb2, 0x27, 0x4e, 0x6d, - 0xc9, 0xc2, 0x8f, 0x67, 0xd0, 0xae, 0x3e, 0x53, 0x05, 0x07, 0x75, 0x1d, 0x71, 0xbe, 0x24, 0xa1, - 0x63, 0x2f, 0x75, 0x92, 0xf8, 0x43, 0x16, 0xd6, 0x77, 0x08, 0x25, 0x2d, 0x4a, 0xda, 0xf7, 0x5c, - 0xd2, 0x53, 0x48, 0xfc, 0xc8, 0x98, 0x62, 0xb1, 0xaa, 0x5c, 0xb3, 0x66, 0x82, 0x6c, 0x7b, 0x18, - 0x5b, 0xb7, 0xe6, 0xe5, 0x71, 0xf6, 0x18, 0x97, 0x9a, 0xcf, 0xcf, 0xb2, 0xf0, 0x55, 0xf1, 0x74, - 0x20, 0xde, 0x35, 0xc7, 0x74, 0xfe, 0x62, 0x8a, 0x4d, 0x4b, 0x4d, 0x05, 0x33, 0x20, 0xf6, 0xed, - 0x61, 0x6c, 0x7d, 0x7f, 0xfe, 0x5c, 0x30, 0x63, 0x88, 0xff, 0x19, 0x6d, 0xf2, 0xd3, 0xfe, 0x79, - 0xb5, 0xa9, 0x83, 0x2e, 0xa6, 0x4d, 0x7d, 0x8c, 0x4b, 0xcd, 0xe7, 0x5f, 0x8a, 0xb0, 0xcc, 0x55, - 0x92, 0xd2, 0xf8, 0x2d, 0x90, 0xd7, 0x23, 0xc9, 0x21, 0x4a, 0xae, 0xd4, 0x61, 0xd0, 0xaa, 0xef, - 0xc9, 0x8b, 0x93, 0xb0, 0x40, 0xef, 0x40, 0x31, 0xe2, 0x17, 0x57, 0x79, 0xf2, 0xad, 0x4c, 0xbe, - 0x0d, 0xe9, 0x57, 0xe4, 0xdd, 0x8c, 0x23, 0xed, 0xd1, 0x4d, 0x28, 0xf6, 0x38, 0x8b, 0xf2, 0xe2, - 0x5e, 0x9b, 0x44, 0x4e, 0x5f, 0xe5, 0x18, 0x5a, 0x60, 0xd0, 0x0d, 0x28, 0xf0, 0x23, 0xb6, 0x7c, - 0xa3, 0xd6, 0x3e, 0x3b, 0x7d, 0xd0, 0xdd, 0xcd, 0x38, 0xc2, 0x1c, 0x35, 0x21, 0x1f, 0x84, 0x7e, - 0x5f, 0x5e, 0x77, 0xae, 0x4d, 0x7e, 0x53, 0xbd, 0x1f, 0xec, 0x66, 0x1c, 0x6e, 0x8b, 0xde, 0x82, - 0x52, 0xc4, 0x2f, 0x16, 0x11, 0x7f, 0x28, 0x62, 0xa7, 0xca, 0x09, 0x98, 0x02, 0x49, 0x4c, 0xd1, - 0x5b, 0x50, 0x3c, 0xe6, 0xc7, 0x46, 0xf9, 0xfa, 0xb8, 0xa1, 0x82, 0xf4, 0x03, 0x25, 0x5b, 0x97, - 0xb0, 0x45, 0xf7, 0x60, 0x89, 0xfa, 0xc1, 0x51, 0x72, 0x3a, 0x93, 0x8f, 0x4c, 0x55, 0x15, 0x3b, - 0xeb, 0xf4, 0xb6, 0x9b, 0x71, 0x34, 0x1c, 0x7a, 0x04, 0xab, 0x8f, 0xb5, 0x63, 0x00, 0x49, 0x9e, - 0x13, 0x35, 0x9e, 0x67, 0x1f, 0x50, 0x76, 0x33, 0xce, 0x14, 0x1a, 0xed, 0xc0, 0x4a, 0xa4, 0xed, - 0x70, 0xf2, 0xe9, 0x5c, 0x5b, 0x97, 0xbe, 0x07, 0xee, 0x66, 0x9c, 0x09, 0x0c, 0x7a, 0x08, 0x2b, - 0x6d, 0x2d, 0xbf, 0xcb, 0x87, 0x71, 0x6d, 0x56, 0xb3, 0x77, 0x00, 0x36, 0x9a, 0x8e, 0x45, 0x1f, - 0xc0, 0x6a, 0x30, 0x91, 0xdb, 0xe4, 0xcb, 0xf8, 0xd7, 0xf5, 0x55, 0xce, 0x48, 0x82, 0x6c, 0x91, - 0x93, 0x60, 0x75, 0x7a, 0x22, 0xc4, 0xcd, 0xe5, 0xb3, 0xa7, 0xa7, 0x27, 0x01, 0x75, 0x7a, 0xa2, - 0xc7, 0x86, 0x71, 0x3a, 0xaa, 0x7d, 0x5c, 0x84, 0x25, 0x19, 0x66, 0xe2, 0x35, 0xec, 0xbb, 0x69, - 0xe4, 0x88, 0x28, 0x7b, 0xed, 0xac, 0xc8, 0xe1, 0xe6, 0x4a, 0xe0, 0xbc, 0x99, 0x06, 0x8e, 0x08, - 0xb9, 0xf5, 0x71, 0x8a, 0xe3, 0xdf, 0x55, 0x10, 0x32, 0x58, 0xb6, 0x92, 0x60, 0x11, 0x91, 0xf6, - 0xea, 0xec, 0x3b, 0x65, 0x82, 0x92, 0x91, 0xb2, 0x0d, 0x25, 0x57, 0xfc, 0x44, 0x30, 0x2b, 0xc6, - 0xa6, 0x7f, 0x41, 0x60, 0xda, 0x97, 0x00, 0xb4, 0x35, 0x8e, 0x98, 0x82, 0x7c, 0x12, 0x9f, 0x8a, - 0x98, 0x14, 0x94, 0x04, 0xcc, 0xf5, 0x34, 0x60, 0x8a, 0x93, 0xcf, 0xe8, 0x49, 0xb8, 0xa4, 0x0b, - 0x93, 0xd1, 0x72, 0x17, 0x96, 0x13, 0x7d, 0xf1, 0x2e, 0x19, 0x2e, 0xaf, 0x9d, 0x75, 0xac, 0x4b, - 0xf0, 0x3a, 0x0a, 0xdd, 0x9f, 0x12, 0x65, 0x79, 0x72, 0x2b, 0x9e, 0x94, 0x64, 0x32, 0xd2, 0xa4, - 0x22, 0x1f, 0xc0, 0x95, 0xb1, 0xa8, 0xc4, 0x9c, 0x60, 0xfa, 0x84, 0xaf, 0xc9, 0x31, 0x19, 0x6a, - 0x12, 0xa8, 0x4e, 0x4b, 0x8a, 0x71, 0xf1, 0xac, 0x69, 0x25, 0x52, 0x9c, 0x9a, 0x96, 0xe8, 0x40, - 0xbb, 0xb0, 0xd0, 0x27, 0x14, 0xb7, 0x31, 0xc5, 0x66, 0x89, 0x6f, 0x4b, 0xaf, 0x4f, 0x05, 0x88, - 0x44, 0xd7, 0xdf, 0x97, 0x86, 0x77, 0x3d, 0x1a, 0x9e, 0xc8, 0xb7, 0x8b, 0x14, 0xbd, 0xf1, 0x3d, - 0x58, 0xd6, 0x0c, 0xd0, 0x2a, 0xe4, 0x8e, 0x48, 0xf2, 0xb3, 0x11, 0x2b, 0xa2, 0x35, 0x28, 0x1c, - 0xe3, 0xde, 0x80, 0x70, 0x7d, 0x96, 0x1d, 0x51, 0xd9, 0xce, 0xbe, 0x63, 0xd8, 0x65, 0x28, 0x85, - 0xe2, 0x2b, 0x76, 0xe7, 0xd9, 0xf3, 0x4a, 0xe6, 0xf3, 0xe7, 0x95, 0xcc, 0x17, 0xcf, 0x2b, 0xc6, - 0x47, 0xa3, 0x8a, 0xf1, 0xeb, 0x51, 0xc5, 0xf8, 0x74, 0x54, 0x31, 0x9e, 0x8d, 0x2a, 0xc6, 0x9f, - 0x47, 0x15, 0xe3, 0x6f, 0xa3, 0x4a, 0xe6, 0x8b, 0x51, 0xc5, 0xf8, 0xe4, 0x45, 0x25, 0xf3, 0xec, - 0x45, 0x25, 0xf3, 0xf9, 0x8b, 0x4a, 0xe6, 0x27, 0xd7, 0xcf, 0xbd, 0x43, 0x1e, 0x14, 0x39, 0x53, - 0x5b, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x35, 0x32, 0x52, 0x3f, 0x1f, 0x00, 0x00, + // 2004 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcf, 0x6f, 0x1c, 0x49, + 0xf5, 0x9f, 0x9e, 0x9f, 0x9e, 0x67, 0x7b, 0xe2, 0x6f, 0xc5, 0x5f, 0x6f, 0xe3, 0xcd, 0x4e, 0x9b, + 0x91, 0xd8, 0x35, 0x08, 0x66, 0x36, 0xf6, 0x6e, 0xd8, 0x35, 0x21, 0xda, 0x74, 0x9c, 0xac, 0x13, + 0xb2, 0x6c, 0xb6, 0x6d, 0x71, 0xe0, 0x82, 0xca, 0x33, 0xe5, 0x99, 0xc6, 0x33, 0xdd, 0x9d, 0xee, + 0x1a, 0x27, 0x96, 0x10, 0xda, 0x7f, 0x00, 0xb1, 0x7f, 0x05, 0xe2, 0x86, 0x84, 0x38, 0x71, 0xe2, + 0x84, 0x76, 0x0f, 0x48, 0x39, 0xa1, 0x95, 0x25, 0x06, 0xe2, 0x48, 0x08, 0xf9, 0xb4, 0x12, 0x57, + 0x0e, 0xa8, 0x7e, 0x74, 0x4f, 0xd5, 0x74, 0x1b, 0xcf, 0x04, 0x84, 0x64, 0xe0, 0x32, 0xd3, 0x55, + 0xf5, 0x3e, 0xd5, 0x55, 0x9f, 0xf7, 0x79, 0xf5, 0xaa, 0xaa, 0xe1, 0x8d, 0xe0, 0xb0, 0xdb, 0x7a, + 0x3c, 0x24, 0xa1, 0x4b, 0x42, 0xfe, 0x7f, 0x1c, 0x62, 0xaf, 0x4b, 0x94, 0xc7, 0x66, 0x10, 0xfa, + 0xd4, 0x47, 0x30, 0xae, 0x59, 0xdd, 0xe8, 0xba, 0xb4, 0x37, 0xdc, 0x6f, 0xb6, 0xfd, 0x41, 0xab, + 0xeb, 0x77, 0xfd, 0x56, 0xd7, 0xf7, 0xbb, 0x7d, 0x82, 0x03, 0x37, 0x92, 0x8f, 0xad, 0x30, 0x68, + 0xb7, 0x22, 0x8a, 0xe9, 0x30, 0x12, 0xf8, 0xd5, 0x65, 0x66, 0xc8, 0x1f, 0x39, 0x44, 0xd6, 0x5a, + 0xd2, 0x9c, 0x97, 0xf6, 0x87, 0x07, 0x2d, 0xea, 0x0e, 0x48, 0x44, 0xf1, 0x20, 0x88, 0x0d, 0xd8, + 0xf8, 0xfa, 0x7e, 0x57, 0x20, 0x5d, 0xaf, 0x43, 0x9e, 0x76, 0x31, 0x25, 0x4f, 0xf0, 0xb1, 0x34, + 0x78, 0x55, 0x33, 0x88, 0x1f, 0x64, 0xe3, 0xaa, 0xd6, 0x18, 0x60, 0x4a, 0x49, 0xe8, 0xc9, 0xb6, + 0x2f, 0x69, 0x6d, 0xd1, 0x21, 0xa1, 0xed, 0x9e, 0x6c, 0x5a, 0x93, 0x4d, 0x8f, 0xfb, 0x03, 0xbf, + 0x43, 0xfa, 0x7c, 0x22, 0x91, 0xf8, 0x95, 0x16, 0x57, 0x99, 0x45, 0x30, 0x8c, 0x7a, 0xfc, 0x47, + 0x56, 0xde, 0xb9, 0x90, 0xcb, 0x7d, 0x1c, 0x91, 0x56, 0x87, 0x1c, 0xb8, 0x9e, 0x4b, 0x5d, 0xdf, + 0x8b, 0xd4, 0x67, 0xd9, 0xc9, 0x8d, 0xe9, 0x3a, 0x99, 0xf4, 0xcf, 0xea, 0x9b, 0x0c, 0x17, 0x51, + 0x3f, 0xc4, 0x5d, 0xd2, 0x6a, 0xf7, 0x86, 0xde, 0x61, 0xab, 0x8d, 0xdb, 0x3d, 0xd2, 0x0a, 0x49, + 0x34, 0xec, 0xd3, 0x48, 0x14, 0xe8, 0x71, 0x40, 0xe4, 0x9b, 0x1a, 0x9f, 0x15, 0x61, 0xfe, 0xa1, + 0x7f, 0xe8, 0x3a, 0xe4, 0xf1, 0x90, 0x44, 0x14, 0x2d, 0x43, 0x89, 0xf7, 0x6a, 0x1a, 0x6b, 0xc6, + 0x7a, 0xd5, 0x11, 0x05, 0x56, 0xdb, 0x77, 0x07, 0x2e, 0x35, 0xf3, 0x6b, 0xc6, 0xfa, 0xa2, 0x23, + 0x0a, 0x08, 0x41, 0x31, 0xa2, 0x24, 0x30, 0x0b, 0x6b, 0xc6, 0x7a, 0xc1, 0xe1, 0xcf, 0x68, 0x15, + 0xe6, 0x5c, 0x8f, 0x92, 0xf0, 0x08, 0xf7, 0xcd, 0x2a, 0xaf, 0x4f, 0xca, 0xe8, 0x16, 0x54, 0x22, + 0x8a, 0x43, 0xba, 0x17, 0x99, 0xc5, 0x35, 0x63, 0x7d, 0x7e, 0x63, 0xb5, 0x29, 0x3c, 0xdf, 0x8c, + 0x3d, 0xdf, 0xdc, 0x8b, 0x3d, 0x6f, 0xcf, 0x7d, 0x3a, 0xb2, 0x72, 0x9f, 0xfc, 0xd1, 0x32, 0x9c, + 0x18, 0x84, 0xb6, 0xa0, 0x44, 0xbc, 0xce, 0x5e, 0x64, 0x96, 0x66, 0x40, 0x0b, 0x08, 0xba, 0x0e, + 0xd5, 0x8e, 0x1b, 0x92, 0x36, 0x63, 0xd9, 0x2c, 0xaf, 0x19, 0xeb, 0xb5, 0x8d, 0xab, 0xcd, 0x44, + 0x28, 0xdb, 0x71, 0x93, 0x33, 0xb6, 0x62, 0xd3, 0x0b, 0x30, 0xed, 0x99, 0x15, 0xce, 0x04, 0x7f, + 0x46, 0x0d, 0x28, 0x47, 0x3d, 0x1c, 0x76, 0x22, 0x73, 0x6e, 0xad, 0xb0, 0x5e, 0xb5, 0xe1, 0x6c, + 0x64, 0xc9, 0x1a, 0x47, 0xfe, 0xa3, 0x1f, 0x40, 0x31, 0xe8, 0x63, 0xcf, 0x04, 0x3e, 0xca, 0xa5, + 0xa6, 0xe2, 0xa5, 0x47, 0x7d, 0xec, 0xd9, 0xef, 0x9e, 0x8c, 0xac, 0xb7, 0xd5, 0xe0, 0x09, 0xf1, + 0x01, 0xf6, 0x70, 0xab, 0xef, 0x1f, 0xba, 0xad, 0xa3, 0xcd, 0x96, 0xea, 0x7b, 0xd6, 0x51, 0xf3, + 0x23, 0xd6, 0x01, 0x83, 0x3a, 0xbc, 0x63, 0xf4, 0x00, 0xe6, 0x99, 0x8f, 0xc9, 0x1d, 0xe6, 0xe0, + 0xc8, 0x9c, 0xe7, 0xef, 0x79, 0x65, 0x3c, 0x1b, 0x5e, 0xef, 0x90, 0x83, 0xf7, 0x43, 0x7f, 0x18, + 0xd8, 0x57, 0xce, 0x46, 0x96, 0x6a, 0xef, 0xa8, 0x05, 0xf4, 0x00, 0x6a, 0x4c, 0x14, 0xae, 0xd7, + 0xfd, 0x30, 0xe0, 0x0a, 0x34, 0x17, 0x78, 0x77, 0xd7, 0x9a, 0xaa, 0x64, 0x9a, 0x77, 0x34, 0x1b, + 0xbb, 0xc8, 0xe8, 0x75, 0x26, 0x90, 0x8d, 0xd3, 0x02, 0x20, 0xa6, 0xa5, 0xfb, 0x5e, 0x44, 0xb1, + 0x47, 0x5f, 0x46, 0x52, 0x37, 0xa1, 0xcc, 0x82, 0x7f, 0x2f, 0xe2, 0xa2, 0x9a, 0xd6, 0xc7, 0x12, + 0xa3, 0x3b, 0xb9, 0x38, 0x93, 0x93, 0x4b, 0x99, 0x4e, 0x2e, 0x5f, 0xe8, 0xe4, 0xca, 0xbf, 0xc9, + 0xc9, 0x73, 0xff, 0x5a, 0x27, 0x57, 0x5f, 0xda, 0xc9, 0x26, 0x14, 0xd9, 0x28, 0xd1, 0x12, 0x14, + 0x42, 0xfc, 0x84, 0xfb, 0x74, 0xc1, 0x61, 0x8f, 0x8d, 0xd3, 0x22, 0x2c, 0x88, 0xa5, 0x24, 0x0a, + 0x7c, 0x2f, 0x22, 0x8c, 0xc7, 0x5d, 0xbe, 0xfa, 0x0b, 0xcf, 0x4b, 0x1e, 0x79, 0x8d, 0x23, 0x5b, + 0xd0, 0x7b, 0x50, 0xdc, 0xc6, 0x14, 0x73, 0x15, 0xcc, 0x6f, 0x2c, 0xab, 0x3c, 0xb2, 0xbe, 0x58, + 0x9b, 0xbd, 0xc2, 0x06, 0x72, 0x36, 0xb2, 0x6a, 0x1d, 0x4c, 0xf1, 0xd7, 0xfd, 0x81, 0x4b, 0xc9, + 0x20, 0xa0, 0xc7, 0x0e, 0x47, 0xa2, 0xb7, 0xa1, 0x7a, 0x37, 0x0c, 0xfd, 0x70, 0xef, 0x38, 0x20, + 0x5c, 0x35, 0x55, 0xfb, 0x95, 0xb3, 0x91, 0x75, 0x95, 0xc4, 0x95, 0x0a, 0x62, 0x6c, 0x89, 0xbe, + 0x0a, 0x25, 0x5e, 0xe0, 0x3a, 0xa9, 0xda, 0x57, 0xcf, 0x46, 0xd6, 0x15, 0x0e, 0x51, 0xcc, 0x85, + 0x85, 0x2e, 0xab, 0xd2, 0x54, 0xb2, 0x4a, 0xd4, 0x5d, 0x56, 0xd5, 0x6d, 0x42, 0xe5, 0x88, 0x84, + 0x11, 0xeb, 0xa6, 0xc2, 0xeb, 0xe3, 0x22, 0xba, 0x0d, 0xc0, 0x88, 0x71, 0x23, 0xea, 0xb6, 0x63, + 0x67, 0x2f, 0x36, 0x45, 0xb2, 0x71, 0xb8, 0x8f, 0x6c, 0x24, 0x59, 0x50, 0x0c, 0x1d, 0xe5, 0x19, + 0xfd, 0xc2, 0x80, 0xca, 0x0e, 0xc1, 0x1d, 0x12, 0x32, 0xf7, 0x16, 0xd6, 0xe7, 0x37, 0xbe, 0xd2, + 0x54, 0x33, 0xcb, 0xa3, 0xd0, 0x1f, 0x10, 0xda, 0x23, 0xc3, 0x28, 0x76, 0x90, 0xb0, 0xb6, 0xbd, + 0x93, 0x91, 0x45, 0xa6, 0x94, 0xea, 0x54, 0x09, 0xed, 0xdc, 0x57, 0x9d, 0x8d, 0x2c, 0xe3, 0x1b, + 0x4e, 0x3c, 0x4a, 0xb4, 0x01, 0x73, 0x4f, 0x70, 0xe8, 0xb9, 0x5e, 0x37, 0x32, 0x81, 0x47, 0xda, + 0xca, 0xd9, 0xc8, 0x42, 0x71, 0x9d, 0xe2, 0x88, 0xc4, 0xae, 0xf1, 0x07, 0x03, 0xfe, 0x8f, 0x09, + 0x63, 0x97, 0x8d, 0x27, 0x52, 0x96, 0x98, 0x01, 0xa6, 0xed, 0x9e, 0x69, 0xb0, 0x6e, 0x1c, 0x51, + 0x50, 0xf3, 0x4d, 0xfe, 0x9f, 0xca, 0x37, 0x85, 0xd9, 0xf3, 0x4d, 0xbc, 0xae, 0x14, 0x33, 0xd7, + 0x95, 0xd2, 0x79, 0xeb, 0x4a, 0xe3, 0xa7, 0x72, 0x0d, 0x8d, 0xe7, 0x37, 0x43, 0x28, 0xdd, 0x4b, + 0x42, 0xa9, 0xc0, 0x47, 0x9b, 0x28, 0x54, 0xf4, 0x75, 0xbf, 0x43, 0x3c, 0xea, 0x1e, 0xb8, 0x24, + 0xbc, 0x20, 0xa0, 0x14, 0x95, 0x16, 0x74, 0x95, 0xaa, 0x12, 0x2b, 0x5e, 0x0a, 0x89, 0xe9, 0x71, + 0x55, 0x7a, 0x89, 0xb8, 0x6a, 0xfc, 0x35, 0x0f, 0x2b, 0xcc, 0x23, 0x0f, 0xf1, 0x3e, 0xe9, 0x7f, + 0x17, 0x0f, 0x66, 0xf4, 0xca, 0xeb, 0x8a, 0x57, 0xaa, 0x36, 0xfa, 0x1f, 0xeb, 0xd3, 0xb1, 0xfe, + 0x33, 0x03, 0xe6, 0xe2, 0x04, 0x80, 0x9a, 0x00, 0x02, 0xc6, 0xd7, 0x78, 0xc1, 0x75, 0x8d, 0x81, + 0xc3, 0xa4, 0xd6, 0x51, 0x2c, 0xd0, 0x0f, 0xa1, 0x2c, 0x4a, 0x32, 0x16, 0x94, 0xb4, 0xb9, 0x4b, + 0x43, 0x82, 0x07, 0xb7, 0x3b, 0x38, 0xa0, 0x24, 0xb4, 0xdf, 0x65, 0xa3, 0x38, 0x19, 0x59, 0x6f, + 0x9c, 0xc7, 0x52, 0xbc, 0xc3, 0x97, 0x38, 0xe6, 0x5f, 0xf1, 0x4e, 0x47, 0xbe, 0xa1, 0xf1, 0x13, + 0x03, 0x96, 0xd8, 0x40, 0x19, 0x35, 0x89, 0x30, 0xb6, 0x61, 0x2e, 0x94, 0xcf, 0x7c, 0xb8, 0xf3, + 0x1b, 0x8d, 0xa6, 0x4e, 0x6b, 0x06, 0x95, 0x3c, 0xe1, 0x1a, 0x4e, 0x82, 0x44, 0x9b, 0x1a, 0x8d, + 0xf9, 0x2c, 0x1a, 0x45, 0x8e, 0x56, 0x89, 0xfb, 0x4d, 0x1e, 0xd0, 0x7d, 0x76, 0x42, 0x62, 0xfa, + 0x1b, 0x4b, 0xf5, 0x69, 0x6a, 0x44, 0xd7, 0xc6, 0xa4, 0xa4, 0xed, 0xed, 0x5b, 0x27, 0x23, 0x6b, + 0xeb, 0x02, 0xed, 0xfc, 0x03, 0xbc, 0x32, 0x0b, 0x55, 0xbe, 0xf9, 0xcb, 0x20, 0xdf, 0xc6, 0xaf, + 0xf2, 0x50, 0xfb, 0x9e, 0xdf, 0x1f, 0x0e, 0x48, 0x42, 0x5f, 0x90, 0xa2, 0xcf, 0x1c, 0xd3, 0xa7, + 0xdb, 0xda, 0x5b, 0x27, 0x23, 0xeb, 0xc6, 0xb4, 0xd4, 0xe9, 0xd8, 0x4b, 0x4d, 0xdb, 0x9f, 0xf3, + 0xb0, 0xbc, 0xe7, 0x07, 0xdf, 0xd9, 0xe5, 0xa7, 0x68, 0x65, 0x99, 0xec, 0xa5, 0xc8, 0x5b, 0x1e, + 0x93, 0xc7, 0x10, 0x1f, 0x60, 0x1a, 0xba, 0x4f, 0xed, 0x1b, 0x27, 0x23, 0x6b, 0x63, 0x5a, 0xe2, + 0xc6, 0xb8, 0xcb, 0x4c, 0x9a, 0xb6, 0x07, 0x2a, 0x4c, 0xb9, 0x07, 0xfa, 0x5b, 0x1e, 0x56, 0x3e, + 0x1a, 0x62, 0x8f, 0xba, 0x7d, 0x22, 0xc8, 0x4e, 0xa8, 0xfe, 0x51, 0x8a, 0xea, 0xfa, 0x98, 0x6a, + 0x1d, 0x23, 0x49, 0x7f, 0xef, 0x64, 0x64, 0xdd, 0x9c, 0x96, 0xf4, 0xac, 0x1e, 0xfe, 0xeb, 0xe8, + 0xff, 0x75, 0x1e, 0x6a, 0xbb, 0x62, 0xd7, 0x16, 0x4f, 0xfc, 0x28, 0x83, 0x76, 0xf5, 0x9a, 0x2a, + 0xd8, 0x6f, 0xea, 0x88, 0xd9, 0x16, 0x09, 0x1d, 0x7b, 0xa9, 0x17, 0x89, 0xdf, 0xe5, 0x61, 0x65, + 0x9b, 0x50, 0xd2, 0xa6, 0xa4, 0x73, 0xcf, 0x25, 0x7d, 0x85, 0xc4, 0x8f, 0x8d, 0x14, 0x8b, 0x6b, + 0xca, 0x31, 0x2b, 0x13, 0x64, 0xdb, 0x27, 0x23, 0xeb, 0xd6, 0xb4, 0x3c, 0x66, 0xf7, 0x71, 0xa9, + 0xf9, 0xfc, 0x2c, 0x0f, 0xff, 0x2f, 0xae, 0x0e, 0xc4, 0xbd, 0xe6, 0x98, 0xce, 0x1f, 0xa7, 0xd8, + 0xb4, 0xd4, 0xa5, 0x20, 0x03, 0x62, 0xdf, 0x3e, 0x19, 0x59, 0xdf, 0x9e, 0x7e, 0x2d, 0xc8, 0xe8, + 0xe2, 0x3f, 0x46, 0x9b, 0x7c, 0xb7, 0x3f, 0xab, 0x36, 0x75, 0xd0, 0xcb, 0x69, 0x53, 0xef, 0xe3, + 0x52, 0xf3, 0xf9, 0xdb, 0x3c, 0x2c, 0x73, 0x95, 0xec, 0xe2, 0x41, 0xd0, 0x57, 0x36, 0x04, 0x17, + 0x64, 0xa9, 0x34, 0x62, 0xd6, 0x2c, 0x95, 0xee, 0xe1, 0x52, 0x13, 0xf9, 0xcb, 0x0a, 0x2c, 0xf2, + 0x49, 0x25, 0x0c, 0x7e, 0x0d, 0xe4, 0x39, 0x53, 0xf2, 0x87, 0xe2, 0xbb, 0x89, 0x30, 0x68, 0x37, + 0x77, 0xe5, 0x09, 0x54, 0x58, 0xa0, 0x77, 0xa0, 0x1c, 0xf1, 0x1b, 0x00, 0x79, 0x84, 0xa8, 0x4f, + 0x5e, 0xb2, 0xe9, 0x77, 0x0d, 0x3b, 0x39, 0x47, 0xda, 0xa3, 0x9b, 0x50, 0xee, 0x73, 0x39, 0xca, + 0x1b, 0x90, 0xc6, 0x24, 0x32, 0x7d, 0x26, 0x66, 0x68, 0x81, 0x41, 0x37, 0xa0, 0xc4, 0xcf, 0x2a, + 0xf2, 0xb2, 0x5f, 0x7b, 0x6d, 0xfa, 0xc4, 0xb0, 0x93, 0x73, 0x84, 0x39, 0xda, 0x80, 0x62, 0x10, + 0xfa, 0x03, 0x79, 0x6e, 0xbc, 0x36, 0xf9, 0x4e, 0xf5, 0xa0, 0xb5, 0x93, 0x73, 0xb8, 0x2d, 0x7a, + 0x0b, 0x2a, 0x11, 0x3f, 0xa1, 0x45, 0xfc, 0xc6, 0x8d, 0x6d, 0xcf, 0x27, 0x60, 0x0a, 0x24, 0x36, + 0x45, 0x6f, 0x41, 0xf9, 0x88, 0xef, 0xbf, 0xe5, 0x35, 0xee, 0xaa, 0x0a, 0xd2, 0x77, 0xe6, 0x6c, + 0x5e, 0xc2, 0x16, 0xdd, 0x83, 0x05, 0xea, 0x07, 0x87, 0xf1, 0x36, 0x57, 0xde, 0xd6, 0xad, 0xa9, + 0xd8, 0xac, 0x6d, 0xf0, 0x4e, 0xce, 0xd1, 0x70, 0xe8, 0x11, 0x2c, 0x3d, 0xd6, 0xf6, 0x53, 0x24, + 0xbe, 0x97, 0xd5, 0x78, 0xce, 0xde, 0xe9, 0xed, 0xe4, 0x9c, 0x14, 0x1a, 0x6d, 0x43, 0x2d, 0xd2, + 0xb6, 0x0a, 0xf2, 0x1b, 0x84, 0x36, 0x2f, 0x7d, 0x33, 0xb1, 0x93, 0x73, 0x26, 0x30, 0xe8, 0x21, + 0xd4, 0x3a, 0x5a, 0xa2, 0x94, 0x5f, 0x18, 0xb4, 0x51, 0x65, 0xa7, 0x52, 0xd6, 0x9b, 0x8e, 0x45, + 0x1f, 0xc2, 0x52, 0x30, 0x91, 0x24, 0xe4, 0x27, 0x86, 0x2f, 0xeb, 0xb3, 0xcc, 0xc8, 0x26, 0x6c, + 0x92, 0x93, 0x60, 0x75, 0x78, 0x62, 0xad, 0x34, 0x17, 0xcf, 0x1f, 0x9e, 0xbe, 0x9a, 0xaa, 0xc3, + 0x13, 0x2d, 0xe8, 0x21, 0x5c, 0x89, 0xf4, 0x95, 0xc2, 0xac, 0xa5, 0xfd, 0x99, 0xb5, 0xa2, 0xec, + 0xe4, 0x9c, 0x49, 0xa8, 0x0d, 0xe3, 0x85, 0xad, 0xf1, 0xfb, 0x32, 0x2c, 0xc8, 0xa0, 0x15, 0x97, + 0x94, 0xdf, 0x4c, 0xe2, 0x50, 0xc4, 0xec, 0x6b, 0xe7, 0xc5, 0x21, 0x37, 0x57, 0xc2, 0xf0, 0xcd, + 0x24, 0x0c, 0x45, 0x00, 0xaf, 0x8c, 0x17, 0x4b, 0x3e, 0x0b, 0x05, 0x21, 0x43, 0x6f, 0x33, 0x0e, + 0x3d, 0x11, 0xb7, 0xaf, 0x66, 0x1f, 0xf5, 0x63, 0x94, 0x8c, 0xbb, 0x2d, 0xa8, 0xb8, 0xe2, 0xcb, + 0x4d, 0x56, 0xc4, 0xa6, 0x3f, 0xec, 0xb0, 0x48, 0x92, 0x00, 0xb4, 0x39, 0x8e, 0xbf, 0x92, 0xfc, + 0x52, 0x91, 0x8a, 0xbf, 0x04, 0x14, 0x87, 0xdf, 0xf5, 0x24, 0xfc, 0xca, 0x93, 0x5f, 0x37, 0xe2, + 0xe0, 0x4b, 0x26, 0x26, 0x63, 0xef, 0x2e, 0x2c, 0xc6, 0x6a, 0xe5, 0x4d, 0x32, 0xf8, 0x5e, 0x3b, + 0x6f, 0xb7, 0x1d, 0xe3, 0x75, 0x14, 0xba, 0x9f, 0x92, 0x78, 0x75, 0x72, 0x87, 0x34, 0x29, 0xf0, + 0xb8, 0xa7, 0x49, 0x7d, 0x3f, 0x80, 0x2b, 0x63, 0x89, 0x8a, 0x31, 0x41, 0x66, 0x4a, 0x7b, 0xa4, + 0x5b, 0x31, 0xf9, 0x4c, 0x00, 0xd5, 0x61, 0x49, 0x69, 0xcf, 0x9f, 0x37, 0xac, 0x58, 0xd8, 0xa9, + 0x61, 0x49, 0x5d, 0xbf, 0x0f, 0xb5, 0x44, 0x9c, 0x62, 0x54, 0x0b, 0x92, 0xa9, 0x73, 0xd2, 0x64, + 0xd2, 0x91, 0x0e, 0x43, 0x3b, 0x30, 0x37, 0x20, 0x14, 0x77, 0x30, 0xc5, 0x66, 0x85, 0x67, 0xcb, + 0xd7, 0x53, 0x91, 0x21, 0x6d, 0x9b, 0x1f, 0x48, 0xc3, 0xbb, 0x1e, 0x0d, 0x8f, 0xe5, 0xdd, 0x54, + 0x82, 0x5e, 0xfd, 0x16, 0x2c, 0x6a, 0x06, 0x68, 0x09, 0x0a, 0x87, 0x24, 0xfe, 0x2c, 0xc8, 0x1e, + 0xd1, 0x32, 0x94, 0x8e, 0x70, 0x7f, 0x48, 0xb8, 0xd0, 0xab, 0x8e, 0x28, 0x6c, 0xe5, 0xdf, 0x31, + 0xec, 0x2a, 0x54, 0x42, 0xf1, 0x16, 0xbb, 0xfb, 0xec, 0x79, 0x3d, 0xf7, 0xf9, 0xf3, 0x7a, 0xee, + 0x8b, 0xe7, 0x75, 0xe3, 0xe3, 0xd3, 0xba, 0xf1, 0xf3, 0xd3, 0xba, 0xf1, 0xe9, 0x69, 0xdd, 0x78, + 0x76, 0x5a, 0x37, 0xfe, 0x74, 0x5a, 0x37, 0xfe, 0x72, 0x5a, 0xcf, 0x7d, 0x71, 0x5a, 0x37, 0x3e, + 0x79, 0x51, 0xcf, 0x3d, 0x7b, 0x51, 0xcf, 0x7d, 0xfe, 0xa2, 0x9e, 0xfb, 0xfe, 0xf5, 0x99, 0x13, + 0xf7, 0x7e, 0x99, 0xf3, 0xb4, 0xf9, 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x9e, 0x81, 0xb1, + 0x1f, 0x21, 0x00, 0x00, } func (this *LokiRequest) Equal(that interface{}) bool { @@ -2321,6 +2390,42 @@ func (this *DetectedLabelsResponse) Equal(that interface{}) bool { } return true } +func (this *QuerySamplesResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QuerySamplesResponse) + if !ok { + that2, ok := that.(QuerySamplesResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if that1.Response == nil { + if this.Response != nil { + return false + } + } else if !this.Response.Equal(*that1.Response) { + return false + } + if len(this.Headers) != len(that1.Headers) { + return false + } + for i := range this.Headers { + if !this.Headers[i].Equal(that1.Headers[i]) { + return false + } + } + return true +} func (this *QueryResponse) Equal(that interface{}) bool { if that == nil { return this == nil @@ -2642,6 +2747,30 @@ func (this *QueryResponse_DetectedLabels) Equal(that interface{}) bool { } return true } +func (this *QueryResponse_SamplesResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryResponse_SamplesResponse) + if !ok { + that2, ok := that.(QueryResponse_SamplesResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.SamplesResponse.Equal(that1.SamplesResponse) { + return false + } + return true +} func (this *QueryRequest) Equal(that interface{}) bool { if that == nil { return this == nil @@ -2920,6 +3049,30 @@ func (this *QueryRequest_DetectedLabels) Equal(that interface{}) bool { } return true } +func (this *QueryRequest_SamplesRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryRequest_SamplesRequest) + if !ok { + that2, ok := that.(QueryRequest_SamplesRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.SamplesRequest.Equal(that1.SamplesRequest) { + return false + } + return true +} func (this *LokiRequest) GoString() string { if this == nil { return "nil" @@ -3154,11 +3307,22 @@ func (this *DetectedLabelsResponse) GoString() string { s = append(s, "}") return strings.Join(s, "") } +func (this *QuerySamplesResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&queryrange.QuerySamplesResponse{") + s = append(s, "Response: "+fmt.Sprintf("%#v", this.Response)+",\n") + s = append(s, "Headers: "+fmt.Sprintf("%#v", this.Headers)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func (this *QueryResponse) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 17) + s := make([]string, 0, 18) s = append(s, "&queryrange.QueryResponse{") if this.Status != nil { s = append(s, "Status: "+fmt.Sprintf("%#v", this.Status)+",\n") @@ -3265,11 +3429,19 @@ func (this *QueryResponse_DetectedLabels) GoString() string { `DetectedLabels:` + fmt.Sprintf("%#v", this.DetectedLabels) + `}`}, ", ") return s } +func (this *QueryResponse_SamplesResponse) GoString() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&queryrange.QueryResponse_SamplesResponse{` + + `SamplesResponse:` + fmt.Sprintf("%#v", this.SamplesResponse) + `}`}, ", ") + return s +} func (this *QueryRequest) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 15) + s := make([]string, 0, 16) s = append(s, "&queryrange.QueryRequest{") if this.Request != nil { s = append(s, "Request: "+fmt.Sprintf("%#v", this.Request)+",\n") @@ -3370,6 +3542,14 @@ func (this *QueryRequest_DetectedLabels) GoString() string { `DetectedLabels:` + fmt.Sprintf("%#v", this.DetectedLabels) + `}`}, ", ") return s } +func (this *QueryRequest_SamplesRequest) GoString() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&queryrange.QueryRequest_SamplesRequest{` + + `SamplesRequest:` + fmt.Sprintf("%#v", this.SamplesRequest) + `}`}, ", ") + return s +} func valueToGoStringQueryrange(v interface{}, typ string) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -4428,6 +4608,55 @@ func (m *DetectedLabelsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *QuerySamplesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySamplesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySamplesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Headers) > 0 { + for iNdEx := len(m.Headers) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.Headers[iNdEx].Size() + i -= size + if _, err := m.Headers[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQueryrange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Response != nil { + { + size := m.Response.Size() + i -= size + if _, err := m.Response.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQueryrange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *QueryResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4712,6 +4941,26 @@ func (m *QueryResponse_DetectedLabels) MarshalToSizedBuffer(dAtA []byte) (int, e } return len(dAtA) - i, nil } +func (m *QueryResponse_SamplesResponse) MarshalTo(dAtA []byte) (int, error) { + return m.MarshalToSizedBuffer(dAtA[:m.Size()]) +} + +func (m *QueryResponse_SamplesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SamplesResponse != nil { + { + size, err := m.SamplesResponse.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryrange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 + } + return len(dAtA) - i, nil +} func (m *QueryRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4963,6 +5212,26 @@ func (m *QueryRequest_DetectedLabels) MarshalToSizedBuffer(dAtA []byte) (int, er } return len(dAtA) - i, nil } +func (m *QueryRequest_SamplesRequest) MarshalTo(dAtA []byte) (int, error) { + return m.MarshalToSizedBuffer(dAtA[:m.Size()]) +} + +func (m *QueryRequest_SamplesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SamplesRequest != nil { + { + size, err := m.SamplesRequest.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryrange(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + return len(dAtA) - i, nil +} func encodeVarintQueryrange(dAtA []byte, offset int, v uint64) int { offset -= sovQueryrange(v) base := offset @@ -5410,6 +5679,25 @@ func (m *DetectedLabelsResponse) Size() (n int) { return n } +func (m *QuerySamplesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Response != nil { + l = m.Response.Size() + n += 1 + l + sovQueryrange(uint64(l)) + } + if len(m.Headers) > 0 { + for _, e := range m.Headers { + l = e.Size() + n += 1 + l + sovQueryrange(uint64(l)) + } + } + return n +} + func (m *QueryResponse) Size() (n int) { if m == nil { return 0 @@ -5570,6 +5858,18 @@ func (m *QueryResponse_DetectedLabels) Size() (n int) { } return n } +func (m *QueryResponse_SamplesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SamplesResponse != nil { + l = m.SamplesResponse.Size() + n += 1 + l + sovQueryrange(uint64(l)) + } + return n +} func (m *QueryRequest) Size() (n int) { if m == nil { return 0 @@ -5710,6 +6010,18 @@ func (m *QueryRequest_DetectedLabels) Size() (n int) { } return n } +func (m *QueryRequest_SamplesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SamplesRequest != nil { + l = m.SamplesRequest.Size() + n += 1 + l + sovQueryrange(uint64(l)) + } + return n +} func sovQueryrange(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 @@ -5944,6 +6256,17 @@ func (this *DetectedLabelsResponse) String() string { }, "") return s } +func (this *QuerySamplesResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QuerySamplesResponse{`, + `Response:` + fmt.Sprintf("%v", this.Response) + `,`, + `Headers:` + fmt.Sprintf("%v", this.Headers) + `,`, + `}`, + }, "") + return s +} func (this *QueryResponse) String() string { if this == nil { return "nil" @@ -6075,6 +6398,16 @@ func (this *QueryResponse_DetectedLabels) String() string { }, "") return s } +func (this *QueryResponse_SamplesResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QueryResponse_SamplesResponse{`, + `SamplesResponse:` + strings.Replace(fmt.Sprintf("%v", this.SamplesResponse), "QuerySamplesResponse", "QuerySamplesResponse", 1) + `,`, + `}`, + }, "") + return s +} func (this *QueryRequest) String() string { if this == nil { return "nil" @@ -6196,6 +6529,16 @@ func (this *QueryRequest_DetectedLabels) String() string { }, "") return s } +func (this *QueryRequest_SamplesRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QueryRequest_SamplesRequest{`, + `SamplesRequest:` + strings.Replace(fmt.Sprintf("%v", this.SamplesRequest), "QuerySamplesRequest", "logproto.QuerySamplesRequest", 1) + `,`, + `}`, + }, "") + return s +} func valueToStringQueryrange(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -9262,6 +9605,129 @@ func (m *DetectedLabelsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySamplesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryrange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySamplesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySamplesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryrange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryrange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryrange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Response == nil { + m.Response = &github_com_grafana_loki_v3_pkg_logproto.QuerySamplesResponse{} + } + if err := m.Response.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryrange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryrange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryrange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Headers = append(m.Headers, github_com_grafana_loki_v3_pkg_querier_queryrange_queryrangebase_definitions.PrometheusResponseHeader{}) + if err := m.Headers[len(m.Headers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQueryrange(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQueryrange + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQueryrange + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -9747,6 +10213,41 @@ func (m *QueryResponse) Unmarshal(dAtA []byte) error { } m.Response = &QueryResponse_DetectedLabels{v} iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SamplesResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryrange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryrange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryrange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &QuerySamplesResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Response = &QueryResponse_SamplesResponse{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQueryrange(dAtA[iNdEx:]) @@ -10277,6 +10778,41 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error { } m.Request = &QueryRequest_DetectedLabels{v} iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SamplesRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryrange + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryrange + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryrange + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &logproto.QuerySamplesRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &QueryRequest_SamplesRequest{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQueryrange(dAtA[iNdEx:]) diff --git a/pkg/querier/queryrange/queryrange.proto b/pkg/querier/queryrange/queryrange.proto index 2169b2da3154..bc4083bc9dc5 100644 --- a/pkg/querier/queryrange/queryrange.proto +++ b/pkg/querier/queryrange/queryrange.proto @@ -210,6 +210,13 @@ message DetectedLabelsResponse { (gogoproto.customtype) = "github.com/grafana/loki/v3/pkg/querier/queryrange/queryrangebase/definitions.PrometheusResponseHeader" ]; } +message QuerySamplesResponse { + logproto.QuerySamplesResponse response = 1 [(gogoproto.customtype) = "github.com/grafana/loki/v3/pkg/logproto.QuerySamplesResponse"]; + repeated definitions.PrometheusResponseHeader Headers = 2 [ + (gogoproto.jsontag) = "-", + (gogoproto.customtype) = "github.com/grafana/loki/v3/pkg/querier/queryrange/queryrangebase/definitions.PrometheusResponseHeader" + ]; +} message QueryResponse { google.rpc.Status status = 1; @@ -226,6 +233,7 @@ message QueryResponse { DetectedFieldsResponse detectedFields = 11; QueryPatternsResponse patternsResponse = 12; DetectedLabelsResponse detectedLabels = 13; + QuerySamplesResponse samplesResponse = 14; } } @@ -241,6 +249,7 @@ message QueryRequest { logproto.DetectedFieldsRequest detectedFields = 9; logproto.QueryPatternsRequest patternsRequest = 10; logproto.DetectedLabelsRequest detectedLabels = 11; + logproto.QuerySamplesRequest samplesRequest = 12; } map metadata = 7 [(gogoproto.nullable) = false]; } diff --git a/pkg/querier/queryrange/roundtrip.go b/pkg/querier/queryrange/roundtrip.go index 35806abb38d4..f80132116645 100644 --- a/pkg/querier/queryrange/roundtrip.go +++ b/pkg/querier/queryrange/roundtrip.go @@ -294,7 +294,8 @@ func NewDetectedLabelsTripperware(cfg Config, opts logql.EngineOpts, logger log. NewLimitsMiddleware(l), NewQuerySizeLimiterMiddleware(schema.Configs, opts, logger, l, statsHandler), base.InstrumentMiddleware("split_by_interval", metrics.InstrumentMiddlewareMetrics), - SplitByIntervalMiddleware(schema.Configs, limits, merger, splitter, metrics.SplitByMetrics)} + SplitByIntervalMiddleware(schema.Configs, limits, merger, splitter, metrics.SplitByMetrics), + } // The sharding middleware takes care of enforcing this limit for both shardable and non-shardable queries. // If we are not using sharding, we enforce the limit by adding this middleware after time splitting. @@ -516,6 +517,7 @@ const ( DetectedFieldsOp = "detected_fields" PatternsQueryOp = "patterns" DetectedLabelsOp = "detected_labels" + SamplesQueryOp = "samples" ) func getOperation(path string) string { @@ -542,6 +544,8 @@ func getOperation(path string) string { return PatternsQueryOp case path == "/loki/api/v1/detected_labels": return DetectedLabelsOp + case path == "/loki/api/v1/explore/query_range": + return SamplesQueryOp default: return "" } diff --git a/pkg/storage/stores/composite_store.go b/pkg/storage/stores/composite_store.go index 62ba7f12df8a..b975873c3043 100644 --- a/pkg/storage/stores/composite_store.go +++ b/pkg/storage/stores/composite_store.go @@ -149,10 +149,10 @@ func (c CompositeStore) LabelValuesForMetricName(ctx context.Context, userID str } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c CompositeStore) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c CompositeStore) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { var result util.UniqueStrings err := c.forStores(ctx, from, through, func(innerCtx context.Context, from, through model.Time, store Store) error { - labelNames, err := store.LabelNamesForMetricName(innerCtx, userID, from, through, metricName) + labelNames, err := store.LabelNamesForMetricName(innerCtx, userID, from, through, metricName, matchers...) if err != nil { return err } diff --git a/pkg/storage/stores/composite_store_entry.go b/pkg/storage/stores/composite_store_entry.go index fd214543ef03..2c6e3c5e4a90 100644 --- a/pkg/storage/stores/composite_store_entry.go +++ b/pkg/storage/stores/composite_store_entry.go @@ -108,7 +108,7 @@ func (c *storeEntry) SetChunkFilterer(chunkFilter chunk.RequestChunkFilterer) { } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SeriesStore.LabelNamesForMetricName") defer sp.Finish() log := spanlogger.FromContext(ctx) @@ -122,7 +122,7 @@ func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, } level.Debug(log).Log("metric", metricName) - return c.indexReader.LabelNamesForMetricName(ctx, userID, from, through, metricName) + return c.indexReader.LabelNamesForMetricName(ctx, userID, from, through, metricName, matchers...) } func (c *storeEntry) LabelValuesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, labelName string, matchers ...*labels.Matcher) ([]string, error) { diff --git a/pkg/storage/stores/composite_store_test.go b/pkg/storage/stores/composite_store_test.go index 203057c60845..ab44f6b69d3c 100644 --- a/pkg/storage/stores/composite_store_test.go +++ b/pkg/storage/stores/composite_store_test.go @@ -45,7 +45,7 @@ func (m mockStore) GetSeries(_ context.Context, _ string, _, _ model.Time, _ ... return nil, nil } -func (m mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil } @@ -210,7 +210,7 @@ func (m mockStoreLabel) LabelValuesForMetricName(_ context.Context, _ string, _, return m.values, nil } -func (m mockStoreLabel) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m mockStoreLabel) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return m.values, nil } diff --git a/pkg/storage/stores/index/index.go b/pkg/storage/stores/index/index.go index 99e5b3597883..4014fca8c3e7 100644 --- a/pkg/storage/stores/index/index.go +++ b/pkg/storage/stores/index/index.go @@ -25,7 +25,7 @@ type Filterable interface { type BaseReader interface { GetSeries(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) ([]labels.Labels, error) LabelValuesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, labelName string, matchers ...*labels.Matcher) ([]string, error) - LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) + LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) } type StatsReader interface { @@ -112,11 +112,11 @@ func (m MonitoredReaderWriter) LabelValuesForMetricName(ctx context.Context, use return values, nil } -func (m MonitoredReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (m MonitoredReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { var values []string if err := loki_instrument.TimeRequest(ctx, "label_names", instrument.NewHistogramCollector(m.metrics.indexQueryLatency), instrument.ErrorCode, func(ctx context.Context) error { var err error - values, err = m.rw.LabelNamesForMetricName(ctx, userID, from, through, metricName) + values, err = m.rw.LabelNamesForMetricName(ctx, userID, from, through, metricName, matchers...) return err }); err != nil { return nil, err diff --git a/pkg/storage/stores/series/series_index_gateway_store.go b/pkg/storage/stores/series/series_index_gateway_store.go index b58979bd11a1..0202494ae6e1 100644 --- a/pkg/storage/stores/series/series_index_gateway_store.go +++ b/pkg/storage/stores/series/series_index_gateway_store.go @@ -80,11 +80,12 @@ func (c *IndexGatewayClientStore) GetSeries(ctx context.Context, _ string, from, } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *IndexGatewayClientStore) LabelNamesForMetricName(ctx context.Context, _ string, from, through model.Time, metricName string) ([]string, error) { +func (c *IndexGatewayClientStore) LabelNamesForMetricName(ctx context.Context, _ string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { resp, err := c.client.LabelNamesForMetricName(ctx, &logproto.LabelNamesForMetricNameRequest{ MetricName: metricName, From: from, Through: through, + Matchers: (&syntax.MatchersExpr{Mts: matchers}).String(), }) if err != nil { return nil, err diff --git a/pkg/storage/stores/series/series_index_store.go b/pkg/storage/stores/series/series_index_store.go index 535f6a524950..c3ef58266e82 100644 --- a/pkg/storage/stores/series/series_index_store.go +++ b/pkg/storage/stores/series/series_index_store.go @@ -316,14 +316,14 @@ func (c *IndexReaderWriter) chunksToSeries(ctx context.Context, in []logproto.Ch } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *IndexReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c *IndexReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SeriesStore.LabelNamesForMetricName") defer sp.Finish() log := spanlogger.FromContext(ctx) defer log.Span.Finish() // Fetch the series IDs from the index - seriesIDs, err := c.lookupSeriesByMetricNameMatchers(ctx, from, through, userID, metricName, nil) + seriesIDs, err := c.lookupSeriesByMetricNameMatchers(ctx, from, through, userID, metricName, matchers) if err != nil { return nil, err } diff --git a/pkg/storage/stores/series/series_store_test.go b/pkg/storage/stores/series/series_store_test.go index f5948e8ef60d..15ecb1623eeb 100644 --- a/pkg/storage/stores/series/series_store_test.go +++ b/pkg/storage/stores/series/series_store_test.go @@ -246,14 +246,24 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { for _, tc := range []struct { metricName string expect []string + matchers []*labels.Matcher }{ { `foo`, []string{"bar", "flip", "toms"}, + nil, }, { `bar`, []string{"bar", "toms"}, + nil, + }, + { + `foo`, + []string{"bar", "toms"}, + []*labels.Matcher{ + labels.MustNewMatcher(labels.MatchRegexp, "bar", "beep"), + }, }, } { for _, schema := range schemas { @@ -286,7 +296,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Query with ordinary time-range - labelNames1, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now, tc.metricName) + labelNames1, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now, tc.metricName, tc.matchers...) require.NoError(t, err) if !reflect.DeepEqual(tc.expect, labelNames1) { @@ -294,7 +304,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Pushing end of time-range into future should yield exact same resultset - labelNames2, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now.Add(time.Hour*24*10), tc.metricName) + labelNames2, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now.Add(time.Hour*24*10), tc.metricName, tc.matchers...) require.NoError(t, err) if !reflect.DeepEqual(tc.expect, labelNames2) { @@ -302,7 +312,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Query with both begin & end of time-range in future should yield empty resultset - labelNames3, err := store.LabelNamesForMetricName(ctx, userID, now.Add(time.Hour), now.Add(time.Hour*2), tc.metricName) + labelNames3, err := store.LabelNamesForMetricName(ctx, userID, now.Add(time.Hour), now.Add(time.Hour*2), tc.metricName, tc.matchers...) require.NoError(t, err) if len(labelNames3) != 0 { t.Fatalf("%s: future query should yield empty resultset ... actually got %v label names: %#v", diff --git a/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go b/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go index 47d33fe632fa..4eade5789910 100644 --- a/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go +++ b/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go @@ -170,8 +170,8 @@ func (c *IndexClient) LabelValuesForMetricName(ctx context.Context, userID strin } // tsdb no longer uses the __metric_name__="logs" hack, so we can ignore metric names! -func (c *IndexClient) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, _ string) ([]string, error) { - return c.idx.LabelNames(ctx, userID, from, through) +func (c *IndexClient) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, _ string, matchers ...*labels.Matcher) ([]string, error) { + return c.idx.LabelNames(ctx, userID, from, through, matchers...) } func (c *IndexClient) Stats(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) (*stats.Stats, error) { diff --git a/pkg/storage/util_test.go b/pkg/storage/util_test.go index 23f89b7a9dfe..7c325cc4da6b 100644 --- a/pkg/storage/util_test.go +++ b/pkg/storage/util_test.go @@ -220,7 +220,7 @@ func (m *mockChunkStore) LabelValuesForMetricName(_ context.Context, _ string, _ return nil, nil } -func (m *mockChunkStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m *mockChunkStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil } diff --git a/pkg/tool/audit/README.md b/pkg/tool/audit/README.md new file mode 100644 index 000000000000..1756cd4f9815 --- /dev/null +++ b/pkg/tool/audit/README.md @@ -0,0 +1,40 @@ +# Loki Index Auditing + +## Usage + +To audit your index data: +1. Make sure you're authenticated to the cloud where your bucket lives in. +In this example I'll be using GCP. +2. Create a new YAML configuration file that defines your storage configuration. +`lokitool` will use it to communicate with your data. +Only TSDB is supported. Make sure you give all three fields: `schema_config`, `storage_config` and `tenant`. In this example I'm naming my file `configfile.yaml`: +```yaml +schema_config: + configs: + - from: "2023-08-21" + index: + period: 24h + prefix: loki_env_tsdb_index_ + object_store: gcs + schema: v13 + store: tsdb + +storage_config: + gcs: + bucket_name: loki-bucket + +tenant: 12345 +``` +3. Build a new `lokitool` binary: +```bash +go build ./cmd/lokitool +``` +4. Finally, invoke the `audit index` command the following way: +```bash +./lokitool audit index --period=19856 --config.file=configfile.yaml --index.file=index/loki_env_tsdb_index_19856/12345/1715707992714992001-compactor-1715199977885-1815707796275-g8003361.tsdb.gz +``` +The `--period` is the period of the index being audited. You can find it by checking the 5-digits number appended +as a suffix of the Loki environment name in the index file. Example: For `index/loki_env_tsdb_index_19856/12345/...`, +the period is 19856. +The `--config.file` is the YAML configuration described in the first step. +The `--index.file` is the path to the index file you want to audit. Take a look at your bucket to see its exactly path and substitute it accordingly. \ No newline at end of file diff --git a/pkg/tool/audit/audit.go b/pkg/tool/audit/audit.go new file mode 100644 index 000000000000..63bbaab01796 --- /dev/null +++ b/pkg/tool/audit/audit.go @@ -0,0 +1,133 @@ +package audit + +import ( + "context" + "fmt" + "io" + "path" + "strings" + "time" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + progressbar "github.com/schollz/progressbar/v3" + "go.uber.org/atomic" + "golang.org/x/sync/errgroup" + + "github.com/grafana/loki/v3/pkg/compactor" + "github.com/grafana/loki/v3/pkg/compactor/retention" + "github.com/grafana/loki/v3/pkg/storage" + loki_storage "github.com/grafana/loki/v3/pkg/storage" + "github.com/grafana/loki/v3/pkg/storage/chunk/client" + indexshipper_storage "github.com/grafana/loki/v3/pkg/storage/stores/shipper/indexshipper/storage" + shipperutil "github.com/grafana/loki/v3/pkg/storage/stores/shipper/indexshipper/storage" + "github.com/grafana/loki/v3/pkg/storage/stores/shipper/indexshipper/tsdb" + util_log "github.com/grafana/loki/v3/pkg/util/log" +) + +const ( + TsFormat = time.RFC3339Nano +) + +func Run(ctx context.Context, cloudIndexPath, table string, cfg Config, logger log.Logger) (int, int, error) { + level.Info(logger).Log("msg", "auditing index", "index", cloudIndexPath, "table", table, "tenant", cfg.Tenant, "working_dir", cfg.WorkingDir) + + objClient, err := GetObjectClient(cfg) + if err != nil { + return 0, 0, err + } + + localFile, err := DownloadIndexFile(ctx, cfg, cloudIndexPath, objClient, logger) + if err != nil { + return 0, 0, err + } + + compactedIdx, err := ParseCompactexIndex(ctx, localFile, table, cfg) + if err != nil { + return 0, 0, err + } + defer compactedIdx.Cleanup() + + return ValidateCompactedIndex(ctx, objClient, compactedIdx, cfg.Concurrency, logger) +} + +func GetObjectClient(cfg Config) (client.ObjectClient, error) { + periodCfg := cfg.SchemaConfig.Configs[len(cfg.SchemaConfig.Configs)-1] // only check the last period. + + objClient, err := loki_storage.NewObjectClient(periodCfg.ObjectType, cfg.StorageConfig, storage.NewClientMetrics()) + if err != nil { + return nil, fmt.Errorf("couldn't create object client: %w", err) + } + + return objClient, nil +} + +func DownloadIndexFile(ctx context.Context, cfg Config, cloudIndexPath string, objClient client.ObjectClient, logger log.Logger) (string, error) { + splitPath := strings.Split(cloudIndexPath, "/") + localFileName := splitPath[len(splitPath)-1] + decompress := indexshipper_storage.IsCompressedFile(cloudIndexPath) + if decompress { + // get rid of the last extension, which is .gz + localFileName = strings.TrimSuffix(localFileName, path.Ext(localFileName)) + } + localFilePath := path.Join(cfg.WorkingDir, localFileName) + if err := shipperutil.DownloadFileFromStorage(localFilePath, decompress, false, logger, func() (io.ReadCloser, error) { + r, _, err := objClient.GetObject(ctx, cloudIndexPath) + return r, err + }); err != nil { + return "", fmt.Errorf("couldn't download file %q from storage: %w", cloudIndexPath, err) + } + + level.Info(logger).Log("msg", "file successfully downloaded from storage", "path", cloudIndexPath) + return localFileName, nil +} + +func ParseCompactexIndex(ctx context.Context, localFilePath, table string, cfg Config) (compactor.CompactedIndex, error) { + periodCfg := cfg.SchemaConfig.Configs[len(cfg.SchemaConfig.Configs)-1] // only check the last period. + idxCompactor := tsdb.NewIndexCompactor() + compactedIdx, err := idxCompactor.OpenCompactedIndexFile(ctx, localFilePath, table, cfg.Tenant, cfg.WorkingDir, periodCfg, util_log.Logger) + if err != nil { + return nil, fmt.Errorf("couldn't open compacted index file %q: %w", localFilePath, err) + } + return compactedIdx, nil +} + +func ValidateCompactedIndex(ctx context.Context, objClient client.ObjectClient, compactedIdx compactor.CompactedIndex, parallelism int, logger log.Logger) (int, int, error) { + var missingChunks, foundChunks atomic.Int32 + foundChunks.Store(0) + missingChunks.Store(0) + bar := progressbar.NewOptions(-1, + progressbar.OptionShowCount(), + progressbar.OptionSetDescription("Chunks validated"), + ) + + g, ctx := errgroup.WithContext(ctx) + g.SetLimit(parallelism) + compactedIdx.ForEachChunk(ctx, func(ce retention.ChunkEntry) (deleteChunk bool, err error) { //nolint:errcheck + bar.Add(1) // nolint:errcheck + g.Go(func() error { + exists, err := CheckChunkExistance(string(ce.ChunkID), objClient) + if err != nil || !exists { + missingChunks.Add(1) + logger.Log("msg", "chunk is missing", "err", err, "chunk_id", string(ce.ChunkID)) + return nil + } + foundChunks.Add(1) + return nil + }) + + return false, nil + }) + g.Wait() // nolint:errcheck + + return int(foundChunks.Load()), int(missingChunks.Load()), nil +} + +func CheckChunkExistance(key string, objClient client.ObjectClient) (bool, error) { + exists, err := objClient.ObjectExists(context.Background(), key) + if err != nil { + return false, err + } + + return exists, nil +} diff --git a/pkg/tool/audit/audit_test.go b/pkg/tool/audit/audit_test.go new file mode 100644 index 000000000000..c9afa7b34f35 --- /dev/null +++ b/pkg/tool/audit/audit_test.go @@ -0,0 +1,59 @@ +package audit + +import ( + "context" + "strings" + "testing" + + "github.com/go-kit/log" + "github.com/stretchr/testify/require" + + "github.com/grafana/loki/v3/pkg/compactor" + "github.com/grafana/loki/v3/pkg/compactor/retention" + "github.com/grafana/loki/v3/pkg/storage/chunk/client" +) + +type testObjClient struct { + client.ObjectClient +} + +func (t testObjClient) ObjectExists(_ context.Context, object string) (bool, error) { + if strings.Contains(object, "missing") { + return false, nil + } + return true, nil +} + +type testCompactedIdx struct { + compactor.CompactedIndex + + chunks []retention.ChunkEntry +} + +func (t testCompactedIdx) ForEachChunk(_ context.Context, f retention.ChunkEntryCallback) error { + for _, chunk := range t.chunks { + if _, err := f(chunk); err != nil { + return err + } + } + return nil +} + +func TestAuditIndex(t *testing.T) { + ctx := context.Background() + objClient := testObjClient{} + compactedIdx := testCompactedIdx{ + chunks: []retention.ChunkEntry{ + {ChunkRef: retention.ChunkRef{ChunkID: []byte("found-1")}}, + {ChunkRef: retention.ChunkRef{ChunkID: []byte("found-2")}}, + {ChunkRef: retention.ChunkRef{ChunkID: []byte("found-3")}}, + {ChunkRef: retention.ChunkRef{ChunkID: []byte("found-4")}}, + {ChunkRef: retention.ChunkRef{ChunkID: []byte("missing-1")}}, + }, + } + logger := log.NewNopLogger() + found, missing, err := ValidateCompactedIndex(ctx, objClient, compactedIdx, 1, logger) + require.NoError(t, err) + require.Equal(t, 4, found) + require.Equal(t, 1, missing) +} diff --git a/pkg/tool/audit/config.go b/pkg/tool/audit/config.go new file mode 100644 index 000000000000..d22f52c97370 --- /dev/null +++ b/pkg/tool/audit/config.go @@ -0,0 +1,70 @@ +package audit + +import ( + "flag" + "fmt" + + "github.com/grafana/dskit/flagext" + dskitlog "github.com/grafana/dskit/log" + + "github.com/grafana/loki/v3/pkg/storage" + lokiStorage "github.com/grafana/loki/v3/pkg/storage/config" +) + +type FileConfig struct { + ConfigFile string +} + +func (c *FileConfig) RegisterFlags(f *flag.FlagSet) { + f.StringVar(&c.ConfigFile, "config.file", "config.yaml", "configuration file to load") +} + +// Config Loki related storage and schema configs +type Config struct { + FileConfig `yaml:",inline"` + Tenant string `yaml:"tenant,omitempty"` + SchemaConfig lokiStorage.SchemaConfig `yaml:"schema_config,omitempty"` + StorageConfig storage.Config `yaml:"storage_config,omitempty"` + LogLevel dskitlog.Level `yaml:"log_level"` + Concurrency int `yaml:"concurrency"` + WorkingDir string `yaml:"working_dir"` + Period string `yaml:"period,omitempty"` +} + +func (c *Config) RegisterFlags(f *flag.FlagSet) { + c.FileConfig.RegisterFlags(f) + c.SchemaConfig.RegisterFlags(f) + c.StorageConfig.RegisterFlags(f) + c.LogLevel.RegisterFlags(f) + f.StringVar(&c.Tenant, "tenant", "", "tenant to analyze data") + f.IntVar(&c.Concurrency, "concurrency", 100, "amount of files to check concurrently") + f.StringVar(&c.WorkingDir, "working-dir", ".", "working directory to store downloaded files") + f.StringVar(&c.Period, "period", "", "the table period in a format like 19959") +} + +func (c *Config) Validate() error { + if err := c.SchemaConfig.Validate(); err != nil { + return fmt.Errorf("schema config is invalid: %v", err) + } + if err := c.StorageConfig.Validate(); err != nil { + return fmt.Errorf("storage config is invalid: %v", err) + } + if len(c.Tenant) <= 0 { + return fmt.Errorf("tenant argument missing. Use -tenant flag or add 'tenant' to the config file") + } + if c.Concurrency <= 0 { + return fmt.Errorf("concurrency argument needs to be greater than 0") + } + if c.Period == "" { + return fmt.Errorf("period argument missing. Use -period flag or add 'period' to the config file") + } + return nil +} + +// Clone takes advantage of pass-by-value semantics to return a distinct *Config. +// This is primarily used to parse a different flag set without mutating the original *Config. +func (c *Config) Clone() flagext.Registerer { + return func(c Config) *Config { + return &c + }(*c) +} diff --git a/pkg/tool/commands/audit.go b/pkg/tool/commands/audit.go new file mode 100644 index 000000000000..dae7e2c10bb5 --- /dev/null +++ b/pkg/tool/commands/audit.go @@ -0,0 +1,63 @@ +package commands + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "gopkg.in/alecthomas/kingpin.v2" + + "github.com/grafana/loki/v3/pkg/tool/audit" + util_cfg "github.com/grafana/loki/v3/pkg/util/cfg" +) + +// AuditIndexCommand validates an index by checking existing chunks. +type AuditCommand struct { + path string + + configFile string + + extraArgs []string +} + +func (a *AuditCommand) auditIndex(_ *kingpin.ParseContext) error { + logger := log.NewLogfmtLogger(os.Stdout) + + var auditCfg audit.Config + if err := util_cfg.DefaultUnmarshal(&auditCfg, a.extraArgs, flag.CommandLine); err != nil { + fmt.Fprintf(os.Stderr, "failed parsing config: %v\n", err) + os.Exit(1) + } + if err := auditCfg.Validate(); err != nil { + fmt.Fprintf(os.Stderr, "failed validating config: %v\n", err) + os.Exit(1) + } + + found, missing, err := audit.Run(context.Background(), a.path, auditCfg.Period, auditCfg, logger) + if err != nil { + return err + } + level.Info(logger).Log("msg", "finished auditing index", "chunks_found", found, "chunks_missing", missing) + if missing > 0 { + level.Error(logger).Log("msg", "your index is missing chunks, please check previous logs for more information", "index", a.path) + } else { + level.Info(logger).Log("msg", "your index is healthy", "index", a.path) + } + return nil +} + +func (a *AuditCommand) Register(app *kingpin.Application) { + auditCmd := app.Command("audit", "Audit Loki state.") + + // Register audit commands. + auditIndexCmd := auditCmd. + Command("index", "Audit the given index by checking all its expected chunks are present."). + Action(a.auditIndex) + + auditIndexCmd.Flag("config.file", "Auditing and storage configuration").Required().StringVar(&a.configFile) + auditIndexCmd.Flag("index.file", "Index to be audited").Required().StringVar(&a.path) + auditIndexCmd.Arg("args", "").StringsVar(&a.extraArgs) +} diff --git a/pkg/util/marshal/marshal.go b/pkg/util/marshal/marshal.go index 1a4d6701b1b1..6886650c822b 100644 --- a/pkg/util/marshal/marshal.go +++ b/pkg/util/marshal/marshal.go @@ -9,6 +9,8 @@ import ( "github.com/gorilla/websocket" jsoniter "github.com/json-iterator/go" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/promql/parser" "github.com/grafana/loki/v3/pkg/loghttp" @@ -46,6 +48,8 @@ func WriteResponseJSON(r *http.Request, v any, w http.ResponseWriter) error { return WriteVolumeResponseJSON(result, w) case *logproto.QueryPatternsResponse: return WriteQueryPatternsResponseJSON(result, w) + case *logproto.QuerySamplesResponse: + return WriteQuerySamplesResponseJSON(result, w) } return fmt.Errorf("unknown response type %T", v) } @@ -239,3 +243,47 @@ func WriteDetectedLabelsResponseJSON(r *logproto.DetectedLabelsResponse, w io.Wr s.WriteRaw("\n") return s.Flush() } + +// WriteQuerySamplesResponseJSON marshals a logproto.QuerySamplesResponse to JSON and then +// writes it to the provided io.Writer. +func WriteQuerySamplesResponseJSON(r *logproto.QuerySamplesResponse, w io.Writer) error { + s := jsoniter.ConfigFastest.BorrowStream(w) + defer jsoniter.ConfigFastest.ReturnStream(s) + + matrix, err := logprotoSeriesToPromQLMatrix(r.Series) + if err != nil { + return fmt.Errorf("could not convert logproto series to promql matrix: %w", err) + } + + // TODO(twhitney): add stats + err = EncodeResult(matrix, nil, stats.Result{}, s, nil) + if err != nil { + return fmt.Errorf("could not write JSON response: %w", err) + } + + s.WriteRaw("\n") + s.Flush() + return nil +} + +func logprotoSeriesToPromQLMatrix(series []logproto.Series) (promql.Matrix, error) { + promMatrix := make(promql.Matrix, len(series)) + for i, s := range series { + lbls, err := parser.ParseMetric(s.Labels) + if err != nil { + return nil, err + } + + promSeries := promql.Series{ + Metric: lbls, + Floats: make([]promql.FPoint, len(s.Samples)), + } + for i, sample := range s.Samples { + t := model.TimeFromUnixNano(sample.Timestamp) + promSeries.Floats[i] = promql.FPoint{T: int64(t), F: sample.Value} + } + promMatrix[i] = promSeries + } + + return promMatrix, nil +} diff --git a/pkg/util/marshal/marshal_test.go b/pkg/util/marshal/marshal_test.go index c749677f7702..b8c90c5a61d4 100644 --- a/pkg/util/marshal/marshal_test.go +++ b/pkg/util/marshal/marshal_test.go @@ -1135,3 +1135,127 @@ func Test_WriteQueryPatternsResponseJSON(t *testing.T) { }) } } + +func Test_WriteQuerySamplesResponseJSON(t *testing.T) { + expected := func(result string) string { + return fmt.Sprintf(`{ + "status": "success", + "data": { + "result": %s, + "resultType": "matrix", + "stats" : %s + } + }`, result, emptyStats) + } + + for i, tc := range []struct { + input *logproto.QuerySamplesResponse + expected string + }{ + { + &logproto.QuerySamplesResponse{}, + expected("[]"), + }, + { + &logproto.QuerySamplesResponse{ + Series: []logproto.Series{ + { + Labels: `{foo="bar"}`, + Samples: []logproto.Sample{ + {Timestamp: 1e9, Value: 1}, + {Timestamp: 2e9, Value: 2}, + }, + }, + }, + }, + expected(`[ + { + "metric": { + "foo": "bar" + }, + "values": [ + [1, "1"], + [2, "2"] + ] + } + ]`), + }, + { + &logproto.QuerySamplesResponse{ + Series: []logproto.Series{ + { + Labels: `{foo="bar"}`, + Samples: []logproto.Sample{ + {Timestamp: 1e9, Value: 1}, + {Timestamp: 2e9, Value: 2}, + }, + }, + { + Labels: `{foo="buzz"}`, + Samples: []logproto.Sample{ + {Timestamp: 3e9, Value: 1}, + {Timestamp: 3e9, Value: 2}, + }, + }, + }, + }, + expected(`[ + { + "metric": { + "foo": "bar" + }, + "values": [ + [1, "1"], + [2, "2"] + ] + }, + { + "metric": { + "foo": "buzz" + }, + "values": [ + [3, "1"], + [3, "2"] + ] + } + ]`), + }, + { + &logproto.QuerySamplesResponse{ + Series: []logproto.Series{ + { + Labels: `{foo="bar"}`, + Samples: []logproto.Sample{}, + }, + { + Labels: `{foo="buzz"}`, + Samples: []logproto.Sample{}, + }, + }, + }, + expected(`[ + { + "metric": { + "foo": "bar" + }, + "values": [] + }, + { + "metric": { + "foo": "buzz" + }, + "values": [] + } + ]`), + }, + } { + tc := tc + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + var b bytes.Buffer + err := WriteQuerySamplesResponseJSON(tc.input, &b) + require.NoError(t, err) + got := b.String() + require.JSONEqf(t, tc.expected, got, "Patterns Test %d failed", i) + }) + } +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index d569c0c94997..d0ea68f4082f 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,6 +1,7 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo // +build darwin freebsd openbsd netbsd dragonfly hurd // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 31503226f6c8..7402e0618aab 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,5 +1,6 @@ -//go:build appengine || js || nacl || wasm -// +build appengine js nacl wasm +//go:build (appengine || js || nacl || tinygo || wasm) && !windows +// +build appengine js nacl tinygo wasm +// +build !windows package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 67787657fb2b..0337d8cf6dea 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,6 +1,7 @@ -//go:build (linux || aix || zos) && !appengine +//go:build (linux || aix || zos) && !appengine && !tinygo // +build linux aix zos // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/rivo/uniseg/LICENSE.txt b/vendor/github.com/rivo/uniseg/LICENSE.txt new file mode 100644 index 000000000000..5040f1ef808d --- /dev/null +++ b/vendor/github.com/rivo/uniseg/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Oliver Kuederle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md new file mode 100644 index 000000000000..a8191b8154a2 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/README.md @@ -0,0 +1,137 @@ +# Unicode Text Segmentation for Go + +[![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg) +[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg) + +This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html). + +## Background + +### Grapheme Clusters + +In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples: + +|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters| +|-|-|-|-| +|Kaฬˆse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`| +|๐Ÿณ๏ธโ€๐ŸŒˆ|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`| +|๐Ÿ‡ฉ๐Ÿ‡ช|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`| + +This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit. + +### Word Boundaries + +Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings. + +### Sentence Boundaries + +Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings. + +### Line Breaking + +Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters). + +### Monospace Width + +Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information. + +## Installation + +```bash +go get github.com/rivo/uniseg +``` + +## Examples + +### Counting Characters in a String + +```go +n := uniseg.GraphemeClusterCount("๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿณ๏ธโ€๐ŸŒˆ") +fmt.Println(n) +// 2 +``` + +### Calculating the Monospace String Width + +```go +width := uniseg.StringWidth("๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿณ๏ธโ€๐ŸŒˆ!") +fmt.Println(width) +// 5 +``` + +### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class + +This is the most convenient method of iterating over grapheme clusters: + +```go +gr := uniseg.NewGraphemes("๐Ÿ‘๐Ÿผ!") +for gr.Next() { + fmt.Printf("%x ", gr.Runes()) +} +// [1f44d 1f3fc] [21] +``` + +### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function + +This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries: + +```go +str := "๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿณ๏ธโ€๐ŸŒˆ" +state := -1 +var c string +for len(str) > 0 { + c, str, _, state = uniseg.StepString(str, state) + fmt.Printf("%x ", []rune(c)) +} +// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308] +``` + +### Advanced Examples + +The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString): + +```go +str := "Hello, world!" +state := -1 +var c string +for len(str) > 0 { + c, str, state = uniseg.FirstWordInString(str, state) + fmt.Printf("(%s)\n", c) +} +// (Hello) +// (,) +// ( ) +// (world) +// (!) +``` + +Similarly, use + +- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only, +- [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and +- [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries). + +If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line boundaries. + +Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString): + +```go +fmt.Println(uniseg.ReverseString("๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿณ๏ธโ€๐ŸŒˆ")) +// ๐Ÿณ๏ธโ€๐ŸŒˆ๐Ÿ‡ฉ๐Ÿ‡ช +``` + +## Documentation + +Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation. + +## Dependencies + +This package does not depend on any packages outside the standard library. + +## Sponsor this Project + +[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project! + +## Your Feedback + +Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions. \ No newline at end of file diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go new file mode 100644 index 000000000000..11224ae22d45 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/doc.go @@ -0,0 +1,108 @@ +/* +Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and +string width calculation for monospace fonts. Unicode Text Segmentation conforms +to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode +Line Breaking conforms to Unicode Standard Annex #14 +(https://unicode.org/reports/tr14/). + +In short, using this package, you can split a string into grapheme clusters +(what people would usually refer to as a "character"), into words, and into +sentences. Or, in its simplest case, this package allows you to count the number +of characters in a string, especially when it contains complex characters such +as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or +other languages. Additionally, you can use it to implement line breaking (or +"word wrapping"), that is, to determine where text can be broken over to the +next line when the width of the line is not big enough to fit the entire text. +Finally, you can use it to calculate the display width of a string for monospace +fonts. + +# Getting Started + +If you just want to count the number of characters in a string, you can use +[GraphemeClusterCount]. If you want to determine the display width of a string, +you can use [StringWidth]. If you want to iterate over a string, you can use +[Step], [StepString], or the [Graphemes] class (more convenient but less +performant). This will provide you with all information: grapheme clusters, +word boundaries, sentence boundaries, line breaks, and monospace character +widths. The specialized functions [FirstGraphemeCluster], +[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString], +[FirstSentence], and [FirstSentenceInString] can be used if only one type of +information is needed. + +# Grapheme Clusters + +Consider the rainbow flag emoji: ๐Ÿณ๏ธโ€๐ŸŒˆ. On most modern systems, it appears as one +character. But its string representation actually has 14 bytes, so counting +bytes (or using len("๐Ÿณ๏ธโ€๐ŸŒˆ")) will not work as expected. Counting runes won't, +either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function +utf8.RuneCountInString("๐Ÿณ๏ธโ€๐ŸŒˆ") and len([]rune("๐Ÿณ๏ธโ€๐ŸŒˆ")) will both return 4. + +The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji. +The Graphemes class and a variety of functions in this package will allow you to +split strings into its grapheme clusters. + +# Word Boundaries + +Word boundaries are used in a number of different contexts. The most familiar +ones are selection (double-click mouse selection), cursor movement ("move to +next word" control-arrow keys), and the dialog option "Whole Word Search" for +search and replace. This package provides methods for determining word +boundaries. + +# Sentence Boundaries + +Sentence boundaries are often used for triple-click or some other method of +selecting or iterating through blocks of text that are larger than single words. +They are also used to determine whether words occur within the same sentence in +database queries. This package provides methods for determining sentence +boundaries. + +# Line Breaking + +Line breaking, also known as word wrapping, is the process of breaking a section +of text into lines such that it will fit in the available width of a page, +window or other display area. This package provides methods to determine the +positions in a string where a line must be broken, may be broken, or must not be +broken. + +# Monospace Width + +Monospace width, as referred to in this package, is the width of a string in a +monospace font. This is commonly used in terminal user interfaces or text +displays or editors that don't support proportional fonts. A width of 1 +corresponds to a single character cell. The C function [wcswidth()] and its +implementation in other programming languages is in widespread use for the same +purpose. However, there is no standard for the calculation of such widths, and +this package differs from wcswidth() in a number of ways, presumably to generate +more visually pleasing results. + +To start, we assume that every code point has a width of 1, with the following +exceptions: + + - Code points with grapheme cluster break properties Control, CR, LF, Extend, + and ZWJ have a width of 0. + - U+2E3A, Two-Em Dash, has a width of 3. + - U+2E3B, Three-Em Dash, has a width of 4. + - Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide" + (W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both + have a width of 1.) + - Code points with grapheme cluster break property Regional Indicator have a + width of 2. + - Code points with grapheme cluster break property Extended Pictographic have + a width of 2, unless their Emoji Presentation flag is "No", in which case + the width is 1. + +For Hangul grapheme clusters composed of conjoining Jamo and for Regional +Indicators (flags), all code points except the first one have a width of 0. For +grapheme clusters starting with an Extended Pictographic, any additional code +point will force a total width of 2, except if the Variation Selector-15 +(U+FE0E) is included, in which case the total width is always 1. Grapheme +clusters ending with Variation Selector-16 (U+FE0F) have a width of 2. + +Note that whether these widths appear correct depends on your application's +render engine, to which extent it conforms to the Unicode Standard, and its +choice of font. + +[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html +*/ +package uniseg diff --git a/vendor/github.com/rivo/uniseg/eastasianwidth.go b/vendor/github.com/rivo/uniseg/eastasianwidth.go new file mode 100644 index 000000000000..5fc54d9915ae --- /dev/null +++ b/vendor/github.com/rivo/uniseg/eastasianwidth.go @@ -0,0 +1,2588 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// eastAsianWidth are taken from +// https://www.unicode.org/Public/15.0.0/ucd/EastAsianWidth.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var eastAsianWidth = [][3]int{ + {0x0000, 0x001F, prN}, // Cc [32] .. + {0x0020, 0x0020, prNa}, // Zs SPACE + {0x0021, 0x0023, prNa}, // Po [3] EXCLAMATION MARK..NUMBER SIGN + {0x0024, 0x0024, prNa}, // Sc DOLLAR SIGN + {0x0025, 0x0027, prNa}, // Po [3] PERCENT SIGN..APOSTROPHE + {0x0028, 0x0028, prNa}, // Ps LEFT PARENTHESIS + {0x0029, 0x0029, prNa}, // Pe RIGHT PARENTHESIS + {0x002A, 0x002A, prNa}, // Po ASTERISK + {0x002B, 0x002B, prNa}, // Sm PLUS SIGN + {0x002C, 0x002C, prNa}, // Po COMMA + {0x002D, 0x002D, prNa}, // Pd HYPHEN-MINUS + {0x002E, 0x002F, prNa}, // Po [2] FULL STOP..SOLIDUS + {0x0030, 0x0039, prNa}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003B, prNa}, // Po [2] COLON..SEMICOLON + {0x003C, 0x003E, prNa}, // Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN + {0x003F, 0x0040, prNa}, // Po [2] QUESTION MARK..COMMERCIAL AT + {0x0041, 0x005A, prNa}, // Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prNa}, // Ps LEFT SQUARE BRACKET + {0x005C, 0x005C, prNa}, // Po REVERSE SOLIDUS + {0x005D, 0x005D, prNa}, // Pe RIGHT SQUARE BRACKET + {0x005E, 0x005E, prNa}, // Sk CIRCUMFLEX ACCENT + {0x005F, 0x005F, prNa}, // Pc LOW LINE + {0x0060, 0x0060, prNa}, // Sk GRAVE ACCENT + {0x0061, 0x007A, prNa}, // Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prNa}, // Ps LEFT CURLY BRACKET + {0x007C, 0x007C, prNa}, // Sm VERTICAL LINE + {0x007D, 0x007D, prNa}, // Pe RIGHT CURLY BRACKET + {0x007E, 0x007E, prNa}, // Sm TILDE + {0x007F, 0x007F, prN}, // Cc + {0x0080, 0x009F, prN}, // Cc [32] .. + {0x00A0, 0x00A0, prN}, // Zs NO-BREAK SPACE + {0x00A1, 0x00A1, prA}, // Po INVERTED EXCLAMATION MARK + {0x00A2, 0x00A3, prNa}, // Sc [2] CENT SIGN..POUND SIGN + {0x00A4, 0x00A4, prA}, // Sc CURRENCY SIGN + {0x00A5, 0x00A5, prNa}, // Sc YEN SIGN + {0x00A6, 0x00A6, prNa}, // So BROKEN BAR + {0x00A7, 0x00A7, prA}, // Po SECTION SIGN + {0x00A8, 0x00A8, prA}, // Sk DIAERESIS + {0x00A9, 0x00A9, prN}, // So COPYRIGHT SIGN + {0x00AA, 0x00AA, prA}, // Lo FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prN}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AC, 0x00AC, prNa}, // Sm NOT SIGN + {0x00AD, 0x00AD, prA}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prA}, // So REGISTERED SIGN + {0x00AF, 0x00AF, prNa}, // Sk MACRON + {0x00B0, 0x00B0, prA}, // So DEGREE SIGN + {0x00B1, 0x00B1, prA}, // Sm PLUS-MINUS SIGN + {0x00B2, 0x00B3, prA}, // No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE + {0x00B4, 0x00B4, prA}, // Sk ACUTE ACCENT + {0x00B5, 0x00B5, prN}, // Ll MICRO SIGN + {0x00B6, 0x00B7, prA}, // Po [2] PILCROW SIGN..MIDDLE DOT + {0x00B8, 0x00B8, prA}, // Sk CEDILLA + {0x00B9, 0x00B9, prA}, // No SUPERSCRIPT ONE + {0x00BA, 0x00BA, prA}, // Lo MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prN}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00BC, 0x00BE, prA}, // No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS + {0x00BF, 0x00BF, prA}, // Po INVERTED QUESTION MARK + {0x00C0, 0x00C5, prN}, // Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE + {0x00C6, 0x00C6, prA}, // Lu LATIN CAPITAL LETTER AE + {0x00C7, 0x00CF, prN}, // Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS + {0x00D0, 0x00D0, prA}, // Lu LATIN CAPITAL LETTER ETH + {0x00D1, 0x00D6, prN}, // Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D7, 0x00D7, prA}, // Sm MULTIPLICATION SIGN + {0x00D8, 0x00D8, prA}, // Lu LATIN CAPITAL LETTER O WITH STROKE + {0x00D9, 0x00DD, prN}, // Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE + {0x00DE, 0x00E1, prA}, // L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE + {0x00E2, 0x00E5, prN}, // Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE + {0x00E6, 0x00E6, prA}, // Ll LATIN SMALL LETTER AE + {0x00E7, 0x00E7, prN}, // Ll LATIN SMALL LETTER C WITH CEDILLA + {0x00E8, 0x00EA, prA}, // Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX + {0x00EB, 0x00EB, prN}, // Ll LATIN SMALL LETTER E WITH DIAERESIS + {0x00EC, 0x00ED, prA}, // Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE + {0x00EE, 0x00EF, prN}, // Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS + {0x00F0, 0x00F0, prA}, // Ll LATIN SMALL LETTER ETH + {0x00F1, 0x00F1, prN}, // Ll LATIN SMALL LETTER N WITH TILDE + {0x00F2, 0x00F3, prA}, // Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE + {0x00F4, 0x00F6, prN}, // Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F7, 0x00F7, prA}, // Sm DIVISION SIGN + {0x00F8, 0x00FA, prA}, // Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE + {0x00FB, 0x00FB, prN}, // Ll LATIN SMALL LETTER U WITH CIRCUMFLEX + {0x00FC, 0x00FC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS + {0x00FD, 0x00FD, prN}, // Ll LATIN SMALL LETTER Y WITH ACUTE + {0x00FE, 0x00FE, prA}, // Ll LATIN SMALL LETTER THORN + {0x00FF, 0x00FF, prN}, // Ll LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x0100, prN}, // Lu LATIN CAPITAL LETTER A WITH MACRON + {0x0101, 0x0101, prA}, // Ll LATIN SMALL LETTER A WITH MACRON + {0x0102, 0x0110, prN}, // L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE + {0x0111, 0x0111, prA}, // Ll LATIN SMALL LETTER D WITH STROKE + {0x0112, 0x0112, prN}, // Lu LATIN CAPITAL LETTER E WITH MACRON + {0x0113, 0x0113, prA}, // Ll LATIN SMALL LETTER E WITH MACRON + {0x0114, 0x011A, prN}, // L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON + {0x011B, 0x011B, prA}, // Ll LATIN SMALL LETTER E WITH CARON + {0x011C, 0x0125, prN}, // L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX + {0x0126, 0x0127, prA}, // L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE + {0x0128, 0x012A, prN}, // L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON + {0x012B, 0x012B, prA}, // Ll LATIN SMALL LETTER I WITH MACRON + {0x012C, 0x0130, prN}, // L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE + {0x0131, 0x0133, prA}, // L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ + {0x0134, 0x0137, prN}, // L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA + {0x0138, 0x0138, prA}, // Ll LATIN SMALL LETTER KRA + {0x0139, 0x013E, prN}, // L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON + {0x013F, 0x0142, prA}, // L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE + {0x0143, 0x0143, prN}, // Lu LATIN CAPITAL LETTER N WITH ACUTE + {0x0144, 0x0144, prA}, // Ll LATIN SMALL LETTER N WITH ACUTE + {0x0145, 0x0147, prN}, // L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON + {0x0148, 0x014B, prA}, // L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG + {0x014C, 0x014C, prN}, // Lu LATIN CAPITAL LETTER O WITH MACRON + {0x014D, 0x014D, prA}, // Ll LATIN SMALL LETTER O WITH MACRON + {0x014E, 0x0151, prN}, // L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE + {0x0152, 0x0153, prA}, // L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE + {0x0154, 0x0165, prN}, // L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON + {0x0166, 0x0167, prA}, // L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE + {0x0168, 0x016A, prN}, // L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON + {0x016B, 0x016B, prA}, // Ll LATIN SMALL LETTER U WITH MACRON + {0x016C, 0x017F, prN}, // L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S + {0x0180, 0x01BA, prN}, // L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prN}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prN}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prN}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x01CD, prN}, // L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON + {0x01CE, 0x01CE, prA}, // Ll LATIN SMALL LETTER A WITH CARON + {0x01CF, 0x01CF, prN}, // Lu LATIN CAPITAL LETTER I WITH CARON + {0x01D0, 0x01D0, prA}, // Ll LATIN SMALL LETTER I WITH CARON + {0x01D1, 0x01D1, prN}, // Lu LATIN CAPITAL LETTER O WITH CARON + {0x01D2, 0x01D2, prA}, // Ll LATIN SMALL LETTER O WITH CARON + {0x01D3, 0x01D3, prN}, // Lu LATIN CAPITAL LETTER U WITH CARON + {0x01D4, 0x01D4, prA}, // Ll LATIN SMALL LETTER U WITH CARON + {0x01D5, 0x01D5, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON + {0x01D6, 0x01D6, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + {0x01D7, 0x01D7, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE + {0x01D8, 0x01D8, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + {0x01D9, 0x01D9, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON + {0x01DA, 0x01DA, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON + {0x01DB, 0x01DB, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE + {0x01DC, 0x01DC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE + {0x01DD, 0x024F, prN}, // L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE + {0x0250, 0x0250, prN}, // Ll LATIN SMALL LETTER TURNED A + {0x0251, 0x0251, prA}, // Ll LATIN SMALL LETTER ALPHA + {0x0252, 0x0260, prN}, // Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK + {0x0261, 0x0261, prA}, // Ll LATIN SMALL LETTER SCRIPT G + {0x0262, 0x0293, prN}, // Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prN}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prN}, // Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prN}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C3, prN}, // Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD + {0x02C4, 0x02C4, prA}, // Sk MODIFIER LETTER UP ARROWHEAD + {0x02C5, 0x02C5, prN}, // Sk MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02C6, prN}, // Lm MODIFIER LETTER CIRCUMFLEX ACCENT + {0x02C7, 0x02C7, prA}, // Lm CARON + {0x02C8, 0x02C8, prN}, // Lm MODIFIER LETTER VERTICAL LINE + {0x02C9, 0x02CB, prA}, // Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT + {0x02CC, 0x02CC, prN}, // Lm MODIFIER LETTER LOW VERTICAL LINE + {0x02CD, 0x02CD, prA}, // Lm MODIFIER LETTER LOW MACRON + {0x02CE, 0x02CF, prN}, // Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT + {0x02D0, 0x02D0, prA}, // Lm MODIFIER LETTER TRIANGULAR COLON + {0x02D1, 0x02D1, prN}, // Lm MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prN}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02D8, 0x02DB, prA}, // Sk [4] BREVE..OGONEK + {0x02DC, 0x02DC, prN}, // Sk SMALL TILDE + {0x02DD, 0x02DD, prA}, // Sk DOUBLE ACUTE ACCENT + {0x02DE, 0x02DE, prN}, // Sk MODIFIER LETTER RHOTIC HOOK + {0x02DF, 0x02DF, prA}, // Sk MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prN}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prN}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prN}, // Lm MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prN}, // Sk MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prN}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prN}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x036F, prA}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prN}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prN}, // Lm GREEK NUMERAL SIGN + {0x0375, 0x0375, prN}, // Sk GREEK LOWER NUMERAL SIGN + {0x0376, 0x0377, prN}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prN}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prN}, // Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prN}, // Po GREEK QUESTION MARK + {0x037F, 0x037F, prN}, // Lu GREEK CAPITAL LETTER YOT + {0x0384, 0x0385, prN}, // Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS + {0x0386, 0x0386, prN}, // Lu GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prN}, // Po GREEK ANO TELEIA + {0x0388, 0x038A, prN}, // Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prN}, // Lu GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x0390, prN}, // L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + {0x0391, 0x03A1, prA}, // Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03A9, prA}, // Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA + {0x03AA, 0x03B0, prN}, // L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + {0x03B1, 0x03C1, prA}, // Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO + {0x03C2, 0x03C2, prN}, // Ll GREEK SMALL LETTER FINAL SIGMA + {0x03C3, 0x03C9, prA}, // Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA + {0x03CA, 0x03F5, prN}, // L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL + {0x03F6, 0x03F6, prN}, // Sm GREEK REVERSED LUNATE EPSILON SYMBOL + {0x03F7, 0x03FF, prN}, // L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x0400, 0x0400, prN}, // Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE + {0x0401, 0x0401, prA}, // Lu CYRILLIC CAPITAL LETTER IO + {0x0402, 0x040F, prN}, // Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE + {0x0410, 0x044F, prA}, // L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA + {0x0450, 0x0450, prN}, // Ll CYRILLIC SMALL LETTER IE WITH GRAVE + {0x0451, 0x0451, prA}, // Ll CYRILLIC SMALL LETTER IO + {0x0452, 0x0481, prN}, // L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA + {0x0482, 0x0482, prN}, // So CYRILLIC THOUSANDS SIGN + {0x0483, 0x0487, prN}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prN}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x04FF, prN}, // L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x052F, prN}, // L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prN}, // Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prN}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055F, prN}, // Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prN}, // Ll [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prN}, // Po ARMENIAN FULL STOP + {0x058A, 0x058A, prN}, // Pd ARMENIAN HYPHEN + {0x058D, 0x058E, prN}, // So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN + {0x058F, 0x058F, prN}, // Sc ARMENIAN DRAM SIGN + {0x0591, 0x05BD, prN}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BE, 0x05BE, prN}, // Pd HEBREW PUNCTUATION MAQAF + {0x05BF, 0x05BF, prN}, // Mn HEBREW POINT RAFE + {0x05C0, 0x05C0, prN}, // Po HEBREW PUNCTUATION PASEQ + {0x05C1, 0x05C2, prN}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C3, 0x05C3, prN}, // Po HEBREW PUNCTUATION SOF PASUQ + {0x05C4, 0x05C5, prN}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C6, 0x05C6, prN}, // Po HEBREW PUNCTUATION NUN HAFUKHA + {0x05C7, 0x05C7, prN}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prN}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prN}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F4, prN}, // Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prN}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0606, 0x0608, prN}, // Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY + {0x0609, 0x060A, prN}, // Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN + {0x060B, 0x060B, prN}, // Sc AFGHANI SIGN + {0x060C, 0x060D, prN}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x060E, 0x060F, prN}, // So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA + {0x0610, 0x061A, prN}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061B, 0x061B, prN}, // Po ARABIC SEMICOLON + {0x061C, 0x061C, prN}, // Cf ARABIC LETTER MARK + {0x061D, 0x061F, prN}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prN}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prN}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prN}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prN}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prN}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066A, 0x066D, prN}, // Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR + {0x066E, 0x066F, prN}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prN}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prN}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prN}, // Po ARABIC FULL STOP + {0x06D5, 0x06D5, prN}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prN}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prN}, // Cf ARABIC END OF AYAH + {0x06DE, 0x06DE, prN}, // So ARABIC START OF RUB EL HIZB + {0x06DF, 0x06E4, prN}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prN}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prN}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06E9, 0x06E9, prN}, // So ARABIC PLACE OF SAJDAH + {0x06EA, 0x06ED, prN}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prN}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prN}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prN}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FD, 0x06FE, prN}, // So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN + {0x06FF, 0x06FF, prN}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x070D, prN}, // Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS + {0x070F, 0x070F, prN}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prN}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prN}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prN}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prN}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x074F, prN}, // Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE + {0x0750, 0x077F, prN}, // Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE + {0x0780, 0x07A5, prN}, // Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prN}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prN}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prN}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prN}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prN}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prN}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F6, 0x07F6, prN}, // So NKO SYMBOL OO DENNEN + {0x07F7, 0x07F9, prN}, // Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prN}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prN}, // Mn NKO DANTAYALAN + {0x07FE, 0x07FF, prN}, // Sc [2] NKO DOROME SIGN..NKO TAMAN SIGN + {0x0800, 0x0815, prN}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prN}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prN}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prN}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prN}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prN}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prN}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prN}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0830, 0x083E, prN}, // Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prN}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prN}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x085E, 0x085E, prN}, // Po MANDAIC PUNCTUATION + {0x0860, 0x086A, prN}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prN}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0888, 0x0888, prN}, // Sk ARABIC RAISED ROUND DOT + {0x0889, 0x088E, prN}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prN}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prN}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prN}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prN}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prN}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prN}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x08FF, prN}, // Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA + {0x0900, 0x0902, prN}, // Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prN}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prN}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prN}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prN}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prN}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prN}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prN}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prN}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prN}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prN}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prN}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prN}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prN}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prN}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prN}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prN}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prN}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0970, 0x0970, prN}, // Po DEVANAGARI ABBREVIATION SIGN + {0x0971, 0x0971, prN}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x097F, prN}, // Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA + {0x0980, 0x0980, prN}, // Lo BENGALI ANJI + {0x0981, 0x0981, prN}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prN}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prN}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prN}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prN}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prN}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prN}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prN}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prN}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prN}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prN}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prN}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prN}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prN}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prN}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prN}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prN}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prN}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prN}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prN}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prN}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prN}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09F2, 0x09F3, prN}, // Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN + {0x09F4, 0x09F9, prN}, // No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN + {0x09FA, 0x09FA, prN}, // So BENGALI ISSHAR + {0x09FB, 0x09FB, prN}, // Sc BENGALI GANDA MARK + {0x09FC, 0x09FC, prN}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FD, 0x09FD, prN}, // Po BENGALI ABBREVIATION SIGN + {0x09FE, 0x09FE, prN}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prN}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prN}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prN}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prN}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prN}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prN}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prN}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prN}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prN}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prN}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prN}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prN}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prN}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prN}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prN}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prN}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prN}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prN}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prN}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prN}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prN}, // Mn GURMUKHI SIGN YAKASH + {0x0A76, 0x0A76, prN}, // Po GURMUKHI ABBREVIATION SIGN + {0x0A81, 0x0A82, prN}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prN}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prN}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prN}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prN}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prN}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prN}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prN}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prN}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prN}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prN}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prN}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prN}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prN}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prN}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prN}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prN}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prN}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prN}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prN}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF0, 0x0AF0, prN}, // Po GUJARATI ABBREVIATION SIGN + {0x0AF1, 0x0AF1, prN}, // Sc GUJARATI RUPEE SIGN + {0x0AF9, 0x0AF9, prN}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prN}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prN}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prN}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prN}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prN}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prN}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prN}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prN}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prN}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prN}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prN}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prN}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prN}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prN}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prN}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prN}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prN}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prN}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prN}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prN}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prN}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prN}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prN}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prN}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B70, 0x0B70, prN}, // So ORIYA ISSHAR + {0x0B71, 0x0B71, prN}, // Lo ORIYA LETTER WA + {0x0B72, 0x0B77, prN}, // No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS + {0x0B82, 0x0B82, prN}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prN}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prN}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prN}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prN}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prN}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prN}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prN}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prN}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prN}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prN}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prN}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prN}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prN}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prN}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prN}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prN}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prN}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prN}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prN}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0BF0, 0x0BF2, prN}, // No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND + {0x0BF3, 0x0BF8, prN}, // So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN + {0x0BF9, 0x0BF9, prN}, // Sc TAMIL RUPEE SIGN + {0x0BFA, 0x0BFA, prN}, // So TAMIL NUMBER SIGN + {0x0C00, 0x0C00, prN}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prN}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prN}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prN}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prN}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prN}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prN}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prN}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prN}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prN}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prN}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prN}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prN}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prN}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prN}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prN}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prN}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prN}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prN}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C77, 0x0C77, prN}, // Po TELUGU SIGN SIDDHAM + {0x0C78, 0x0C7E, prN}, // No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR + {0x0C7F, 0x0C7F, prN}, // So TELUGU SIGN TUUMU + {0x0C80, 0x0C80, prN}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prN}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prN}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C84, 0x0C84, prN}, // Po KANNADA SIGN SIDDHAM + {0x0C85, 0x0C8C, prN}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prN}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prN}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prN}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prN}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prN}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prN}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prN}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prN}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prN}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prN}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prN}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prN}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prN}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prN}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prN}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prN}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prN}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prN}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prN}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prN}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prN}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prN}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prN}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prN}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prN}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prN}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prN}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prN}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prN}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prN}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prN}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prN}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prN}, // Lo MALAYALAM LETTER DOT REPH + {0x0D4F, 0x0D4F, prN}, // So MALAYALAM SIGN PARA + {0x0D54, 0x0D56, prN}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prN}, // Mc MALAYALAM AU LENGTH MARK + {0x0D58, 0x0D5E, prN}, // No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH + {0x0D5F, 0x0D61, prN}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prN}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prN}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D70, 0x0D78, prN}, // No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS + {0x0D79, 0x0D79, prN}, // So MALAYALAM DATE MARK + {0x0D7A, 0x0D7F, prN}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prN}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prN}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prN}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prN}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prN}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prN}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prN}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prN}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prN}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prN}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prN}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prN}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prN}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prN}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0DF4, 0x0DF4, prN}, // Po SINHALA PUNCTUATION KUNDDALIYA + {0x0E01, 0x0E30, prN}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prN}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prN}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prN}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E3F, 0x0E3F, prN}, // Sc THAI CURRENCY SYMBOL BAHT + {0x0E40, 0x0E45, prN}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prN}, // Lm THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prN}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E4F, 0x0E4F, prN}, // Po THAI CHARACTER FONGMAN + {0x0E50, 0x0E59, prN}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E5A, 0x0E5B, prN}, // Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT + {0x0E81, 0x0E82, prN}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prN}, // Lo LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prN}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prN}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prN}, // Lo LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prN}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prN}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prN}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prN}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prN}, // Lo LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prN}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prN}, // Lm LAO KO LA + {0x0EC8, 0x0ECE, prN}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prN}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prN}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prN}, // Lo TIBETAN SYLLABLE OM + {0x0F01, 0x0F03, prN}, // So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA + {0x0F04, 0x0F12, prN}, // Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD + {0x0F13, 0x0F13, prN}, // So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN + {0x0F14, 0x0F14, prN}, // Po TIBETAN MARK GTER TSHEG + {0x0F15, 0x0F17, prN}, // So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS + {0x0F18, 0x0F19, prN}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F1A, 0x0F1F, prN}, // So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG + {0x0F20, 0x0F29, prN}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F2A, 0x0F33, prN}, // No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO + {0x0F34, 0x0F34, prN}, // So TIBETAN MARK BSDUS RTAGS + {0x0F35, 0x0F35, prN}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F36, 0x0F36, prN}, // So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN + {0x0F37, 0x0F37, prN}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F38, 0x0F38, prN}, // So TIBETAN MARK CHE MGO + {0x0F39, 0x0F39, prN}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prN}, // Ps TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prN}, // Pe TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prN}, // Ps TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prN}, // Pe TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prN}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prN}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prN}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prN}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prN}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prN}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F85, 0x0F85, prN}, // Po TIBETAN MARK PALUTA + {0x0F86, 0x0F87, prN}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prN}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prN}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prN}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FBE, 0x0FC5, prN}, // So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE + {0x0FC6, 0x0FC6, prN}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x0FC7, 0x0FCC, prN}, // So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL + {0x0FCE, 0x0FCF, prN}, // So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM + {0x0FD0, 0x0FD4, prN}, // Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA + {0x0FD5, 0x0FD8, prN}, // So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS + {0x0FD9, 0x0FDA, prN}, // Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS + {0x1000, 0x102A, prN}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prN}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prN}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prN}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prN}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prN}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prN}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prN}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prN}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prN}, // Lo MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prN}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104F, prN}, // Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE + {0x1050, 0x1055, prN}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prN}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prN}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prN}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prN}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prN}, // Lo MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prN}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prN}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prN}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prN}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prN}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prN}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prN}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prN}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prN}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prN}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prN}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prN}, // Lo MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prN}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prN}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prN}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prN}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x109E, 0x109F, prN}, // So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION + {0x10A0, 0x10C5, prN}, // Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prN}, // Lu GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prN}, // Lu GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prN}, // Ll [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FB, 0x10FB, prN}, // Po GEORGIAN PARAGRAPH SEPARATOR + {0x10FC, 0x10FC, prN}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prN}, // Ll [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x115F, prW}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11FF, prN}, // Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN + {0x1200, 0x1248, prN}, // Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prN}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prN}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prN}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prN}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prN}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prN}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prN}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prN}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prN}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prN}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prN}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prN}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prN}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prN}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prN}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prN}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1360, 0x1368, prN}, // Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR + {0x1369, 0x137C, prN}, // No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND + {0x1380, 0x138F, prN}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x1390, 0x1399, prN}, // So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT + {0x13A0, 0x13F5, prN}, // Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prN}, // Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1400, 0x1400, prN}, // Pd CANADIAN SYLLABICS HYPHEN + {0x1401, 0x166C, prN}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166D, 0x166D, prN}, // So CANADIAN SYLLABICS CHI SIGN + {0x166E, 0x166E, prN}, // Po CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prN}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prN}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prN}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prN}, // Ps OGHAM FEATHER MARK + {0x169C, 0x169C, prN}, // Pe OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prN}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EB, 0x16ED, prN}, // Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION + {0x16EE, 0x16F0, prN}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prN}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prN}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prN}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prN}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x171F, prN}, // Lo TAGALOG LETTER ARCHAIC RA + {0x1720, 0x1731, prN}, // Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA + {0x1732, 0x1733, prN}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prN}, // Mc HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prN}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prN}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prN}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prN}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prN}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prN}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prN}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prN}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prN}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prN}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prN}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prN}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prN}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prN}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D4, 0x17D6, prN}, // Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH + {0x17D7, 0x17D7, prN}, // Lm KHMER SIGN LEK TOO + {0x17D8, 0x17DA, prN}, // Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT + {0x17DB, 0x17DB, prN}, // Sc KHMER CURRENCY SYMBOL RIEL + {0x17DC, 0x17DC, prN}, // Lo KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prN}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prN}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x17F0, 0x17F9, prN}, // No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON + {0x1800, 0x1805, prN}, // Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS + {0x1806, 0x1806, prN}, // Pd MONGOLIAN TODO SOFT HYPHEN + {0x1807, 0x180A, prN}, // Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU + {0x180B, 0x180D, prN}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prN}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prN}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prN}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prN}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prN}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prN}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prN}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prN}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prN}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prN}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prN}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prN}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prN}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prN}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prN}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prN}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prN}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prN}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prN}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prN}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prN}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1940, 0x1940, prN}, // So LIMBU SIGN LOO + {0x1944, 0x1945, prN}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prN}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prN}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prN}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prN}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prN}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prN}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x19DA, 0x19DA, prN}, // No NEW TAI LUE THAM DIGIT ONE + {0x19DE, 0x19DF, prN}, // So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV + {0x19E0, 0x19FF, prN}, // So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC + {0x1A00, 0x1A16, prN}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prN}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prN}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prN}, // Mn BUGINESE VOWEL SIGN AE + {0x1A1E, 0x1A1F, prN}, // Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION + {0x1A20, 0x1A54, prN}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prN}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prN}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prN}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prN}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prN}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prN}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prN}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prN}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prN}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prN}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prN}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prN}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prN}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prN}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA0, 0x1AA6, prN}, // Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA + {0x1AA7, 0x1AA7, prN}, // Lm TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAD, prN}, // Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG + {0x1AB0, 0x1ABD, prN}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prN}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prN}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prN}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prN}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prN}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prN}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prN}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prN}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prN}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prN}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prN}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prN}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prN}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prN}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prN}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B60, prN}, // Po [7] BALINESE PANTI..BALINESE PAMENENG + {0x1B61, 0x1B6A, prN}, // So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE + {0x1B6B, 0x1B73, prN}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B74, 0x1B7C, prN}, // So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING + {0x1B7D, 0x1B7E, prN}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prN}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prN}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prN}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prN}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prN}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prN}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prN}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prN}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prN}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prN}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prN}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BBF, prN}, // Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M + {0x1BC0, 0x1BE5, prN}, // Lo [38] BATAK LETTER A..BATAK LETTER U + {0x1BE6, 0x1BE6, prN}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prN}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prN}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prN}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prN}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prN}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prN}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prN}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1BFC, 0x1BFF, prN}, // Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT + {0x1C00, 0x1C23, prN}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prN}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prN}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prN}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prN}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3F, prN}, // Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK + {0x1C40, 0x1C49, prN}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prN}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prN}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prN}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prN}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prN}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prN}, // Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prN}, // Lu [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prN}, // Lu [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CC0, 0x1CC7, prN}, // Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA + {0x1CD0, 0x1CD2, prN}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD3, 0x1CD3, prN}, // Po VEDIC SIGN NIHSHVASA + {0x1CD4, 0x1CE0, prN}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prN}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prN}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prN}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prN}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prN}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prN}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prN}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prN}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prN}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prN}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prN}, // Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prN}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prN}, // Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prN}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D7F, prN}, // Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE + {0x1D80, 0x1D9A, prN}, // Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prN}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prN}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1EFF, prN}, // L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP + {0x1F00, 0x1F15, prN}, // L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prN}, // Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prN}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prN}, // Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prN}, // Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prN}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prN}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prN}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBD, 0x1FBD, prN}, // Sk GREEK KORONIS + {0x1FBE, 0x1FBE, prN}, // Ll GREEK PROSGEGRAMMENI + {0x1FBF, 0x1FC1, prN}, // Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI + {0x1FC2, 0x1FC4, prN}, // Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prN}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FCD, 0x1FCF, prN}, // Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI + {0x1FD0, 0x1FD3, prN}, // Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prN}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FDD, 0x1FDF, prN}, // Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI + {0x1FE0, 0x1FEC, prN}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FED, 0x1FEF, prN}, // Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA + {0x1FF2, 0x1FF4, prN}, // Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prN}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x1FFD, 0x1FFE, prN}, // Sk [2] GREEK OXIA..GREEK DASIA + {0x2000, 0x200A, prN}, // Zs [11] EN QUAD..HAIR SPACE + {0x200B, 0x200F, prN}, // Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK + {0x2010, 0x2010, prA}, // Pd HYPHEN + {0x2011, 0x2012, prN}, // Pd [2] NON-BREAKING HYPHEN..FIGURE DASH + {0x2013, 0x2015, prA}, // Pd [3] EN DASH..HORIZONTAL BAR + {0x2016, 0x2016, prA}, // Po DOUBLE VERTICAL LINE + {0x2017, 0x2017, prN}, // Po DOUBLE LOW LINE + {0x2018, 0x2018, prA}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prA}, // Pf RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prN}, // Ps SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201B, prN}, // Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK + {0x201C, 0x201C, prA}, // Pi LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prA}, // Pf RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prN}, // Ps DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prN}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2020, 0x2022, prA}, // Po [3] DAGGER..BULLET + {0x2023, 0x2023, prN}, // Po TRIANGULAR BULLET + {0x2024, 0x2027, prA}, // Po [4] ONE DOT LEADER..HYPHENATION POINT + {0x2028, 0x2028, prN}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prN}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prN}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prN}, // Zs NARROW NO-BREAK SPACE + {0x2030, 0x2030, prA}, // Po PER MILLE SIGN + {0x2031, 0x2031, prN}, // Po PER TEN THOUSAND SIGN + {0x2032, 0x2033, prA}, // Po [2] PRIME..DOUBLE PRIME + {0x2034, 0x2034, prN}, // Po TRIPLE PRIME + {0x2035, 0x2035, prA}, // Po REVERSED PRIME + {0x2036, 0x2038, prN}, // Po [3] REVERSED DOUBLE PRIME..CARET + {0x2039, 0x2039, prN}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prN}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203B, 0x203B, prA}, // Po REFERENCE MARK + {0x203C, 0x203D, prN}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x203E, 0x203E, prA}, // Po OVERLINE + {0x203F, 0x2040, prN}, // Pc [2] UNDERTIE..CHARACTER TIE + {0x2041, 0x2043, prN}, // Po [3] CARET INSERTION POINT..HYPHEN BULLET + {0x2044, 0x2044, prN}, // Sm FRACTION SLASH + {0x2045, 0x2045, prN}, // Ps LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prN}, // Pe RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2051, prN}, // Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY + {0x2052, 0x2052, prN}, // Sm COMMERCIAL MINUS SIGN + {0x2053, 0x2053, prN}, // Po SWUNG DASH + {0x2054, 0x2054, prN}, // Pc INVERTED UNDERTIE + {0x2055, 0x205E, prN}, // Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS + {0x205F, 0x205F, prN}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prN}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prN}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2070, 0x2070, prN}, // No SUPERSCRIPT ZERO + {0x2071, 0x2071, prN}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x2074, 0x2074, prA}, // No SUPERSCRIPT FOUR + {0x2075, 0x2079, prN}, // No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE + {0x207A, 0x207C, prN}, // Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN + {0x207D, 0x207D, prN}, // Ps SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prN}, // Pe SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prA}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x2080, 0x2080, prN}, // No SUBSCRIPT ZERO + {0x2081, 0x2084, prA}, // No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR + {0x2085, 0x2089, prN}, // No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE + {0x208A, 0x208C, prN}, // Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN + {0x208D, 0x208D, prN}, // Ps SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prN}, // Pe SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prN}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20A0, 0x20A8, prN}, // Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN + {0x20A9, 0x20A9, prH}, // Sc WON SIGN + {0x20AA, 0x20AB, prN}, // Sc [2] NEW SHEQEL SIGN..DONG SIGN + {0x20AC, 0x20AC, prA}, // Sc EURO SIGN + {0x20AD, 0x20C0, prN}, // Sc [20] KIP SIGN..SOM SIGN + {0x20D0, 0x20DC, prN}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prN}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prN}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prN}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prN}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2100, 0x2101, prN}, // So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT + {0x2102, 0x2102, prN}, // Lu DOUBLE-STRUCK CAPITAL C + {0x2103, 0x2103, prA}, // So DEGREE CELSIUS + {0x2104, 0x2104, prN}, // So CENTRE LINE SYMBOL + {0x2105, 0x2105, prA}, // So CARE OF + {0x2106, 0x2106, prN}, // So CADA UNA + {0x2107, 0x2107, prN}, // Lu EULER CONSTANT + {0x2108, 0x2108, prN}, // So SCRUPLE + {0x2109, 0x2109, prA}, // So DEGREE FAHRENHEIT + {0x210A, 0x2112, prN}, // L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L + {0x2113, 0x2113, prA}, // Ll SCRIPT SMALL L + {0x2114, 0x2114, prN}, // So L B BAR SYMBOL + {0x2115, 0x2115, prN}, // Lu DOUBLE-STRUCK CAPITAL N + {0x2116, 0x2116, prA}, // So NUMERO SIGN + {0x2117, 0x2117, prN}, // So SOUND RECORDING COPYRIGHT + {0x2118, 0x2118, prN}, // Sm SCRIPT CAPITAL P + {0x2119, 0x211D, prN}, // Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x211E, 0x2120, prN}, // So [3] PRESCRIPTION TAKE..SERVICE MARK + {0x2121, 0x2122, prA}, // So [2] TELEPHONE SIGN..TRADE MARK SIGN + {0x2123, 0x2123, prN}, // So VERSICLE + {0x2124, 0x2124, prN}, // Lu DOUBLE-STRUCK CAPITAL Z + {0x2125, 0x2125, prN}, // So OUNCE SIGN + {0x2126, 0x2126, prA}, // Lu OHM SIGN + {0x2127, 0x2127, prN}, // So INVERTED OHM SIGN + {0x2128, 0x2128, prN}, // Lu BLACK-LETTER CAPITAL Z + {0x2129, 0x2129, prN}, // So TURNED GREEK SMALL LETTER IOTA + {0x212A, 0x212A, prN}, // Lu KELVIN SIGN + {0x212B, 0x212B, prA}, // Lu ANGSTROM SIGN + {0x212C, 0x212D, prN}, // Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C + {0x212E, 0x212E, prN}, // So ESTIMATED SYMBOL + {0x212F, 0x2134, prN}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prN}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prN}, // Ll INFORMATION SOURCE + {0x213A, 0x213B, prN}, // So [2] ROTATED CAPITAL Q..FACSIMILE SIGN + {0x213C, 0x213F, prN}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2140, 0x2144, prN}, // Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y + {0x2145, 0x2149, prN}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214A, 0x214A, prN}, // So PROPERTY LINE + {0x214B, 0x214B, prN}, // Sm TURNED AMPERSAND + {0x214C, 0x214D, prN}, // So [2] PER SIGN..AKTIESELSKAB + {0x214E, 0x214E, prN}, // Ll TURNED SMALL F + {0x214F, 0x214F, prN}, // So SYMBOL FOR SAMARITAN SOURCE + {0x2150, 0x2152, prN}, // No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH + {0x2153, 0x2154, prA}, // No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS + {0x2155, 0x215A, prN}, // No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS + {0x215B, 0x215E, prA}, // No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS + {0x215F, 0x215F, prN}, // No FRACTION NUMERATOR ONE + {0x2160, 0x216B, prA}, // Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE + {0x216C, 0x216F, prN}, // Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x2179, prA}, // Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN + {0x217A, 0x2182, prN}, // Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prN}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prN}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2189, 0x2189, prA}, // No VULGAR FRACTION ZERO THIRDS + {0x218A, 0x218B, prN}, // So [2] TURNED DIGIT TWO..TURNED DIGIT THREE + {0x2190, 0x2194, prA}, // Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW + {0x2195, 0x2199, prA}, // So [5] UP DOWN ARROW..SOUTH WEST ARROW + {0x219A, 0x219B, prN}, // Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE + {0x219C, 0x219F, prN}, // So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW + {0x21A0, 0x21A0, prN}, // Sm RIGHTWARDS TWO HEADED ARROW + {0x21A1, 0x21A2, prN}, // So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL + {0x21A3, 0x21A3, prN}, // Sm RIGHTWARDS ARROW WITH TAIL + {0x21A4, 0x21A5, prN}, // So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR + {0x21A6, 0x21A6, prN}, // Sm RIGHTWARDS ARROW FROM BAR + {0x21A7, 0x21AD, prN}, // So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW + {0x21AE, 0x21AE, prN}, // Sm LEFT RIGHT ARROW WITH STROKE + {0x21AF, 0x21B7, prN}, // So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW + {0x21B8, 0x21B9, prA}, // So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR + {0x21BA, 0x21CD, prN}, // So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE + {0x21CE, 0x21CF, prN}, // Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE + {0x21D0, 0x21D1, prN}, // So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW + {0x21D2, 0x21D2, prA}, // Sm RIGHTWARDS DOUBLE ARROW + {0x21D3, 0x21D3, prN}, // So DOWNWARDS DOUBLE ARROW + {0x21D4, 0x21D4, prA}, // Sm LEFT RIGHT DOUBLE ARROW + {0x21D5, 0x21E6, prN}, // So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW + {0x21E7, 0x21E7, prA}, // So UPWARDS WHITE ARROW + {0x21E8, 0x21F3, prN}, // So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW + {0x21F4, 0x21FF, prN}, // Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW + {0x2200, 0x2200, prA}, // Sm FOR ALL + {0x2201, 0x2201, prN}, // Sm COMPLEMENT + {0x2202, 0x2203, prA}, // Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS + {0x2204, 0x2206, prN}, // Sm [3] THERE DOES NOT EXIST..INCREMENT + {0x2207, 0x2208, prA}, // Sm [2] NABLA..ELEMENT OF + {0x2209, 0x220A, prN}, // Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF + {0x220B, 0x220B, prA}, // Sm CONTAINS AS MEMBER + {0x220C, 0x220E, prN}, // Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF + {0x220F, 0x220F, prA}, // Sm N-ARY PRODUCT + {0x2210, 0x2210, prN}, // Sm N-ARY COPRODUCT + {0x2211, 0x2211, prA}, // Sm N-ARY SUMMATION + {0x2212, 0x2214, prN}, // Sm [3] MINUS SIGN..DOT PLUS + {0x2215, 0x2215, prA}, // Sm DIVISION SLASH + {0x2216, 0x2219, prN}, // Sm [4] SET MINUS..BULLET OPERATOR + {0x221A, 0x221A, prA}, // Sm SQUARE ROOT + {0x221B, 0x221C, prN}, // Sm [2] CUBE ROOT..FOURTH ROOT + {0x221D, 0x2220, prA}, // Sm [4] PROPORTIONAL TO..ANGLE + {0x2221, 0x2222, prN}, // Sm [2] MEASURED ANGLE..SPHERICAL ANGLE + {0x2223, 0x2223, prA}, // Sm DIVIDES + {0x2224, 0x2224, prN}, // Sm DOES NOT DIVIDE + {0x2225, 0x2225, prA}, // Sm PARALLEL TO + {0x2226, 0x2226, prN}, // Sm NOT PARALLEL TO + {0x2227, 0x222C, prA}, // Sm [6] LOGICAL AND..DOUBLE INTEGRAL + {0x222D, 0x222D, prN}, // Sm TRIPLE INTEGRAL + {0x222E, 0x222E, prA}, // Sm CONTOUR INTEGRAL + {0x222F, 0x2233, prN}, // Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL + {0x2234, 0x2237, prA}, // Sm [4] THEREFORE..PROPORTION + {0x2238, 0x223B, prN}, // Sm [4] DOT MINUS..HOMOTHETIC + {0x223C, 0x223D, prA}, // Sm [2] TILDE OPERATOR..REVERSED TILDE + {0x223E, 0x2247, prN}, // Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + {0x2248, 0x2248, prA}, // Sm ALMOST EQUAL TO + {0x2249, 0x224B, prN}, // Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE + {0x224C, 0x224C, prA}, // Sm ALL EQUAL TO + {0x224D, 0x2251, prN}, // Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO + {0x2252, 0x2252, prA}, // Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x2253, 0x225F, prN}, // Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO + {0x2260, 0x2261, prA}, // Sm [2] NOT EQUAL TO..IDENTICAL TO + {0x2262, 0x2263, prN}, // Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO + {0x2264, 0x2267, prA}, // Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO + {0x2268, 0x2269, prN}, // Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO + {0x226A, 0x226B, prA}, // Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN + {0x226C, 0x226D, prN}, // Sm [2] BETWEEN..NOT EQUIVALENT TO + {0x226E, 0x226F, prA}, // Sm [2] NOT LESS-THAN..NOT GREATER-THAN + {0x2270, 0x2281, prN}, // Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED + {0x2282, 0x2283, prA}, // Sm [2] SUBSET OF..SUPERSET OF + {0x2284, 0x2285, prN}, // Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF + {0x2286, 0x2287, prA}, // Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO + {0x2288, 0x2294, prN}, // Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP + {0x2295, 0x2295, prA}, // Sm CIRCLED PLUS + {0x2296, 0x2298, prN}, // Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH + {0x2299, 0x2299, prA}, // Sm CIRCLED DOT OPERATOR + {0x229A, 0x22A4, prN}, // Sm [11] CIRCLED RING OPERATOR..DOWN TACK + {0x22A5, 0x22A5, prA}, // Sm UP TACK + {0x22A6, 0x22BE, prN}, // Sm [25] ASSERTION..RIGHT ANGLE WITH ARC + {0x22BF, 0x22BF, prA}, // Sm RIGHT TRIANGLE + {0x22C0, 0x22FF, prN}, // Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP + {0x2300, 0x2307, prN}, // So [8] DIAMETER SIGN..WAVY LINE + {0x2308, 0x2308, prN}, // Ps LEFT CEILING + {0x2309, 0x2309, prN}, // Pe RIGHT CEILING + {0x230A, 0x230A, prN}, // Ps LEFT FLOOR + {0x230B, 0x230B, prN}, // Pe RIGHT FLOOR + {0x230C, 0x2311, prN}, // So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE + {0x2312, 0x2312, prA}, // So ARC + {0x2313, 0x2319, prN}, // So [7] SEGMENT..TURNED NOT SIGN + {0x231A, 0x231B, prW}, // So [2] WATCH..HOURGLASS + {0x231C, 0x231F, prN}, // So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER + {0x2320, 0x2321, prN}, // Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL + {0x2322, 0x2328, prN}, // So [7] FROWN..KEYBOARD + {0x2329, 0x2329, prW}, // Ps LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prW}, // Pe RIGHT-POINTING ANGLE BRACKET + {0x232B, 0x237B, prN}, // So [81] ERASE TO THE LEFT..NOT CHECK MARK + {0x237C, 0x237C, prN}, // Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + {0x237D, 0x239A, prN}, // So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL + {0x239B, 0x23B3, prN}, // Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM + {0x23B4, 0x23DB, prN}, // So [40] TOP SQUARE BRACKET..FUSE + {0x23DC, 0x23E1, prN}, // Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET + {0x23E2, 0x23E8, prN}, // So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL + {0x23E9, 0x23EC, prW}, // So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE + {0x23ED, 0x23EF, prN}, // So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR + {0x23F0, 0x23F0, prW}, // So ALARM CLOCK + {0x23F1, 0x23F2, prN}, // So [2] STOPWATCH..TIMER CLOCK + {0x23F3, 0x23F3, prW}, // So HOURGLASS WITH FLOWING SAND + {0x23F4, 0x23FF, prN}, // So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL + {0x2400, 0x2426, prN}, // So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO + {0x2440, 0x244A, prN}, // So [11] OCR HOOK..OCR DOUBLE BACKSLASH + {0x2460, 0x249B, prA}, // No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP + {0x249C, 0x24E9, prA}, // So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24EA, 0x24EA, prN}, // No CIRCLED DIGIT ZERO + {0x24EB, 0x24FF, prA}, // No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO + {0x2500, 0x254B, prA}, // So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0x254C, 0x254F, prN}, // So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + {0x2550, 0x2573, prA}, // So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS + {0x2574, 0x257F, prN}, // So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN + {0x2580, 0x258F, prA}, // So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK + {0x2590, 0x2591, prN}, // So [2] RIGHT HALF BLOCK..LIGHT SHADE + {0x2592, 0x2595, prA}, // So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK + {0x2596, 0x259F, prN}, // So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT + {0x25A0, 0x25A1, prA}, // So [2] BLACK SQUARE..WHITE SQUARE + {0x25A2, 0x25A2, prN}, // So WHITE SQUARE WITH ROUNDED CORNERS + {0x25A3, 0x25A9, prA}, // So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL + {0x25AA, 0x25B1, prN}, // So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM + {0x25B2, 0x25B3, prA}, // So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE + {0x25B4, 0x25B5, prN}, // So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE + {0x25B6, 0x25B6, prA}, // So BLACK RIGHT-POINTING TRIANGLE + {0x25B7, 0x25B7, prA}, // Sm WHITE RIGHT-POINTING TRIANGLE + {0x25B8, 0x25BB, prN}, // So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER + {0x25BC, 0x25BD, prA}, // So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE + {0x25BE, 0x25BF, prN}, // So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE + {0x25C0, 0x25C0, prA}, // So BLACK LEFT-POINTING TRIANGLE + {0x25C1, 0x25C1, prA}, // Sm WHITE LEFT-POINTING TRIANGLE + {0x25C2, 0x25C5, prN}, // So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER + {0x25C6, 0x25C8, prA}, // So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + {0x25C9, 0x25CA, prN}, // So [2] FISHEYE..LOZENGE + {0x25CB, 0x25CB, prA}, // So WHITE CIRCLE + {0x25CC, 0x25CD, prN}, // So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL + {0x25CE, 0x25D1, prA}, // So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK + {0x25D2, 0x25E1, prN}, // So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE + {0x25E2, 0x25E5, prA}, // So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE + {0x25E6, 0x25EE, prN}, // So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + {0x25EF, 0x25EF, prA}, // So LARGE CIRCLE + {0x25F0, 0x25F7, prN}, // So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT + {0x25F8, 0x25FC, prN}, // Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE + {0x25FD, 0x25FE, prW}, // Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE + {0x25FF, 0x25FF, prN}, // Sm LOWER RIGHT TRIANGLE + {0x2600, 0x2604, prN}, // So [5] BLACK SUN WITH RAYS..COMET + {0x2605, 0x2606, prA}, // So [2] BLACK STAR..WHITE STAR + {0x2607, 0x2608, prN}, // So [2] LIGHTNING..THUNDERSTORM + {0x2609, 0x2609, prA}, // So SUN + {0x260A, 0x260D, prN}, // So [4] ASCENDING NODE..OPPOSITION + {0x260E, 0x260F, prA}, // So [2] BLACK TELEPHONE..WHITE TELEPHONE + {0x2610, 0x2613, prN}, // So [4] BALLOT BOX..SALTIRE + {0x2614, 0x2615, prW}, // So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE + {0x2616, 0x261B, prN}, // So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX + {0x261C, 0x261C, prA}, // So WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prN}, // So WHITE UP POINTING INDEX + {0x261E, 0x261E, prA}, // So WHITE RIGHT POINTING INDEX + {0x261F, 0x263F, prN}, // So [33] WHITE DOWN POINTING INDEX..MERCURY + {0x2640, 0x2640, prA}, // So FEMALE SIGN + {0x2641, 0x2641, prN}, // So EARTH + {0x2642, 0x2642, prA}, // So MALE SIGN + {0x2643, 0x2647, prN}, // So [5] JUPITER..PLUTO + {0x2648, 0x2653, prW}, // So [12] ARIES..PISCES + {0x2654, 0x265F, prN}, // So [12] WHITE CHESS KING..BLACK CHESS PAWN + {0x2660, 0x2661, prA}, // So [2] BLACK SPADE SUIT..WHITE HEART SUIT + {0x2662, 0x2662, prN}, // So WHITE DIAMOND SUIT + {0x2663, 0x2665, prA}, // So [3] BLACK CLUB SUIT..BLACK HEART SUIT + {0x2666, 0x2666, prN}, // So BLACK DIAMOND SUIT + {0x2667, 0x266A, prA}, // So [4] WHITE CLUB SUIT..EIGHTH NOTE + {0x266B, 0x266B, prN}, // So BEAMED EIGHTH NOTES + {0x266C, 0x266D, prA}, // So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN + {0x266E, 0x266E, prN}, // So MUSIC NATURAL SIGN + {0x266F, 0x266F, prA}, // Sm MUSIC SHARP SIGN + {0x2670, 0x267E, prN}, // So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN + {0x267F, 0x267F, prW}, // So WHEELCHAIR SYMBOL + {0x2680, 0x2692, prN}, // So [19] DIE FACE-1..HAMMER AND PICK + {0x2693, 0x2693, prW}, // So ANCHOR + {0x2694, 0x269D, prN}, // So [10] CROSSED SWORDS..OUTLINED WHITE STAR + {0x269E, 0x269F, prA}, // So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A0, prN}, // So WARNING SIGN + {0x26A1, 0x26A1, prW}, // So HIGH VOLTAGE SIGN + {0x26A2, 0x26A9, prN}, // So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prW}, // So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE + {0x26AC, 0x26BC, prN}, // So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE + {0x26BD, 0x26BE, prW}, // So [2] SOCCER BALL..BASEBALL + {0x26BF, 0x26BF, prA}, // So SQUARED KEY + {0x26C0, 0x26C3, prN}, // So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prW}, // So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD + {0x26C6, 0x26CD, prA}, // So [8] RAIN..DISABLED CAR + {0x26CE, 0x26CE, prW}, // So OPHIUCHUS + {0x26CF, 0x26D3, prA}, // So [5] PICK..CHAINS + {0x26D4, 0x26D4, prW}, // So NO ENTRY + {0x26D5, 0x26E1, prA}, // So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2 + {0x26E2, 0x26E2, prN}, // So ASTRONOMICAL SYMBOL FOR URANUS + {0x26E3, 0x26E3, prA}, // So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + {0x26E4, 0x26E7, prN}, // So [4] PENTAGRAM..INVERTED PENTAGRAM + {0x26E8, 0x26E9, prA}, // So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE + {0x26EA, 0x26EA, prW}, // So CHURCH + {0x26EB, 0x26F1, prA}, // So [7] CASTLE..UMBRELLA ON GROUND + {0x26F2, 0x26F3, prW}, // So [2] FOUNTAIN..FLAG IN HOLE + {0x26F4, 0x26F4, prA}, // So FERRY + {0x26F5, 0x26F5, prW}, // So SAILBOAT + {0x26F6, 0x26F9, prA}, // So [4] SQUARE FOUR CORNERS..PERSON WITH BALL + {0x26FA, 0x26FA, prW}, // So TENT + {0x26FB, 0x26FC, prA}, // So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prW}, // So FUEL PUMP + {0x26FE, 0x26FF, prA}, // So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + {0x2700, 0x2704, prN}, // So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prW}, // So WHITE HEAVY CHECK MARK + {0x2706, 0x2709, prN}, // So [4] TELEPHONE LOCATION SIGN..ENVELOPE + {0x270A, 0x270B, prW}, // So [2] RAISED FIST..RAISED HAND + {0x270C, 0x2727, prN}, // So [28] VICTORY HAND..WHITE FOUR POINTED STAR + {0x2728, 0x2728, prW}, // So SPARKLES + {0x2729, 0x273C, prN}, // So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK + {0x273D, 0x273D, prA}, // So HEAVY TEARDROP-SPOKED ASTERISK + {0x273E, 0x274B, prN}, // So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + {0x274C, 0x274C, prW}, // So CROSS MARK + {0x274D, 0x274D, prN}, // So SHADOWED WHITE CIRCLE + {0x274E, 0x274E, prW}, // So NEGATIVE SQUARED CROSS MARK + {0x274F, 0x2752, prN}, // So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE + {0x2753, 0x2755, prW}, // So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT + {0x2756, 0x2756, prN}, // So BLACK DIAMOND MINUS WHITE X + {0x2757, 0x2757, prW}, // So HEAVY EXCLAMATION MARK SYMBOL + {0x2758, 0x2767, prN}, // So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET + {0x2768, 0x2768, prN}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prN}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prN}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prN}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prN}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prN}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prN}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prN}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prN}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prN}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prN}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prN}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prN}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prN}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x2776, 0x277F, prA}, // No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN + {0x2780, 0x2793, prN}, // No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + {0x2794, 0x2794, prN}, // So HEAVY WIDE-HEADED RIGHTWARDS ARROW + {0x2795, 0x2797, prW}, // So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN + {0x2798, 0x27AF, prN}, // So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + {0x27B0, 0x27B0, prW}, // So CURLY LOOP + {0x27B1, 0x27BE, prN}, // So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW + {0x27BF, 0x27BF, prW}, // So DOUBLE CURLY LOOP + {0x27C0, 0x27C4, prN}, // Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET + {0x27C5, 0x27C5, prN}, // Ps LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prN}, // Pe RIGHT S-SHAPED BAG DELIMITER + {0x27C7, 0x27E5, prN}, // Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK + {0x27E6, 0x27E6, prNa}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prNa}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prNa}, // Ps MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prNa}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prNa}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prNa}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prNa}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prNa}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prN}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prN}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x27F0, 0x27FF, prN}, // Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW + {0x2800, 0x28FF, prN}, // So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 + {0x2900, 0x297F, prN}, // Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL + {0x2980, 0x2982, prN}, // Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON + {0x2983, 0x2983, prN}, // Ps LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prN}, // Pe RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prNa}, // Ps LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prNa}, // Pe RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prN}, // Ps Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prN}, // Pe Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prN}, // Ps Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prN}, // Pe Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prN}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prN}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prN}, // Ps LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prN}, // Pe RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prN}, // Ps LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prN}, // Pe RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prN}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prN}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prN}, // Ps LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prN}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET + {0x2999, 0x29D7, prN}, // Sm [63] DOTTED FENCE..BLACK HOURGLASS + {0x29D8, 0x29D8, prN}, // Ps LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prN}, // Pe RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prN}, // Ps LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prN}, // Pe RIGHT DOUBLE WIGGLY FENCE + {0x29DC, 0x29FB, prN}, // Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS + {0x29FC, 0x29FC, prN}, // Ps LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prN}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET + {0x29FE, 0x29FF, prN}, // Sm [2] TINY..MINY + {0x2A00, 0x2AFF, prN}, // Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR + {0x2B00, 0x2B1A, prN}, // So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE + {0x2B1B, 0x2B1C, prW}, // So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE + {0x2B1D, 0x2B2F, prN}, // So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE + {0x2B30, 0x2B44, prN}, // Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET + {0x2B45, 0x2B46, prN}, // So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW + {0x2B47, 0x2B4C, prN}, // Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + {0x2B4D, 0x2B4F, prN}, // So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW + {0x2B50, 0x2B50, prW}, // So WHITE MEDIUM STAR + {0x2B51, 0x2B54, prN}, // So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON + {0x2B55, 0x2B55, prW}, // So HEAVY LARGE CIRCLE + {0x2B56, 0x2B59, prA}, // So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE + {0x2B5A, 0x2B73, prN}, // So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR + {0x2B76, 0x2B95, prN}, // So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW + {0x2B97, 0x2BFF, prN}, // So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL + {0x2C00, 0x2C5F, prN}, // L& [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C7B, prN}, // L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prN}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C7F, prN}, // Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL + {0x2C80, 0x2CE4, prN}, // L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI + {0x2CE5, 0x2CEA, prN}, // So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA + {0x2CEB, 0x2CEE, prN}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prN}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prN}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2CF9, 0x2CFC, prN}, // Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER + {0x2CFD, 0x2CFD, prN}, // No COPTIC FRACTION ONE HALF + {0x2CFE, 0x2CFF, prN}, // Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER + {0x2D00, 0x2D25, prN}, // Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prN}, // Ll GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prN}, // Ll GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prN}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prN}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D70, 0x2D70, prN}, // Po TIFINAGH SEPARATOR MARK + {0x2D7F, 0x2D7F, prN}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prN}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prN}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prN}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prN}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prN}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prN}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prN}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prN}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prN}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prN}, // Pi LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prN}, // Pf RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prN}, // Pi LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prN}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prN}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prN}, // Pi LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prN}, // Pf RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prN}, // Po RAISED SQUARE + {0x2E0C, 0x2E0C, prN}, // Pi LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prN}, // Pf RIGHT RAISED OMISSION BRACKET + {0x2E0E, 0x2E16, prN}, // Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE + {0x2E17, 0x2E17, prN}, // Pd DOUBLE OBLIQUE HYPHEN + {0x2E18, 0x2E19, prN}, // Po [2] INVERTED INTERROBANG..PALM BRANCH + {0x2E1A, 0x2E1A, prN}, // Pd HYPHEN WITH DIAERESIS + {0x2E1B, 0x2E1B, prN}, // Po TILDE WITH RING ABOVE + {0x2E1C, 0x2E1C, prN}, // Pi LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prN}, // Pf RIGHT LOW PARAPHRASE BRACKET + {0x2E1E, 0x2E1F, prN}, // Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW + {0x2E20, 0x2E20, prN}, // Pi LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prN}, // Pf RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prN}, // Ps TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prN}, // Pe TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prN}, // Ps BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prN}, // Pe BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prN}, // Ps LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prN}, // Pe RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prN}, // Ps LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prN}, // Pe RIGHT DOUBLE PARENTHESIS + {0x2E2A, 0x2E2E, prN}, // Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prN}, // Lm VERTICAL TILDE + {0x2E30, 0x2E39, prN}, // Po [10] RING POINT..TOP HALF SECTION SIGN + {0x2E3A, 0x2E3B, prN}, // Pd [2] TWO-EM DASH..THREE-EM DASH + {0x2E3C, 0x2E3F, prN}, // Po [4] STENOGRAPHIC FULL STOP..CAPITULUM + {0x2E40, 0x2E40, prN}, // Pd DOUBLE HYPHEN + {0x2E41, 0x2E41, prN}, // Po REVERSED COMMA + {0x2E42, 0x2E42, prN}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E43, 0x2E4F, prN}, // Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER + {0x2E50, 0x2E51, prN}, // So [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR + {0x2E52, 0x2E54, prN}, // Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prN}, // Ps LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prN}, // Pe RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prN}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prN}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prN}, // Ps TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prN}, // Pe TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prN}, // Ps BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prN}, // Pe BOTTOM HALF RIGHT PARENTHESIS + {0x2E5D, 0x2E5D, prN}, // Pd OBLIQUE HYPHEN + {0x2E80, 0x2E99, prW}, // So [26] CJK RADICAL REPEAT..CJK RADICAL RAP + {0x2E9B, 0x2EF3, prW}, // So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE + {0x2F00, 0x2FD5, prW}, // So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE + {0x2FF0, 0x2FFB, prW}, // So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID + {0x3000, 0x3000, prF}, // Zs IDEOGRAPHIC SPACE + {0x3001, 0x3003, prW}, // Po [3] IDEOGRAPHIC COMMA..DITTO MARK + {0x3004, 0x3004, prW}, // So JAPANESE INDUSTRIAL STANDARD SYMBOL + {0x3005, 0x3005, prW}, // Lm IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prW}, // Lo IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prW}, // Nl IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prW}, // Ps LEFT ANGLE BRACKET + {0x3009, 0x3009, prW}, // Pe RIGHT ANGLE BRACKET + {0x300A, 0x300A, prW}, // Ps LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prW}, // Pe RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prW}, // Ps LEFT CORNER BRACKET + {0x300D, 0x300D, prW}, // Pe RIGHT CORNER BRACKET + {0x300E, 0x300E, prW}, // Ps LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prW}, // Pe RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prW}, // Ps LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prW}, // Pe RIGHT BLACK LENTICULAR BRACKET + {0x3012, 0x3013, prW}, // So [2] POSTAL MARK..GETA MARK + {0x3014, 0x3014, prW}, // Ps LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prW}, // Pe RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prW}, // Ps LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prW}, // Pe RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prW}, // Ps LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prW}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prW}, // Ps LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prW}, // Pe RIGHT WHITE SQUARE BRACKET + {0x301C, 0x301C, prW}, // Pd WAVE DASH + {0x301D, 0x301D, prW}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prW}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3020, 0x3020, prW}, // So POSTAL MARK FACE + {0x3021, 0x3029, prW}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prW}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prW}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prW}, // Pd WAVY DASH + {0x3031, 0x3035, prW}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x3036, 0x3037, prW}, // So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL + {0x3038, 0x303A, prW}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prW}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prW}, // Lo MASU MARK + {0x303D, 0x303D, prW}, // Po PART ALTERNATION MARK + {0x303E, 0x303E, prW}, // So IDEOGRAPHIC VARIATION INDICATOR + {0x303F, 0x303F, prN}, // So IDEOGRAPHIC HALF FILL SPACE + {0x3041, 0x3096, prW}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prW}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prW}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prW}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prW}, // Lo HIRAGANA DIGRAPH YORI + {0x30A0, 0x30A0, prW}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30FA, prW}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FB, 0x30FB, prW}, // Po KATAKANA MIDDLE DOT + {0x30FC, 0x30FE, prW}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prW}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prW}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prW}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x3190, 0x3191, prW}, // So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK + {0x3192, 0x3195, prW}, // No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK + {0x3196, 0x319F, prW}, // So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK + {0x31A0, 0x31BF, prW}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31C0, 0x31E3, prW}, // So [36] CJK STROKE T..CJK STROKE Q + {0x31F0, 0x31FF, prW}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3200, 0x321E, prW}, // So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU + {0x3220, 0x3229, prW}, // No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN + {0x322A, 0x3247, prW}, // So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO + {0x3248, 0x324F, prA}, // No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE + {0x3250, 0x3250, prW}, // So PARTNERSHIP SIGN + {0x3251, 0x325F, prW}, // No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE + {0x3260, 0x327F, prW}, // So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL + {0x3280, 0x3289, prW}, // No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN + {0x328A, 0x32B0, prW}, // So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT + {0x32B1, 0x32BF, prW}, // No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY + {0x32C0, 0x32FF, prW}, // So [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA + {0x3300, 0x33FF, prW}, // So [256] SQUARE APAATO..SQUARE GAL + {0x3400, 0x4DBF, prW}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4DC0, 0x4DFF, prN}, // So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION + {0x4E00, 0x9FFF, prW}, // Lo [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF + {0xA000, 0xA014, prW}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prW}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prW}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA490, 0xA4C6, prW}, // So [55] YI RADICAL QOT..YI RADICAL KE + {0xA4D0, 0xA4F7, prN}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prN}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FE, 0xA4FF, prN}, // Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prN}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prN}, // Lm VAI SYLLABLE LENGTHENER + {0xA60D, 0xA60F, prN}, // Po [3] VAI COMMA..VAI QUESTION MARK + {0xA610, 0xA61F, prN}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prN}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prN}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prN}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prN}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prN}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prN}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA673, 0xA673, prN}, // Po SLAVONIC ASTERISK + {0xA674, 0xA67D, prN}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67E, 0xA67E, prN}, // Po CYRILLIC KAVYKA + {0xA67F, 0xA67F, prN}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA69B, prN}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prN}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prN}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prN}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prN}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prN}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F2, 0xA6F7, prN}, // Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK + {0xA700, 0xA716, prN}, // Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prN}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prN}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prN}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prN}, // Lm MODIFIER LETTER US + {0xA771, 0xA787, prN}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prN}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prN}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prN}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prN}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prN}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prN}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prN}, // Ll LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prN}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prN}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prN}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prN}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prN}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prN}, // Ll LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA7FF, prN}, // Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M + {0xA800, 0xA801, prN}, // Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prN}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prN}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prN}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prN}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prN}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prN}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prN}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prN}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prN}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA828, 0xA82B, prN}, // So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 + {0xA82C, 0xA82C, prN}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA830, 0xA835, prN}, // No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS + {0xA836, 0xA837, prN}, // So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK + {0xA838, 0xA838, prN}, // Sc NORTH INDIC RUPEE MARK + {0xA839, 0xA839, prN}, // So NORTH INDIC QUANTITY MARK + {0xA840, 0xA873, prN}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA874, 0xA877, prN}, // Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prN}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prN}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prN}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prN}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prN}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prN}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prN}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prN}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8F8, 0xA8FA, prN}, // Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET + {0xA8FB, 0xA8FB, prN}, // Lo DEVANAGARI HEADSTROKE + {0xA8FC, 0xA8FC, prN}, // Po DEVANAGARI SIGN SIDDHAM + {0xA8FD, 0xA8FE, prN}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prN}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prN}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prN}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prN}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92E, 0xA92F, prN}, // Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA + {0xA930, 0xA946, prN}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prN}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prN}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA95F, 0xA95F, prN}, // Po REJANG SECTION MARK + {0xA960, 0xA97C, prW}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prN}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prN}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prN}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prN}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prN}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prN}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prN}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prN}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prN}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C1, 0xA9CD, prN}, // Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH + {0xA9CF, 0xA9CF, prN}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prN}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9DE, 0xA9DF, prN}, // Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN + {0xA9E0, 0xA9E4, prN}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prN}, // Mn MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prN}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prN}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prN}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prN}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prN}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prN}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prN}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prN}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prN}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prN}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prN}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prN}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prN}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prN}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prN}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prN}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5C, 0xAA5F, prN}, // Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prN}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prN}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prN}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA77, 0xAA79, prN}, // So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO + {0xAA7A, 0xAA7A, prN}, // Lo MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prN}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prN}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prN}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAA7F, prN}, // Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA + {0xAA80, 0xAAAF, prN}, // Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prN}, // Mn TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prN}, // Lo TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prN}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prN}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prN}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prN}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prN}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prN}, // Lo TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prN}, // Mn TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prN}, // Lo TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prN}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prN}, // Lm TAI VIET SYMBOL SAM + {0xAADE, 0xAADF, prN}, // Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI + {0xAAE0, 0xAAEA, prN}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prN}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prN}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prN}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prN}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prN}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prN}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prN}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prN}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prN}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prN}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prN}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prN}, // Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prN}, // Sk MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prN}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prN}, // Ll [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prN}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB6A, 0xAB6B, prN}, // Sk [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK + {0xAB70, 0xABBF, prN}, // Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prN}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prN}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prN}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prN}, // Po MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prN}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prN}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prN}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prW}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prN}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prN}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xD800, 0xDB7F, prN}, // Cs [896] .. + {0xDB80, 0xDBFF, prN}, // Cs [128] .. + {0xDC00, 0xDFFF, prN}, // Cs [1024] .. + {0xE000, 0xF8FF, prA}, // Co [6400] .. + {0xF900, 0xFA6D, prW}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA6E, 0xFA6F, prW}, // Cn [2] .. + {0xFA70, 0xFAD9, prW}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFADA, 0xFAFF, prW}, // Cn [38] .. + {0xFB00, 0xFB06, prN}, // Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prN}, // Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prN}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prN}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prN}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB29, 0xFB29, prN}, // Sm HEBREW LETTER ALTERNATIVE PLUS SIGN + {0xFB2A, 0xFB36, prN}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prN}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prN}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prN}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prN}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prN}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prN}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBB2, 0xFBC2, prN}, // Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE + {0xFBD3, 0xFD3D, prN}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prN}, // Pe ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prN}, // Ps ORNATE RIGHT PARENTHESIS + {0xFD40, 0xFD4F, prN}, // So [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH + {0xFD50, 0xFD8F, prN}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prN}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDCF, 0xFDCF, prN}, // So ARABIC LIGATURE SALAAMUHU ALAYNAA + {0xFDF0, 0xFDFB, prN}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFDFC, 0xFDFC, prN}, // Sc RIAL SIGN + {0xFDFD, 0xFDFF, prN}, // So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL + {0xFE00, 0xFE0F, prA}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE16, prW}, // Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK + {0xFE17, 0xFE17, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE19, 0xFE19, prW}, // Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS + {0xFE20, 0xFE2F, prN}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE30, 0xFE30, prW}, // Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xFE31, 0xFE32, prW}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE33, 0xFE34, prW}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE35, 0xFE35, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE45, 0xFE46, prW}, // Po [2] SESAME DOT..WHITE SESAME DOT + {0xFE47, 0xFE47, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE49, 0xFE4C, prW}, // Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE + {0xFE4D, 0xFE4F, prW}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE52, prW}, // Po [3] SMALL COMMA..SMALL FULL STOP + {0xFE54, 0xFE57, prW}, // Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prW}, // Pd SMALL EM DASH + {0xFE59, 0xFE59, prW}, // Ps SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prW}, // Pe SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prW}, // Ps SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prW}, // Pe SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prW}, // Ps SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prW}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE5F, 0xFE61, prW}, // Po [3] SMALL NUMBER SIGN..SMALL ASTERISK + {0xFE62, 0xFE62, prW}, // Sm SMALL PLUS SIGN + {0xFE63, 0xFE63, prW}, // Pd SMALL HYPHEN-MINUS + {0xFE64, 0xFE66, prW}, // Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN + {0xFE68, 0xFE68, prW}, // Po SMALL REVERSE SOLIDUS + {0xFE69, 0xFE69, prW}, // Sc SMALL DOLLAR SIGN + {0xFE6A, 0xFE6B, prW}, // Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT + {0xFE70, 0xFE74, prN}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prN}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prN}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF03, prF}, // Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN + {0xFF04, 0xFF04, prF}, // Sc FULLWIDTH DOLLAR SIGN + {0xFF05, 0xFF07, prF}, // Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE + {0xFF08, 0xFF08, prF}, // Ps FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prF}, // Pe FULLWIDTH RIGHT PARENTHESIS + {0xFF0A, 0xFF0A, prF}, // Po FULLWIDTH ASTERISK + {0xFF0B, 0xFF0B, prF}, // Sm FULLWIDTH PLUS SIGN + {0xFF0C, 0xFF0C, prF}, // Po FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prF}, // Pd FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0F, prF}, // Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS + {0xFF10, 0xFF19, prF}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1B, prF}, // Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON + {0xFF1C, 0xFF1E, prF}, // Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN + {0xFF1F, 0xFF20, prF}, // Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT + {0xFF21, 0xFF3A, prF}, // Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prF}, // Ps FULLWIDTH LEFT SQUARE BRACKET + {0xFF3C, 0xFF3C, prF}, // Po FULLWIDTH REVERSE SOLIDUS + {0xFF3D, 0xFF3D, prF}, // Pe FULLWIDTH RIGHT SQUARE BRACKET + {0xFF3E, 0xFF3E, prF}, // Sk FULLWIDTH CIRCUMFLEX ACCENT + {0xFF3F, 0xFF3F, prF}, // Pc FULLWIDTH LOW LINE + {0xFF40, 0xFF40, prF}, // Sk FULLWIDTH GRAVE ACCENT + {0xFF41, 0xFF5A, prF}, // Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prF}, // Ps FULLWIDTH LEFT CURLY BRACKET + {0xFF5C, 0xFF5C, prF}, // Sm FULLWIDTH VERTICAL LINE + {0xFF5D, 0xFF5D, prF}, // Pe FULLWIDTH RIGHT CURLY BRACKET + {0xFF5E, 0xFF5E, prF}, // Sm FULLWIDTH TILDE + {0xFF5F, 0xFF5F, prF}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prF}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prH}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prH}, // Ps HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prH}, // Pe HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF65, prH}, // Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT + {0xFF66, 0xFF6F, prH}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prH}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prH}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prH}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prH}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prH}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFE0, 0xFFE1, prF}, // Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN + {0xFFE2, 0xFFE2, prF}, // Sm FULLWIDTH NOT SIGN + {0xFFE3, 0xFFE3, prF}, // Sk FULLWIDTH MACRON + {0xFFE4, 0xFFE4, prF}, // So FULLWIDTH BROKEN BAR + {0xFFE5, 0xFFE6, prF}, // Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN + {0xFFE8, 0xFFE8, prH}, // So HALFWIDTH FORMS LIGHT VERTICAL + {0xFFE9, 0xFFEC, prH}, // Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW + {0xFFED, 0xFFEE, prH}, // So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE + {0xFFF9, 0xFFFB, prN}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0xFFFC, 0xFFFC, prN}, // So OBJECT REPLACEMENT CHARACTER + {0xFFFD, 0xFFFD, prA}, // So REPLACEMENT CHARACTER + {0x10000, 0x1000B, prN}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prN}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prN}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prN}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prN}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prN}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prN}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10100, 0x10102, prN}, // Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK + {0x10107, 0x10133, prN}, // No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND + {0x10137, 0x1013F, prN}, // So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT + {0x10140, 0x10174, prN}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x10175, 0x10178, prN}, // No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN + {0x10179, 0x10189, prN}, // So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN + {0x1018A, 0x1018B, prN}, // No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN + {0x1018C, 0x1018E, prN}, // So [3] GREEK SINUSOID SIGN..NOMISMA SIGN + {0x10190, 0x1019C, prN}, // So [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL + {0x101A0, 0x101A0, prN}, // So GREEK SYMBOL TAU RHO + {0x101D0, 0x101FC, prN}, // So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND + {0x101FD, 0x101FD, prN}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prN}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prN}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prN}, // Mn COPTIC EPACT THOUSANDS MARK + {0x102E1, 0x102FB, prN}, // No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED + {0x10300, 0x1031F, prN}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x10320, 0x10323, prN}, // No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY + {0x1032D, 0x1032F, prN}, // Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE + {0x10330, 0x10340, prN}, // Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prN}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prN}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prN}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prN}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prN}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prN}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x1039F, 0x1039F, prN}, // Po UGARITIC WORD DIVIDER + {0x103A0, 0x103C3, prN}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prN}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D0, 0x103D0, prN}, // Po OLD PERSIAN WORD DIVIDER + {0x103D1, 0x103D5, prN}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prN}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1047F, prN}, // Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW + {0x10480, 0x1049D, prN}, // Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO + {0x104A0, 0x104A9, prN}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prN}, // Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prN}, // Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prN}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prN}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x1056F, 0x1056F, prN}, // Po CAUCASIAN ALBANIAN CITATION MARK + {0x10570, 0x1057A, prN}, // Lu [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prN}, // Lu [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prN}, // Lu [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prN}, // Lu [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prN}, // Ll [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prN}, // Ll [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prN}, // Ll [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prN}, // Ll [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prN}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prN}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prN}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prN}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prN}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prN}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prN}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prN}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prN}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prN}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prN}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x1083F, prN}, // Lo CYPRIOT SYLLABLE ZO + {0x10840, 0x10855, prN}, // Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW + {0x10857, 0x10857, prN}, // Po IMPERIAL ARAMAIC SECTION SIGN + {0x10858, 0x1085F, prN}, // No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND + {0x10860, 0x10876, prN}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10877, 0x10878, prN}, // So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON + {0x10879, 0x1087F, prN}, // No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY + {0x10880, 0x1089E, prN}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108A7, 0x108AF, prN}, // No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED + {0x108E0, 0x108F2, prN}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prN}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x108FB, 0x108FF, prN}, // No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED + {0x10900, 0x10915, prN}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10916, 0x1091B, prN}, // No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE + {0x1091F, 0x1091F, prN}, // Po PHOENICIAN WORD SEPARATOR + {0x10920, 0x10939, prN}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x1093F, 0x1093F, prN}, // Po LYDIAN TRIANGULAR MARK + {0x10980, 0x1099F, prN}, // Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 + {0x109A0, 0x109B7, prN}, // Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BC, 0x109BD, prN}, // No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF + {0x109BE, 0x109BF, prN}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x109C0, 0x109CF, prN}, // No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY + {0x109D2, 0x109FF, prN}, // No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS + {0x10A00, 0x10A00, prN}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prN}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prN}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prN}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prN}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prN}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prN}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prN}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prN}, // Mn KHAROSHTHI VIRAMA + {0x10A40, 0x10A48, prN}, // No [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF + {0x10A50, 0x10A58, prN}, // Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES + {0x10A60, 0x10A7C, prN}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A7D, 0x10A7E, prN}, // No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY + {0x10A7F, 0x10A7F, prN}, // Po OLD SOUTH ARABIAN NUMERIC INDICATOR + {0x10A80, 0x10A9C, prN}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10A9D, 0x10A9F, prN}, // No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY + {0x10AC0, 0x10AC7, prN}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC8, 0x10AC8, prN}, // So MANICHAEAN SIGN UD + {0x10AC9, 0x10AE4, prN}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prN}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10AEB, 0x10AEF, prN}, // No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED + {0x10AF0, 0x10AF6, prN}, // Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER + {0x10B00, 0x10B35, prN}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B39, 0x10B3F, prN}, // Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION + {0x10B40, 0x10B55, prN}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B58, 0x10B5F, prN}, // No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND + {0x10B60, 0x10B72, prN}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B78, 0x10B7F, prN}, // No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND + {0x10B80, 0x10B91, prN}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10B99, 0x10B9C, prN}, // Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT + {0x10BA9, 0x10BAF, prN}, // No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED + {0x10C00, 0x10C48, prN}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prN}, // Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prN}, // Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10CFA, 0x10CFF, prN}, // No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND + {0x10D00, 0x10D23, prN}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prN}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prN}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E60, 0x10E7E, prN}, // No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS + {0x10E80, 0x10EA9, prN}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prN}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EAD, 0x10EAD, prN}, // Pd YEZIDI HYPHENATION MARK + {0x10EB0, 0x10EB1, prN}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prN}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prN}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F1D, 0x10F26, prN}, // No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF + {0x10F27, 0x10F27, prN}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prN}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prN}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F51, 0x10F54, prN}, // No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED + {0x10F55, 0x10F59, prN}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prN}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prN}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prN}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prN}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FC5, 0x10FCB, prN}, // No [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED + {0x10FE0, 0x10FF6, prN}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prN}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prN}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prN}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prN}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prN}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x1104D, prN}, // Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS + {0x11052, 0x11065, prN}, // No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND + {0x11066, 0x1106F, prN}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prN}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prN}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prN}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prN}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x1107F, prN}, // Mn BRAHMI NUMBER JOINER + {0x11080, 0x11081, prN}, // Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prN}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prN}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prN}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prN}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prN}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prN}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BB, 0x110BC, prN}, // Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN + {0x110BD, 0x110BD, prN}, // Cf KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prN}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prN}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prN}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prN}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prN}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prN}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prN}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prN}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prN}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prN}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prN}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11140, 0x11143, prN}, // Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK + {0x11144, 0x11144, prN}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prN}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prN}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prN}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prN}, // Mn MAHAJANI SIGN NUKTA + {0x11174, 0x11175, prN}, // Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK + {0x11176, 0x11176, prN}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prN}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prN}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prN}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prN}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prN}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prN}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prN}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C8, prN}, // Po [4] SHARADA DANDA..SHARADA SEPARATOR + {0x111C9, 0x111CC, prN}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prN}, // Po SHARADA SUTRA MARK + {0x111CE, 0x111CE, prN}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prN}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prN}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prN}, // Lo SHARADA EKAM + {0x111DB, 0x111DB, prN}, // Po SHARADA SIGN SIDDHAM + {0x111DC, 0x111DC, prN}, // Lo SHARADA HEADSTROKE + {0x111DD, 0x111DF, prN}, // Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 + {0x111E1, 0x111F4, prN}, // No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND + {0x11200, 0x11211, prN}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prN}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prN}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prN}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prN}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prN}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prN}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prN}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x1123D, prN}, // Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN + {0x1123E, 0x1123E, prN}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prN}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prN}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prN}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prN}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prN}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prN}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prN}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prN}, // Po MULTANI SECTION MARK + {0x112B0, 0x112DE, prN}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prN}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prN}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prN}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prN}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prN}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prN}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prN}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prN}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prN}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prN}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prN}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prN}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prN}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prN}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prN}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prN}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prN}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prN}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prN}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prN}, // Lo GRANTHA OM + {0x11357, 0x11357, prN}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prN}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prN}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prN}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prN}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prN}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prN}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prN}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prN}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prN}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prN}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prN}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prN}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144F, prN}, // Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN + {0x11450, 0x11459, prN}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145A, 0x1145B, prN}, // Po [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK + {0x1145D, 0x1145D, prN}, // Po NEWA INSERTION SIGN + {0x1145E, 0x1145E, prN}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prN}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prN}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prN}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prN}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prN}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prN}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prN}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prN}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prN}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prN}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prN}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C6, 0x114C6, prN}, // Po TIRHUTA ABBREVIATION SIGN + {0x114C7, 0x114C7, prN}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prN}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prN}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prN}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prN}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prN}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prN}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prN}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prN}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C1, 0x115D7, prN}, // Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prN}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prN}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prN}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prN}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prN}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prN}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prN}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prN}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prN}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11643, prN}, // Po [3] MODI DANDA..MODI ABBREVIATION SIGN + {0x11644, 0x11644, prN}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prN}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11660, 0x1166C, prN}, // Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT + {0x11680, 0x116AA, prN}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prN}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prN}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prN}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prN}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prN}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prN}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prN}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prN}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116B9, 0x116B9, prN}, // Po TAKRI ABBREVIATION SIGN + {0x116C0, 0x116C9, prN}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prN}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prN}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prN}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prN}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prN}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prN}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prN}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173A, 0x1173B, prN}, // No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY + {0x1173C, 0x1173E, prN}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x1173F, 0x1173F, prN}, // So AHOM SYMBOL VI + {0x11740, 0x11746, prN}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prN}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prN}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prN}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prN}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prN}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x1183B, 0x1183B, prN}, // Po DOGRA ABBREVIATION SIGN + {0x118A0, 0x118DF, prN}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prN}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118EA, 0x118F2, prN}, // No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY + {0x118FF, 0x118FF, prN}, // Lo WARANG CITI OM + {0x11900, 0x11906, prN}, // Lo [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E + {0x11909, 0x11909, prN}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prN}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prN}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prN}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prN}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prN}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prN}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prN}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prN}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prN}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prN}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prN}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prN}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prN}, // Mn DIVES AKURU SIGN NUKTA + {0x11944, 0x11946, prN}, // Po [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prN}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prN}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prN}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prN}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prN}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prN}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prN}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prN}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prN}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E2, 0x119E2, prN}, // Po NANDINAGARI SIGN SIDDHAM + {0x119E3, 0x119E3, prN}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prN}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prN}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prN}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prN}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prN}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prN}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prN}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prN}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A3F, 0x11A46, prN}, // Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK + {0x11A47, 0x11A47, prN}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prN}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prN}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prN}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prN}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prN}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prN}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prN}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prN}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9A, 0x11A9C, prN}, // Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prN}, // Lo SOYOMBO MARK PLUTA + {0x11A9E, 0x11AA2, prN}, // Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2 + {0x11AB0, 0x11ABF, prN}, // Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA + {0x11AC0, 0x11AF8, prN}, // Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL + {0x11B00, 0x11B09, prN}, // Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU + {0x11C00, 0x11C08, prN}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prN}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prN}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prN}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prN}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prN}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prN}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prN}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C45, prN}, // Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 + {0x11C50, 0x11C59, prN}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C5A, 0x11C6C, prN}, // No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK + {0x11C70, 0x11C71, prN}, // Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD + {0x11C72, 0x11C8F, prN}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prN}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prN}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prN}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prN}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prN}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prN}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prN}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prN}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prN}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prN}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prN}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prN}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prN}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prN}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prN}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prN}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prN}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prN}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prN}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prN}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prN}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prN}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prN}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prN}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prN}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prN}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prN}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prN}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prN}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prN}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prN}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prN}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prN}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prN}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prN}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prN}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prN}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prN}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prN}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prN}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prN}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prN}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prN}, // Mn KAWI CONJOINER + {0x11F43, 0x11F4F, prN}, // Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL + {0x11F50, 0x11F59, prN}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prN}, // Lo LISU LETTER YHA + {0x11FC0, 0x11FD4, prN}, // No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH + {0x11FD5, 0x11FDC, prN}, // So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI + {0x11FDD, 0x11FE0, prN}, // Sc [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN + {0x11FE1, 0x11FF1, prN}, // So [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA + {0x11FFF, 0x11FFF, prN}, // Po TAMIL PUNCTUATION END OF TEXT + {0x12000, 0x12399, prN}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prN}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12470, 0x12474, prN}, // Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON + {0x12480, 0x12543, prN}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prN}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x12FF1, 0x12FF2, prN}, // Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 + {0x13000, 0x1342F, prN}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prN}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prN}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prN}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prN}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prN}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prN}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prN}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prN}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prN}, // Po [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prN}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prN}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prN}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prN}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prN}, // Po BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prN}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prN}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B3B, prN}, // Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM + {0x16B3C, 0x16B3F, prN}, // So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB + {0x16B40, 0x16B43, prN}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prN}, // Po PAHAWH HMONG SIGN XAUS + {0x16B45, 0x16B45, prN}, // So PAHAWH HMONG SIGN CIM TSOV ROG + {0x16B50, 0x16B59, prN}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B5B, 0x16B61, prN}, // No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS + {0x16B63, 0x16B77, prN}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prN}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prN}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E80, 0x16E96, prN}, // No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM + {0x16E97, 0x16E9A, prN}, // Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH + {0x16F00, 0x16F4A, prN}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prN}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prN}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prN}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prN}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prN}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prW}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE2, 0x16FE2, prW}, // Po OLD CHINESE HOOK MARK + {0x16FE3, 0x16FE3, prW}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prW}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prW}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prW}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18AFF, prW}, // Lo [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768 + {0x18B00, 0x18CD5, prW}, // Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prW}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prW}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prW}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prW}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B0FF, prW}, // Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 + {0x1B100, 0x1B122, prW}, // Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prW}, // Lo HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prW}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prW}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prW}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prW}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prN}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prN}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prN}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prN}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9C, 0x1BC9C, prN}, // So DUPLOYAN SIGN O WITH CROSS + {0x1BC9D, 0x1BC9E, prN}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prN}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prN}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prN}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prN}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1CF50, 0x1CFC3, prN}, // So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK + {0x1D000, 0x1D0F5, prN}, // So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO + {0x1D100, 0x1D126, prN}, // So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 + {0x1D129, 0x1D164, prN}, // So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE + {0x1D165, 0x1D166, prN}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prN}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16A, 0x1D16C, prN}, // So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 + {0x1D16D, 0x1D172, prN}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prN}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prN}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D183, 0x1D184, prN}, // So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN + {0x1D185, 0x1D18B, prN}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D18C, 0x1D1A9, prN}, // So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH + {0x1D1AA, 0x1D1AD, prN}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D1AE, 0x1D1EA, prN}, // So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON + {0x1D200, 0x1D241, prN}, // So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 + {0x1D242, 0x1D244, prN}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D245, 0x1D245, prN}, // So GREEK MUSICAL LEIMMA + {0x1D2C0, 0x1D2D3, prN}, // No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN + {0x1D2E0, 0x1D2F3, prN}, // No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN + {0x1D300, 0x1D356, prN}, // So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING + {0x1D360, 0x1D378, prN}, // No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE + {0x1D400, 0x1D454, prN}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prN}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prN}, // Lu MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prN}, // Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prN}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prN}, // Ll MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prN}, // Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prN}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prN}, // Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prN}, // Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prN}, // Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prN}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prN}, // Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prN}, // Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prN}, // Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prN}, // Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prN}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prN}, // Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C1, 0x1D6C1, prN}, // Sm MATHEMATICAL BOLD NABLA + {0x1D6C2, 0x1D6DA, prN}, // Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DB, 0x1D6DB, prN}, // Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL + {0x1D6DC, 0x1D6FA, prN}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FB, 0x1D6FB, prN}, // Sm MATHEMATICAL ITALIC NABLA + {0x1D6FC, 0x1D714, prN}, // Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D715, 0x1D715, prN}, // Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL + {0x1D716, 0x1D734, prN}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D735, 0x1D735, prN}, // Sm MATHEMATICAL BOLD ITALIC NABLA + {0x1D736, 0x1D74E, prN}, // Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D74F, 0x1D74F, prN}, // Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D750, 0x1D76E, prN}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D76F, 0x1D76F, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD NABLA + {0x1D770, 0x1D788, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D789, 0x1D789, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL + {0x1D78A, 0x1D7A8, prN}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7A9, 0x1D7A9, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA + {0x1D7AA, 0x1D7C2, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C3, 0x1D7C3, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D7C4, 0x1D7CB, prN}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prN}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1D800, 0x1D9FF, prN}, // So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD + {0x1DA00, 0x1DA36, prN}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA37, 0x1DA3A, prN}, // So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE + {0x1DA3B, 0x1DA6C, prN}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA6D, 0x1DA74, prN}, // So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING + {0x1DA75, 0x1DA75, prN}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA76, 0x1DA83, prN}, // So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH + {0x1DA84, 0x1DA84, prN}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA85, 0x1DA86, prN}, // So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS + {0x1DA87, 0x1DA8B, prN}, // Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS + {0x1DA9B, 0x1DA9F, prN}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prN}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prN}, // Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prN}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prN}, // Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prN}, // Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prN}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prN}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prN}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prN}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prN}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prN}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prN}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prN}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prN}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prN}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E14F, 0x1E14F, prN}, // So NYIAKENG PUACHUE HMONG CIRCLED CA + {0x1E290, 0x1E2AD, prN}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prN}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prN}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prN}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prN}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E2FF, 0x1E2FF, prN}, // Sc WANCHO NGUN SIGN + {0x1E4D0, 0x1E4EA, prN}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prN}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prN}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prN}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prN}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prN}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prN}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prN}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prN}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8C7, 0x1E8CF, prN}, // No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE + {0x1E8D0, 0x1E8D6, prN}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prN}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prN}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prN}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prN}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1E95E, 0x1E95F, prN}, // Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK + {0x1EC71, 0x1ECAB, prN}, // No [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE + {0x1ECAC, 0x1ECAC, prN}, // So INDIC SIYAQ PLACEHOLDER + {0x1ECAD, 0x1ECAF, prN}, // No [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS + {0x1ECB0, 0x1ECB0, prN}, // Sc INDIC SIYAQ RUPEE MARK + {0x1ECB1, 0x1ECB4, prN}, // No [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK + {0x1ED01, 0x1ED2D, prN}, // No [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND + {0x1ED2E, 0x1ED2E, prN}, // So OTTOMAN SIYAQ MARRATAN + {0x1ED2F, 0x1ED3D, prN}, // No [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH + {0x1EE00, 0x1EE03, prN}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prN}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prN}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prN}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prN}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prN}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prN}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prN}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prN}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prN}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prN}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prN}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prN}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prN}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prN}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prN}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prN}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prN}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prN}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prN}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prN}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prN}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prN}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prN}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prN}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prN}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prN}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prN}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1EEF0, 0x1EEF1, prN}, // Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL + {0x1F000, 0x1F003, prN}, // So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prW}, // So MAHJONG TILE RED DRAGON + {0x1F005, 0x1F02B, prN}, // So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK + {0x1F030, 0x1F093, prN}, // So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 + {0x1F0A0, 0x1F0AE, prN}, // So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES + {0x1F0B1, 0x1F0BF, prN}, // So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER + {0x1F0C1, 0x1F0CE, prN}, // So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prW}, // So PLAYING CARD BLACK JOKER + {0x1F0D1, 0x1F0F5, prN}, // So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 + {0x1F100, 0x1F10A, prA}, // No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA + {0x1F10B, 0x1F10C, prN}, // No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO + {0x1F10D, 0x1F10F, prN}, // So [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F110, 0x1F12D, prA}, // So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD + {0x1F12E, 0x1F12F, prN}, // So [2] CIRCLED WZ..COPYLEFT SYMBOL + {0x1F130, 0x1F169, prA}, // So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16A, 0x1F16F, prN}, // So [6] RAISED MC SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F18D, prA}, // So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA + {0x1F18E, 0x1F18E, prW}, // So NEGATIVE SQUARED AB + {0x1F18F, 0x1F190, prA}, // So [2] NEGATIVE SQUARED WC..SQUARE DJ + {0x1F191, 0x1F19A, prW}, // So [10] SQUARED CL..SQUARED VS + {0x1F19B, 0x1F1AC, prA}, // So [18] SQUARED THREE D..SQUARED VOD + {0x1F1AD, 0x1F1AD, prN}, // So MASK WORK SYMBOL + {0x1F1E6, 0x1F1FF, prN}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F200, 0x1F202, prW}, // So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA + {0x1F210, 0x1F23B, prW}, // So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D + {0x1F240, 0x1F248, prW}, // So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 + {0x1F250, 0x1F251, prW}, // So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT + {0x1F260, 0x1F265, prW}, // So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI + {0x1F300, 0x1F320, prW}, // So [33] CYCLONE..SHOOTING STAR + {0x1F321, 0x1F32C, prN}, // So [12] THERMOMETER..WIND BLOWING FACE + {0x1F32D, 0x1F335, prW}, // So [9] HOT DOG..CACTUS + {0x1F336, 0x1F336, prN}, // So HOT PEPPER + {0x1F337, 0x1F37C, prW}, // So [70] TULIP..BABY BOTTLE + {0x1F37D, 0x1F37D, prN}, // So FORK AND KNIFE WITH PLATE + {0x1F37E, 0x1F393, prW}, // So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP + {0x1F394, 0x1F39F, prN}, // So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS + {0x1F3A0, 0x1F3CA, prW}, // So [43] CAROUSEL HORSE..SWIMMER + {0x1F3CB, 0x1F3CE, prN}, // So [4] WEIGHT LIFTER..RACING CAR + {0x1F3CF, 0x1F3D3, prW}, // So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL + {0x1F3D4, 0x1F3DF, prN}, // So [12] SNOW CAPPED MOUNTAIN..STADIUM + {0x1F3E0, 0x1F3F0, prW}, // So [17] HOUSE BUILDING..EUROPEAN CASTLE + {0x1F3F1, 0x1F3F3, prN}, // So [3] WHITE PENNANT..WAVING WHITE FLAG + {0x1F3F4, 0x1F3F4, prW}, // So WAVING BLACK FLAG + {0x1F3F5, 0x1F3F7, prN}, // So [3] ROSETTE..LABEL + {0x1F3F8, 0x1F3FA, prW}, // So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA + {0x1F3FB, 0x1F3FF, prW}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F43E, prW}, // So [63] RAT..PAW PRINTS + {0x1F43F, 0x1F43F, prN}, // So CHIPMUNK + {0x1F440, 0x1F440, prW}, // So EYES + {0x1F441, 0x1F441, prN}, // So EYE + {0x1F442, 0x1F4FC, prW}, // So [187] EAR..VIDEOCASSETTE + {0x1F4FD, 0x1F4FE, prN}, // So [2] FILM PROJECTOR..PORTABLE STEREO + {0x1F4FF, 0x1F53D, prW}, // So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE + {0x1F53E, 0x1F54A, prN}, // So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE + {0x1F54B, 0x1F54E, prW}, // So [4] KAABA..MENORAH WITH NINE BRANCHES + {0x1F54F, 0x1F54F, prN}, // So BOWL OF HYGIEIA + {0x1F550, 0x1F567, prW}, // So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY + {0x1F568, 0x1F579, prN}, // So [18] RIGHT SPEAKER..JOYSTICK + {0x1F57A, 0x1F57A, prW}, // So MAN DANCING + {0x1F57B, 0x1F594, prN}, // So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prW}, // So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS + {0x1F597, 0x1F5A3, prN}, // So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prW}, // So BLACK HEART + {0x1F5A5, 0x1F5FA, prN}, // So [86] DESKTOP COMPUTER..WORLD MAP + {0x1F5FB, 0x1F5FF, prW}, // So [5] MOUNT FUJI..MOYAI + {0x1F600, 0x1F64F, prW}, // So [80] GRINNING FACE..PERSON WITH FOLDED HANDS + {0x1F650, 0x1F67F, prN}, // So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD + {0x1F680, 0x1F6C5, prW}, // So [70] ROCKET..LEFT LUGGAGE + {0x1F6C6, 0x1F6CB, prN}, // So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP + {0x1F6CC, 0x1F6CC, prW}, // So SLEEPING ACCOMMODATION + {0x1F6CD, 0x1F6CF, prN}, // So [3] SHOPPING BAGS..BED + {0x1F6D0, 0x1F6D2, prW}, // So [3] PLACE OF WORSHIP..SHOPPING TROLLEY + {0x1F6D3, 0x1F6D4, prN}, // So [2] STUPA..PAGODA + {0x1F6D5, 0x1F6D7, prW}, // So [3] HINDU TEMPLE..ELEVATOR + {0x1F6DC, 0x1F6DF, prW}, // So [4] WIRELESS..RING BUOY + {0x1F6E0, 0x1F6EA, prN}, // So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prW}, // So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING + {0x1F6F0, 0x1F6F3, prN}, // So [4] SATELLITE..PASSENGER SHIP + {0x1F6F4, 0x1F6FC, prW}, // So [9] SCOOTER..ROLLER SKATE + {0x1F700, 0x1F776, prN}, // So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE + {0x1F77B, 0x1F77F, prN}, // So [5] HAUMEA..ORCUS + {0x1F780, 0x1F7D9, prN}, // So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR + {0x1F7E0, 0x1F7EB, prW}, // So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE + {0x1F7F0, 0x1F7F0, prW}, // So HEAVY EQUALS SIGN + {0x1F800, 0x1F80B, prN}, // So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD + {0x1F810, 0x1F847, prN}, // So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW + {0x1F850, 0x1F859, prN}, // So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW + {0x1F860, 0x1F887, prN}, // So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW + {0x1F890, 0x1F8AD, prN}, // So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS + {0x1F8B0, 0x1F8B1, prN}, // So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST + {0x1F900, 0x1F90B, prN}, // So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT + {0x1F90C, 0x1F93A, prW}, // So [47] PINCHED FINGERS..FENCER + {0x1F93B, 0x1F93B, prN}, // So MODERN PENTATHLON + {0x1F93C, 0x1F945, prW}, // So [10] WRESTLERS..GOAL NET + {0x1F946, 0x1F946, prN}, // So RIFLE + {0x1F947, 0x1F9FF, prW}, // So [185] FIRST PLACE MEDAL..NAZAR AMULET + {0x1FA00, 0x1FA53, prN}, // So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP + {0x1FA60, 0x1FA6D, prN}, // So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER + {0x1FA70, 0x1FA7C, prW}, // So [13] BALLET SHOES..CRUTCH + {0x1FA80, 0x1FA88, prW}, // So [9] YO-YO..FLUTE + {0x1FA90, 0x1FABD, prW}, // So [46] RINGED PLANET..WING + {0x1FABF, 0x1FAC5, prW}, // So [7] GOOSE..PERSON WITH CROWN + {0x1FACE, 0x1FADB, prW}, // So [14] MOOSE..PEA POD + {0x1FAE0, 0x1FAE8, prW}, // So [9] MELTING FACE..SHAKING FACE + {0x1FAF0, 0x1FAF8, prW}, // So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND + {0x1FB00, 0x1FB92, prN}, // So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK + {0x1FB94, 0x1FBCA, prN}, // So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON + {0x1FBF0, 0x1FBF9, prN}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x20000, 0x2A6DF, prW}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A6E0, 0x2A6FF, prW}, // Cn [32] .. + {0x2A700, 0x2B739, prW}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B73A, 0x2B73F, prW}, // Cn [6] .. + {0x2B740, 0x2B81D, prW}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B81E, 0x2B81F, prW}, // Cn [2] .. + {0x2B820, 0x2CEA1, prW}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEA2, 0x2CEAF, prW}, // Cn [14] .. + {0x2CEB0, 0x2EBE0, prW}, // Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2EBE1, 0x2F7FF, prW}, // Cn [3103] .. + {0x2F800, 0x2FA1D, prW}, // Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x2FA1E, 0x2FA1F, prW}, // Cn [2] .. + {0x2FA20, 0x2FFFD, prW}, // Cn [1502] .. + {0x30000, 0x3134A, prW}, // Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x3134B, 0x3134F, prW}, // Cn [5] .. + {0x31350, 0x323AF, prW}, // Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0x323B0, 0x3FFFD, prW}, // Cn [56398] .. + {0xE0001, 0xE0001, prN}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prN}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prA}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xF0000, 0xFFFFD, prA}, // Co [65534] .. + {0x100000, 0x10FFFD, prA}, // Co [65534] .. +} diff --git a/vendor/github.com/rivo/uniseg/emojipresentation.go b/vendor/github.com/rivo/uniseg/emojipresentation.go new file mode 100644 index 000000000000..9b5f499c4a04 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/emojipresentation.go @@ -0,0 +1,295 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// emojiPresentation are taken from +// +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var emojiPresentation = [][3]int{ + {0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (โŒš..โŒ›) watch..hourglass done + {0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (โฉ..โฌ) fast-forward button..fast down button + {0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (โฐ) alarm clock + {0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (โณ) hourglass not done + {0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (โ—ฝ..โ—พ) white medium-small square..black medium-small square + {0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (โ˜”..โ˜•) umbrella with rain drops..hot beverage + {0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (โ™ˆ..โ™“) Aries..Pisces + {0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (โ™ฟ) wheelchair symbol + {0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (โš“) anchor + {0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (โšก) high voltage + {0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (โšช..โšซ) white circle..black circle + {0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (โšฝ..โšพ) soccer ball..baseball + {0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (โ›„..โ›…) snowman without snow..sun behind cloud + {0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (โ›Ž) Ophiuchus + {0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (โ›”) no entry + {0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (โ›ช) church + {0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (โ›ฒ..โ›ณ) fountain..flag in hole + {0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (โ›ต) sailboat + {0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (โ›บ) tent + {0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (โ›ฝ) fuel pump + {0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (โœ…) check mark button + {0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (โœŠ..โœ‹) raised fist..raised hand + {0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (โœจ) sparkles + {0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (โŒ) cross mark + {0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (โŽ) cross mark button + {0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (โ“..โ•) red question mark..white exclamation mark + {0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (โ—) red exclamation mark + {0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (โž•..โž—) plus..divide + {0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (โžฐ) curly loop + {0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (โžฟ) double curly loop + {0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (โฌ›..โฌœ) black large square..white large square + {0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (โญ) star + {0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (โญ•) hollow red circle + {0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (๐Ÿ€„) mahjong red dragon + {0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (๐Ÿƒ) joker + {0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (๐Ÿ†Ž) AB button (blood type) + {0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (๐Ÿ†‘..๐Ÿ†š) CL button..VS button + {0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (๐Ÿ‡ฆ..๐Ÿ‡ฟ) regional indicator symbol letter a..regional indicator symbol letter z + {0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (๐Ÿˆ) Japanese โ€œhereโ€ button + {0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (๐Ÿˆš) Japanese โ€œfree of chargeโ€ button + {0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (๐Ÿˆฏ) Japanese โ€œreservedโ€ button + {0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (๐Ÿˆฒ..๐Ÿˆถ) Japanese โ€œprohibitedโ€ button..Japanese โ€œnot free of chargeโ€ button + {0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (๐Ÿˆธ..๐Ÿˆบ) Japanese โ€œapplicationโ€ button..Japanese โ€œopen for businessโ€ button + {0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (๐Ÿ‰..๐Ÿ‰‘) Japanese โ€œbargainโ€ button..Japanese โ€œacceptableโ€ button + {0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (๐ŸŒ€..๐ŸŒŒ) cyclone..milky way + {0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (๐ŸŒ..๐ŸŒŽ) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (๐ŸŒ) globe showing Asia-Australia + {0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (๐ŸŒ) globe with meridians + {0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (๐ŸŒ‘) new moon + {0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (๐ŸŒ’) waxing crescent moon + {0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (๐ŸŒ“..๐ŸŒ•) first quarter moon..full moon + {0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (๐ŸŒ–..๐ŸŒ˜) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (๐ŸŒ™) crescent moon + {0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (๐ŸŒš) new moon face + {0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (๐ŸŒ›) first quarter moon face + {0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (๐ŸŒœ) last quarter moon face + {0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (๐ŸŒ..๐ŸŒž) full moon face..sun with face + {0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (๐ŸŒŸ..๐ŸŒ ) glowing star..shooting star + {0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (๐ŸŒญ..๐ŸŒฏ) hot dog..burrito + {0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (๐ŸŒฐ..๐ŸŒฑ) chestnut..seedling + {0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (๐ŸŒฒ..๐ŸŒณ) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (๐ŸŒด..๐ŸŒต) palm tree..cactus + {0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (๐ŸŒท..๐ŸŠ) tulip..tangerine + {0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (๐Ÿ‹) lemon + {0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (๐ŸŒ..๐Ÿ) banana..green apple + {0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (๐Ÿ) pear + {0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (๐Ÿ‘..๐Ÿป) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (๐Ÿผ) baby bottle + {0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (๐Ÿพ..๐Ÿฟ) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (๐ŸŽ€..๐ŸŽ“) ribbon..graduation cap + {0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (๐ŸŽ ..๐Ÿ„) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (๐Ÿ…) sports medal + {0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (๐Ÿ†) trophy + {0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (๐Ÿ‡) horse racing + {0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (๐Ÿˆ) american football + {0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (๐Ÿ‰) rugby football + {0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (๐ŸŠ) person swimming + {0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (๐Ÿ..๐Ÿ“) cricket game..ping pong + {0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (๐Ÿ ..๐Ÿฃ) house..Japanese post office + {0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (๐Ÿค) post office + {0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (๐Ÿฅ..๐Ÿฐ) hospital..castle + {0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (๐Ÿด) black flag + {0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (๐Ÿธ..๐Ÿ‡) badminton..rabbit + {0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (๐Ÿˆ) cat + {0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (๐Ÿ‰..๐Ÿ‹) dragon..whale + {0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (๐ŸŒ..๐ŸŽ) snail..horse + {0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (๐Ÿ..๐Ÿ) ram..goat + {0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (๐Ÿ‘..๐Ÿ’) ewe..monkey + {0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (๐Ÿ“) rooster + {0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (๐Ÿ”) chicken + {0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (๐Ÿ•) dog + {0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (๐Ÿ–) pig + {0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (๐Ÿ—..๐Ÿฉ) boar..poodle + {0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (๐Ÿช) camel + {0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (๐Ÿซ..๐Ÿพ) two-hump camel..paw prints + {0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (๐Ÿ‘€) eyes + {0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (๐Ÿ‘‚..๐Ÿ‘ค) ear..bust in silhouette + {0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (๐Ÿ‘ฅ) busts in silhouette + {0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (๐Ÿ‘ฆ..๐Ÿ‘ซ) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (๐Ÿ‘ฌ..๐Ÿ‘ญ) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (๐Ÿ‘ฎ..๐Ÿ’ฌ) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (๐Ÿ’ญ) thought balloon + {0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (๐Ÿ’ฎ..๐Ÿ’ต) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (๐Ÿ’ถ..๐Ÿ’ท) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (๐Ÿ’ธ..๐Ÿ“ซ) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (๐Ÿ“ฌ..๐Ÿ“ญ) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (๐Ÿ“ฎ) postbox + {0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (๐Ÿ“ฏ) postal horn + {0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (๐Ÿ“ฐ..๐Ÿ“ด) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (๐Ÿ“ต) no mobile phones + {0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (๐Ÿ“ถ..๐Ÿ“ท) antenna bars..camera + {0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (๐Ÿ“ธ) camera with flash + {0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (๐Ÿ“น..๐Ÿ“ผ) video camera..videocassette + {0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (๐Ÿ“ฟ..๐Ÿ”‚) prayer beads..repeat single button + {0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (๐Ÿ”ƒ) clockwise vertical arrows + {0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (๐Ÿ”„..๐Ÿ”‡) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (๐Ÿ”ˆ) speaker low volume + {0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (๐Ÿ”‰) speaker medium volume + {0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (๐Ÿ”Š..๐Ÿ””) speaker high volume..bell + {0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (๐Ÿ”•) bell with slash + {0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (๐Ÿ”–..๐Ÿ”ซ) bookmark..water pistol + {0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (๐Ÿ”ฌ..๐Ÿ”ญ) microscope..telescope + {0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (๐Ÿ”ฎ..๐Ÿ”ฝ) crystal ball..downwards button + {0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (๐Ÿ•‹..๐Ÿ•Ž) kaaba..menorah + {0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (๐Ÿ•..๐Ÿ•›) one oโ€™clock..twelve oโ€™clock + {0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (๐Ÿ•œ..๐Ÿ•ง) one-thirty..twelve-thirty + {0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (๐Ÿ•บ) man dancing + {0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (๐Ÿ–•..๐Ÿ––) middle finger..vulcan salute + {0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (๐Ÿ–ค) black heart + {0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (๐Ÿ—ป..๐Ÿ—ฟ) mount fuji..moai + {0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜€) grinning face + {0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (๐Ÿ˜..๐Ÿ˜†) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (๐Ÿ˜‡..๐Ÿ˜ˆ) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (๐Ÿ˜‰..๐Ÿ˜) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜Ž) smiling face with sunglasses + {0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜) smirking face + {0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (๐Ÿ˜) neutral face + {0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜‘) expressionless face + {0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (๐Ÿ˜’..๐Ÿ˜”) unamused face..pensive face + {0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜•) confused face + {0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜–) confounded face + {0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜—) kissing face + {0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜˜) face blowing a kiss + {0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜™) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜š) kissing face with closed eyes + {0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜›) face with tongue + {0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (๐Ÿ˜œ..๐Ÿ˜ž) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜Ÿ) worried face + {0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (๐Ÿ˜ ..๐Ÿ˜ฅ) angry face..sad but relieved face + {0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (๐Ÿ˜ฆ..๐Ÿ˜ง) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (๐Ÿ˜จ..๐Ÿ˜ซ) fearful face..tired face + {0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜ฌ) grimacing face + {0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜ญ) loudly crying face + {0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (๐Ÿ˜ฎ..๐Ÿ˜ฏ) face with open mouth..hushed face + {0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (๐Ÿ˜ฐ..๐Ÿ˜ณ) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜ด) sleeping face + {0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (๐Ÿ˜ต) face with crossed-out eyes + {0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (๐Ÿ˜ถ) face without mouth + {0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (๐Ÿ˜ท..๐Ÿ™€) face with medical mask..weary cat + {0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (๐Ÿ™..๐Ÿ™„) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (๐Ÿ™…..๐Ÿ™) person gesturing NO..folded hands + {0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (๐Ÿš€) rocket + {0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (๐Ÿš..๐Ÿš‚) helicopter..locomotive + {0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (๐Ÿšƒ..๐Ÿš…) railway car..bullet train + {0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (๐Ÿš†) train + {0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (๐Ÿš‡) metro + {0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (๐Ÿšˆ) light rail + {0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (๐Ÿš‰) station + {0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (๐ŸšŠ..๐Ÿš‹) tram..tram car + {0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (๐ŸšŒ) bus + {0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (๐Ÿš) oncoming bus + {0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (๐ŸšŽ) trolleybus + {0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (๐Ÿš) bus stop + {0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (๐Ÿš) minibus + {0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (๐Ÿš‘..๐Ÿš“) ambulance..police car + {0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (๐Ÿš”) oncoming police car + {0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (๐Ÿš•) taxi + {0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (๐Ÿš–) oncoming taxi + {0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (๐Ÿš—) automobile + {0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (๐Ÿš˜) oncoming automobile + {0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (๐Ÿš™..๐Ÿšš) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (๐Ÿš›..๐Ÿšก) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (๐Ÿšข) ship + {0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (๐Ÿšฃ) person rowing boat + {0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (๐Ÿšค..๐Ÿšฅ) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (๐Ÿšฆ) vertical traffic light + {0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (๐Ÿšง..๐Ÿšญ) construction..no smoking + {0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (๐Ÿšฎ..๐Ÿšฑ) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (๐Ÿšฒ) bicycle + {0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (๐Ÿšณ..๐Ÿšต) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (๐Ÿšถ) person walking + {0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (๐Ÿšท..๐Ÿšธ) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (๐Ÿšน..๐Ÿšพ) menโ€™s room..water closet + {0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (๐Ÿšฟ) shower + {0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (๐Ÿ›€) person taking bath + {0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (๐Ÿ›..๐Ÿ›…) bathtub..left luggage + {0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (๐Ÿ›Œ) person in bed + {0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (๐Ÿ›) place of worship + {0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (๐Ÿ›‘..๐Ÿ›’) stop sign..shopping cart + {0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (๐Ÿ›•) hindu temple + {0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (๐Ÿ›–..๐Ÿ›—) hut..elevator + {0x1F6DC, 0x1F6DC, prEmojiPresentation}, // E15.0 [1] (๐Ÿ›œ) wireless + {0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (๐Ÿ›..๐Ÿ›Ÿ) playground slide..ring buoy + {0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (๐Ÿ›ซ..๐Ÿ›ฌ) airplane departure..airplane arrival + {0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (๐Ÿ›ด..๐Ÿ›ถ) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (๐Ÿ›ท..๐Ÿ›ธ) sled..flying saucer + {0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (๐Ÿ›น) skateboard + {0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (๐Ÿ›บ) auto rickshaw + {0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (๐Ÿ›ป..๐Ÿ›ผ) pickup truck..roller skate + {0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (๐ŸŸ ..๐ŸŸซ) orange circle..brown square + {0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (๐ŸŸฐ) heavy equals sign + {0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (๐ŸคŒ) pinched fingers + {0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (๐Ÿค..๐Ÿค) white heart..pinching hand + {0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (๐Ÿค..๐Ÿค˜) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (๐Ÿค™..๐Ÿคž) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (๐ŸคŸ) love-you gesture + {0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (๐Ÿค ..๐Ÿคง) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (๐Ÿคจ..๐Ÿคฏ) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (๐Ÿคฐ) pregnant woman + {0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (๐Ÿคฑ..๐Ÿคฒ) breast-feeding..palms up together + {0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (๐Ÿคณ..๐Ÿคบ) selfie..person fencing + {0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (๐Ÿคผ..๐Ÿคพ) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (๐Ÿคฟ) diving mask + {0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (๐Ÿฅ€..๐Ÿฅ…) wilted flower..goal net + {0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (๐Ÿฅ‡..๐Ÿฅ‹) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (๐ŸฅŒ) curling stone + {0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (๐Ÿฅ..๐Ÿฅ) lacrosse..flying disc + {0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (๐Ÿฅ..๐Ÿฅž) croissant..pancakes + {0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (๐ŸฅŸ..๐Ÿฅซ) dumpling..canned food + {0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (๐Ÿฅฌ..๐Ÿฅฐ) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (๐Ÿฅฑ) yawning face + {0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (๐Ÿฅฒ) smiling face with tear + {0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (๐Ÿฅณ..๐Ÿฅถ) partying face..cold face + {0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (๐Ÿฅท..๐Ÿฅธ) ninja..disguised face + {0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (๐Ÿฅน) face holding back tears + {0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (๐Ÿฅบ) pleading face + {0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (๐Ÿฅป) sari + {0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (๐Ÿฅผ..๐Ÿฅฟ) lab coat..flat shoe + {0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (๐Ÿฆ€..๐Ÿฆ„) crab..unicorn + {0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (๐Ÿฆ…..๐Ÿฆ‘) eagle..squid + {0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (๐Ÿฆ’..๐Ÿฆ—) giraffe..cricket + {0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (๐Ÿฆ˜..๐Ÿฆข) kangaroo..swan + {0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (๐Ÿฆฃ..๐Ÿฆค) mammoth..dodo + {0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (๐Ÿฆฅ..๐Ÿฆช) sloth..oyster + {0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (๐Ÿฆซ..๐Ÿฆญ) beaver..seal + {0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (๐Ÿฆฎ..๐Ÿฆฏ) guide dog..white cane + {0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (๐Ÿฆฐ..๐Ÿฆน) red hair..supervillain + {0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (๐Ÿฆบ..๐Ÿฆฟ) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (๐Ÿง€) cheese wedge + {0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (๐Ÿง..๐Ÿง‚) cupcake..salt + {0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (๐Ÿงƒ..๐ŸงŠ) beverage box..ice + {0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (๐Ÿง‹) bubble tea + {0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (๐ŸงŒ) troll + {0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (๐Ÿง..๐Ÿง) person standing..deaf person + {0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (๐Ÿง..๐Ÿงฆ) face with monocle..socks + {0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (๐Ÿงง..๐Ÿงฟ) red envelope..nazar amulet + {0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (๐Ÿฉฐ..๐Ÿฉณ) ballet shoes..shorts + {0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (๐Ÿฉด) thong sandal + {0x1FA75, 0x1FA77, prEmojiPresentation}, // E15.0 [3] (๐Ÿฉต..๐Ÿฉท) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (๐Ÿฉธ..๐Ÿฉบ) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (๐Ÿฉป..๐Ÿฉผ) x-ray..crutch + {0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (๐Ÿช€..๐Ÿช‚) yo-yo..parachute + {0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (๐Ÿชƒ..๐Ÿช†) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prEmojiPresentation}, // E15.0 [2] (๐Ÿช‡..๐Ÿชˆ) maracas..flute + {0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (๐Ÿช..๐Ÿช•) ringed planet..banjo + {0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (๐Ÿช–..๐Ÿชจ) military helmet..rock + {0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (๐Ÿชฉ..๐Ÿชฌ) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prEmojiPresentation}, // E15.0 [3] (๐Ÿชญ..๐Ÿชฏ) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (๐Ÿชฐ..๐Ÿชถ) fly..feather + {0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (๐Ÿชท..๐Ÿชบ) lotus..nest with eggs + {0x1FABB, 0x1FABD, prEmojiPresentation}, // E15.0 [3] (๐Ÿชป..๐Ÿชฝ) hyacinth..wing + {0x1FABF, 0x1FABF, prEmojiPresentation}, // E15.0 [1] (๐Ÿชฟ) goose + {0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (๐Ÿซ€..๐Ÿซ‚) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (๐Ÿซƒ..๐Ÿซ…) pregnant man..person with crown + {0x1FACE, 0x1FACF, prEmojiPresentation}, // E15.0 [2] (๐ŸซŽ..๐Ÿซ) moose..donkey + {0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (๐Ÿซ..๐Ÿซ–) blueberries..teapot + {0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (๐Ÿซ—..๐Ÿซ™) pouring liquid..jar + {0x1FADA, 0x1FADB, prEmojiPresentation}, // E15.0 [2] (๐Ÿซš..๐Ÿซ›) ginger root..pea pod + {0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (๐Ÿซ ..๐Ÿซง) melting face..bubbles + {0x1FAE8, 0x1FAE8, prEmojiPresentation}, // E15.0 [1] (๐Ÿซจ) shaking face + {0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (๐Ÿซฐ..๐Ÿซถ) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prEmojiPresentation}, // E15.0 [2] (๐Ÿซท..๐Ÿซธ) leftwards pushing hand..rightwards pushing hand +} diff --git a/vendor/github.com/rivo/uniseg/gen_breaktest.go b/vendor/github.com/rivo/uniseg/gen_breaktest.go new file mode 100644 index 000000000000..6bfbeb5e7f94 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/gen_breaktest.go @@ -0,0 +1,215 @@ +//go:build generate + +// This program generates a Go containing a slice of test cases based on the +// Unicode Character Database auxiliary data files. The command line arguments +// are as follows: +// +// 1. The name of the Unicode data file (just the filename, without extension). +// 2. The name of the locally generated Go file. +// 3. The name of the slice containing the test cases. +// 4. The name of the generator, for logging purposes. +// +//go:generate go run gen_breaktest.go GraphemeBreakTest graphemebreak_test.go graphemeBreakTestCases graphemes +//go:generate go run gen_breaktest.go WordBreakTest wordbreak_test.go wordBreakTestCases words +//go:generate go run gen_breaktest.go SentenceBreakTest sentencebreak_test.go sentenceBreakTestCases sentences +//go:generate go run gen_breaktest.go LineBreakTest linebreak_test.go lineBreakTestCases lines + +package main + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "go/format" + "io/ioutil" + "log" + "net/http" + "os" + "time" +) + +// We want to test against a specific version rather than the latest. When the +// package is upgraded to a new version, change these to generate new tests. +const ( + testCaseURL = `https://www.unicode.org/Public/15.0.0/ucd/auxiliary/%s.txt` +) + +func main() { + if len(os.Args) < 5 { + fmt.Println("Not enough arguments, see code for details") + os.Exit(1) + } + + log.SetPrefix("gen_breaktest (" + os.Args[4] + "): ") + log.SetFlags(0) + + // Read text of testcases and parse into Go source code. + src, err := parse(fmt.Sprintf(testCaseURL, os.Args[1])) + if err != nil { + log.Fatal(err) + } + + // Format the Go code. + formatted, err := format.Source(src) + if err != nil { + log.Fatalln("gofmt:", err) + } + + // Write it out. + log.Print("Writing to ", os.Args[2]) + if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil { + log.Fatal(err) + } +} + +// parse reads a break text file, either from a local file or from a URL. It +// parses the file data into Go source code representing the test cases. +func parse(url string) ([]byte, error) { + log.Printf("Parsing %s", url) + res, err := http.Get(url) + if err != nil { + return nil, err + } + body := res.Body + defer body.Close() + + buf := new(bytes.Buffer) + buf.Grow(120 << 10) + buf.WriteString(`// Code generated via go generate from gen_breaktest.go. DO NOT EDIT. + +package uniseg + +// ` + os.Args[3] + ` are Grapheme testcases taken from +// ` + url + ` +// on ` + time.Now().Format("January 2, 2006") + `. See +// https://www.unicode.org/license.html for the Unicode license agreement. +var ` + os.Args[3] + ` = []testCase { +`) + + sc := bufio.NewScanner(body) + num := 1 + var line []byte + original := make([]byte, 0, 64) + expected := make([]byte, 0, 64) + for sc.Scan() { + num++ + line = sc.Bytes() + if len(line) == 0 || line[0] == '#' { + continue + } + var comment []byte + if i := bytes.IndexByte(line, '#'); i >= 0 { + comment = bytes.TrimSpace(line[i+1:]) + line = bytes.TrimSpace(line[:i]) + } + original, expected, err := parseRuneSequence(line, original[:0], expected[:0]) + if err != nil { + return nil, fmt.Errorf(`line %d: %v: %q`, num, err, line) + } + fmt.Fprintf(buf, "\t{original: \"%s\", expected: %s}, // %s\n", original, expected, comment) + } + if err := sc.Err(); err != nil { + return nil, err + } + + // Check for final "# EOF", useful check if we're streaming via HTTP + if !bytes.Equal(line, []byte("# EOF")) { + return nil, fmt.Errorf(`line %d: exected "# EOF" as final line, got %q`, num, line) + } + buf.WriteString("}\n") + return buf.Bytes(), nil +} + +// Used by parseRuneSequence to match input via bytes.HasPrefix. +var ( + prefixBreak = []byte("รท ") + prefixDontBreak = []byte("ร— ") + breakOk = []byte("รท") + breakNo = []byte("ร—") +) + +// parseRuneSequence parses a rune + breaking opportunity sequence from b +// and appends the Go code for testcase.original to orig +// and appends the Go code for testcase.expected to exp. +// It retuns the new orig and exp slices. +// +// E.g.ย for the inputย b="รท 0020 ร— 0308 รท 1F1E6 รท" +// it will append +// +// "\u0020\u0308\U0001F1E6" +// +// and "[][]rune{{0x0020,0x0308},{0x1F1E6},}" +// to orig and exp respectively. +// +// The formatting of exp is expected to be cleaned up by gofmt or format.Source. +// Note we explicitly require the sequence to start with รท and we implicitly +// require it to end with รท. +func parseRuneSequence(b, orig, exp []byte) ([]byte, []byte, error) { + // Check for and remove first รท or ร—. + if !bytes.HasPrefix(b, prefixBreak) && !bytes.HasPrefix(b, prefixDontBreak) { + return nil, nil, errors.New("expected รท or ร— as first character") + } + if bytes.HasPrefix(b, prefixBreak) { + b = b[len(prefixBreak):] + } else { + b = b[len(prefixDontBreak):] + } + + boundary := true + exp = append(exp, "[][]rune{"...) + for len(b) > 0 { + if boundary { + exp = append(exp, '{') + } + exp = append(exp, "0x"...) + // Find end of hex digits. + var i int + for i = 0; i < len(b) && b[i] != ' '; i++ { + if d := b[i]; ('0' <= d || d <= '9') || + ('A' <= d || d <= 'F') || + ('a' <= d || d <= 'f') { + continue + } + return nil, nil, errors.New("bad hex digit") + } + switch i { + case 4: + orig = append(orig, "\\u"...) + case 5: + orig = append(orig, "\\U000"...) + default: + return nil, nil, errors.New("unsupport code point hex length") + } + orig = append(orig, b[:i]...) + exp = append(exp, b[:i]...) + b = b[i:] + + // Check for space between hex and รท or ร—. + if len(b) < 1 || b[0] != ' ' { + return nil, nil, errors.New("bad input") + } + b = b[1:] + + // Check for next boundary. + switch { + case bytes.HasPrefix(b, breakOk): + boundary = true + b = b[len(breakOk):] + case bytes.HasPrefix(b, breakNo): + boundary = false + b = b[len(breakNo):] + default: + return nil, nil, errors.New("missing รท or ร—") + } + if boundary { + exp = append(exp, '}') + } + exp = append(exp, ',') + if len(b) > 0 && b[0] == ' ' { + b = b[1:] + } + } + exp = append(exp, '}') + return orig, exp, nil +} diff --git a/vendor/github.com/rivo/uniseg/gen_properties.go b/vendor/github.com/rivo/uniseg/gen_properties.go new file mode 100644 index 000000000000..8992d2c5f8b1 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/gen_properties.go @@ -0,0 +1,261 @@ +//go:build generate + +// This program generates a property file in Go file from Unicode Character +// Database auxiliary data files. The command line arguments are as follows: +// +// 1. The name of the Unicode data file (just the filename, without extension). +// Can be "-" (to skip) if the emoji flag is included. +// 2. The name of the locally generated Go file. +// 3. The name of the slice mapping code points to properties. +// 4. The name of the generator, for logging purposes. +// 5. (Optional) Flags, comma-separated. The following flags are available: +// - "emojis=": include the specified emoji properties (e.g. +// "Extended_Pictographic"). +// - "gencat": include general category properties. +// +//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic +//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic +//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences +//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat +//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth +//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation +package main + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "go/format" + "io/ioutil" + "log" + "net/http" + "os" + "regexp" + "sort" + "strconv" + "strings" + "time" +) + +// We want to test against a specific version rather than the latest. When the +// package is upgraded to a new version, change these to generate new tests. +const ( + propertyURL = `https://www.unicode.org/Public/15.0.0/ucd/%s.txt` + emojiURL = `https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt` +) + +// The regular expression for a line containing a code point range property. +var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`) + +func main() { + if len(os.Args) < 5 { + fmt.Println("Not enough arguments, see code for details") + os.Exit(1) + } + + log.SetPrefix("gen_properties (" + os.Args[4] + "): ") + log.SetFlags(0) + + // Parse flags. + flags := make(map[string]string) + if len(os.Args) >= 6 { + for _, flag := range strings.Split(os.Args[5], ",") { + flagFields := strings.Split(flag, "=") + if len(flagFields) == 1 { + flags[flagFields[0]] = "yes" + } else { + flags[flagFields[0]] = flagFields[1] + } + } + } + + // Parse the text file and generate Go source code from it. + _, includeGeneralCategory := flags["gencat"] + var mainURL string + if os.Args[1] != "-" { + mainURL = fmt.Sprintf(propertyURL, os.Args[1]) + } + src, err := parse(mainURL, flags["emojis"], includeGeneralCategory) + if err != nil { + log.Fatal(err) + } + + // Format the Go code. + formatted, err := format.Source([]byte(src)) + if err != nil { + log.Fatal("gofmt:", err) + } + + // Save it to the (local) target file. + log.Print("Writing to ", os.Args[2]) + if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil { + log.Fatal(err) + } +} + +// parse parses the Unicode Properties text files located at the given URLs and +// returns their equivalent Go source code to be used in the uniseg package. If +// "emojiProperty" is not an empty string, emoji code points for that emoji +// property (e.g. "Extended_Pictographic") will be included. In those cases, you +// may pass an empty "propertyURL" to skip parsing the main properties file. If +// "includeGeneralCategory" is true, the Unicode General Category property will +// be extracted from the comments and included in the output. +func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) { + if propertyURL == "" && emojiProperty == "" { + return "", errors.New("no properties to parse") + } + + // Temporary buffer to hold properties. + var properties [][4]string + + // Open the first URL. + if propertyURL != "" { + log.Printf("Parsing %s", propertyURL) + res, err := http.Get(propertyURL) + if err != nil { + return "", err + } + in1 := res.Body + defer in1.Close() + + // Parse it. + scanner := bufio.NewScanner(in1) + num := 0 + for scanner.Scan() { + num++ + line := strings.TrimSpace(scanner.Text()) + + // Skip comments and empty lines. + if strings.HasPrefix(line, "#") || line == "" { + continue + } + + // Everything else must be a code point range, a property and a comment. + from, to, property, comment, err := parseProperty(line) + if err != nil { + return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err) + } + properties = append(properties, [4]string{from, to, property, comment}) + } + if err := scanner.Err(); err != nil { + return "", err + } + } + + // Open the second URL. + if emojiProperty != "" { + log.Printf("Parsing %s", emojiURL) + res, err := http.Get(emojiURL) + if err != nil { + return "", err + } + in2 := res.Body + defer in2.Close() + + // Parse it. + scanner := bufio.NewScanner(in2) + num := 0 + for scanner.Scan() { + num++ + line := scanner.Text() + + // Skip comments, empty lines, and everything not containing + // "Extended_Pictographic". + if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) { + continue + } + + // Everything else must be a code point range, a property and a comment. + from, to, property, comment, err := parseProperty(line) + if err != nil { + return "", fmt.Errorf("emojis line %d: %v", num, err) + } + properties = append(properties, [4]string{from, to, property, comment}) + } + if err := scanner.Err(); err != nil { + return "", err + } + } + + // Avoid overflow during binary search. + if len(properties) >= 1<<31 { + return "", errors.New("too many properties") + } + + // Sort properties. + sort.Slice(properties, func(i, j int) bool { + left, _ := strconv.ParseUint(properties[i][0], 16, 64) + right, _ := strconv.ParseUint(properties[j][0], 16, 64) + return left < right + }) + + // Header. + var ( + buf bytes.Buffer + emojiComment string + ) + columns := 3 + if includeGeneralCategory { + columns = 4 + } + if emojiURL != "" { + emojiComment = ` +// and +// ` + emojiURL + ` +// ("Extended_Pictographic" only)` + } + buf.WriteString(`// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// ` + os.Args[3] + ` are taken from +// ` + propertyURL + emojiComment + ` +// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{ + `) + + // Properties. + for _, prop := range properties { + if includeGeneralCategory { + generalCategory := "gc" + prop[3][:2] + if generalCategory == "gcL&" { + generalCategory = "gcLC" + } + prop[3] = prop[3][3:] + fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3]) + } else { + fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3]) + } + } + + // Tail. + buf.WriteString("}") + + return buf.String(), nil +} + +// parseProperty parses a line of the Unicode properties text file containing a +// property for a code point range and returns it along with its comment. +func parseProperty(line string) (from, to, property, comment string, err error) { + fields := propertyPattern.FindStringSubmatch(line) + if fields == nil { + err = errors.New("no property found") + return + } + from = fields[1] + to = fields[3] + if to == "" { + to = from + } + property = fields[4] + comment = fields[5] + return +} + +// translateProperty translates a property name as used in the Unicode data file +// to a variable used in the Go code. +func translateProperty(prefix, property string) string { + return prefix + strings.ReplaceAll(property, "_", "") +} diff --git a/vendor/github.com/rivo/uniseg/grapheme.go b/vendor/github.com/rivo/uniseg/grapheme.go new file mode 100644 index 000000000000..b12403d43c2e --- /dev/null +++ b/vendor/github.com/rivo/uniseg/grapheme.go @@ -0,0 +1,331 @@ +package uniseg + +import "unicode/utf8" + +// Graphemes implements an iterator over Unicode grapheme clusters, or +// user-perceived characters. While iterating, it also provides information +// about word boundaries, sentence boundaries, line breaks, and monospace +// character widths. +// +// After constructing the class via [NewGraphemes] for a given string "str", +// [Graphemes.Next] is called for every grapheme cluster in a loop until it +// returns false. Inside the loop, information about the grapheme cluster as +// well as boundary information and character width is available via the various +// methods (see examples below). +// +// This class basically wraps the [StepString] parser and provides a convenient +// interface to it. If you are only interested in some parts of this package's +// functionality, using the specialized functions starting with "First" is +// almost always faster. +type Graphemes struct { + // The original string. + original string + + // The remaining string to be parsed. + remaining string + + // The current grapheme cluster. + cluster string + + // The byte offset of the current grapheme cluster relative to the original + // string. + offset int + + // The current boundary information of the [Step] parser. + boundaries int + + // The current state of the [Step] parser. + state int +} + +// NewGraphemes returns a new grapheme cluster iterator. +func NewGraphemes(str string) *Graphemes { + return &Graphemes{ + original: str, + remaining: str, + state: -1, + } +} + +// Next advances the iterator by one grapheme cluster and returns false if no +// clusters are left. This function must be called before the first cluster is +// accessed. +func (g *Graphemes) Next() bool { + if len(g.remaining) == 0 { + // We're already past the end. + g.state = -2 + g.cluster = "" + return false + } + g.offset += len(g.cluster) + g.cluster, g.remaining, g.boundaries, g.state = StepString(g.remaining, g.state) + return true +} + +// Runes returns a slice of runes (code points) which corresponds to the current +// grapheme cluster. If the iterator is already past the end or [Graphemes.Next] +// has not yet been called, nil is returned. +func (g *Graphemes) Runes() []rune { + if g.state < 0 { + return nil + } + return []rune(g.cluster) +} + +// Str returns a substring of the original string which corresponds to the +// current grapheme cluster. If the iterator is already past the end or +// [Graphemes.Next] has not yet been called, an empty string is returned. +func (g *Graphemes) Str() string { + return g.cluster +} + +// Bytes returns a byte slice which corresponds to the current grapheme cluster. +// If the iterator is already past the end or [Graphemes.Next] has not yet been +// called, nil is returned. +func (g *Graphemes) Bytes() []byte { + if g.state < 0 { + return nil + } + return []byte(g.cluster) +} + +// Positions returns the interval of the current grapheme cluster as byte +// positions into the original string. The first returned value "from" indexes +// the first byte and the second returned value "to" indexes the first byte that +// is not included anymore, i.e. str[from:to] is the current grapheme cluster of +// the original string "str". If [Graphemes.Next] has not yet been called, both +// values are 0. If the iterator is already past the end, both values are 1. +func (g *Graphemes) Positions() (int, int) { + if g.state == -1 { + return 0, 0 + } else if g.state == -2 { + return 1, 1 + } + return g.offset, g.offset + len(g.cluster) +} + +// IsWordBoundary returns true if a word ends after the current grapheme +// cluster. +func (g *Graphemes) IsWordBoundary() bool { + if g.state < 0 { + return true + } + return g.boundaries&MaskWord != 0 +} + +// IsSentenceBoundary returns true if a sentence ends after the current +// grapheme cluster. +func (g *Graphemes) IsSentenceBoundary() bool { + if g.state < 0 { + return true + } + return g.boundaries&MaskSentence != 0 +} + +// LineBreak returns whether the line can be broken after the current grapheme +// cluster. A value of [LineDontBreak] means the line may not be broken, a value +// of [LineMustBreak] means the line must be broken, and a value of +// [LineCanBreak] means the line may or may not be broken. +func (g *Graphemes) LineBreak() int { + if g.state == -1 { + return LineDontBreak + } + if g.state == -2 { + return LineMustBreak + } + return g.boundaries & MaskLine +} + +// Width returns the monospace width of the current grapheme cluster. +func (g *Graphemes) Width() int { + if g.state < 0 { + return 0 + } + return g.boundaries >> ShiftWidth +} + +// Reset puts the iterator into its initial state such that the next call to +// [Graphemes.Next] sets it to the first grapheme cluster again. +func (g *Graphemes) Reset() { + g.state = -1 + g.offset = 0 + g.cluster = "" + g.remaining = g.original +} + +// GraphemeClusterCount returns the number of user-perceived characters +// (grapheme clusters) for the given string. +func GraphemeClusterCount(s string) (n int) { + state := -1 + for len(s) > 0 { + _, s, _, state = FirstGraphemeClusterInString(s, state) + n++ + } + return +} + +// ReverseString reverses the given string while observing grapheme cluster +// boundaries. +func ReverseString(s string) string { + str := []byte(s) + reversed := make([]byte, len(str)) + state := -1 + index := len(str) + for len(str) > 0 { + var cluster []byte + cluster, str, _, state = FirstGraphemeCluster(str, state) + index -= len(cluster) + copy(reversed[index:], cluster) + if index <= len(str)/2 { + break + } + } + return string(reversed) +} + +// The number of bits the grapheme property must be shifted to make place for +// grapheme states. +const shiftGraphemePropState = 4 + +// FirstGraphemeCluster returns the first grapheme cluster found in the given +// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme +// Cluster Boundaries]. This function can be called continuously to extract all +// grapheme clusters from a byte slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified grapheme cluster. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "cluster" byte slice is the sub-slice of the input slice containing the +// identified grapheme cluster. +// +// The returned width is the width of the grapheme cluster for most monospace +// fonts where a value of 1 represents one character cell. +// +// Given an empty byte slice "b", the function returns nil values. +// +// While slightly less convenient than using the Graphemes class, this function +// has much better performance and makes no allocations. It lends itself well to +// large byte slices. +// +// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries +func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftGraphemePropState + } + return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState) + } + + // If we don't know the state, determine it now. + var firstProp int + if state < 0 { + state, firstProp, _ = transitionGraphemeState(state, r) + } else { + firstProp = state >> shiftGraphemePropState + } + width += runeWidth(r, firstProp) + + // Transition until we find a boundary. + for { + var ( + prop int + boundary bool + ) + + r, l := utf8.DecodeRune(b[length:]) + state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r) + + if boundary { + return b[:length], b[length:], width, state | (prop << shiftGraphemePropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(b) <= length { + return b, nil, width, grAny | (prop << shiftGraphemePropState) + } + } +} + +// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and +// outputs are strings. +func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) { + // An empty string returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftGraphemePropState + } + return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState) + } + + // If we don't know the state, determine it now. + var firstProp int + if state < 0 { + state, firstProp, _ = transitionGraphemeState(state, r) + } else { + firstProp = state >> shiftGraphemePropState + } + width += runeWidth(r, firstProp) + + // Transition until we find a boundary. + for { + var ( + prop int + boundary bool + ) + + r, l := utf8.DecodeRuneInString(str[length:]) + state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r) + + if boundary { + return str[:length], str[length:], width, state | (prop << shiftGraphemePropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(str) <= length { + return str, "", width, grAny | (prop << shiftGraphemePropState) + } + } +} diff --git a/vendor/github.com/rivo/uniseg/graphemeproperties.go b/vendor/github.com/rivo/uniseg/graphemeproperties.go new file mode 100644 index 000000000000..0aff4a619a7d --- /dev/null +++ b/vendor/github.com/rivo/uniseg/graphemeproperties.go @@ -0,0 +1,1915 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// graphemeCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var graphemeCodePoints = [][3]int{ + {0x0000, 0x0009, prControl}, // Cc [10] .. + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prControl}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x000E, 0x001F, prControl}, // Cc [18] .. + {0x007F, 0x009F, prControl}, // Cc [33] .. + {0x00A9, 0x00A9, prExtendedPictographic}, // E0.6 [1] (ยฉ๏ธ) copyright + {0x00AD, 0x00AD, prControl}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prExtendedPictographic}, // E0.6 [1] (ยฎ๏ธ) registered + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x0600, 0x0605, prPrepend}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prControl}, // Cf ARABIC LETTER MARK + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prPrepend}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x070F, 0x070F, prPrepend}, // Cf SYRIAC ABBREVIATION MARK + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0890, 0x0891, prPrepend}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prPrepend}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prSpacingMark}, // Mc DEVANAGARI SIGN VISARGA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prSpacingMark}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093E, 0x0940, prSpacingMark}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prSpacingMark}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prSpacingMark}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prSpacingMark}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BE, 0x09BE, prExtend}, // Mc BENGALI VOWEL SIGN AA + {0x09BF, 0x09C0, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prSpacingMark}, // Mc GURMUKHI SIGN VISARGA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prSpacingMark}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prSpacingMark}, // Mc GUJARATI SIGN VISARGA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABE, 0x0AC0, prSpacingMark}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prSpacingMark}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prSpacingMark}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prSpacingMark}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prSpacingMark}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0BBE, 0x0BBE, prExtend}, // Mc TAMIL VOWEL SIGN AA + {0x0BBF, 0x0BBF, prSpacingMark}, // Mc TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prSpacingMark}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prSpacingMark}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prSpacingMark}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prSpacingMark}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBE, 0x0CBE, prSpacingMark}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC1, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U + {0x0CC2, 0x0CC2, prExtend}, // Mc KANNADA VOWEL SIGN UU + {0x0CC3, 0x0CC4, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CF3, 0x0CF3, prSpacingMark}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prSpacingMark}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3E, 0x0D3E, prExtend}, // Mc MALAYALAM VOWEL SIGN AA + {0x0D3F, 0x0D40, prSpacingMark}, // Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prPrepend}, // Lo MALAYALAM LETTER DOT REPH + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prSpacingMark}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DCF, prExtend}, // Mc SINHALA VOWEL SIGN AELA-PILLA + {0x0DD0, 0x0DD1, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDE, prSpacingMark}, // Mc [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA + {0x0DDF, 0x0DDF, prExtend}, // Mc SINHALA VOWEL SIGN GAYANUKITTA + {0x0DF2, 0x0DF3, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E33, 0x0E33, prSpacingMark}, // Lo THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB3, 0x0EB3, prSpacingMark}, // Lo LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3E, 0x0F3F, prSpacingMark}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prSpacingMark}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prSpacingMark}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prSpacingMark}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x1056, 0x1057, prSpacingMark}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1084, 0x1084, prSpacingMark}, // Mc MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x1100, 0x115F, prL}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11A7, prV}, // Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE + {0x11A8, 0x11FF, prT}, // Lo [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prSpacingMark}, // Mc TAGALOG SIGN PAMUDPOD + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prSpacingMark}, // Mc HANUNOO SIGN PAMUDPOD + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prSpacingMark}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prSpacingMark}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prSpacingMark}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prControl}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prSpacingMark}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prSpacingMark}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prSpacingMark}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prSpacingMark}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prSpacingMark}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A55, 0x1A55, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prSpacingMark}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prSpacingMark}, // Mc BALINESE SIGN BISAH + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prSpacingMark}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prSpacingMark}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prSpacingMark}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prSpacingMark}, // Mc SUNDANESE SIGN PANGWISAD + {0x1BA1, 0x1BA1, prSpacingMark}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prSpacingMark}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prSpacingMark}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prSpacingMark}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prSpacingMark}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prSpacingMark}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prSpacingMark}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C24, 0x1C2B, prSpacingMark}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prSpacingMark}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prSpacingMark}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF7, 0x1CF7, prSpacingMark}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x200B, 0x200B, prControl}, // Cf ZERO WIDTH SPACE + {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER + {0x200E, 0x200F, prControl}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2028, 0x2028, prControl}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prControl}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prControl}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x203C, 0x203C, prExtendedPictographic}, // E0.6 [1] (โ€ผ๏ธ) double exclamation mark + {0x2049, 0x2049, prExtendedPictographic}, // E0.6 [1] (โ‰๏ธ) exclamation question mark + {0x2060, 0x2064, prControl}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2065, 0x2065, prControl}, // Cn + {0x2066, 0x206F, prControl}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2122, 0x2122, prExtendedPictographic}, // E0.6 [1] (โ„ข๏ธ) trade mark + {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] (โ„น๏ธ) information + {0x2194, 0x2199, prExtendedPictographic}, // E0.6 [6] (โ†”๏ธ..โ†™๏ธ) left-right arrow..down-left arrow + {0x21A9, 0x21AA, prExtendedPictographic}, // E0.6 [2] (โ†ฉ๏ธ..โ†ช๏ธ) right arrow curving left..left arrow curving right + {0x231A, 0x231B, prExtendedPictographic}, // E0.6 [2] (โŒš..โŒ›) watch..hourglass done + {0x2328, 0x2328, prExtendedPictographic}, // E1.0 [1] (โŒจ๏ธ) keyboard + {0x2388, 0x2388, prExtendedPictographic}, // E0.0 [1] (โŽˆ) HELM SYMBOL + {0x23CF, 0x23CF, prExtendedPictographic}, // E1.0 [1] (โ๏ธ) eject button + {0x23E9, 0x23EC, prExtendedPictographic}, // E0.6 [4] (โฉ..โฌ) fast-forward button..fast down button + {0x23ED, 0x23EE, prExtendedPictographic}, // E0.7 [2] (โญ๏ธ..โฎ๏ธ) next track button..last track button + {0x23EF, 0x23EF, prExtendedPictographic}, // E1.0 [1] (โฏ๏ธ) play or pause button + {0x23F0, 0x23F0, prExtendedPictographic}, // E0.6 [1] (โฐ) alarm clock + {0x23F1, 0x23F2, prExtendedPictographic}, // E1.0 [2] (โฑ๏ธ..โฒ๏ธ) stopwatch..timer clock + {0x23F3, 0x23F3, prExtendedPictographic}, // E0.6 [1] (โณ) hourglass not done + {0x23F8, 0x23FA, prExtendedPictographic}, // E0.7 [3] (โธ๏ธ..โบ๏ธ) pause button..record button + {0x24C2, 0x24C2, prExtendedPictographic}, // E0.6 [1] (โ“‚๏ธ) circled M + {0x25AA, 0x25AB, prExtendedPictographic}, // E0.6 [2] (โ–ช๏ธ..โ–ซ๏ธ) black small square..white small square + {0x25B6, 0x25B6, prExtendedPictographic}, // E0.6 [1] (โ–ถ๏ธ) play button + {0x25C0, 0x25C0, prExtendedPictographic}, // E0.6 [1] (โ—€๏ธ) reverse button + {0x25FB, 0x25FE, prExtendedPictographic}, // E0.6 [4] (โ—ป๏ธ..โ—พ) white medium square..black medium-small square + {0x2600, 0x2601, prExtendedPictographic}, // E0.6 [2] (โ˜€๏ธ..โ˜๏ธ) sun..cloud + {0x2602, 0x2603, prExtendedPictographic}, // E0.7 [2] (โ˜‚๏ธ..โ˜ƒ๏ธ) umbrella..snowman + {0x2604, 0x2604, prExtendedPictographic}, // E1.0 [1] (โ˜„๏ธ) comet + {0x2605, 0x2605, prExtendedPictographic}, // E0.0 [1] (โ˜…) BLACK STAR + {0x2607, 0x260D, prExtendedPictographic}, // E0.0 [7] (โ˜‡..โ˜) LIGHTNING..OPPOSITION + {0x260E, 0x260E, prExtendedPictographic}, // E0.6 [1] (โ˜Ž๏ธ) telephone + {0x260F, 0x2610, prExtendedPictographic}, // E0.0 [2] (โ˜..โ˜) WHITE TELEPHONE..BALLOT BOX + {0x2611, 0x2611, prExtendedPictographic}, // E0.6 [1] (โ˜‘๏ธ) check box with check + {0x2612, 0x2612, prExtendedPictographic}, // E0.0 [1] (โ˜’) BALLOT BOX WITH X + {0x2614, 0x2615, prExtendedPictographic}, // E0.6 [2] (โ˜”..โ˜•) umbrella with rain drops..hot beverage + {0x2616, 0x2617, prExtendedPictographic}, // E0.0 [2] (โ˜–..โ˜—) WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prExtendedPictographic}, // E1.0 [1] (โ˜˜๏ธ) shamrock + {0x2619, 0x261C, prExtendedPictographic}, // E0.0 [4] (โ˜™..โ˜œ) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prExtendedPictographic}, // E0.6 [1] (โ˜๏ธ) index pointing up + {0x261E, 0x261F, prExtendedPictographic}, // E0.0 [2] (โ˜ž..โ˜Ÿ) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2620, prExtendedPictographic}, // E1.0 [1] (โ˜ ๏ธ) skull and crossbones + {0x2621, 0x2621, prExtendedPictographic}, // E0.0 [1] (โ˜ก) CAUTION SIGN + {0x2622, 0x2623, prExtendedPictographic}, // E1.0 [2] (โ˜ข๏ธ..โ˜ฃ๏ธ) radioactive..biohazard + {0x2624, 0x2625, prExtendedPictographic}, // E0.0 [2] (โ˜ค..โ˜ฅ) CADUCEUS..ANKH + {0x2626, 0x2626, prExtendedPictographic}, // E1.0 [1] (โ˜ฆ๏ธ) orthodox cross + {0x2627, 0x2629, prExtendedPictographic}, // E0.0 [3] (โ˜ง..โ˜ฉ) CHI RHO..CROSS OF JERUSALEM + {0x262A, 0x262A, prExtendedPictographic}, // E0.7 [1] (โ˜ช๏ธ) star and crescent + {0x262B, 0x262D, prExtendedPictographic}, // E0.0 [3] (โ˜ซ..โ˜ญ) FARSI SYMBOL..HAMMER AND SICKLE + {0x262E, 0x262E, prExtendedPictographic}, // E1.0 [1] (โ˜ฎ๏ธ) peace symbol + {0x262F, 0x262F, prExtendedPictographic}, // E0.7 [1] (โ˜ฏ๏ธ) yin yang + {0x2630, 0x2637, prExtendedPictographic}, // E0.0 [8] (โ˜ฐ..โ˜ท) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH + {0x2638, 0x2639, prExtendedPictographic}, // E0.7 [2] (โ˜ธ๏ธ..โ˜น๏ธ) wheel of dharma..frowning face + {0x263A, 0x263A, prExtendedPictographic}, // E0.6 [1] (โ˜บ๏ธ) smiling face + {0x263B, 0x263F, prExtendedPictographic}, // E0.0 [5] (โ˜ป..โ˜ฟ) BLACK SMILING FACE..MERCURY + {0x2640, 0x2640, prExtendedPictographic}, // E4.0 [1] (โ™€๏ธ) female sign + {0x2641, 0x2641, prExtendedPictographic}, // E0.0 [1] (โ™) EARTH + {0x2642, 0x2642, prExtendedPictographic}, // E4.0 [1] (โ™‚๏ธ) male sign + {0x2643, 0x2647, prExtendedPictographic}, // E0.0 [5] (โ™ƒ..โ™‡) JUPITER..PLUTO + {0x2648, 0x2653, prExtendedPictographic}, // E0.6 [12] (โ™ˆ..โ™“) Aries..Pisces + {0x2654, 0x265E, prExtendedPictographic}, // E0.0 [11] (โ™”..โ™ž) WHITE CHESS KING..BLACK CHESS KNIGHT + {0x265F, 0x265F, prExtendedPictographic}, // E11.0 [1] (โ™Ÿ๏ธ) chess pawn + {0x2660, 0x2660, prExtendedPictographic}, // E0.6 [1] (โ™ ๏ธ) spade suit + {0x2661, 0x2662, prExtendedPictographic}, // E0.0 [2] (โ™ก..โ™ข) WHITE HEART SUIT..WHITE DIAMOND SUIT + {0x2663, 0x2663, prExtendedPictographic}, // E0.6 [1] (โ™ฃ๏ธ) club suit + {0x2664, 0x2664, prExtendedPictographic}, // E0.0 [1] (โ™ค) WHITE SPADE SUIT + {0x2665, 0x2666, prExtendedPictographic}, // E0.6 [2] (โ™ฅ๏ธ..โ™ฆ๏ธ) heart suit..diamond suit + {0x2667, 0x2667, prExtendedPictographic}, // E0.0 [1] (โ™ง) WHITE CLUB SUIT + {0x2668, 0x2668, prExtendedPictographic}, // E0.6 [1] (โ™จ๏ธ) hot springs + {0x2669, 0x267A, prExtendedPictographic}, // E0.0 [18] (โ™ฉ..โ™บ) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS + {0x267B, 0x267B, prExtendedPictographic}, // E0.6 [1] (โ™ป๏ธ) recycling symbol + {0x267C, 0x267D, prExtendedPictographic}, // E0.0 [2] (โ™ผ..โ™ฝ) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL + {0x267E, 0x267E, prExtendedPictographic}, // E11.0 [1] (โ™พ๏ธ) infinity + {0x267F, 0x267F, prExtendedPictographic}, // E0.6 [1] (โ™ฟ) wheelchair symbol + {0x2680, 0x2685, prExtendedPictographic}, // E0.0 [6] (โš€..โš…) DIE FACE-1..DIE FACE-6 + {0x2690, 0x2691, prExtendedPictographic}, // E0.0 [2] (โš..โš‘) WHITE FLAG..BLACK FLAG + {0x2692, 0x2692, prExtendedPictographic}, // E1.0 [1] (โš’๏ธ) hammer and pick + {0x2693, 0x2693, prExtendedPictographic}, // E0.6 [1] (โš“) anchor + {0x2694, 0x2694, prExtendedPictographic}, // E1.0 [1] (โš”๏ธ) crossed swords + {0x2695, 0x2695, prExtendedPictographic}, // E4.0 [1] (โš•๏ธ) medical symbol + {0x2696, 0x2697, prExtendedPictographic}, // E1.0 [2] (โš–๏ธ..โš—๏ธ) balance scale..alembic + {0x2698, 0x2698, prExtendedPictographic}, // E0.0 [1] (โš˜) FLOWER + {0x2699, 0x2699, prExtendedPictographic}, // E1.0 [1] (โš™๏ธ) gear + {0x269A, 0x269A, prExtendedPictographic}, // E0.0 [1] (โšš) STAFF OF HERMES + {0x269B, 0x269C, prExtendedPictographic}, // E1.0 [2] (โš›๏ธ..โšœ๏ธ) atom symbol..fleur-de-lis + {0x269D, 0x269F, prExtendedPictographic}, // E0.0 [3] (โš..โšŸ) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A1, prExtendedPictographic}, // E0.6 [2] (โš ๏ธ..โšก) warning..high voltage + {0x26A2, 0x26A6, prExtendedPictographic}, // E0.0 [5] (โšข..โšฆ) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN + {0x26A7, 0x26A7, prExtendedPictographic}, // E13.0 [1] (โšง๏ธ) transgender symbol + {0x26A8, 0x26A9, prExtendedPictographic}, // E0.0 [2] (โšจ..โšฉ) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prExtendedPictographic}, // E0.6 [2] (โšช..โšซ) white circle..black circle + {0x26AC, 0x26AF, prExtendedPictographic}, // E0.0 [4] (โšฌ..โšฏ) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL + {0x26B0, 0x26B1, prExtendedPictographic}, // E1.0 [2] (โšฐ๏ธ..โšฑ๏ธ) coffin..funeral urn + {0x26B2, 0x26BC, prExtendedPictographic}, // E0.0 [11] (โšฒ..โšผ) NEUTER..SESQUIQUADRATE + {0x26BD, 0x26BE, prExtendedPictographic}, // E0.6 [2] (โšฝ..โšพ) soccer ball..baseball + {0x26BF, 0x26C3, prExtendedPictographic}, // E0.0 [5] (โšฟ..โ›ƒ) SQUARED KEY..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prExtendedPictographic}, // E0.6 [2] (โ›„..โ›…) snowman without snow..sun behind cloud + {0x26C6, 0x26C7, prExtendedPictographic}, // E0.0 [2] (โ›†..โ›‡) RAIN..BLACK SNOWMAN + {0x26C8, 0x26C8, prExtendedPictographic}, // E0.7 [1] (โ›ˆ๏ธ) cloud with lightning and rain + {0x26C9, 0x26CD, prExtendedPictographic}, // E0.0 [5] (โ›‰..โ›) TURNED WHITE SHOGI PIECE..DISABLED CAR + {0x26CE, 0x26CE, prExtendedPictographic}, // E0.6 [1] (โ›Ž) Ophiuchus + {0x26CF, 0x26CF, prExtendedPictographic}, // E0.7 [1] (โ›๏ธ) pick + {0x26D0, 0x26D0, prExtendedPictographic}, // E0.0 [1] (โ›) CAR SLIDING + {0x26D1, 0x26D1, prExtendedPictographic}, // E0.7 [1] (โ›‘๏ธ) rescue workerโ€™s helmet + {0x26D2, 0x26D2, prExtendedPictographic}, // E0.0 [1] (โ›’) CIRCLED CROSSING LANES + {0x26D3, 0x26D3, prExtendedPictographic}, // E0.7 [1] (โ›“๏ธ) chains + {0x26D4, 0x26D4, prExtendedPictographic}, // E0.6 [1] (โ›”) no entry + {0x26D5, 0x26E8, prExtendedPictographic}, // E0.0 [20] (โ›•..โ›จ) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD + {0x26E9, 0x26E9, prExtendedPictographic}, // E0.7 [1] (โ›ฉ๏ธ) shinto shrine + {0x26EA, 0x26EA, prExtendedPictographic}, // E0.6 [1] (โ›ช) church + {0x26EB, 0x26EF, prExtendedPictographic}, // E0.0 [5] (โ›ซ..โ›ฏ) CASTLE..MAP SYMBOL FOR LIGHTHOUSE + {0x26F0, 0x26F1, prExtendedPictographic}, // E0.7 [2] (โ›ฐ๏ธ..โ›ฑ๏ธ) mountain..umbrella on ground + {0x26F2, 0x26F3, prExtendedPictographic}, // E0.6 [2] (โ›ฒ..โ›ณ) fountain..flag in hole + {0x26F4, 0x26F4, prExtendedPictographic}, // E0.7 [1] (โ›ด๏ธ) ferry + {0x26F5, 0x26F5, prExtendedPictographic}, // E0.6 [1] (โ›ต) sailboat + {0x26F6, 0x26F6, prExtendedPictographic}, // E0.0 [1] (โ›ถ) SQUARE FOUR CORNERS + {0x26F7, 0x26F9, prExtendedPictographic}, // E0.7 [3] (โ›ท๏ธ..โ›น๏ธ) skier..person bouncing ball + {0x26FA, 0x26FA, prExtendedPictographic}, // E0.6 [1] (โ›บ) tent + {0x26FB, 0x26FC, prExtendedPictographic}, // E0.0 [2] (โ›ป..โ›ผ) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prExtendedPictographic}, // E0.6 [1] (โ›ฝ) fuel pump + {0x26FE, 0x2701, prExtendedPictographic}, // E0.0 [4] (โ›พ..โœ) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS + {0x2702, 0x2702, prExtendedPictographic}, // E0.6 [1] (โœ‚๏ธ) scissors + {0x2703, 0x2704, prExtendedPictographic}, // E0.0 [2] (โœƒ..โœ„) LOWER BLADE SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prExtendedPictographic}, // E0.6 [1] (โœ…) check mark button + {0x2708, 0x270C, prExtendedPictographic}, // E0.6 [5] (โœˆ๏ธ..โœŒ๏ธ) airplane..victory hand + {0x270D, 0x270D, prExtendedPictographic}, // E0.7 [1] (โœ๏ธ) writing hand + {0x270E, 0x270E, prExtendedPictographic}, // E0.0 [1] (โœŽ) LOWER RIGHT PENCIL + {0x270F, 0x270F, prExtendedPictographic}, // E0.6 [1] (โœ๏ธ) pencil + {0x2710, 0x2711, prExtendedPictographic}, // E0.0 [2] (โœ..โœ‘) UPPER RIGHT PENCIL..WHITE NIB + {0x2712, 0x2712, prExtendedPictographic}, // E0.6 [1] (โœ’๏ธ) black nib + {0x2714, 0x2714, prExtendedPictographic}, // E0.6 [1] (โœ”๏ธ) check mark + {0x2716, 0x2716, prExtendedPictographic}, // E0.6 [1] (โœ–๏ธ) multiply + {0x271D, 0x271D, prExtendedPictographic}, // E0.7 [1] (โœ๏ธ) latin cross + {0x2721, 0x2721, prExtendedPictographic}, // E0.7 [1] (โœก๏ธ) star of David + {0x2728, 0x2728, prExtendedPictographic}, // E0.6 [1] (โœจ) sparkles + {0x2733, 0x2734, prExtendedPictographic}, // E0.6 [2] (โœณ๏ธ..โœด๏ธ) eight-spoked asterisk..eight-pointed star + {0x2744, 0x2744, prExtendedPictographic}, // E0.6 [1] (โ„๏ธ) snowflake + {0x2747, 0x2747, prExtendedPictographic}, // E0.6 [1] (โ‡๏ธ) sparkle + {0x274C, 0x274C, prExtendedPictographic}, // E0.6 [1] (โŒ) cross mark + {0x274E, 0x274E, prExtendedPictographic}, // E0.6 [1] (โŽ) cross mark button + {0x2753, 0x2755, prExtendedPictographic}, // E0.6 [3] (โ“..โ•) red question mark..white exclamation mark + {0x2757, 0x2757, prExtendedPictographic}, // E0.6 [1] (โ—) red exclamation mark + {0x2763, 0x2763, prExtendedPictographic}, // E1.0 [1] (โฃ๏ธ) heart exclamation + {0x2764, 0x2764, prExtendedPictographic}, // E0.6 [1] (โค๏ธ) red heart + {0x2765, 0x2767, prExtendedPictographic}, // E0.0 [3] (โฅ..โง) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2795, 0x2797, prExtendedPictographic}, // E0.6 [3] (โž•..โž—) plus..divide + {0x27A1, 0x27A1, prExtendedPictographic}, // E0.6 [1] (โžก๏ธ) right arrow + {0x27B0, 0x27B0, prExtendedPictographic}, // E0.6 [1] (โžฐ) curly loop + {0x27BF, 0x27BF, prExtendedPictographic}, // E1.0 [1] (โžฟ) double curly loop + {0x2934, 0x2935, prExtendedPictographic}, // E0.6 [2] (โคด๏ธ..โคต๏ธ) right arrow curving up..right arrow curving down + {0x2B05, 0x2B07, prExtendedPictographic}, // E0.6 [3] (โฌ…๏ธ..โฌ‡๏ธ) left arrow..down arrow + {0x2B1B, 0x2B1C, prExtendedPictographic}, // E0.6 [2] (โฌ›..โฌœ) black large square..white large square + {0x2B50, 0x2B50, prExtendedPictographic}, // E0.6 [1] (โญ) star + {0x2B55, 0x2B55, prExtendedPictographic}, // E0.6 [1] (โญ•) hollow red circle + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prExtendedPictographic}, // E0.6 [1] (ใ€ฐ๏ธ) wavy dash + {0x303D, 0x303D, prExtendedPictographic}, // E0.6 [1] (ใ€ฝ๏ธ) part alternation mark + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x3297, 0x3297, prExtendedPictographic}, // E0.6 [1] (ใŠ—๏ธ) Japanese โ€œcongratulationsโ€ button + {0x3299, 0x3299, prExtendedPictographic}, // E0.6 [1] (ใŠ™๏ธ) Japanese โ€œsecretโ€ button + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA823, 0xA824, prSpacingMark}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prSpacingMark}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA880, 0xA881, prSpacingMark}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA8B4, 0xA8C3, prSpacingMark}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prSpacingMark}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prL}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prSpacingMark}, // Mc JAVANESE SIGN WIGNYAN + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prSpacingMark}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prSpacingMark}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prSpacingMark}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prSpacingMark}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAEB, 0xAAEB, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF5, 0xAAF5, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xABE3, 0xABE4, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEC, 0xABEC, prSpacingMark}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xAC00, 0xAC00, prLV}, // Lo HANGUL SYLLABLE GA + {0xAC01, 0xAC1B, prLVT}, // Lo [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH + {0xAC1C, 0xAC1C, prLV}, // Lo HANGUL SYLLABLE GAE + {0xAC1D, 0xAC37, prLVT}, // Lo [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH + {0xAC38, 0xAC38, prLV}, // Lo HANGUL SYLLABLE GYA + {0xAC39, 0xAC53, prLVT}, // Lo [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH + {0xAC54, 0xAC54, prLV}, // Lo HANGUL SYLLABLE GYAE + {0xAC55, 0xAC6F, prLVT}, // Lo [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH + {0xAC70, 0xAC70, prLV}, // Lo HANGUL SYLLABLE GEO + {0xAC71, 0xAC8B, prLVT}, // Lo [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH + {0xAC8C, 0xAC8C, prLV}, // Lo HANGUL SYLLABLE GE + {0xAC8D, 0xACA7, prLVT}, // Lo [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH + {0xACA8, 0xACA8, prLV}, // Lo HANGUL SYLLABLE GYEO + {0xACA9, 0xACC3, prLVT}, // Lo [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH + {0xACC4, 0xACC4, prLV}, // Lo HANGUL SYLLABLE GYE + {0xACC5, 0xACDF, prLVT}, // Lo [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH + {0xACE0, 0xACE0, prLV}, // Lo HANGUL SYLLABLE GO + {0xACE1, 0xACFB, prLVT}, // Lo [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH + {0xACFC, 0xACFC, prLV}, // Lo HANGUL SYLLABLE GWA + {0xACFD, 0xAD17, prLVT}, // Lo [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH + {0xAD18, 0xAD18, prLV}, // Lo HANGUL SYLLABLE GWAE + {0xAD19, 0xAD33, prLVT}, // Lo [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH + {0xAD34, 0xAD34, prLV}, // Lo HANGUL SYLLABLE GOE + {0xAD35, 0xAD4F, prLVT}, // Lo [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH + {0xAD50, 0xAD50, prLV}, // Lo HANGUL SYLLABLE GYO + {0xAD51, 0xAD6B, prLVT}, // Lo [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH + {0xAD6C, 0xAD6C, prLV}, // Lo HANGUL SYLLABLE GU + {0xAD6D, 0xAD87, prLVT}, // Lo [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH + {0xAD88, 0xAD88, prLV}, // Lo HANGUL SYLLABLE GWEO + {0xAD89, 0xADA3, prLVT}, // Lo [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH + {0xADA4, 0xADA4, prLV}, // Lo HANGUL SYLLABLE GWE + {0xADA5, 0xADBF, prLVT}, // Lo [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH + {0xADC0, 0xADC0, prLV}, // Lo HANGUL SYLLABLE GWI + {0xADC1, 0xADDB, prLVT}, // Lo [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH + {0xADDC, 0xADDC, prLV}, // Lo HANGUL SYLLABLE GYU + {0xADDD, 0xADF7, prLVT}, // Lo [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH + {0xADF8, 0xADF8, prLV}, // Lo HANGUL SYLLABLE GEU + {0xADF9, 0xAE13, prLVT}, // Lo [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH + {0xAE14, 0xAE14, prLV}, // Lo HANGUL SYLLABLE GYI + {0xAE15, 0xAE2F, prLVT}, // Lo [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH + {0xAE30, 0xAE30, prLV}, // Lo HANGUL SYLLABLE GI + {0xAE31, 0xAE4B, prLVT}, // Lo [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH + {0xAE4C, 0xAE4C, prLV}, // Lo HANGUL SYLLABLE GGA + {0xAE4D, 0xAE67, prLVT}, // Lo [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH + {0xAE68, 0xAE68, prLV}, // Lo HANGUL SYLLABLE GGAE + {0xAE69, 0xAE83, prLVT}, // Lo [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH + {0xAE84, 0xAE84, prLV}, // Lo HANGUL SYLLABLE GGYA + {0xAE85, 0xAE9F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH + {0xAEA0, 0xAEA0, prLV}, // Lo HANGUL SYLLABLE GGYAE + {0xAEA1, 0xAEBB, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH + {0xAEBC, 0xAEBC, prLV}, // Lo HANGUL SYLLABLE GGEO + {0xAEBD, 0xAED7, prLVT}, // Lo [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH + {0xAED8, 0xAED8, prLV}, // Lo HANGUL SYLLABLE GGE + {0xAED9, 0xAEF3, prLVT}, // Lo [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH + {0xAEF4, 0xAEF4, prLV}, // Lo HANGUL SYLLABLE GGYEO + {0xAEF5, 0xAF0F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH + {0xAF10, 0xAF10, prLV}, // Lo HANGUL SYLLABLE GGYE + {0xAF11, 0xAF2B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH + {0xAF2C, 0xAF2C, prLV}, // Lo HANGUL SYLLABLE GGO + {0xAF2D, 0xAF47, prLVT}, // Lo [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH + {0xAF48, 0xAF48, prLV}, // Lo HANGUL SYLLABLE GGWA + {0xAF49, 0xAF63, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH + {0xAF64, 0xAF64, prLV}, // Lo HANGUL SYLLABLE GGWAE + {0xAF65, 0xAF7F, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH + {0xAF80, 0xAF80, prLV}, // Lo HANGUL SYLLABLE GGOE + {0xAF81, 0xAF9B, prLVT}, // Lo [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH + {0xAF9C, 0xAF9C, prLV}, // Lo HANGUL SYLLABLE GGYO + {0xAF9D, 0xAFB7, prLVT}, // Lo [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH + {0xAFB8, 0xAFB8, prLV}, // Lo HANGUL SYLLABLE GGU + {0xAFB9, 0xAFD3, prLVT}, // Lo [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH + {0xAFD4, 0xAFD4, prLV}, // Lo HANGUL SYLLABLE GGWEO + {0xAFD5, 0xAFEF, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH + {0xAFF0, 0xAFF0, prLV}, // Lo HANGUL SYLLABLE GGWE + {0xAFF1, 0xB00B, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH + {0xB00C, 0xB00C, prLV}, // Lo HANGUL SYLLABLE GGWI + {0xB00D, 0xB027, prLVT}, // Lo [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH + {0xB028, 0xB028, prLV}, // Lo HANGUL SYLLABLE GGYU + {0xB029, 0xB043, prLVT}, // Lo [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH + {0xB044, 0xB044, prLV}, // Lo HANGUL SYLLABLE GGEU + {0xB045, 0xB05F, prLVT}, // Lo [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH + {0xB060, 0xB060, prLV}, // Lo HANGUL SYLLABLE GGYI + {0xB061, 0xB07B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH + {0xB07C, 0xB07C, prLV}, // Lo HANGUL SYLLABLE GGI + {0xB07D, 0xB097, prLVT}, // Lo [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH + {0xB098, 0xB098, prLV}, // Lo HANGUL SYLLABLE NA + {0xB099, 0xB0B3, prLVT}, // Lo [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH + {0xB0B4, 0xB0B4, prLV}, // Lo HANGUL SYLLABLE NAE + {0xB0B5, 0xB0CF, prLVT}, // Lo [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH + {0xB0D0, 0xB0D0, prLV}, // Lo HANGUL SYLLABLE NYA + {0xB0D1, 0xB0EB, prLVT}, // Lo [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH + {0xB0EC, 0xB0EC, prLV}, // Lo HANGUL SYLLABLE NYAE + {0xB0ED, 0xB107, prLVT}, // Lo [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH + {0xB108, 0xB108, prLV}, // Lo HANGUL SYLLABLE NEO + {0xB109, 0xB123, prLVT}, // Lo [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH + {0xB124, 0xB124, prLV}, // Lo HANGUL SYLLABLE NE + {0xB125, 0xB13F, prLVT}, // Lo [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH + {0xB140, 0xB140, prLV}, // Lo HANGUL SYLLABLE NYEO + {0xB141, 0xB15B, prLVT}, // Lo [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH + {0xB15C, 0xB15C, prLV}, // Lo HANGUL SYLLABLE NYE + {0xB15D, 0xB177, prLVT}, // Lo [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH + {0xB178, 0xB178, prLV}, // Lo HANGUL SYLLABLE NO + {0xB179, 0xB193, prLVT}, // Lo [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH + {0xB194, 0xB194, prLV}, // Lo HANGUL SYLLABLE NWA + {0xB195, 0xB1AF, prLVT}, // Lo [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH + {0xB1B0, 0xB1B0, prLV}, // Lo HANGUL SYLLABLE NWAE + {0xB1B1, 0xB1CB, prLVT}, // Lo [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH + {0xB1CC, 0xB1CC, prLV}, // Lo HANGUL SYLLABLE NOE + {0xB1CD, 0xB1E7, prLVT}, // Lo [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH + {0xB1E8, 0xB1E8, prLV}, // Lo HANGUL SYLLABLE NYO + {0xB1E9, 0xB203, prLVT}, // Lo [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH + {0xB204, 0xB204, prLV}, // Lo HANGUL SYLLABLE NU + {0xB205, 0xB21F, prLVT}, // Lo [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH + {0xB220, 0xB220, prLV}, // Lo HANGUL SYLLABLE NWEO + {0xB221, 0xB23B, prLVT}, // Lo [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH + {0xB23C, 0xB23C, prLV}, // Lo HANGUL SYLLABLE NWE + {0xB23D, 0xB257, prLVT}, // Lo [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH + {0xB258, 0xB258, prLV}, // Lo HANGUL SYLLABLE NWI + {0xB259, 0xB273, prLVT}, // Lo [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH + {0xB274, 0xB274, prLV}, // Lo HANGUL SYLLABLE NYU + {0xB275, 0xB28F, prLVT}, // Lo [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH + {0xB290, 0xB290, prLV}, // Lo HANGUL SYLLABLE NEU + {0xB291, 0xB2AB, prLVT}, // Lo [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH + {0xB2AC, 0xB2AC, prLV}, // Lo HANGUL SYLLABLE NYI + {0xB2AD, 0xB2C7, prLVT}, // Lo [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH + {0xB2C8, 0xB2C8, prLV}, // Lo HANGUL SYLLABLE NI + {0xB2C9, 0xB2E3, prLVT}, // Lo [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH + {0xB2E4, 0xB2E4, prLV}, // Lo HANGUL SYLLABLE DA + {0xB2E5, 0xB2FF, prLVT}, // Lo [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH + {0xB300, 0xB300, prLV}, // Lo HANGUL SYLLABLE DAE + {0xB301, 0xB31B, prLVT}, // Lo [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH + {0xB31C, 0xB31C, prLV}, // Lo HANGUL SYLLABLE DYA + {0xB31D, 0xB337, prLVT}, // Lo [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH + {0xB338, 0xB338, prLV}, // Lo HANGUL SYLLABLE DYAE + {0xB339, 0xB353, prLVT}, // Lo [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH + {0xB354, 0xB354, prLV}, // Lo HANGUL SYLLABLE DEO + {0xB355, 0xB36F, prLVT}, // Lo [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH + {0xB370, 0xB370, prLV}, // Lo HANGUL SYLLABLE DE + {0xB371, 0xB38B, prLVT}, // Lo [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH + {0xB38C, 0xB38C, prLV}, // Lo HANGUL SYLLABLE DYEO + {0xB38D, 0xB3A7, prLVT}, // Lo [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH + {0xB3A8, 0xB3A8, prLV}, // Lo HANGUL SYLLABLE DYE + {0xB3A9, 0xB3C3, prLVT}, // Lo [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH + {0xB3C4, 0xB3C4, prLV}, // Lo HANGUL SYLLABLE DO + {0xB3C5, 0xB3DF, prLVT}, // Lo [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH + {0xB3E0, 0xB3E0, prLV}, // Lo HANGUL SYLLABLE DWA + {0xB3E1, 0xB3FB, prLVT}, // Lo [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH + {0xB3FC, 0xB3FC, prLV}, // Lo HANGUL SYLLABLE DWAE + {0xB3FD, 0xB417, prLVT}, // Lo [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH + {0xB418, 0xB418, prLV}, // Lo HANGUL SYLLABLE DOE + {0xB419, 0xB433, prLVT}, // Lo [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH + {0xB434, 0xB434, prLV}, // Lo HANGUL SYLLABLE DYO + {0xB435, 0xB44F, prLVT}, // Lo [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH + {0xB450, 0xB450, prLV}, // Lo HANGUL SYLLABLE DU + {0xB451, 0xB46B, prLVT}, // Lo [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH + {0xB46C, 0xB46C, prLV}, // Lo HANGUL SYLLABLE DWEO + {0xB46D, 0xB487, prLVT}, // Lo [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH + {0xB488, 0xB488, prLV}, // Lo HANGUL SYLLABLE DWE + {0xB489, 0xB4A3, prLVT}, // Lo [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH + {0xB4A4, 0xB4A4, prLV}, // Lo HANGUL SYLLABLE DWI + {0xB4A5, 0xB4BF, prLVT}, // Lo [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH + {0xB4C0, 0xB4C0, prLV}, // Lo HANGUL SYLLABLE DYU + {0xB4C1, 0xB4DB, prLVT}, // Lo [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH + {0xB4DC, 0xB4DC, prLV}, // Lo HANGUL SYLLABLE DEU + {0xB4DD, 0xB4F7, prLVT}, // Lo [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH + {0xB4F8, 0xB4F8, prLV}, // Lo HANGUL SYLLABLE DYI + {0xB4F9, 0xB513, prLVT}, // Lo [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH + {0xB514, 0xB514, prLV}, // Lo HANGUL SYLLABLE DI + {0xB515, 0xB52F, prLVT}, // Lo [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH + {0xB530, 0xB530, prLV}, // Lo HANGUL SYLLABLE DDA + {0xB531, 0xB54B, prLVT}, // Lo [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH + {0xB54C, 0xB54C, prLV}, // Lo HANGUL SYLLABLE DDAE + {0xB54D, 0xB567, prLVT}, // Lo [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH + {0xB568, 0xB568, prLV}, // Lo HANGUL SYLLABLE DDYA + {0xB569, 0xB583, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH + {0xB584, 0xB584, prLV}, // Lo HANGUL SYLLABLE DDYAE + {0xB585, 0xB59F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH + {0xB5A0, 0xB5A0, prLV}, // Lo HANGUL SYLLABLE DDEO + {0xB5A1, 0xB5BB, prLVT}, // Lo [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH + {0xB5BC, 0xB5BC, prLV}, // Lo HANGUL SYLLABLE DDE + {0xB5BD, 0xB5D7, prLVT}, // Lo [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH + {0xB5D8, 0xB5D8, prLV}, // Lo HANGUL SYLLABLE DDYEO + {0xB5D9, 0xB5F3, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH + {0xB5F4, 0xB5F4, prLV}, // Lo HANGUL SYLLABLE DDYE + {0xB5F5, 0xB60F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH + {0xB610, 0xB610, prLV}, // Lo HANGUL SYLLABLE DDO + {0xB611, 0xB62B, prLVT}, // Lo [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH + {0xB62C, 0xB62C, prLV}, // Lo HANGUL SYLLABLE DDWA + {0xB62D, 0xB647, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH + {0xB648, 0xB648, prLV}, // Lo HANGUL SYLLABLE DDWAE + {0xB649, 0xB663, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH + {0xB664, 0xB664, prLV}, // Lo HANGUL SYLLABLE DDOE + {0xB665, 0xB67F, prLVT}, // Lo [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH + {0xB680, 0xB680, prLV}, // Lo HANGUL SYLLABLE DDYO + {0xB681, 0xB69B, prLVT}, // Lo [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH + {0xB69C, 0xB69C, prLV}, // Lo HANGUL SYLLABLE DDU + {0xB69D, 0xB6B7, prLVT}, // Lo [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH + {0xB6B8, 0xB6B8, prLV}, // Lo HANGUL SYLLABLE DDWEO + {0xB6B9, 0xB6D3, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH + {0xB6D4, 0xB6D4, prLV}, // Lo HANGUL SYLLABLE DDWE + {0xB6D5, 0xB6EF, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH + {0xB6F0, 0xB6F0, prLV}, // Lo HANGUL SYLLABLE DDWI + {0xB6F1, 0xB70B, prLVT}, // Lo [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH + {0xB70C, 0xB70C, prLV}, // Lo HANGUL SYLLABLE DDYU + {0xB70D, 0xB727, prLVT}, // Lo [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH + {0xB728, 0xB728, prLV}, // Lo HANGUL SYLLABLE DDEU + {0xB729, 0xB743, prLVT}, // Lo [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH + {0xB744, 0xB744, prLV}, // Lo HANGUL SYLLABLE DDYI + {0xB745, 0xB75F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH + {0xB760, 0xB760, prLV}, // Lo HANGUL SYLLABLE DDI + {0xB761, 0xB77B, prLVT}, // Lo [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH + {0xB77C, 0xB77C, prLV}, // Lo HANGUL SYLLABLE RA + {0xB77D, 0xB797, prLVT}, // Lo [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH + {0xB798, 0xB798, prLV}, // Lo HANGUL SYLLABLE RAE + {0xB799, 0xB7B3, prLVT}, // Lo [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH + {0xB7B4, 0xB7B4, prLV}, // Lo HANGUL SYLLABLE RYA + {0xB7B5, 0xB7CF, prLVT}, // Lo [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH + {0xB7D0, 0xB7D0, prLV}, // Lo HANGUL SYLLABLE RYAE + {0xB7D1, 0xB7EB, prLVT}, // Lo [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH + {0xB7EC, 0xB7EC, prLV}, // Lo HANGUL SYLLABLE REO + {0xB7ED, 0xB807, prLVT}, // Lo [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH + {0xB808, 0xB808, prLV}, // Lo HANGUL SYLLABLE RE + {0xB809, 0xB823, prLVT}, // Lo [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH + {0xB824, 0xB824, prLV}, // Lo HANGUL SYLLABLE RYEO + {0xB825, 0xB83F, prLVT}, // Lo [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH + {0xB840, 0xB840, prLV}, // Lo HANGUL SYLLABLE RYE + {0xB841, 0xB85B, prLVT}, // Lo [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH + {0xB85C, 0xB85C, prLV}, // Lo HANGUL SYLLABLE RO + {0xB85D, 0xB877, prLVT}, // Lo [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH + {0xB878, 0xB878, prLV}, // Lo HANGUL SYLLABLE RWA + {0xB879, 0xB893, prLVT}, // Lo [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH + {0xB894, 0xB894, prLV}, // Lo HANGUL SYLLABLE RWAE + {0xB895, 0xB8AF, prLVT}, // Lo [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH + {0xB8B0, 0xB8B0, prLV}, // Lo HANGUL SYLLABLE ROE + {0xB8B1, 0xB8CB, prLVT}, // Lo [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH + {0xB8CC, 0xB8CC, prLV}, // Lo HANGUL SYLLABLE RYO + {0xB8CD, 0xB8E7, prLVT}, // Lo [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH + {0xB8E8, 0xB8E8, prLV}, // Lo HANGUL SYLLABLE RU + {0xB8E9, 0xB903, prLVT}, // Lo [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH + {0xB904, 0xB904, prLV}, // Lo HANGUL SYLLABLE RWEO + {0xB905, 0xB91F, prLVT}, // Lo [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH + {0xB920, 0xB920, prLV}, // Lo HANGUL SYLLABLE RWE + {0xB921, 0xB93B, prLVT}, // Lo [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH + {0xB93C, 0xB93C, prLV}, // Lo HANGUL SYLLABLE RWI + {0xB93D, 0xB957, prLVT}, // Lo [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH + {0xB958, 0xB958, prLV}, // Lo HANGUL SYLLABLE RYU + {0xB959, 0xB973, prLVT}, // Lo [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH + {0xB974, 0xB974, prLV}, // Lo HANGUL SYLLABLE REU + {0xB975, 0xB98F, prLVT}, // Lo [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH + {0xB990, 0xB990, prLV}, // Lo HANGUL SYLLABLE RYI + {0xB991, 0xB9AB, prLVT}, // Lo [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH + {0xB9AC, 0xB9AC, prLV}, // Lo HANGUL SYLLABLE RI + {0xB9AD, 0xB9C7, prLVT}, // Lo [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH + {0xB9C8, 0xB9C8, prLV}, // Lo HANGUL SYLLABLE MA + {0xB9C9, 0xB9E3, prLVT}, // Lo [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH + {0xB9E4, 0xB9E4, prLV}, // Lo HANGUL SYLLABLE MAE + {0xB9E5, 0xB9FF, prLVT}, // Lo [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH + {0xBA00, 0xBA00, prLV}, // Lo HANGUL SYLLABLE MYA + {0xBA01, 0xBA1B, prLVT}, // Lo [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH + {0xBA1C, 0xBA1C, prLV}, // Lo HANGUL SYLLABLE MYAE + {0xBA1D, 0xBA37, prLVT}, // Lo [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH + {0xBA38, 0xBA38, prLV}, // Lo HANGUL SYLLABLE MEO + {0xBA39, 0xBA53, prLVT}, // Lo [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH + {0xBA54, 0xBA54, prLV}, // Lo HANGUL SYLLABLE ME + {0xBA55, 0xBA6F, prLVT}, // Lo [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH + {0xBA70, 0xBA70, prLV}, // Lo HANGUL SYLLABLE MYEO + {0xBA71, 0xBA8B, prLVT}, // Lo [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH + {0xBA8C, 0xBA8C, prLV}, // Lo HANGUL SYLLABLE MYE + {0xBA8D, 0xBAA7, prLVT}, // Lo [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH + {0xBAA8, 0xBAA8, prLV}, // Lo HANGUL SYLLABLE MO + {0xBAA9, 0xBAC3, prLVT}, // Lo [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH + {0xBAC4, 0xBAC4, prLV}, // Lo HANGUL SYLLABLE MWA + {0xBAC5, 0xBADF, prLVT}, // Lo [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH + {0xBAE0, 0xBAE0, prLV}, // Lo HANGUL SYLLABLE MWAE + {0xBAE1, 0xBAFB, prLVT}, // Lo [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH + {0xBAFC, 0xBAFC, prLV}, // Lo HANGUL SYLLABLE MOE + {0xBAFD, 0xBB17, prLVT}, // Lo [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH + {0xBB18, 0xBB18, prLV}, // Lo HANGUL SYLLABLE MYO + {0xBB19, 0xBB33, prLVT}, // Lo [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH + {0xBB34, 0xBB34, prLV}, // Lo HANGUL SYLLABLE MU + {0xBB35, 0xBB4F, prLVT}, // Lo [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH + {0xBB50, 0xBB50, prLV}, // Lo HANGUL SYLLABLE MWEO + {0xBB51, 0xBB6B, prLVT}, // Lo [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH + {0xBB6C, 0xBB6C, prLV}, // Lo HANGUL SYLLABLE MWE + {0xBB6D, 0xBB87, prLVT}, // Lo [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH + {0xBB88, 0xBB88, prLV}, // Lo HANGUL SYLLABLE MWI + {0xBB89, 0xBBA3, prLVT}, // Lo [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH + {0xBBA4, 0xBBA4, prLV}, // Lo HANGUL SYLLABLE MYU + {0xBBA5, 0xBBBF, prLVT}, // Lo [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH + {0xBBC0, 0xBBC0, prLV}, // Lo HANGUL SYLLABLE MEU + {0xBBC1, 0xBBDB, prLVT}, // Lo [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH + {0xBBDC, 0xBBDC, prLV}, // Lo HANGUL SYLLABLE MYI + {0xBBDD, 0xBBF7, prLVT}, // Lo [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH + {0xBBF8, 0xBBF8, prLV}, // Lo HANGUL SYLLABLE MI + {0xBBF9, 0xBC13, prLVT}, // Lo [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH + {0xBC14, 0xBC14, prLV}, // Lo HANGUL SYLLABLE BA + {0xBC15, 0xBC2F, prLVT}, // Lo [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH + {0xBC30, 0xBC30, prLV}, // Lo HANGUL SYLLABLE BAE + {0xBC31, 0xBC4B, prLVT}, // Lo [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH + {0xBC4C, 0xBC4C, prLV}, // Lo HANGUL SYLLABLE BYA + {0xBC4D, 0xBC67, prLVT}, // Lo [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH + {0xBC68, 0xBC68, prLV}, // Lo HANGUL SYLLABLE BYAE + {0xBC69, 0xBC83, prLVT}, // Lo [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH + {0xBC84, 0xBC84, prLV}, // Lo HANGUL SYLLABLE BEO + {0xBC85, 0xBC9F, prLVT}, // Lo [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH + {0xBCA0, 0xBCA0, prLV}, // Lo HANGUL SYLLABLE BE + {0xBCA1, 0xBCBB, prLVT}, // Lo [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH + {0xBCBC, 0xBCBC, prLV}, // Lo HANGUL SYLLABLE BYEO + {0xBCBD, 0xBCD7, prLVT}, // Lo [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH + {0xBCD8, 0xBCD8, prLV}, // Lo HANGUL SYLLABLE BYE + {0xBCD9, 0xBCF3, prLVT}, // Lo [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH + {0xBCF4, 0xBCF4, prLV}, // Lo HANGUL SYLLABLE BO + {0xBCF5, 0xBD0F, prLVT}, // Lo [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH + {0xBD10, 0xBD10, prLV}, // Lo HANGUL SYLLABLE BWA + {0xBD11, 0xBD2B, prLVT}, // Lo [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH + {0xBD2C, 0xBD2C, prLV}, // Lo HANGUL SYLLABLE BWAE + {0xBD2D, 0xBD47, prLVT}, // Lo [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH + {0xBD48, 0xBD48, prLV}, // Lo HANGUL SYLLABLE BOE + {0xBD49, 0xBD63, prLVT}, // Lo [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH + {0xBD64, 0xBD64, prLV}, // Lo HANGUL SYLLABLE BYO + {0xBD65, 0xBD7F, prLVT}, // Lo [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH + {0xBD80, 0xBD80, prLV}, // Lo HANGUL SYLLABLE BU + {0xBD81, 0xBD9B, prLVT}, // Lo [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH + {0xBD9C, 0xBD9C, prLV}, // Lo HANGUL SYLLABLE BWEO + {0xBD9D, 0xBDB7, prLVT}, // Lo [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH + {0xBDB8, 0xBDB8, prLV}, // Lo HANGUL SYLLABLE BWE + {0xBDB9, 0xBDD3, prLVT}, // Lo [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH + {0xBDD4, 0xBDD4, prLV}, // Lo HANGUL SYLLABLE BWI + {0xBDD5, 0xBDEF, prLVT}, // Lo [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH + {0xBDF0, 0xBDF0, prLV}, // Lo HANGUL SYLLABLE BYU + {0xBDF1, 0xBE0B, prLVT}, // Lo [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH + {0xBE0C, 0xBE0C, prLV}, // Lo HANGUL SYLLABLE BEU + {0xBE0D, 0xBE27, prLVT}, // Lo [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH + {0xBE28, 0xBE28, prLV}, // Lo HANGUL SYLLABLE BYI + {0xBE29, 0xBE43, prLVT}, // Lo [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH + {0xBE44, 0xBE44, prLV}, // Lo HANGUL SYLLABLE BI + {0xBE45, 0xBE5F, prLVT}, // Lo [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH + {0xBE60, 0xBE60, prLV}, // Lo HANGUL SYLLABLE BBA + {0xBE61, 0xBE7B, prLVT}, // Lo [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH + {0xBE7C, 0xBE7C, prLV}, // Lo HANGUL SYLLABLE BBAE + {0xBE7D, 0xBE97, prLVT}, // Lo [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH + {0xBE98, 0xBE98, prLV}, // Lo HANGUL SYLLABLE BBYA + {0xBE99, 0xBEB3, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH + {0xBEB4, 0xBEB4, prLV}, // Lo HANGUL SYLLABLE BBYAE + {0xBEB5, 0xBECF, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH + {0xBED0, 0xBED0, prLV}, // Lo HANGUL SYLLABLE BBEO + {0xBED1, 0xBEEB, prLVT}, // Lo [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH + {0xBEEC, 0xBEEC, prLV}, // Lo HANGUL SYLLABLE BBE + {0xBEED, 0xBF07, prLVT}, // Lo [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH + {0xBF08, 0xBF08, prLV}, // Lo HANGUL SYLLABLE BBYEO + {0xBF09, 0xBF23, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH + {0xBF24, 0xBF24, prLV}, // Lo HANGUL SYLLABLE BBYE + {0xBF25, 0xBF3F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH + {0xBF40, 0xBF40, prLV}, // Lo HANGUL SYLLABLE BBO + {0xBF41, 0xBF5B, prLVT}, // Lo [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH + {0xBF5C, 0xBF5C, prLV}, // Lo HANGUL SYLLABLE BBWA + {0xBF5D, 0xBF77, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH + {0xBF78, 0xBF78, prLV}, // Lo HANGUL SYLLABLE BBWAE + {0xBF79, 0xBF93, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH + {0xBF94, 0xBF94, prLV}, // Lo HANGUL SYLLABLE BBOE + {0xBF95, 0xBFAF, prLVT}, // Lo [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH + {0xBFB0, 0xBFB0, prLV}, // Lo HANGUL SYLLABLE BBYO + {0xBFB1, 0xBFCB, prLVT}, // Lo [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH + {0xBFCC, 0xBFCC, prLV}, // Lo HANGUL SYLLABLE BBU + {0xBFCD, 0xBFE7, prLVT}, // Lo [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH + {0xBFE8, 0xBFE8, prLV}, // Lo HANGUL SYLLABLE BBWEO + {0xBFE9, 0xC003, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH + {0xC004, 0xC004, prLV}, // Lo HANGUL SYLLABLE BBWE + {0xC005, 0xC01F, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH + {0xC020, 0xC020, prLV}, // Lo HANGUL SYLLABLE BBWI + {0xC021, 0xC03B, prLVT}, // Lo [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH + {0xC03C, 0xC03C, prLV}, // Lo HANGUL SYLLABLE BBYU + {0xC03D, 0xC057, prLVT}, // Lo [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH + {0xC058, 0xC058, prLV}, // Lo HANGUL SYLLABLE BBEU + {0xC059, 0xC073, prLVT}, // Lo [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH + {0xC074, 0xC074, prLV}, // Lo HANGUL SYLLABLE BBYI + {0xC075, 0xC08F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH + {0xC090, 0xC090, prLV}, // Lo HANGUL SYLLABLE BBI + {0xC091, 0xC0AB, prLVT}, // Lo [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH + {0xC0AC, 0xC0AC, prLV}, // Lo HANGUL SYLLABLE SA + {0xC0AD, 0xC0C7, prLVT}, // Lo [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH + {0xC0C8, 0xC0C8, prLV}, // Lo HANGUL SYLLABLE SAE + {0xC0C9, 0xC0E3, prLVT}, // Lo [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH + {0xC0E4, 0xC0E4, prLV}, // Lo HANGUL SYLLABLE SYA + {0xC0E5, 0xC0FF, prLVT}, // Lo [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH + {0xC100, 0xC100, prLV}, // Lo HANGUL SYLLABLE SYAE + {0xC101, 0xC11B, prLVT}, // Lo [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH + {0xC11C, 0xC11C, prLV}, // Lo HANGUL SYLLABLE SEO + {0xC11D, 0xC137, prLVT}, // Lo [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH + {0xC138, 0xC138, prLV}, // Lo HANGUL SYLLABLE SE + {0xC139, 0xC153, prLVT}, // Lo [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH + {0xC154, 0xC154, prLV}, // Lo HANGUL SYLLABLE SYEO + {0xC155, 0xC16F, prLVT}, // Lo [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH + {0xC170, 0xC170, prLV}, // Lo HANGUL SYLLABLE SYE + {0xC171, 0xC18B, prLVT}, // Lo [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH + {0xC18C, 0xC18C, prLV}, // Lo HANGUL SYLLABLE SO + {0xC18D, 0xC1A7, prLVT}, // Lo [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH + {0xC1A8, 0xC1A8, prLV}, // Lo HANGUL SYLLABLE SWA + {0xC1A9, 0xC1C3, prLVT}, // Lo [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH + {0xC1C4, 0xC1C4, prLV}, // Lo HANGUL SYLLABLE SWAE + {0xC1C5, 0xC1DF, prLVT}, // Lo [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH + {0xC1E0, 0xC1E0, prLV}, // Lo HANGUL SYLLABLE SOE + {0xC1E1, 0xC1FB, prLVT}, // Lo [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH + {0xC1FC, 0xC1FC, prLV}, // Lo HANGUL SYLLABLE SYO + {0xC1FD, 0xC217, prLVT}, // Lo [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH + {0xC218, 0xC218, prLV}, // Lo HANGUL SYLLABLE SU + {0xC219, 0xC233, prLVT}, // Lo [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH + {0xC234, 0xC234, prLV}, // Lo HANGUL SYLLABLE SWEO + {0xC235, 0xC24F, prLVT}, // Lo [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH + {0xC250, 0xC250, prLV}, // Lo HANGUL SYLLABLE SWE + {0xC251, 0xC26B, prLVT}, // Lo [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH + {0xC26C, 0xC26C, prLV}, // Lo HANGUL SYLLABLE SWI + {0xC26D, 0xC287, prLVT}, // Lo [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH + {0xC288, 0xC288, prLV}, // Lo HANGUL SYLLABLE SYU + {0xC289, 0xC2A3, prLVT}, // Lo [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH + {0xC2A4, 0xC2A4, prLV}, // Lo HANGUL SYLLABLE SEU + {0xC2A5, 0xC2BF, prLVT}, // Lo [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH + {0xC2C0, 0xC2C0, prLV}, // Lo HANGUL SYLLABLE SYI + {0xC2C1, 0xC2DB, prLVT}, // Lo [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH + {0xC2DC, 0xC2DC, prLV}, // Lo HANGUL SYLLABLE SI + {0xC2DD, 0xC2F7, prLVT}, // Lo [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH + {0xC2F8, 0xC2F8, prLV}, // Lo HANGUL SYLLABLE SSA + {0xC2F9, 0xC313, prLVT}, // Lo [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH + {0xC314, 0xC314, prLV}, // Lo HANGUL SYLLABLE SSAE + {0xC315, 0xC32F, prLVT}, // Lo [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH + {0xC330, 0xC330, prLV}, // Lo HANGUL SYLLABLE SSYA + {0xC331, 0xC34B, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH + {0xC34C, 0xC34C, prLV}, // Lo HANGUL SYLLABLE SSYAE + {0xC34D, 0xC367, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH + {0xC368, 0xC368, prLV}, // Lo HANGUL SYLLABLE SSEO + {0xC369, 0xC383, prLVT}, // Lo [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH + {0xC384, 0xC384, prLV}, // Lo HANGUL SYLLABLE SSE + {0xC385, 0xC39F, prLVT}, // Lo [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH + {0xC3A0, 0xC3A0, prLV}, // Lo HANGUL SYLLABLE SSYEO + {0xC3A1, 0xC3BB, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH + {0xC3BC, 0xC3BC, prLV}, // Lo HANGUL SYLLABLE SSYE + {0xC3BD, 0xC3D7, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH + {0xC3D8, 0xC3D8, prLV}, // Lo HANGUL SYLLABLE SSO + {0xC3D9, 0xC3F3, prLVT}, // Lo [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH + {0xC3F4, 0xC3F4, prLV}, // Lo HANGUL SYLLABLE SSWA + {0xC3F5, 0xC40F, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH + {0xC410, 0xC410, prLV}, // Lo HANGUL SYLLABLE SSWAE + {0xC411, 0xC42B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH + {0xC42C, 0xC42C, prLV}, // Lo HANGUL SYLLABLE SSOE + {0xC42D, 0xC447, prLVT}, // Lo [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH + {0xC448, 0xC448, prLV}, // Lo HANGUL SYLLABLE SSYO + {0xC449, 0xC463, prLVT}, // Lo [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH + {0xC464, 0xC464, prLV}, // Lo HANGUL SYLLABLE SSU + {0xC465, 0xC47F, prLVT}, // Lo [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH + {0xC480, 0xC480, prLV}, // Lo HANGUL SYLLABLE SSWEO + {0xC481, 0xC49B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH + {0xC49C, 0xC49C, prLV}, // Lo HANGUL SYLLABLE SSWE + {0xC49D, 0xC4B7, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH + {0xC4B8, 0xC4B8, prLV}, // Lo HANGUL SYLLABLE SSWI + {0xC4B9, 0xC4D3, prLVT}, // Lo [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH + {0xC4D4, 0xC4D4, prLV}, // Lo HANGUL SYLLABLE SSYU + {0xC4D5, 0xC4EF, prLVT}, // Lo [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH + {0xC4F0, 0xC4F0, prLV}, // Lo HANGUL SYLLABLE SSEU + {0xC4F1, 0xC50B, prLVT}, // Lo [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH + {0xC50C, 0xC50C, prLV}, // Lo HANGUL SYLLABLE SSYI + {0xC50D, 0xC527, prLVT}, // Lo [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH + {0xC528, 0xC528, prLV}, // Lo HANGUL SYLLABLE SSI + {0xC529, 0xC543, prLVT}, // Lo [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH + {0xC544, 0xC544, prLV}, // Lo HANGUL SYLLABLE A + {0xC545, 0xC55F, prLVT}, // Lo [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH + {0xC560, 0xC560, prLV}, // Lo HANGUL SYLLABLE AE + {0xC561, 0xC57B, prLVT}, // Lo [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH + {0xC57C, 0xC57C, prLV}, // Lo HANGUL SYLLABLE YA + {0xC57D, 0xC597, prLVT}, // Lo [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH + {0xC598, 0xC598, prLV}, // Lo HANGUL SYLLABLE YAE + {0xC599, 0xC5B3, prLVT}, // Lo [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH + {0xC5B4, 0xC5B4, prLV}, // Lo HANGUL SYLLABLE EO + {0xC5B5, 0xC5CF, prLVT}, // Lo [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH + {0xC5D0, 0xC5D0, prLV}, // Lo HANGUL SYLLABLE E + {0xC5D1, 0xC5EB, prLVT}, // Lo [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH + {0xC5EC, 0xC5EC, prLV}, // Lo HANGUL SYLLABLE YEO + {0xC5ED, 0xC607, prLVT}, // Lo [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH + {0xC608, 0xC608, prLV}, // Lo HANGUL SYLLABLE YE + {0xC609, 0xC623, prLVT}, // Lo [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH + {0xC624, 0xC624, prLV}, // Lo HANGUL SYLLABLE O + {0xC625, 0xC63F, prLVT}, // Lo [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH + {0xC640, 0xC640, prLV}, // Lo HANGUL SYLLABLE WA + {0xC641, 0xC65B, prLVT}, // Lo [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH + {0xC65C, 0xC65C, prLV}, // Lo HANGUL SYLLABLE WAE + {0xC65D, 0xC677, prLVT}, // Lo [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH + {0xC678, 0xC678, prLV}, // Lo HANGUL SYLLABLE OE + {0xC679, 0xC693, prLVT}, // Lo [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH + {0xC694, 0xC694, prLV}, // Lo HANGUL SYLLABLE YO + {0xC695, 0xC6AF, prLVT}, // Lo [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH + {0xC6B0, 0xC6B0, prLV}, // Lo HANGUL SYLLABLE U + {0xC6B1, 0xC6CB, prLVT}, // Lo [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH + {0xC6CC, 0xC6CC, prLV}, // Lo HANGUL SYLLABLE WEO + {0xC6CD, 0xC6E7, prLVT}, // Lo [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH + {0xC6E8, 0xC6E8, prLV}, // Lo HANGUL SYLLABLE WE + {0xC6E9, 0xC703, prLVT}, // Lo [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH + {0xC704, 0xC704, prLV}, // Lo HANGUL SYLLABLE WI + {0xC705, 0xC71F, prLVT}, // Lo [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH + {0xC720, 0xC720, prLV}, // Lo HANGUL SYLLABLE YU + {0xC721, 0xC73B, prLVT}, // Lo [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH + {0xC73C, 0xC73C, prLV}, // Lo HANGUL SYLLABLE EU + {0xC73D, 0xC757, prLVT}, // Lo [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH + {0xC758, 0xC758, prLV}, // Lo HANGUL SYLLABLE YI + {0xC759, 0xC773, prLVT}, // Lo [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH + {0xC774, 0xC774, prLV}, // Lo HANGUL SYLLABLE I + {0xC775, 0xC78F, prLVT}, // Lo [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH + {0xC790, 0xC790, prLV}, // Lo HANGUL SYLLABLE JA + {0xC791, 0xC7AB, prLVT}, // Lo [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH + {0xC7AC, 0xC7AC, prLV}, // Lo HANGUL SYLLABLE JAE + {0xC7AD, 0xC7C7, prLVT}, // Lo [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH + {0xC7C8, 0xC7C8, prLV}, // Lo HANGUL SYLLABLE JYA + {0xC7C9, 0xC7E3, prLVT}, // Lo [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH + {0xC7E4, 0xC7E4, prLV}, // Lo HANGUL SYLLABLE JYAE + {0xC7E5, 0xC7FF, prLVT}, // Lo [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH + {0xC800, 0xC800, prLV}, // Lo HANGUL SYLLABLE JEO + {0xC801, 0xC81B, prLVT}, // Lo [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH + {0xC81C, 0xC81C, prLV}, // Lo HANGUL SYLLABLE JE + {0xC81D, 0xC837, prLVT}, // Lo [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH + {0xC838, 0xC838, prLV}, // Lo HANGUL SYLLABLE JYEO + {0xC839, 0xC853, prLVT}, // Lo [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH + {0xC854, 0xC854, prLV}, // Lo HANGUL SYLLABLE JYE + {0xC855, 0xC86F, prLVT}, // Lo [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH + {0xC870, 0xC870, prLV}, // Lo HANGUL SYLLABLE JO + {0xC871, 0xC88B, prLVT}, // Lo [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH + {0xC88C, 0xC88C, prLV}, // Lo HANGUL SYLLABLE JWA + {0xC88D, 0xC8A7, prLVT}, // Lo [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH + {0xC8A8, 0xC8A8, prLV}, // Lo HANGUL SYLLABLE JWAE + {0xC8A9, 0xC8C3, prLVT}, // Lo [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH + {0xC8C4, 0xC8C4, prLV}, // Lo HANGUL SYLLABLE JOE + {0xC8C5, 0xC8DF, prLVT}, // Lo [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH + {0xC8E0, 0xC8E0, prLV}, // Lo HANGUL SYLLABLE JYO + {0xC8E1, 0xC8FB, prLVT}, // Lo [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH + {0xC8FC, 0xC8FC, prLV}, // Lo HANGUL SYLLABLE JU + {0xC8FD, 0xC917, prLVT}, // Lo [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH + {0xC918, 0xC918, prLV}, // Lo HANGUL SYLLABLE JWEO + {0xC919, 0xC933, prLVT}, // Lo [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH + {0xC934, 0xC934, prLV}, // Lo HANGUL SYLLABLE JWE + {0xC935, 0xC94F, prLVT}, // Lo [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH + {0xC950, 0xC950, prLV}, // Lo HANGUL SYLLABLE JWI + {0xC951, 0xC96B, prLVT}, // Lo [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH + {0xC96C, 0xC96C, prLV}, // Lo HANGUL SYLLABLE JYU + {0xC96D, 0xC987, prLVT}, // Lo [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH + {0xC988, 0xC988, prLV}, // Lo HANGUL SYLLABLE JEU + {0xC989, 0xC9A3, prLVT}, // Lo [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH + {0xC9A4, 0xC9A4, prLV}, // Lo HANGUL SYLLABLE JYI + {0xC9A5, 0xC9BF, prLVT}, // Lo [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH + {0xC9C0, 0xC9C0, prLV}, // Lo HANGUL SYLLABLE JI + {0xC9C1, 0xC9DB, prLVT}, // Lo [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH + {0xC9DC, 0xC9DC, prLV}, // Lo HANGUL SYLLABLE JJA + {0xC9DD, 0xC9F7, prLVT}, // Lo [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH + {0xC9F8, 0xC9F8, prLV}, // Lo HANGUL SYLLABLE JJAE + {0xC9F9, 0xCA13, prLVT}, // Lo [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH + {0xCA14, 0xCA14, prLV}, // Lo HANGUL SYLLABLE JJYA + {0xCA15, 0xCA2F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH + {0xCA30, 0xCA30, prLV}, // Lo HANGUL SYLLABLE JJYAE + {0xCA31, 0xCA4B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH + {0xCA4C, 0xCA4C, prLV}, // Lo HANGUL SYLLABLE JJEO + {0xCA4D, 0xCA67, prLVT}, // Lo [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH + {0xCA68, 0xCA68, prLV}, // Lo HANGUL SYLLABLE JJE + {0xCA69, 0xCA83, prLVT}, // Lo [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH + {0xCA84, 0xCA84, prLV}, // Lo HANGUL SYLLABLE JJYEO + {0xCA85, 0xCA9F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH + {0xCAA0, 0xCAA0, prLV}, // Lo HANGUL SYLLABLE JJYE + {0xCAA1, 0xCABB, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH + {0xCABC, 0xCABC, prLV}, // Lo HANGUL SYLLABLE JJO + {0xCABD, 0xCAD7, prLVT}, // Lo [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH + {0xCAD8, 0xCAD8, prLV}, // Lo HANGUL SYLLABLE JJWA + {0xCAD9, 0xCAF3, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH + {0xCAF4, 0xCAF4, prLV}, // Lo HANGUL SYLLABLE JJWAE + {0xCAF5, 0xCB0F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH + {0xCB10, 0xCB10, prLV}, // Lo HANGUL SYLLABLE JJOE + {0xCB11, 0xCB2B, prLVT}, // Lo [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH + {0xCB2C, 0xCB2C, prLV}, // Lo HANGUL SYLLABLE JJYO + {0xCB2D, 0xCB47, prLVT}, // Lo [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH + {0xCB48, 0xCB48, prLV}, // Lo HANGUL SYLLABLE JJU + {0xCB49, 0xCB63, prLVT}, // Lo [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH + {0xCB64, 0xCB64, prLV}, // Lo HANGUL SYLLABLE JJWEO + {0xCB65, 0xCB7F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH + {0xCB80, 0xCB80, prLV}, // Lo HANGUL SYLLABLE JJWE + {0xCB81, 0xCB9B, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH + {0xCB9C, 0xCB9C, prLV}, // Lo HANGUL SYLLABLE JJWI + {0xCB9D, 0xCBB7, prLVT}, // Lo [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH + {0xCBB8, 0xCBB8, prLV}, // Lo HANGUL SYLLABLE JJYU + {0xCBB9, 0xCBD3, prLVT}, // Lo [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH + {0xCBD4, 0xCBD4, prLV}, // Lo HANGUL SYLLABLE JJEU + {0xCBD5, 0xCBEF, prLVT}, // Lo [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH + {0xCBF0, 0xCBF0, prLV}, // Lo HANGUL SYLLABLE JJYI + {0xCBF1, 0xCC0B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH + {0xCC0C, 0xCC0C, prLV}, // Lo HANGUL SYLLABLE JJI + {0xCC0D, 0xCC27, prLVT}, // Lo [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH + {0xCC28, 0xCC28, prLV}, // Lo HANGUL SYLLABLE CA + {0xCC29, 0xCC43, prLVT}, // Lo [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH + {0xCC44, 0xCC44, prLV}, // Lo HANGUL SYLLABLE CAE + {0xCC45, 0xCC5F, prLVT}, // Lo [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH + {0xCC60, 0xCC60, prLV}, // Lo HANGUL SYLLABLE CYA + {0xCC61, 0xCC7B, prLVT}, // Lo [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH + {0xCC7C, 0xCC7C, prLV}, // Lo HANGUL SYLLABLE CYAE + {0xCC7D, 0xCC97, prLVT}, // Lo [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH + {0xCC98, 0xCC98, prLV}, // Lo HANGUL SYLLABLE CEO + {0xCC99, 0xCCB3, prLVT}, // Lo [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH + {0xCCB4, 0xCCB4, prLV}, // Lo HANGUL SYLLABLE CE + {0xCCB5, 0xCCCF, prLVT}, // Lo [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH + {0xCCD0, 0xCCD0, prLV}, // Lo HANGUL SYLLABLE CYEO + {0xCCD1, 0xCCEB, prLVT}, // Lo [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH + {0xCCEC, 0xCCEC, prLV}, // Lo HANGUL SYLLABLE CYE + {0xCCED, 0xCD07, prLVT}, // Lo [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH + {0xCD08, 0xCD08, prLV}, // Lo HANGUL SYLLABLE CO + {0xCD09, 0xCD23, prLVT}, // Lo [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH + {0xCD24, 0xCD24, prLV}, // Lo HANGUL SYLLABLE CWA + {0xCD25, 0xCD3F, prLVT}, // Lo [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH + {0xCD40, 0xCD40, prLV}, // Lo HANGUL SYLLABLE CWAE + {0xCD41, 0xCD5B, prLVT}, // Lo [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH + {0xCD5C, 0xCD5C, prLV}, // Lo HANGUL SYLLABLE COE + {0xCD5D, 0xCD77, prLVT}, // Lo [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH + {0xCD78, 0xCD78, prLV}, // Lo HANGUL SYLLABLE CYO + {0xCD79, 0xCD93, prLVT}, // Lo [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH + {0xCD94, 0xCD94, prLV}, // Lo HANGUL SYLLABLE CU + {0xCD95, 0xCDAF, prLVT}, // Lo [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH + {0xCDB0, 0xCDB0, prLV}, // Lo HANGUL SYLLABLE CWEO + {0xCDB1, 0xCDCB, prLVT}, // Lo [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH + {0xCDCC, 0xCDCC, prLV}, // Lo HANGUL SYLLABLE CWE + {0xCDCD, 0xCDE7, prLVT}, // Lo [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH + {0xCDE8, 0xCDE8, prLV}, // Lo HANGUL SYLLABLE CWI + {0xCDE9, 0xCE03, prLVT}, // Lo [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH + {0xCE04, 0xCE04, prLV}, // Lo HANGUL SYLLABLE CYU + {0xCE05, 0xCE1F, prLVT}, // Lo [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH + {0xCE20, 0xCE20, prLV}, // Lo HANGUL SYLLABLE CEU + {0xCE21, 0xCE3B, prLVT}, // Lo [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH + {0xCE3C, 0xCE3C, prLV}, // Lo HANGUL SYLLABLE CYI + {0xCE3D, 0xCE57, prLVT}, // Lo [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH + {0xCE58, 0xCE58, prLV}, // Lo HANGUL SYLLABLE CI + {0xCE59, 0xCE73, prLVT}, // Lo [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH + {0xCE74, 0xCE74, prLV}, // Lo HANGUL SYLLABLE KA + {0xCE75, 0xCE8F, prLVT}, // Lo [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH + {0xCE90, 0xCE90, prLV}, // Lo HANGUL SYLLABLE KAE + {0xCE91, 0xCEAB, prLVT}, // Lo [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH + {0xCEAC, 0xCEAC, prLV}, // Lo HANGUL SYLLABLE KYA + {0xCEAD, 0xCEC7, prLVT}, // Lo [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH + {0xCEC8, 0xCEC8, prLV}, // Lo HANGUL SYLLABLE KYAE + {0xCEC9, 0xCEE3, prLVT}, // Lo [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH + {0xCEE4, 0xCEE4, prLV}, // Lo HANGUL SYLLABLE KEO + {0xCEE5, 0xCEFF, prLVT}, // Lo [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH + {0xCF00, 0xCF00, prLV}, // Lo HANGUL SYLLABLE KE + {0xCF01, 0xCF1B, prLVT}, // Lo [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH + {0xCF1C, 0xCF1C, prLV}, // Lo HANGUL SYLLABLE KYEO + {0xCF1D, 0xCF37, prLVT}, // Lo [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH + {0xCF38, 0xCF38, prLV}, // Lo HANGUL SYLLABLE KYE + {0xCF39, 0xCF53, prLVT}, // Lo [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH + {0xCF54, 0xCF54, prLV}, // Lo HANGUL SYLLABLE KO + {0xCF55, 0xCF6F, prLVT}, // Lo [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH + {0xCF70, 0xCF70, prLV}, // Lo HANGUL SYLLABLE KWA + {0xCF71, 0xCF8B, prLVT}, // Lo [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH + {0xCF8C, 0xCF8C, prLV}, // Lo HANGUL SYLLABLE KWAE + {0xCF8D, 0xCFA7, prLVT}, // Lo [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH + {0xCFA8, 0xCFA8, prLV}, // Lo HANGUL SYLLABLE KOE + {0xCFA9, 0xCFC3, prLVT}, // Lo [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH + {0xCFC4, 0xCFC4, prLV}, // Lo HANGUL SYLLABLE KYO + {0xCFC5, 0xCFDF, prLVT}, // Lo [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH + {0xCFE0, 0xCFE0, prLV}, // Lo HANGUL SYLLABLE KU + {0xCFE1, 0xCFFB, prLVT}, // Lo [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH + {0xCFFC, 0xCFFC, prLV}, // Lo HANGUL SYLLABLE KWEO + {0xCFFD, 0xD017, prLVT}, // Lo [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH + {0xD018, 0xD018, prLV}, // Lo HANGUL SYLLABLE KWE + {0xD019, 0xD033, prLVT}, // Lo [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH + {0xD034, 0xD034, prLV}, // Lo HANGUL SYLLABLE KWI + {0xD035, 0xD04F, prLVT}, // Lo [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH + {0xD050, 0xD050, prLV}, // Lo HANGUL SYLLABLE KYU + {0xD051, 0xD06B, prLVT}, // Lo [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH + {0xD06C, 0xD06C, prLV}, // Lo HANGUL SYLLABLE KEU + {0xD06D, 0xD087, prLVT}, // Lo [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH + {0xD088, 0xD088, prLV}, // Lo HANGUL SYLLABLE KYI + {0xD089, 0xD0A3, prLVT}, // Lo [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH + {0xD0A4, 0xD0A4, prLV}, // Lo HANGUL SYLLABLE KI + {0xD0A5, 0xD0BF, prLVT}, // Lo [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH + {0xD0C0, 0xD0C0, prLV}, // Lo HANGUL SYLLABLE TA + {0xD0C1, 0xD0DB, prLVT}, // Lo [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH + {0xD0DC, 0xD0DC, prLV}, // Lo HANGUL SYLLABLE TAE + {0xD0DD, 0xD0F7, prLVT}, // Lo [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH + {0xD0F8, 0xD0F8, prLV}, // Lo HANGUL SYLLABLE TYA + {0xD0F9, 0xD113, prLVT}, // Lo [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH + {0xD114, 0xD114, prLV}, // Lo HANGUL SYLLABLE TYAE + {0xD115, 0xD12F, prLVT}, // Lo [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH + {0xD130, 0xD130, prLV}, // Lo HANGUL SYLLABLE TEO + {0xD131, 0xD14B, prLVT}, // Lo [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH + {0xD14C, 0xD14C, prLV}, // Lo HANGUL SYLLABLE TE + {0xD14D, 0xD167, prLVT}, // Lo [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH + {0xD168, 0xD168, prLV}, // Lo HANGUL SYLLABLE TYEO + {0xD169, 0xD183, prLVT}, // Lo [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH + {0xD184, 0xD184, prLV}, // Lo HANGUL SYLLABLE TYE + {0xD185, 0xD19F, prLVT}, // Lo [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH + {0xD1A0, 0xD1A0, prLV}, // Lo HANGUL SYLLABLE TO + {0xD1A1, 0xD1BB, prLVT}, // Lo [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH + {0xD1BC, 0xD1BC, prLV}, // Lo HANGUL SYLLABLE TWA + {0xD1BD, 0xD1D7, prLVT}, // Lo [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH + {0xD1D8, 0xD1D8, prLV}, // Lo HANGUL SYLLABLE TWAE + {0xD1D9, 0xD1F3, prLVT}, // Lo [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH + {0xD1F4, 0xD1F4, prLV}, // Lo HANGUL SYLLABLE TOE + {0xD1F5, 0xD20F, prLVT}, // Lo [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH + {0xD210, 0xD210, prLV}, // Lo HANGUL SYLLABLE TYO + {0xD211, 0xD22B, prLVT}, // Lo [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH + {0xD22C, 0xD22C, prLV}, // Lo HANGUL SYLLABLE TU + {0xD22D, 0xD247, prLVT}, // Lo [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH + {0xD248, 0xD248, prLV}, // Lo HANGUL SYLLABLE TWEO + {0xD249, 0xD263, prLVT}, // Lo [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH + {0xD264, 0xD264, prLV}, // Lo HANGUL SYLLABLE TWE + {0xD265, 0xD27F, prLVT}, // Lo [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH + {0xD280, 0xD280, prLV}, // Lo HANGUL SYLLABLE TWI + {0xD281, 0xD29B, prLVT}, // Lo [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH + {0xD29C, 0xD29C, prLV}, // Lo HANGUL SYLLABLE TYU + {0xD29D, 0xD2B7, prLVT}, // Lo [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH + {0xD2B8, 0xD2B8, prLV}, // Lo HANGUL SYLLABLE TEU + {0xD2B9, 0xD2D3, prLVT}, // Lo [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH + {0xD2D4, 0xD2D4, prLV}, // Lo HANGUL SYLLABLE TYI + {0xD2D5, 0xD2EF, prLVT}, // Lo [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH + {0xD2F0, 0xD2F0, prLV}, // Lo HANGUL SYLLABLE TI + {0xD2F1, 0xD30B, prLVT}, // Lo [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH + {0xD30C, 0xD30C, prLV}, // Lo HANGUL SYLLABLE PA + {0xD30D, 0xD327, prLVT}, // Lo [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH + {0xD328, 0xD328, prLV}, // Lo HANGUL SYLLABLE PAE + {0xD329, 0xD343, prLVT}, // Lo [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH + {0xD344, 0xD344, prLV}, // Lo HANGUL SYLLABLE PYA + {0xD345, 0xD35F, prLVT}, // Lo [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH + {0xD360, 0xD360, prLV}, // Lo HANGUL SYLLABLE PYAE + {0xD361, 0xD37B, prLVT}, // Lo [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH + {0xD37C, 0xD37C, prLV}, // Lo HANGUL SYLLABLE PEO + {0xD37D, 0xD397, prLVT}, // Lo [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH + {0xD398, 0xD398, prLV}, // Lo HANGUL SYLLABLE PE + {0xD399, 0xD3B3, prLVT}, // Lo [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH + {0xD3B4, 0xD3B4, prLV}, // Lo HANGUL SYLLABLE PYEO + {0xD3B5, 0xD3CF, prLVT}, // Lo [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH + {0xD3D0, 0xD3D0, prLV}, // Lo HANGUL SYLLABLE PYE + {0xD3D1, 0xD3EB, prLVT}, // Lo [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH + {0xD3EC, 0xD3EC, prLV}, // Lo HANGUL SYLLABLE PO + {0xD3ED, 0xD407, prLVT}, // Lo [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH + {0xD408, 0xD408, prLV}, // Lo HANGUL SYLLABLE PWA + {0xD409, 0xD423, prLVT}, // Lo [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH + {0xD424, 0xD424, prLV}, // Lo HANGUL SYLLABLE PWAE + {0xD425, 0xD43F, prLVT}, // Lo [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH + {0xD440, 0xD440, prLV}, // Lo HANGUL SYLLABLE POE + {0xD441, 0xD45B, prLVT}, // Lo [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH + {0xD45C, 0xD45C, prLV}, // Lo HANGUL SYLLABLE PYO + {0xD45D, 0xD477, prLVT}, // Lo [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH + {0xD478, 0xD478, prLV}, // Lo HANGUL SYLLABLE PU + {0xD479, 0xD493, prLVT}, // Lo [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH + {0xD494, 0xD494, prLV}, // Lo HANGUL SYLLABLE PWEO + {0xD495, 0xD4AF, prLVT}, // Lo [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH + {0xD4B0, 0xD4B0, prLV}, // Lo HANGUL SYLLABLE PWE + {0xD4B1, 0xD4CB, prLVT}, // Lo [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH + {0xD4CC, 0xD4CC, prLV}, // Lo HANGUL SYLLABLE PWI + {0xD4CD, 0xD4E7, prLVT}, // Lo [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH + {0xD4E8, 0xD4E8, prLV}, // Lo HANGUL SYLLABLE PYU + {0xD4E9, 0xD503, prLVT}, // Lo [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH + {0xD504, 0xD504, prLV}, // Lo HANGUL SYLLABLE PEU + {0xD505, 0xD51F, prLVT}, // Lo [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH + {0xD520, 0xD520, prLV}, // Lo HANGUL SYLLABLE PYI + {0xD521, 0xD53B, prLVT}, // Lo [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH + {0xD53C, 0xD53C, prLV}, // Lo HANGUL SYLLABLE PI + {0xD53D, 0xD557, prLVT}, // Lo [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH + {0xD558, 0xD558, prLV}, // Lo HANGUL SYLLABLE HA + {0xD559, 0xD573, prLVT}, // Lo [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH + {0xD574, 0xD574, prLV}, // Lo HANGUL SYLLABLE HAE + {0xD575, 0xD58F, prLVT}, // Lo [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH + {0xD590, 0xD590, prLV}, // Lo HANGUL SYLLABLE HYA + {0xD591, 0xD5AB, prLVT}, // Lo [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH + {0xD5AC, 0xD5AC, prLV}, // Lo HANGUL SYLLABLE HYAE + {0xD5AD, 0xD5C7, prLVT}, // Lo [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH + {0xD5C8, 0xD5C8, prLV}, // Lo HANGUL SYLLABLE HEO + {0xD5C9, 0xD5E3, prLVT}, // Lo [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH + {0xD5E4, 0xD5E4, prLV}, // Lo HANGUL SYLLABLE HE + {0xD5E5, 0xD5FF, prLVT}, // Lo [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH + {0xD600, 0xD600, prLV}, // Lo HANGUL SYLLABLE HYEO + {0xD601, 0xD61B, prLVT}, // Lo [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH + {0xD61C, 0xD61C, prLV}, // Lo HANGUL SYLLABLE HYE + {0xD61D, 0xD637, prLVT}, // Lo [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH + {0xD638, 0xD638, prLV}, // Lo HANGUL SYLLABLE HO + {0xD639, 0xD653, prLVT}, // Lo [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH + {0xD654, 0xD654, prLV}, // Lo HANGUL SYLLABLE HWA + {0xD655, 0xD66F, prLVT}, // Lo [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH + {0xD670, 0xD670, prLV}, // Lo HANGUL SYLLABLE HWAE + {0xD671, 0xD68B, prLVT}, // Lo [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH + {0xD68C, 0xD68C, prLV}, // Lo HANGUL SYLLABLE HOE + {0xD68D, 0xD6A7, prLVT}, // Lo [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH + {0xD6A8, 0xD6A8, prLV}, // Lo HANGUL SYLLABLE HYO + {0xD6A9, 0xD6C3, prLVT}, // Lo [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH + {0xD6C4, 0xD6C4, prLV}, // Lo HANGUL SYLLABLE HU + {0xD6C5, 0xD6DF, prLVT}, // Lo [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH + {0xD6E0, 0xD6E0, prLV}, // Lo HANGUL SYLLABLE HWEO + {0xD6E1, 0xD6FB, prLVT}, // Lo [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH + {0xD6FC, 0xD6FC, prLV}, // Lo HANGUL SYLLABLE HWE + {0xD6FD, 0xD717, prLVT}, // Lo [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH + {0xD718, 0xD718, prLV}, // Lo HANGUL SYLLABLE HWI + {0xD719, 0xD733, prLVT}, // Lo [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH + {0xD734, 0xD734, prLV}, // Lo HANGUL SYLLABLE HYU + {0xD735, 0xD74F, prLVT}, // Lo [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH + {0xD750, 0xD750, prLV}, // Lo HANGUL SYLLABLE HEU + {0xD751, 0xD76B, prLVT}, // Lo [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH + {0xD76C, 0xD76C, prLV}, // Lo HANGUL SYLLABLE HYI + {0xD76D, 0xD787, prLVT}, // Lo [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH + {0xD788, 0xD788, prLV}, // Lo HANGUL SYLLABLE HI + {0xD789, 0xD7A3, prLVT}, // Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prV}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prT}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFEFF, 0xFEFF, prControl}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFF0, 0xFFF8, prControl}, // Cn [9] .. + {0xFFF9, 0xFFFB, prControl}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x11000, 0x11000, prSpacingMark}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prSpacingMark}, // Mc BRAHMI SIGN VISARGA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prSpacingMark}, // Mc KAITHI SIGN VISARGA + {0x110B0, 0x110B2, prSpacingMark}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prSpacingMark}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prPrepend}, // Cf KAITHI NUMBER SIGN + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prPrepend}, // Cf KAITHI NUMBER SIGN ABOVE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prSpacingMark}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11145, 0x11146, prSpacingMark}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prSpacingMark}, // Mc SHARADA SIGN VISARGA + {0x111B3, 0x111B5, prSpacingMark}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prSpacingMark}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C2, 0x111C3, prPrepend}, // Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CE, 0x111CE, prSpacingMark}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x1122C, 0x1122E, prSpacingMark}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prSpacingMark}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prSpacingMark}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prSpacingMark}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prSpacingMark}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133E, 0x1133E, prExtend}, // Mc GRANTHA VOWEL SIGN AA + {0x1133F, 0x1133F, prSpacingMark}, // Mc GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prSpacingMark}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prSpacingMark}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x11362, 0x11363, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11435, 0x11437, prSpacingMark}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prSpacingMark}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prSpacingMark}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x114B0, 0x114B0, prExtend}, // Mc TIRHUTA VOWEL SIGN AA + {0x114B1, 0x114B2, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BC, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O + {0x114BD, 0x114BD, prExtend}, // Mc TIRHUTA VOWEL SIGN SHORT O + {0x114BE, 0x114BE, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prSpacingMark}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x115AF, 0x115AF, prExtend}, // Mc SIDDHAM VOWEL SIGN AA + {0x115B0, 0x115B1, prSpacingMark}, // Mc [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prSpacingMark}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prSpacingMark}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11630, 0x11632, prSpacingMark}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prSpacingMark}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prSpacingMark}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prSpacingMark}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prSpacingMark}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prSpacingMark}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prSpacingMark}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x1182C, 0x1182E, prSpacingMark}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prSpacingMark}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x11930, 0x11930, prExtend}, // Mc DIVES AKURU VOWEL SIGN AA + {0x11931, 0x11935, prSpacingMark}, // Mc [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prSpacingMark}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prSpacingMark}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prPrepend}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prSpacingMark}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prPrepend}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prSpacingMark}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x119D1, 0x119D3, prSpacingMark}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prSpacingMark}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E4, 0x119E4, prSpacingMark}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prSpacingMark}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prPrepend}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prSpacingMark}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A84, 0x11A89, prPrepend}, // Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prSpacingMark}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11C2F, 0x11C2F, prSpacingMark}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prSpacingMark}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prSpacingMark}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prSpacingMark}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prSpacingMark}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prPrepend}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D8A, 0x11D8E, prSpacingMark}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prSpacingMark}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prSpacingMark}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prSpacingMark}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prPrepend}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prSpacingMark}, // Mc KAWI SIGN VISARGA + {0x11F34, 0x11F35, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prSpacingMark}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x13430, 0x1343F, prControl}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F51, 0x16F87, prSpacingMark}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prSpacingMark}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BCA0, 0x1BCA3, prControl}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D165, prExtend}, // Mc MUSICAL SYMBOL COMBINING STEM + {0x1D166, 0x1D166, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D16D, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT + {0x1D16E, 0x1D172, prExtend}, // Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prControl}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1F000, 0x1F003, prExtendedPictographic}, // E0.0 [4] (๐Ÿ€€..๐Ÿ€ƒ) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prExtendedPictographic}, // E0.6 [1] (๐Ÿ€„) mahjong red dragon + {0x1F005, 0x1F0CE, prExtendedPictographic}, // E0.0 [202] (๐Ÿ€…..๐ŸƒŽ) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prExtendedPictographic}, // E0.6 [1] (๐Ÿƒ) joker + {0x1F0D0, 0x1F0FF, prExtendedPictographic}, // E0.0 [48] (๐Ÿƒ..๐Ÿƒฟ) .. + {0x1F10D, 0x1F10F, prExtendedPictographic}, // E0.0 [3] (๐Ÿ„..๐Ÿ„) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F12F, 0x1F12F, prExtendedPictographic}, // E0.0 [1] (๐Ÿ„ฏ) COPYLEFT SYMBOL + {0x1F16C, 0x1F16F, prExtendedPictographic}, // E0.0 [4] (๐Ÿ…ฌ..๐Ÿ…ฏ) RAISED MR SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F171, prExtendedPictographic}, // E0.6 [2] (๐Ÿ…ฐ๏ธ..๐Ÿ…ฑ๏ธ) A button (blood type)..B button (blood type) + {0x1F17E, 0x1F17F, prExtendedPictographic}, // E0.6 [2] (๐Ÿ…พ๏ธ..๐Ÿ…ฟ๏ธ) O button (blood type)..P button + {0x1F18E, 0x1F18E, prExtendedPictographic}, // E0.6 [1] (๐Ÿ†Ž) AB button (blood type) + {0x1F191, 0x1F19A, prExtendedPictographic}, // E0.6 [10] (๐Ÿ†‘..๐Ÿ†š) CL button..VS button + {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // E0.0 [57] (๐Ÿ†ญ..๐Ÿ‡ฅ) MASK WORK SYMBOL.. + {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F201, 0x1F202, prExtendedPictographic}, // E0.6 [2] (๐Ÿˆ..๐Ÿˆ‚๏ธ) Japanese โ€œhereโ€ button..Japanese โ€œservice chargeโ€ button + {0x1F203, 0x1F20F, prExtendedPictographic}, // E0.0 [13] (๐Ÿˆƒ..๐Ÿˆ) .. + {0x1F21A, 0x1F21A, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆš) Japanese โ€œfree of chargeโ€ button + {0x1F22F, 0x1F22F, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆฏ) Japanese โ€œreservedโ€ button + {0x1F232, 0x1F23A, prExtendedPictographic}, // E0.6 [9] (๐Ÿˆฒ..๐Ÿˆบ) Japanese โ€œprohibitedโ€ button..Japanese โ€œopen for businessโ€ button + {0x1F23C, 0x1F23F, prExtendedPictographic}, // E0.0 [4] (๐Ÿˆผ..๐Ÿˆฟ) .. + {0x1F249, 0x1F24F, prExtendedPictographic}, // E0.0 [7] (๐Ÿ‰‰..๐Ÿ‰) .. + {0x1F250, 0x1F251, prExtendedPictographic}, // E0.6 [2] (๐Ÿ‰..๐Ÿ‰‘) Japanese โ€œbargainโ€ button..Japanese โ€œacceptableโ€ button + {0x1F252, 0x1F2FF, prExtendedPictographic}, // E0.0 [174] (๐Ÿ‰’..๐Ÿ‹ฟ) .. + {0x1F300, 0x1F30C, prExtendedPictographic}, // E0.6 [13] (๐ŸŒ€..๐ŸŒŒ) cyclone..milky way + {0x1F30D, 0x1F30E, prExtendedPictographic}, // E0.7 [2] (๐ŸŒ..๐ŸŒŽ) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ) globe showing Asia-Australia + {0x1F310, 0x1F310, prExtendedPictographic}, // E1.0 [1] (๐ŸŒ) globe with meridians + {0x1F311, 0x1F311, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ‘) new moon + {0x1F312, 0x1F312, prExtendedPictographic}, // E1.0 [1] (๐ŸŒ’) waxing crescent moon + {0x1F313, 0x1F315, prExtendedPictographic}, // E0.6 [3] (๐ŸŒ“..๐ŸŒ•) first quarter moon..full moon + {0x1F316, 0x1F318, prExtendedPictographic}, // E1.0 [3] (๐ŸŒ–..๐ŸŒ˜) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ™) crescent moon + {0x1F31A, 0x1F31A, prExtendedPictographic}, // E1.0 [1] (๐ŸŒš) new moon face + {0x1F31B, 0x1F31B, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ›) first quarter moon face + {0x1F31C, 0x1F31C, prExtendedPictographic}, // E0.7 [1] (๐ŸŒœ) last quarter moon face + {0x1F31D, 0x1F31E, prExtendedPictographic}, // E1.0 [2] (๐ŸŒ..๐ŸŒž) full moon face..sun with face + {0x1F31F, 0x1F320, prExtendedPictographic}, // E0.6 [2] (๐ŸŒŸ..๐ŸŒ ) glowing star..shooting star + {0x1F321, 0x1F321, prExtendedPictographic}, // E0.7 [1] (๐ŸŒก๏ธ) thermometer + {0x1F322, 0x1F323, prExtendedPictographic}, // E0.0 [2] (๐ŸŒข..๐ŸŒฃ) BLACK DROPLET..WHITE SUN + {0x1F324, 0x1F32C, prExtendedPictographic}, // E0.7 [9] (๐ŸŒค๏ธ..๐ŸŒฌ๏ธ) sun behind small cloud..wind face + {0x1F32D, 0x1F32F, prExtendedPictographic}, // E1.0 [3] (๐ŸŒญ..๐ŸŒฏ) hot dog..burrito + {0x1F330, 0x1F331, prExtendedPictographic}, // E0.6 [2] (๐ŸŒฐ..๐ŸŒฑ) chestnut..seedling + {0x1F332, 0x1F333, prExtendedPictographic}, // E1.0 [2] (๐ŸŒฒ..๐ŸŒณ) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prExtendedPictographic}, // E0.6 [2] (๐ŸŒด..๐ŸŒต) palm tree..cactus + {0x1F336, 0x1F336, prExtendedPictographic}, // E0.7 [1] (๐ŸŒถ๏ธ) hot pepper + {0x1F337, 0x1F34A, prExtendedPictographic}, // E0.6 [20] (๐ŸŒท..๐ŸŠ) tulip..tangerine + {0x1F34B, 0x1F34B, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‹) lemon + {0x1F34C, 0x1F34F, prExtendedPictographic}, // E0.6 [4] (๐ŸŒ..๐Ÿ) banana..green apple + {0x1F350, 0x1F350, prExtendedPictographic}, // E1.0 [1] (๐Ÿ) pear + {0x1F351, 0x1F37B, prExtendedPictographic}, // E0.6 [43] (๐Ÿ‘..๐Ÿป) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prExtendedPictographic}, // E1.0 [1] (๐Ÿผ) baby bottle + {0x1F37D, 0x1F37D, prExtendedPictographic}, // E0.7 [1] (๐Ÿฝ๏ธ) fork and knife with plate + {0x1F37E, 0x1F37F, prExtendedPictographic}, // E1.0 [2] (๐Ÿพ..๐Ÿฟ) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prExtendedPictographic}, // E0.6 [20] (๐ŸŽ€..๐ŸŽ“) ribbon..graduation cap + {0x1F394, 0x1F395, prExtendedPictographic}, // E0.0 [2] (๐ŸŽ”..๐ŸŽ•) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS + {0x1F396, 0x1F397, prExtendedPictographic}, // E0.7 [2] (๐ŸŽ–๏ธ..๐ŸŽ—๏ธ) military medal..reminder ribbon + {0x1F398, 0x1F398, prExtendedPictographic}, // E0.0 [1] (๐ŸŽ˜) MUSICAL KEYBOARD WITH JACKS + {0x1F399, 0x1F39B, prExtendedPictographic}, // E0.7 [3] (๐ŸŽ™๏ธ..๐ŸŽ›๏ธ) studio microphone..control knobs + {0x1F39C, 0x1F39D, prExtendedPictographic}, // E0.0 [2] (๐ŸŽœ..๐ŸŽ) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F39F, prExtendedPictographic}, // E0.7 [2] (๐ŸŽž๏ธ..๐ŸŽŸ๏ธ) film frames..admission tickets + {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // E0.6 [37] (๐ŸŽ ..๐Ÿ„) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // E1.0 [1] (๐Ÿ…) sports medal + {0x1F3C6, 0x1F3C6, prExtendedPictographic}, // E0.6 [1] (๐Ÿ†) trophy + {0x1F3C7, 0x1F3C7, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‡) horse racing + {0x1F3C8, 0x1F3C8, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆ) american football + {0x1F3C9, 0x1F3C9, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‰) rugby football + {0x1F3CA, 0x1F3CA, prExtendedPictographic}, // E0.6 [1] (๐ŸŠ) person swimming + {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // E0.7 [4] (๐Ÿ‹๏ธ..๐ŸŽ๏ธ) person lifting weights..racing car + {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // E1.0 [5] (๐Ÿ..๐Ÿ“) cricket game..ping pong + {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // E0.7 [12] (๐Ÿ”๏ธ..๐ŸŸ๏ธ) snow-capped mountain..stadium + {0x1F3E0, 0x1F3E3, prExtendedPictographic}, // E0.6 [4] (๐Ÿ ..๐Ÿฃ) house..Japanese post office + {0x1F3E4, 0x1F3E4, prExtendedPictographic}, // E1.0 [1] (๐Ÿค) post office + {0x1F3E5, 0x1F3F0, prExtendedPictographic}, // E0.6 [12] (๐Ÿฅ..๐Ÿฐ) hospital..castle + {0x1F3F1, 0x1F3F2, prExtendedPictographic}, // E0.0 [2] (๐Ÿฑ..๐Ÿฒ) WHITE PENNANT..BLACK PENNANT + {0x1F3F3, 0x1F3F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿณ๏ธ) white flag + {0x1F3F4, 0x1F3F4, prExtendedPictographic}, // E1.0 [1] (๐Ÿด) black flag + {0x1F3F5, 0x1F3F5, prExtendedPictographic}, // E0.7 [1] (๐Ÿต๏ธ) rosette + {0x1F3F6, 0x1F3F6, prExtendedPictographic}, // E0.0 [1] (๐Ÿถ) BLACK ROSETTE + {0x1F3F7, 0x1F3F7, prExtendedPictographic}, // E0.7 [1] (๐Ÿท๏ธ) label + {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // E1.0 [3] (๐Ÿธ..๐Ÿบ) badminton..amphora + {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F407, prExtendedPictographic}, // E1.0 [8] (๐Ÿ€..๐Ÿ‡) rat..rabbit + {0x1F408, 0x1F408, prExtendedPictographic}, // E0.7 [1] (๐Ÿˆ) cat + {0x1F409, 0x1F40B, prExtendedPictographic}, // E1.0 [3] (๐Ÿ‰..๐Ÿ‹) dragon..whale + {0x1F40C, 0x1F40E, prExtendedPictographic}, // E0.6 [3] (๐ŸŒ..๐ŸŽ) snail..horse + {0x1F40F, 0x1F410, prExtendedPictographic}, // E1.0 [2] (๐Ÿ..๐Ÿ) ram..goat + {0x1F411, 0x1F412, prExtendedPictographic}, // E0.6 [2] (๐Ÿ‘..๐Ÿ’) ewe..monkey + {0x1F413, 0x1F413, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“) rooster + {0x1F414, 0x1F414, prExtendedPictographic}, // E0.6 [1] (๐Ÿ”) chicken + {0x1F415, 0x1F415, prExtendedPictographic}, // E0.7 [1] (๐Ÿ•) dog + {0x1F416, 0x1F416, prExtendedPictographic}, // E1.0 [1] (๐Ÿ–) pig + {0x1F417, 0x1F429, prExtendedPictographic}, // E0.6 [19] (๐Ÿ—..๐Ÿฉ) boar..poodle + {0x1F42A, 0x1F42A, prExtendedPictographic}, // E1.0 [1] (๐Ÿช) camel + {0x1F42B, 0x1F43E, prExtendedPictographic}, // E0.6 [20] (๐Ÿซ..๐Ÿพ) two-hump camel..paw prints + {0x1F43F, 0x1F43F, prExtendedPictographic}, // E0.7 [1] (๐Ÿฟ๏ธ) chipmunk + {0x1F440, 0x1F440, prExtendedPictographic}, // E0.6 [1] (๐Ÿ‘€) eyes + {0x1F441, 0x1F441, prExtendedPictographic}, // E0.7 [1] (๐Ÿ‘๏ธ) eye + {0x1F442, 0x1F464, prExtendedPictographic}, // E0.6 [35] (๐Ÿ‘‚..๐Ÿ‘ค) ear..bust in silhouette + {0x1F465, 0x1F465, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‘ฅ) busts in silhouette + {0x1F466, 0x1F46B, prExtendedPictographic}, // E0.6 [6] (๐Ÿ‘ฆ..๐Ÿ‘ซ) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prExtendedPictographic}, // E1.0 [2] (๐Ÿ‘ฌ..๐Ÿ‘ญ) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prExtendedPictographic}, // E0.6 [63] (๐Ÿ‘ฎ..๐Ÿ’ฌ) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prExtendedPictographic}, // E1.0 [1] (๐Ÿ’ญ) thought balloon + {0x1F4AE, 0x1F4B5, prExtendedPictographic}, // E0.6 [8] (๐Ÿ’ฎ..๐Ÿ’ต) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prExtendedPictographic}, // E1.0 [2] (๐Ÿ’ถ..๐Ÿ’ท) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prExtendedPictographic}, // E0.6 [52] (๐Ÿ’ธ..๐Ÿ“ซ) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prExtendedPictographic}, // E0.7 [2] (๐Ÿ“ฌ..๐Ÿ“ญ) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prExtendedPictographic}, // E0.6 [1] (๐Ÿ“ฎ) postbox + {0x1F4EF, 0x1F4EF, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ฏ) postal horn + {0x1F4F0, 0x1F4F4, prExtendedPictographic}, // E0.6 [5] (๐Ÿ“ฐ..๐Ÿ“ด) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ต) no mobile phones + {0x1F4F6, 0x1F4F7, prExtendedPictographic}, // E0.6 [2] (๐Ÿ“ถ..๐Ÿ“ท) antenna bars..camera + {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ธ) camera with flash + {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // E0.6 [4] (๐Ÿ“น..๐Ÿ“ผ) video camera..videocassette + {0x1F4FD, 0x1F4FD, prExtendedPictographic}, // E0.7 [1] (๐Ÿ“ฝ๏ธ) film projector + {0x1F4FE, 0x1F4FE, prExtendedPictographic}, // E0.0 [1] (๐Ÿ“พ) PORTABLE STEREO + {0x1F4FF, 0x1F502, prExtendedPictographic}, // E1.0 [4] (๐Ÿ“ฟ..๐Ÿ”‚) prayer beads..repeat single button + {0x1F503, 0x1F503, prExtendedPictographic}, // E0.6 [1] (๐Ÿ”ƒ) clockwise vertical arrows + {0x1F504, 0x1F507, prExtendedPictographic}, // E1.0 [4] (๐Ÿ”„..๐Ÿ”‡) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prExtendedPictographic}, // E0.7 [1] (๐Ÿ”ˆ) speaker low volume + {0x1F509, 0x1F509, prExtendedPictographic}, // E1.0 [1] (๐Ÿ”‰) speaker medium volume + {0x1F50A, 0x1F514, prExtendedPictographic}, // E0.6 [11] (๐Ÿ”Š..๐Ÿ””) speaker high volume..bell + {0x1F515, 0x1F515, prExtendedPictographic}, // E1.0 [1] (๐Ÿ”•) bell with slash + {0x1F516, 0x1F52B, prExtendedPictographic}, // E0.6 [22] (๐Ÿ”–..๐Ÿ”ซ) bookmark..water pistol + {0x1F52C, 0x1F52D, prExtendedPictographic}, // E1.0 [2] (๐Ÿ”ฌ..๐Ÿ”ญ) microscope..telescope + {0x1F52E, 0x1F53D, prExtendedPictographic}, // E0.6 [16] (๐Ÿ”ฎ..๐Ÿ”ฝ) crystal ball..downwards button + {0x1F546, 0x1F548, prExtendedPictographic}, // E0.0 [3] (๐Ÿ•†..๐Ÿ•ˆ) WHITE LATIN CROSS..CELTIC CROSS + {0x1F549, 0x1F54A, prExtendedPictographic}, // E0.7 [2] (๐Ÿ•‰๏ธ..๐Ÿ•Š๏ธ) om..dove + {0x1F54B, 0x1F54E, prExtendedPictographic}, // E1.0 [4] (๐Ÿ•‹..๐Ÿ•Ž) kaaba..menorah + {0x1F54F, 0x1F54F, prExtendedPictographic}, // E0.0 [1] (๐Ÿ•) BOWL OF HYGIEIA + {0x1F550, 0x1F55B, prExtendedPictographic}, // E0.6 [12] (๐Ÿ•..๐Ÿ•›) one oโ€™clock..twelve oโ€™clock + {0x1F55C, 0x1F567, prExtendedPictographic}, // E0.7 [12] (๐Ÿ•œ..๐Ÿ•ง) one-thirty..twelve-thirty + {0x1F568, 0x1F56E, prExtendedPictographic}, // E0.0 [7] (๐Ÿ•จ..๐Ÿ•ฎ) RIGHT SPEAKER..BOOK + {0x1F56F, 0x1F570, prExtendedPictographic}, // E0.7 [2] (๐Ÿ•ฏ๏ธ..๐Ÿ•ฐ๏ธ) candle..mantelpiece clock + {0x1F571, 0x1F572, prExtendedPictographic}, // E0.0 [2] (๐Ÿ•ฑ..๐Ÿ•ฒ) BLACK SKULL AND CROSSBONES..NO PIRACY + {0x1F573, 0x1F579, prExtendedPictographic}, // E0.7 [7] (๐Ÿ•ณ๏ธ..๐Ÿ•น๏ธ) hole..joystick + {0x1F57A, 0x1F57A, prExtendedPictographic}, // E3.0 [1] (๐Ÿ•บ) man dancing + {0x1F57B, 0x1F586, prExtendedPictographic}, // E0.0 [12] (๐Ÿ•ป..๐Ÿ–†) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE + {0x1F587, 0x1F587, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–‡๏ธ) linked paperclips + {0x1F588, 0x1F589, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–ˆ..๐Ÿ–‰) BLACK PUSHPIN..LOWER LEFT PENCIL + {0x1F58A, 0x1F58D, prExtendedPictographic}, // E0.7 [4] (๐Ÿ–Š๏ธ..๐Ÿ–๏ธ) pen..crayon + {0x1F58E, 0x1F58F, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–Ž..๐Ÿ–) LEFT WRITING HAND..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–๏ธ) hand with fingers splayed + {0x1F591, 0x1F594, prExtendedPictographic}, // E0.0 [4] (๐Ÿ–‘..๐Ÿ–”) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prExtendedPictographic}, // E1.0 [2] (๐Ÿ–•..๐Ÿ––) middle finger..vulcan salute + {0x1F597, 0x1F5A3, prExtendedPictographic}, // E0.0 [13] (๐Ÿ–—..๐Ÿ–ฃ) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // E3.0 [1] (๐Ÿ–ค) black heart + {0x1F5A5, 0x1F5A5, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–ฅ๏ธ) desktop computer + {0x1F5A6, 0x1F5A7, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–ฆ..๐Ÿ–ง) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS + {0x1F5A8, 0x1F5A8, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–จ๏ธ) printer + {0x1F5A9, 0x1F5B0, prExtendedPictographic}, // E0.0 [8] (๐Ÿ–ฉ..๐Ÿ–ฐ) POCKET CALCULATOR..TWO BUTTON MOUSE + {0x1F5B1, 0x1F5B2, prExtendedPictographic}, // E0.7 [2] (๐Ÿ–ฑ๏ธ..๐Ÿ–ฒ๏ธ) computer mouse..trackball + {0x1F5B3, 0x1F5BB, prExtendedPictographic}, // E0.0 [9] (๐Ÿ–ณ..๐Ÿ–ป) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE + {0x1F5BC, 0x1F5BC, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–ผ๏ธ) framed picture + {0x1F5BD, 0x1F5C1, prExtendedPictographic}, // E0.0 [5] (๐Ÿ–ฝ..๐Ÿ—) FRAME WITH TILES..OPEN FOLDER + {0x1F5C2, 0x1F5C4, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—‚๏ธ..๐Ÿ—„๏ธ) card index dividers..file cabinet + {0x1F5C5, 0x1F5D0, prExtendedPictographic}, // E0.0 [12] (๐Ÿ—…..๐Ÿ—) EMPTY NOTE..PAGES + {0x1F5D1, 0x1F5D3, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—‘๏ธ..๐Ÿ—“๏ธ) wastebasket..spiral calendar + {0x1F5D4, 0x1F5DB, prExtendedPictographic}, // E0.0 [8] (๐Ÿ—”..๐Ÿ—›) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5DE, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—œ๏ธ..๐Ÿ—ž๏ธ) clamp..rolled-up newspaper + {0x1F5DF, 0x1F5E0, prExtendedPictographic}, // E0.0 [2] (๐Ÿ—Ÿ..๐Ÿ— ) PAGE WITH CIRCLED TEXT..STOCK CHART + {0x1F5E1, 0x1F5E1, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ก๏ธ) dagger + {0x1F5E2, 0x1F5E2, prExtendedPictographic}, // E0.0 [1] (๐Ÿ—ข) LIPS + {0x1F5E3, 0x1F5E3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ฃ๏ธ) speaking head + {0x1F5E4, 0x1F5E7, prExtendedPictographic}, // E0.0 [4] (๐Ÿ—ค..๐Ÿ—ง) THREE RAYS ABOVE..THREE RAYS RIGHT + {0x1F5E8, 0x1F5E8, prExtendedPictographic}, // E2.0 [1] (๐Ÿ—จ๏ธ) left speech bubble + {0x1F5E9, 0x1F5EE, prExtendedPictographic}, // E0.0 [6] (๐Ÿ—ฉ..๐Ÿ—ฎ) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE + {0x1F5EF, 0x1F5EF, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ฏ๏ธ) right anger bubble + {0x1F5F0, 0x1F5F2, prExtendedPictographic}, // E0.0 [3] (๐Ÿ—ฐ..๐Ÿ—ฒ) MOOD BUBBLE..LIGHTNING MOOD + {0x1F5F3, 0x1F5F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ณ๏ธ) ballot box with ballot + {0x1F5F4, 0x1F5F9, prExtendedPictographic}, // E0.0 [6] (๐Ÿ—ด..๐Ÿ—น) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FA, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—บ๏ธ) world map + {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // E0.6 [5] (๐Ÿ—ป..๐Ÿ—ฟ) mount fuji..moai + {0x1F600, 0x1F600, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜€) grinning face + {0x1F601, 0x1F606, prExtendedPictographic}, // E0.6 [6] (๐Ÿ˜..๐Ÿ˜†) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜‡..๐Ÿ˜ˆ) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prExtendedPictographic}, // E0.6 [5] (๐Ÿ˜‰..๐Ÿ˜) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜Ž) smiling face with sunglasses + {0x1F60F, 0x1F60F, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜) smirking face + {0x1F610, 0x1F610, prExtendedPictographic}, // E0.7 [1] (๐Ÿ˜) neutral face + {0x1F611, 0x1F611, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜‘) expressionless face + {0x1F612, 0x1F614, prExtendedPictographic}, // E0.6 [3] (๐Ÿ˜’..๐Ÿ˜”) unamused face..pensive face + {0x1F615, 0x1F615, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜•) confused face + {0x1F616, 0x1F616, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜–) confounded face + {0x1F617, 0x1F617, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜—) kissing face + {0x1F618, 0x1F618, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜˜) face blowing a kiss + {0x1F619, 0x1F619, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜™) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜š) kissing face with closed eyes + {0x1F61B, 0x1F61B, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜›) face with tongue + {0x1F61C, 0x1F61E, prExtendedPictographic}, // E0.6 [3] (๐Ÿ˜œ..๐Ÿ˜ž) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜Ÿ) worried face + {0x1F620, 0x1F625, prExtendedPictographic}, // E0.6 [6] (๐Ÿ˜ ..๐Ÿ˜ฅ) angry face..sad but relieved face + {0x1F626, 0x1F627, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜ฆ..๐Ÿ˜ง) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prExtendedPictographic}, // E0.6 [4] (๐Ÿ˜จ..๐Ÿ˜ซ) fearful face..tired face + {0x1F62C, 0x1F62C, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ฌ) grimacing face + {0x1F62D, 0x1F62D, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜ญ) loudly crying face + {0x1F62E, 0x1F62F, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜ฎ..๐Ÿ˜ฏ) face with open mouth..hushed face + {0x1F630, 0x1F633, prExtendedPictographic}, // E0.6 [4] (๐Ÿ˜ฐ..๐Ÿ˜ณ) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ด) sleeping face + {0x1F635, 0x1F635, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜ต) face with crossed-out eyes + {0x1F636, 0x1F636, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ถ) face without mouth + {0x1F637, 0x1F640, prExtendedPictographic}, // E0.6 [10] (๐Ÿ˜ท..๐Ÿ™€) face with medical mask..weary cat + {0x1F641, 0x1F644, prExtendedPictographic}, // E1.0 [4] (๐Ÿ™..๐Ÿ™„) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prExtendedPictographic}, // E0.6 [11] (๐Ÿ™…..๐Ÿ™) person gesturing NO..folded hands + {0x1F680, 0x1F680, prExtendedPictographic}, // E0.6 [1] (๐Ÿš€) rocket + {0x1F681, 0x1F682, prExtendedPictographic}, // E1.0 [2] (๐Ÿš..๐Ÿš‚) helicopter..locomotive + {0x1F683, 0x1F685, prExtendedPictographic}, // E0.6 [3] (๐Ÿšƒ..๐Ÿš…) railway car..bullet train + {0x1F686, 0x1F686, prExtendedPictographic}, // E1.0 [1] (๐Ÿš†) train + {0x1F687, 0x1F687, prExtendedPictographic}, // E0.6 [1] (๐Ÿš‡) metro + {0x1F688, 0x1F688, prExtendedPictographic}, // E1.0 [1] (๐Ÿšˆ) light rail + {0x1F689, 0x1F689, prExtendedPictographic}, // E0.6 [1] (๐Ÿš‰) station + {0x1F68A, 0x1F68B, prExtendedPictographic}, // E1.0 [2] (๐ŸšŠ..๐Ÿš‹) tram..tram car + {0x1F68C, 0x1F68C, prExtendedPictographic}, // E0.6 [1] (๐ŸšŒ) bus + {0x1F68D, 0x1F68D, prExtendedPictographic}, // E0.7 [1] (๐Ÿš) oncoming bus + {0x1F68E, 0x1F68E, prExtendedPictographic}, // E1.0 [1] (๐ŸšŽ) trolleybus + {0x1F68F, 0x1F68F, prExtendedPictographic}, // E0.6 [1] (๐Ÿš) bus stop + {0x1F690, 0x1F690, prExtendedPictographic}, // E1.0 [1] (๐Ÿš) minibus + {0x1F691, 0x1F693, prExtendedPictographic}, // E0.6 [3] (๐Ÿš‘..๐Ÿš“) ambulance..police car + {0x1F694, 0x1F694, prExtendedPictographic}, // E0.7 [1] (๐Ÿš”) oncoming police car + {0x1F695, 0x1F695, prExtendedPictographic}, // E0.6 [1] (๐Ÿš•) taxi + {0x1F696, 0x1F696, prExtendedPictographic}, // E1.0 [1] (๐Ÿš–) oncoming taxi + {0x1F697, 0x1F697, prExtendedPictographic}, // E0.6 [1] (๐Ÿš—) automobile + {0x1F698, 0x1F698, prExtendedPictographic}, // E0.7 [1] (๐Ÿš˜) oncoming automobile + {0x1F699, 0x1F69A, prExtendedPictographic}, // E0.6 [2] (๐Ÿš™..๐Ÿšš) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prExtendedPictographic}, // E1.0 [7] (๐Ÿš›..๐Ÿšก) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prExtendedPictographic}, // E0.6 [1] (๐Ÿšข) ship + {0x1F6A3, 0x1F6A3, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฃ) person rowing boat + {0x1F6A4, 0x1F6A5, prExtendedPictographic}, // E0.6 [2] (๐Ÿšค..๐Ÿšฅ) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฆ) vertical traffic light + {0x1F6A7, 0x1F6AD, prExtendedPictographic}, // E0.6 [7] (๐Ÿšง..๐Ÿšญ) construction..no smoking + {0x1F6AE, 0x1F6B1, prExtendedPictographic}, // E1.0 [4] (๐Ÿšฎ..๐Ÿšฑ) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prExtendedPictographic}, // E0.6 [1] (๐Ÿšฒ) bicycle + {0x1F6B3, 0x1F6B5, prExtendedPictographic}, // E1.0 [3] (๐Ÿšณ..๐Ÿšต) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prExtendedPictographic}, // E0.6 [1] (๐Ÿšถ) person walking + {0x1F6B7, 0x1F6B8, prExtendedPictographic}, // E1.0 [2] (๐Ÿšท..๐Ÿšธ) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prExtendedPictographic}, // E0.6 [6] (๐Ÿšน..๐Ÿšพ) menโ€™s room..water closet + {0x1F6BF, 0x1F6BF, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฟ) shower + {0x1F6C0, 0x1F6C0, prExtendedPictographic}, // E0.6 [1] (๐Ÿ›€) person taking bath + {0x1F6C1, 0x1F6C5, prExtendedPictographic}, // E1.0 [5] (๐Ÿ›..๐Ÿ›…) bathtub..left luggage + {0x1F6C6, 0x1F6CA, prExtendedPictographic}, // E0.0 [5] (๐Ÿ›†..๐Ÿ›Š) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL + {0x1F6CB, 0x1F6CB, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›‹๏ธ) couch and lamp + {0x1F6CC, 0x1F6CC, prExtendedPictographic}, // E1.0 [1] (๐Ÿ›Œ) person in bed + {0x1F6CD, 0x1F6CF, prExtendedPictographic}, // E0.7 [3] (๐Ÿ›๏ธ..๐Ÿ›๏ธ) shopping bags..bed + {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // E1.0 [1] (๐Ÿ›) place of worship + {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // E3.0 [2] (๐Ÿ›‘..๐Ÿ›’) stop sign..shopping cart + {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // E0.0 [2] (๐Ÿ›“..๐Ÿ›”) STUPA..PAGODA + {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // E12.0 [1] (๐Ÿ›•) hindu temple + {0x1F6D6, 0x1F6D7, prExtendedPictographic}, // E13.0 [2] (๐Ÿ›–..๐Ÿ›—) hut..elevator + {0x1F6D8, 0x1F6DB, prExtendedPictographic}, // E0.0 [4] (๐Ÿ›˜..๐Ÿ››) .. + {0x1F6DC, 0x1F6DC, prExtendedPictographic}, // E15.0 [1] (๐Ÿ›œ) wireless + {0x1F6DD, 0x1F6DF, prExtendedPictographic}, // E14.0 [3] (๐Ÿ›..๐Ÿ›Ÿ) playground slide..ring buoy + {0x1F6E0, 0x1F6E5, prExtendedPictographic}, // E0.7 [6] (๐Ÿ› ๏ธ..๐Ÿ›ฅ๏ธ) hammer and wrench..motor boat + {0x1F6E6, 0x1F6E8, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ฆ..๐Ÿ›จ) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE + {0x1F6E9, 0x1F6E9, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ฉ๏ธ) small airplane + {0x1F6EA, 0x1F6EA, prExtendedPictographic}, // E0.0 [1] (๐Ÿ›ช) NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prExtendedPictographic}, // E1.0 [2] (๐Ÿ›ซ..๐Ÿ›ฌ) airplane departure..airplane arrival + {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ญ..๐Ÿ›ฏ) .. + {0x1F6F0, 0x1F6F0, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ฐ๏ธ) satellite + {0x1F6F1, 0x1F6F2, prExtendedPictographic}, // E0.0 [2] (๐Ÿ›ฑ..๐Ÿ›ฒ) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE + {0x1F6F3, 0x1F6F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ณ๏ธ) passenger ship + {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // E3.0 [3] (๐Ÿ›ด..๐Ÿ›ถ) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // E5.0 [2] (๐Ÿ›ท..๐Ÿ›ธ) sled..flying saucer + {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // E11.0 [1] (๐Ÿ›น) skateboard + {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // E12.0 [1] (๐Ÿ›บ) auto rickshaw + {0x1F6FB, 0x1F6FC, prExtendedPictographic}, // E13.0 [2] (๐Ÿ›ป..๐Ÿ›ผ) pickup truck..roller skate + {0x1F6FD, 0x1F6FF, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ฝ..๐Ÿ›ฟ) .. + {0x1F774, 0x1F77F, prExtendedPictographic}, // E0.0 [12] (๐Ÿด..๐Ÿฟ) LOT OF FORTUNE..ORCUS + {0x1F7D5, 0x1F7DF, prExtendedPictographic}, // E0.0 [11] (๐ŸŸ•..๐ŸŸŸ) CIRCLED TRIANGLE.. + {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // E12.0 [12] (๐ŸŸ ..๐ŸŸซ) orange circle..brown square + {0x1F7EC, 0x1F7EF, prExtendedPictographic}, // E0.0 [4] (๐ŸŸฌ..๐ŸŸฏ) .. + {0x1F7F0, 0x1F7F0, prExtendedPictographic}, // E14.0 [1] (๐ŸŸฐ) heavy equals sign + {0x1F7F1, 0x1F7FF, prExtendedPictographic}, // E0.0 [15] (๐ŸŸฑ..๐ŸŸฟ) .. + {0x1F80C, 0x1F80F, prExtendedPictographic}, // E0.0 [4] (๐Ÿ Œ..๐Ÿ ) .. + {0x1F848, 0x1F84F, prExtendedPictographic}, // E0.0 [8] (๐Ÿกˆ..๐Ÿก) .. + {0x1F85A, 0x1F85F, prExtendedPictographic}, // E0.0 [6] (๐Ÿกš..๐ŸกŸ) .. + {0x1F888, 0x1F88F, prExtendedPictographic}, // E0.0 [8] (๐Ÿขˆ..๐Ÿข) .. + {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // E0.0 [82] (๐Ÿขฎ..๐Ÿฃฟ) .. + {0x1F90C, 0x1F90C, prExtendedPictographic}, // E13.0 [1] (๐ŸคŒ) pinched fingers + {0x1F90D, 0x1F90F, prExtendedPictographic}, // E12.0 [3] (๐Ÿค..๐Ÿค) white heart..pinching hand + {0x1F910, 0x1F918, prExtendedPictographic}, // E1.0 [9] (๐Ÿค..๐Ÿค˜) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prExtendedPictographic}, // E3.0 [6] (๐Ÿค™..๐Ÿคž) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prExtendedPictographic}, // E5.0 [1] (๐ŸคŸ) love-you gesture + {0x1F920, 0x1F927, prExtendedPictographic}, // E3.0 [8] (๐Ÿค ..๐Ÿคง) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prExtendedPictographic}, // E5.0 [8] (๐Ÿคจ..๐Ÿคฏ) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prExtendedPictographic}, // E3.0 [1] (๐Ÿคฐ) pregnant woman + {0x1F931, 0x1F932, prExtendedPictographic}, // E5.0 [2] (๐Ÿคฑ..๐Ÿคฒ) breast-feeding..palms up together + {0x1F933, 0x1F93A, prExtendedPictographic}, // E3.0 [8] (๐Ÿคณ..๐Ÿคบ) selfie..person fencing + {0x1F93C, 0x1F93E, prExtendedPictographic}, // E3.0 [3] (๐Ÿคผ..๐Ÿคพ) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prExtendedPictographic}, // E12.0 [1] (๐Ÿคฟ) diving mask + {0x1F940, 0x1F945, prExtendedPictographic}, // E3.0 [6] (๐Ÿฅ€..๐Ÿฅ…) wilted flower..goal net + {0x1F947, 0x1F94B, prExtendedPictographic}, // E3.0 [5] (๐Ÿฅ‡..๐Ÿฅ‹) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prExtendedPictographic}, // E5.0 [1] (๐ŸฅŒ) curling stone + {0x1F94D, 0x1F94F, prExtendedPictographic}, // E11.0 [3] (๐Ÿฅ..๐Ÿฅ) lacrosse..flying disc + {0x1F950, 0x1F95E, prExtendedPictographic}, // E3.0 [15] (๐Ÿฅ..๐Ÿฅž) croissant..pancakes + {0x1F95F, 0x1F96B, prExtendedPictographic}, // E5.0 [13] (๐ŸฅŸ..๐Ÿฅซ) dumpling..canned food + {0x1F96C, 0x1F970, prExtendedPictographic}, // E11.0 [5] (๐Ÿฅฌ..๐Ÿฅฐ) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prExtendedPictographic}, // E12.0 [1] (๐Ÿฅฑ) yawning face + {0x1F972, 0x1F972, prExtendedPictographic}, // E13.0 [1] (๐Ÿฅฒ) smiling face with tear + {0x1F973, 0x1F976, prExtendedPictographic}, // E11.0 [4] (๐Ÿฅณ..๐Ÿฅถ) partying face..cold face + {0x1F977, 0x1F978, prExtendedPictographic}, // E13.0 [2] (๐Ÿฅท..๐Ÿฅธ) ninja..disguised face + {0x1F979, 0x1F979, prExtendedPictographic}, // E14.0 [1] (๐Ÿฅน) face holding back tears + {0x1F97A, 0x1F97A, prExtendedPictographic}, // E11.0 [1] (๐Ÿฅบ) pleading face + {0x1F97B, 0x1F97B, prExtendedPictographic}, // E12.0 [1] (๐Ÿฅป) sari + {0x1F97C, 0x1F97F, prExtendedPictographic}, // E11.0 [4] (๐Ÿฅผ..๐Ÿฅฟ) lab coat..flat shoe + {0x1F980, 0x1F984, prExtendedPictographic}, // E1.0 [5] (๐Ÿฆ€..๐Ÿฆ„) crab..unicorn + {0x1F985, 0x1F991, prExtendedPictographic}, // E3.0 [13] (๐Ÿฆ…..๐Ÿฆ‘) eagle..squid + {0x1F992, 0x1F997, prExtendedPictographic}, // E5.0 [6] (๐Ÿฆ’..๐Ÿฆ—) giraffe..cricket + {0x1F998, 0x1F9A2, prExtendedPictographic}, // E11.0 [11] (๐Ÿฆ˜..๐Ÿฆข) kangaroo..swan + {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // E13.0 [2] (๐Ÿฆฃ..๐Ÿฆค) mammoth..dodo + {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // E12.0 [6] (๐Ÿฆฅ..๐Ÿฆช) sloth..oyster + {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // E13.0 [3] (๐Ÿฆซ..๐Ÿฆญ) beaver..seal + {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // E12.0 [2] (๐Ÿฆฎ..๐Ÿฆฏ) guide dog..white cane + {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // E11.0 [10] (๐Ÿฆฐ..๐Ÿฆน) red hair..supervillain + {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // E12.0 [6] (๐Ÿฆบ..๐Ÿฆฟ) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // E1.0 [1] (๐Ÿง€) cheese wedge + {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // E11.0 [2] (๐Ÿง..๐Ÿง‚) cupcake..salt + {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // E12.0 [8] (๐Ÿงƒ..๐ŸงŠ) beverage box..ice + {0x1F9CB, 0x1F9CB, prExtendedPictographic}, // E13.0 [1] (๐Ÿง‹) bubble tea + {0x1F9CC, 0x1F9CC, prExtendedPictographic}, // E14.0 [1] (๐ŸงŒ) troll + {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // E12.0 [3] (๐Ÿง..๐Ÿง) person standing..deaf person + {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // E5.0 [23] (๐Ÿง..๐Ÿงฆ) face with monocle..socks + {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // E11.0 [25] (๐Ÿงง..๐Ÿงฟ) red envelope..nazar amulet + {0x1FA00, 0x1FA6F, prExtendedPictographic}, // E0.0 [112] (๐Ÿจ€..๐Ÿฉฏ) NEUTRAL CHESS KING.. + {0x1FA70, 0x1FA73, prExtendedPictographic}, // E12.0 [4] (๐Ÿฉฐ..๐Ÿฉณ) ballet shoes..shorts + {0x1FA74, 0x1FA74, prExtendedPictographic}, // E13.0 [1] (๐Ÿฉด) thong sandal + {0x1FA75, 0x1FA77, prExtendedPictographic}, // E15.0 [3] (๐Ÿฉต..๐Ÿฉท) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prExtendedPictographic}, // E12.0 [3] (๐Ÿฉธ..๐Ÿฉบ) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prExtendedPictographic}, // E14.0 [2] (๐Ÿฉป..๐Ÿฉผ) x-ray..crutch + {0x1FA7D, 0x1FA7F, prExtendedPictographic}, // E0.0 [3] (๐Ÿฉฝ..๐Ÿฉฟ) .. + {0x1FA80, 0x1FA82, prExtendedPictographic}, // E12.0 [3] (๐Ÿช€..๐Ÿช‚) yo-yo..parachute + {0x1FA83, 0x1FA86, prExtendedPictographic}, // E13.0 [4] (๐Ÿชƒ..๐Ÿช†) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prExtendedPictographic}, // E15.0 [2] (๐Ÿช‡..๐Ÿชˆ) maracas..flute + {0x1FA89, 0x1FA8F, prExtendedPictographic}, // E0.0 [7] (๐Ÿช‰..๐Ÿช) .. + {0x1FA90, 0x1FA95, prExtendedPictographic}, // E12.0 [6] (๐Ÿช..๐Ÿช•) ringed planet..banjo + {0x1FA96, 0x1FAA8, prExtendedPictographic}, // E13.0 [19] (๐Ÿช–..๐Ÿชจ) military helmet..rock + {0x1FAA9, 0x1FAAC, prExtendedPictographic}, // E14.0 [4] (๐Ÿชฉ..๐Ÿชฌ) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prExtendedPictographic}, // E15.0 [3] (๐Ÿชญ..๐Ÿชฏ) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prExtendedPictographic}, // E13.0 [7] (๐Ÿชฐ..๐Ÿชถ) fly..feather + {0x1FAB7, 0x1FABA, prExtendedPictographic}, // E14.0 [4] (๐Ÿชท..๐Ÿชบ) lotus..nest with eggs + {0x1FABB, 0x1FABD, prExtendedPictographic}, // E15.0 [3] (๐Ÿชป..๐Ÿชฝ) hyacinth..wing + {0x1FABE, 0x1FABE, prExtendedPictographic}, // E0.0 [1] (๐Ÿชพ) + {0x1FABF, 0x1FABF, prExtendedPictographic}, // E15.0 [1] (๐Ÿชฟ) goose + {0x1FAC0, 0x1FAC2, prExtendedPictographic}, // E13.0 [3] (๐Ÿซ€..๐Ÿซ‚) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prExtendedPictographic}, // E14.0 [3] (๐Ÿซƒ..๐Ÿซ…) pregnant man..person with crown + {0x1FAC6, 0x1FACD, prExtendedPictographic}, // E0.0 [8] (๐Ÿซ†..๐Ÿซ) .. + {0x1FACE, 0x1FACF, prExtendedPictographic}, // E15.0 [2] (๐ŸซŽ..๐Ÿซ) moose..donkey + {0x1FAD0, 0x1FAD6, prExtendedPictographic}, // E13.0 [7] (๐Ÿซ..๐Ÿซ–) blueberries..teapot + {0x1FAD7, 0x1FAD9, prExtendedPictographic}, // E14.0 [3] (๐Ÿซ—..๐Ÿซ™) pouring liquid..jar + {0x1FADA, 0x1FADB, prExtendedPictographic}, // E15.0 [2] (๐Ÿซš..๐Ÿซ›) ginger root..pea pod + {0x1FADC, 0x1FADF, prExtendedPictographic}, // E0.0 [4] (๐Ÿซœ..๐ŸซŸ) .. + {0x1FAE0, 0x1FAE7, prExtendedPictographic}, // E14.0 [8] (๐Ÿซ ..๐Ÿซง) melting face..bubbles + {0x1FAE8, 0x1FAE8, prExtendedPictographic}, // E15.0 [1] (๐Ÿซจ) shaking face + {0x1FAE9, 0x1FAEF, prExtendedPictographic}, // E0.0 [7] (๐Ÿซฉ..๐Ÿซฏ) .. + {0x1FAF0, 0x1FAF6, prExtendedPictographic}, // E14.0 [7] (๐Ÿซฐ..๐Ÿซถ) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prExtendedPictographic}, // E15.0 [2] (๐Ÿซท..๐Ÿซธ) leftwards pushing hand..rightwards pushing hand + {0x1FAF9, 0x1FAFF, prExtendedPictographic}, // E0.0 [7] (๐Ÿซน..๐Ÿซฟ) .. + {0x1FC00, 0x1FFFD, prExtendedPictographic}, // E0.0[1022] (๐Ÿฐ€..๐Ÿฟฝ) .. + {0xE0000, 0xE0000, prControl}, // Cn + {0xE0001, 0xE0001, prControl}, // Cf LANGUAGE TAG + {0xE0002, 0xE001F, prControl}, // Cn [30] .. + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0080, 0xE00FF, prControl}, // Cn [128] .. + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xE01F0, 0xE0FFF, prControl}, // Cn [3600] .. +} diff --git a/vendor/github.com/rivo/uniseg/graphemerules.go b/vendor/github.com/rivo/uniseg/graphemerules.go new file mode 100644 index 000000000000..5d399d29c8fb --- /dev/null +++ b/vendor/github.com/rivo/uniseg/graphemerules.go @@ -0,0 +1,176 @@ +package uniseg + +// The states of the grapheme cluster parser. +const ( + grAny = iota + grCR + grControlLF + grL + grLVV + grLVTT + grPrepend + grExtendedPictographic + grExtendedPictographicZWJ + grRIOdd + grRIEven +) + +// The grapheme cluster parser's breaking instructions. +const ( + grNoBoundary = iota + grBoundary +) + +// grTransitions implements the grapheme cluster parser's state transitions. +// Maps state and property to a new state, a breaking instruction, and rule +// number. The breaking instruction always refers to the boundary between the +// last and next code point. Returns negative values if no transition is found. +// +// This function is used as follows: +// +// 1. Find specific state + specific property. Stop if found. +// 2. Find specific state + any property. +// 3. Find any state + specific property. +// 4. If only (2) or (3) (but not both) was found, stop. +// 5. If both (2) and (3) were found, use state from (3) and breaking instruction +// from the transition with the lower rule number, prefer (3) if rule numbers +// are equal. Stop. +// 6. Assume grAny and grBoundary. +// +// Unicode version 15.0.0. +func grTransitions(state, prop int) (newState int, newProp int, boundary int) { + // It turns out that using a big switch statement is much faster than using + // a map. + + switch uint64(state) | uint64(prop)<<32 { + // GB5 + case grAny | prCR<<32: + return grCR, grBoundary, 50 + case grAny | prLF<<32: + return grControlLF, grBoundary, 50 + case grAny | prControl<<32: + return grControlLF, grBoundary, 50 + + // GB4 + case grCR | prAny<<32: + return grAny, grBoundary, 40 + case grControlLF | prAny<<32: + return grAny, grBoundary, 40 + + // GB3 + case grCR | prLF<<32: + return grControlLF, grNoBoundary, 30 + + // GB6 + case grAny | prL<<32: + return grL, grBoundary, 9990 + case grL | prL<<32: + return grL, grNoBoundary, 60 + case grL | prV<<32: + return grLVV, grNoBoundary, 60 + case grL | prLV<<32: + return grLVV, grNoBoundary, 60 + case grL | prLVT<<32: + return grLVTT, grNoBoundary, 60 + + // GB7 + case grAny | prLV<<32: + return grLVV, grBoundary, 9990 + case grAny | prV<<32: + return grLVV, grBoundary, 9990 + case grLVV | prV<<32: + return grLVV, grNoBoundary, 70 + case grLVV | prT<<32: + return grLVTT, grNoBoundary, 70 + + // GB8 + case grAny | prLVT<<32: + return grLVTT, grBoundary, 9990 + case grAny | prT<<32: + return grLVTT, grBoundary, 9990 + case grLVTT | prT<<32: + return grLVTT, grNoBoundary, 80 + + // GB9 + case grAny | prExtend<<32: + return grAny, grNoBoundary, 90 + case grAny | prZWJ<<32: + return grAny, grNoBoundary, 90 + + // GB9a + case grAny | prSpacingMark<<32: + return grAny, grNoBoundary, 91 + + // GB9b + case grAny | prPrepend<<32: + return grPrepend, grBoundary, 9990 + case grPrepend | prAny<<32: + return grAny, grNoBoundary, 92 + + // GB11 + case grAny | prExtendedPictographic<<32: + return grExtendedPictographic, grBoundary, 9990 + case grExtendedPictographic | prExtend<<32: + return grExtendedPictographic, grNoBoundary, 110 + case grExtendedPictographic | prZWJ<<32: + return grExtendedPictographicZWJ, grNoBoundary, 110 + case grExtendedPictographicZWJ | prExtendedPictographic<<32: + return grExtendedPictographic, grNoBoundary, 110 + + // GB12 / GB13 + case grAny | prRegionalIndicator<<32: + return grRIOdd, grBoundary, 9990 + case grRIOdd | prRegionalIndicator<<32: + return grRIEven, grNoBoundary, 120 + case grRIEven | prRegionalIndicator<<32: + return grRIOdd, grBoundary, 120 + default: + return -1, -1, -1 + } +} + +// transitionGraphemeState determines the new state of the grapheme cluster +// parser given the current state and the next code point. It also returns the +// code point's grapheme property (the value mapped by the [graphemeCodePoints] +// table) and whether a cluster boundary was detected. +func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) { + // Determine the property of the next character. + prop = propertyGraphemes(r) + + // Find the applicable transition. + nextState, nextProp, _ := grTransitions(state, prop) + if nextState >= 0 { + // We have a specific transition. We'll use it. + return nextState, prop, nextProp == grBoundary + } + + // No specific transition found. Try the less specific ones. + anyPropState, anyPropProp, anyPropRule := grTransitions(state, prAny) + anyStateState, anyStateProp, anyStateRule := grTransitions(grAny, prop) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState = anyStateState + boundary = anyStateProp == grBoundary + if anyPropRule < anyStateRule { + boundary = anyPropProp == grBoundary + } + return + } + + if anyPropState >= 0 { + // We only have a specific state. + return anyPropState, prop, anyPropProp == grBoundary + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } + + if anyStateState >= 0 { + // We only have a specific property. + return anyStateState, prop, anyStateProp == grBoundary + } + + // No known transition. GB999: Any รท Any. + return grAny, prop, true +} diff --git a/vendor/github.com/rivo/uniseg/line.go b/vendor/github.com/rivo/uniseg/line.go new file mode 100644 index 000000000000..7a46318d93d2 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/line.go @@ -0,0 +1,134 @@ +package uniseg + +import "unicode/utf8" + +// FirstLineSegment returns the prefix of the given byte slice after which a +// decision to break the string over to the next line can or must be made, +// according to the rules of [Unicode Standard Annex #14]. This is used to +// implement line breaking. +// +// Line breaking, also known as word wrapping, is the process of breaking a +// section of text into lines such that it will fit in the available width of a +// page, window or other display area. +// +// The returned "segment" may not be broken into smaller parts, unless no other +// breaking opportunities present themselves, in which case you may break by +// grapheme clusters (using the [FirstGraphemeCluster] function to determine the +// grapheme clusters). +// +// The "mustBreak" flag indicates whether you MUST break the line after the +// given segment (true), for example after newline characters, or you MAY break +// the line after the given segment (false). +// +// This function can be called continuously to extract all non-breaking sub-sets +// from a byte slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified line segment. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "segment" byte slice is the sub-slice of the input slice containing the +// identified line segment. +// +// Given an empty byte slice "b", the function returns nil values. +// +// Note that in accordance with [UAX #14 LB3], the final segment will end with +// "mustBreak" set to true. You can choose to ignore this by checking if the +// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or +// [HasTrailingLineBreakInString] on the last rune. +// +// Note also that this algorithm may break within grapheme clusters. This is +// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use +// the [Step] function instead. +// +// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/ +// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm +func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, true, lbAny // LB3. + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionLineBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary int + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionLineBreakState(state, r, b[length+l:], "") + + if boundary != LineDontBreak { + return b[:length], b[length:], boundary == LineMustBreak, state + } + + length += l + if len(b) <= length { + return b, nil, true, lbAny // LB3 + } + } +} + +// FirstLineSegmentInString is like [FirstLineSegment] but its input and outputs +// are strings. +func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", true, lbAny // LB3. + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionLineBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary int + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionLineBreakState(state, r, nil, str[length+l:]) + + if boundary != LineDontBreak { + return str[:length], str[length:], boundary == LineMustBreak, state + } + + length += l + if len(str) <= length { + return str, "", true, lbAny // LB3. + } + } +} + +// HasTrailingLineBreak returns true if the last rune in the given byte slice is +// one of the hard line break code points defined in LB4 and LB5 of [UAX #14]. +// +// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm +func HasTrailingLineBreak(b []byte) bool { + r, _ := utf8.DecodeLastRune(b) + property, _ := propertyLineBreak(r) + return property == prBK || property == prCR || property == prLF || property == prNL +} + +// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string. +func HasTrailingLineBreakInString(str string) bool { + r, _ := utf8.DecodeLastRuneInString(str) + property, _ := propertyLineBreak(r) + return property == prBK || property == prCR || property == prLF || property == prNL +} diff --git a/vendor/github.com/rivo/uniseg/lineproperties.go b/vendor/github.com/rivo/uniseg/lineproperties.go new file mode 100644 index 000000000000..ac7fac4c053a --- /dev/null +++ b/vendor/github.com/rivo/uniseg/lineproperties.go @@ -0,0 +1,3554 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// lineBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/LineBreak.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var lineBreakCodePoints = [][4]int{ + {0x0000, 0x0008, prCM, gcCc}, // [9] .. + {0x0009, 0x0009, prBA, gcCc}, // + {0x000A, 0x000A, prLF, gcCc}, // + {0x000B, 0x000C, prBK, gcCc}, // [2] .. + {0x000D, 0x000D, prCR, gcCc}, // + {0x000E, 0x001F, prCM, gcCc}, // [18] .. + {0x0020, 0x0020, prSP, gcZs}, // SPACE + {0x0021, 0x0021, prEX, gcPo}, // EXCLAMATION MARK + {0x0022, 0x0022, prQU, gcPo}, // QUOTATION MARK + {0x0023, 0x0023, prAL, gcPo}, // NUMBER SIGN + {0x0024, 0x0024, prPR, gcSc}, // DOLLAR SIGN + {0x0025, 0x0025, prPO, gcPo}, // PERCENT SIGN + {0x0026, 0x0026, prAL, gcPo}, // AMPERSAND + {0x0027, 0x0027, prQU, gcPo}, // APOSTROPHE + {0x0028, 0x0028, prOP, gcPs}, // LEFT PARENTHESIS + {0x0029, 0x0029, prCP, gcPe}, // RIGHT PARENTHESIS + {0x002A, 0x002A, prAL, gcPo}, // ASTERISK + {0x002B, 0x002B, prPR, gcSm}, // PLUS SIGN + {0x002C, 0x002C, prIS, gcPo}, // COMMA + {0x002D, 0x002D, prHY, gcPd}, // HYPHEN-MINUS + {0x002E, 0x002E, prIS, gcPo}, // FULL STOP + {0x002F, 0x002F, prSY, gcPo}, // SOLIDUS + {0x0030, 0x0039, prNU, gcNd}, // [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003B, prIS, gcPo}, // [2] COLON..SEMICOLON + {0x003C, 0x003E, prAL, gcSm}, // [3] LESS-THAN SIGN..GREATER-THAN SIGN + {0x003F, 0x003F, prEX, gcPo}, // QUESTION MARK + {0x0040, 0x0040, prAL, gcPo}, // COMMERCIAL AT + {0x0041, 0x005A, prAL, gcLu}, // [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prOP, gcPs}, // LEFT SQUARE BRACKET + {0x005C, 0x005C, prPR, gcPo}, // REVERSE SOLIDUS + {0x005D, 0x005D, prCP, gcPe}, // RIGHT SQUARE BRACKET + {0x005E, 0x005E, prAL, gcSk}, // CIRCUMFLEX ACCENT + {0x005F, 0x005F, prAL, gcPc}, // LOW LINE + {0x0060, 0x0060, prAL, gcSk}, // GRAVE ACCENT + {0x0061, 0x007A, prAL, gcLl}, // [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prOP, gcPs}, // LEFT CURLY BRACKET + {0x007C, 0x007C, prBA, gcSm}, // VERTICAL LINE + {0x007D, 0x007D, prCL, gcPe}, // RIGHT CURLY BRACKET + {0x007E, 0x007E, prAL, gcSm}, // TILDE + {0x007F, 0x007F, prCM, gcCc}, // + {0x0080, 0x0084, prCM, gcCc}, // [5] .. + {0x0085, 0x0085, prNL, gcCc}, // + {0x0086, 0x009F, prCM, gcCc}, // [26] .. + {0x00A0, 0x00A0, prGL, gcZs}, // NO-BREAK SPACE + {0x00A1, 0x00A1, prOP, gcPo}, // INVERTED EXCLAMATION MARK + {0x00A2, 0x00A2, prPO, gcSc}, // CENT SIGN + {0x00A3, 0x00A5, prPR, gcSc}, // [3] POUND SIGN..YEN SIGN + {0x00A6, 0x00A6, prAL, gcSo}, // BROKEN BAR + {0x00A7, 0x00A7, prAI, gcPo}, // SECTION SIGN + {0x00A8, 0x00A8, prAI, gcSk}, // DIAERESIS + {0x00A9, 0x00A9, prAL, gcSo}, // COPYRIGHT SIGN + {0x00AA, 0x00AA, prAI, gcLo}, // FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prQU, gcPi}, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AC, 0x00AC, prAL, gcSm}, // NOT SIGN + {0x00AD, 0x00AD, prBA, gcCf}, // SOFT HYPHEN + {0x00AE, 0x00AE, prAL, gcSo}, // REGISTERED SIGN + {0x00AF, 0x00AF, prAL, gcSk}, // MACRON + {0x00B0, 0x00B0, prPO, gcSo}, // DEGREE SIGN + {0x00B1, 0x00B1, prPR, gcSm}, // PLUS-MINUS SIGN + {0x00B2, 0x00B3, prAI, gcNo}, // [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE + {0x00B4, 0x00B4, prBB, gcSk}, // ACUTE ACCENT + {0x00B5, 0x00B5, prAL, gcLl}, // MICRO SIGN + {0x00B6, 0x00B7, prAI, gcPo}, // [2] PILCROW SIGN..MIDDLE DOT + {0x00B8, 0x00B8, prAI, gcSk}, // CEDILLA + {0x00B9, 0x00B9, prAI, gcNo}, // SUPERSCRIPT ONE + {0x00BA, 0x00BA, prAI, gcLo}, // MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prQU, gcPf}, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00BC, 0x00BE, prAI, gcNo}, // [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS + {0x00BF, 0x00BF, prOP, gcPo}, // INVERTED QUESTION MARK + {0x00C0, 0x00D6, prAL, gcLu}, // [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D7, 0x00D7, prAI, gcSm}, // MULTIPLICATION SIGN + {0x00D8, 0x00F6, prAL, gcLC}, // [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F7, 0x00F7, prAI, gcSm}, // DIVISION SIGN + {0x00F8, 0x00FF, prAL, gcLl}, // [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x017F, prAL, gcLC}, // [128] LATIN CAPITAL LETTER A WITH MACRON..LATIN SMALL LETTER LONG S + {0x0180, 0x01BA, prAL, gcLC}, // [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prAL, gcLo}, // LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prAL, gcLC}, // [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prAL, gcLo}, // [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x024F, prAL, gcLC}, // [140] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER Y WITH STROKE + {0x0250, 0x0293, prAL, gcLl}, // [68] LATIN SMALL LETTER TURNED A..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prAL, gcLo}, // LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prAL, gcLl}, // [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prAL, gcLm}, // [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C5, prAL, gcSk}, // [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02C6, prAL, gcLm}, // MODIFIER LETTER CIRCUMFLEX ACCENT + {0x02C7, 0x02C7, prAI, gcLm}, // CARON + {0x02C8, 0x02C8, prBB, gcLm}, // MODIFIER LETTER VERTICAL LINE + {0x02C9, 0x02CB, prAI, gcLm}, // [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT + {0x02CC, 0x02CC, prBB, gcLm}, // MODIFIER LETTER LOW VERTICAL LINE + {0x02CD, 0x02CD, prAI, gcLm}, // MODIFIER LETTER LOW MACRON + {0x02CE, 0x02CF, prAL, gcLm}, // [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT + {0x02D0, 0x02D0, prAI, gcLm}, // MODIFIER LETTER TRIANGULAR COLON + {0x02D1, 0x02D1, prAL, gcLm}, // MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prAL, gcSk}, // [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02D8, 0x02DB, prAI, gcSk}, // [4] BREVE..OGONEK + {0x02DC, 0x02DC, prAL, gcSk}, // SMALL TILDE + {0x02DD, 0x02DD, prAI, gcSk}, // DOUBLE ACUTE ACCENT + {0x02DE, 0x02DE, prAL, gcSk}, // MODIFIER LETTER RHOTIC HOOK + {0x02DF, 0x02DF, prBB, gcSk}, // MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prAL, gcLm}, // [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prAL, gcSk}, // [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prAL, gcLm}, // MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prAL, gcSk}, // MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prAL, gcLm}, // MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prAL, gcSk}, // [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x034E, prCM, gcMn}, // [79] COMBINING GRAVE ACCENT..COMBINING UPWARDS ARROW BELOW + {0x034F, 0x034F, prGL, gcMn}, // COMBINING GRAPHEME JOINER + {0x0350, 0x035B, prCM, gcMn}, // [12] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING ZIGZAG ABOVE + {0x035C, 0x0362, prGL, gcMn}, // [7] COMBINING DOUBLE BREVE BELOW..COMBINING DOUBLE RIGHTWARDS ARROW BELOW + {0x0363, 0x036F, prCM, gcMn}, // [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prAL, gcLC}, // [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prAL, gcLm}, // GREEK NUMERAL SIGN + {0x0375, 0x0375, prAL, gcSk}, // GREEK LOWER NUMERAL SIGN + {0x0376, 0x0377, prAL, gcLC}, // [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prAL, gcLm}, // GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prAL, gcLl}, // [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prIS, gcPo}, // GREEK QUESTION MARK + {0x037F, 0x037F, prAL, gcLu}, // GREEK CAPITAL LETTER YOT + {0x0384, 0x0385, prAL, gcSk}, // [2] GREEK TONOS..GREEK DIALYTIKA TONOS + {0x0386, 0x0386, prAL, gcLu}, // GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prAL, gcPo}, // GREEK ANO TELEIA + {0x0388, 0x038A, prAL, gcLu}, // [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prAL, gcLu}, // GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x03A1, prAL, gcLC}, // [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03F5, prAL, gcLC}, // [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL + {0x03F6, 0x03F6, prAL, gcSm}, // GREEK REVERSED LUNATE EPSILON SYMBOL + {0x03F7, 0x03FF, prAL, gcLC}, // [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x0400, 0x0481, prAL, gcLC}, // [130] CYRILLIC CAPITAL LETTER IE WITH GRAVE..CYRILLIC SMALL LETTER KOPPA + {0x0482, 0x0482, prAL, gcSo}, // CYRILLIC THOUSANDS SIGN + {0x0483, 0x0487, prCM, gcMn}, // [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prCM, gcMe}, // [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x04FF, prAL, gcLC}, // [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x052F, prAL, gcLC}, // [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prAL, gcLu}, // [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prAL, gcLm}, // ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055F, prAL, gcPo}, // [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prAL, gcLl}, // [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prIS, gcPo}, // ARMENIAN FULL STOP + {0x058A, 0x058A, prBA, gcPd}, // ARMENIAN HYPHEN + {0x058D, 0x058E, prAL, gcSo}, // [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN + {0x058F, 0x058F, prPR, gcSc}, // ARMENIAN DRAM SIGN + {0x0591, 0x05BD, prCM, gcMn}, // [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BE, 0x05BE, prBA, gcPd}, // HEBREW PUNCTUATION MAQAF + {0x05BF, 0x05BF, prCM, gcMn}, // HEBREW POINT RAFE + {0x05C0, 0x05C0, prAL, gcPo}, // HEBREW PUNCTUATION PASEQ + {0x05C1, 0x05C2, prCM, gcMn}, // [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C3, 0x05C3, prAL, gcPo}, // HEBREW PUNCTUATION SOF PASUQ + {0x05C4, 0x05C5, prCM, gcMn}, // [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C6, 0x05C6, prEX, gcPo}, // HEBREW PUNCTUATION NUN HAFUKHA + {0x05C7, 0x05C7, prCM, gcMn}, // HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prHL, gcLo}, // [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prHL, gcLo}, // [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F4, prAL, gcPo}, // [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prAL, gcCf}, // [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0606, 0x0608, prAL, gcSm}, // [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY + {0x0609, 0x060A, prPO, gcPo}, // [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN + {0x060B, 0x060B, prPO, gcSc}, // AFGHANI SIGN + {0x060C, 0x060D, prIS, gcPo}, // [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x060E, 0x060F, prAL, gcSo}, // [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA + {0x0610, 0x061A, prCM, gcMn}, // [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061B, 0x061B, prEX, gcPo}, // ARABIC SEMICOLON + {0x061C, 0x061C, prCM, gcCf}, // ARABIC LETTER MARK + {0x061D, 0x061F, prEX, gcPo}, // [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prAL, gcLo}, // [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prAL, gcLm}, // ARABIC TATWEEL + {0x0641, 0x064A, prAL, gcLo}, // [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prCM, gcMn}, // [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNU, gcNd}, // [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066A, 0x066A, prPO, gcPo}, // ARABIC PERCENT SIGN + {0x066B, 0x066C, prNU, gcPo}, // [2] ARABIC DECIMAL SEPARATOR..ARABIC THOUSANDS SEPARATOR + {0x066D, 0x066D, prAL, gcPo}, // ARABIC FIVE POINTED STAR + {0x066E, 0x066F, prAL, gcLo}, // [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prCM, gcMn}, // ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prAL, gcLo}, // [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prEX, gcPo}, // ARABIC FULL STOP + {0x06D5, 0x06D5, prAL, gcLo}, // ARABIC LETTER AE + {0x06D6, 0x06DC, prCM, gcMn}, // [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prAL, gcCf}, // ARABIC END OF AYAH + {0x06DE, 0x06DE, prAL, gcSo}, // ARABIC START OF RUB EL HIZB + {0x06DF, 0x06E4, prCM, gcMn}, // [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prAL, gcLm}, // [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prCM, gcMn}, // [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06E9, 0x06E9, prAL, gcSo}, // ARABIC PLACE OF SAJDAH + {0x06EA, 0x06ED, prCM, gcMn}, // [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prAL, gcLo}, // [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNU, gcNd}, // [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prAL, gcLo}, // [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FD, 0x06FE, prAL, gcSo}, // [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN + {0x06FF, 0x06FF, prAL, gcLo}, // ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x070D, prAL, gcPo}, // [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS + {0x070F, 0x070F, prAL, gcCf}, // SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prAL, gcLo}, // SYRIAC LETTER ALAPH + {0x0711, 0x0711, prCM, gcMn}, // SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prAL, gcLo}, // [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prCM, gcMn}, // [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x074F, prAL, gcLo}, // [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE + {0x0750, 0x077F, prAL, gcLo}, // [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE + {0x0780, 0x07A5, prAL, gcLo}, // [38] THAANA LETTER HAA..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prCM, gcMn}, // [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prAL, gcLo}, // THAANA LETTER NAA + {0x07C0, 0x07C9, prNU, gcNd}, // [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prAL, gcLo}, // [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prCM, gcMn}, // [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prAL, gcLm}, // [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F6, 0x07F6, prAL, gcSo}, // NKO SYMBOL OO DENNEN + {0x07F7, 0x07F7, prAL, gcPo}, // NKO SYMBOL GBAKURUNEN + {0x07F8, 0x07F8, prIS, gcPo}, // NKO COMMA + {0x07F9, 0x07F9, prEX, gcPo}, // NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prAL, gcLm}, // NKO LAJANYALAN + {0x07FD, 0x07FD, prCM, gcMn}, // NKO DANTAYALAN + {0x07FE, 0x07FF, prPR, gcSc}, // [2] NKO DOROME SIGN..NKO TAMAN SIGN + {0x0800, 0x0815, prAL, gcLo}, // [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prCM, gcMn}, // [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prAL, gcLm}, // SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prCM, gcMn}, // [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prAL, gcLm}, // SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prCM, gcMn}, // [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prAL, gcLm}, // SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prCM, gcMn}, // [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0830, 0x083E, prAL, gcPo}, // [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prAL, gcLo}, // [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prCM, gcMn}, // [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x085E, 0x085E, prAL, gcPo}, // MANDAIC PUNCTUATION + {0x0860, 0x086A, prAL, gcLo}, // [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prAL, gcLo}, // [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0888, 0x0888, prAL, gcSk}, // ARABIC RAISED ROUND DOT + {0x0889, 0x088E, prAL, gcLo}, // [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prAL, gcCf}, // [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prCM, gcMn}, // [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prAL, gcLo}, // [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prAL, gcLm}, // ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prCM, gcMn}, // [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prAL, gcCf}, // ARABIC DISPUTED END OF AYAH + {0x08E3, 0x08FF, prCM, gcMn}, // [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA + {0x0900, 0x0902, prCM, gcMn}, // [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prCM, gcMc}, // DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prAL, gcLo}, // [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prCM, gcMn}, // DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prCM, gcMc}, // DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prCM, gcMn}, // DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prAL, gcLo}, // DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prCM, gcMc}, // [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prCM, gcMn}, // [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prCM, gcMc}, // [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prCM, gcMn}, // DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prCM, gcMc}, // [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prAL, gcLo}, // DEVANAGARI OM + {0x0951, 0x0957, prCM, gcMn}, // [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prAL, gcLo}, // [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prCM, gcMn}, // [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prBA, gcPo}, // [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prNU, gcNd}, // [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0970, 0x0970, prAL, gcPo}, // DEVANAGARI ABBREVIATION SIGN + {0x0971, 0x0971, prAL, gcLm}, // DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x097F, prAL, gcLo}, // [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA + {0x0980, 0x0980, prAL, gcLo}, // BENGALI ANJI + {0x0981, 0x0981, prCM, gcMn}, // BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prCM, gcMc}, // [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prAL, gcLo}, // [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prAL, gcLo}, // [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prAL, gcLo}, // [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prAL, gcLo}, // [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prAL, gcLo}, // BENGALI LETTER LA + {0x09B6, 0x09B9, prAL, gcLo}, // [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prCM, gcMn}, // BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prAL, gcLo}, // BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prCM, gcMc}, // [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prCM, gcMn}, // [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prCM, gcMc}, // [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prCM, gcMc}, // [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prCM, gcMn}, // BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prAL, gcLo}, // BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prCM, gcMc}, // BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prAL, gcLo}, // [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prAL, gcLo}, // [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prCM, gcMn}, // [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNU, gcNd}, // [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prAL, gcLo}, // [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09F2, 0x09F3, prPO, gcSc}, // [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN + {0x09F4, 0x09F8, prAL, gcNo}, // [5] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR + {0x09F9, 0x09F9, prPO, gcNo}, // BENGALI CURRENCY DENOMINATOR SIXTEEN + {0x09FA, 0x09FA, prAL, gcSo}, // BENGALI ISSHAR + {0x09FB, 0x09FB, prPR, gcSc}, // BENGALI GANDA MARK + {0x09FC, 0x09FC, prAL, gcLo}, // BENGALI LETTER VEDIC ANUSVARA + {0x09FD, 0x09FD, prAL, gcPo}, // BENGALI ABBREVIATION SIGN + {0x09FE, 0x09FE, prCM, gcMn}, // BENGALI SANDHI MARK + {0x0A01, 0x0A02, prCM, gcMn}, // [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prCM, gcMc}, // GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prAL, gcLo}, // [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prAL, gcLo}, // [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prAL, gcLo}, // [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prAL, gcLo}, // [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prAL, gcLo}, // [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prAL, gcLo}, // [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prAL, gcLo}, // [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prCM, gcMn}, // GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prCM, gcMc}, // [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prCM, gcMn}, // [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prCM, gcMn}, // GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prAL, gcLo}, // [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prAL, gcLo}, // GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNU, gcNd}, // [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prCM, gcMn}, // [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prAL, gcLo}, // [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prCM, gcMn}, // GURMUKHI SIGN YAKASH + {0x0A76, 0x0A76, prAL, gcPo}, // GURMUKHI ABBREVIATION SIGN + {0x0A81, 0x0A82, prCM, gcMn}, // [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prCM, gcMc}, // GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prAL, gcLo}, // [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prAL, gcLo}, // [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prAL, gcLo}, // [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prAL, gcLo}, // [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prAL, gcLo}, // [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prAL, gcLo}, // [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prCM, gcMn}, // GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prAL, gcLo}, // GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prCM, gcMc}, // [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prCM, gcMn}, // [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prCM, gcMc}, // GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prCM, gcMc}, // [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prCM, gcMn}, // GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prAL, gcLo}, // GUJARATI OM + {0x0AE0, 0x0AE1, prAL, gcLo}, // [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNU, gcNd}, // [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF0, 0x0AF0, prAL, gcPo}, // GUJARATI ABBREVIATION SIGN + {0x0AF1, 0x0AF1, prPR, gcSc}, // GUJARATI RUPEE SIGN + {0x0AF9, 0x0AF9, prAL, gcLo}, // GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prCM, gcMn}, // [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prCM, gcMn}, // ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prCM, gcMc}, // [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prAL, gcLo}, // [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prAL, gcLo}, // [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prAL, gcLo}, // [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prAL, gcLo}, // [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prAL, gcLo}, // [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prAL, gcLo}, // [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prCM, gcMn}, // ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prAL, gcLo}, // ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prCM, gcMc}, // ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prCM, gcMn}, // ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prCM, gcMc}, // ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prCM, gcMn}, // [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prCM, gcMc}, // [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prCM, gcMc}, // [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prCM, gcMn}, // ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prCM, gcMn}, // [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prCM, gcMc}, // ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prAL, gcLo}, // [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prAL, gcLo}, // [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prCM, gcMn}, // [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNU, gcNd}, // [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B70, 0x0B70, prAL, gcSo}, // ORIYA ISSHAR + {0x0B71, 0x0B71, prAL, gcLo}, // ORIYA LETTER WA + {0x0B72, 0x0B77, prAL, gcNo}, // [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS + {0x0B82, 0x0B82, prCM, gcMn}, // TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prAL, gcLo}, // TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prAL, gcLo}, // [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prAL, gcLo}, // [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prAL, gcLo}, // [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prAL, gcLo}, // [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prAL, gcLo}, // TAMIL LETTER JA + {0x0B9E, 0x0B9F, prAL, gcLo}, // [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prAL, gcLo}, // [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prAL, gcLo}, // [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prAL, gcLo}, // [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prCM, gcMc}, // [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prCM, gcMn}, // TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prCM, gcMc}, // [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prCM, gcMc}, // [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prCM, gcMc}, // [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prCM, gcMn}, // TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prAL, gcLo}, // TAMIL OM + {0x0BD7, 0x0BD7, prCM, gcMc}, // TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNU, gcNd}, // [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0BF0, 0x0BF2, prAL, gcNo}, // [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND + {0x0BF3, 0x0BF8, prAL, gcSo}, // [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN + {0x0BF9, 0x0BF9, prPR, gcSc}, // TAMIL RUPEE SIGN + {0x0BFA, 0x0BFA, prAL, gcSo}, // TAMIL NUMBER SIGN + {0x0C00, 0x0C00, prCM, gcMn}, // TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prCM, gcMc}, // [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prCM, gcMn}, // TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prAL, gcLo}, // [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prAL, gcLo}, // [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prAL, gcLo}, // [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prAL, gcLo}, // [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prCM, gcMn}, // TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prAL, gcLo}, // TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prCM, gcMn}, // [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prCM, gcMc}, // [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prCM, gcMn}, // [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prCM, gcMn}, // [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prCM, gcMn}, // [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prAL, gcLo}, // [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prAL, gcLo}, // TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prAL, gcLo}, // [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prCM, gcMn}, // [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNU, gcNd}, // [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C77, 0x0C77, prBB, gcPo}, // TELUGU SIGN SIDDHAM + {0x0C78, 0x0C7E, prAL, gcNo}, // [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR + {0x0C7F, 0x0C7F, prAL, gcSo}, // TELUGU SIGN TUUMU + {0x0C80, 0x0C80, prAL, gcLo}, // KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prCM, gcMn}, // KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prCM, gcMc}, // [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C84, 0x0C84, prBB, gcPo}, // KANNADA SIGN SIDDHAM + {0x0C85, 0x0C8C, prAL, gcLo}, // [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prAL, gcLo}, // [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prAL, gcLo}, // [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prAL, gcLo}, // [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prAL, gcLo}, // [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prCM, gcMn}, // KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prAL, gcLo}, // KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prCM, gcMc}, // KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prCM, gcMn}, // KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prCM, gcMc}, // [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prCM, gcMn}, // KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prCM, gcMc}, // [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prCM, gcMc}, // [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prCM, gcMn}, // [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prCM, gcMc}, // [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prAL, gcLo}, // [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prAL, gcLo}, // [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prCM, gcMn}, // [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNU, gcNd}, // [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prAL, gcLo}, // [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prCM, gcMc}, // KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prCM, gcMn}, // [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prCM, gcMc}, // [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prAL, gcLo}, // [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prAL, gcLo}, // [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prAL, gcLo}, // [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prCM, gcMn}, // [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prAL, gcLo}, // MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prCM, gcMn}, // [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prCM, gcMn}, // MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prAL, gcLo}, // MALAYALAM LETTER DOT REPH + {0x0D4F, 0x0D4F, prAL, gcSo}, // MALAYALAM SIGN PARA + {0x0D54, 0x0D56, prAL, gcLo}, // [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prCM, gcMc}, // MALAYALAM AU LENGTH MARK + {0x0D58, 0x0D5E, prAL, gcNo}, // [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH + {0x0D5F, 0x0D61, prAL, gcLo}, // [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prCM, gcMn}, // [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNU, gcNd}, // [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D70, 0x0D78, prAL, gcNo}, // [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS + {0x0D79, 0x0D79, prPO, gcSo}, // MALAYALAM DATE MARK + {0x0D7A, 0x0D7F, prAL, gcLo}, // [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prCM, gcMn}, // SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prCM, gcMc}, // [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prAL, gcLo}, // [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prAL, gcLo}, // [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prAL, gcLo}, // [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prAL, gcLo}, // SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prAL, gcLo}, // [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prCM, gcMn}, // SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prCM, gcMc}, // [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prCM, gcMn}, // [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prCM, gcMn}, // SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prCM, gcMc}, // [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNU, gcNd}, // [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prCM, gcMc}, // [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0DF4, 0x0DF4, prAL, gcPo}, // SINHALA PUNCTUATION KUNDDALIYA + {0x0E01, 0x0E30, prSA, gcLo}, // [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prSA, gcMn}, // THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prSA, gcLo}, // [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prSA, gcMn}, // [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E3F, 0x0E3F, prPR, gcSc}, // THAI CURRENCY SYMBOL BAHT + {0x0E40, 0x0E45, prSA, gcLo}, // [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prSA, gcLm}, // THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prSA, gcMn}, // [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E4F, 0x0E4F, prAL, gcPo}, // THAI CHARACTER FONGMAN + {0x0E50, 0x0E59, prNU, gcNd}, // [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E5A, 0x0E5B, prBA, gcPo}, // [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT + {0x0E81, 0x0E82, prSA, gcLo}, // [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prSA, gcLo}, // LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prSA, gcLo}, // [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prSA, gcLo}, // [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prSA, gcLo}, // LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prSA, gcLo}, // [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prSA, gcMn}, // LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prSA, gcLo}, // [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prSA, gcMn}, // [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prSA, gcLo}, // LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prSA, gcLo}, // [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prSA, gcLm}, // LAO KO LA + {0x0EC8, 0x0ECE, prSA, gcMn}, // [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNU, gcNd}, // [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prSA, gcLo}, // [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prAL, gcLo}, // TIBETAN SYLLABLE OM + {0x0F01, 0x0F03, prBB, gcSo}, // [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA + {0x0F04, 0x0F04, prBB, gcPo}, // TIBETAN MARK INITIAL YIG MGO MDUN MA + {0x0F05, 0x0F05, prAL, gcPo}, // TIBETAN MARK CLOSING YIG MGO SGAB MA + {0x0F06, 0x0F07, prBB, gcPo}, // [2] TIBETAN MARK CARET YIG MGO PHUR SHAD MA..TIBETAN MARK YIG MGO TSHEG SHAD MA + {0x0F08, 0x0F08, prGL, gcPo}, // TIBETAN MARK SBRUL SHAD + {0x0F09, 0x0F0A, prBB, gcPo}, // [2] TIBETAN MARK BSKUR YIG MGO..TIBETAN MARK BKA- SHOG YIG MGO + {0x0F0B, 0x0F0B, prBA, gcPo}, // TIBETAN MARK INTERSYLLABIC TSHEG + {0x0F0C, 0x0F0C, prGL, gcPo}, // TIBETAN MARK DELIMITER TSHEG BSTAR + {0x0F0D, 0x0F11, prEX, gcPo}, // [5] TIBETAN MARK SHAD..TIBETAN MARK RIN CHEN SPUNGS SHAD + {0x0F12, 0x0F12, prGL, gcPo}, // TIBETAN MARK RGYA GRAM SHAD + {0x0F13, 0x0F13, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN + {0x0F14, 0x0F14, prEX, gcPo}, // TIBETAN MARK GTER TSHEG + {0x0F15, 0x0F17, prAL, gcSo}, // [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS + {0x0F18, 0x0F19, prCM, gcMn}, // [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F1A, 0x0F1F, prAL, gcSo}, // [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG + {0x0F20, 0x0F29, prNU, gcNd}, // [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F2A, 0x0F33, prAL, gcNo}, // [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO + {0x0F34, 0x0F34, prBA, gcSo}, // TIBETAN MARK BSDUS RTAGS + {0x0F35, 0x0F35, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F36, 0x0F36, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN + {0x0F37, 0x0F37, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F38, 0x0F38, prAL, gcSo}, // TIBETAN MARK CHE MGO + {0x0F39, 0x0F39, prCM, gcMn}, // TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prOP, gcPs}, // TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prCL, gcPe}, // TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prOP, gcPs}, // TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prCL, gcPe}, // TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prCM, gcMc}, // [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prAL, gcLo}, // [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prAL, gcLo}, // [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prCM, gcMn}, // [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prBA, gcMc}, // TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prCM, gcMn}, // [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F85, 0x0F85, prBA, gcPo}, // TIBETAN MARK PALUTA + {0x0F86, 0x0F87, prCM, gcMn}, // [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prAL, gcLo}, // [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prCM, gcMn}, // [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prCM, gcMn}, // [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FBE, 0x0FBF, prBA, gcSo}, // [2] TIBETAN KU RU KHA..TIBETAN KU RU KHA BZHI MIG CAN + {0x0FC0, 0x0FC5, prAL, gcSo}, // [6] TIBETAN CANTILLATION SIGN HEAVY BEAT..TIBETAN SYMBOL RDO RJE + {0x0FC6, 0x0FC6, prCM, gcMn}, // TIBETAN SYMBOL PADMA GDAN + {0x0FC7, 0x0FCC, prAL, gcSo}, // [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL + {0x0FCE, 0x0FCF, prAL, gcSo}, // [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM + {0x0FD0, 0x0FD1, prBB, gcPo}, // [2] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK MNYAM YIG GI MGO RGYAN + {0x0FD2, 0x0FD2, prBA, gcPo}, // TIBETAN MARK NYIS TSHEG + {0x0FD3, 0x0FD3, prBB, gcPo}, // TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA + {0x0FD4, 0x0FD4, prAL, gcPo}, // TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA + {0x0FD5, 0x0FD8, prAL, gcSo}, // [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS + {0x0FD9, 0x0FDA, prGL, gcPo}, // [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS + {0x1000, 0x102A, prSA, gcLo}, // [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prSA, gcMc}, // MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prSA, gcMn}, // [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prSA, gcMc}, // MYANMAR SIGN VISARGA + {0x1039, 0x103A, prSA, gcMn}, // [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prSA, gcMc}, // [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prSA, gcMn}, // [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prSA, gcLo}, // MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prNU, gcNd}, // [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104B, prBA, gcPo}, // [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION + {0x104C, 0x104F, prAL, gcPo}, // [4] MYANMAR SYMBOL LOCATIVE..MYANMAR SYMBOL GENITIVE + {0x1050, 0x1055, prSA, gcLo}, // [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prSA, gcLo}, // [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prSA, gcMn}, // [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prSA, gcLo}, // MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prSA, gcMc}, // [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prSA, gcLo}, // [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prSA, gcMc}, // [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prSA, gcLo}, // [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prSA, gcLo}, // [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prSA, gcMn}, // MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prSA, gcMc}, // [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prSA, gcMn}, // MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prSA, gcLo}, // MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prSA, gcMc}, // MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNU, gcNd}, // [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prSA, gcMc}, // [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prSA, gcMn}, // MYANMAR VOWEL SIGN AITON AI + {0x109E, 0x109F, prSA, gcSo}, // [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION + {0x10A0, 0x10C5, prAL, gcLu}, // [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prAL, gcLu}, // GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prAL, gcLu}, // GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prAL, gcLl}, // [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FB, 0x10FB, prAL, gcPo}, // GEORGIAN PARAGRAPH SEPARATOR + {0x10FC, 0x10FC, prAL, gcLm}, // MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prAL, gcLl}, // [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x115F, prJL, gcLo}, // [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11A7, prJV, gcLo}, // [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE + {0x11A8, 0x11FF, prJT, gcLo}, // [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN + {0x1200, 0x1248, prAL, gcLo}, // [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prAL, gcLo}, // ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prAL, gcLo}, // [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prAL, gcLo}, // [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prAL, gcLo}, // ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prAL, gcLo}, // [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prAL, gcLo}, // [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prCM, gcMn}, // [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1360, 0x1360, prAL, gcPo}, // ETHIOPIC SECTION MARK + {0x1361, 0x1361, prBA, gcPo}, // ETHIOPIC WORDSPACE + {0x1362, 0x1368, prAL, gcPo}, // [7] ETHIOPIC FULL STOP..ETHIOPIC PARAGRAPH SEPARATOR + {0x1369, 0x137C, prAL, gcNo}, // [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND + {0x1380, 0x138F, prAL, gcLo}, // [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x1390, 0x1399, prAL, gcSo}, // [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT + {0x13A0, 0x13F5, prAL, gcLu}, // [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prAL, gcLl}, // [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1400, 0x1400, prBA, gcPd}, // CANADIAN SYLLABICS HYPHEN + {0x1401, 0x166C, prAL, gcLo}, // [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166D, 0x166D, prAL, gcSo}, // CANADIAN SYLLABICS CHI SIGN + {0x166E, 0x166E, prAL, gcPo}, // CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prAL, gcLo}, // [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prBA, gcZs}, // OGHAM SPACE MARK + {0x1681, 0x169A, prAL, gcLo}, // [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prOP, gcPs}, // OGHAM FEATHER MARK + {0x169C, 0x169C, prCL, gcPe}, // OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prAL, gcLo}, // [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EB, 0x16ED, prBA, gcPo}, // [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION + {0x16EE, 0x16F0, prAL, gcNl}, // [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prAL, gcLo}, // [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prAL, gcLo}, // [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prCM, gcMn}, // [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prCM, gcMc}, // TAGALOG SIGN PAMUDPOD + {0x171F, 0x171F, prAL, gcLo}, // TAGALOG LETTER ARCHAIC RA + {0x1720, 0x1731, prAL, gcLo}, // [18] HANUNOO LETTER A..HANUNOO LETTER HA + {0x1732, 0x1733, prCM, gcMn}, // [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prCM, gcMc}, // HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prBA, gcPo}, // [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prAL, gcLo}, // [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prCM, gcMn}, // [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prAL, gcLo}, // [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prAL, gcLo}, // [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prCM, gcMn}, // [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prSA, gcLo}, // [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prSA, gcMn}, // [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prSA, gcMc}, // KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prSA, gcMn}, // [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prSA, gcMc}, // [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prSA, gcMn}, // KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prSA, gcMc}, // [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prSA, gcMn}, // [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D4, 0x17D5, prBA, gcPo}, // [2] KHMER SIGN KHAN..KHMER SIGN BARIYOOSAN + {0x17D6, 0x17D6, prNS, gcPo}, // KHMER SIGN CAMNUC PII KUUH + {0x17D7, 0x17D7, prSA, gcLm}, // KHMER SIGN LEK TOO + {0x17D8, 0x17D8, prBA, gcPo}, // KHMER SIGN BEYYAL + {0x17D9, 0x17D9, prAL, gcPo}, // KHMER SIGN PHNAEK MUAN + {0x17DA, 0x17DA, prBA, gcPo}, // KHMER SIGN KOOMUUT + {0x17DB, 0x17DB, prPR, gcSc}, // KHMER CURRENCY SYMBOL RIEL + {0x17DC, 0x17DC, prSA, gcLo}, // KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prSA, gcMn}, // KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNU, gcNd}, // [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x17F0, 0x17F9, prAL, gcNo}, // [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON + {0x1800, 0x1801, prAL, gcPo}, // [2] MONGOLIAN BIRGA..MONGOLIAN ELLIPSIS + {0x1802, 0x1803, prEX, gcPo}, // [2] MONGOLIAN COMMA..MONGOLIAN FULL STOP + {0x1804, 0x1805, prBA, gcPo}, // [2] MONGOLIAN COLON..MONGOLIAN FOUR DOTS + {0x1806, 0x1806, prBB, gcPd}, // MONGOLIAN TODO SOFT HYPHEN + {0x1807, 0x1807, prAL, gcPo}, // MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER + {0x1808, 0x1809, prEX, gcPo}, // [2] MONGOLIAN MANCHU COMMA..MONGOLIAN MANCHU FULL STOP + {0x180A, 0x180A, prAL, gcPo}, // MONGOLIAN NIRUGU + {0x180B, 0x180D, prCM, gcMn}, // [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prGL, gcCf}, // MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prCM, gcMn}, // MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNU, gcNd}, // [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prAL, gcLo}, // [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prAL, gcLm}, // MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prAL, gcLo}, // [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prAL, gcLo}, // [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prCM, gcMn}, // [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prAL, gcLo}, // [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prCM, gcMn}, // MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prAL, gcLo}, // MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prAL, gcLo}, // [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prAL, gcLo}, // [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prCM, gcMn}, // [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prCM, gcMc}, // [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prCM, gcMn}, // [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prCM, gcMc}, // [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prCM, gcMc}, // [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prCM, gcMn}, // LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prCM, gcMc}, // [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prCM, gcMn}, // [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1940, 0x1940, prAL, gcSo}, // LIMBU SIGN LOO + {0x1944, 0x1945, prEX, gcPo}, // [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prNU, gcNd}, // [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prSA, gcLo}, // [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prSA, gcLo}, // [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prSA, gcLo}, // [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prSA, gcLo}, // [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prNU, gcNd}, // [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x19DA, 0x19DA, prSA, gcNo}, // NEW TAI LUE THAM DIGIT ONE + {0x19DE, 0x19DF, prSA, gcSo}, // [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV + {0x19E0, 0x19FF, prAL, gcSo}, // [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC + {0x1A00, 0x1A16, prAL, gcLo}, // [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prCM, gcMn}, // [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prCM, gcMc}, // [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prCM, gcMn}, // BUGINESE VOWEL SIGN AE + {0x1A1E, 0x1A1F, prAL, gcPo}, // [2] BUGINESE PALLAWA..BUGINESE END OF SECTION + {0x1A20, 0x1A54, prSA, gcLo}, // [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prSA, gcMc}, // TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prSA, gcMn}, // TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prSA, gcMc}, // TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prSA, gcMn}, // [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prSA, gcMn}, // TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prSA, gcMc}, // TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prSA, gcMn}, // TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prSA, gcMc}, // [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prSA, gcMn}, // [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prSA, gcMc}, // [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prSA, gcMn}, // [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prCM, gcMn}, // TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNU, gcNd}, // [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNU, gcNd}, // [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA0, 0x1AA6, prSA, gcPo}, // [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA + {0x1AA7, 0x1AA7, prSA, gcLm}, // TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAD, prSA, gcPo}, // [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG + {0x1AB0, 0x1ABD, prCM, gcMn}, // [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prCM, gcMe}, // COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prCM, gcMn}, // [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prCM, gcMn}, // [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prCM, gcMc}, // BALINESE SIGN BISAH + {0x1B05, 0x1B33, prAL, gcLo}, // [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prCM, gcMn}, // BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prCM, gcMc}, // BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prCM, gcMn}, // [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prCM, gcMc}, // BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prCM, gcMn}, // BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prCM, gcMc}, // [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prCM, gcMn}, // BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prCM, gcMc}, // [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prAL, gcLo}, // [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNU, gcNd}, // [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B5B, prBA, gcPo}, // [2] BALINESE PANTI..BALINESE PAMADA + {0x1B5C, 0x1B5C, prAL, gcPo}, // BALINESE WINDU + {0x1B5D, 0x1B60, prBA, gcPo}, // [4] BALINESE CARIK PAMUNGKAH..BALINESE PAMENENG + {0x1B61, 0x1B6A, prAL, gcSo}, // [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE + {0x1B6B, 0x1B73, prCM, gcMn}, // [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B74, 0x1B7C, prAL, gcSo}, // [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING + {0x1B7D, 0x1B7E, prBA, gcPo}, // [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prCM, gcMn}, // [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prCM, gcMc}, // SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prAL, gcLo}, // [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prCM, gcMc}, // SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prCM, gcMn}, // [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prCM, gcMc}, // [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prCM, gcMn}, // [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prCM, gcMc}, // SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prCM, gcMn}, // [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prAL, gcLo}, // [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNU, gcNd}, // [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BBF, prAL, gcLo}, // [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M + {0x1BC0, 0x1BE5, prAL, gcLo}, // [38] BATAK LETTER A..BATAK LETTER U + {0x1BE6, 0x1BE6, prCM, gcMn}, // BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prCM, gcMc}, // BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prCM, gcMn}, // [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prCM, gcMc}, // [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prCM, gcMn}, // BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prCM, gcMc}, // BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prCM, gcMn}, // [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prCM, gcMc}, // [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1BFC, 0x1BFF, prAL, gcPo}, // [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT + {0x1C00, 0x1C23, prAL, gcLo}, // [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prCM, gcMc}, // [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prCM, gcMn}, // [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prCM, gcMc}, // [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prCM, gcMn}, // [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3F, prBA, gcPo}, // [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK + {0x1C40, 0x1C49, prNU, gcNd}, // [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prAL, gcLo}, // [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNU, gcNd}, // [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prAL, gcLo}, // [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prAL, gcLm}, // [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prBA, gcPo}, // [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prAL, gcLl}, // [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prAL, gcLu}, // [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prAL, gcLu}, // [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CC0, 0x1CC7, prAL, gcPo}, // [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA + {0x1CD0, 0x1CD2, prCM, gcMn}, // [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD3, 0x1CD3, prAL, gcPo}, // VEDIC SIGN NIHSHVASA + {0x1CD4, 0x1CE0, prCM, gcMn}, // [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prCM, gcMc}, // VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prCM, gcMn}, // [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prAL, gcLo}, // [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prCM, gcMn}, // VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prAL, gcLo}, // [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prCM, gcMn}, // VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prAL, gcLo}, // [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prCM, gcMc}, // VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prCM, gcMn}, // [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prAL, gcLo}, // VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prAL, gcLl}, // [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prAL, gcLm}, // [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prAL, gcLl}, // [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prAL, gcLm}, // MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D7F, prAL, gcLl}, // [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE + {0x1D80, 0x1D9A, prAL, gcLl}, // [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prAL, gcLm}, // [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DCC, prCM, gcMn}, // [13] COMBINING DOTTED GRAVE ACCENT..COMBINING MACRON-BREVE + {0x1DCD, 0x1DCD, prGL, gcMn}, // COMBINING DOUBLE CIRCUMFLEX ABOVE + {0x1DCE, 0x1DFB, prCM, gcMn}, // [46] COMBINING OGONEK ABOVE..COMBINING DELETION MARK + {0x1DFC, 0x1DFC, prGL, gcMn}, // COMBINING DOUBLE INVERTED BREVE BELOW + {0x1DFD, 0x1DFF, prCM, gcMn}, // [3] COMBINING ALMOST EQUAL TO BELOW..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1EFF, prAL, gcLC}, // [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP + {0x1F00, 0x1F15, prAL, gcLC}, // [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prAL, gcLC}, // [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prAL, gcLl}, // [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prAL, gcLC}, // [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prAL, gcLC}, // [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prAL, gcLC}, // [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBD, 0x1FBD, prAL, gcSk}, // GREEK KORONIS + {0x1FBE, 0x1FBE, prAL, gcLl}, // GREEK PROSGEGRAMMENI + {0x1FBF, 0x1FC1, prAL, gcSk}, // [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI + {0x1FC2, 0x1FC4, prAL, gcLl}, // [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prAL, gcLC}, // [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FCD, 0x1FCF, prAL, gcSk}, // [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI + {0x1FD0, 0x1FD3, prAL, gcLl}, // [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prAL, gcLC}, // [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FDD, 0x1FDF, prAL, gcSk}, // [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI + {0x1FE0, 0x1FEC, prAL, gcLC}, // [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FED, 0x1FEF, prAL, gcSk}, // [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA + {0x1FF2, 0x1FF4, prAL, gcLl}, // [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prAL, gcLC}, // [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x1FFD, 0x1FFD, prBB, gcSk}, // GREEK OXIA + {0x1FFE, 0x1FFE, prAL, gcSk}, // GREEK DASIA + {0x2000, 0x2006, prBA, gcZs}, // [7] EN QUAD..SIX-PER-EM SPACE + {0x2007, 0x2007, prGL, gcZs}, // FIGURE SPACE + {0x2008, 0x200A, prBA, gcZs}, // [3] PUNCTUATION SPACE..HAIR SPACE + {0x200B, 0x200B, prZW, gcCf}, // ZERO WIDTH SPACE + {0x200C, 0x200C, prCM, gcCf}, // ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ, gcCf}, // ZERO WIDTH JOINER + {0x200E, 0x200F, prCM, gcCf}, // [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2010, 0x2010, prBA, gcPd}, // HYPHEN + {0x2011, 0x2011, prGL, gcPd}, // NON-BREAKING HYPHEN + {0x2012, 0x2013, prBA, gcPd}, // [2] FIGURE DASH..EN DASH + {0x2014, 0x2014, prB2, gcPd}, // EM DASH + {0x2015, 0x2015, prAI, gcPd}, // HORIZONTAL BAR + {0x2016, 0x2016, prAI, gcPo}, // DOUBLE VERTICAL LINE + {0x2017, 0x2017, prAL, gcPo}, // DOUBLE LOW LINE + {0x2018, 0x2018, prQU, gcPi}, // LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prQU, gcPf}, // RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prOP, gcPs}, // SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201C, prQU, gcPi}, // [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prQU, gcPf}, // RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prOP, gcPs}, // DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prQU, gcPi}, // DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2020, 0x2021, prAI, gcPo}, // [2] DAGGER..DOUBLE DAGGER + {0x2022, 0x2023, prAL, gcPo}, // [2] BULLET..TRIANGULAR BULLET + {0x2024, 0x2026, prIN, gcPo}, // [3] ONE DOT LEADER..HORIZONTAL ELLIPSIS + {0x2027, 0x2027, prBA, gcPo}, // HYPHENATION POINT + {0x2028, 0x2028, prBK, gcZl}, // LINE SEPARATOR + {0x2029, 0x2029, prBK, gcZp}, // PARAGRAPH SEPARATOR + {0x202A, 0x202E, prCM, gcCf}, // [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prGL, gcZs}, // NARROW NO-BREAK SPACE + {0x2030, 0x2037, prPO, gcPo}, // [8] PER MILLE SIGN..REVERSED TRIPLE PRIME + {0x2038, 0x2038, prAL, gcPo}, // CARET + {0x2039, 0x2039, prQU, gcPi}, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prQU, gcPf}, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203B, 0x203B, prAI, gcPo}, // REFERENCE MARK + {0x203C, 0x203D, prNS, gcPo}, // [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x203E, 0x203E, prAL, gcPo}, // OVERLINE + {0x203F, 0x2040, prAL, gcPc}, // [2] UNDERTIE..CHARACTER TIE + {0x2041, 0x2043, prAL, gcPo}, // [3] CARET INSERTION POINT..HYPHEN BULLET + {0x2044, 0x2044, prIS, gcSm}, // FRACTION SLASH + {0x2045, 0x2045, prOP, gcPs}, // LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2049, prNS, gcPo}, // [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK + {0x204A, 0x2051, prAL, gcPo}, // [8] TIRONIAN SIGN ET..TWO ASTERISKS ALIGNED VERTICALLY + {0x2052, 0x2052, prAL, gcSm}, // COMMERCIAL MINUS SIGN + {0x2053, 0x2053, prAL, gcPo}, // SWUNG DASH + {0x2054, 0x2054, prAL, gcPc}, // INVERTED UNDERTIE + {0x2055, 0x2055, prAL, gcPo}, // FLOWER PUNCTUATION MARK + {0x2056, 0x2056, prBA, gcPo}, // THREE DOT PUNCTUATION + {0x2057, 0x2057, prPO, gcPo}, // QUADRUPLE PRIME + {0x2058, 0x205B, prBA, gcPo}, // [4] FOUR DOT PUNCTUATION..FOUR DOT MARK + {0x205C, 0x205C, prAL, gcPo}, // DOTTED CROSS + {0x205D, 0x205E, prBA, gcPo}, // [2] TRICOLON..VERTICAL FOUR DOTS + {0x205F, 0x205F, prBA, gcZs}, // MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2060, prWJ, gcCf}, // WORD JOINER + {0x2061, 0x2064, prAL, gcCf}, // [4] FUNCTION APPLICATION..INVISIBLE PLUS + {0x2066, 0x206F, prCM, gcCf}, // [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2070, 0x2070, prAL, gcNo}, // SUPERSCRIPT ZERO + {0x2071, 0x2071, prAL, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER I + {0x2074, 0x2074, prAI, gcNo}, // SUPERSCRIPT FOUR + {0x2075, 0x2079, prAL, gcNo}, // [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE + {0x207A, 0x207C, prAL, gcSm}, // [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN + {0x207D, 0x207D, prOP, gcPs}, // SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prCL, gcPe}, // SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prAI, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER N + {0x2080, 0x2080, prAL, gcNo}, // SUBSCRIPT ZERO + {0x2081, 0x2084, prAI, gcNo}, // [4] SUBSCRIPT ONE..SUBSCRIPT FOUR + {0x2085, 0x2089, prAL, gcNo}, // [5] SUBSCRIPT FIVE..SUBSCRIPT NINE + {0x208A, 0x208C, prAL, gcSm}, // [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN + {0x208D, 0x208D, prOP, gcPs}, // SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prCL, gcPe}, // SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prAL, gcLm}, // [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20A0, 0x20A6, prPR, gcSc}, // [7] EURO-CURRENCY SIGN..NAIRA SIGN + {0x20A7, 0x20A7, prPO, gcSc}, // PESETA SIGN + {0x20A8, 0x20B5, prPR, gcSc}, // [14] RUPEE SIGN..CEDI SIGN + {0x20B6, 0x20B6, prPO, gcSc}, // LIVRE TOURNOIS SIGN + {0x20B7, 0x20BA, prPR, gcSc}, // [4] SPESMILO SIGN..TURKISH LIRA SIGN + {0x20BB, 0x20BB, prPO, gcSc}, // NORDIC MARK SIGN + {0x20BC, 0x20BD, prPR, gcSc}, // [2] MANAT SIGN..RUBLE SIGN + {0x20BE, 0x20BE, prPO, gcSc}, // LARI SIGN + {0x20BF, 0x20BF, prPR, gcSc}, // BITCOIN SIGN + {0x20C0, 0x20C0, prPO, gcSc}, // SOM SIGN + {0x20C1, 0x20CF, prPR, gcCn}, // [15] .. + {0x20D0, 0x20DC, prCM, gcMn}, // [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prCM, gcMe}, // [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prCM, gcMn}, // COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prCM, gcMe}, // [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prCM, gcMn}, // [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2100, 0x2101, prAL, gcSo}, // [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT + {0x2102, 0x2102, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL C + {0x2103, 0x2103, prPO, gcSo}, // DEGREE CELSIUS + {0x2104, 0x2104, prAL, gcSo}, // CENTRE LINE SYMBOL + {0x2105, 0x2105, prAI, gcSo}, // CARE OF + {0x2106, 0x2106, prAL, gcSo}, // CADA UNA + {0x2107, 0x2107, prAL, gcLu}, // EULER CONSTANT + {0x2108, 0x2108, prAL, gcSo}, // SCRUPLE + {0x2109, 0x2109, prPO, gcSo}, // DEGREE FAHRENHEIT + {0x210A, 0x2112, prAL, gcLC}, // [9] SCRIPT SMALL G..SCRIPT CAPITAL L + {0x2113, 0x2113, prAI, gcLl}, // SCRIPT SMALL L + {0x2114, 0x2114, prAL, gcSo}, // L B BAR SYMBOL + {0x2115, 0x2115, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL N + {0x2116, 0x2116, prPR, gcSo}, // NUMERO SIGN + {0x2117, 0x2117, prAL, gcSo}, // SOUND RECORDING COPYRIGHT + {0x2118, 0x2118, prAL, gcSm}, // SCRIPT CAPITAL P + {0x2119, 0x211D, prAL, gcLu}, // [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x211E, 0x2120, prAL, gcSo}, // [3] PRESCRIPTION TAKE..SERVICE MARK + {0x2121, 0x2122, prAI, gcSo}, // [2] TELEPHONE SIGN..TRADE MARK SIGN + {0x2123, 0x2123, prAL, gcSo}, // VERSICLE + {0x2124, 0x2124, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL Z + {0x2125, 0x2125, prAL, gcSo}, // OUNCE SIGN + {0x2126, 0x2126, prAL, gcLu}, // OHM SIGN + {0x2127, 0x2127, prAL, gcSo}, // INVERTED OHM SIGN + {0x2128, 0x2128, prAL, gcLu}, // BLACK-LETTER CAPITAL Z + {0x2129, 0x2129, prAL, gcSo}, // TURNED GREEK SMALL LETTER IOTA + {0x212A, 0x212A, prAL, gcLu}, // KELVIN SIGN + {0x212B, 0x212B, prAI, gcLu}, // ANGSTROM SIGN + {0x212C, 0x212D, prAL, gcLu}, // [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C + {0x212E, 0x212E, prAL, gcSo}, // ESTIMATED SYMBOL + {0x212F, 0x2134, prAL, gcLC}, // [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prAL, gcLo}, // [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prAL, gcLl}, // INFORMATION SOURCE + {0x213A, 0x213B, prAL, gcSo}, // [2] ROTATED CAPITAL Q..FACSIMILE SIGN + {0x213C, 0x213F, prAL, gcLC}, // [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2140, 0x2144, prAL, gcSm}, // [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y + {0x2145, 0x2149, prAL, gcLC}, // [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214A, 0x214A, prAL, gcSo}, // PROPERTY LINE + {0x214B, 0x214B, prAL, gcSm}, // TURNED AMPERSAND + {0x214C, 0x214D, prAL, gcSo}, // [2] PER SIGN..AKTIESELSKAB + {0x214E, 0x214E, prAL, gcLl}, // TURNED SMALL F + {0x214F, 0x214F, prAL, gcSo}, // SYMBOL FOR SAMARITAN SOURCE + {0x2150, 0x2153, prAL, gcNo}, // [4] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE THIRD + {0x2154, 0x2155, prAI, gcNo}, // [2] VULGAR FRACTION TWO THIRDS..VULGAR FRACTION ONE FIFTH + {0x2156, 0x215A, prAL, gcNo}, // [5] VULGAR FRACTION TWO FIFTHS..VULGAR FRACTION FIVE SIXTHS + {0x215B, 0x215B, prAI, gcNo}, // VULGAR FRACTION ONE EIGHTH + {0x215C, 0x215D, prAL, gcNo}, // [2] VULGAR FRACTION THREE EIGHTHS..VULGAR FRACTION FIVE EIGHTHS + {0x215E, 0x215E, prAI, gcNo}, // VULGAR FRACTION SEVEN EIGHTHS + {0x215F, 0x215F, prAL, gcNo}, // FRACTION NUMERATOR ONE + {0x2160, 0x216B, prAI, gcNl}, // [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE + {0x216C, 0x216F, prAL, gcNl}, // [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x2179, prAI, gcNl}, // [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN + {0x217A, 0x2182, prAL, gcNl}, // [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prAL, gcLC}, // [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prAL, gcNl}, // [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2189, 0x2189, prAI, gcNo}, // VULGAR FRACTION ZERO THIRDS + {0x218A, 0x218B, prAL, gcSo}, // [2] TURNED DIGIT TWO..TURNED DIGIT THREE + {0x2190, 0x2194, prAI, gcSm}, // [5] LEFTWARDS ARROW..LEFT RIGHT ARROW + {0x2195, 0x2199, prAI, gcSo}, // [5] UP DOWN ARROW..SOUTH WEST ARROW + {0x219A, 0x219B, prAL, gcSm}, // [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE + {0x219C, 0x219F, prAL, gcSo}, // [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW + {0x21A0, 0x21A0, prAL, gcSm}, // RIGHTWARDS TWO HEADED ARROW + {0x21A1, 0x21A2, prAL, gcSo}, // [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL + {0x21A3, 0x21A3, prAL, gcSm}, // RIGHTWARDS ARROW WITH TAIL + {0x21A4, 0x21A5, prAL, gcSo}, // [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR + {0x21A6, 0x21A6, prAL, gcSm}, // RIGHTWARDS ARROW FROM BAR + {0x21A7, 0x21AD, prAL, gcSo}, // [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW + {0x21AE, 0x21AE, prAL, gcSm}, // LEFT RIGHT ARROW WITH STROKE + {0x21AF, 0x21CD, prAL, gcSo}, // [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE + {0x21CE, 0x21CF, prAL, gcSm}, // [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE + {0x21D0, 0x21D1, prAL, gcSo}, // [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW + {0x21D2, 0x21D2, prAI, gcSm}, // RIGHTWARDS DOUBLE ARROW + {0x21D3, 0x21D3, prAL, gcSo}, // DOWNWARDS DOUBLE ARROW + {0x21D4, 0x21D4, prAI, gcSm}, // LEFT RIGHT DOUBLE ARROW + {0x21D5, 0x21F3, prAL, gcSo}, // [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW + {0x21F4, 0x21FF, prAL, gcSm}, // [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW + {0x2200, 0x2200, prAI, gcSm}, // FOR ALL + {0x2201, 0x2201, prAL, gcSm}, // COMPLEMENT + {0x2202, 0x2203, prAI, gcSm}, // [2] PARTIAL DIFFERENTIAL..THERE EXISTS + {0x2204, 0x2206, prAL, gcSm}, // [3] THERE DOES NOT EXIST..INCREMENT + {0x2207, 0x2208, prAI, gcSm}, // [2] NABLA..ELEMENT OF + {0x2209, 0x220A, prAL, gcSm}, // [2] NOT AN ELEMENT OF..SMALL ELEMENT OF + {0x220B, 0x220B, prAI, gcSm}, // CONTAINS AS MEMBER + {0x220C, 0x220E, prAL, gcSm}, // [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF + {0x220F, 0x220F, prAI, gcSm}, // N-ARY PRODUCT + {0x2210, 0x2210, prAL, gcSm}, // N-ARY COPRODUCT + {0x2211, 0x2211, prAI, gcSm}, // N-ARY SUMMATION + {0x2212, 0x2213, prPR, gcSm}, // [2] MINUS SIGN..MINUS-OR-PLUS SIGN + {0x2214, 0x2214, prAL, gcSm}, // DOT PLUS + {0x2215, 0x2215, prAI, gcSm}, // DIVISION SLASH + {0x2216, 0x2219, prAL, gcSm}, // [4] SET MINUS..BULLET OPERATOR + {0x221A, 0x221A, prAI, gcSm}, // SQUARE ROOT + {0x221B, 0x221C, prAL, gcSm}, // [2] CUBE ROOT..FOURTH ROOT + {0x221D, 0x2220, prAI, gcSm}, // [4] PROPORTIONAL TO..ANGLE + {0x2221, 0x2222, prAL, gcSm}, // [2] MEASURED ANGLE..SPHERICAL ANGLE + {0x2223, 0x2223, prAI, gcSm}, // DIVIDES + {0x2224, 0x2224, prAL, gcSm}, // DOES NOT DIVIDE + {0x2225, 0x2225, prAI, gcSm}, // PARALLEL TO + {0x2226, 0x2226, prAL, gcSm}, // NOT PARALLEL TO + {0x2227, 0x222C, prAI, gcSm}, // [6] LOGICAL AND..DOUBLE INTEGRAL + {0x222D, 0x222D, prAL, gcSm}, // TRIPLE INTEGRAL + {0x222E, 0x222E, prAI, gcSm}, // CONTOUR INTEGRAL + {0x222F, 0x2233, prAL, gcSm}, // [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL + {0x2234, 0x2237, prAI, gcSm}, // [4] THEREFORE..PROPORTION + {0x2238, 0x223B, prAL, gcSm}, // [4] DOT MINUS..HOMOTHETIC + {0x223C, 0x223D, prAI, gcSm}, // [2] TILDE OPERATOR..REVERSED TILDE + {0x223E, 0x2247, prAL, gcSm}, // [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + {0x2248, 0x2248, prAI, gcSm}, // ALMOST EQUAL TO + {0x2249, 0x224B, prAL, gcSm}, // [3] NOT ALMOST EQUAL TO..TRIPLE TILDE + {0x224C, 0x224C, prAI, gcSm}, // ALL EQUAL TO + {0x224D, 0x2251, prAL, gcSm}, // [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO + {0x2252, 0x2252, prAI, gcSm}, // APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x2253, 0x225F, prAL, gcSm}, // [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO + {0x2260, 0x2261, prAI, gcSm}, // [2] NOT EQUAL TO..IDENTICAL TO + {0x2262, 0x2263, prAL, gcSm}, // [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO + {0x2264, 0x2267, prAI, gcSm}, // [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO + {0x2268, 0x2269, prAL, gcSm}, // [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO + {0x226A, 0x226B, prAI, gcSm}, // [2] MUCH LESS-THAN..MUCH GREATER-THAN + {0x226C, 0x226D, prAL, gcSm}, // [2] BETWEEN..NOT EQUIVALENT TO + {0x226E, 0x226F, prAI, gcSm}, // [2] NOT LESS-THAN..NOT GREATER-THAN + {0x2270, 0x2281, prAL, gcSm}, // [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED + {0x2282, 0x2283, prAI, gcSm}, // [2] SUBSET OF..SUPERSET OF + {0x2284, 0x2285, prAL, gcSm}, // [2] NOT A SUBSET OF..NOT A SUPERSET OF + {0x2286, 0x2287, prAI, gcSm}, // [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO + {0x2288, 0x2294, prAL, gcSm}, // [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP + {0x2295, 0x2295, prAI, gcSm}, // CIRCLED PLUS + {0x2296, 0x2298, prAL, gcSm}, // [3] CIRCLED MINUS..CIRCLED DIVISION SLASH + {0x2299, 0x2299, prAI, gcSm}, // CIRCLED DOT OPERATOR + {0x229A, 0x22A4, prAL, gcSm}, // [11] CIRCLED RING OPERATOR..DOWN TACK + {0x22A5, 0x22A5, prAI, gcSm}, // UP TACK + {0x22A6, 0x22BE, prAL, gcSm}, // [25] ASSERTION..RIGHT ANGLE WITH ARC + {0x22BF, 0x22BF, prAI, gcSm}, // RIGHT TRIANGLE + {0x22C0, 0x22EE, prAL, gcSm}, // [47] N-ARY LOGICAL AND..VERTICAL ELLIPSIS + {0x22EF, 0x22EF, prIN, gcSm}, // MIDLINE HORIZONTAL ELLIPSIS + {0x22F0, 0x22FF, prAL, gcSm}, // [16] UP RIGHT DIAGONAL ELLIPSIS..Z NOTATION BAG MEMBERSHIP + {0x2300, 0x2307, prAL, gcSo}, // [8] DIAMETER SIGN..WAVY LINE + {0x2308, 0x2308, prOP, gcPs}, // LEFT CEILING + {0x2309, 0x2309, prCL, gcPe}, // RIGHT CEILING + {0x230A, 0x230A, prOP, gcPs}, // LEFT FLOOR + {0x230B, 0x230B, prCL, gcPe}, // RIGHT FLOOR + {0x230C, 0x2311, prAL, gcSo}, // [6] BOTTOM RIGHT CROP..SQUARE LOZENGE + {0x2312, 0x2312, prAI, gcSo}, // ARC + {0x2313, 0x2319, prAL, gcSo}, // [7] SEGMENT..TURNED NOT SIGN + {0x231A, 0x231B, prID, gcSo}, // [2] WATCH..HOURGLASS + {0x231C, 0x231F, prAL, gcSo}, // [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER + {0x2320, 0x2321, prAL, gcSm}, // [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL + {0x2322, 0x2328, prAL, gcSo}, // [7] FROWN..KEYBOARD + {0x2329, 0x2329, prOP, gcPs}, // LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prCL, gcPe}, // RIGHT-POINTING ANGLE BRACKET + {0x232B, 0x237B, prAL, gcSo}, // [81] ERASE TO THE LEFT..NOT CHECK MARK + {0x237C, 0x237C, prAL, gcSm}, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + {0x237D, 0x239A, prAL, gcSo}, // [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL + {0x239B, 0x23B3, prAL, gcSm}, // [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM + {0x23B4, 0x23DB, prAL, gcSo}, // [40] TOP SQUARE BRACKET..FUSE + {0x23DC, 0x23E1, prAL, gcSm}, // [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET + {0x23E2, 0x23EF, prAL, gcSo}, // [14] WHITE TRAPEZIUM..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR + {0x23F0, 0x23F3, prID, gcSo}, // [4] ALARM CLOCK..HOURGLASS WITH FLOWING SAND + {0x23F4, 0x23FF, prAL, gcSo}, // [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL + {0x2400, 0x2426, prAL, gcSo}, // [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO + {0x2440, 0x244A, prAL, gcSo}, // [11] OCR HOOK..OCR DOUBLE BACKSLASH + {0x2460, 0x249B, prAI, gcNo}, // [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP + {0x249C, 0x24E9, prAI, gcSo}, // [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24EA, 0x24FE, prAI, gcNo}, // [21] CIRCLED DIGIT ZERO..DOUBLE CIRCLED NUMBER TEN + {0x24FF, 0x24FF, prAL, gcNo}, // NEGATIVE CIRCLED DIGIT ZERO + {0x2500, 0x254B, prAI, gcSo}, // [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0x254C, 0x254F, prAL, gcSo}, // [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + {0x2550, 0x2574, prAI, gcSo}, // [37] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT LEFT + {0x2575, 0x257F, prAL, gcSo}, // [11] BOX DRAWINGS LIGHT UP..BOX DRAWINGS HEAVY UP AND LIGHT DOWN + {0x2580, 0x258F, prAI, gcSo}, // [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK + {0x2590, 0x2591, prAL, gcSo}, // [2] RIGHT HALF BLOCK..LIGHT SHADE + {0x2592, 0x2595, prAI, gcSo}, // [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK + {0x2596, 0x259F, prAL, gcSo}, // [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT + {0x25A0, 0x25A1, prAI, gcSo}, // [2] BLACK SQUARE..WHITE SQUARE + {0x25A2, 0x25A2, prAL, gcSo}, // WHITE SQUARE WITH ROUNDED CORNERS + {0x25A3, 0x25A9, prAI, gcSo}, // [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL + {0x25AA, 0x25B1, prAL, gcSo}, // [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM + {0x25B2, 0x25B3, prAI, gcSo}, // [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE + {0x25B4, 0x25B5, prAL, gcSo}, // [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE + {0x25B6, 0x25B6, prAI, gcSo}, // BLACK RIGHT-POINTING TRIANGLE + {0x25B7, 0x25B7, prAI, gcSm}, // WHITE RIGHT-POINTING TRIANGLE + {0x25B8, 0x25BB, prAL, gcSo}, // [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER + {0x25BC, 0x25BD, prAI, gcSo}, // [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE + {0x25BE, 0x25BF, prAL, gcSo}, // [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE + {0x25C0, 0x25C0, prAI, gcSo}, // BLACK LEFT-POINTING TRIANGLE + {0x25C1, 0x25C1, prAI, gcSm}, // WHITE LEFT-POINTING TRIANGLE + {0x25C2, 0x25C5, prAL, gcSo}, // [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER + {0x25C6, 0x25C8, prAI, gcSo}, // [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + {0x25C9, 0x25CA, prAL, gcSo}, // [2] FISHEYE..LOZENGE + {0x25CB, 0x25CB, prAI, gcSo}, // WHITE CIRCLE + {0x25CC, 0x25CD, prAL, gcSo}, // [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL + {0x25CE, 0x25D1, prAI, gcSo}, // [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK + {0x25D2, 0x25E1, prAL, gcSo}, // [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE + {0x25E2, 0x25E5, prAI, gcSo}, // [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE + {0x25E6, 0x25EE, prAL, gcSo}, // [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + {0x25EF, 0x25EF, prAI, gcSo}, // LARGE CIRCLE + {0x25F0, 0x25F7, prAL, gcSo}, // [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT + {0x25F8, 0x25FF, prAL, gcSm}, // [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE + {0x2600, 0x2603, prID, gcSo}, // [4] BLACK SUN WITH RAYS..SNOWMAN + {0x2604, 0x2604, prAL, gcSo}, // COMET + {0x2605, 0x2606, prAI, gcSo}, // [2] BLACK STAR..WHITE STAR + {0x2607, 0x2608, prAL, gcSo}, // [2] LIGHTNING..THUNDERSTORM + {0x2609, 0x2609, prAI, gcSo}, // SUN + {0x260A, 0x260D, prAL, gcSo}, // [4] ASCENDING NODE..OPPOSITION + {0x260E, 0x260F, prAI, gcSo}, // [2] BLACK TELEPHONE..WHITE TELEPHONE + {0x2610, 0x2613, prAL, gcSo}, // [4] BALLOT BOX..SALTIRE + {0x2614, 0x2615, prID, gcSo}, // [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE + {0x2616, 0x2617, prAI, gcSo}, // [2] WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prID, gcSo}, // SHAMROCK + {0x2619, 0x2619, prAL, gcSo}, // REVERSED ROTATED FLORAL HEART BULLET + {0x261A, 0x261C, prID, gcSo}, // [3] BLACK LEFT POINTING INDEX..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prEB, gcSo}, // WHITE UP POINTING INDEX + {0x261E, 0x261F, prID, gcSo}, // [2] WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2638, prAL, gcSo}, // [25] SKULL AND CROSSBONES..WHEEL OF DHARMA + {0x2639, 0x263B, prID, gcSo}, // [3] WHITE FROWNING FACE..BLACK SMILING FACE + {0x263C, 0x263F, prAL, gcSo}, // [4] WHITE SUN WITH RAYS..MERCURY + {0x2640, 0x2640, prAI, gcSo}, // FEMALE SIGN + {0x2641, 0x2641, prAL, gcSo}, // EARTH + {0x2642, 0x2642, prAI, gcSo}, // MALE SIGN + {0x2643, 0x265F, prAL, gcSo}, // [29] JUPITER..BLACK CHESS PAWN + {0x2660, 0x2661, prAI, gcSo}, // [2] BLACK SPADE SUIT..WHITE HEART SUIT + {0x2662, 0x2662, prAL, gcSo}, // WHITE DIAMOND SUIT + {0x2663, 0x2665, prAI, gcSo}, // [3] BLACK CLUB SUIT..BLACK HEART SUIT + {0x2666, 0x2666, prAL, gcSo}, // BLACK DIAMOND SUIT + {0x2667, 0x2667, prAI, gcSo}, // WHITE CLUB SUIT + {0x2668, 0x2668, prID, gcSo}, // HOT SPRINGS + {0x2669, 0x266A, prAI, gcSo}, // [2] QUARTER NOTE..EIGHTH NOTE + {0x266B, 0x266B, prAL, gcSo}, // BEAMED EIGHTH NOTES + {0x266C, 0x266D, prAI, gcSo}, // [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN + {0x266E, 0x266E, prAL, gcSo}, // MUSIC NATURAL SIGN + {0x266F, 0x266F, prAI, gcSm}, // MUSIC SHARP SIGN + {0x2670, 0x267E, prAL, gcSo}, // [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN + {0x267F, 0x267F, prID, gcSo}, // WHEELCHAIR SYMBOL + {0x2680, 0x269D, prAL, gcSo}, // [30] DIE FACE-1..OUTLINED WHITE STAR + {0x269E, 0x269F, prAI, gcSo}, // [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT + {0x26A0, 0x26BC, prAL, gcSo}, // [29] WARNING SIGN..SESQUIQUADRATE + {0x26BD, 0x26C8, prID, gcSo}, // [12] SOCCER BALL..THUNDER CLOUD AND RAIN + {0x26C9, 0x26CC, prAI, gcSo}, // [4] TURNED WHITE SHOGI PIECE..CROSSING LANES + {0x26CD, 0x26CD, prID, gcSo}, // DISABLED CAR + {0x26CE, 0x26CE, prAL, gcSo}, // OPHIUCHUS + {0x26CF, 0x26D1, prID, gcSo}, // [3] PICK..HELMET WITH WHITE CROSS + {0x26D2, 0x26D2, prAI, gcSo}, // CIRCLED CROSSING LANES + {0x26D3, 0x26D4, prID, gcSo}, // [2] CHAINS..NO ENTRY + {0x26D5, 0x26D7, prAI, gcSo}, // [3] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..WHITE TWO-WAY LEFT WAY TRAFFIC + {0x26D8, 0x26D9, prID, gcSo}, // [2] BLACK LEFT LANE MERGE..WHITE LEFT LANE MERGE + {0x26DA, 0x26DB, prAI, gcSo}, // [2] DRIVE SLOW SIGN..HEAVY WHITE DOWN-POINTING TRIANGLE + {0x26DC, 0x26DC, prID, gcSo}, // LEFT CLOSED ENTRY + {0x26DD, 0x26DE, prAI, gcSo}, // [2] SQUARED SALTIRE..FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE + {0x26DF, 0x26E1, prID, gcSo}, // [3] BLACK TRUCK..RESTRICTED LEFT ENTRY-2 + {0x26E2, 0x26E2, prAL, gcSo}, // ASTRONOMICAL SYMBOL FOR URANUS + {0x26E3, 0x26E3, prAI, gcSo}, // HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + {0x26E4, 0x26E7, prAL, gcSo}, // [4] PENTAGRAM..INVERTED PENTAGRAM + {0x26E8, 0x26E9, prAI, gcSo}, // [2] BLACK CROSS ON SHIELD..SHINTO SHRINE + {0x26EA, 0x26EA, prID, gcSo}, // CHURCH + {0x26EB, 0x26F0, prAI, gcSo}, // [6] CASTLE..MOUNTAIN + {0x26F1, 0x26F5, prID, gcSo}, // [5] UMBRELLA ON GROUND..SAILBOAT + {0x26F6, 0x26F6, prAI, gcSo}, // SQUARE FOUR CORNERS + {0x26F7, 0x26F8, prID, gcSo}, // [2] SKIER..ICE SKATE + {0x26F9, 0x26F9, prEB, gcSo}, // PERSON WITH BALL + {0x26FA, 0x26FA, prID, gcSo}, // TENT + {0x26FB, 0x26FC, prAI, gcSo}, // [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FF, prID, gcSo}, // [3] FUEL PUMP..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + {0x2700, 0x2704, prID, gcSo}, // [5] BLACK SAFETY SCISSORS..WHITE SCISSORS + {0x2705, 0x2707, prAL, gcSo}, // [3] WHITE HEAVY CHECK MARK..TAPE DRIVE + {0x2708, 0x2709, prID, gcSo}, // [2] AIRPLANE..ENVELOPE + {0x270A, 0x270D, prEB, gcSo}, // [4] RAISED FIST..WRITING HAND + {0x270E, 0x2756, prAL, gcSo}, // [73] LOWER RIGHT PENCIL..BLACK DIAMOND MINUS WHITE X + {0x2757, 0x2757, prAI, gcSo}, // HEAVY EXCLAMATION MARK SYMBOL + {0x2758, 0x275A, prAL, gcSo}, // [3] LIGHT VERTICAL BAR..HEAVY VERTICAL BAR + {0x275B, 0x2760, prQU, gcSo}, // [6] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x2761, 0x2761, prAL, gcSo}, // CURVED STEM PARAGRAPH SIGN ORNAMENT + {0x2762, 0x2763, prEX, gcSo}, // [2] HEAVY EXCLAMATION MARK ORNAMENT..HEAVY HEART EXCLAMATION MARK ORNAMENT + {0x2764, 0x2764, prID, gcSo}, // HEAVY BLACK HEART + {0x2765, 0x2767, prAL, gcSo}, // [3] ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2768, 0x2768, prOP, gcPs}, // MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prCL, gcPe}, // MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prOP, gcPs}, // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prCL, gcPe}, // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prOP, gcPs}, // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prCL, gcPe}, // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prOP, gcPs}, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prCL, gcPe}, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prOP, gcPs}, // MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prCL, gcPe}, // MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x2776, 0x2793, prAI, gcNo}, // [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + {0x2794, 0x27BF, prAL, gcSo}, // [44] HEAVY WIDE-HEADED RIGHTWARDS ARROW..DOUBLE CURLY LOOP + {0x27C0, 0x27C4, prAL, gcSm}, // [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET + {0x27C5, 0x27C5, prOP, gcPs}, // LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prCL, gcPe}, // RIGHT S-SHAPED BAG DELIMITER + {0x27C7, 0x27E5, prAL, gcSm}, // [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK + {0x27E6, 0x27E6, prOP, gcPs}, // MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prOP, gcPs}, // MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prCL, gcPe}, // MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prOP, gcPs}, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prCL, gcPe}, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prOP, gcPs}, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prOP, gcPs}, // MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prCL, gcPe}, // MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x27F0, 0x27FF, prAL, gcSm}, // [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW + {0x2800, 0x28FF, prAL, gcSo}, // [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 + {0x2900, 0x297F, prAL, gcSm}, // [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL + {0x2980, 0x2982, prAL, gcSm}, // [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON + {0x2983, 0x2983, prOP, gcPs}, // LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prCL, gcPe}, // RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prOP, gcPs}, // LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prCL, gcPe}, // RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prOP, gcPs}, // Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prCL, gcPe}, // Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prOP, gcPs}, // Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prCL, gcPe}, // Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prOP, gcPs}, // LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prOP, gcPs}, // LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prCL, gcPe}, // RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prOP, gcPs}, // LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prCL, gcPe}, // RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prOP, gcPs}, // DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prCL, gcPe}, // DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prOP, gcPs}, // LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prCL, gcPe}, // RIGHT BLACK TORTOISE SHELL BRACKET + {0x2999, 0x29D7, prAL, gcSm}, // [63] DOTTED FENCE..BLACK HOURGLASS + {0x29D8, 0x29D8, prOP, gcPs}, // LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prCL, gcPe}, // RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prOP, gcPs}, // LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prCL, gcPe}, // RIGHT DOUBLE WIGGLY FENCE + {0x29DC, 0x29FB, prAL, gcSm}, // [32] INCOMPLETE INFINITY..TRIPLE PLUS + {0x29FC, 0x29FC, prOP, gcPs}, // LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prCL, gcPe}, // RIGHT-POINTING CURVED ANGLE BRACKET + {0x29FE, 0x29FF, prAL, gcSm}, // [2] TINY..MINY + {0x2A00, 0x2AFF, prAL, gcSm}, // [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR + {0x2B00, 0x2B2F, prAL, gcSo}, // [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE + {0x2B30, 0x2B44, prAL, gcSm}, // [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET + {0x2B45, 0x2B46, prAL, gcSo}, // [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW + {0x2B47, 0x2B4C, prAL, gcSm}, // [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + {0x2B4D, 0x2B54, prAL, gcSo}, // [8] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..WHITE RIGHT-POINTING PENTAGON + {0x2B55, 0x2B59, prAI, gcSo}, // [5] HEAVY LARGE CIRCLE..HEAVY CIRCLED SALTIRE + {0x2B5A, 0x2B73, prAL, gcSo}, // [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR + {0x2B76, 0x2B95, prAL, gcSo}, // [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW + {0x2B97, 0x2BFF, prAL, gcSo}, // [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL + {0x2C00, 0x2C5F, prAL, gcLC}, // [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C7B, prAL, gcLC}, // [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prAL, gcLm}, // [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C7F, prAL, gcLu}, // [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL + {0x2C80, 0x2CE4, prAL, gcLC}, // [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI + {0x2CE5, 0x2CEA, prAL, gcSo}, // [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA + {0x2CEB, 0x2CEE, prAL, gcLC}, // [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prCM, gcMn}, // [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prAL, gcLC}, // [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2CF9, 0x2CF9, prEX, gcPo}, // COPTIC OLD NUBIAN FULL STOP + {0x2CFA, 0x2CFC, prBA, gcPo}, // [3] COPTIC OLD NUBIAN DIRECT QUESTION MARK..COPTIC OLD NUBIAN VERSE DIVIDER + {0x2CFD, 0x2CFD, prAL, gcNo}, // COPTIC FRACTION ONE HALF + {0x2CFE, 0x2CFE, prEX, gcPo}, // COPTIC FULL STOP + {0x2CFF, 0x2CFF, prBA, gcPo}, // COPTIC MORPHOLOGICAL DIVIDER + {0x2D00, 0x2D25, prAL, gcLl}, // [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prAL, gcLl}, // GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prAL, gcLl}, // GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prAL, gcLo}, // [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prAL, gcLm}, // TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D70, 0x2D70, prBA, gcPo}, // TIFINAGH SEPARATOR MARK + {0x2D7F, 0x2D7F, prCM, gcMn}, // TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prAL, gcLo}, // [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prCM, gcMn}, // [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prQU, gcPo}, // [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prQU, gcPi}, // LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prQU, gcPf}, // RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prQU, gcPi}, // LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prQU, gcPf}, // RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prQU, gcPo}, // [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prQU, gcPi}, // LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prQU, gcPf}, // RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prQU, gcPo}, // RAISED SQUARE + {0x2E0C, 0x2E0C, prQU, gcPi}, // LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prQU, gcPf}, // RIGHT RAISED OMISSION BRACKET + {0x2E0E, 0x2E15, prBA, gcPo}, // [8] EDITORIAL CORONIS..UPWARDS ANCORA + {0x2E16, 0x2E16, prAL, gcPo}, // DOTTED RIGHT-POINTING ANGLE + {0x2E17, 0x2E17, prBA, gcPd}, // DOUBLE OBLIQUE HYPHEN + {0x2E18, 0x2E18, prOP, gcPo}, // INVERTED INTERROBANG + {0x2E19, 0x2E19, prBA, gcPo}, // PALM BRANCH + {0x2E1A, 0x2E1A, prAL, gcPd}, // HYPHEN WITH DIAERESIS + {0x2E1B, 0x2E1B, prAL, gcPo}, // TILDE WITH RING ABOVE + {0x2E1C, 0x2E1C, prQU, gcPi}, // LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prQU, gcPf}, // RIGHT LOW PARAPHRASE BRACKET + {0x2E1E, 0x2E1F, prAL, gcPo}, // [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW + {0x2E20, 0x2E20, prQU, gcPi}, // LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prQU, gcPf}, // RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prOP, gcPs}, // TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prCL, gcPe}, // TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prOP, gcPs}, // BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prCL, gcPe}, // BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prOP, gcPs}, // LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prCL, gcPe}, // RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prOP, gcPs}, // LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prCL, gcPe}, // RIGHT DOUBLE PARENTHESIS + {0x2E2A, 0x2E2D, prBA, gcPo}, // [4] TWO DOTS OVER ONE DOT PUNCTUATION..FIVE DOT MARK + {0x2E2E, 0x2E2E, prEX, gcPo}, // REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prAL, gcLm}, // VERTICAL TILDE + {0x2E30, 0x2E31, prBA, gcPo}, // [2] RING POINT..WORD SEPARATOR MIDDLE DOT + {0x2E32, 0x2E32, prAL, gcPo}, // TURNED COMMA + {0x2E33, 0x2E34, prBA, gcPo}, // [2] RAISED DOT..RAISED COMMA + {0x2E35, 0x2E39, prAL, gcPo}, // [5] TURNED SEMICOLON..TOP HALF SECTION SIGN + {0x2E3A, 0x2E3B, prB2, gcPd}, // [2] TWO-EM DASH..THREE-EM DASH + {0x2E3C, 0x2E3E, prBA, gcPo}, // [3] STENOGRAPHIC FULL STOP..WIGGLY VERTICAL LINE + {0x2E3F, 0x2E3F, prAL, gcPo}, // CAPITULUM + {0x2E40, 0x2E40, prBA, gcPd}, // DOUBLE HYPHEN + {0x2E41, 0x2E41, prBA, gcPo}, // REVERSED COMMA + {0x2E42, 0x2E42, prOP, gcPs}, // DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E43, 0x2E4A, prBA, gcPo}, // [8] DASH WITH LEFT UPTURN..DOTTED SOLIDUS + {0x2E4B, 0x2E4B, prAL, gcPo}, // TRIPLE DAGGER + {0x2E4C, 0x2E4C, prBA, gcPo}, // MEDIEVAL COMMA + {0x2E4D, 0x2E4D, prAL, gcPo}, // PARAGRAPHUS MARK + {0x2E4E, 0x2E4F, prBA, gcPo}, // [2] PUNCTUS ELEVATUS MARK..CORNISH VERSE DIVIDER + {0x2E50, 0x2E51, prAL, gcSo}, // [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR + {0x2E52, 0x2E52, prAL, gcPo}, // TIRONIAN SIGN CAPITAL ET + {0x2E53, 0x2E54, prEX, gcPo}, // [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prOP, gcPs}, // LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prOP, gcPs}, // LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prOP, gcPs}, // TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prCL, gcPe}, // TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prOP, gcPs}, // BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prCL, gcPe}, // BOTTOM HALF RIGHT PARENTHESIS + {0x2E5D, 0x2E5D, prBA, gcPd}, // OBLIQUE HYPHEN + {0x2E80, 0x2E99, prID, gcSo}, // [26] CJK RADICAL REPEAT..CJK RADICAL RAP + {0x2E9B, 0x2EF3, prID, gcSo}, // [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE + {0x2F00, 0x2FD5, prID, gcSo}, // [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE + {0x2FF0, 0x2FFB, prID, gcSo}, // [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID + {0x3000, 0x3000, prBA, gcZs}, // IDEOGRAPHIC SPACE + {0x3001, 0x3002, prCL, gcPo}, // [2] IDEOGRAPHIC COMMA..IDEOGRAPHIC FULL STOP + {0x3003, 0x3003, prID, gcPo}, // DITTO MARK + {0x3004, 0x3004, prID, gcSo}, // JAPANESE INDUSTRIAL STANDARD SYMBOL + {0x3005, 0x3005, prNS, gcLm}, // IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prID, gcLo}, // IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prID, gcNl}, // IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prOP, gcPs}, // LEFT ANGLE BRACKET + {0x3009, 0x3009, prCL, gcPe}, // RIGHT ANGLE BRACKET + {0x300A, 0x300A, prOP, gcPs}, // LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prCL, gcPe}, // RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prOP, gcPs}, // LEFT CORNER BRACKET + {0x300D, 0x300D, prCL, gcPe}, // RIGHT CORNER BRACKET + {0x300E, 0x300E, prOP, gcPs}, // LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prCL, gcPe}, // RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prOP, gcPs}, // LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prCL, gcPe}, // RIGHT BLACK LENTICULAR BRACKET + {0x3012, 0x3013, prID, gcSo}, // [2] POSTAL MARK..GETA MARK + {0x3014, 0x3014, prOP, gcPs}, // LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prCL, gcPe}, // RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prOP, gcPs}, // LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prCL, gcPe}, // RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prOP, gcPs}, // LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prCL, gcPe}, // RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prOP, gcPs}, // LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prCL, gcPe}, // RIGHT WHITE SQUARE BRACKET + {0x301C, 0x301C, prNS, gcPd}, // WAVE DASH + {0x301D, 0x301D, prOP, gcPs}, // REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prCL, gcPe}, // [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3020, 0x3020, prID, gcSo}, // POSTAL MARK FACE + {0x3021, 0x3029, prID, gcNl}, // [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prCM, gcMn}, // [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prCM, gcMc}, // [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prID, gcPd}, // WAVY DASH + {0x3031, 0x3034, prID, gcLm}, // [4] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF + {0x3035, 0x3035, prCM, gcLm}, // VERTICAL KANA REPEAT MARK LOWER HALF + {0x3036, 0x3037, prID, gcSo}, // [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL + {0x3038, 0x303A, prID, gcNl}, // [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prNS, gcLm}, // VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prNS, gcLo}, // MASU MARK + {0x303D, 0x303D, prID, gcPo}, // PART ALTERNATION MARK + {0x303E, 0x303F, prID, gcSo}, // [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE + {0x3041, 0x3041, prCJ, gcLo}, // HIRAGANA LETTER SMALL A + {0x3042, 0x3042, prID, gcLo}, // HIRAGANA LETTER A + {0x3043, 0x3043, prCJ, gcLo}, // HIRAGANA LETTER SMALL I + {0x3044, 0x3044, prID, gcLo}, // HIRAGANA LETTER I + {0x3045, 0x3045, prCJ, gcLo}, // HIRAGANA LETTER SMALL U + {0x3046, 0x3046, prID, gcLo}, // HIRAGANA LETTER U + {0x3047, 0x3047, prCJ, gcLo}, // HIRAGANA LETTER SMALL E + {0x3048, 0x3048, prID, gcLo}, // HIRAGANA LETTER E + {0x3049, 0x3049, prCJ, gcLo}, // HIRAGANA LETTER SMALL O + {0x304A, 0x3062, prID, gcLo}, // [25] HIRAGANA LETTER O..HIRAGANA LETTER DI + {0x3063, 0x3063, prCJ, gcLo}, // HIRAGANA LETTER SMALL TU + {0x3064, 0x3082, prID, gcLo}, // [31] HIRAGANA LETTER TU..HIRAGANA LETTER MO + {0x3083, 0x3083, prCJ, gcLo}, // HIRAGANA LETTER SMALL YA + {0x3084, 0x3084, prID, gcLo}, // HIRAGANA LETTER YA + {0x3085, 0x3085, prCJ, gcLo}, // HIRAGANA LETTER SMALL YU + {0x3086, 0x3086, prID, gcLo}, // HIRAGANA LETTER YU + {0x3087, 0x3087, prCJ, gcLo}, // HIRAGANA LETTER SMALL YO + {0x3088, 0x308D, prID, gcLo}, // [6] HIRAGANA LETTER YO..HIRAGANA LETTER RO + {0x308E, 0x308E, prCJ, gcLo}, // HIRAGANA LETTER SMALL WA + {0x308F, 0x3094, prID, gcLo}, // [6] HIRAGANA LETTER WA..HIRAGANA LETTER VU + {0x3095, 0x3096, prCJ, gcLo}, // [2] HIRAGANA LETTER SMALL KA..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prCM, gcMn}, // [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prNS, gcSk}, // [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prNS, gcLm}, // [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prID, gcLo}, // HIRAGANA DIGRAPH YORI + {0x30A0, 0x30A0, prNS, gcPd}, // KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30A1, prCJ, gcLo}, // KATAKANA LETTER SMALL A + {0x30A2, 0x30A2, prID, gcLo}, // KATAKANA LETTER A + {0x30A3, 0x30A3, prCJ, gcLo}, // KATAKANA LETTER SMALL I + {0x30A4, 0x30A4, prID, gcLo}, // KATAKANA LETTER I + {0x30A5, 0x30A5, prCJ, gcLo}, // KATAKANA LETTER SMALL U + {0x30A6, 0x30A6, prID, gcLo}, // KATAKANA LETTER U + {0x30A7, 0x30A7, prCJ, gcLo}, // KATAKANA LETTER SMALL E + {0x30A8, 0x30A8, prID, gcLo}, // KATAKANA LETTER E + {0x30A9, 0x30A9, prCJ, gcLo}, // KATAKANA LETTER SMALL O + {0x30AA, 0x30C2, prID, gcLo}, // [25] KATAKANA LETTER O..KATAKANA LETTER DI + {0x30C3, 0x30C3, prCJ, gcLo}, // KATAKANA LETTER SMALL TU + {0x30C4, 0x30E2, prID, gcLo}, // [31] KATAKANA LETTER TU..KATAKANA LETTER MO + {0x30E3, 0x30E3, prCJ, gcLo}, // KATAKANA LETTER SMALL YA + {0x30E4, 0x30E4, prID, gcLo}, // KATAKANA LETTER YA + {0x30E5, 0x30E5, prCJ, gcLo}, // KATAKANA LETTER SMALL YU + {0x30E6, 0x30E6, prID, gcLo}, // KATAKANA LETTER YU + {0x30E7, 0x30E7, prCJ, gcLo}, // KATAKANA LETTER SMALL YO + {0x30E8, 0x30ED, prID, gcLo}, // [6] KATAKANA LETTER YO..KATAKANA LETTER RO + {0x30EE, 0x30EE, prCJ, gcLo}, // KATAKANA LETTER SMALL WA + {0x30EF, 0x30F4, prID, gcLo}, // [6] KATAKANA LETTER WA..KATAKANA LETTER VU + {0x30F5, 0x30F6, prCJ, gcLo}, // [2] KATAKANA LETTER SMALL KA..KATAKANA LETTER SMALL KE + {0x30F7, 0x30FA, prID, gcLo}, // [4] KATAKANA LETTER VA..KATAKANA LETTER VO + {0x30FB, 0x30FB, prNS, gcPo}, // KATAKANA MIDDLE DOT + {0x30FC, 0x30FC, prCJ, gcLm}, // KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0x30FD, 0x30FE, prNS, gcLm}, // [2] KATAKANA ITERATION MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prID, gcLo}, // KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prID, gcLo}, // [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prID, gcLo}, // [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x3190, 0x3191, prID, gcSo}, // [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK + {0x3192, 0x3195, prID, gcNo}, // [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK + {0x3196, 0x319F, prID, gcSo}, // [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK + {0x31A0, 0x31BF, prID, gcLo}, // [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31C0, 0x31E3, prID, gcSo}, // [36] CJK STROKE T..CJK STROKE Q + {0x31F0, 0x31FF, prCJ, gcLo}, // [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3200, 0x321E, prID, gcSo}, // [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU + {0x3220, 0x3229, prID, gcNo}, // [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN + {0x322A, 0x3247, prID, gcSo}, // [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO + {0x3248, 0x324F, prAI, gcNo}, // [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE + {0x3250, 0x3250, prID, gcSo}, // PARTNERSHIP SIGN + {0x3251, 0x325F, prID, gcNo}, // [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE + {0x3260, 0x327F, prID, gcSo}, // [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL + {0x3280, 0x3289, prID, gcNo}, // [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN + {0x328A, 0x32B0, prID, gcSo}, // [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT + {0x32B1, 0x32BF, prID, gcNo}, // [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY + {0x32C0, 0x32FF, prID, gcSo}, // [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA + {0x3300, 0x33FF, prID, gcSo}, // [256] SQUARE APAATO..SQUARE GAL + {0x3400, 0x4DBF, prID, gcLo}, // [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4DC0, 0x4DFF, prAL, gcSo}, // [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION + {0x4E00, 0x9FFF, prID, gcLo}, // [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF + {0xA000, 0xA014, prID, gcLo}, // [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prNS, gcLm}, // YI SYLLABLE WU + {0xA016, 0xA48C, prID, gcLo}, // [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA490, 0xA4C6, prID, gcSo}, // [55] YI RADICAL QOT..YI RADICAL KE + {0xA4D0, 0xA4F7, prAL, gcLo}, // [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prAL, gcLm}, // [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FE, 0xA4FF, prBA, gcPo}, // [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prAL, gcLo}, // [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prAL, gcLm}, // VAI SYLLABLE LENGTHENER + {0xA60D, 0xA60D, prBA, gcPo}, // VAI COMMA + {0xA60E, 0xA60E, prEX, gcPo}, // VAI FULL STOP + {0xA60F, 0xA60F, prBA, gcPo}, // VAI QUESTION MARK + {0xA610, 0xA61F, prAL, gcLo}, // [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNU, gcNd}, // [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prAL, gcLo}, // [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prAL, gcLC}, // [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prAL, gcLo}, // CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prCM, gcMn}, // COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prCM, gcMe}, // [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA673, 0xA673, prAL, gcPo}, // SLAVONIC ASTERISK + {0xA674, 0xA67D, prCM, gcMn}, // [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67E, 0xA67E, prAL, gcPo}, // CYRILLIC KAVYKA + {0xA67F, 0xA67F, prAL, gcLm}, // CYRILLIC PAYEROK + {0xA680, 0xA69B, prAL, gcLC}, // [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prAL, gcLm}, // [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prCM, gcMn}, // [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prAL, gcLo}, // [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prAL, gcNl}, // [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prCM, gcMn}, // [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F2, 0xA6F2, prAL, gcPo}, // BAMUM NJAEMLI + {0xA6F3, 0xA6F7, prBA, gcPo}, // [5] BAMUM FULL STOP..BAMUM QUESTION MARK + {0xA700, 0xA716, prAL, gcSk}, // [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prAL, gcLm}, // [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prAL, gcSk}, // [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prAL, gcLC}, // [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prAL, gcLm}, // MODIFIER LETTER US + {0xA771, 0xA787, prAL, gcLC}, // [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prAL, gcLm}, // MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prAL, gcSk}, // [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prAL, gcLC}, // [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prAL, gcLo}, // LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prAL, gcLC}, // [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prAL, gcLC}, // [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prAL, gcLl}, // LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prAL, gcLC}, // [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prAL, gcLm}, // [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prAL, gcLC}, // [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prAL, gcLo}, // LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prAL, gcLm}, // [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prAL, gcLl}, // LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA7FF, prAL, gcLo}, // [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M + {0xA800, 0xA801, prAL, gcLo}, // [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prCM, gcMn}, // SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prAL, gcLo}, // [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prCM, gcMn}, // SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prAL, gcLo}, // [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prCM, gcMn}, // SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prAL, gcLo}, // [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prCM, gcMc}, // [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prCM, gcMn}, // [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prCM, gcMc}, // SYLOTI NAGRI VOWEL SIGN OO + {0xA828, 0xA82B, prAL, gcSo}, // [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 + {0xA82C, 0xA82C, prCM, gcMn}, // SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA830, 0xA835, prAL, gcNo}, // [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS + {0xA836, 0xA837, prAL, gcSo}, // [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK + {0xA838, 0xA838, prPO, gcSc}, // NORTH INDIC RUPEE MARK + {0xA839, 0xA839, prAL, gcSo}, // NORTH INDIC QUANTITY MARK + {0xA840, 0xA873, prAL, gcLo}, // [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA874, 0xA875, prBB, gcPo}, // [2] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA DOUBLE HEAD MARK + {0xA876, 0xA877, prEX, gcPo}, // [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prCM, gcMc}, // [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prAL, gcLo}, // [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prCM, gcMc}, // [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prCM, gcMn}, // [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prBA, gcPo}, // [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prNU, gcNd}, // [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prCM, gcMn}, // [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prAL, gcLo}, // [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8F8, 0xA8FA, prAL, gcPo}, // [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET + {0xA8FB, 0xA8FB, prAL, gcLo}, // DEVANAGARI HEADSTROKE + {0xA8FC, 0xA8FC, prBB, gcPo}, // DEVANAGARI SIGN SIDDHAM + {0xA8FD, 0xA8FE, prAL, gcLo}, // [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prCM, gcMn}, // DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNU, gcNd}, // [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prAL, gcLo}, // [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prCM, gcMn}, // [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92E, 0xA92F, prBA, gcPo}, // [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA + {0xA930, 0xA946, prAL, gcLo}, // [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prCM, gcMn}, // [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prCM, gcMc}, // [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA95F, 0xA95F, prAL, gcPo}, // REJANG SECTION MARK + {0xA960, 0xA97C, prJL, gcLo}, // [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prCM, gcMn}, // [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prCM, gcMc}, // JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prAL, gcLo}, // [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prCM, gcMn}, // JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prCM, gcMn}, // [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prCM, gcMn}, // [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prCM, gcMc}, // [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C1, 0xA9C6, prAL, gcPo}, // [6] JAVANESE LEFT RERENGGAN..JAVANESE PADA WINDU + {0xA9C7, 0xA9C9, prBA, gcPo}, // [3] JAVANESE PADA PANGKAT..JAVANESE PADA LUNGSI + {0xA9CA, 0xA9CD, prAL, gcPo}, // [4] JAVANESE PADA ADEG..JAVANESE TURNED PADA PISELEH + {0xA9CF, 0xA9CF, prAL, gcLm}, // JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNU, gcNd}, // [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9DE, 0xA9DF, prAL, gcPo}, // [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN + {0xA9E0, 0xA9E4, prSA, gcLo}, // [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prSA, gcMn}, // MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prSA, gcLm}, // MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prSA, gcLo}, // [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prNU, gcNd}, // [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prSA, gcLo}, // [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prAL, gcLo}, // [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prCM, gcMn}, // [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prCM, gcMc}, // [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prCM, gcMn}, // [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prCM, gcMc}, // [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prCM, gcMn}, // [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prAL, gcLo}, // [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prAL, gcLo}, // [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prCM, gcMc}, // CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNU, gcNd}, // [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5C, 0xAA5C, prAL, gcPo}, // CHAM PUNCTUATION SPIRAL + {0xAA5D, 0xAA5F, prBA, gcPo}, // [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prSA, gcLo}, // [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prSA, gcLm}, // MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prSA, gcLo}, // [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA77, 0xAA79, prSA, gcSo}, // [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO + {0xAA7A, 0xAA7A, prSA, gcLo}, // MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prSA, gcMc}, // MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prSA, gcMn}, // MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prSA, gcMc}, // MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAA7F, prSA, gcLo}, // [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA + {0xAA80, 0xAAAF, prSA, gcLo}, // [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prSA, gcMn}, // TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prSA, gcLo}, // TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prSA, gcMn}, // [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prSA, gcLo}, // [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prSA, gcMn}, // [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prSA, gcLo}, // [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prSA, gcMn}, // [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prSA, gcLo}, // TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prSA, gcMn}, // TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prSA, gcLo}, // TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prSA, gcLo}, // [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prSA, gcLm}, // TAI VIET SYMBOL SAM + {0xAADE, 0xAADF, prSA, gcPo}, // [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI + {0xAAE0, 0xAAEA, prAL, gcLo}, // [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prCM, gcMn}, // [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prBA, gcPo}, // [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prAL, gcLo}, // MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prAL, gcLm}, // [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prCM, gcMn}, // MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prAL, gcLl}, // [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prAL, gcSk}, // MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prAL, gcLm}, // [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prAL, gcLl}, // [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prAL, gcLm}, // MODIFIER LETTER SMALL TURNED W + {0xAB6A, 0xAB6B, prAL, gcSk}, // [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK + {0xAB70, 0xABBF, prAL, gcLl}, // [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prAL, gcLo}, // [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prBA, gcPo}, // MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prCM, gcMc}, // MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prCM, gcMn}, // MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNU, gcNd}, // [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xAC00, prH2, gcLo}, // HANGUL SYLLABLE GA + {0xAC01, 0xAC1B, prH3, gcLo}, // [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH + {0xAC1C, 0xAC1C, prH2, gcLo}, // HANGUL SYLLABLE GAE + {0xAC1D, 0xAC37, prH3, gcLo}, // [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH + {0xAC38, 0xAC38, prH2, gcLo}, // HANGUL SYLLABLE GYA + {0xAC39, 0xAC53, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH + {0xAC54, 0xAC54, prH2, gcLo}, // HANGUL SYLLABLE GYAE + {0xAC55, 0xAC6F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH + {0xAC70, 0xAC70, prH2, gcLo}, // HANGUL SYLLABLE GEO + {0xAC71, 0xAC8B, prH3, gcLo}, // [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH + {0xAC8C, 0xAC8C, prH2, gcLo}, // HANGUL SYLLABLE GE + {0xAC8D, 0xACA7, prH3, gcLo}, // [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH + {0xACA8, 0xACA8, prH2, gcLo}, // HANGUL SYLLABLE GYEO + {0xACA9, 0xACC3, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH + {0xACC4, 0xACC4, prH2, gcLo}, // HANGUL SYLLABLE GYE + {0xACC5, 0xACDF, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH + {0xACE0, 0xACE0, prH2, gcLo}, // HANGUL SYLLABLE GO + {0xACE1, 0xACFB, prH3, gcLo}, // [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH + {0xACFC, 0xACFC, prH2, gcLo}, // HANGUL SYLLABLE GWA + {0xACFD, 0xAD17, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH + {0xAD18, 0xAD18, prH2, gcLo}, // HANGUL SYLLABLE GWAE + {0xAD19, 0xAD33, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH + {0xAD34, 0xAD34, prH2, gcLo}, // HANGUL SYLLABLE GOE + {0xAD35, 0xAD4F, prH3, gcLo}, // [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH + {0xAD50, 0xAD50, prH2, gcLo}, // HANGUL SYLLABLE GYO + {0xAD51, 0xAD6B, prH3, gcLo}, // [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH + {0xAD6C, 0xAD6C, prH2, gcLo}, // HANGUL SYLLABLE GU + {0xAD6D, 0xAD87, prH3, gcLo}, // [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH + {0xAD88, 0xAD88, prH2, gcLo}, // HANGUL SYLLABLE GWEO + {0xAD89, 0xADA3, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH + {0xADA4, 0xADA4, prH2, gcLo}, // HANGUL SYLLABLE GWE + {0xADA5, 0xADBF, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH + {0xADC0, 0xADC0, prH2, gcLo}, // HANGUL SYLLABLE GWI + {0xADC1, 0xADDB, prH3, gcLo}, // [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH + {0xADDC, 0xADDC, prH2, gcLo}, // HANGUL SYLLABLE GYU + {0xADDD, 0xADF7, prH3, gcLo}, // [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH + {0xADF8, 0xADF8, prH2, gcLo}, // HANGUL SYLLABLE GEU + {0xADF9, 0xAE13, prH3, gcLo}, // [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH + {0xAE14, 0xAE14, prH2, gcLo}, // HANGUL SYLLABLE GYI + {0xAE15, 0xAE2F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH + {0xAE30, 0xAE30, prH2, gcLo}, // HANGUL SYLLABLE GI + {0xAE31, 0xAE4B, prH3, gcLo}, // [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH + {0xAE4C, 0xAE4C, prH2, gcLo}, // HANGUL SYLLABLE GGA + {0xAE4D, 0xAE67, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH + {0xAE68, 0xAE68, prH2, gcLo}, // HANGUL SYLLABLE GGAE + {0xAE69, 0xAE83, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH + {0xAE84, 0xAE84, prH2, gcLo}, // HANGUL SYLLABLE GGYA + {0xAE85, 0xAE9F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH + {0xAEA0, 0xAEA0, prH2, gcLo}, // HANGUL SYLLABLE GGYAE + {0xAEA1, 0xAEBB, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH + {0xAEBC, 0xAEBC, prH2, gcLo}, // HANGUL SYLLABLE GGEO + {0xAEBD, 0xAED7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH + {0xAED8, 0xAED8, prH2, gcLo}, // HANGUL SYLLABLE GGE + {0xAED9, 0xAEF3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH + {0xAEF4, 0xAEF4, prH2, gcLo}, // HANGUL SYLLABLE GGYEO + {0xAEF5, 0xAF0F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH + {0xAF10, 0xAF10, prH2, gcLo}, // HANGUL SYLLABLE GGYE + {0xAF11, 0xAF2B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH + {0xAF2C, 0xAF2C, prH2, gcLo}, // HANGUL SYLLABLE GGO + {0xAF2D, 0xAF47, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH + {0xAF48, 0xAF48, prH2, gcLo}, // HANGUL SYLLABLE GGWA + {0xAF49, 0xAF63, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH + {0xAF64, 0xAF64, prH2, gcLo}, // HANGUL SYLLABLE GGWAE + {0xAF65, 0xAF7F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH + {0xAF80, 0xAF80, prH2, gcLo}, // HANGUL SYLLABLE GGOE + {0xAF81, 0xAF9B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH + {0xAF9C, 0xAF9C, prH2, gcLo}, // HANGUL SYLLABLE GGYO + {0xAF9D, 0xAFB7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH + {0xAFB8, 0xAFB8, prH2, gcLo}, // HANGUL SYLLABLE GGU + {0xAFB9, 0xAFD3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH + {0xAFD4, 0xAFD4, prH2, gcLo}, // HANGUL SYLLABLE GGWEO + {0xAFD5, 0xAFEF, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH + {0xAFF0, 0xAFF0, prH2, gcLo}, // HANGUL SYLLABLE GGWE + {0xAFF1, 0xB00B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH + {0xB00C, 0xB00C, prH2, gcLo}, // HANGUL SYLLABLE GGWI + {0xB00D, 0xB027, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH + {0xB028, 0xB028, prH2, gcLo}, // HANGUL SYLLABLE GGYU + {0xB029, 0xB043, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH + {0xB044, 0xB044, prH2, gcLo}, // HANGUL SYLLABLE GGEU + {0xB045, 0xB05F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH + {0xB060, 0xB060, prH2, gcLo}, // HANGUL SYLLABLE GGYI + {0xB061, 0xB07B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH + {0xB07C, 0xB07C, prH2, gcLo}, // HANGUL SYLLABLE GGI + {0xB07D, 0xB097, prH3, gcLo}, // [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH + {0xB098, 0xB098, prH2, gcLo}, // HANGUL SYLLABLE NA + {0xB099, 0xB0B3, prH3, gcLo}, // [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH + {0xB0B4, 0xB0B4, prH2, gcLo}, // HANGUL SYLLABLE NAE + {0xB0B5, 0xB0CF, prH3, gcLo}, // [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH + {0xB0D0, 0xB0D0, prH2, gcLo}, // HANGUL SYLLABLE NYA + {0xB0D1, 0xB0EB, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH + {0xB0EC, 0xB0EC, prH2, gcLo}, // HANGUL SYLLABLE NYAE + {0xB0ED, 0xB107, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH + {0xB108, 0xB108, prH2, gcLo}, // HANGUL SYLLABLE NEO + {0xB109, 0xB123, prH3, gcLo}, // [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH + {0xB124, 0xB124, prH2, gcLo}, // HANGUL SYLLABLE NE + {0xB125, 0xB13F, prH3, gcLo}, // [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH + {0xB140, 0xB140, prH2, gcLo}, // HANGUL SYLLABLE NYEO + {0xB141, 0xB15B, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH + {0xB15C, 0xB15C, prH2, gcLo}, // HANGUL SYLLABLE NYE + {0xB15D, 0xB177, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH + {0xB178, 0xB178, prH2, gcLo}, // HANGUL SYLLABLE NO + {0xB179, 0xB193, prH3, gcLo}, // [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH + {0xB194, 0xB194, prH2, gcLo}, // HANGUL SYLLABLE NWA + {0xB195, 0xB1AF, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH + {0xB1B0, 0xB1B0, prH2, gcLo}, // HANGUL SYLLABLE NWAE + {0xB1B1, 0xB1CB, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH + {0xB1CC, 0xB1CC, prH2, gcLo}, // HANGUL SYLLABLE NOE + {0xB1CD, 0xB1E7, prH3, gcLo}, // [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH + {0xB1E8, 0xB1E8, prH2, gcLo}, // HANGUL SYLLABLE NYO + {0xB1E9, 0xB203, prH3, gcLo}, // [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH + {0xB204, 0xB204, prH2, gcLo}, // HANGUL SYLLABLE NU + {0xB205, 0xB21F, prH3, gcLo}, // [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH + {0xB220, 0xB220, prH2, gcLo}, // HANGUL SYLLABLE NWEO + {0xB221, 0xB23B, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH + {0xB23C, 0xB23C, prH2, gcLo}, // HANGUL SYLLABLE NWE + {0xB23D, 0xB257, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH + {0xB258, 0xB258, prH2, gcLo}, // HANGUL SYLLABLE NWI + {0xB259, 0xB273, prH3, gcLo}, // [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH + {0xB274, 0xB274, prH2, gcLo}, // HANGUL SYLLABLE NYU + {0xB275, 0xB28F, prH3, gcLo}, // [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH + {0xB290, 0xB290, prH2, gcLo}, // HANGUL SYLLABLE NEU + {0xB291, 0xB2AB, prH3, gcLo}, // [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH + {0xB2AC, 0xB2AC, prH2, gcLo}, // HANGUL SYLLABLE NYI + {0xB2AD, 0xB2C7, prH3, gcLo}, // [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH + {0xB2C8, 0xB2C8, prH2, gcLo}, // HANGUL SYLLABLE NI + {0xB2C9, 0xB2E3, prH3, gcLo}, // [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH + {0xB2E4, 0xB2E4, prH2, gcLo}, // HANGUL SYLLABLE DA + {0xB2E5, 0xB2FF, prH3, gcLo}, // [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH + {0xB300, 0xB300, prH2, gcLo}, // HANGUL SYLLABLE DAE + {0xB301, 0xB31B, prH3, gcLo}, // [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH + {0xB31C, 0xB31C, prH2, gcLo}, // HANGUL SYLLABLE DYA + {0xB31D, 0xB337, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH + {0xB338, 0xB338, prH2, gcLo}, // HANGUL SYLLABLE DYAE + {0xB339, 0xB353, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH + {0xB354, 0xB354, prH2, gcLo}, // HANGUL SYLLABLE DEO + {0xB355, 0xB36F, prH3, gcLo}, // [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH + {0xB370, 0xB370, prH2, gcLo}, // HANGUL SYLLABLE DE + {0xB371, 0xB38B, prH3, gcLo}, // [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH + {0xB38C, 0xB38C, prH2, gcLo}, // HANGUL SYLLABLE DYEO + {0xB38D, 0xB3A7, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH + {0xB3A8, 0xB3A8, prH2, gcLo}, // HANGUL SYLLABLE DYE + {0xB3A9, 0xB3C3, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH + {0xB3C4, 0xB3C4, prH2, gcLo}, // HANGUL SYLLABLE DO + {0xB3C5, 0xB3DF, prH3, gcLo}, // [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH + {0xB3E0, 0xB3E0, prH2, gcLo}, // HANGUL SYLLABLE DWA + {0xB3E1, 0xB3FB, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH + {0xB3FC, 0xB3FC, prH2, gcLo}, // HANGUL SYLLABLE DWAE + {0xB3FD, 0xB417, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH + {0xB418, 0xB418, prH2, gcLo}, // HANGUL SYLLABLE DOE + {0xB419, 0xB433, prH3, gcLo}, // [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH + {0xB434, 0xB434, prH2, gcLo}, // HANGUL SYLLABLE DYO + {0xB435, 0xB44F, prH3, gcLo}, // [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH + {0xB450, 0xB450, prH2, gcLo}, // HANGUL SYLLABLE DU + {0xB451, 0xB46B, prH3, gcLo}, // [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH + {0xB46C, 0xB46C, prH2, gcLo}, // HANGUL SYLLABLE DWEO + {0xB46D, 0xB487, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH + {0xB488, 0xB488, prH2, gcLo}, // HANGUL SYLLABLE DWE + {0xB489, 0xB4A3, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH + {0xB4A4, 0xB4A4, prH2, gcLo}, // HANGUL SYLLABLE DWI + {0xB4A5, 0xB4BF, prH3, gcLo}, // [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH + {0xB4C0, 0xB4C0, prH2, gcLo}, // HANGUL SYLLABLE DYU + {0xB4C1, 0xB4DB, prH3, gcLo}, // [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH + {0xB4DC, 0xB4DC, prH2, gcLo}, // HANGUL SYLLABLE DEU + {0xB4DD, 0xB4F7, prH3, gcLo}, // [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH + {0xB4F8, 0xB4F8, prH2, gcLo}, // HANGUL SYLLABLE DYI + {0xB4F9, 0xB513, prH3, gcLo}, // [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH + {0xB514, 0xB514, prH2, gcLo}, // HANGUL SYLLABLE DI + {0xB515, 0xB52F, prH3, gcLo}, // [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH + {0xB530, 0xB530, prH2, gcLo}, // HANGUL SYLLABLE DDA + {0xB531, 0xB54B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH + {0xB54C, 0xB54C, prH2, gcLo}, // HANGUL SYLLABLE DDAE + {0xB54D, 0xB567, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH + {0xB568, 0xB568, prH2, gcLo}, // HANGUL SYLLABLE DDYA + {0xB569, 0xB583, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH + {0xB584, 0xB584, prH2, gcLo}, // HANGUL SYLLABLE DDYAE + {0xB585, 0xB59F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH + {0xB5A0, 0xB5A0, prH2, gcLo}, // HANGUL SYLLABLE DDEO + {0xB5A1, 0xB5BB, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH + {0xB5BC, 0xB5BC, prH2, gcLo}, // HANGUL SYLLABLE DDE + {0xB5BD, 0xB5D7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH + {0xB5D8, 0xB5D8, prH2, gcLo}, // HANGUL SYLLABLE DDYEO + {0xB5D9, 0xB5F3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH + {0xB5F4, 0xB5F4, prH2, gcLo}, // HANGUL SYLLABLE DDYE + {0xB5F5, 0xB60F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH + {0xB610, 0xB610, prH2, gcLo}, // HANGUL SYLLABLE DDO + {0xB611, 0xB62B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH + {0xB62C, 0xB62C, prH2, gcLo}, // HANGUL SYLLABLE DDWA + {0xB62D, 0xB647, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH + {0xB648, 0xB648, prH2, gcLo}, // HANGUL SYLLABLE DDWAE + {0xB649, 0xB663, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH + {0xB664, 0xB664, prH2, gcLo}, // HANGUL SYLLABLE DDOE + {0xB665, 0xB67F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH + {0xB680, 0xB680, prH2, gcLo}, // HANGUL SYLLABLE DDYO + {0xB681, 0xB69B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH + {0xB69C, 0xB69C, prH2, gcLo}, // HANGUL SYLLABLE DDU + {0xB69D, 0xB6B7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH + {0xB6B8, 0xB6B8, prH2, gcLo}, // HANGUL SYLLABLE DDWEO + {0xB6B9, 0xB6D3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH + {0xB6D4, 0xB6D4, prH2, gcLo}, // HANGUL SYLLABLE DDWE + {0xB6D5, 0xB6EF, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH + {0xB6F0, 0xB6F0, prH2, gcLo}, // HANGUL SYLLABLE DDWI + {0xB6F1, 0xB70B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH + {0xB70C, 0xB70C, prH2, gcLo}, // HANGUL SYLLABLE DDYU + {0xB70D, 0xB727, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH + {0xB728, 0xB728, prH2, gcLo}, // HANGUL SYLLABLE DDEU + {0xB729, 0xB743, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH + {0xB744, 0xB744, prH2, gcLo}, // HANGUL SYLLABLE DDYI + {0xB745, 0xB75F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH + {0xB760, 0xB760, prH2, gcLo}, // HANGUL SYLLABLE DDI + {0xB761, 0xB77B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH + {0xB77C, 0xB77C, prH2, gcLo}, // HANGUL SYLLABLE RA + {0xB77D, 0xB797, prH3, gcLo}, // [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH + {0xB798, 0xB798, prH2, gcLo}, // HANGUL SYLLABLE RAE + {0xB799, 0xB7B3, prH3, gcLo}, // [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH + {0xB7B4, 0xB7B4, prH2, gcLo}, // HANGUL SYLLABLE RYA + {0xB7B5, 0xB7CF, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH + {0xB7D0, 0xB7D0, prH2, gcLo}, // HANGUL SYLLABLE RYAE + {0xB7D1, 0xB7EB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH + {0xB7EC, 0xB7EC, prH2, gcLo}, // HANGUL SYLLABLE REO + {0xB7ED, 0xB807, prH3, gcLo}, // [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH + {0xB808, 0xB808, prH2, gcLo}, // HANGUL SYLLABLE RE + {0xB809, 0xB823, prH3, gcLo}, // [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH + {0xB824, 0xB824, prH2, gcLo}, // HANGUL SYLLABLE RYEO + {0xB825, 0xB83F, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH + {0xB840, 0xB840, prH2, gcLo}, // HANGUL SYLLABLE RYE + {0xB841, 0xB85B, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH + {0xB85C, 0xB85C, prH2, gcLo}, // HANGUL SYLLABLE RO + {0xB85D, 0xB877, prH3, gcLo}, // [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH + {0xB878, 0xB878, prH2, gcLo}, // HANGUL SYLLABLE RWA + {0xB879, 0xB893, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH + {0xB894, 0xB894, prH2, gcLo}, // HANGUL SYLLABLE RWAE + {0xB895, 0xB8AF, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH + {0xB8B0, 0xB8B0, prH2, gcLo}, // HANGUL SYLLABLE ROE + {0xB8B1, 0xB8CB, prH3, gcLo}, // [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH + {0xB8CC, 0xB8CC, prH2, gcLo}, // HANGUL SYLLABLE RYO + {0xB8CD, 0xB8E7, prH3, gcLo}, // [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH + {0xB8E8, 0xB8E8, prH2, gcLo}, // HANGUL SYLLABLE RU + {0xB8E9, 0xB903, prH3, gcLo}, // [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH + {0xB904, 0xB904, prH2, gcLo}, // HANGUL SYLLABLE RWEO + {0xB905, 0xB91F, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH + {0xB920, 0xB920, prH2, gcLo}, // HANGUL SYLLABLE RWE + {0xB921, 0xB93B, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH + {0xB93C, 0xB93C, prH2, gcLo}, // HANGUL SYLLABLE RWI + {0xB93D, 0xB957, prH3, gcLo}, // [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH + {0xB958, 0xB958, prH2, gcLo}, // HANGUL SYLLABLE RYU + {0xB959, 0xB973, prH3, gcLo}, // [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH + {0xB974, 0xB974, prH2, gcLo}, // HANGUL SYLLABLE REU + {0xB975, 0xB98F, prH3, gcLo}, // [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH + {0xB990, 0xB990, prH2, gcLo}, // HANGUL SYLLABLE RYI + {0xB991, 0xB9AB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH + {0xB9AC, 0xB9AC, prH2, gcLo}, // HANGUL SYLLABLE RI + {0xB9AD, 0xB9C7, prH3, gcLo}, // [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH + {0xB9C8, 0xB9C8, prH2, gcLo}, // HANGUL SYLLABLE MA + {0xB9C9, 0xB9E3, prH3, gcLo}, // [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH + {0xB9E4, 0xB9E4, prH2, gcLo}, // HANGUL SYLLABLE MAE + {0xB9E5, 0xB9FF, prH3, gcLo}, // [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH + {0xBA00, 0xBA00, prH2, gcLo}, // HANGUL SYLLABLE MYA + {0xBA01, 0xBA1B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH + {0xBA1C, 0xBA1C, prH2, gcLo}, // HANGUL SYLLABLE MYAE + {0xBA1D, 0xBA37, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH + {0xBA38, 0xBA38, prH2, gcLo}, // HANGUL SYLLABLE MEO + {0xBA39, 0xBA53, prH3, gcLo}, // [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH + {0xBA54, 0xBA54, prH2, gcLo}, // HANGUL SYLLABLE ME + {0xBA55, 0xBA6F, prH3, gcLo}, // [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH + {0xBA70, 0xBA70, prH2, gcLo}, // HANGUL SYLLABLE MYEO + {0xBA71, 0xBA8B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH + {0xBA8C, 0xBA8C, prH2, gcLo}, // HANGUL SYLLABLE MYE + {0xBA8D, 0xBAA7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH + {0xBAA8, 0xBAA8, prH2, gcLo}, // HANGUL SYLLABLE MO + {0xBAA9, 0xBAC3, prH3, gcLo}, // [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH + {0xBAC4, 0xBAC4, prH2, gcLo}, // HANGUL SYLLABLE MWA + {0xBAC5, 0xBADF, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH + {0xBAE0, 0xBAE0, prH2, gcLo}, // HANGUL SYLLABLE MWAE + {0xBAE1, 0xBAFB, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH + {0xBAFC, 0xBAFC, prH2, gcLo}, // HANGUL SYLLABLE MOE + {0xBAFD, 0xBB17, prH3, gcLo}, // [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH + {0xBB18, 0xBB18, prH2, gcLo}, // HANGUL SYLLABLE MYO + {0xBB19, 0xBB33, prH3, gcLo}, // [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH + {0xBB34, 0xBB34, prH2, gcLo}, // HANGUL SYLLABLE MU + {0xBB35, 0xBB4F, prH3, gcLo}, // [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH + {0xBB50, 0xBB50, prH2, gcLo}, // HANGUL SYLLABLE MWEO + {0xBB51, 0xBB6B, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH + {0xBB6C, 0xBB6C, prH2, gcLo}, // HANGUL SYLLABLE MWE + {0xBB6D, 0xBB87, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH + {0xBB88, 0xBB88, prH2, gcLo}, // HANGUL SYLLABLE MWI + {0xBB89, 0xBBA3, prH3, gcLo}, // [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH + {0xBBA4, 0xBBA4, prH2, gcLo}, // HANGUL SYLLABLE MYU + {0xBBA5, 0xBBBF, prH3, gcLo}, // [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH + {0xBBC0, 0xBBC0, prH2, gcLo}, // HANGUL SYLLABLE MEU + {0xBBC1, 0xBBDB, prH3, gcLo}, // [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH + {0xBBDC, 0xBBDC, prH2, gcLo}, // HANGUL SYLLABLE MYI + {0xBBDD, 0xBBF7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH + {0xBBF8, 0xBBF8, prH2, gcLo}, // HANGUL SYLLABLE MI + {0xBBF9, 0xBC13, prH3, gcLo}, // [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH + {0xBC14, 0xBC14, prH2, gcLo}, // HANGUL SYLLABLE BA + {0xBC15, 0xBC2F, prH3, gcLo}, // [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH + {0xBC30, 0xBC30, prH2, gcLo}, // HANGUL SYLLABLE BAE + {0xBC31, 0xBC4B, prH3, gcLo}, // [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH + {0xBC4C, 0xBC4C, prH2, gcLo}, // HANGUL SYLLABLE BYA + {0xBC4D, 0xBC67, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH + {0xBC68, 0xBC68, prH2, gcLo}, // HANGUL SYLLABLE BYAE + {0xBC69, 0xBC83, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH + {0xBC84, 0xBC84, prH2, gcLo}, // HANGUL SYLLABLE BEO + {0xBC85, 0xBC9F, prH3, gcLo}, // [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH + {0xBCA0, 0xBCA0, prH2, gcLo}, // HANGUL SYLLABLE BE + {0xBCA1, 0xBCBB, prH3, gcLo}, // [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH + {0xBCBC, 0xBCBC, prH2, gcLo}, // HANGUL SYLLABLE BYEO + {0xBCBD, 0xBCD7, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH + {0xBCD8, 0xBCD8, prH2, gcLo}, // HANGUL SYLLABLE BYE + {0xBCD9, 0xBCF3, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH + {0xBCF4, 0xBCF4, prH2, gcLo}, // HANGUL SYLLABLE BO + {0xBCF5, 0xBD0F, prH3, gcLo}, // [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH + {0xBD10, 0xBD10, prH2, gcLo}, // HANGUL SYLLABLE BWA + {0xBD11, 0xBD2B, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH + {0xBD2C, 0xBD2C, prH2, gcLo}, // HANGUL SYLLABLE BWAE + {0xBD2D, 0xBD47, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH + {0xBD48, 0xBD48, prH2, gcLo}, // HANGUL SYLLABLE BOE + {0xBD49, 0xBD63, prH3, gcLo}, // [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH + {0xBD64, 0xBD64, prH2, gcLo}, // HANGUL SYLLABLE BYO + {0xBD65, 0xBD7F, prH3, gcLo}, // [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH + {0xBD80, 0xBD80, prH2, gcLo}, // HANGUL SYLLABLE BU + {0xBD81, 0xBD9B, prH3, gcLo}, // [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH + {0xBD9C, 0xBD9C, prH2, gcLo}, // HANGUL SYLLABLE BWEO + {0xBD9D, 0xBDB7, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH + {0xBDB8, 0xBDB8, prH2, gcLo}, // HANGUL SYLLABLE BWE + {0xBDB9, 0xBDD3, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH + {0xBDD4, 0xBDD4, prH2, gcLo}, // HANGUL SYLLABLE BWI + {0xBDD5, 0xBDEF, prH3, gcLo}, // [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH + {0xBDF0, 0xBDF0, prH2, gcLo}, // HANGUL SYLLABLE BYU + {0xBDF1, 0xBE0B, prH3, gcLo}, // [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH + {0xBE0C, 0xBE0C, prH2, gcLo}, // HANGUL SYLLABLE BEU + {0xBE0D, 0xBE27, prH3, gcLo}, // [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH + {0xBE28, 0xBE28, prH2, gcLo}, // HANGUL SYLLABLE BYI + {0xBE29, 0xBE43, prH3, gcLo}, // [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH + {0xBE44, 0xBE44, prH2, gcLo}, // HANGUL SYLLABLE BI + {0xBE45, 0xBE5F, prH3, gcLo}, // [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH + {0xBE60, 0xBE60, prH2, gcLo}, // HANGUL SYLLABLE BBA + {0xBE61, 0xBE7B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH + {0xBE7C, 0xBE7C, prH2, gcLo}, // HANGUL SYLLABLE BBAE + {0xBE7D, 0xBE97, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH + {0xBE98, 0xBE98, prH2, gcLo}, // HANGUL SYLLABLE BBYA + {0xBE99, 0xBEB3, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH + {0xBEB4, 0xBEB4, prH2, gcLo}, // HANGUL SYLLABLE BBYAE + {0xBEB5, 0xBECF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH + {0xBED0, 0xBED0, prH2, gcLo}, // HANGUL SYLLABLE BBEO + {0xBED1, 0xBEEB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH + {0xBEEC, 0xBEEC, prH2, gcLo}, // HANGUL SYLLABLE BBE + {0xBEED, 0xBF07, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH + {0xBF08, 0xBF08, prH2, gcLo}, // HANGUL SYLLABLE BBYEO + {0xBF09, 0xBF23, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH + {0xBF24, 0xBF24, prH2, gcLo}, // HANGUL SYLLABLE BBYE + {0xBF25, 0xBF3F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH + {0xBF40, 0xBF40, prH2, gcLo}, // HANGUL SYLLABLE BBO + {0xBF41, 0xBF5B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH + {0xBF5C, 0xBF5C, prH2, gcLo}, // HANGUL SYLLABLE BBWA + {0xBF5D, 0xBF77, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH + {0xBF78, 0xBF78, prH2, gcLo}, // HANGUL SYLLABLE BBWAE + {0xBF79, 0xBF93, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH + {0xBF94, 0xBF94, prH2, gcLo}, // HANGUL SYLLABLE BBOE + {0xBF95, 0xBFAF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH + {0xBFB0, 0xBFB0, prH2, gcLo}, // HANGUL SYLLABLE BBYO + {0xBFB1, 0xBFCB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH + {0xBFCC, 0xBFCC, prH2, gcLo}, // HANGUL SYLLABLE BBU + {0xBFCD, 0xBFE7, prH3, gcLo}, // [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH + {0xBFE8, 0xBFE8, prH2, gcLo}, // HANGUL SYLLABLE BBWEO + {0xBFE9, 0xC003, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH + {0xC004, 0xC004, prH2, gcLo}, // HANGUL SYLLABLE BBWE + {0xC005, 0xC01F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH + {0xC020, 0xC020, prH2, gcLo}, // HANGUL SYLLABLE BBWI + {0xC021, 0xC03B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH + {0xC03C, 0xC03C, prH2, gcLo}, // HANGUL SYLLABLE BBYU + {0xC03D, 0xC057, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH + {0xC058, 0xC058, prH2, gcLo}, // HANGUL SYLLABLE BBEU + {0xC059, 0xC073, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH + {0xC074, 0xC074, prH2, gcLo}, // HANGUL SYLLABLE BBYI + {0xC075, 0xC08F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH + {0xC090, 0xC090, prH2, gcLo}, // HANGUL SYLLABLE BBI + {0xC091, 0xC0AB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH + {0xC0AC, 0xC0AC, prH2, gcLo}, // HANGUL SYLLABLE SA + {0xC0AD, 0xC0C7, prH3, gcLo}, // [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH + {0xC0C8, 0xC0C8, prH2, gcLo}, // HANGUL SYLLABLE SAE + {0xC0C9, 0xC0E3, prH3, gcLo}, // [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH + {0xC0E4, 0xC0E4, prH2, gcLo}, // HANGUL SYLLABLE SYA + {0xC0E5, 0xC0FF, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH + {0xC100, 0xC100, prH2, gcLo}, // HANGUL SYLLABLE SYAE + {0xC101, 0xC11B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH + {0xC11C, 0xC11C, prH2, gcLo}, // HANGUL SYLLABLE SEO + {0xC11D, 0xC137, prH3, gcLo}, // [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH + {0xC138, 0xC138, prH2, gcLo}, // HANGUL SYLLABLE SE + {0xC139, 0xC153, prH3, gcLo}, // [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH + {0xC154, 0xC154, prH2, gcLo}, // HANGUL SYLLABLE SYEO + {0xC155, 0xC16F, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH + {0xC170, 0xC170, prH2, gcLo}, // HANGUL SYLLABLE SYE + {0xC171, 0xC18B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH + {0xC18C, 0xC18C, prH2, gcLo}, // HANGUL SYLLABLE SO + {0xC18D, 0xC1A7, prH3, gcLo}, // [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH + {0xC1A8, 0xC1A8, prH2, gcLo}, // HANGUL SYLLABLE SWA + {0xC1A9, 0xC1C3, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH + {0xC1C4, 0xC1C4, prH2, gcLo}, // HANGUL SYLLABLE SWAE + {0xC1C5, 0xC1DF, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH + {0xC1E0, 0xC1E0, prH2, gcLo}, // HANGUL SYLLABLE SOE + {0xC1E1, 0xC1FB, prH3, gcLo}, // [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH + {0xC1FC, 0xC1FC, prH2, gcLo}, // HANGUL SYLLABLE SYO + {0xC1FD, 0xC217, prH3, gcLo}, // [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH + {0xC218, 0xC218, prH2, gcLo}, // HANGUL SYLLABLE SU + {0xC219, 0xC233, prH3, gcLo}, // [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH + {0xC234, 0xC234, prH2, gcLo}, // HANGUL SYLLABLE SWEO + {0xC235, 0xC24F, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH + {0xC250, 0xC250, prH2, gcLo}, // HANGUL SYLLABLE SWE + {0xC251, 0xC26B, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH + {0xC26C, 0xC26C, prH2, gcLo}, // HANGUL SYLLABLE SWI + {0xC26D, 0xC287, prH3, gcLo}, // [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH + {0xC288, 0xC288, prH2, gcLo}, // HANGUL SYLLABLE SYU + {0xC289, 0xC2A3, prH3, gcLo}, // [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH + {0xC2A4, 0xC2A4, prH2, gcLo}, // HANGUL SYLLABLE SEU + {0xC2A5, 0xC2BF, prH3, gcLo}, // [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH + {0xC2C0, 0xC2C0, prH2, gcLo}, // HANGUL SYLLABLE SYI + {0xC2C1, 0xC2DB, prH3, gcLo}, // [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH + {0xC2DC, 0xC2DC, prH2, gcLo}, // HANGUL SYLLABLE SI + {0xC2DD, 0xC2F7, prH3, gcLo}, // [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH + {0xC2F8, 0xC2F8, prH2, gcLo}, // HANGUL SYLLABLE SSA + {0xC2F9, 0xC313, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH + {0xC314, 0xC314, prH2, gcLo}, // HANGUL SYLLABLE SSAE + {0xC315, 0xC32F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH + {0xC330, 0xC330, prH2, gcLo}, // HANGUL SYLLABLE SSYA + {0xC331, 0xC34B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH + {0xC34C, 0xC34C, prH2, gcLo}, // HANGUL SYLLABLE SSYAE + {0xC34D, 0xC367, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH + {0xC368, 0xC368, prH2, gcLo}, // HANGUL SYLLABLE SSEO + {0xC369, 0xC383, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH + {0xC384, 0xC384, prH2, gcLo}, // HANGUL SYLLABLE SSE + {0xC385, 0xC39F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH + {0xC3A0, 0xC3A0, prH2, gcLo}, // HANGUL SYLLABLE SSYEO + {0xC3A1, 0xC3BB, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH + {0xC3BC, 0xC3BC, prH2, gcLo}, // HANGUL SYLLABLE SSYE + {0xC3BD, 0xC3D7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH + {0xC3D8, 0xC3D8, prH2, gcLo}, // HANGUL SYLLABLE SSO + {0xC3D9, 0xC3F3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH + {0xC3F4, 0xC3F4, prH2, gcLo}, // HANGUL SYLLABLE SSWA + {0xC3F5, 0xC40F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH + {0xC410, 0xC410, prH2, gcLo}, // HANGUL SYLLABLE SSWAE + {0xC411, 0xC42B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH + {0xC42C, 0xC42C, prH2, gcLo}, // HANGUL SYLLABLE SSOE + {0xC42D, 0xC447, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH + {0xC448, 0xC448, prH2, gcLo}, // HANGUL SYLLABLE SSYO + {0xC449, 0xC463, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH + {0xC464, 0xC464, prH2, gcLo}, // HANGUL SYLLABLE SSU + {0xC465, 0xC47F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH + {0xC480, 0xC480, prH2, gcLo}, // HANGUL SYLLABLE SSWEO + {0xC481, 0xC49B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH + {0xC49C, 0xC49C, prH2, gcLo}, // HANGUL SYLLABLE SSWE + {0xC49D, 0xC4B7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH + {0xC4B8, 0xC4B8, prH2, gcLo}, // HANGUL SYLLABLE SSWI + {0xC4B9, 0xC4D3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH + {0xC4D4, 0xC4D4, prH2, gcLo}, // HANGUL SYLLABLE SSYU + {0xC4D5, 0xC4EF, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH + {0xC4F0, 0xC4F0, prH2, gcLo}, // HANGUL SYLLABLE SSEU + {0xC4F1, 0xC50B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH + {0xC50C, 0xC50C, prH2, gcLo}, // HANGUL SYLLABLE SSYI + {0xC50D, 0xC527, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH + {0xC528, 0xC528, prH2, gcLo}, // HANGUL SYLLABLE SSI + {0xC529, 0xC543, prH3, gcLo}, // [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH + {0xC544, 0xC544, prH2, gcLo}, // HANGUL SYLLABLE A + {0xC545, 0xC55F, prH3, gcLo}, // [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH + {0xC560, 0xC560, prH2, gcLo}, // HANGUL SYLLABLE AE + {0xC561, 0xC57B, prH3, gcLo}, // [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH + {0xC57C, 0xC57C, prH2, gcLo}, // HANGUL SYLLABLE YA + {0xC57D, 0xC597, prH3, gcLo}, // [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH + {0xC598, 0xC598, prH2, gcLo}, // HANGUL SYLLABLE YAE + {0xC599, 0xC5B3, prH3, gcLo}, // [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH + {0xC5B4, 0xC5B4, prH2, gcLo}, // HANGUL SYLLABLE EO + {0xC5B5, 0xC5CF, prH3, gcLo}, // [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH + {0xC5D0, 0xC5D0, prH2, gcLo}, // HANGUL SYLLABLE E + {0xC5D1, 0xC5EB, prH3, gcLo}, // [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH + {0xC5EC, 0xC5EC, prH2, gcLo}, // HANGUL SYLLABLE YEO + {0xC5ED, 0xC607, prH3, gcLo}, // [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH + {0xC608, 0xC608, prH2, gcLo}, // HANGUL SYLLABLE YE + {0xC609, 0xC623, prH3, gcLo}, // [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH + {0xC624, 0xC624, prH2, gcLo}, // HANGUL SYLLABLE O + {0xC625, 0xC63F, prH3, gcLo}, // [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH + {0xC640, 0xC640, prH2, gcLo}, // HANGUL SYLLABLE WA + {0xC641, 0xC65B, prH3, gcLo}, // [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH + {0xC65C, 0xC65C, prH2, gcLo}, // HANGUL SYLLABLE WAE + {0xC65D, 0xC677, prH3, gcLo}, // [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH + {0xC678, 0xC678, prH2, gcLo}, // HANGUL SYLLABLE OE + {0xC679, 0xC693, prH3, gcLo}, // [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH + {0xC694, 0xC694, prH2, gcLo}, // HANGUL SYLLABLE YO + {0xC695, 0xC6AF, prH3, gcLo}, // [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH + {0xC6B0, 0xC6B0, prH2, gcLo}, // HANGUL SYLLABLE U + {0xC6B1, 0xC6CB, prH3, gcLo}, // [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH + {0xC6CC, 0xC6CC, prH2, gcLo}, // HANGUL SYLLABLE WEO + {0xC6CD, 0xC6E7, prH3, gcLo}, // [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH + {0xC6E8, 0xC6E8, prH2, gcLo}, // HANGUL SYLLABLE WE + {0xC6E9, 0xC703, prH3, gcLo}, // [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH + {0xC704, 0xC704, prH2, gcLo}, // HANGUL SYLLABLE WI + {0xC705, 0xC71F, prH3, gcLo}, // [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH + {0xC720, 0xC720, prH2, gcLo}, // HANGUL SYLLABLE YU + {0xC721, 0xC73B, prH3, gcLo}, // [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH + {0xC73C, 0xC73C, prH2, gcLo}, // HANGUL SYLLABLE EU + {0xC73D, 0xC757, prH3, gcLo}, // [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH + {0xC758, 0xC758, prH2, gcLo}, // HANGUL SYLLABLE YI + {0xC759, 0xC773, prH3, gcLo}, // [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH + {0xC774, 0xC774, prH2, gcLo}, // HANGUL SYLLABLE I + {0xC775, 0xC78F, prH3, gcLo}, // [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH + {0xC790, 0xC790, prH2, gcLo}, // HANGUL SYLLABLE JA + {0xC791, 0xC7AB, prH3, gcLo}, // [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH + {0xC7AC, 0xC7AC, prH2, gcLo}, // HANGUL SYLLABLE JAE + {0xC7AD, 0xC7C7, prH3, gcLo}, // [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH + {0xC7C8, 0xC7C8, prH2, gcLo}, // HANGUL SYLLABLE JYA + {0xC7C9, 0xC7E3, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH + {0xC7E4, 0xC7E4, prH2, gcLo}, // HANGUL SYLLABLE JYAE + {0xC7E5, 0xC7FF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH + {0xC800, 0xC800, prH2, gcLo}, // HANGUL SYLLABLE JEO + {0xC801, 0xC81B, prH3, gcLo}, // [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH + {0xC81C, 0xC81C, prH2, gcLo}, // HANGUL SYLLABLE JE + {0xC81D, 0xC837, prH3, gcLo}, // [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH + {0xC838, 0xC838, prH2, gcLo}, // HANGUL SYLLABLE JYEO + {0xC839, 0xC853, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH + {0xC854, 0xC854, prH2, gcLo}, // HANGUL SYLLABLE JYE + {0xC855, 0xC86F, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH + {0xC870, 0xC870, prH2, gcLo}, // HANGUL SYLLABLE JO + {0xC871, 0xC88B, prH3, gcLo}, // [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH + {0xC88C, 0xC88C, prH2, gcLo}, // HANGUL SYLLABLE JWA + {0xC88D, 0xC8A7, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH + {0xC8A8, 0xC8A8, prH2, gcLo}, // HANGUL SYLLABLE JWAE + {0xC8A9, 0xC8C3, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH + {0xC8C4, 0xC8C4, prH2, gcLo}, // HANGUL SYLLABLE JOE + {0xC8C5, 0xC8DF, prH3, gcLo}, // [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH + {0xC8E0, 0xC8E0, prH2, gcLo}, // HANGUL SYLLABLE JYO + {0xC8E1, 0xC8FB, prH3, gcLo}, // [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH + {0xC8FC, 0xC8FC, prH2, gcLo}, // HANGUL SYLLABLE JU + {0xC8FD, 0xC917, prH3, gcLo}, // [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH + {0xC918, 0xC918, prH2, gcLo}, // HANGUL SYLLABLE JWEO + {0xC919, 0xC933, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH + {0xC934, 0xC934, prH2, gcLo}, // HANGUL SYLLABLE JWE + {0xC935, 0xC94F, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH + {0xC950, 0xC950, prH2, gcLo}, // HANGUL SYLLABLE JWI + {0xC951, 0xC96B, prH3, gcLo}, // [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH + {0xC96C, 0xC96C, prH2, gcLo}, // HANGUL SYLLABLE JYU + {0xC96D, 0xC987, prH3, gcLo}, // [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH + {0xC988, 0xC988, prH2, gcLo}, // HANGUL SYLLABLE JEU + {0xC989, 0xC9A3, prH3, gcLo}, // [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH + {0xC9A4, 0xC9A4, prH2, gcLo}, // HANGUL SYLLABLE JYI + {0xC9A5, 0xC9BF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH + {0xC9C0, 0xC9C0, prH2, gcLo}, // HANGUL SYLLABLE JI + {0xC9C1, 0xC9DB, prH3, gcLo}, // [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH + {0xC9DC, 0xC9DC, prH2, gcLo}, // HANGUL SYLLABLE JJA + {0xC9DD, 0xC9F7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH + {0xC9F8, 0xC9F8, prH2, gcLo}, // HANGUL SYLLABLE JJAE + {0xC9F9, 0xCA13, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH + {0xCA14, 0xCA14, prH2, gcLo}, // HANGUL SYLLABLE JJYA + {0xCA15, 0xCA2F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH + {0xCA30, 0xCA30, prH2, gcLo}, // HANGUL SYLLABLE JJYAE + {0xCA31, 0xCA4B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH + {0xCA4C, 0xCA4C, prH2, gcLo}, // HANGUL SYLLABLE JJEO + {0xCA4D, 0xCA67, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH + {0xCA68, 0xCA68, prH2, gcLo}, // HANGUL SYLLABLE JJE + {0xCA69, 0xCA83, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH + {0xCA84, 0xCA84, prH2, gcLo}, // HANGUL SYLLABLE JJYEO + {0xCA85, 0xCA9F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH + {0xCAA0, 0xCAA0, prH2, gcLo}, // HANGUL SYLLABLE JJYE + {0xCAA1, 0xCABB, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH + {0xCABC, 0xCABC, prH2, gcLo}, // HANGUL SYLLABLE JJO + {0xCABD, 0xCAD7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH + {0xCAD8, 0xCAD8, prH2, gcLo}, // HANGUL SYLLABLE JJWA + {0xCAD9, 0xCAF3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH + {0xCAF4, 0xCAF4, prH2, gcLo}, // HANGUL SYLLABLE JJWAE + {0xCAF5, 0xCB0F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH + {0xCB10, 0xCB10, prH2, gcLo}, // HANGUL SYLLABLE JJOE + {0xCB11, 0xCB2B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH + {0xCB2C, 0xCB2C, prH2, gcLo}, // HANGUL SYLLABLE JJYO + {0xCB2D, 0xCB47, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH + {0xCB48, 0xCB48, prH2, gcLo}, // HANGUL SYLLABLE JJU + {0xCB49, 0xCB63, prH3, gcLo}, // [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH + {0xCB64, 0xCB64, prH2, gcLo}, // HANGUL SYLLABLE JJWEO + {0xCB65, 0xCB7F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH + {0xCB80, 0xCB80, prH2, gcLo}, // HANGUL SYLLABLE JJWE + {0xCB81, 0xCB9B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH + {0xCB9C, 0xCB9C, prH2, gcLo}, // HANGUL SYLLABLE JJWI + {0xCB9D, 0xCBB7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH + {0xCBB8, 0xCBB8, prH2, gcLo}, // HANGUL SYLLABLE JJYU + {0xCBB9, 0xCBD3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH + {0xCBD4, 0xCBD4, prH2, gcLo}, // HANGUL SYLLABLE JJEU + {0xCBD5, 0xCBEF, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH + {0xCBF0, 0xCBF0, prH2, gcLo}, // HANGUL SYLLABLE JJYI + {0xCBF1, 0xCC0B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH + {0xCC0C, 0xCC0C, prH2, gcLo}, // HANGUL SYLLABLE JJI + {0xCC0D, 0xCC27, prH3, gcLo}, // [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH + {0xCC28, 0xCC28, prH2, gcLo}, // HANGUL SYLLABLE CA + {0xCC29, 0xCC43, prH3, gcLo}, // [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH + {0xCC44, 0xCC44, prH2, gcLo}, // HANGUL SYLLABLE CAE + {0xCC45, 0xCC5F, prH3, gcLo}, // [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH + {0xCC60, 0xCC60, prH2, gcLo}, // HANGUL SYLLABLE CYA + {0xCC61, 0xCC7B, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH + {0xCC7C, 0xCC7C, prH2, gcLo}, // HANGUL SYLLABLE CYAE + {0xCC7D, 0xCC97, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH + {0xCC98, 0xCC98, prH2, gcLo}, // HANGUL SYLLABLE CEO + {0xCC99, 0xCCB3, prH3, gcLo}, // [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH + {0xCCB4, 0xCCB4, prH2, gcLo}, // HANGUL SYLLABLE CE + {0xCCB5, 0xCCCF, prH3, gcLo}, // [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH + {0xCCD0, 0xCCD0, prH2, gcLo}, // HANGUL SYLLABLE CYEO + {0xCCD1, 0xCCEB, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH + {0xCCEC, 0xCCEC, prH2, gcLo}, // HANGUL SYLLABLE CYE + {0xCCED, 0xCD07, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH + {0xCD08, 0xCD08, prH2, gcLo}, // HANGUL SYLLABLE CO + {0xCD09, 0xCD23, prH3, gcLo}, // [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH + {0xCD24, 0xCD24, prH2, gcLo}, // HANGUL SYLLABLE CWA + {0xCD25, 0xCD3F, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH + {0xCD40, 0xCD40, prH2, gcLo}, // HANGUL SYLLABLE CWAE + {0xCD41, 0xCD5B, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH + {0xCD5C, 0xCD5C, prH2, gcLo}, // HANGUL SYLLABLE COE + {0xCD5D, 0xCD77, prH3, gcLo}, // [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH + {0xCD78, 0xCD78, prH2, gcLo}, // HANGUL SYLLABLE CYO + {0xCD79, 0xCD93, prH3, gcLo}, // [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH + {0xCD94, 0xCD94, prH2, gcLo}, // HANGUL SYLLABLE CU + {0xCD95, 0xCDAF, prH3, gcLo}, // [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH + {0xCDB0, 0xCDB0, prH2, gcLo}, // HANGUL SYLLABLE CWEO + {0xCDB1, 0xCDCB, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH + {0xCDCC, 0xCDCC, prH2, gcLo}, // HANGUL SYLLABLE CWE + {0xCDCD, 0xCDE7, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH + {0xCDE8, 0xCDE8, prH2, gcLo}, // HANGUL SYLLABLE CWI + {0xCDE9, 0xCE03, prH3, gcLo}, // [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH + {0xCE04, 0xCE04, prH2, gcLo}, // HANGUL SYLLABLE CYU + {0xCE05, 0xCE1F, prH3, gcLo}, // [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH + {0xCE20, 0xCE20, prH2, gcLo}, // HANGUL SYLLABLE CEU + {0xCE21, 0xCE3B, prH3, gcLo}, // [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH + {0xCE3C, 0xCE3C, prH2, gcLo}, // HANGUL SYLLABLE CYI + {0xCE3D, 0xCE57, prH3, gcLo}, // [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH + {0xCE58, 0xCE58, prH2, gcLo}, // HANGUL SYLLABLE CI + {0xCE59, 0xCE73, prH3, gcLo}, // [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH + {0xCE74, 0xCE74, prH2, gcLo}, // HANGUL SYLLABLE KA + {0xCE75, 0xCE8F, prH3, gcLo}, // [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH + {0xCE90, 0xCE90, prH2, gcLo}, // HANGUL SYLLABLE KAE + {0xCE91, 0xCEAB, prH3, gcLo}, // [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH + {0xCEAC, 0xCEAC, prH2, gcLo}, // HANGUL SYLLABLE KYA + {0xCEAD, 0xCEC7, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH + {0xCEC8, 0xCEC8, prH2, gcLo}, // HANGUL SYLLABLE KYAE + {0xCEC9, 0xCEE3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH + {0xCEE4, 0xCEE4, prH2, gcLo}, // HANGUL SYLLABLE KEO + {0xCEE5, 0xCEFF, prH3, gcLo}, // [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH + {0xCF00, 0xCF00, prH2, gcLo}, // HANGUL SYLLABLE KE + {0xCF01, 0xCF1B, prH3, gcLo}, // [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH + {0xCF1C, 0xCF1C, prH2, gcLo}, // HANGUL SYLLABLE KYEO + {0xCF1D, 0xCF37, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH + {0xCF38, 0xCF38, prH2, gcLo}, // HANGUL SYLLABLE KYE + {0xCF39, 0xCF53, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH + {0xCF54, 0xCF54, prH2, gcLo}, // HANGUL SYLLABLE KO + {0xCF55, 0xCF6F, prH3, gcLo}, // [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH + {0xCF70, 0xCF70, prH2, gcLo}, // HANGUL SYLLABLE KWA + {0xCF71, 0xCF8B, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH + {0xCF8C, 0xCF8C, prH2, gcLo}, // HANGUL SYLLABLE KWAE + {0xCF8D, 0xCFA7, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH + {0xCFA8, 0xCFA8, prH2, gcLo}, // HANGUL SYLLABLE KOE + {0xCFA9, 0xCFC3, prH3, gcLo}, // [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH + {0xCFC4, 0xCFC4, prH2, gcLo}, // HANGUL SYLLABLE KYO + {0xCFC5, 0xCFDF, prH3, gcLo}, // [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH + {0xCFE0, 0xCFE0, prH2, gcLo}, // HANGUL SYLLABLE KU + {0xCFE1, 0xCFFB, prH3, gcLo}, // [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH + {0xCFFC, 0xCFFC, prH2, gcLo}, // HANGUL SYLLABLE KWEO + {0xCFFD, 0xD017, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH + {0xD018, 0xD018, prH2, gcLo}, // HANGUL SYLLABLE KWE + {0xD019, 0xD033, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH + {0xD034, 0xD034, prH2, gcLo}, // HANGUL SYLLABLE KWI + {0xD035, 0xD04F, prH3, gcLo}, // [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH + {0xD050, 0xD050, prH2, gcLo}, // HANGUL SYLLABLE KYU + {0xD051, 0xD06B, prH3, gcLo}, // [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH + {0xD06C, 0xD06C, prH2, gcLo}, // HANGUL SYLLABLE KEU + {0xD06D, 0xD087, prH3, gcLo}, // [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH + {0xD088, 0xD088, prH2, gcLo}, // HANGUL SYLLABLE KYI + {0xD089, 0xD0A3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH + {0xD0A4, 0xD0A4, prH2, gcLo}, // HANGUL SYLLABLE KI + {0xD0A5, 0xD0BF, prH3, gcLo}, // [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH + {0xD0C0, 0xD0C0, prH2, gcLo}, // HANGUL SYLLABLE TA + {0xD0C1, 0xD0DB, prH3, gcLo}, // [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH + {0xD0DC, 0xD0DC, prH2, gcLo}, // HANGUL SYLLABLE TAE + {0xD0DD, 0xD0F7, prH3, gcLo}, // [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH + {0xD0F8, 0xD0F8, prH2, gcLo}, // HANGUL SYLLABLE TYA + {0xD0F9, 0xD113, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH + {0xD114, 0xD114, prH2, gcLo}, // HANGUL SYLLABLE TYAE + {0xD115, 0xD12F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH + {0xD130, 0xD130, prH2, gcLo}, // HANGUL SYLLABLE TEO + {0xD131, 0xD14B, prH3, gcLo}, // [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH + {0xD14C, 0xD14C, prH2, gcLo}, // HANGUL SYLLABLE TE + {0xD14D, 0xD167, prH3, gcLo}, // [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH + {0xD168, 0xD168, prH2, gcLo}, // HANGUL SYLLABLE TYEO + {0xD169, 0xD183, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH + {0xD184, 0xD184, prH2, gcLo}, // HANGUL SYLLABLE TYE + {0xD185, 0xD19F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH + {0xD1A0, 0xD1A0, prH2, gcLo}, // HANGUL SYLLABLE TO + {0xD1A1, 0xD1BB, prH3, gcLo}, // [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH + {0xD1BC, 0xD1BC, prH2, gcLo}, // HANGUL SYLLABLE TWA + {0xD1BD, 0xD1D7, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH + {0xD1D8, 0xD1D8, prH2, gcLo}, // HANGUL SYLLABLE TWAE + {0xD1D9, 0xD1F3, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH + {0xD1F4, 0xD1F4, prH2, gcLo}, // HANGUL SYLLABLE TOE + {0xD1F5, 0xD20F, prH3, gcLo}, // [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH + {0xD210, 0xD210, prH2, gcLo}, // HANGUL SYLLABLE TYO + {0xD211, 0xD22B, prH3, gcLo}, // [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH + {0xD22C, 0xD22C, prH2, gcLo}, // HANGUL SYLLABLE TU + {0xD22D, 0xD247, prH3, gcLo}, // [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH + {0xD248, 0xD248, prH2, gcLo}, // HANGUL SYLLABLE TWEO + {0xD249, 0xD263, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH + {0xD264, 0xD264, prH2, gcLo}, // HANGUL SYLLABLE TWE + {0xD265, 0xD27F, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH + {0xD280, 0xD280, prH2, gcLo}, // HANGUL SYLLABLE TWI + {0xD281, 0xD29B, prH3, gcLo}, // [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH + {0xD29C, 0xD29C, prH2, gcLo}, // HANGUL SYLLABLE TYU + {0xD29D, 0xD2B7, prH3, gcLo}, // [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH + {0xD2B8, 0xD2B8, prH2, gcLo}, // HANGUL SYLLABLE TEU + {0xD2B9, 0xD2D3, prH3, gcLo}, // [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH + {0xD2D4, 0xD2D4, prH2, gcLo}, // HANGUL SYLLABLE TYI + {0xD2D5, 0xD2EF, prH3, gcLo}, // [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH + {0xD2F0, 0xD2F0, prH2, gcLo}, // HANGUL SYLLABLE TI + {0xD2F1, 0xD30B, prH3, gcLo}, // [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH + {0xD30C, 0xD30C, prH2, gcLo}, // HANGUL SYLLABLE PA + {0xD30D, 0xD327, prH3, gcLo}, // [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH + {0xD328, 0xD328, prH2, gcLo}, // HANGUL SYLLABLE PAE + {0xD329, 0xD343, prH3, gcLo}, // [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH + {0xD344, 0xD344, prH2, gcLo}, // HANGUL SYLLABLE PYA + {0xD345, 0xD35F, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH + {0xD360, 0xD360, prH2, gcLo}, // HANGUL SYLLABLE PYAE + {0xD361, 0xD37B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH + {0xD37C, 0xD37C, prH2, gcLo}, // HANGUL SYLLABLE PEO + {0xD37D, 0xD397, prH3, gcLo}, // [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH + {0xD398, 0xD398, prH2, gcLo}, // HANGUL SYLLABLE PE + {0xD399, 0xD3B3, prH3, gcLo}, // [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH + {0xD3B4, 0xD3B4, prH2, gcLo}, // HANGUL SYLLABLE PYEO + {0xD3B5, 0xD3CF, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH + {0xD3D0, 0xD3D0, prH2, gcLo}, // HANGUL SYLLABLE PYE + {0xD3D1, 0xD3EB, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH + {0xD3EC, 0xD3EC, prH2, gcLo}, // HANGUL SYLLABLE PO + {0xD3ED, 0xD407, prH3, gcLo}, // [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH + {0xD408, 0xD408, prH2, gcLo}, // HANGUL SYLLABLE PWA + {0xD409, 0xD423, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH + {0xD424, 0xD424, prH2, gcLo}, // HANGUL SYLLABLE PWAE + {0xD425, 0xD43F, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH + {0xD440, 0xD440, prH2, gcLo}, // HANGUL SYLLABLE POE + {0xD441, 0xD45B, prH3, gcLo}, // [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH + {0xD45C, 0xD45C, prH2, gcLo}, // HANGUL SYLLABLE PYO + {0xD45D, 0xD477, prH3, gcLo}, // [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH + {0xD478, 0xD478, prH2, gcLo}, // HANGUL SYLLABLE PU + {0xD479, 0xD493, prH3, gcLo}, // [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH + {0xD494, 0xD494, prH2, gcLo}, // HANGUL SYLLABLE PWEO + {0xD495, 0xD4AF, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH + {0xD4B0, 0xD4B0, prH2, gcLo}, // HANGUL SYLLABLE PWE + {0xD4B1, 0xD4CB, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH + {0xD4CC, 0xD4CC, prH2, gcLo}, // HANGUL SYLLABLE PWI + {0xD4CD, 0xD4E7, prH3, gcLo}, // [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH + {0xD4E8, 0xD4E8, prH2, gcLo}, // HANGUL SYLLABLE PYU + {0xD4E9, 0xD503, prH3, gcLo}, // [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH + {0xD504, 0xD504, prH2, gcLo}, // HANGUL SYLLABLE PEU + {0xD505, 0xD51F, prH3, gcLo}, // [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH + {0xD520, 0xD520, prH2, gcLo}, // HANGUL SYLLABLE PYI + {0xD521, 0xD53B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH + {0xD53C, 0xD53C, prH2, gcLo}, // HANGUL SYLLABLE PI + {0xD53D, 0xD557, prH3, gcLo}, // [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH + {0xD558, 0xD558, prH2, gcLo}, // HANGUL SYLLABLE HA + {0xD559, 0xD573, prH3, gcLo}, // [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH + {0xD574, 0xD574, prH2, gcLo}, // HANGUL SYLLABLE HAE + {0xD575, 0xD58F, prH3, gcLo}, // [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH + {0xD590, 0xD590, prH2, gcLo}, // HANGUL SYLLABLE HYA + {0xD591, 0xD5AB, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH + {0xD5AC, 0xD5AC, prH2, gcLo}, // HANGUL SYLLABLE HYAE + {0xD5AD, 0xD5C7, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH + {0xD5C8, 0xD5C8, prH2, gcLo}, // HANGUL SYLLABLE HEO + {0xD5C9, 0xD5E3, prH3, gcLo}, // [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH + {0xD5E4, 0xD5E4, prH2, gcLo}, // HANGUL SYLLABLE HE + {0xD5E5, 0xD5FF, prH3, gcLo}, // [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH + {0xD600, 0xD600, prH2, gcLo}, // HANGUL SYLLABLE HYEO + {0xD601, 0xD61B, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH + {0xD61C, 0xD61C, prH2, gcLo}, // HANGUL SYLLABLE HYE + {0xD61D, 0xD637, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH + {0xD638, 0xD638, prH2, gcLo}, // HANGUL SYLLABLE HO + {0xD639, 0xD653, prH3, gcLo}, // [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH + {0xD654, 0xD654, prH2, gcLo}, // HANGUL SYLLABLE HWA + {0xD655, 0xD66F, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH + {0xD670, 0xD670, prH2, gcLo}, // HANGUL SYLLABLE HWAE + {0xD671, 0xD68B, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH + {0xD68C, 0xD68C, prH2, gcLo}, // HANGUL SYLLABLE HOE + {0xD68D, 0xD6A7, prH3, gcLo}, // [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH + {0xD6A8, 0xD6A8, prH2, gcLo}, // HANGUL SYLLABLE HYO + {0xD6A9, 0xD6C3, prH3, gcLo}, // [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH + {0xD6C4, 0xD6C4, prH2, gcLo}, // HANGUL SYLLABLE HU + {0xD6C5, 0xD6DF, prH3, gcLo}, // [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH + {0xD6E0, 0xD6E0, prH2, gcLo}, // HANGUL SYLLABLE HWEO + {0xD6E1, 0xD6FB, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH + {0xD6FC, 0xD6FC, prH2, gcLo}, // HANGUL SYLLABLE HWE + {0xD6FD, 0xD717, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH + {0xD718, 0xD718, prH2, gcLo}, // HANGUL SYLLABLE HWI + {0xD719, 0xD733, prH3, gcLo}, // [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH + {0xD734, 0xD734, prH2, gcLo}, // HANGUL SYLLABLE HYU + {0xD735, 0xD74F, prH3, gcLo}, // [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH + {0xD750, 0xD750, prH2, gcLo}, // HANGUL SYLLABLE HEU + {0xD751, 0xD76B, prH3, gcLo}, // [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH + {0xD76C, 0xD76C, prH2, gcLo}, // HANGUL SYLLABLE HYI + {0xD76D, 0xD787, prH3, gcLo}, // [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH + {0xD788, 0xD788, prH2, gcLo}, // HANGUL SYLLABLE HI + {0xD789, 0xD7A3, prH3, gcLo}, // [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prJV, gcLo}, // [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prJT, gcLo}, // [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xD800, 0xDB7F, prSG, gcCs}, // [896] .. + {0xDB80, 0xDBFF, prSG, gcCs}, // [128] .. + {0xDC00, 0xDFFF, prSG, gcCs}, // [1024] .. + {0xE000, 0xF8FF, prXX, gcCo}, // [6400] .. + {0xF900, 0xFA6D, prID, gcLo}, // [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA6E, 0xFA6F, prID, gcCn}, // [2] .. + {0xFA70, 0xFAD9, prID, gcLo}, // [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFADA, 0xFAFF, prID, gcCn}, // [38] .. + {0xFB00, 0xFB06, prAL, gcLl}, // [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prAL, gcLl}, // [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prHL, gcLo}, // HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prCM, gcMn}, // HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prHL, gcLo}, // [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB29, 0xFB29, prAL, gcSm}, // HEBREW LETTER ALTERNATIVE PLUS SIGN + {0xFB2A, 0xFB36, prHL, gcLo}, // [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prHL, gcLo}, // [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prHL, gcLo}, // HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prHL, gcLo}, // [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prHL, gcLo}, // [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prHL, gcLo}, // [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prAL, gcLo}, // [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBB2, 0xFBC2, prAL, gcSk}, // [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE + {0xFBD3, 0xFD3D, prAL, gcLo}, // [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prCL, gcPe}, // ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prOP, gcPs}, // ORNATE RIGHT PARENTHESIS + {0xFD40, 0xFD4F, prAL, gcSo}, // [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH + {0xFD50, 0xFD8F, prAL, gcLo}, // [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prAL, gcLo}, // [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDCF, 0xFDCF, prAL, gcSo}, // ARABIC LIGATURE SALAAMUHU ALAYNAA + {0xFDF0, 0xFDFB, prAL, gcLo}, // [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFDFC, 0xFDFC, prPO, gcSc}, // RIAL SIGN + {0xFDFD, 0xFDFF, prAL, gcSo}, // [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL + {0xFE00, 0xFE0F, prCM, gcMn}, // [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE10, prIS, gcPo}, // PRESENTATION FORM FOR VERTICAL COMMA + {0xFE11, 0xFE12, prCL, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA..PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP + {0xFE13, 0xFE14, prIS, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL COLON..PRESENTATION FORM FOR VERTICAL SEMICOLON + {0xFE15, 0xFE16, prEX, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK..PRESENTATION FORM FOR VERTICAL QUESTION MARK + {0xFE17, 0xFE17, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE19, 0xFE19, prIN, gcPo}, // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS + {0xFE20, 0xFE2F, prCM, gcMn}, // [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE30, 0xFE30, prID, gcPo}, // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xFE31, 0xFE32, prID, gcPd}, // [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE33, 0xFE34, prID, gcPc}, // [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE35, 0xFE35, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE45, 0xFE46, prID, gcPo}, // [2] SESAME DOT..WHITE SESAME DOT + {0xFE47, 0xFE47, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE49, 0xFE4C, prID, gcPo}, // [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE + {0xFE4D, 0xFE4F, prID, gcPc}, // [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE50, prCL, gcPo}, // SMALL COMMA + {0xFE51, 0xFE51, prID, gcPo}, // SMALL IDEOGRAPHIC COMMA + {0xFE52, 0xFE52, prCL, gcPo}, // SMALL FULL STOP + {0xFE54, 0xFE55, prNS, gcPo}, // [2] SMALL SEMICOLON..SMALL COLON + {0xFE56, 0xFE57, prEX, gcPo}, // [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prID, gcPd}, // SMALL EM DASH + {0xFE59, 0xFE59, prOP, gcPs}, // SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prCL, gcPe}, // SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prOP, gcPs}, // SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prCL, gcPe}, // SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prOP, gcPs}, // SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prCL, gcPe}, // SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE5F, 0xFE61, prID, gcPo}, // [3] SMALL NUMBER SIGN..SMALL ASTERISK + {0xFE62, 0xFE62, prID, gcSm}, // SMALL PLUS SIGN + {0xFE63, 0xFE63, prID, gcPd}, // SMALL HYPHEN-MINUS + {0xFE64, 0xFE66, prID, gcSm}, // [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN + {0xFE68, 0xFE68, prID, gcPo}, // SMALL REVERSE SOLIDUS + {0xFE69, 0xFE69, prPR, gcSc}, // SMALL DOLLAR SIGN + {0xFE6A, 0xFE6A, prPO, gcPo}, // SMALL PERCENT SIGN + {0xFE6B, 0xFE6B, prID, gcPo}, // SMALL COMMERCIAL AT + {0xFE70, 0xFE74, prAL, gcLo}, // [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prAL, gcLo}, // [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prWJ, gcCf}, // ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF01, prEX, gcPo}, // FULLWIDTH EXCLAMATION MARK + {0xFF02, 0xFF03, prID, gcPo}, // [2] FULLWIDTH QUOTATION MARK..FULLWIDTH NUMBER SIGN + {0xFF04, 0xFF04, prPR, gcSc}, // FULLWIDTH DOLLAR SIGN + {0xFF05, 0xFF05, prPO, gcPo}, // FULLWIDTH PERCENT SIGN + {0xFF06, 0xFF07, prID, gcPo}, // [2] FULLWIDTH AMPERSAND..FULLWIDTH APOSTROPHE + {0xFF08, 0xFF08, prOP, gcPs}, // FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prCL, gcPe}, // FULLWIDTH RIGHT PARENTHESIS + {0xFF0A, 0xFF0A, prID, gcPo}, // FULLWIDTH ASTERISK + {0xFF0B, 0xFF0B, prID, gcSm}, // FULLWIDTH PLUS SIGN + {0xFF0C, 0xFF0C, prCL, gcPo}, // FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prID, gcPd}, // FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0E, prCL, gcPo}, // FULLWIDTH FULL STOP + {0xFF0F, 0xFF0F, prID, gcPo}, // FULLWIDTH SOLIDUS + {0xFF10, 0xFF19, prID, gcNd}, // [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1B, prNS, gcPo}, // [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON + {0xFF1C, 0xFF1E, prID, gcSm}, // [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN + {0xFF1F, 0xFF1F, prEX, gcPo}, // FULLWIDTH QUESTION MARK + {0xFF20, 0xFF20, prID, gcPo}, // FULLWIDTH COMMERCIAL AT + {0xFF21, 0xFF3A, prID, gcLu}, // [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prOP, gcPs}, // FULLWIDTH LEFT SQUARE BRACKET + {0xFF3C, 0xFF3C, prID, gcPo}, // FULLWIDTH REVERSE SOLIDUS + {0xFF3D, 0xFF3D, prCL, gcPe}, // FULLWIDTH RIGHT SQUARE BRACKET + {0xFF3E, 0xFF3E, prID, gcSk}, // FULLWIDTH CIRCUMFLEX ACCENT + {0xFF3F, 0xFF3F, prID, gcPc}, // FULLWIDTH LOW LINE + {0xFF40, 0xFF40, prID, gcSk}, // FULLWIDTH GRAVE ACCENT + {0xFF41, 0xFF5A, prID, gcLl}, // [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prOP, gcPs}, // FULLWIDTH LEFT CURLY BRACKET + {0xFF5C, 0xFF5C, prID, gcSm}, // FULLWIDTH VERTICAL LINE + {0xFF5D, 0xFF5D, prCL, gcPe}, // FULLWIDTH RIGHT CURLY BRACKET + {0xFF5E, 0xFF5E, prID, gcSm}, // FULLWIDTH TILDE + {0xFF5F, 0xFF5F, prOP, gcPs}, // FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prCL, gcPe}, // FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prOP, gcPs}, // HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prCL, gcPe}, // HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF64, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC COMMA + {0xFF65, 0xFF65, prNS, gcPo}, // HALFWIDTH KATAKANA MIDDLE DOT + {0xFF66, 0xFF66, prID, gcLo}, // HALFWIDTH KATAKANA LETTER WO + {0xFF67, 0xFF6F, prCJ, gcLo}, // [9] HALFWIDTH KATAKANA LETTER SMALL A..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prCJ, gcLm}, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prID, gcLo}, // [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prNS, gcLm}, // [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prID, gcLo}, // [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prID, gcLo}, // [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFE0, 0xFFE0, prPO, gcSc}, // FULLWIDTH CENT SIGN + {0xFFE1, 0xFFE1, prPR, gcSc}, // FULLWIDTH POUND SIGN + {0xFFE2, 0xFFE2, prID, gcSm}, // FULLWIDTH NOT SIGN + {0xFFE3, 0xFFE3, prID, gcSk}, // FULLWIDTH MACRON + {0xFFE4, 0xFFE4, prID, gcSo}, // FULLWIDTH BROKEN BAR + {0xFFE5, 0xFFE6, prPR, gcSc}, // [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN + {0xFFE8, 0xFFE8, prAL, gcSo}, // HALFWIDTH FORMS LIGHT VERTICAL + {0xFFE9, 0xFFEC, prAL, gcSm}, // [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW + {0xFFED, 0xFFEE, prAL, gcSo}, // [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE + {0xFFF9, 0xFFFB, prCM, gcCf}, // [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0xFFFC, 0xFFFC, prCB, gcSo}, // OBJECT REPLACEMENT CHARACTER + {0xFFFD, 0xFFFD, prAI, gcSo}, // REPLACEMENT CHARACTER + {0x10000, 0x1000B, prAL, gcLo}, // [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prAL, gcLo}, // [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prAL, gcLo}, // [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prAL, gcLo}, // [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prAL, gcLo}, // [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prAL, gcLo}, // [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prAL, gcLo}, // [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10100, 0x10102, prBA, gcPo}, // [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK + {0x10107, 0x10133, prAL, gcNo}, // [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND + {0x10137, 0x1013F, prAL, gcSo}, // [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT + {0x10140, 0x10174, prAL, gcNl}, // [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x10175, 0x10178, prAL, gcNo}, // [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN + {0x10179, 0x10189, prAL, gcSo}, // [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN + {0x1018A, 0x1018B, prAL, gcNo}, // [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN + {0x1018C, 0x1018E, prAL, gcSo}, // [3] GREEK SINUSOID SIGN..NOMISMA SIGN + {0x10190, 0x1019C, prAL, gcSo}, // [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL + {0x101A0, 0x101A0, prAL, gcSo}, // GREEK SYMBOL TAU RHO + {0x101D0, 0x101FC, prAL, gcSo}, // [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND + {0x101FD, 0x101FD, prCM, gcMn}, // PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prAL, gcLo}, // [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prAL, gcLo}, // [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prCM, gcMn}, // COPTIC EPACT THOUSANDS MARK + {0x102E1, 0x102FB, prAL, gcNo}, // [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED + {0x10300, 0x1031F, prAL, gcLo}, // [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x10320, 0x10323, prAL, gcNo}, // [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY + {0x1032D, 0x1032F, prAL, gcLo}, // [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE + {0x10330, 0x10340, prAL, gcLo}, // [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prAL, gcNl}, // GOTHIC LETTER NINETY + {0x10342, 0x10349, prAL, gcLo}, // [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prAL, gcNl}, // GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prAL, gcLo}, // [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prCM, gcMn}, // [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prAL, gcLo}, // [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x1039F, 0x1039F, prBA, gcPo}, // UGARITIC WORD DIVIDER + {0x103A0, 0x103C3, prAL, gcLo}, // [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prAL, gcLo}, // [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D0, 0x103D0, prBA, gcPo}, // OLD PERSIAN WORD DIVIDER + {0x103D1, 0x103D5, prAL, gcNl}, // [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prAL, gcLC}, // [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1047F, prAL, gcLo}, // [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW + {0x10480, 0x1049D, prAL, gcLo}, // [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNU, gcNd}, // [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prAL, gcLu}, // [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prAL, gcLl}, // [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prAL, gcLo}, // [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prAL, gcLo}, // [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x1056F, 0x1056F, prAL, gcPo}, // CAUCASIAN ALBANIAN CITATION MARK + {0x10570, 0x1057A, prAL, gcLu}, // [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prAL, gcLu}, // [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prAL, gcLu}, // [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prAL, gcLu}, // [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prAL, gcLl}, // [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prAL, gcLl}, // [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prAL, gcLl}, // [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prAL, gcLl}, // [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prAL, gcLo}, // [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prAL, gcLo}, // [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prAL, gcLo}, // [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prAL, gcLm}, // [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prAL, gcLm}, // [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prAL, gcLm}, // [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prAL, gcLo}, // [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prAL, gcLo}, // CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prAL, gcLo}, // [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prAL, gcLo}, // [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prAL, gcLo}, // CYPRIOT SYLLABLE ZA + {0x1083F, 0x1083F, prAL, gcLo}, // CYPRIOT SYLLABLE ZO + {0x10840, 0x10855, prAL, gcLo}, // [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW + {0x10857, 0x10857, prBA, gcPo}, // IMPERIAL ARAMAIC SECTION SIGN + {0x10858, 0x1085F, prAL, gcNo}, // [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND + {0x10860, 0x10876, prAL, gcLo}, // [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10877, 0x10878, prAL, gcSo}, // [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON + {0x10879, 0x1087F, prAL, gcNo}, // [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY + {0x10880, 0x1089E, prAL, gcLo}, // [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108A7, 0x108AF, prAL, gcNo}, // [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED + {0x108E0, 0x108F2, prAL, gcLo}, // [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prAL, gcLo}, // [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x108FB, 0x108FF, prAL, gcNo}, // [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED + {0x10900, 0x10915, prAL, gcLo}, // [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10916, 0x1091B, prAL, gcNo}, // [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE + {0x1091F, 0x1091F, prBA, gcPo}, // PHOENICIAN WORD SEPARATOR + {0x10920, 0x10939, prAL, gcLo}, // [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x1093F, 0x1093F, prAL, gcPo}, // LYDIAN TRIANGULAR MARK + {0x10980, 0x1099F, prAL, gcLo}, // [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 + {0x109A0, 0x109B7, prAL, gcLo}, // [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BC, 0x109BD, prAL, gcNo}, // [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF + {0x109BE, 0x109BF, prAL, gcLo}, // [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x109C0, 0x109CF, prAL, gcNo}, // [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY + {0x109D2, 0x109FF, prAL, gcNo}, // [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS + {0x10A00, 0x10A00, prAL, gcLo}, // KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prCM, gcMn}, // [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prCM, gcMn}, // [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prCM, gcMn}, // [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prAL, gcLo}, // [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prAL, gcLo}, // [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prAL, gcLo}, // [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prCM, gcMn}, // [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prCM, gcMn}, // KHAROSHTHI VIRAMA + {0x10A40, 0x10A48, prAL, gcNo}, // [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF + {0x10A50, 0x10A57, prBA, gcPo}, // [8] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION DOUBLE DANDA + {0x10A58, 0x10A58, prAL, gcPo}, // KHAROSHTHI PUNCTUATION LINES + {0x10A60, 0x10A7C, prAL, gcLo}, // [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A7D, 0x10A7E, prAL, gcNo}, // [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY + {0x10A7F, 0x10A7F, prAL, gcPo}, // OLD SOUTH ARABIAN NUMERIC INDICATOR + {0x10A80, 0x10A9C, prAL, gcLo}, // [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10A9D, 0x10A9F, prAL, gcNo}, // [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY + {0x10AC0, 0x10AC7, prAL, gcLo}, // [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC8, 0x10AC8, prAL, gcSo}, // MANICHAEAN SIGN UD + {0x10AC9, 0x10AE4, prAL, gcLo}, // [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prCM, gcMn}, // [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10AEB, 0x10AEF, prAL, gcNo}, // [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED + {0x10AF0, 0x10AF5, prBA, gcPo}, // [6] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION TWO DOTS + {0x10AF6, 0x10AF6, prIN, gcPo}, // MANICHAEAN PUNCTUATION LINE FILLER + {0x10B00, 0x10B35, prAL, gcLo}, // [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B39, 0x10B3F, prBA, gcPo}, // [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION + {0x10B40, 0x10B55, prAL, gcLo}, // [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B58, 0x10B5F, prAL, gcNo}, // [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND + {0x10B60, 0x10B72, prAL, gcLo}, // [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B78, 0x10B7F, prAL, gcNo}, // [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND + {0x10B80, 0x10B91, prAL, gcLo}, // [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10B99, 0x10B9C, prAL, gcPo}, // [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT + {0x10BA9, 0x10BAF, prAL, gcNo}, // [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED + {0x10C00, 0x10C48, prAL, gcLo}, // [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prAL, gcLu}, // [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prAL, gcLl}, // [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10CFA, 0x10CFF, prAL, gcNo}, // [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND + {0x10D00, 0x10D23, prAL, gcLo}, // [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prCM, gcMn}, // [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNU, gcNd}, // [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E60, 0x10E7E, prAL, gcNo}, // [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS + {0x10E80, 0x10EA9, prAL, gcLo}, // [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prCM, gcMn}, // [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EAD, 0x10EAD, prBA, gcPd}, // YEZIDI HYPHENATION MARK + {0x10EB0, 0x10EB1, prAL, gcLo}, // [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prCM, gcMn}, // [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prAL, gcLo}, // [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F1D, 0x10F26, prAL, gcNo}, // [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF + {0x10F27, 0x10F27, prAL, gcLo}, // OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prAL, gcLo}, // [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prCM, gcMn}, // [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F51, 0x10F54, prAL, gcNo}, // [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED + {0x10F55, 0x10F59, prAL, gcPo}, // [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prAL, gcLo}, // [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prCM, gcMn}, // [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prAL, gcPo}, // [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prAL, gcLo}, // [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FC5, 0x10FCB, prAL, gcNo}, // [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED + {0x10FE0, 0x10FF6, prAL, gcLo}, // [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prCM, gcMc}, // BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prCM, gcMn}, // BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prCM, gcMc}, // BRAHMI SIGN VISARGA + {0x11003, 0x11037, prAL, gcLo}, // [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prCM, gcMn}, // [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x11048, prBA, gcPo}, // [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA + {0x11049, 0x1104D, prAL, gcPo}, // [5] BRAHMI PUNCTUATION DOT..BRAHMI PUNCTUATION LOTUS + {0x11052, 0x11065, prAL, gcNo}, // [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND + {0x11066, 0x1106F, prNU, gcNd}, // [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prCM, gcMn}, // BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prAL, gcLo}, // [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prCM, gcMn}, // [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prAL, gcLo}, // BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x1107F, prCM, gcMn}, // BRAHMI NUMBER JOINER + {0x11080, 0x11081, prCM, gcMn}, // [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prCM, gcMc}, // KAITHI SIGN VISARGA + {0x11083, 0x110AF, prAL, gcLo}, // [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prCM, gcMc}, // [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prCM, gcMn}, // [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prCM, gcMc}, // [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prCM, gcMn}, // [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BB, 0x110BC, prAL, gcPo}, // [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN + {0x110BD, 0x110BD, prAL, gcCf}, // KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prBA, gcPo}, // [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prCM, gcMn}, // KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prAL, gcCf}, // KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prAL, gcLo}, // [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNU, gcNd}, // [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prCM, gcMn}, // [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prAL, gcLo}, // [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prCM, gcMn}, // [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prCM, gcMc}, // CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prCM, gcMn}, // [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNU, gcNd}, // [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11140, 0x11143, prBA, gcPo}, // [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK + {0x11144, 0x11144, prAL, gcLo}, // CHAKMA LETTER LHAA + {0x11145, 0x11146, prCM, gcMc}, // [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prAL, gcLo}, // CHAKMA LETTER VAA + {0x11150, 0x11172, prAL, gcLo}, // [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prCM, gcMn}, // MAHAJANI SIGN NUKTA + {0x11174, 0x11174, prAL, gcPo}, // MAHAJANI ABBREVIATION SIGN + {0x11175, 0x11175, prBB, gcPo}, // MAHAJANI SECTION MARK + {0x11176, 0x11176, prAL, gcLo}, // MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prCM, gcMn}, // [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prCM, gcMc}, // SHARADA SIGN VISARGA + {0x11183, 0x111B2, prAL, gcLo}, // [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prCM, gcMc}, // [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prCM, gcMn}, // [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prCM, gcMc}, // [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prAL, gcLo}, // [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C6, prBA, gcPo}, // [2] SHARADA DANDA..SHARADA DOUBLE DANDA + {0x111C7, 0x111C7, prAL, gcPo}, // SHARADA ABBREVIATION SIGN + {0x111C8, 0x111C8, prBA, gcPo}, // SHARADA SEPARATOR + {0x111C9, 0x111CC, prCM, gcMn}, // [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prAL, gcPo}, // SHARADA SUTRA MARK + {0x111CE, 0x111CE, prCM, gcMc}, // SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prCM, gcMn}, // SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNU, gcNd}, // [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prAL, gcLo}, // SHARADA EKAM + {0x111DB, 0x111DB, prBB, gcPo}, // SHARADA SIGN SIDDHAM + {0x111DC, 0x111DC, prAL, gcLo}, // SHARADA HEADSTROKE + {0x111DD, 0x111DF, prBA, gcPo}, // [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 + {0x111E1, 0x111F4, prAL, gcNo}, // [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND + {0x11200, 0x11211, prAL, gcLo}, // [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prAL, gcLo}, // [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prCM, gcMc}, // [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prCM, gcMn}, // [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prCM, gcMc}, // [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prCM, gcMn}, // KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prCM, gcMc}, // KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prCM, gcMn}, // [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x11239, prBA, gcPo}, // [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA + {0x1123A, 0x1123A, prAL, gcPo}, // KHOJKI WORD SEPARATOR + {0x1123B, 0x1123C, prBA, gcPo}, // [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK + {0x1123D, 0x1123D, prAL, gcPo}, // KHOJKI ABBREVIATION SIGN + {0x1123E, 0x1123E, prCM, gcMn}, // KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prAL, gcLo}, // [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prCM, gcMn}, // KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prAL, gcLo}, // [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prAL, gcLo}, // MULTANI LETTER GHA + {0x1128A, 0x1128D, prAL, gcLo}, // [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prAL, gcLo}, // [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prAL, gcLo}, // [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prBA, gcPo}, // MULTANI SECTION MARK + {0x112B0, 0x112DE, prAL, gcLo}, // [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prCM, gcMn}, // KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prCM, gcMc}, // [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prCM, gcMn}, // [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNU, gcNd}, // [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prCM, gcMn}, // [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prCM, gcMc}, // [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prAL, gcLo}, // [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prAL, gcLo}, // [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prAL, gcLo}, // [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prAL, gcLo}, // [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prAL, gcLo}, // [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prAL, gcLo}, // [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prCM, gcMn}, // [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prAL, gcLo}, // GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prCM, gcMn}, // GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prCM, gcMc}, // [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prCM, gcMc}, // [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prAL, gcLo}, // GRANTHA OM + {0x11357, 0x11357, prCM, gcMc}, // GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prAL, gcLo}, // [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prCM, gcMn}, // [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prCM, gcMn}, // [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prAL, gcLo}, // [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prCM, gcMc}, // [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prCM, gcMn}, // [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prCM, gcMc}, // [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prCM, gcMn}, // [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prCM, gcMc}, // NEWA SIGN VISARGA + {0x11446, 0x11446, prCM, gcMn}, // NEWA SIGN NUKTA + {0x11447, 0x1144A, prAL, gcLo}, // [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144E, prBA, gcPo}, // [4] NEWA DANDA..NEWA GAP FILLER + {0x1144F, 0x1144F, prAL, gcPo}, // NEWA ABBREVIATION SIGN + {0x11450, 0x11459, prNU, gcNd}, // [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145A, 0x1145B, prBA, gcPo}, // [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK + {0x1145D, 0x1145D, prAL, gcPo}, // NEWA INSERTION SIGN + {0x1145E, 0x1145E, prCM, gcMn}, // NEWA SANDHI MARK + {0x1145F, 0x11461, prAL, gcLo}, // [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prAL, gcLo}, // [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prCM, gcMc}, // [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prCM, gcMn}, // [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prCM, gcMc}, // TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prCM, gcMn}, // TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prCM, gcMc}, // [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prCM, gcMn}, // [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prCM, gcMc}, // TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prCM, gcMn}, // [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prAL, gcLo}, // [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C6, 0x114C6, prAL, gcPo}, // TIRHUTA ABBREVIATION SIGN + {0x114C7, 0x114C7, prAL, gcLo}, // TIRHUTA OM + {0x114D0, 0x114D9, prNU, gcNd}, // [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prAL, gcLo}, // [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prCM, gcMc}, // [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prCM, gcMn}, // [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prCM, gcMc}, // [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prCM, gcMn}, // [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prCM, gcMc}, // SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prCM, gcMn}, // [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C1, 0x115C1, prBB, gcPo}, // SIDDHAM SIGN SIDDHAM + {0x115C2, 0x115C3, prBA, gcPo}, // [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA + {0x115C4, 0x115C5, prEX, gcPo}, // [2] SIDDHAM SEPARATOR DOT..SIDDHAM SEPARATOR BAR + {0x115C6, 0x115C8, prAL, gcPo}, // [3] SIDDHAM REPETITION MARK-1..SIDDHAM REPETITION MARK-3 + {0x115C9, 0x115D7, prBA, gcPo}, // [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prAL, gcLo}, // [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prCM, gcMn}, // [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prAL, gcLo}, // [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prCM, gcMc}, // [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prCM, gcMn}, // [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prCM, gcMc}, // [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prCM, gcMn}, // MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prCM, gcMc}, // MODI SIGN VISARGA + {0x1163F, 0x11640, prCM, gcMn}, // [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11642, prBA, gcPo}, // [2] MODI DANDA..MODI DOUBLE DANDA + {0x11643, 0x11643, prAL, gcPo}, // MODI ABBREVIATION SIGN + {0x11644, 0x11644, prAL, gcLo}, // MODI SIGN HUVA + {0x11650, 0x11659, prNU, gcNd}, // [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11660, 0x1166C, prBB, gcPo}, // [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT + {0x11680, 0x116AA, prAL, gcLo}, // [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prCM, gcMn}, // TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prCM, gcMc}, // TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prCM, gcMn}, // TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prCM, gcMc}, // [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prCM, gcMn}, // [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prCM, gcMc}, // TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prCM, gcMn}, // TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prAL, gcLo}, // TAKRI LETTER ARCHAIC KHA + {0x116B9, 0x116B9, prAL, gcPo}, // TAKRI ABBREVIATION SIGN + {0x116C0, 0x116C9, prNU, gcNd}, // [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prSA, gcLo}, // [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prSA, gcMn}, // [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prSA, gcMc}, // [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prSA, gcMn}, // [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prSA, gcMc}, // AHOM VOWEL SIGN E + {0x11727, 0x1172B, prSA, gcMn}, // [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNU, gcNd}, // [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173A, 0x1173B, prSA, gcNo}, // [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY + {0x1173C, 0x1173E, prBA, gcPo}, // [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x1173F, 0x1173F, prSA, gcSo}, // AHOM SYMBOL VI + {0x11740, 0x11746, prSA, gcLo}, // [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prAL, gcLo}, // [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prCM, gcMc}, // [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prCM, gcMn}, // [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prCM, gcMc}, // DOGRA SIGN VISARGA + {0x11839, 0x1183A, prCM, gcMn}, // [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x1183B, 0x1183B, prAL, gcPo}, // DOGRA ABBREVIATION SIGN + {0x118A0, 0x118DF, prAL, gcLC}, // [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNU, gcNd}, // [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118EA, 0x118F2, prAL, gcNo}, // [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY + {0x118FF, 0x118FF, prAL, gcLo}, // WARANG CITI OM + {0x11900, 0x11906, prAL, gcLo}, // [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E + {0x11909, 0x11909, prAL, gcLo}, // DIVES AKURU LETTER O + {0x1190C, 0x11913, prAL, gcLo}, // [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prAL, gcLo}, // [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prAL, gcLo}, // [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prCM, gcMc}, // [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prCM, gcMc}, // [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prCM, gcMn}, // [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prCM, gcMc}, // DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prCM, gcMn}, // DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prAL, gcLo}, // DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prCM, gcMc}, // DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prAL, gcLo}, // DIVES AKURU INITIAL RA + {0x11942, 0x11942, prCM, gcMc}, // DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prCM, gcMn}, // DIVES AKURU SIGN NUKTA + {0x11944, 0x11946, prBA, gcPo}, // [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prNU, gcNd}, // [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prAL, gcLo}, // [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prAL, gcLo}, // [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prCM, gcMc}, // [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prCM, gcMn}, // [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prCM, gcMn}, // [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prCM, gcMc}, // [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prCM, gcMn}, // NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prAL, gcLo}, // NANDINAGARI SIGN AVAGRAHA + {0x119E2, 0x119E2, prBB, gcPo}, // NANDINAGARI SIGN SIDDHAM + {0x119E3, 0x119E3, prAL, gcLo}, // NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prCM, gcMc}, // NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prAL, gcLo}, // ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prCM, gcMn}, // [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prAL, gcLo}, // [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prCM, gcMn}, // [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prCM, gcMc}, // ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prAL, gcLo}, // ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prCM, gcMn}, // [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A3F, 0x11A3F, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL HEAD MARK + {0x11A40, 0x11A40, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING HEAD MARK + {0x11A41, 0x11A44, prBA, gcPo}, // [4] ZANABAZAR SQUARE MARK TSHEG..ZANABAZAR SQUARE MARK LONG TSHEG + {0x11A45, 0x11A45, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK + {0x11A46, 0x11A46, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK + {0x11A47, 0x11A47, prCM, gcMn}, // ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prAL, gcLo}, // SOYOMBO LETTER A + {0x11A51, 0x11A56, prCM, gcMn}, // [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prCM, gcMc}, // [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prCM, gcMn}, // [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prAL, gcLo}, // [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prCM, gcMn}, // [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prCM, gcMc}, // SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prCM, gcMn}, // [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9A, 0x11A9C, prBA, gcPo}, // [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prAL, gcLo}, // SOYOMBO MARK PLUTA + {0x11A9E, 0x11AA0, prBB, gcPo}, // [3] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO HEAD MARK WITH MOON AND SUN + {0x11AA1, 0x11AA2, prBA, gcPo}, // [2] SOYOMBO TERMINAL MARK-1..SOYOMBO TERMINAL MARK-2 + {0x11AB0, 0x11ABF, prAL, gcLo}, // [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA + {0x11AC0, 0x11AF8, prAL, gcLo}, // [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL + {0x11B00, 0x11B09, prBB, gcPo}, // [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU + {0x11C00, 0x11C08, prAL, gcLo}, // [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prAL, gcLo}, // [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prCM, gcMc}, // BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prCM, gcMn}, // [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prCM, gcMn}, // [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prCM, gcMc}, // BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prCM, gcMn}, // BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prAL, gcLo}, // BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C45, prBA, gcPo}, // [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 + {0x11C50, 0x11C59, prNU, gcNd}, // [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C5A, 0x11C6C, prAL, gcNo}, // [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK + {0x11C70, 0x11C70, prBB, gcPo}, // MARCHEN HEAD MARK + {0x11C71, 0x11C71, prEX, gcPo}, // MARCHEN MARK SHAD + {0x11C72, 0x11C8F, prAL, gcLo}, // [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prCM, gcMn}, // [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prCM, gcMc}, // MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prCM, gcMn}, // [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prCM, gcMc}, // MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prCM, gcMn}, // [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prCM, gcMc}, // MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prCM, gcMn}, // [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prAL, gcLo}, // [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prAL, gcLo}, // [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prAL, gcLo}, // [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prCM, gcMn}, // [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prCM, gcMn}, // MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prCM, gcMn}, // [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prCM, gcMn}, // [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prAL, gcLo}, // MASARAM GONDI REPHA + {0x11D47, 0x11D47, prCM, gcMn}, // MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNU, gcNd}, // [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prAL, gcLo}, // [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prAL, gcLo}, // [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prAL, gcLo}, // [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prCM, gcMc}, // [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prCM, gcMn}, // [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prCM, gcMc}, // [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prCM, gcMn}, // GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prCM, gcMc}, // GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prCM, gcMn}, // GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prAL, gcLo}, // GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNU, gcNd}, // [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prAL, gcLo}, // [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prCM, gcMn}, // [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prCM, gcMc}, // [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prAL, gcPo}, // [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prCM, gcMn}, // [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prAL, gcLo}, // KAWI SIGN REPHA + {0x11F03, 0x11F03, prCM, gcMc}, // KAWI SIGN VISARGA + {0x11F04, 0x11F10, prAL, gcLo}, // [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prAL, gcLo}, // [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prCM, gcMc}, // [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prCM, gcMn}, // [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prCM, gcMc}, // [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prCM, gcMn}, // KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prCM, gcMc}, // KAWI SIGN KILLER + {0x11F42, 0x11F42, prCM, gcMn}, // KAWI CONJOINER + {0x11F43, 0x11F44, prBA, gcPo}, // [2] KAWI DANDA..KAWI DOUBLE DANDA + {0x11F45, 0x11F4F, prID, gcPo}, // [11] KAWI PUNCTUATION SECTION MARKER..KAWI PUNCTUATION CLOSING SPIRAL + {0x11F50, 0x11F59, prNU, gcNd}, // [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prAL, gcLo}, // LISU LETTER YHA + {0x11FC0, 0x11FD4, prAL, gcNo}, // [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH + {0x11FD5, 0x11FDC, prAL, gcSo}, // [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI + {0x11FDD, 0x11FE0, prPO, gcSc}, // [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN + {0x11FE1, 0x11FF1, prAL, gcSo}, // [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA + {0x11FFF, 0x11FFF, prBA, gcPo}, // TAMIL PUNCTUATION END OF TEXT + {0x12000, 0x12399, prAL, gcLo}, // [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prAL, gcNl}, // [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12470, 0x12474, prBA, gcPo}, // [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON + {0x12480, 0x12543, prAL, gcLo}, // [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prAL, gcLo}, // [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x12FF1, 0x12FF2, prAL, gcPo}, // [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 + {0x13000, 0x13257, prAL, gcLo}, // [600] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH O006 + {0x13258, 0x1325A, prOP, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006A..EGYPTIAN HIEROGLYPH O006C + {0x1325B, 0x1325D, prCL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006D..EGYPTIAN HIEROGLYPH O006F + {0x1325E, 0x13281, prAL, gcLo}, // [36] EGYPTIAN HIEROGLYPH O007..EGYPTIAN HIEROGLYPH O033 + {0x13282, 0x13282, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O033A + {0x13283, 0x13285, prAL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O034..EGYPTIAN HIEROGLYPH O036 + {0x13286, 0x13286, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036A + {0x13287, 0x13287, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036B + {0x13288, 0x13288, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036C + {0x13289, 0x13289, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036D + {0x1328A, 0x13378, prAL, gcLo}, // [239] EGYPTIAN HIEROGLYPH O037..EGYPTIAN HIEROGLYPH V011 + {0x13379, 0x13379, prOP, gcLo}, // EGYPTIAN HIEROGLYPH V011A + {0x1337A, 0x1337B, prCL, gcLo}, // [2] EGYPTIAN HIEROGLYPH V011B..EGYPTIAN HIEROGLYPH V011C + {0x1337C, 0x1342F, prAL, gcLo}, // [180] EGYPTIAN HIEROGLYPH V012..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x13436, prGL, gcCf}, // [7] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH OVERLAY MIDDLE + {0x13437, 0x13437, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN SEGMENT + {0x13438, 0x13438, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END SEGMENT + {0x13439, 0x1343B, prGL, gcCf}, // [3] EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH INSERT AT BOTTOM + {0x1343C, 0x1343C, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE + {0x1343D, 0x1343D, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END ENCLOSURE + {0x1343E, 0x1343E, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE + {0x1343F, 0x1343F, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prCM, gcMn}, // EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prAL, gcLo}, // [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prCM, gcMn}, // [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x145CD, prAL, gcLo}, // [462] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A409 + {0x145CE, 0x145CE, prOP, gcLo}, // ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK + {0x145CF, 0x145CF, prCL, gcLo}, // ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK + {0x145D0, 0x14646, prAL, gcLo}, // [119] ANATOLIAN HIEROGLYPH A411..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prAL, gcLo}, // [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prAL, gcLo}, // [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNU, gcNd}, // [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prBA, gcPo}, // [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prAL, gcLo}, // [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNU, gcNd}, // [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prAL, gcLo}, // [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prCM, gcMn}, // [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prBA, gcPo}, // BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prAL, gcLo}, // [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prCM, gcMn}, // [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B39, prBA, gcPo}, // [3] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN CIM CHEEM + {0x16B3A, 0x16B3B, prAL, gcPo}, // [2] PAHAWH HMONG SIGN VOS THIAB..PAHAWH HMONG SIGN VOS FEEM + {0x16B3C, 0x16B3F, prAL, gcSo}, // [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB + {0x16B40, 0x16B43, prAL, gcLm}, // [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prBA, gcPo}, // PAHAWH HMONG SIGN XAUS + {0x16B45, 0x16B45, prAL, gcSo}, // PAHAWH HMONG SIGN CIM TSOV ROG + {0x16B50, 0x16B59, prNU, gcNd}, // [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B5B, 0x16B61, prAL, gcNo}, // [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS + {0x16B63, 0x16B77, prAL, gcLo}, // [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prAL, gcLo}, // [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prAL, gcLC}, // [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E80, 0x16E96, prAL, gcNo}, // [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM + {0x16E97, 0x16E98, prBA, gcPo}, // [2] MEDEFAIDRIN COMMA..MEDEFAIDRIN FULL STOP + {0x16E99, 0x16E9A, prAL, gcPo}, // [2] MEDEFAIDRIN SYMBOL AIVA..MEDEFAIDRIN EXCLAMATION OH + {0x16F00, 0x16F4A, prAL, gcLo}, // [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prCM, gcMn}, // MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prAL, gcLo}, // MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prCM, gcMc}, // [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prCM, gcMn}, // [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prAL, gcLm}, // [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prNS, gcLm}, // [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE2, 0x16FE2, prNS, gcPo}, // OLD CHINESE HOOK MARK + {0x16FE3, 0x16FE3, prNS, gcLm}, // OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prGL, gcMn}, // KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prCM, gcMc}, // [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prID, gcLo}, // [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18AFF, prID, gcLo}, // [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768 + {0x18B00, 0x18CD5, prAL, gcLo}, // [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prID, gcLo}, // [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prAL, gcLm}, // [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prAL, gcLm}, // [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prAL, gcLm}, // [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B0FF, prID, gcLo}, // [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 + {0x1B100, 0x1B122, prID, gcLo}, // [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prCJ, gcLo}, // HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prCJ, gcLo}, // [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prCJ, gcLo}, // KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prCJ, gcLo}, // [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prID, gcLo}, // [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prAL, gcLo}, // [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prAL, gcLo}, // [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prAL, gcLo}, // [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prAL, gcLo}, // [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9C, 0x1BC9C, prAL, gcSo}, // DUPLOYAN SIGN O WITH CROSS + {0x1BC9D, 0x1BC9E, prCM, gcMn}, // [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prBA, gcPo}, // DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prCM, gcCf}, // [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prCM, gcMn}, // [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prCM, gcMn}, // [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1CF50, 0x1CFC3, prAL, gcSo}, // [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK + {0x1D000, 0x1D0F5, prAL, gcSo}, // [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO + {0x1D100, 0x1D126, prAL, gcSo}, // [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 + {0x1D129, 0x1D164, prAL, gcSo}, // [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE + {0x1D165, 0x1D166, prCM, gcMc}, // [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prCM, gcMn}, // [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16A, 0x1D16C, prAL, gcSo}, // [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 + {0x1D16D, 0x1D172, prCM, gcMc}, // [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prCM, gcCf}, // [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prCM, gcMn}, // [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D183, 0x1D184, prAL, gcSo}, // [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN + {0x1D185, 0x1D18B, prCM, gcMn}, // [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D18C, 0x1D1A9, prAL, gcSo}, // [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH + {0x1D1AA, 0x1D1AD, prCM, gcMn}, // [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D1AE, 0x1D1EA, prAL, gcSo}, // [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON + {0x1D200, 0x1D241, prAL, gcSo}, // [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 + {0x1D242, 0x1D244, prCM, gcMn}, // [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D245, 0x1D245, prAL, gcSo}, // GREEK MUSICAL LEIMMA + {0x1D2C0, 0x1D2D3, prAL, gcNo}, // [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN + {0x1D2E0, 0x1D2F3, prAL, gcNo}, // [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN + {0x1D300, 0x1D356, prAL, gcSo}, // [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING + {0x1D360, 0x1D378, prAL, gcNo}, // [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE + {0x1D400, 0x1D454, prAL, gcLC}, // [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prAL, gcLC}, // [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prAL, gcLu}, // MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prAL, gcLu}, // [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prAL, gcLC}, // [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prAL, gcLl}, // MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prAL, gcLl}, // [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prAL, gcLC}, // [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prAL, gcLu}, // [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prAL, gcLu}, // [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prAL, gcLu}, // [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prAL, gcLC}, // [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prAL, gcLu}, // [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prAL, gcLu}, // [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prAL, gcLu}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prAL, gcLu}, // [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prAL, gcLC}, // [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prAL, gcLu}, // [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C1, 0x1D6C1, prAL, gcSm}, // MATHEMATICAL BOLD NABLA + {0x1D6C2, 0x1D6DA, prAL, gcLl}, // [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DB, 0x1D6DB, prAL, gcSm}, // MATHEMATICAL BOLD PARTIAL DIFFERENTIAL + {0x1D6DC, 0x1D6FA, prAL, gcLC}, // [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FB, 0x1D6FB, prAL, gcSm}, // MATHEMATICAL ITALIC NABLA + {0x1D6FC, 0x1D714, prAL, gcLl}, // [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D715, 0x1D715, prAL, gcSm}, // MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL + {0x1D716, 0x1D734, prAL, gcLC}, // [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D735, 0x1D735, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC NABLA + {0x1D736, 0x1D74E, prAL, gcLl}, // [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D74F, 0x1D74F, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D750, 0x1D76E, prAL, gcLC}, // [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D76F, 0x1D76F, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD NABLA + {0x1D770, 0x1D788, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D789, 0x1D789, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL + {0x1D78A, 0x1D7A8, prAL, gcLC}, // [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7A9, 0x1D7A9, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA + {0x1D7AA, 0x1D7C2, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C3, 0x1D7C3, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D7C4, 0x1D7CB, prAL, gcLC}, // [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNU, gcNd}, // [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1D800, 0x1D9FF, prAL, gcSo}, // [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD + {0x1DA00, 0x1DA36, prCM, gcMn}, // [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA37, 0x1DA3A, prAL, gcSo}, // [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE + {0x1DA3B, 0x1DA6C, prCM, gcMn}, // [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA6D, 0x1DA74, prAL, gcSo}, // [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING + {0x1DA75, 0x1DA75, prCM, gcMn}, // SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA76, 0x1DA83, prAL, gcSo}, // [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH + {0x1DA84, 0x1DA84, prCM, gcMn}, // SIGNWRITING LOCATION HEAD NECK + {0x1DA85, 0x1DA86, prAL, gcSo}, // [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS + {0x1DA87, 0x1DA8A, prBA, gcPo}, // [4] SIGNWRITING COMMA..SIGNWRITING COLON + {0x1DA8B, 0x1DA8B, prAL, gcPo}, // SIGNWRITING PARENTHESIS + {0x1DA9B, 0x1DA9F, prCM, gcMn}, // [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prCM, gcMn}, // [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prAL, gcLl}, // [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prAL, gcLo}, // LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prAL, gcLl}, // [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prAL, gcLl}, // [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prCM, gcMn}, // [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prCM, gcMn}, // [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prCM, gcMn}, // [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prAL, gcLm}, // [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prCM, gcMn}, // COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prAL, gcLo}, // [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prCM, gcMn}, // [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prAL, gcLm}, // [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNU, gcNd}, // [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prAL, gcLo}, // NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E14F, 0x1E14F, prAL, gcSo}, // NYIAKENG PUACHUE HMONG CIRCLED CA + {0x1E290, 0x1E2AD, prAL, gcLo}, // [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prCM, gcMn}, // TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prAL, gcLo}, // [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prCM, gcMn}, // [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNU, gcNd}, // [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E2FF, 0x1E2FF, prPR, gcSc}, // WANCHO NGUN SIGN + {0x1E4D0, 0x1E4EA, prAL, gcLo}, // [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prAL, gcLm}, // NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prCM, gcMn}, // [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNU, gcNd}, // [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prAL, gcLo}, // [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prAL, gcLo}, // [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8C7, 0x1E8CF, prAL, gcNo}, // [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE + {0x1E8D0, 0x1E8D6, prCM, gcMn}, // [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prAL, gcLC}, // [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prCM, gcMn}, // [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prAL, gcLm}, // ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNU, gcNd}, // [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1E95E, 0x1E95F, prOP, gcPo}, // [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK + {0x1EC71, 0x1ECAB, prAL, gcNo}, // [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE + {0x1ECAC, 0x1ECAC, prPO, gcSo}, // INDIC SIYAQ PLACEHOLDER + {0x1ECAD, 0x1ECAF, prAL, gcNo}, // [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS + {0x1ECB0, 0x1ECB0, prPO, gcSc}, // INDIC SIYAQ RUPEE MARK + {0x1ECB1, 0x1ECB4, prAL, gcNo}, // [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK + {0x1ED01, 0x1ED2D, prAL, gcNo}, // [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND + {0x1ED2E, 0x1ED2E, prAL, gcSo}, // OTTOMAN SIYAQ MARRATAN + {0x1ED2F, 0x1ED3D, prAL, gcNo}, // [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH + {0x1EE00, 0x1EE03, prAL, gcLo}, // [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prAL, gcLo}, // [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prAL, gcLo}, // [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prAL, gcLo}, // [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prAL, gcLo}, // [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prAL, gcLo}, // [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prAL, gcLo}, // [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prAL, gcLo}, // [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prAL, gcLo}, // [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prAL, gcLo}, // [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prAL, gcLo}, // [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prAL, gcLo}, // [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prAL, gcLo}, // [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prAL, gcLo}, // [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1EEF0, 0x1EEF1, prAL, gcSm}, // [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL + {0x1F000, 0x1F02B, prID, gcSo}, // [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK + {0x1F02C, 0x1F02F, prID, gcCn}, // [4] .. + {0x1F030, 0x1F093, prID, gcSo}, // [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 + {0x1F094, 0x1F09F, prID, gcCn}, // [12] .. + {0x1F0A0, 0x1F0AE, prID, gcSo}, // [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES + {0x1F0AF, 0x1F0B0, prID, gcCn}, // [2] .. + {0x1F0B1, 0x1F0BF, prID, gcSo}, // [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER + {0x1F0C0, 0x1F0C0, prID, gcCn}, // + {0x1F0C1, 0x1F0CF, prID, gcSo}, // [15] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD BLACK JOKER + {0x1F0D0, 0x1F0D0, prID, gcCn}, // + {0x1F0D1, 0x1F0F5, prID, gcSo}, // [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 + {0x1F0F6, 0x1F0FF, prID, gcCn}, // [10] .. + {0x1F100, 0x1F10C, prAI, gcNo}, // [13] DIGIT ZERO FULL STOP..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO + {0x1F10D, 0x1F10F, prID, gcSo}, // [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F110, 0x1F12D, prAI, gcSo}, // [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD + {0x1F12E, 0x1F12F, prAL, gcSo}, // [2] CIRCLED WZ..COPYLEFT SYMBOL + {0x1F130, 0x1F169, prAI, gcSo}, // [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16A, 0x1F16C, prAL, gcSo}, // [3] RAISED MC SIGN..RAISED MR SIGN + {0x1F16D, 0x1F16F, prID, gcSo}, // [3] CIRCLED CC..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F1AC, prAI, gcSo}, // [61] NEGATIVE SQUARED LATIN CAPITAL LETTER A..SQUARED VOD + {0x1F1AD, 0x1F1AD, prID, gcSo}, // MASK WORK SYMBOL + {0x1F1AE, 0x1F1E5, prID, gcCn}, // [56] .. + {0x1F1E6, 0x1F1FF, prRI, gcSo}, // [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F200, 0x1F202, prID, gcSo}, // [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA + {0x1F203, 0x1F20F, prID, gcCn}, // [13] .. + {0x1F210, 0x1F23B, prID, gcSo}, // [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D + {0x1F23C, 0x1F23F, prID, gcCn}, // [4] .. + {0x1F240, 0x1F248, prID, gcSo}, // [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 + {0x1F249, 0x1F24F, prID, gcCn}, // [7] .. + {0x1F250, 0x1F251, prID, gcSo}, // [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT + {0x1F252, 0x1F25F, prID, gcCn}, // [14] .. + {0x1F260, 0x1F265, prID, gcSo}, // [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI + {0x1F266, 0x1F2FF, prID, gcCn}, // [154] .. + {0x1F300, 0x1F384, prID, gcSo}, // [133] CYCLONE..CHRISTMAS TREE + {0x1F385, 0x1F385, prEB, gcSo}, // FATHER CHRISTMAS + {0x1F386, 0x1F39B, prID, gcSo}, // [22] FIREWORKS..CONTROL KNOBS + {0x1F39C, 0x1F39D, prAL, gcSo}, // [2] BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F3B4, prID, gcSo}, // [23] FILM FRAMES..FLOWER PLAYING CARDS + {0x1F3B5, 0x1F3B6, prAL, gcSo}, // [2] MUSICAL NOTE..MULTIPLE MUSICAL NOTES + {0x1F3B7, 0x1F3BB, prID, gcSo}, // [5] SAXOPHONE..VIOLIN + {0x1F3BC, 0x1F3BC, prAL, gcSo}, // MUSICAL SCORE + {0x1F3BD, 0x1F3C1, prID, gcSo}, // [5] RUNNING SHIRT WITH SASH..CHEQUERED FLAG + {0x1F3C2, 0x1F3C4, prEB, gcSo}, // [3] SNOWBOARDER..SURFER + {0x1F3C5, 0x1F3C6, prID, gcSo}, // [2] SPORTS MEDAL..TROPHY + {0x1F3C7, 0x1F3C7, prEB, gcSo}, // HORSE RACING + {0x1F3C8, 0x1F3C9, prID, gcSo}, // [2] AMERICAN FOOTBALL..RUGBY FOOTBALL + {0x1F3CA, 0x1F3CC, prEB, gcSo}, // [3] SWIMMER..GOLFER + {0x1F3CD, 0x1F3FA, prID, gcSo}, // [46] RACING MOTORCYCLE..AMPHORA + {0x1F3FB, 0x1F3FF, prEM, gcSk}, // [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F441, prID, gcSo}, // [66] RAT..EYE + {0x1F442, 0x1F443, prEB, gcSo}, // [2] EAR..NOSE + {0x1F444, 0x1F445, prID, gcSo}, // [2] MOUTH..TONGUE + {0x1F446, 0x1F450, prEB, gcSo}, // [11] WHITE UP POINTING BACKHAND INDEX..OPEN HANDS SIGN + {0x1F451, 0x1F465, prID, gcSo}, // [21] CROWN..BUSTS IN SILHOUETTE + {0x1F466, 0x1F478, prEB, gcSo}, // [19] BOY..PRINCESS + {0x1F479, 0x1F47B, prID, gcSo}, // [3] JAPANESE OGRE..GHOST + {0x1F47C, 0x1F47C, prEB, gcSo}, // BABY ANGEL + {0x1F47D, 0x1F480, prID, gcSo}, // [4] EXTRATERRESTRIAL ALIEN..SKULL + {0x1F481, 0x1F483, prEB, gcSo}, // [3] INFORMATION DESK PERSON..DANCER + {0x1F484, 0x1F484, prID, gcSo}, // LIPSTICK + {0x1F485, 0x1F487, prEB, gcSo}, // [3] NAIL POLISH..HAIRCUT + {0x1F488, 0x1F48E, prID, gcSo}, // [7] BARBER POLE..GEM STONE + {0x1F48F, 0x1F48F, prEB, gcSo}, // KISS + {0x1F490, 0x1F490, prID, gcSo}, // BOUQUET + {0x1F491, 0x1F491, prEB, gcSo}, // COUPLE WITH HEART + {0x1F492, 0x1F49F, prID, gcSo}, // [14] WEDDING..HEART DECORATION + {0x1F4A0, 0x1F4A0, prAL, gcSo}, // DIAMOND SHAPE WITH A DOT INSIDE + {0x1F4A1, 0x1F4A1, prID, gcSo}, // ELECTRIC LIGHT BULB + {0x1F4A2, 0x1F4A2, prAL, gcSo}, // ANGER SYMBOL + {0x1F4A3, 0x1F4A3, prID, gcSo}, // BOMB + {0x1F4A4, 0x1F4A4, prAL, gcSo}, // SLEEPING SYMBOL + {0x1F4A5, 0x1F4A9, prID, gcSo}, // [5] COLLISION SYMBOL..PILE OF POO + {0x1F4AA, 0x1F4AA, prEB, gcSo}, // FLEXED BICEPS + {0x1F4AB, 0x1F4AE, prID, gcSo}, // [4] DIZZY SYMBOL..WHITE FLOWER + {0x1F4AF, 0x1F4AF, prAL, gcSo}, // HUNDRED POINTS SYMBOL + {0x1F4B0, 0x1F4B0, prID, gcSo}, // MONEY BAG + {0x1F4B1, 0x1F4B2, prAL, gcSo}, // [2] CURRENCY EXCHANGE..HEAVY DOLLAR SIGN + {0x1F4B3, 0x1F4FF, prID, gcSo}, // [77] CREDIT CARD..PRAYER BEADS + {0x1F500, 0x1F506, prAL, gcSo}, // [7] TWISTED RIGHTWARDS ARROWS..HIGH BRIGHTNESS SYMBOL + {0x1F507, 0x1F516, prID, gcSo}, // [16] SPEAKER WITH CANCELLATION STROKE..BOOKMARK + {0x1F517, 0x1F524, prAL, gcSo}, // [14] LINK SYMBOL..INPUT SYMBOL FOR LATIN LETTERS + {0x1F525, 0x1F531, prID, gcSo}, // [13] FIRE..TRIDENT EMBLEM + {0x1F532, 0x1F549, prAL, gcSo}, // [24] BLACK SQUARE BUTTON..OM SYMBOL + {0x1F54A, 0x1F573, prID, gcSo}, // [42] DOVE OF PEACE..HOLE + {0x1F574, 0x1F575, prEB, gcSo}, // [2] MAN IN BUSINESS SUIT LEVITATING..SLEUTH OR SPY + {0x1F576, 0x1F579, prID, gcSo}, // [4] DARK SUNGLASSES..JOYSTICK + {0x1F57A, 0x1F57A, prEB, gcSo}, // MAN DANCING + {0x1F57B, 0x1F58F, prID, gcSo}, // [21] LEFT HAND TELEPHONE RECEIVER..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prEB, gcSo}, // RAISED HAND WITH FINGERS SPLAYED + {0x1F591, 0x1F594, prID, gcSo}, // [4] REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prEB, gcSo}, // [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS + {0x1F597, 0x1F5D3, prID, gcSo}, // [61] WHITE DOWN POINTING LEFT HAND INDEX..SPIRAL CALENDAR PAD + {0x1F5D4, 0x1F5DB, prAL, gcSo}, // [8] DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5F3, prID, gcSo}, // [24] COMPRESSION..BALLOT BOX WITH BALLOT + {0x1F5F4, 0x1F5F9, prAL, gcSo}, // [6] BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FF, prID, gcSo}, // [6] WORLD MAP..MOYAI + {0x1F600, 0x1F644, prID, gcSo}, // [69] GRINNING FACE..FACE WITH ROLLING EYES + {0x1F645, 0x1F647, prEB, gcSo}, // [3] FACE WITH NO GOOD GESTURE..PERSON BOWING DEEPLY + {0x1F648, 0x1F64A, prID, gcSo}, // [3] SEE-NO-EVIL MONKEY..SPEAK-NO-EVIL MONKEY + {0x1F64B, 0x1F64F, prEB, gcSo}, // [5] HAPPY PERSON RAISING ONE HAND..PERSON WITH FOLDED HANDS + {0x1F650, 0x1F675, prAL, gcSo}, // [38] NORTH WEST POINTING LEAF..SWASH AMPERSAND ORNAMENT + {0x1F676, 0x1F678, prQU, gcSo}, // [3] SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT..SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x1F679, 0x1F67B, prNS, gcSo}, // [3] HEAVY INTERROBANG ORNAMENT..HEAVY SANS-SERIF INTERROBANG ORNAMENT + {0x1F67C, 0x1F67F, prAL, gcSo}, // [4] VERY HEAVY SOLIDUS..REVERSE CHECKER BOARD + {0x1F680, 0x1F6A2, prID, gcSo}, // [35] ROCKET..SHIP + {0x1F6A3, 0x1F6A3, prEB, gcSo}, // ROWBOAT + {0x1F6A4, 0x1F6B3, prID, gcSo}, // [16] SPEEDBOAT..NO BICYCLES + {0x1F6B4, 0x1F6B6, prEB, gcSo}, // [3] BICYCLIST..PEDESTRIAN + {0x1F6B7, 0x1F6BF, prID, gcSo}, // [9] NO PEDESTRIANS..SHOWER + {0x1F6C0, 0x1F6C0, prEB, gcSo}, // BATH + {0x1F6C1, 0x1F6CB, prID, gcSo}, // [11] BATHTUB..COUCH AND LAMP + {0x1F6CC, 0x1F6CC, prEB, gcSo}, // SLEEPING ACCOMMODATION + {0x1F6CD, 0x1F6D7, prID, gcSo}, // [11] SHOPPING BAGS..ELEVATOR + {0x1F6D8, 0x1F6DB, prID, gcCn}, // [4] .. + {0x1F6DC, 0x1F6EC, prID, gcSo}, // [17] WIRELESS..AIRPLANE ARRIVING + {0x1F6ED, 0x1F6EF, prID, gcCn}, // [3] .. + {0x1F6F0, 0x1F6FC, prID, gcSo}, // [13] SATELLITE..ROLLER SKATE + {0x1F6FD, 0x1F6FF, prID, gcCn}, // [3] .. + {0x1F700, 0x1F773, prAL, gcSo}, // [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE + {0x1F774, 0x1F776, prID, gcSo}, // [3] LOT OF FORTUNE..LUNAR ECLIPSE + {0x1F777, 0x1F77A, prID, gcCn}, // [4] .. + {0x1F77B, 0x1F77F, prID, gcSo}, // [5] HAUMEA..ORCUS + {0x1F780, 0x1F7D4, prAL, gcSo}, // [85] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR + {0x1F7D5, 0x1F7D9, prID, gcSo}, // [5] CIRCLED TRIANGLE..NINE POINTED WHITE STAR + {0x1F7DA, 0x1F7DF, prID, gcCn}, // [6] .. + {0x1F7E0, 0x1F7EB, prID, gcSo}, // [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE + {0x1F7EC, 0x1F7EF, prID, gcCn}, // [4] .. + {0x1F7F0, 0x1F7F0, prID, gcSo}, // HEAVY EQUALS SIGN + {0x1F7F1, 0x1F7FF, prID, gcCn}, // [15] .. + {0x1F800, 0x1F80B, prAL, gcSo}, // [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD + {0x1F80C, 0x1F80F, prID, gcCn}, // [4] .. + {0x1F810, 0x1F847, prAL, gcSo}, // [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW + {0x1F848, 0x1F84F, prID, gcCn}, // [8] .. + {0x1F850, 0x1F859, prAL, gcSo}, // [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW + {0x1F85A, 0x1F85F, prID, gcCn}, // [6] .. + {0x1F860, 0x1F887, prAL, gcSo}, // [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW + {0x1F888, 0x1F88F, prID, gcCn}, // [8] .. + {0x1F890, 0x1F8AD, prAL, gcSo}, // [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS + {0x1F8AE, 0x1F8AF, prID, gcCn}, // [2] .. + {0x1F8B0, 0x1F8B1, prID, gcSo}, // [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST + {0x1F8B2, 0x1F8FF, prID, gcCn}, // [78] .. + {0x1F900, 0x1F90B, prAL, gcSo}, // [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT + {0x1F90C, 0x1F90C, prEB, gcSo}, // PINCHED FINGERS + {0x1F90D, 0x1F90E, prID, gcSo}, // [2] WHITE HEART..BROWN HEART + {0x1F90F, 0x1F90F, prEB, gcSo}, // PINCHING HAND + {0x1F910, 0x1F917, prID, gcSo}, // [8] ZIPPER-MOUTH FACE..HUGGING FACE + {0x1F918, 0x1F91F, prEB, gcSo}, // [8] SIGN OF THE HORNS..I LOVE YOU HAND SIGN + {0x1F920, 0x1F925, prID, gcSo}, // [6] FACE WITH COWBOY HAT..LYING FACE + {0x1F926, 0x1F926, prEB, gcSo}, // FACE PALM + {0x1F927, 0x1F92F, prID, gcSo}, // [9] SNEEZING FACE..SHOCKED FACE WITH EXPLODING HEAD + {0x1F930, 0x1F939, prEB, gcSo}, // [10] PREGNANT WOMAN..JUGGLING + {0x1F93A, 0x1F93B, prID, gcSo}, // [2] FENCER..MODERN PENTATHLON + {0x1F93C, 0x1F93E, prEB, gcSo}, // [3] WRESTLERS..HANDBALL + {0x1F93F, 0x1F976, prID, gcSo}, // [56] DIVING MASK..FREEZING FACE + {0x1F977, 0x1F977, prEB, gcSo}, // NINJA + {0x1F978, 0x1F9B4, prID, gcSo}, // [61] DISGUISED FACE..BONE + {0x1F9B5, 0x1F9B6, prEB, gcSo}, // [2] LEG..FOOT + {0x1F9B7, 0x1F9B7, prID, gcSo}, // TOOTH + {0x1F9B8, 0x1F9B9, prEB, gcSo}, // [2] SUPERHERO..SUPERVILLAIN + {0x1F9BA, 0x1F9BA, prID, gcSo}, // SAFETY VEST + {0x1F9BB, 0x1F9BB, prEB, gcSo}, // EAR WITH HEARING AID + {0x1F9BC, 0x1F9CC, prID, gcSo}, // [17] MOTORIZED WHEELCHAIR..TROLL + {0x1F9CD, 0x1F9CF, prEB, gcSo}, // [3] STANDING PERSON..DEAF PERSON + {0x1F9D0, 0x1F9D0, prID, gcSo}, // FACE WITH MONOCLE + {0x1F9D1, 0x1F9DD, prEB, gcSo}, // [13] ADULT..ELF + {0x1F9DE, 0x1F9FF, prID, gcSo}, // [34] GENIE..NAZAR AMULET + {0x1FA00, 0x1FA53, prAL, gcSo}, // [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP + {0x1FA54, 0x1FA5F, prID, gcCn}, // [12] .. + {0x1FA60, 0x1FA6D, prID, gcSo}, // [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER + {0x1FA6E, 0x1FA6F, prID, gcCn}, // [2] .. + {0x1FA70, 0x1FA7C, prID, gcSo}, // [13] BALLET SHOES..CRUTCH + {0x1FA7D, 0x1FA7F, prID, gcCn}, // [3] .. + {0x1FA80, 0x1FA88, prID, gcSo}, // [9] YO-YO..FLUTE + {0x1FA89, 0x1FA8F, prID, gcCn}, // [7] .. + {0x1FA90, 0x1FABD, prID, gcSo}, // [46] RINGED PLANET..WING + {0x1FABE, 0x1FABE, prID, gcCn}, // + {0x1FABF, 0x1FAC2, prID, gcSo}, // [4] GOOSE..PEOPLE HUGGING + {0x1FAC3, 0x1FAC5, prEB, gcSo}, // [3] PREGNANT MAN..PERSON WITH CROWN + {0x1FAC6, 0x1FACD, prID, gcCn}, // [8] .. + {0x1FACE, 0x1FADB, prID, gcSo}, // [14] MOOSE..PEA POD + {0x1FADC, 0x1FADF, prID, gcCn}, // [4] .. + {0x1FAE0, 0x1FAE8, prID, gcSo}, // [9] MELTING FACE..SHAKING FACE + {0x1FAE9, 0x1FAEF, prID, gcCn}, // [7] .. + {0x1FAF0, 0x1FAF8, prEB, gcSo}, // [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND + {0x1FAF9, 0x1FAFF, prID, gcCn}, // [7] .. + {0x1FB00, 0x1FB92, prAL, gcSo}, // [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK + {0x1FB94, 0x1FBCA, prAL, gcSo}, // [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON + {0x1FBF0, 0x1FBF9, prNU, gcNd}, // [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x1FC00, 0x1FFFD, prID, gcCn}, // [1022] .. + {0x20000, 0x2A6DF, prID, gcLo}, // [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A6E0, 0x2A6FF, prID, gcCn}, // [32] .. + {0x2A700, 0x2B739, prID, gcLo}, // [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B73A, 0x2B73F, prID, gcCn}, // [6] .. + {0x2B740, 0x2B81D, prID, gcLo}, // [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B81E, 0x2B81F, prID, gcCn}, // [2] .. + {0x2B820, 0x2CEA1, prID, gcLo}, // [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEA2, 0x2CEAF, prID, gcCn}, // [14] .. + {0x2CEB0, 0x2EBE0, prID, gcLo}, // [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2EBE1, 0x2F7FF, prID, gcCn}, // [3103] .. + {0x2F800, 0x2FA1D, prID, gcLo}, // [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x2FA1E, 0x2FA1F, prID, gcCn}, // [2] .. + {0x2FA20, 0x2FFFD, prID, gcCn}, // [1502] .. + {0x30000, 0x3134A, prID, gcLo}, // [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x3134B, 0x3134F, prID, gcCn}, // [5] .. + {0x31350, 0x323AF, prID, gcLo}, // [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0x323B0, 0x3FFFD, prID, gcCn}, // [56398] .. + {0xE0001, 0xE0001, prCM, gcCf}, // LANGUAGE TAG + {0xE0020, 0xE007F, prCM, gcCf}, // [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prCM, gcMn}, // [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xF0000, 0xFFFFD, prXX, gcCo}, // [65534] .. + {0x100000, 0x10FFFD, prXX, gcCo}, // [65534] .. +} diff --git a/vendor/github.com/rivo/uniseg/linerules.go b/vendor/github.com/rivo/uniseg/linerules.go new file mode 100644 index 000000000000..7708ae0fbe15 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/linerules.go @@ -0,0 +1,626 @@ +package uniseg + +import "unicode/utf8" + +// The states of the line break parser. +const ( + lbAny = iota + lbBK + lbCR + lbLF + lbNL + lbSP + lbZW + lbWJ + lbGL + lbBA + lbHY + lbCL + lbCP + lbEX + lbIS + lbSY + lbOP + lbQU + lbQUSP + lbNS + lbCLCPSP + lbB2 + lbB2SP + lbCB + lbBB + lbLB21a + lbHL + lbAL + lbNU + lbPR + lbEB + lbIDEM + lbNUNU + lbNUSY + lbNUIS + lbNUCL + lbNUCP + lbPO + lbJL + lbJV + lbJT + lbH2 + lbH3 + lbOddRI + lbEvenRI + lbExtPicCn + lbZWJBit = 64 + lbCPeaFWHBit = 128 +) + +// These constants define whether a given text may be broken into the next line. +// If the break is optional (LineCanBreak), you may choose to break or not based +// on your own criteria, for example, if the text has reached the available +// width. +const ( + LineDontBreak = iota // You may not break the line here. + LineCanBreak // You may or may not break the line here. + LineMustBreak // You must break the line here. +) + +// lbTransitions implements the line break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func lbTransitions(state, prop int) (newState, lineBreak, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // LB4. + case lbBK | prAny<<32: + return lbAny, LineMustBreak, 40 + + // LB5. + case lbCR | prLF<<32: + return lbLF, LineDontBreak, 50 + case lbCR | prAny<<32: + return lbAny, LineMustBreak, 50 + case lbLF | prAny<<32: + return lbAny, LineMustBreak, 50 + case lbNL | prAny<<32: + return lbAny, LineMustBreak, 50 + + // LB6. + case lbAny | prBK<<32: + return lbBK, LineDontBreak, 60 + case lbAny | prCR<<32: + return lbCR, LineDontBreak, 60 + case lbAny | prLF<<32: + return lbLF, LineDontBreak, 60 + case lbAny | prNL<<32: + return lbNL, LineDontBreak, 60 + + // LB7. + case lbAny | prSP<<32: + return lbSP, LineDontBreak, 70 + case lbAny | prZW<<32: + return lbZW, LineDontBreak, 70 + + // LB8. + case lbZW | prSP<<32: + return lbZW, LineDontBreak, 70 + case lbZW | prAny<<32: + return lbAny, LineCanBreak, 80 + + // LB11. + case lbAny | prWJ<<32: + return lbWJ, LineDontBreak, 110 + case lbWJ | prAny<<32: + return lbAny, LineDontBreak, 110 + + // LB12. + case lbAny | prGL<<32: + return lbGL, LineCanBreak, 310 + case lbGL | prAny<<32: + return lbAny, LineDontBreak, 120 + + // LB13 (simple transitions). + case lbAny | prCL<<32: + return lbCL, LineCanBreak, 310 + case lbAny | prCP<<32: + return lbCP, LineCanBreak, 310 + case lbAny | prEX<<32: + return lbEX, LineDontBreak, 130 + case lbAny | prIS<<32: + return lbIS, LineCanBreak, 310 + case lbAny | prSY<<32: + return lbSY, LineCanBreak, 310 + + // LB14. + case lbAny | prOP<<32: + return lbOP, LineCanBreak, 310 + case lbOP | prSP<<32: + return lbOP, LineDontBreak, 70 + case lbOP | prAny<<32: + return lbAny, LineDontBreak, 140 + + // LB15. + case lbQU | prSP<<32: + return lbQUSP, LineDontBreak, 70 + case lbQU | prOP<<32: + return lbOP, LineDontBreak, 150 + case lbQUSP | prOP<<32: + return lbOP, LineDontBreak, 150 + + // LB16. + case lbCL | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbNUCL | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbCP | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbNUCP | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbCL | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbNUCL | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbCP | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbNUCP | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbCLCPSP | prNS<<32: + return lbNS, LineDontBreak, 160 + + // LB17. + case lbAny | prB2<<32: + return lbB2, LineCanBreak, 310 + case lbB2 | prSP<<32: + return lbB2SP, LineDontBreak, 70 + case lbB2 | prB2<<32: + return lbB2, LineDontBreak, 170 + case lbB2SP | prB2<<32: + return lbB2, LineDontBreak, 170 + + // LB18. + case lbSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbQUSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbCLCPSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbB2SP | prAny<<32: + return lbAny, LineCanBreak, 180 + + // LB19. + case lbAny | prQU<<32: + return lbQU, LineDontBreak, 190 + case lbQU | prAny<<32: + return lbAny, LineDontBreak, 190 + + // LB20. + case lbAny | prCB<<32: + return lbCB, LineCanBreak, 200 + case lbCB | prAny<<32: + return lbAny, LineCanBreak, 200 + + // LB21. + case lbAny | prBA<<32: + return lbBA, LineDontBreak, 210 + case lbAny | prHY<<32: + return lbHY, LineDontBreak, 210 + case lbAny | prNS<<32: + return lbNS, LineDontBreak, 210 + case lbAny | prBB<<32: + return lbBB, LineCanBreak, 310 + case lbBB | prAny<<32: + return lbAny, LineDontBreak, 210 + + // LB21a. + case lbAny | prHL<<32: + return lbHL, LineCanBreak, 310 + case lbHL | prHY<<32: + return lbLB21a, LineDontBreak, 210 + case lbHL | prBA<<32: + return lbLB21a, LineDontBreak, 210 + case lbLB21a | prAny<<32: + return lbAny, LineDontBreak, 211 + + // LB21b. + case lbSY | prHL<<32: + return lbHL, LineDontBreak, 212 + case lbNUSY | prHL<<32: + return lbHL, LineDontBreak, 212 + + // LB22. + case lbAny | prIN<<32: + return lbAny, LineDontBreak, 220 + + // LB23. + case lbAny | prAL<<32: + return lbAL, LineCanBreak, 310 + case lbAny | prNU<<32: + return lbNU, LineCanBreak, 310 + case lbAL | prNU<<32: + return lbNU, LineDontBreak, 230 + case lbHL | prNU<<32: + return lbNU, LineDontBreak, 230 + case lbNU | prAL<<32: + return lbAL, LineDontBreak, 230 + case lbNU | prHL<<32: + return lbHL, LineDontBreak, 230 + case lbNUNU | prAL<<32: + return lbAL, LineDontBreak, 230 + case lbNUNU | prHL<<32: + return lbHL, LineDontBreak, 230 + + // LB23a. + case lbAny | prPR<<32: + return lbPR, LineCanBreak, 310 + case lbAny | prID<<32: + return lbIDEM, LineCanBreak, 310 + case lbAny | prEB<<32: + return lbEB, LineCanBreak, 310 + case lbAny | prEM<<32: + return lbIDEM, LineCanBreak, 310 + case lbPR | prID<<32: + return lbIDEM, LineDontBreak, 231 + case lbPR | prEB<<32: + return lbEB, LineDontBreak, 231 + case lbPR | prEM<<32: + return lbIDEM, LineDontBreak, 231 + case lbIDEM | prPO<<32: + return lbPO, LineDontBreak, 231 + case lbEB | prPO<<32: + return lbPO, LineDontBreak, 231 + + // LB24. + case lbAny | prPO<<32: + return lbPO, LineCanBreak, 310 + case lbPR | prAL<<32: + return lbAL, LineDontBreak, 240 + case lbPR | prHL<<32: + return lbHL, LineDontBreak, 240 + case lbPO | prAL<<32: + return lbAL, LineDontBreak, 240 + case lbPO | prHL<<32: + return lbHL, LineDontBreak, 240 + case lbAL | prPR<<32: + return lbPR, LineDontBreak, 240 + case lbAL | prPO<<32: + return lbPO, LineDontBreak, 240 + case lbHL | prPR<<32: + return lbPR, LineDontBreak, 240 + case lbHL | prPO<<32: + return lbPO, LineDontBreak, 240 + + // LB25 (simple transitions). + case lbPR | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbPO | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbOP | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbHY | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbNU | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNU | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNU | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUNU | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUNU | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUNU | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUSY | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUSY | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUSY | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUIS | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUIS | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUIS | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNU | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNU | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUNU | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUNU | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUSY | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUSY | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUIS | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUIS | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNU | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUNU | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUSY | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUIS | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUCL | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUCP | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNU | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUNU | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUSY | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUIS | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUCL | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUCP | prPR<<32: + return lbPR, LineDontBreak, 250 + + // LB26. + case lbAny | prJL<<32: + return lbJL, LineCanBreak, 310 + case lbAny | prJV<<32: + return lbJV, LineCanBreak, 310 + case lbAny | prJT<<32: + return lbJT, LineCanBreak, 310 + case lbAny | prH2<<32: + return lbH2, LineCanBreak, 310 + case lbAny | prH3<<32: + return lbH3, LineCanBreak, 310 + case lbJL | prJL<<32: + return lbJL, LineDontBreak, 260 + case lbJL | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbJL | prH2<<32: + return lbH2, LineDontBreak, 260 + case lbJL | prH3<<32: + return lbH3, LineDontBreak, 260 + case lbJV | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbJV | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbH2 | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbH2 | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbJT | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbH3 | prJT<<32: + return lbJT, LineDontBreak, 260 + + // LB27. + case lbJL | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbJV | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbJT | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbH2 | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbH3 | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbPR | prJL<<32: + return lbJL, LineDontBreak, 270 + case lbPR | prJV<<32: + return lbJV, LineDontBreak, 270 + case lbPR | prJT<<32: + return lbJT, LineDontBreak, 270 + case lbPR | prH2<<32: + return lbH2, LineDontBreak, 270 + case lbPR | prH3<<32: + return lbH3, LineDontBreak, 270 + + // LB28. + case lbAL | prAL<<32: + return lbAL, LineDontBreak, 280 + case lbAL | prHL<<32: + return lbHL, LineDontBreak, 280 + case lbHL | prAL<<32: + return lbAL, LineDontBreak, 280 + case lbHL | prHL<<32: + return lbHL, LineDontBreak, 280 + + // LB29. + case lbIS | prAL<<32: + return lbAL, LineDontBreak, 290 + case lbIS | prHL<<32: + return lbHL, LineDontBreak, 290 + case lbNUIS | prAL<<32: + return lbAL, LineDontBreak, 290 + case lbNUIS | prHL<<32: + return lbHL, LineDontBreak, 290 + + default: + return -1, -1, -1 + } +} + +// transitionLineBreakState determines the new state of the line break parser +// given the current state and the next code point. It also returns the type of +// line break: LineDontBreak, LineCanBreak, or LineMustBreak. If more than one +// code point is needed to determine the new state, the byte slice or the string +// starting after rune "r" can be used (whichever is not nil or empty) for +// further lookups. +func transitionLineBreakState(state int, r rune, b []byte, str string) (newState int, lineBreak int) { + // Determine the property of the next character. + nextProperty, generalCategory := propertyLineBreak(r) + + // Prepare. + var forceNoBreak, isCPeaFWH bool + if state >= 0 && state&lbCPeaFWHBit != 0 { + isCPeaFWH = true // LB30: CP but ea is not F, W, or H. + state = state &^ lbCPeaFWHBit + } + if state >= 0 && state&lbZWJBit != 0 { + state = state &^ lbZWJBit // Extract zero-width joiner bit. + forceNoBreak = true // LB8a. + } + + defer func() { + // Transition into LB30. + if newState == lbCP || newState == lbNUCP { + ea := propertyEastAsianWidth(r) + if ea != prF && ea != prW && ea != prH { + newState |= lbCPeaFWHBit + } + } + + // Override break. + if forceNoBreak { + lineBreak = LineDontBreak + } + }() + + // LB1. + if nextProperty == prAI || nextProperty == prSG || nextProperty == prXX { + nextProperty = prAL + } else if nextProperty == prSA { + if generalCategory == gcMn || generalCategory == gcMc { + nextProperty = prCM + } else { + nextProperty = prAL + } + } else if nextProperty == prCJ { + nextProperty = prNS + } + + // Combining marks. + if nextProperty == prZWJ || nextProperty == prCM { + var bit int + if nextProperty == prZWJ { + bit = lbZWJBit + } + mustBreakState := state < 0 || state == lbBK || state == lbCR || state == lbLF || state == lbNL + if !mustBreakState && state != lbSP && state != lbZW && state != lbQUSP && state != lbCLCPSP && state != lbB2SP { + // LB9. + return state | bit, LineDontBreak + } else { + // LB10. + if mustBreakState { + return lbAL | bit, LineMustBreak + } + return lbAL | bit, LineCanBreak + } + } + + // Find the applicable transition in the table. + var rule int + newState, lineBreak, rule = lbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropProp, anyPropLineBreak, anyPropRule := lbTransitions(state, prAny) + anyStateProp, anyStateLineBreak, anyStateRule := lbTransitions(lbAny, nextProperty) + if anyPropProp >= 0 && anyStateProp >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule + if anyPropRule < anyStateRule { + lineBreak, rule = anyPropLineBreak, anyPropRule + } + } else if anyPropProp >= 0 { + // We only have a specific state. + newState, lineBreak, rule = anyPropProp, anyPropLineBreak, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateProp >= 0 { + // We only have a specific property. + newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule + } else { + // No known transition. LB31: ALL รท ALL. + newState, lineBreak, rule = lbAny, LineCanBreak, 310 + } + } + + // LB12a. + if rule > 121 && + nextProperty == prGL && + (state != lbSP && state != lbBA && state != lbHY && state != lbLB21a && state != lbQUSP && state != lbCLCPSP && state != lbB2SP) { + return lbGL, LineDontBreak + } + + // LB13. + if rule > 130 && state != lbNU && state != lbNUNU { + switch nextProperty { + case prCL: + return lbCL, LineDontBreak + case prCP: + return lbCP, LineDontBreak + case prIS: + return lbIS, LineDontBreak + case prSY: + return lbSY, LineDontBreak + } + } + + // LB25 (look ahead). + if rule > 250 && + (state == lbPR || state == lbPO) && + nextProperty == prOP || nextProperty == prHY { + var r rune + if b != nil { // Byte slice version. + r, _ = utf8.DecodeRune(b) + } else { // String version. + r, _ = utf8.DecodeRuneInString(str) + } + if r != utf8.RuneError { + pr, _ := propertyLineBreak(r) + if pr == prNU { + return lbNU, LineDontBreak + } + } + } + + // LB30 (part one). + if rule > 300 { + if (state == lbAL || state == lbHL || state == lbNU || state == lbNUNU) && nextProperty == prOP { + ea := propertyEastAsianWidth(r) + if ea != prF && ea != prW && ea != prH { + return lbOP, LineDontBreak + } + } else if isCPeaFWH { + switch nextProperty { + case prAL: + return lbAL, LineDontBreak + case prHL: + return lbHL, LineDontBreak + case prNU: + return lbNU, LineDontBreak + } + } + } + + // LB30a. + if newState == lbAny && nextProperty == prRI { + if state != lbOddRI && state != lbEvenRI { // Includes state == -1. + // Transition into the first RI. + return lbOddRI, lineBreak + } + if state == lbOddRI { + // Don't break pairs of Regional Indicators. + return lbEvenRI, LineDontBreak + } + return lbOddRI, lineBreak + } + + // LB30b. + if rule > 302 { + if nextProperty == prEM { + if state == lbEB || state == lbExtPicCn { + return prAny, LineDontBreak + } + } + graphemeProperty := propertyGraphemes(r) + if graphemeProperty == prExtendedPictographic && generalCategory == gcCn { + return lbExtPicCn, LineCanBreak + } + } + + return +} diff --git a/vendor/github.com/rivo/uniseg/properties.go b/vendor/github.com/rivo/uniseg/properties.go new file mode 100644 index 000000000000..6290e6810f2b --- /dev/null +++ b/vendor/github.com/rivo/uniseg/properties.go @@ -0,0 +1,208 @@ +package uniseg + +// The Unicode properties as used in the various parsers. Only the ones needed +// in the context of this package are included. +const ( + prXX = 0 // Same as prAny. + prAny = iota // prAny must be 0. + prPrepend // Grapheme properties must come first, to reduce the number of bits stored in the state vector. + prCR + prLF + prControl + prExtend + prRegionalIndicator + prSpacingMark + prL + prV + prT + prLV + prLVT + prZWJ + prExtendedPictographic + prNewline + prWSegSpace + prDoubleQuote + prSingleQuote + prMidNumLet + prNumeric + prMidLetter + prMidNum + prExtendNumLet + prALetter + prFormat + prHebrewLetter + prKatakana + prSp + prSTerm + prClose + prSContinue + prATerm + prUpper + prLower + prSep + prOLetter + prCM + prBA + prBK + prSP + prEX + prQU + prAL + prPR + prPO + prOP + prCP + prIS + prHY + prSY + prNU + prCL + prNL + prGL + prAI + prBB + prHL + prSA + prJL + prJV + prJT + prNS + prZW + prB2 + prIN + prWJ + prID + prEB + prCJ + prH2 + prH3 + prSG + prCB + prRI + prEM + prN + prNa + prA + prW + prH + prF + prEmojiPresentation +) + +// Unicode General Categories. Only the ones needed in the context of this +// package are included. +const ( + gcNone = iota // gcNone must be 0. + gcCc + gcZs + gcPo + gcSc + gcPs + gcPe + gcSm + gcPd + gcNd + gcLu + gcSk + gcPc + gcLl + gcSo + gcLo + gcPi + gcCf + gcNo + gcPf + gcLC + gcLm + gcMn + gcMe + gcMc + gcNl + gcZl + gcZp + gcCn + gcCs + gcCo +) + +// Special code points. +const ( + vs15 = 0xfe0e // Variation Selector-15 (text presentation) + vs16 = 0xfe0f // Variation Selector-16 (emoji presentation) +) + +// propertySearch performs a binary search on a property slice and returns the +// entry whose range (start = first array element, end = second array element) +// includes r, or an array of 0's if no such entry was found. +func propertySearch[E interface{ [3]int | [4]int }](dictionary []E, r rune) (result E) { + // Run a binary search. + from := 0 + to := len(dictionary) + for to > from { + middle := (from + to) / 2 + cpRange := dictionary[middle] + if int(r) < cpRange[0] { + to = middle + continue + } + if int(r) > cpRange[1] { + from = middle + 1 + continue + } + return cpRange + } + return +} + +// property returns the Unicode property value (see constants above) of the +// given code point. +func property(dictionary [][3]int, r rune) int { + return propertySearch(dictionary, r)[2] +} + +// propertyLineBreak returns the Unicode property value and General Category +// (see constants above) of the given code point, as listed in the line break +// code points table, while fast tracking ASCII digits and letters. +func propertyLineBreak(r rune) (property, generalCategory int) { + if r >= 'a' && r <= 'z' { + return prAL, gcLl + } + if r >= 'A' && r <= 'Z' { + return prAL, gcLu + } + if r >= '0' && r <= '9' { + return prNU, gcNd + } + entry := propertySearch(lineBreakCodePoints, r) + return entry[2], entry[3] +} + +// propertyGraphemes returns the Unicode grapheme cluster property value of the +// given code point while fast tracking ASCII characters. +func propertyGraphemes(r rune) int { + if r >= 0x20 && r <= 0x7e { + return prAny + } + if r == 0x0a { + return prLF + } + if r == 0x0d { + return prCR + } + if r >= 0 && r <= 0x1f || r == 0x7f { + return prControl + } + return property(graphemeCodePoints, r) +} + +// propertyEastAsianWidth returns the Unicode East Asian Width property value of +// the given code point while fast tracking ASCII characters. +func propertyEastAsianWidth(r rune) int { + if r >= 0x20 && r <= 0x7e { + return prNa + } + if r >= 0 && r <= 0x1f || r == 0x7f { + return prN + } + return property(eastAsianWidth, r) +} diff --git a/vendor/github.com/rivo/uniseg/sentence.go b/vendor/github.com/rivo/uniseg/sentence.go new file mode 100644 index 000000000000..adc2a3577363 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentence.go @@ -0,0 +1,90 @@ +package uniseg + +import "unicode/utf8" + +// FirstSentence returns the first sentence found in the given byte slice +// according to the rules of [Unicode Standard Annex #29, Sentence Boundaries]. +// This function can be called continuously to extract all sentences from a byte +// slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified sentence. If the length of the "rest" +// slice is 0, the entire byte slice "b" has been processed. The "sentence" byte +// slice is the sub-slice of the input slice containing the identified sentence. +// +// Given an empty byte slice "b", the function returns nil values. +// +// [Unicode Standard Annex #29, Sentence Boundaries]: http://unicode.org/reports/tr29/#Sentence_Boundaries +func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, sbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionSentenceBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionSentenceBreakState(state, r, b[length+l:], "") + + if boundary { + return b[:length], b[length:], state + } + + length += l + if len(b) <= length { + return b, nil, sbAny + } + } +} + +// FirstSentenceInString is like [FirstSentence] but its input and outputs are +// strings. +func FirstSentenceInString(str string, state int) (sentence, rest string, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", sbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionSentenceBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionSentenceBreakState(state, r, nil, str[length+l:]) + + if boundary { + return str[:length], str[length:], state + } + + length += l + if len(str) <= length { + return str, "", sbAny + } + } +} diff --git a/vendor/github.com/rivo/uniseg/sentenceproperties.go b/vendor/github.com/rivo/uniseg/sentenceproperties.go new file mode 100644 index 000000000000..67717ec1f3b4 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentenceproperties.go @@ -0,0 +1,2845 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// sentenceBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/SentenceBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var sentenceBreakCodePoints = [][3]int{ + {0x0009, 0x0009, prSp}, // Cc + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prSp}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x0020, 0x0020, prSp}, // Zs SPACE + {0x0021, 0x0021, prSTerm}, // Po EXCLAMATION MARK + {0x0022, 0x0022, prClose}, // Po QUOTATION MARK + {0x0027, 0x0027, prClose}, // Po APOSTROPHE + {0x0028, 0x0028, prClose}, // Ps LEFT PARENTHESIS + {0x0029, 0x0029, prClose}, // Pe RIGHT PARENTHESIS + {0x002C, 0x002C, prSContinue}, // Po COMMA + {0x002D, 0x002D, prSContinue}, // Pd HYPHEN-MINUS + {0x002E, 0x002E, prATerm}, // Po FULL STOP + {0x0030, 0x0039, prNumeric}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003A, prSContinue}, // Po COLON + {0x003F, 0x003F, prSTerm}, // Po QUESTION MARK + {0x0041, 0x005A, prUpper}, // L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prClose}, // Ps LEFT SQUARE BRACKET + {0x005D, 0x005D, prClose}, // Pe RIGHT SQUARE BRACKET + {0x0061, 0x007A, prLower}, // L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prClose}, // Ps LEFT CURLY BRACKET + {0x007D, 0x007D, prClose}, // Pe RIGHT CURLY BRACKET + {0x0085, 0x0085, prSep}, // Cc + {0x00A0, 0x00A0, prSp}, // Zs NO-BREAK SPACE + {0x00AA, 0x00AA, prLower}, // Lo FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prClose}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AD, 0x00AD, prFormat}, // Cf SOFT HYPHEN + {0x00B5, 0x00B5, prLower}, // L& MICRO SIGN + {0x00BA, 0x00BA, prLower}, // Lo MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prClose}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00C0, 0x00D6, prUpper}, // L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D8, 0x00DE, prUpper}, // L& [7] LATIN CAPITAL LETTER O WITH STROKE..LATIN CAPITAL LETTER THORN + {0x00DF, 0x00F6, prLower}, // L& [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F8, 0x00FF, prLower}, // L& [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x0100, prUpper}, // L& LATIN CAPITAL LETTER A WITH MACRON + {0x0101, 0x0101, prLower}, // L& LATIN SMALL LETTER A WITH MACRON + {0x0102, 0x0102, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE + {0x0103, 0x0103, prLower}, // L& LATIN SMALL LETTER A WITH BREVE + {0x0104, 0x0104, prUpper}, // L& LATIN CAPITAL LETTER A WITH OGONEK + {0x0105, 0x0105, prLower}, // L& LATIN SMALL LETTER A WITH OGONEK + {0x0106, 0x0106, prUpper}, // L& LATIN CAPITAL LETTER C WITH ACUTE + {0x0107, 0x0107, prLower}, // L& LATIN SMALL LETTER C WITH ACUTE + {0x0108, 0x0108, prUpper}, // L& LATIN CAPITAL LETTER C WITH CIRCUMFLEX + {0x0109, 0x0109, prLower}, // L& LATIN SMALL LETTER C WITH CIRCUMFLEX + {0x010A, 0x010A, prUpper}, // L& LATIN CAPITAL LETTER C WITH DOT ABOVE + {0x010B, 0x010B, prLower}, // L& LATIN SMALL LETTER C WITH DOT ABOVE + {0x010C, 0x010C, prUpper}, // L& LATIN CAPITAL LETTER C WITH CARON + {0x010D, 0x010D, prLower}, // L& LATIN SMALL LETTER C WITH CARON + {0x010E, 0x010E, prUpper}, // L& LATIN CAPITAL LETTER D WITH CARON + {0x010F, 0x010F, prLower}, // L& LATIN SMALL LETTER D WITH CARON + {0x0110, 0x0110, prUpper}, // L& LATIN CAPITAL LETTER D WITH STROKE + {0x0111, 0x0111, prLower}, // L& LATIN SMALL LETTER D WITH STROKE + {0x0112, 0x0112, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON + {0x0113, 0x0113, prLower}, // L& LATIN SMALL LETTER E WITH MACRON + {0x0114, 0x0114, prUpper}, // L& LATIN CAPITAL LETTER E WITH BREVE + {0x0115, 0x0115, prLower}, // L& LATIN SMALL LETTER E WITH BREVE + {0x0116, 0x0116, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOT ABOVE + {0x0117, 0x0117, prLower}, // L& LATIN SMALL LETTER E WITH DOT ABOVE + {0x0118, 0x0118, prUpper}, // L& LATIN CAPITAL LETTER E WITH OGONEK + {0x0119, 0x0119, prLower}, // L& LATIN SMALL LETTER E WITH OGONEK + {0x011A, 0x011A, prUpper}, // L& LATIN CAPITAL LETTER E WITH CARON + {0x011B, 0x011B, prLower}, // L& LATIN SMALL LETTER E WITH CARON + {0x011C, 0x011C, prUpper}, // L& LATIN CAPITAL LETTER G WITH CIRCUMFLEX + {0x011D, 0x011D, prLower}, // L& LATIN SMALL LETTER G WITH CIRCUMFLEX + {0x011E, 0x011E, prUpper}, // L& LATIN CAPITAL LETTER G WITH BREVE + {0x011F, 0x011F, prLower}, // L& LATIN SMALL LETTER G WITH BREVE + {0x0120, 0x0120, prUpper}, // L& LATIN CAPITAL LETTER G WITH DOT ABOVE + {0x0121, 0x0121, prLower}, // L& LATIN SMALL LETTER G WITH DOT ABOVE + {0x0122, 0x0122, prUpper}, // L& LATIN CAPITAL LETTER G WITH CEDILLA + {0x0123, 0x0123, prLower}, // L& LATIN SMALL LETTER G WITH CEDILLA + {0x0124, 0x0124, prUpper}, // L& LATIN CAPITAL LETTER H WITH CIRCUMFLEX + {0x0125, 0x0125, prLower}, // L& LATIN SMALL LETTER H WITH CIRCUMFLEX + {0x0126, 0x0126, prUpper}, // L& LATIN CAPITAL LETTER H WITH STROKE + {0x0127, 0x0127, prLower}, // L& LATIN SMALL LETTER H WITH STROKE + {0x0128, 0x0128, prUpper}, // L& LATIN CAPITAL LETTER I WITH TILDE + {0x0129, 0x0129, prLower}, // L& LATIN SMALL LETTER I WITH TILDE + {0x012A, 0x012A, prUpper}, // L& LATIN CAPITAL LETTER I WITH MACRON + {0x012B, 0x012B, prLower}, // L& LATIN SMALL LETTER I WITH MACRON + {0x012C, 0x012C, prUpper}, // L& LATIN CAPITAL LETTER I WITH BREVE + {0x012D, 0x012D, prLower}, // L& LATIN SMALL LETTER I WITH BREVE + {0x012E, 0x012E, prUpper}, // L& LATIN CAPITAL LETTER I WITH OGONEK + {0x012F, 0x012F, prLower}, // L& LATIN SMALL LETTER I WITH OGONEK + {0x0130, 0x0130, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOT ABOVE + {0x0131, 0x0131, prLower}, // L& LATIN SMALL LETTER DOTLESS I + {0x0132, 0x0132, prUpper}, // L& LATIN CAPITAL LIGATURE IJ + {0x0133, 0x0133, prLower}, // L& LATIN SMALL LIGATURE IJ + {0x0134, 0x0134, prUpper}, // L& LATIN CAPITAL LETTER J WITH CIRCUMFLEX + {0x0135, 0x0135, prLower}, // L& LATIN SMALL LETTER J WITH CIRCUMFLEX + {0x0136, 0x0136, prUpper}, // L& LATIN CAPITAL LETTER K WITH CEDILLA + {0x0137, 0x0138, prLower}, // L& [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA + {0x0139, 0x0139, prUpper}, // L& LATIN CAPITAL LETTER L WITH ACUTE + {0x013A, 0x013A, prLower}, // L& LATIN SMALL LETTER L WITH ACUTE + {0x013B, 0x013B, prUpper}, // L& LATIN CAPITAL LETTER L WITH CEDILLA + {0x013C, 0x013C, prLower}, // L& LATIN SMALL LETTER L WITH CEDILLA + {0x013D, 0x013D, prUpper}, // L& LATIN CAPITAL LETTER L WITH CARON + {0x013E, 0x013E, prLower}, // L& LATIN SMALL LETTER L WITH CARON + {0x013F, 0x013F, prUpper}, // L& LATIN CAPITAL LETTER L WITH MIDDLE DOT + {0x0140, 0x0140, prLower}, // L& LATIN SMALL LETTER L WITH MIDDLE DOT + {0x0141, 0x0141, prUpper}, // L& LATIN CAPITAL LETTER L WITH STROKE + {0x0142, 0x0142, prLower}, // L& LATIN SMALL LETTER L WITH STROKE + {0x0143, 0x0143, prUpper}, // L& LATIN CAPITAL LETTER N WITH ACUTE + {0x0144, 0x0144, prLower}, // L& LATIN SMALL LETTER N WITH ACUTE + {0x0145, 0x0145, prUpper}, // L& LATIN CAPITAL LETTER N WITH CEDILLA + {0x0146, 0x0146, prLower}, // L& LATIN SMALL LETTER N WITH CEDILLA + {0x0147, 0x0147, prUpper}, // L& LATIN CAPITAL LETTER N WITH CARON + {0x0148, 0x0149, prLower}, // L& [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + {0x014A, 0x014A, prUpper}, // L& LATIN CAPITAL LETTER ENG + {0x014B, 0x014B, prLower}, // L& LATIN SMALL LETTER ENG + {0x014C, 0x014C, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON + {0x014D, 0x014D, prLower}, // L& LATIN SMALL LETTER O WITH MACRON + {0x014E, 0x014E, prUpper}, // L& LATIN CAPITAL LETTER O WITH BREVE + {0x014F, 0x014F, prLower}, // L& LATIN SMALL LETTER O WITH BREVE + {0x0150, 0x0150, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + {0x0151, 0x0151, prLower}, // L& LATIN SMALL LETTER O WITH DOUBLE ACUTE + {0x0152, 0x0152, prUpper}, // L& LATIN CAPITAL LIGATURE OE + {0x0153, 0x0153, prLower}, // L& LATIN SMALL LIGATURE OE + {0x0154, 0x0154, prUpper}, // L& LATIN CAPITAL LETTER R WITH ACUTE + {0x0155, 0x0155, prLower}, // L& LATIN SMALL LETTER R WITH ACUTE + {0x0156, 0x0156, prUpper}, // L& LATIN CAPITAL LETTER R WITH CEDILLA + {0x0157, 0x0157, prLower}, // L& LATIN SMALL LETTER R WITH CEDILLA + {0x0158, 0x0158, prUpper}, // L& LATIN CAPITAL LETTER R WITH CARON + {0x0159, 0x0159, prLower}, // L& LATIN SMALL LETTER R WITH CARON + {0x015A, 0x015A, prUpper}, // L& LATIN CAPITAL LETTER S WITH ACUTE + {0x015B, 0x015B, prLower}, // L& LATIN SMALL LETTER S WITH ACUTE + {0x015C, 0x015C, prUpper}, // L& LATIN CAPITAL LETTER S WITH CIRCUMFLEX + {0x015D, 0x015D, prLower}, // L& LATIN SMALL LETTER S WITH CIRCUMFLEX + {0x015E, 0x015E, prUpper}, // L& LATIN CAPITAL LETTER S WITH CEDILLA + {0x015F, 0x015F, prLower}, // L& LATIN SMALL LETTER S WITH CEDILLA + {0x0160, 0x0160, prUpper}, // L& LATIN CAPITAL LETTER S WITH CARON + {0x0161, 0x0161, prLower}, // L& LATIN SMALL LETTER S WITH CARON + {0x0162, 0x0162, prUpper}, // L& LATIN CAPITAL LETTER T WITH CEDILLA + {0x0163, 0x0163, prLower}, // L& LATIN SMALL LETTER T WITH CEDILLA + {0x0164, 0x0164, prUpper}, // L& LATIN CAPITAL LETTER T WITH CARON + {0x0165, 0x0165, prLower}, // L& LATIN SMALL LETTER T WITH CARON + {0x0166, 0x0166, prUpper}, // L& LATIN CAPITAL LETTER T WITH STROKE + {0x0167, 0x0167, prLower}, // L& LATIN SMALL LETTER T WITH STROKE + {0x0168, 0x0168, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE + {0x0169, 0x0169, prLower}, // L& LATIN SMALL LETTER U WITH TILDE + {0x016A, 0x016A, prUpper}, // L& LATIN CAPITAL LETTER U WITH MACRON + {0x016B, 0x016B, prLower}, // L& LATIN SMALL LETTER U WITH MACRON + {0x016C, 0x016C, prUpper}, // L& LATIN CAPITAL LETTER U WITH BREVE + {0x016D, 0x016D, prLower}, // L& LATIN SMALL LETTER U WITH BREVE + {0x016E, 0x016E, prUpper}, // L& LATIN CAPITAL LETTER U WITH RING ABOVE + {0x016F, 0x016F, prLower}, // L& LATIN SMALL LETTER U WITH RING ABOVE + {0x0170, 0x0170, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + {0x0171, 0x0171, prLower}, // L& LATIN SMALL LETTER U WITH DOUBLE ACUTE + {0x0172, 0x0172, prUpper}, // L& LATIN CAPITAL LETTER U WITH OGONEK + {0x0173, 0x0173, prLower}, // L& LATIN SMALL LETTER U WITH OGONEK + {0x0174, 0x0174, prUpper}, // L& LATIN CAPITAL LETTER W WITH CIRCUMFLEX + {0x0175, 0x0175, prLower}, // L& LATIN SMALL LETTER W WITH CIRCUMFLEX + {0x0176, 0x0176, prUpper}, // L& LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + {0x0177, 0x0177, prLower}, // L& LATIN SMALL LETTER Y WITH CIRCUMFLEX + {0x0178, 0x0179, prUpper}, // L& [2] LATIN CAPITAL LETTER Y WITH DIAERESIS..LATIN CAPITAL LETTER Z WITH ACUTE + {0x017A, 0x017A, prLower}, // L& LATIN SMALL LETTER Z WITH ACUTE + {0x017B, 0x017B, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DOT ABOVE + {0x017C, 0x017C, prLower}, // L& LATIN SMALL LETTER Z WITH DOT ABOVE + {0x017D, 0x017D, prUpper}, // L& LATIN CAPITAL LETTER Z WITH CARON + {0x017E, 0x0180, prLower}, // L& [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE + {0x0181, 0x0182, prUpper}, // L& [2] LATIN CAPITAL LETTER B WITH HOOK..LATIN CAPITAL LETTER B WITH TOPBAR + {0x0183, 0x0183, prLower}, // L& LATIN SMALL LETTER B WITH TOPBAR + {0x0184, 0x0184, prUpper}, // L& LATIN CAPITAL LETTER TONE SIX + {0x0185, 0x0185, prLower}, // L& LATIN SMALL LETTER TONE SIX + {0x0186, 0x0187, prUpper}, // L& [2] LATIN CAPITAL LETTER OPEN O..LATIN CAPITAL LETTER C WITH HOOK + {0x0188, 0x0188, prLower}, // L& LATIN SMALL LETTER C WITH HOOK + {0x0189, 0x018B, prUpper}, // L& [3] LATIN CAPITAL LETTER AFRICAN D..LATIN CAPITAL LETTER D WITH TOPBAR + {0x018C, 0x018D, prLower}, // L& [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA + {0x018E, 0x0191, prUpper}, // L& [4] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER F WITH HOOK + {0x0192, 0x0192, prLower}, // L& LATIN SMALL LETTER F WITH HOOK + {0x0193, 0x0194, prUpper}, // L& [2] LATIN CAPITAL LETTER G WITH HOOK..LATIN CAPITAL LETTER GAMMA + {0x0195, 0x0195, prLower}, // L& LATIN SMALL LETTER HV + {0x0196, 0x0198, prUpper}, // L& [3] LATIN CAPITAL LETTER IOTA..LATIN CAPITAL LETTER K WITH HOOK + {0x0199, 0x019B, prLower}, // L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE + {0x019C, 0x019D, prUpper}, // L& [2] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER N WITH LEFT HOOK + {0x019E, 0x019E, prLower}, // L& LATIN SMALL LETTER N WITH LONG RIGHT LEG + {0x019F, 0x01A0, prUpper}, // L& [2] LATIN CAPITAL LETTER O WITH MIDDLE TILDE..LATIN CAPITAL LETTER O WITH HORN + {0x01A1, 0x01A1, prLower}, // L& LATIN SMALL LETTER O WITH HORN + {0x01A2, 0x01A2, prUpper}, // L& LATIN CAPITAL LETTER OI + {0x01A3, 0x01A3, prLower}, // L& LATIN SMALL LETTER OI + {0x01A4, 0x01A4, prUpper}, // L& LATIN CAPITAL LETTER P WITH HOOK + {0x01A5, 0x01A5, prLower}, // L& LATIN SMALL LETTER P WITH HOOK + {0x01A6, 0x01A7, prUpper}, // L& [2] LATIN LETTER YR..LATIN CAPITAL LETTER TONE TWO + {0x01A8, 0x01A8, prLower}, // L& LATIN SMALL LETTER TONE TWO + {0x01A9, 0x01A9, prUpper}, // L& LATIN CAPITAL LETTER ESH + {0x01AA, 0x01AB, prLower}, // L& [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK + {0x01AC, 0x01AC, prUpper}, // L& LATIN CAPITAL LETTER T WITH HOOK + {0x01AD, 0x01AD, prLower}, // L& LATIN SMALL LETTER T WITH HOOK + {0x01AE, 0x01AF, prUpper}, // L& [2] LATIN CAPITAL LETTER T WITH RETROFLEX HOOK..LATIN CAPITAL LETTER U WITH HORN + {0x01B0, 0x01B0, prLower}, // L& LATIN SMALL LETTER U WITH HORN + {0x01B1, 0x01B3, prUpper}, // L& [3] LATIN CAPITAL LETTER UPSILON..LATIN CAPITAL LETTER Y WITH HOOK + {0x01B4, 0x01B4, prLower}, // L& LATIN SMALL LETTER Y WITH HOOK + {0x01B5, 0x01B5, prUpper}, // L& LATIN CAPITAL LETTER Z WITH STROKE + {0x01B6, 0x01B6, prLower}, // L& LATIN SMALL LETTER Z WITH STROKE + {0x01B7, 0x01B8, prUpper}, // L& [2] LATIN CAPITAL LETTER EZH..LATIN CAPITAL LETTER EZH REVERSED + {0x01B9, 0x01BA, prLower}, // L& [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prOLetter}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BC, prUpper}, // L& LATIN CAPITAL LETTER TONE FIVE + {0x01BD, 0x01BF, prLower}, // L& [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prOLetter}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x01C5, prUpper}, // L& [2] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON + {0x01C6, 0x01C6, prLower}, // L& LATIN SMALL LETTER DZ WITH CARON + {0x01C7, 0x01C8, prUpper}, // L& [2] LATIN CAPITAL LETTER LJ..LATIN CAPITAL LETTER L WITH SMALL LETTER J + {0x01C9, 0x01C9, prLower}, // L& LATIN SMALL LETTER LJ + {0x01CA, 0x01CB, prUpper}, // L& [2] LATIN CAPITAL LETTER NJ..LATIN CAPITAL LETTER N WITH SMALL LETTER J + {0x01CC, 0x01CC, prLower}, // L& LATIN SMALL LETTER NJ + {0x01CD, 0x01CD, prUpper}, // L& LATIN CAPITAL LETTER A WITH CARON + {0x01CE, 0x01CE, prLower}, // L& LATIN SMALL LETTER A WITH CARON + {0x01CF, 0x01CF, prUpper}, // L& LATIN CAPITAL LETTER I WITH CARON + {0x01D0, 0x01D0, prLower}, // L& LATIN SMALL LETTER I WITH CARON + {0x01D1, 0x01D1, prUpper}, // L& LATIN CAPITAL LETTER O WITH CARON + {0x01D2, 0x01D2, prLower}, // L& LATIN SMALL LETTER O WITH CARON + {0x01D3, 0x01D3, prUpper}, // L& LATIN CAPITAL LETTER U WITH CARON + {0x01D4, 0x01D4, prLower}, // L& LATIN SMALL LETTER U WITH CARON + {0x01D5, 0x01D5, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON + {0x01D6, 0x01D6, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + {0x01D7, 0x01D7, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE + {0x01D8, 0x01D8, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + {0x01D9, 0x01D9, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON + {0x01DA, 0x01DA, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND CARON + {0x01DB, 0x01DB, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE + {0x01DC, 0x01DD, prLower}, // L& [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E + {0x01DE, 0x01DE, prUpper}, // L& LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON + {0x01DF, 0x01DF, prLower}, // L& LATIN SMALL LETTER A WITH DIAERESIS AND MACRON + {0x01E0, 0x01E0, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON + {0x01E1, 0x01E1, prLower}, // L& LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON + {0x01E2, 0x01E2, prUpper}, // L& LATIN CAPITAL LETTER AE WITH MACRON + {0x01E3, 0x01E3, prLower}, // L& LATIN SMALL LETTER AE WITH MACRON + {0x01E4, 0x01E4, prUpper}, // L& LATIN CAPITAL LETTER G WITH STROKE + {0x01E5, 0x01E5, prLower}, // L& LATIN SMALL LETTER G WITH STROKE + {0x01E6, 0x01E6, prUpper}, // L& LATIN CAPITAL LETTER G WITH CARON + {0x01E7, 0x01E7, prLower}, // L& LATIN SMALL LETTER G WITH CARON + {0x01E8, 0x01E8, prUpper}, // L& LATIN CAPITAL LETTER K WITH CARON + {0x01E9, 0x01E9, prLower}, // L& LATIN SMALL LETTER K WITH CARON + {0x01EA, 0x01EA, prUpper}, // L& LATIN CAPITAL LETTER O WITH OGONEK + {0x01EB, 0x01EB, prLower}, // L& LATIN SMALL LETTER O WITH OGONEK + {0x01EC, 0x01EC, prUpper}, // L& LATIN CAPITAL LETTER O WITH OGONEK AND MACRON + {0x01ED, 0x01ED, prLower}, // L& LATIN SMALL LETTER O WITH OGONEK AND MACRON + {0x01EE, 0x01EE, prUpper}, // L& LATIN CAPITAL LETTER EZH WITH CARON + {0x01EF, 0x01F0, prLower}, // L& [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON + {0x01F1, 0x01F2, prUpper}, // L& [2] LATIN CAPITAL LETTER DZ..LATIN CAPITAL LETTER D WITH SMALL LETTER Z + {0x01F3, 0x01F3, prLower}, // L& LATIN SMALL LETTER DZ + {0x01F4, 0x01F4, prUpper}, // L& LATIN CAPITAL LETTER G WITH ACUTE + {0x01F5, 0x01F5, prLower}, // L& LATIN SMALL LETTER G WITH ACUTE + {0x01F6, 0x01F8, prUpper}, // L& [3] LATIN CAPITAL LETTER HWAIR..LATIN CAPITAL LETTER N WITH GRAVE + {0x01F9, 0x01F9, prLower}, // L& LATIN SMALL LETTER N WITH GRAVE + {0x01FA, 0x01FA, prUpper}, // L& LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE + {0x01FB, 0x01FB, prLower}, // L& LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE + {0x01FC, 0x01FC, prUpper}, // L& LATIN CAPITAL LETTER AE WITH ACUTE + {0x01FD, 0x01FD, prLower}, // L& LATIN SMALL LETTER AE WITH ACUTE + {0x01FE, 0x01FE, prUpper}, // L& LATIN CAPITAL LETTER O WITH STROKE AND ACUTE + {0x01FF, 0x01FF, prLower}, // L& LATIN SMALL LETTER O WITH STROKE AND ACUTE + {0x0200, 0x0200, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOUBLE GRAVE + {0x0201, 0x0201, prLower}, // L& LATIN SMALL LETTER A WITH DOUBLE GRAVE + {0x0202, 0x0202, prUpper}, // L& LATIN CAPITAL LETTER A WITH INVERTED BREVE + {0x0203, 0x0203, prLower}, // L& LATIN SMALL LETTER A WITH INVERTED BREVE + {0x0204, 0x0204, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOUBLE GRAVE + {0x0205, 0x0205, prLower}, // L& LATIN SMALL LETTER E WITH DOUBLE GRAVE + {0x0206, 0x0206, prUpper}, // L& LATIN CAPITAL LETTER E WITH INVERTED BREVE + {0x0207, 0x0207, prLower}, // L& LATIN SMALL LETTER E WITH INVERTED BREVE + {0x0208, 0x0208, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOUBLE GRAVE + {0x0209, 0x0209, prLower}, // L& LATIN SMALL LETTER I WITH DOUBLE GRAVE + {0x020A, 0x020A, prUpper}, // L& LATIN CAPITAL LETTER I WITH INVERTED BREVE + {0x020B, 0x020B, prLower}, // L& LATIN SMALL LETTER I WITH INVERTED BREVE + {0x020C, 0x020C, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOUBLE GRAVE + {0x020D, 0x020D, prLower}, // L& LATIN SMALL LETTER O WITH DOUBLE GRAVE + {0x020E, 0x020E, prUpper}, // L& LATIN CAPITAL LETTER O WITH INVERTED BREVE + {0x020F, 0x020F, prLower}, // L& LATIN SMALL LETTER O WITH INVERTED BREVE + {0x0210, 0x0210, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOUBLE GRAVE + {0x0211, 0x0211, prLower}, // L& LATIN SMALL LETTER R WITH DOUBLE GRAVE + {0x0212, 0x0212, prUpper}, // L& LATIN CAPITAL LETTER R WITH INVERTED BREVE + {0x0213, 0x0213, prLower}, // L& LATIN SMALL LETTER R WITH INVERTED BREVE + {0x0214, 0x0214, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOUBLE GRAVE + {0x0215, 0x0215, prLower}, // L& LATIN SMALL LETTER U WITH DOUBLE GRAVE + {0x0216, 0x0216, prUpper}, // L& LATIN CAPITAL LETTER U WITH INVERTED BREVE + {0x0217, 0x0217, prLower}, // L& LATIN SMALL LETTER U WITH INVERTED BREVE + {0x0218, 0x0218, prUpper}, // L& LATIN CAPITAL LETTER S WITH COMMA BELOW + {0x0219, 0x0219, prLower}, // L& LATIN SMALL LETTER S WITH COMMA BELOW + {0x021A, 0x021A, prUpper}, // L& LATIN CAPITAL LETTER T WITH COMMA BELOW + {0x021B, 0x021B, prLower}, // L& LATIN SMALL LETTER T WITH COMMA BELOW + {0x021C, 0x021C, prUpper}, // L& LATIN CAPITAL LETTER YOGH + {0x021D, 0x021D, prLower}, // L& LATIN SMALL LETTER YOGH + {0x021E, 0x021E, prUpper}, // L& LATIN CAPITAL LETTER H WITH CARON + {0x021F, 0x021F, prLower}, // L& LATIN SMALL LETTER H WITH CARON + {0x0220, 0x0220, prUpper}, // L& LATIN CAPITAL LETTER N WITH LONG RIGHT LEG + {0x0221, 0x0221, prLower}, // L& LATIN SMALL LETTER D WITH CURL + {0x0222, 0x0222, prUpper}, // L& LATIN CAPITAL LETTER OU + {0x0223, 0x0223, prLower}, // L& LATIN SMALL LETTER OU + {0x0224, 0x0224, prUpper}, // L& LATIN CAPITAL LETTER Z WITH HOOK + {0x0225, 0x0225, prLower}, // L& LATIN SMALL LETTER Z WITH HOOK + {0x0226, 0x0226, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT ABOVE + {0x0227, 0x0227, prLower}, // L& LATIN SMALL LETTER A WITH DOT ABOVE + {0x0228, 0x0228, prUpper}, // L& LATIN CAPITAL LETTER E WITH CEDILLA + {0x0229, 0x0229, prLower}, // L& LATIN SMALL LETTER E WITH CEDILLA + {0x022A, 0x022A, prUpper}, // L& LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON + {0x022B, 0x022B, prLower}, // L& LATIN SMALL LETTER O WITH DIAERESIS AND MACRON + {0x022C, 0x022C, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND MACRON + {0x022D, 0x022D, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND MACRON + {0x022E, 0x022E, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT ABOVE + {0x022F, 0x022F, prLower}, // L& LATIN SMALL LETTER O WITH DOT ABOVE + {0x0230, 0x0230, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON + {0x0231, 0x0231, prLower}, // L& LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON + {0x0232, 0x0232, prUpper}, // L& LATIN CAPITAL LETTER Y WITH MACRON + {0x0233, 0x0239, prLower}, // L& [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH + {0x023A, 0x023B, prUpper}, // L& [2] LATIN CAPITAL LETTER A WITH STROKE..LATIN CAPITAL LETTER C WITH STROKE + {0x023C, 0x023C, prLower}, // L& LATIN SMALL LETTER C WITH STROKE + {0x023D, 0x023E, prUpper}, // L& [2] LATIN CAPITAL LETTER L WITH BAR..LATIN CAPITAL LETTER T WITH DIAGONAL STROKE + {0x023F, 0x0240, prLower}, // L& [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL + {0x0241, 0x0241, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL STOP + {0x0242, 0x0242, prLower}, // L& LATIN SMALL LETTER GLOTTAL STOP + {0x0243, 0x0246, prUpper}, // L& [4] LATIN CAPITAL LETTER B WITH STROKE..LATIN CAPITAL LETTER E WITH STROKE + {0x0247, 0x0247, prLower}, // L& LATIN SMALL LETTER E WITH STROKE + {0x0248, 0x0248, prUpper}, // L& LATIN CAPITAL LETTER J WITH STROKE + {0x0249, 0x0249, prLower}, // L& LATIN SMALL LETTER J WITH STROKE + {0x024A, 0x024A, prUpper}, // L& LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL + {0x024B, 0x024B, prLower}, // L& LATIN SMALL LETTER Q WITH HOOK TAIL + {0x024C, 0x024C, prUpper}, // L& LATIN CAPITAL LETTER R WITH STROKE + {0x024D, 0x024D, prLower}, // L& LATIN SMALL LETTER R WITH STROKE + {0x024E, 0x024E, prUpper}, // L& LATIN CAPITAL LETTER Y WITH STROKE + {0x024F, 0x0293, prLower}, // L& [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prOLetter}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prLower}, // L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02B8, prLower}, // Lm [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y + {0x02B9, 0x02BF, prOLetter}, // Lm [7] MODIFIER LETTER PRIME..MODIFIER LETTER LEFT HALF RING + {0x02C0, 0x02C1, prLower}, // Lm [2] MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C6, 0x02D1, prOLetter}, // Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON + {0x02E0, 0x02E4, prLower}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02EC, 0x02EC, prOLetter}, // Lm MODIFIER LETTER VOICING + {0x02EE, 0x02EE, prOLetter}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0370, prUpper}, // L& GREEK CAPITAL LETTER HETA + {0x0371, 0x0371, prLower}, // L& GREEK SMALL LETTER HETA + {0x0372, 0x0372, prUpper}, // L& GREEK CAPITAL LETTER ARCHAIC SAMPI + {0x0373, 0x0373, prLower}, // L& GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prOLetter}, // Lm GREEK NUMERAL SIGN + {0x0376, 0x0376, prUpper}, // L& GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA + {0x0377, 0x0377, prLower}, // L& GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prLower}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prLower}, // L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037F, 0x037F, prUpper}, // L& GREEK CAPITAL LETTER YOT + {0x0386, 0x0386, prUpper}, // L& GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0388, 0x038A, prUpper}, // L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prUpper}, // L& GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x038F, prUpper}, // L& [2] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER OMEGA WITH TONOS + {0x0390, 0x0390, prLower}, // L& GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + {0x0391, 0x03A1, prUpper}, // L& [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03AB, prUpper}, // L& [9] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + {0x03AC, 0x03CE, prLower}, // L& [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS + {0x03CF, 0x03CF, prUpper}, // L& GREEK CAPITAL KAI SYMBOL + {0x03D0, 0x03D1, prLower}, // L& [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL + {0x03D2, 0x03D4, prUpper}, // L& [3] GREEK UPSILON WITH HOOK SYMBOL..GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL + {0x03D5, 0x03D7, prLower}, // L& [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL + {0x03D8, 0x03D8, prUpper}, // L& GREEK LETTER ARCHAIC KOPPA + {0x03D9, 0x03D9, prLower}, // L& GREEK SMALL LETTER ARCHAIC KOPPA + {0x03DA, 0x03DA, prUpper}, // L& GREEK LETTER STIGMA + {0x03DB, 0x03DB, prLower}, // L& GREEK SMALL LETTER STIGMA + {0x03DC, 0x03DC, prUpper}, // L& GREEK LETTER DIGAMMA + {0x03DD, 0x03DD, prLower}, // L& GREEK SMALL LETTER DIGAMMA + {0x03DE, 0x03DE, prUpper}, // L& GREEK LETTER KOPPA + {0x03DF, 0x03DF, prLower}, // L& GREEK SMALL LETTER KOPPA + {0x03E0, 0x03E0, prUpper}, // L& GREEK LETTER SAMPI + {0x03E1, 0x03E1, prLower}, // L& GREEK SMALL LETTER SAMPI + {0x03E2, 0x03E2, prUpper}, // L& COPTIC CAPITAL LETTER SHEI + {0x03E3, 0x03E3, prLower}, // L& COPTIC SMALL LETTER SHEI + {0x03E4, 0x03E4, prUpper}, // L& COPTIC CAPITAL LETTER FEI + {0x03E5, 0x03E5, prLower}, // L& COPTIC SMALL LETTER FEI + {0x03E6, 0x03E6, prUpper}, // L& COPTIC CAPITAL LETTER KHEI + {0x03E7, 0x03E7, prLower}, // L& COPTIC SMALL LETTER KHEI + {0x03E8, 0x03E8, prUpper}, // L& COPTIC CAPITAL LETTER HORI + {0x03E9, 0x03E9, prLower}, // L& COPTIC SMALL LETTER HORI + {0x03EA, 0x03EA, prUpper}, // L& COPTIC CAPITAL LETTER GANGIA + {0x03EB, 0x03EB, prLower}, // L& COPTIC SMALL LETTER GANGIA + {0x03EC, 0x03EC, prUpper}, // L& COPTIC CAPITAL LETTER SHIMA + {0x03ED, 0x03ED, prLower}, // L& COPTIC SMALL LETTER SHIMA + {0x03EE, 0x03EE, prUpper}, // L& COPTIC CAPITAL LETTER DEI + {0x03EF, 0x03F3, prLower}, // L& [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT + {0x03F4, 0x03F4, prUpper}, // L& GREEK CAPITAL THETA SYMBOL + {0x03F5, 0x03F5, prLower}, // L& GREEK LUNATE EPSILON SYMBOL + {0x03F7, 0x03F7, prUpper}, // L& GREEK CAPITAL LETTER SHO + {0x03F8, 0x03F8, prLower}, // L& GREEK SMALL LETTER SHO + {0x03F9, 0x03FA, prUpper}, // L& [2] GREEK CAPITAL LUNATE SIGMA SYMBOL..GREEK CAPITAL LETTER SAN + {0x03FB, 0x03FC, prLower}, // L& [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL + {0x03FD, 0x042F, prUpper}, // L& [51] GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL..CYRILLIC CAPITAL LETTER YA + {0x0430, 0x045F, prLower}, // L& [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE + {0x0460, 0x0460, prUpper}, // L& CYRILLIC CAPITAL LETTER OMEGA + {0x0461, 0x0461, prLower}, // L& CYRILLIC SMALL LETTER OMEGA + {0x0462, 0x0462, prUpper}, // L& CYRILLIC CAPITAL LETTER YAT + {0x0463, 0x0463, prLower}, // L& CYRILLIC SMALL LETTER YAT + {0x0464, 0x0464, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED E + {0x0465, 0x0465, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED E + {0x0466, 0x0466, prUpper}, // L& CYRILLIC CAPITAL LETTER LITTLE YUS + {0x0467, 0x0467, prLower}, // L& CYRILLIC SMALL LETTER LITTLE YUS + {0x0468, 0x0468, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS + {0x0469, 0x0469, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS + {0x046A, 0x046A, prUpper}, // L& CYRILLIC CAPITAL LETTER BIG YUS + {0x046B, 0x046B, prLower}, // L& CYRILLIC SMALL LETTER BIG YUS + {0x046C, 0x046C, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS + {0x046D, 0x046D, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED BIG YUS + {0x046E, 0x046E, prUpper}, // L& CYRILLIC CAPITAL LETTER KSI + {0x046F, 0x046F, prLower}, // L& CYRILLIC SMALL LETTER KSI + {0x0470, 0x0470, prUpper}, // L& CYRILLIC CAPITAL LETTER PSI + {0x0471, 0x0471, prLower}, // L& CYRILLIC SMALL LETTER PSI + {0x0472, 0x0472, prUpper}, // L& CYRILLIC CAPITAL LETTER FITA + {0x0473, 0x0473, prLower}, // L& CYRILLIC SMALL LETTER FITA + {0x0474, 0x0474, prUpper}, // L& CYRILLIC CAPITAL LETTER IZHITSA + {0x0475, 0x0475, prLower}, // L& CYRILLIC SMALL LETTER IZHITSA + {0x0476, 0x0476, prUpper}, // L& CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + {0x0477, 0x0477, prLower}, // L& CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + {0x0478, 0x0478, prUpper}, // L& CYRILLIC CAPITAL LETTER UK + {0x0479, 0x0479, prLower}, // L& CYRILLIC SMALL LETTER UK + {0x047A, 0x047A, prUpper}, // L& CYRILLIC CAPITAL LETTER ROUND OMEGA + {0x047B, 0x047B, prLower}, // L& CYRILLIC SMALL LETTER ROUND OMEGA + {0x047C, 0x047C, prUpper}, // L& CYRILLIC CAPITAL LETTER OMEGA WITH TITLO + {0x047D, 0x047D, prLower}, // L& CYRILLIC SMALL LETTER OMEGA WITH TITLO + {0x047E, 0x047E, prUpper}, // L& CYRILLIC CAPITAL LETTER OT + {0x047F, 0x047F, prLower}, // L& CYRILLIC SMALL LETTER OT + {0x0480, 0x0480, prUpper}, // L& CYRILLIC CAPITAL LETTER KOPPA + {0x0481, 0x0481, prLower}, // L& CYRILLIC SMALL LETTER KOPPA + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x048A, prUpper}, // L& CYRILLIC CAPITAL LETTER SHORT I WITH TAIL + {0x048B, 0x048B, prLower}, // L& CYRILLIC SMALL LETTER SHORT I WITH TAIL + {0x048C, 0x048C, prUpper}, // L& CYRILLIC CAPITAL LETTER SEMISOFT SIGN + {0x048D, 0x048D, prLower}, // L& CYRILLIC SMALL LETTER SEMISOFT SIGN + {0x048E, 0x048E, prUpper}, // L& CYRILLIC CAPITAL LETTER ER WITH TICK + {0x048F, 0x048F, prLower}, // L& CYRILLIC SMALL LETTER ER WITH TICK + {0x0490, 0x0490, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH UPTURN + {0x0491, 0x0491, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH UPTURN + {0x0492, 0x0492, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH STROKE + {0x0493, 0x0493, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH STROKE + {0x0494, 0x0494, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK + {0x0495, 0x0495, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK + {0x0496, 0x0496, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + {0x0497, 0x0497, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH DESCENDER + {0x0498, 0x0498, prUpper}, // L& CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + {0x0499, 0x0499, prLower}, // L& CYRILLIC SMALL LETTER ZE WITH DESCENDER + {0x049A, 0x049A, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH DESCENDER + {0x049B, 0x049B, prLower}, // L& CYRILLIC SMALL LETTER KA WITH DESCENDER + {0x049C, 0x049C, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + {0x049D, 0x049D, prLower}, // L& CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + {0x049E, 0x049E, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH STROKE + {0x049F, 0x049F, prLower}, // L& CYRILLIC SMALL LETTER KA WITH STROKE + {0x04A0, 0x04A0, prUpper}, // L& CYRILLIC CAPITAL LETTER BASHKIR KA + {0x04A1, 0x04A1, prLower}, // L& CYRILLIC SMALL LETTER BASHKIR KA + {0x04A2, 0x04A2, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH DESCENDER + {0x04A3, 0x04A3, prLower}, // L& CYRILLIC SMALL LETTER EN WITH DESCENDER + {0x04A4, 0x04A4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE EN GHE + {0x04A5, 0x04A5, prLower}, // L& CYRILLIC SMALL LIGATURE EN GHE + {0x04A6, 0x04A6, prUpper}, // L& CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK + {0x04A7, 0x04A7, prLower}, // L& CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK + {0x04A8, 0x04A8, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN HA + {0x04A9, 0x04A9, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN HA + {0x04AA, 0x04AA, prUpper}, // L& CYRILLIC CAPITAL LETTER ES WITH DESCENDER + {0x04AB, 0x04AB, prLower}, // L& CYRILLIC SMALL LETTER ES WITH DESCENDER + {0x04AC, 0x04AC, prUpper}, // L& CYRILLIC CAPITAL LETTER TE WITH DESCENDER + {0x04AD, 0x04AD, prLower}, // L& CYRILLIC SMALL LETTER TE WITH DESCENDER + {0x04AE, 0x04AE, prUpper}, // L& CYRILLIC CAPITAL LETTER STRAIGHT U + {0x04AF, 0x04AF, prLower}, // L& CYRILLIC SMALL LETTER STRAIGHT U + {0x04B0, 0x04B0, prUpper}, // L& CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + {0x04B1, 0x04B1, prLower}, // L& CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + {0x04B2, 0x04B2, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH DESCENDER + {0x04B3, 0x04B3, prLower}, // L& CYRILLIC SMALL LETTER HA WITH DESCENDER + {0x04B4, 0x04B4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE TE TSE + {0x04B5, 0x04B5, prLower}, // L& CYRILLIC SMALL LIGATURE TE TSE + {0x04B6, 0x04B6, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + {0x04B7, 0x04B7, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH DESCENDER + {0x04B8, 0x04B8, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + {0x04B9, 0x04B9, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + {0x04BA, 0x04BA, prUpper}, // L& CYRILLIC CAPITAL LETTER SHHA + {0x04BB, 0x04BB, prLower}, // L& CYRILLIC SMALL LETTER SHHA + {0x04BC, 0x04BC, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN CHE + {0x04BD, 0x04BD, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN CHE + {0x04BE, 0x04BE, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER + {0x04BF, 0x04BF, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER + {0x04C0, 0x04C1, prUpper}, // L& [2] CYRILLIC LETTER PALOCHKA..CYRILLIC CAPITAL LETTER ZHE WITH BREVE + {0x04C2, 0x04C2, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH BREVE + {0x04C3, 0x04C3, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH HOOK + {0x04C4, 0x04C4, prLower}, // L& CYRILLIC SMALL LETTER KA WITH HOOK + {0x04C5, 0x04C5, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH TAIL + {0x04C6, 0x04C6, prLower}, // L& CYRILLIC SMALL LETTER EL WITH TAIL + {0x04C7, 0x04C7, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH HOOK + {0x04C8, 0x04C8, prLower}, // L& CYRILLIC SMALL LETTER EN WITH HOOK + {0x04C9, 0x04C9, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH TAIL + {0x04CA, 0x04CA, prLower}, // L& CYRILLIC SMALL LETTER EN WITH TAIL + {0x04CB, 0x04CB, prUpper}, // L& CYRILLIC CAPITAL LETTER KHAKASSIAN CHE + {0x04CC, 0x04CC, prLower}, // L& CYRILLIC SMALL LETTER KHAKASSIAN CHE + {0x04CD, 0x04CD, prUpper}, // L& CYRILLIC CAPITAL LETTER EM WITH TAIL + {0x04CE, 0x04CF, prLower}, // L& [2] CYRILLIC SMALL LETTER EM WITH TAIL..CYRILLIC SMALL LETTER PALOCHKA + {0x04D0, 0x04D0, prUpper}, // L& CYRILLIC CAPITAL LETTER A WITH BREVE + {0x04D1, 0x04D1, prLower}, // L& CYRILLIC SMALL LETTER A WITH BREVE + {0x04D2, 0x04D2, prUpper}, // L& CYRILLIC CAPITAL LETTER A WITH DIAERESIS + {0x04D3, 0x04D3, prLower}, // L& CYRILLIC SMALL LETTER A WITH DIAERESIS + {0x04D4, 0x04D4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE A IE + {0x04D5, 0x04D5, prLower}, // L& CYRILLIC SMALL LIGATURE A IE + {0x04D6, 0x04D6, prUpper}, // L& CYRILLIC CAPITAL LETTER IE WITH BREVE + {0x04D7, 0x04D7, prLower}, // L& CYRILLIC SMALL LETTER IE WITH BREVE + {0x04D8, 0x04D8, prUpper}, // L& CYRILLIC CAPITAL LETTER SCHWA + {0x04D9, 0x04D9, prLower}, // L& CYRILLIC SMALL LETTER SCHWA + {0x04DA, 0x04DA, prUpper}, // L& CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS + {0x04DB, 0x04DB, prLower}, // L& CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS + {0x04DC, 0x04DC, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS + {0x04DD, 0x04DD, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH DIAERESIS + {0x04DE, 0x04DE, prUpper}, // L& CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS + {0x04DF, 0x04DF, prLower}, // L& CYRILLIC SMALL LETTER ZE WITH DIAERESIS + {0x04E0, 0x04E0, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN DZE + {0x04E1, 0x04E1, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN DZE + {0x04E2, 0x04E2, prUpper}, // L& CYRILLIC CAPITAL LETTER I WITH MACRON + {0x04E3, 0x04E3, prLower}, // L& CYRILLIC SMALL LETTER I WITH MACRON + {0x04E4, 0x04E4, prUpper}, // L& CYRILLIC CAPITAL LETTER I WITH DIAERESIS + {0x04E5, 0x04E5, prLower}, // L& CYRILLIC SMALL LETTER I WITH DIAERESIS + {0x04E6, 0x04E6, prUpper}, // L& CYRILLIC CAPITAL LETTER O WITH DIAERESIS + {0x04E7, 0x04E7, prLower}, // L& CYRILLIC SMALL LETTER O WITH DIAERESIS + {0x04E8, 0x04E8, prUpper}, // L& CYRILLIC CAPITAL LETTER BARRED O + {0x04E9, 0x04E9, prLower}, // L& CYRILLIC SMALL LETTER BARRED O + {0x04EA, 0x04EA, prUpper}, // L& CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS + {0x04EB, 0x04EB, prLower}, // L& CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS + {0x04EC, 0x04EC, prUpper}, // L& CYRILLIC CAPITAL LETTER E WITH DIAERESIS + {0x04ED, 0x04ED, prLower}, // L& CYRILLIC SMALL LETTER E WITH DIAERESIS + {0x04EE, 0x04EE, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH MACRON + {0x04EF, 0x04EF, prLower}, // L& CYRILLIC SMALL LETTER U WITH MACRON + {0x04F0, 0x04F0, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH DIAERESIS + {0x04F1, 0x04F1, prLower}, // L& CYRILLIC SMALL LETTER U WITH DIAERESIS + {0x04F2, 0x04F2, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE + {0x04F3, 0x04F3, prLower}, // L& CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE + {0x04F4, 0x04F4, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS + {0x04F5, 0x04F5, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH DIAERESIS + {0x04F6, 0x04F6, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH DESCENDER + {0x04F7, 0x04F7, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH DESCENDER + {0x04F8, 0x04F8, prUpper}, // L& CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS + {0x04F9, 0x04F9, prLower}, // L& CYRILLIC SMALL LETTER YERU WITH DIAERESIS + {0x04FA, 0x04FA, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK + {0x04FB, 0x04FB, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK + {0x04FC, 0x04FC, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH HOOK + {0x04FD, 0x04FD, prLower}, // L& CYRILLIC SMALL LETTER HA WITH HOOK + {0x04FE, 0x04FE, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH STROKE + {0x04FF, 0x04FF, prLower}, // L& CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x0500, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DE + {0x0501, 0x0501, prLower}, // L& CYRILLIC SMALL LETTER KOMI DE + {0x0502, 0x0502, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DJE + {0x0503, 0x0503, prLower}, // L& CYRILLIC SMALL LETTER KOMI DJE + {0x0504, 0x0504, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI ZJE + {0x0505, 0x0505, prLower}, // L& CYRILLIC SMALL LETTER KOMI ZJE + {0x0506, 0x0506, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DZJE + {0x0507, 0x0507, prLower}, // L& CYRILLIC SMALL LETTER KOMI DZJE + {0x0508, 0x0508, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI LJE + {0x0509, 0x0509, prLower}, // L& CYRILLIC SMALL LETTER KOMI LJE + {0x050A, 0x050A, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI NJE + {0x050B, 0x050B, prLower}, // L& CYRILLIC SMALL LETTER KOMI NJE + {0x050C, 0x050C, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI SJE + {0x050D, 0x050D, prLower}, // L& CYRILLIC SMALL LETTER KOMI SJE + {0x050E, 0x050E, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI TJE + {0x050F, 0x050F, prLower}, // L& CYRILLIC SMALL LETTER KOMI TJE + {0x0510, 0x0510, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED ZE + {0x0511, 0x0511, prLower}, // L& CYRILLIC SMALL LETTER REVERSED ZE + {0x0512, 0x0512, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH HOOK + {0x0513, 0x0513, prLower}, // L& CYRILLIC SMALL LETTER EL WITH HOOK + {0x0514, 0x0514, prUpper}, // L& CYRILLIC CAPITAL LETTER LHA + {0x0515, 0x0515, prLower}, // L& CYRILLIC SMALL LETTER LHA + {0x0516, 0x0516, prUpper}, // L& CYRILLIC CAPITAL LETTER RHA + {0x0517, 0x0517, prLower}, // L& CYRILLIC SMALL LETTER RHA + {0x0518, 0x0518, prUpper}, // L& CYRILLIC CAPITAL LETTER YAE + {0x0519, 0x0519, prLower}, // L& CYRILLIC SMALL LETTER YAE + {0x051A, 0x051A, prUpper}, // L& CYRILLIC CAPITAL LETTER QA + {0x051B, 0x051B, prLower}, // L& CYRILLIC SMALL LETTER QA + {0x051C, 0x051C, prUpper}, // L& CYRILLIC CAPITAL LETTER WE + {0x051D, 0x051D, prLower}, // L& CYRILLIC SMALL LETTER WE + {0x051E, 0x051E, prUpper}, // L& CYRILLIC CAPITAL LETTER ALEUT KA + {0x051F, 0x051F, prLower}, // L& CYRILLIC SMALL LETTER ALEUT KA + {0x0520, 0x0520, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK + {0x0521, 0x0521, prLower}, // L& CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK + {0x0522, 0x0522, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK + {0x0523, 0x0523, prLower}, // L& CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK + {0x0524, 0x0524, prUpper}, // L& CYRILLIC CAPITAL LETTER PE WITH DESCENDER + {0x0525, 0x0525, prLower}, // L& CYRILLIC SMALL LETTER PE WITH DESCENDER + {0x0526, 0x0526, prUpper}, // L& CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER + {0x0527, 0x0527, prLower}, // L& CYRILLIC SMALL LETTER SHHA WITH DESCENDER + {0x0528, 0x0528, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK + {0x0529, 0x0529, prLower}, // L& CYRILLIC SMALL LETTER EN WITH LEFT HOOK + {0x052A, 0x052A, prUpper}, // L& CYRILLIC CAPITAL LETTER DZZHE + {0x052B, 0x052B, prLower}, // L& CYRILLIC SMALL LETTER DZZHE + {0x052C, 0x052C, prUpper}, // L& CYRILLIC CAPITAL LETTER DCHE + {0x052D, 0x052D, prLower}, // L& CYRILLIC SMALL LETTER DCHE + {0x052E, 0x052E, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH DESCENDER + {0x052F, 0x052F, prLower}, // L& CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prUpper}, // L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prOLetter}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055D, 0x055D, prSContinue}, // Po ARMENIAN COMMA + {0x0560, 0x0588, prLower}, // L& [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prSTerm}, // Po ARMENIAN FULL STOP + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prOLetter}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prOLetter}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F3, prOLetter}, // Po HEBREW PUNCTUATION GERESH + {0x0600, 0x0605, prFormat}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x060C, 0x060D, prSContinue}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prFormat}, // Cf ARABIC LETTER MARK + {0x061D, 0x061F, prSTerm}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prOLetter}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prOLetter}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prOLetter}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNumeric}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066B, 0x066C, prNumeric}, // Po [2] ARABIC DECIMAL SEPARATOR..ARABIC THOUSANDS SEPARATOR + {0x066E, 0x066F, prOLetter}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prOLetter}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prSTerm}, // Po ARABIC FULL STOP + {0x06D5, 0x06D5, prOLetter}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prFormat}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prOLetter}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prOLetter}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNumeric}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prOLetter}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FF, 0x06FF, prOLetter}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x0702, prSTerm}, // Po [3] SYRIAC END OF PARAGRAPH..SYRIAC SUBLINEAR FULL STOP + {0x070F, 0x070F, prFormat}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prOLetter}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prOLetter}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x07A5, prOLetter}, // Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prOLetter}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prNumeric}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prOLetter}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prOLetter}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F8, 0x07F8, prSContinue}, // Po NKO COMMA + {0x07F9, 0x07F9, prSTerm}, // Po NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prOLetter}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0800, 0x0815, prOLetter}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prOLetter}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prOLetter}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prOLetter}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0837, 0x0837, prSTerm}, // Po SAMARITAN PUNCTUATION MELODIC QITSA + {0x0839, 0x0839, prSTerm}, // Po SAMARITAN PUNCTUATION QITSA + {0x083D, 0x083E, prSTerm}, // Po [2] SAMARITAN PUNCTUATION SOF MASHFAAT..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prOLetter}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0860, 0x086A, prOLetter}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prOLetter}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0889, 0x088E, prOLetter}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prFormat}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prOLetter}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prOLetter}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prFormat}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prExtend}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prOLetter}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prExtend}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prOLetter}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prExtend}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prExtend}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prExtend}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prOLetter}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prOLetter}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prSTerm}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prNumeric}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0971, 0x0971, prOLetter}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x0980, prOLetter}, // Lo [15] DEVANAGARI LETTER CANDRA A..BENGALI ANJI + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prExtend}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prOLetter}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prOLetter}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prOLetter}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prOLetter}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prOLetter}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prOLetter}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prOLetter}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prExtend}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prExtend}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prExtend}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prOLetter}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prOLetter}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prOLetter}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNumeric}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prOLetter}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09FC, 0x09FC, prOLetter}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prExtend}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prOLetter}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prOLetter}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prOLetter}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prOLetter}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prOLetter}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prOLetter}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prOLetter}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prExtend}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prOLetter}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prOLetter}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNumeric}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prOLetter}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prExtend}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prOLetter}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prOLetter}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prOLetter}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prOLetter}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prOLetter}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prOLetter}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prOLetter}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prExtend}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prExtend}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prExtend}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prOLetter}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prOLetter}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNumeric}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF9, 0x0AF9, prOLetter}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prExtend}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prOLetter}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prOLetter}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prOLetter}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prOLetter}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prOLetter}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prOLetter}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prOLetter}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prExtend}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prExtend}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prExtend}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prOLetter}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prOLetter}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNumeric}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B71, 0x0B71, prOLetter}, // Lo ORIYA LETTER WA + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prOLetter}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prOLetter}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prOLetter}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prOLetter}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prOLetter}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prOLetter}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prOLetter}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prOLetter}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prOLetter}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prOLetter}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prExtend}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prExtend}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prExtend}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prExtend}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prOLetter}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNumeric}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prExtend}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prOLetter}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prOLetter}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prOLetter}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prOLetter}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prOLetter}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prExtend}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prOLetter}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prOLetter}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prOLetter}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNumeric}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C80, 0x0C80, prOLetter}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prExtend}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C85, 0x0C8C, prOLetter}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prOLetter}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prOLetter}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prOLetter}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prOLetter}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prOLetter}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prExtend}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prExtend}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prExtend}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prExtend}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prOLetter}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prOLetter}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNumeric}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prOLetter}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prExtend}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prExtend}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prOLetter}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prOLetter}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prOLetter}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prOLetter}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prOLetter}, // Lo MALAYALAM LETTER DOT REPH + {0x0D54, 0x0D56, prOLetter}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D5F, 0x0D61, prOLetter}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNumeric}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D7A, 0x0D7F, prOLetter}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prExtend}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prOLetter}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prOLetter}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prOLetter}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prOLetter}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prOLetter}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prExtend}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prExtend}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNumeric}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prExtend}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E01, 0x0E30, prOLetter}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prOLetter}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E40, 0x0E45, prOLetter}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prOLetter}, // Lm THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E50, 0x0E59, prNumeric}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E81, 0x0E82, prOLetter}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prOLetter}, // Lo LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prOLetter}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prOLetter}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prOLetter}, // Lo LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prOLetter}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prOLetter}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prOLetter}, // Lo LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prOLetter}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prOLetter}, // Lm LAO KO LA + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNumeric}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prOLetter}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prOLetter}, // Lo TIBETAN SYLLABLE OM + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F20, 0x0F29, prNumeric}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prClose}, // Ps TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prClose}, // Pe TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prClose}, // Ps TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prClose}, // Pe TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prExtend}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prOLetter}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prOLetter}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prExtend}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prOLetter}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x1000, 0x102A, prOLetter}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prExtend}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prExtend}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prExtend}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prExtend}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prOLetter}, // Lo MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prNumeric}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104B, prSTerm}, // Po [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION + {0x1050, 0x1055, prOLetter}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prExtend}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prOLetter}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prOLetter}, // Lo MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prExtend}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prOLetter}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prExtend}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prOLetter}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prOLetter}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prExtend}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prExtend}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prOLetter}, // Lo MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prExtend}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNumeric}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prExtend}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x10A0, 0x10C5, prUpper}, // L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prUpper}, // L& GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prUpper}, // L& GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prOLetter}, // L& [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FC, 0x10FC, prLower}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prOLetter}, // L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x1248, prOLetter}, // Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prOLetter}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prOLetter}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prOLetter}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prOLetter}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prOLetter}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prOLetter}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prOLetter}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1362, 0x1362, prSTerm}, // Po ETHIOPIC FULL STOP + {0x1367, 0x1368, prSTerm}, // Po [2] ETHIOPIC QUESTION MARK..ETHIOPIC PARAGRAPH SEPARATOR + {0x1380, 0x138F, prOLetter}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x13A0, 0x13F5, prUpper}, // L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prLower}, // L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1401, 0x166C, prOLetter}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166E, 0x166E, prSTerm}, // Po CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prOLetter}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prSp}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prOLetter}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prClose}, // Ps OGHAM FEATHER MARK + {0x169C, 0x169C, prClose}, // Pe OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prOLetter}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EE, 0x16F0, prOLetter}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prOLetter}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prOLetter}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prExtend}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x1731, prOLetter}, // Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prExtend}, // Mc HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prSTerm}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prOLetter}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prOLetter}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prOLetter}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prOLetter}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prExtend}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prExtend}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prExtend}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D7, 0x17D7, prOLetter}, // Lm KHMER SIGN LEK TOO + {0x17DC, 0x17DC, prOLetter}, // Lo KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNumeric}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x1802, 0x1802, prSContinue}, // Po MONGOLIAN COMMA + {0x1803, 0x1803, prSTerm}, // Po MONGOLIAN FULL STOP + {0x1808, 0x1808, prSContinue}, // Po MONGOLIAN MANCHU COMMA + {0x1809, 0x1809, prSTerm}, // Po MONGOLIAN MANCHU FULL STOP + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prFormat}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNumeric}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prOLetter}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prOLetter}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prOLetter}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prOLetter}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prOLetter}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prOLetter}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prOLetter}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prOLetter}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prExtend}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prExtend}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prExtend}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prExtend}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1944, 0x1945, prSTerm}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prNumeric}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prOLetter}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prOLetter}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prOLetter}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prOLetter}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prNumeric}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x1A00, 0x1A16, prOLetter}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prExtend}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A20, 0x1A54, prOLetter}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prExtend}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prExtend}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prExtend}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prExtend}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prExtend}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNumeric}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNumeric}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA7, 0x1AA7, prOLetter}, // Lm TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAB, prSTerm}, // Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prExtend}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prOLetter}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prExtend}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prExtend}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prExtend}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prOLetter}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNumeric}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B5B, prSTerm}, // Po [2] BALINESE PANTI..BALINESE PAMADA + {0x1B5E, 0x1B5F, prSTerm}, // Po [2] BALINESE CARIK SIKI..BALINESE CARIK PAREREN + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B7D, 0x1B7E, prSTerm}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prExtend}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prOLetter}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prExtend}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prExtend}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prExtend}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prOLetter}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNumeric}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BE5, prOLetter}, // Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prExtend}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prExtend}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prExtend}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prExtend}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C00, 0x1C23, prOLetter}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prExtend}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prExtend}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3C, prSTerm}, // Po [2] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION NYET THYOOM TA-ROL + {0x1C40, 0x1C49, prNumeric}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prOLetter}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNumeric}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prOLetter}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prOLetter}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prSTerm}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prLower}, // L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prOLetter}, // L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prOLetter}, // L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prExtend}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prOLetter}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prOLetter}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prOLetter}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prExtend}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prOLetter}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prLower}, // L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prLower}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prLower}, // L& [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prLower}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D9A, prLower}, // L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prLower}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1E00, prUpper}, // L& LATIN CAPITAL LETTER A WITH RING BELOW + {0x1E01, 0x1E01, prLower}, // L& LATIN SMALL LETTER A WITH RING BELOW + {0x1E02, 0x1E02, prUpper}, // L& LATIN CAPITAL LETTER B WITH DOT ABOVE + {0x1E03, 0x1E03, prLower}, // L& LATIN SMALL LETTER B WITH DOT ABOVE + {0x1E04, 0x1E04, prUpper}, // L& LATIN CAPITAL LETTER B WITH DOT BELOW + {0x1E05, 0x1E05, prLower}, // L& LATIN SMALL LETTER B WITH DOT BELOW + {0x1E06, 0x1E06, prUpper}, // L& LATIN CAPITAL LETTER B WITH LINE BELOW + {0x1E07, 0x1E07, prLower}, // L& LATIN SMALL LETTER B WITH LINE BELOW + {0x1E08, 0x1E08, prUpper}, // L& LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE + {0x1E09, 0x1E09, prLower}, // L& LATIN SMALL LETTER C WITH CEDILLA AND ACUTE + {0x1E0A, 0x1E0A, prUpper}, // L& LATIN CAPITAL LETTER D WITH DOT ABOVE + {0x1E0B, 0x1E0B, prLower}, // L& LATIN SMALL LETTER D WITH DOT ABOVE + {0x1E0C, 0x1E0C, prUpper}, // L& LATIN CAPITAL LETTER D WITH DOT BELOW + {0x1E0D, 0x1E0D, prLower}, // L& LATIN SMALL LETTER D WITH DOT BELOW + {0x1E0E, 0x1E0E, prUpper}, // L& LATIN CAPITAL LETTER D WITH LINE BELOW + {0x1E0F, 0x1E0F, prLower}, // L& LATIN SMALL LETTER D WITH LINE BELOW + {0x1E10, 0x1E10, prUpper}, // L& LATIN CAPITAL LETTER D WITH CEDILLA + {0x1E11, 0x1E11, prLower}, // L& LATIN SMALL LETTER D WITH CEDILLA + {0x1E12, 0x1E12, prUpper}, // L& LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW + {0x1E13, 0x1E13, prLower}, // L& LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW + {0x1E14, 0x1E14, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON AND GRAVE + {0x1E15, 0x1E15, prLower}, // L& LATIN SMALL LETTER E WITH MACRON AND GRAVE + {0x1E16, 0x1E16, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON AND ACUTE + {0x1E17, 0x1E17, prLower}, // L& LATIN SMALL LETTER E WITH MACRON AND ACUTE + {0x1E18, 0x1E18, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW + {0x1E19, 0x1E19, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW + {0x1E1A, 0x1E1A, prUpper}, // L& LATIN CAPITAL LETTER E WITH TILDE BELOW + {0x1E1B, 0x1E1B, prLower}, // L& LATIN SMALL LETTER E WITH TILDE BELOW + {0x1E1C, 0x1E1C, prUpper}, // L& LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE + {0x1E1D, 0x1E1D, prLower}, // L& LATIN SMALL LETTER E WITH CEDILLA AND BREVE + {0x1E1E, 0x1E1E, prUpper}, // L& LATIN CAPITAL LETTER F WITH DOT ABOVE + {0x1E1F, 0x1E1F, prLower}, // L& LATIN SMALL LETTER F WITH DOT ABOVE + {0x1E20, 0x1E20, prUpper}, // L& LATIN CAPITAL LETTER G WITH MACRON + {0x1E21, 0x1E21, prLower}, // L& LATIN SMALL LETTER G WITH MACRON + {0x1E22, 0x1E22, prUpper}, // L& LATIN CAPITAL LETTER H WITH DOT ABOVE + {0x1E23, 0x1E23, prLower}, // L& LATIN SMALL LETTER H WITH DOT ABOVE + {0x1E24, 0x1E24, prUpper}, // L& LATIN CAPITAL LETTER H WITH DOT BELOW + {0x1E25, 0x1E25, prLower}, // L& LATIN SMALL LETTER H WITH DOT BELOW + {0x1E26, 0x1E26, prUpper}, // L& LATIN CAPITAL LETTER H WITH DIAERESIS + {0x1E27, 0x1E27, prLower}, // L& LATIN SMALL LETTER H WITH DIAERESIS + {0x1E28, 0x1E28, prUpper}, // L& LATIN CAPITAL LETTER H WITH CEDILLA + {0x1E29, 0x1E29, prLower}, // L& LATIN SMALL LETTER H WITH CEDILLA + {0x1E2A, 0x1E2A, prUpper}, // L& LATIN CAPITAL LETTER H WITH BREVE BELOW + {0x1E2B, 0x1E2B, prLower}, // L& LATIN SMALL LETTER H WITH BREVE BELOW + {0x1E2C, 0x1E2C, prUpper}, // L& LATIN CAPITAL LETTER I WITH TILDE BELOW + {0x1E2D, 0x1E2D, prLower}, // L& LATIN SMALL LETTER I WITH TILDE BELOW + {0x1E2E, 0x1E2E, prUpper}, // L& LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE + {0x1E2F, 0x1E2F, prLower}, // L& LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE + {0x1E30, 0x1E30, prUpper}, // L& LATIN CAPITAL LETTER K WITH ACUTE + {0x1E31, 0x1E31, prLower}, // L& LATIN SMALL LETTER K WITH ACUTE + {0x1E32, 0x1E32, prUpper}, // L& LATIN CAPITAL LETTER K WITH DOT BELOW + {0x1E33, 0x1E33, prLower}, // L& LATIN SMALL LETTER K WITH DOT BELOW + {0x1E34, 0x1E34, prUpper}, // L& LATIN CAPITAL LETTER K WITH LINE BELOW + {0x1E35, 0x1E35, prLower}, // L& LATIN SMALL LETTER K WITH LINE BELOW + {0x1E36, 0x1E36, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOT BELOW + {0x1E37, 0x1E37, prLower}, // L& LATIN SMALL LETTER L WITH DOT BELOW + {0x1E38, 0x1E38, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON + {0x1E39, 0x1E39, prLower}, // L& LATIN SMALL LETTER L WITH DOT BELOW AND MACRON + {0x1E3A, 0x1E3A, prUpper}, // L& LATIN CAPITAL LETTER L WITH LINE BELOW + {0x1E3B, 0x1E3B, prLower}, // L& LATIN SMALL LETTER L WITH LINE BELOW + {0x1E3C, 0x1E3C, prUpper}, // L& LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW + {0x1E3D, 0x1E3D, prLower}, // L& LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW + {0x1E3E, 0x1E3E, prUpper}, // L& LATIN CAPITAL LETTER M WITH ACUTE + {0x1E3F, 0x1E3F, prLower}, // L& LATIN SMALL LETTER M WITH ACUTE + {0x1E40, 0x1E40, prUpper}, // L& LATIN CAPITAL LETTER M WITH DOT ABOVE + {0x1E41, 0x1E41, prLower}, // L& LATIN SMALL LETTER M WITH DOT ABOVE + {0x1E42, 0x1E42, prUpper}, // L& LATIN CAPITAL LETTER M WITH DOT BELOW + {0x1E43, 0x1E43, prLower}, // L& LATIN SMALL LETTER M WITH DOT BELOW + {0x1E44, 0x1E44, prUpper}, // L& LATIN CAPITAL LETTER N WITH DOT ABOVE + {0x1E45, 0x1E45, prLower}, // L& LATIN SMALL LETTER N WITH DOT ABOVE + {0x1E46, 0x1E46, prUpper}, // L& LATIN CAPITAL LETTER N WITH DOT BELOW + {0x1E47, 0x1E47, prLower}, // L& LATIN SMALL LETTER N WITH DOT BELOW + {0x1E48, 0x1E48, prUpper}, // L& LATIN CAPITAL LETTER N WITH LINE BELOW + {0x1E49, 0x1E49, prLower}, // L& LATIN SMALL LETTER N WITH LINE BELOW + {0x1E4A, 0x1E4A, prUpper}, // L& LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW + {0x1E4B, 0x1E4B, prLower}, // L& LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW + {0x1E4C, 0x1E4C, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND ACUTE + {0x1E4D, 0x1E4D, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND ACUTE + {0x1E4E, 0x1E4E, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS + {0x1E4F, 0x1E4F, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND DIAERESIS + {0x1E50, 0x1E50, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON AND GRAVE + {0x1E51, 0x1E51, prLower}, // L& LATIN SMALL LETTER O WITH MACRON AND GRAVE + {0x1E52, 0x1E52, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON AND ACUTE + {0x1E53, 0x1E53, prLower}, // L& LATIN SMALL LETTER O WITH MACRON AND ACUTE + {0x1E54, 0x1E54, prUpper}, // L& LATIN CAPITAL LETTER P WITH ACUTE + {0x1E55, 0x1E55, prLower}, // L& LATIN SMALL LETTER P WITH ACUTE + {0x1E56, 0x1E56, prUpper}, // L& LATIN CAPITAL LETTER P WITH DOT ABOVE + {0x1E57, 0x1E57, prLower}, // L& LATIN SMALL LETTER P WITH DOT ABOVE + {0x1E58, 0x1E58, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT ABOVE + {0x1E59, 0x1E59, prLower}, // L& LATIN SMALL LETTER R WITH DOT ABOVE + {0x1E5A, 0x1E5A, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT BELOW + {0x1E5B, 0x1E5B, prLower}, // L& LATIN SMALL LETTER R WITH DOT BELOW + {0x1E5C, 0x1E5C, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON + {0x1E5D, 0x1E5D, prLower}, // L& LATIN SMALL LETTER R WITH DOT BELOW AND MACRON + {0x1E5E, 0x1E5E, prUpper}, // L& LATIN CAPITAL LETTER R WITH LINE BELOW + {0x1E5F, 0x1E5F, prLower}, // L& LATIN SMALL LETTER R WITH LINE BELOW + {0x1E60, 0x1E60, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT ABOVE + {0x1E61, 0x1E61, prLower}, // L& LATIN SMALL LETTER S WITH DOT ABOVE + {0x1E62, 0x1E62, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT BELOW + {0x1E63, 0x1E63, prLower}, // L& LATIN SMALL LETTER S WITH DOT BELOW + {0x1E64, 0x1E64, prUpper}, // L& LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE + {0x1E65, 0x1E65, prLower}, // L& LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE + {0x1E66, 0x1E66, prUpper}, // L& LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE + {0x1E67, 0x1E67, prLower}, // L& LATIN SMALL LETTER S WITH CARON AND DOT ABOVE + {0x1E68, 0x1E68, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE + {0x1E69, 0x1E69, prLower}, // L& LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE + {0x1E6A, 0x1E6A, prUpper}, // L& LATIN CAPITAL LETTER T WITH DOT ABOVE + {0x1E6B, 0x1E6B, prLower}, // L& LATIN SMALL LETTER T WITH DOT ABOVE + {0x1E6C, 0x1E6C, prUpper}, // L& LATIN CAPITAL LETTER T WITH DOT BELOW + {0x1E6D, 0x1E6D, prLower}, // L& LATIN SMALL LETTER T WITH DOT BELOW + {0x1E6E, 0x1E6E, prUpper}, // L& LATIN CAPITAL LETTER T WITH LINE BELOW + {0x1E6F, 0x1E6F, prLower}, // L& LATIN SMALL LETTER T WITH LINE BELOW + {0x1E70, 0x1E70, prUpper}, // L& LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW + {0x1E71, 0x1E71, prLower}, // L& LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW + {0x1E72, 0x1E72, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS BELOW + {0x1E73, 0x1E73, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS BELOW + {0x1E74, 0x1E74, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE BELOW + {0x1E75, 0x1E75, prLower}, // L& LATIN SMALL LETTER U WITH TILDE BELOW + {0x1E76, 0x1E76, prUpper}, // L& LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW + {0x1E77, 0x1E77, prLower}, // L& LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW + {0x1E78, 0x1E78, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE AND ACUTE + {0x1E79, 0x1E79, prLower}, // L& LATIN SMALL LETTER U WITH TILDE AND ACUTE + {0x1E7A, 0x1E7A, prUpper}, // L& LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS + {0x1E7B, 0x1E7B, prLower}, // L& LATIN SMALL LETTER U WITH MACRON AND DIAERESIS + {0x1E7C, 0x1E7C, prUpper}, // L& LATIN CAPITAL LETTER V WITH TILDE + {0x1E7D, 0x1E7D, prLower}, // L& LATIN SMALL LETTER V WITH TILDE + {0x1E7E, 0x1E7E, prUpper}, // L& LATIN CAPITAL LETTER V WITH DOT BELOW + {0x1E7F, 0x1E7F, prLower}, // L& LATIN SMALL LETTER V WITH DOT BELOW + {0x1E80, 0x1E80, prUpper}, // L& LATIN CAPITAL LETTER W WITH GRAVE + {0x1E81, 0x1E81, prLower}, // L& LATIN SMALL LETTER W WITH GRAVE + {0x1E82, 0x1E82, prUpper}, // L& LATIN CAPITAL LETTER W WITH ACUTE + {0x1E83, 0x1E83, prLower}, // L& LATIN SMALL LETTER W WITH ACUTE + {0x1E84, 0x1E84, prUpper}, // L& LATIN CAPITAL LETTER W WITH DIAERESIS + {0x1E85, 0x1E85, prLower}, // L& LATIN SMALL LETTER W WITH DIAERESIS + {0x1E86, 0x1E86, prUpper}, // L& LATIN CAPITAL LETTER W WITH DOT ABOVE + {0x1E87, 0x1E87, prLower}, // L& LATIN SMALL LETTER W WITH DOT ABOVE + {0x1E88, 0x1E88, prUpper}, // L& LATIN CAPITAL LETTER W WITH DOT BELOW + {0x1E89, 0x1E89, prLower}, // L& LATIN SMALL LETTER W WITH DOT BELOW + {0x1E8A, 0x1E8A, prUpper}, // L& LATIN CAPITAL LETTER X WITH DOT ABOVE + {0x1E8B, 0x1E8B, prLower}, // L& LATIN SMALL LETTER X WITH DOT ABOVE + {0x1E8C, 0x1E8C, prUpper}, // L& LATIN CAPITAL LETTER X WITH DIAERESIS + {0x1E8D, 0x1E8D, prLower}, // L& LATIN SMALL LETTER X WITH DIAERESIS + {0x1E8E, 0x1E8E, prUpper}, // L& LATIN CAPITAL LETTER Y WITH DOT ABOVE + {0x1E8F, 0x1E8F, prLower}, // L& LATIN SMALL LETTER Y WITH DOT ABOVE + {0x1E90, 0x1E90, prUpper}, // L& LATIN CAPITAL LETTER Z WITH CIRCUMFLEX + {0x1E91, 0x1E91, prLower}, // L& LATIN SMALL LETTER Z WITH CIRCUMFLEX + {0x1E92, 0x1E92, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DOT BELOW + {0x1E93, 0x1E93, prLower}, // L& LATIN SMALL LETTER Z WITH DOT BELOW + {0x1E94, 0x1E94, prUpper}, // L& LATIN CAPITAL LETTER Z WITH LINE BELOW + {0x1E95, 0x1E9D, prLower}, // L& [9] LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER LONG S WITH HIGH STROKE + {0x1E9E, 0x1E9E, prUpper}, // L& LATIN CAPITAL LETTER SHARP S + {0x1E9F, 0x1E9F, prLower}, // L& LATIN SMALL LETTER DELTA + {0x1EA0, 0x1EA0, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT BELOW + {0x1EA1, 0x1EA1, prLower}, // L& LATIN SMALL LETTER A WITH DOT BELOW + {0x1EA2, 0x1EA2, prUpper}, // L& LATIN CAPITAL LETTER A WITH HOOK ABOVE + {0x1EA3, 0x1EA3, prLower}, // L& LATIN SMALL LETTER A WITH HOOK ABOVE + {0x1EA4, 0x1EA4, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE + {0x1EA5, 0x1EA5, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + {0x1EA6, 0x1EA6, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE + {0x1EA7, 0x1EA7, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE + {0x1EA8, 0x1EA8, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EA9, 0x1EA9, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EAA, 0x1EAA, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE + {0x1EAB, 0x1EAB, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE + {0x1EAC, 0x1EAC, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW + {0x1EAD, 0x1EAD, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW + {0x1EAE, 0x1EAE, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND ACUTE + {0x1EAF, 0x1EAF, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND ACUTE + {0x1EB0, 0x1EB0, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND GRAVE + {0x1EB1, 0x1EB1, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND GRAVE + {0x1EB2, 0x1EB2, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE + {0x1EB3, 0x1EB3, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE + {0x1EB4, 0x1EB4, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND TILDE + {0x1EB5, 0x1EB5, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND TILDE + {0x1EB6, 0x1EB6, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW + {0x1EB7, 0x1EB7, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND DOT BELOW + {0x1EB8, 0x1EB8, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOT BELOW + {0x1EB9, 0x1EB9, prLower}, // L& LATIN SMALL LETTER E WITH DOT BELOW + {0x1EBA, 0x1EBA, prUpper}, // L& LATIN CAPITAL LETTER E WITH HOOK ABOVE + {0x1EBB, 0x1EBB, prLower}, // L& LATIN SMALL LETTER E WITH HOOK ABOVE + {0x1EBC, 0x1EBC, prUpper}, // L& LATIN CAPITAL LETTER E WITH TILDE + {0x1EBD, 0x1EBD, prLower}, // L& LATIN SMALL LETTER E WITH TILDE + {0x1EBE, 0x1EBE, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE + {0x1EBF, 0x1EBF, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE + {0x1EC0, 0x1EC0, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE + {0x1EC1, 0x1EC1, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + {0x1EC2, 0x1EC2, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EC3, 0x1EC3, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EC4, 0x1EC4, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE + {0x1EC5, 0x1EC5, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE + {0x1EC6, 0x1EC6, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW + {0x1EC7, 0x1EC7, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW + {0x1EC8, 0x1EC8, prUpper}, // L& LATIN CAPITAL LETTER I WITH HOOK ABOVE + {0x1EC9, 0x1EC9, prLower}, // L& LATIN SMALL LETTER I WITH HOOK ABOVE + {0x1ECA, 0x1ECA, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOT BELOW + {0x1ECB, 0x1ECB, prLower}, // L& LATIN SMALL LETTER I WITH DOT BELOW + {0x1ECC, 0x1ECC, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT BELOW + {0x1ECD, 0x1ECD, prLower}, // L& LATIN SMALL LETTER O WITH DOT BELOW + {0x1ECE, 0x1ECE, prUpper}, // L& LATIN CAPITAL LETTER O WITH HOOK ABOVE + {0x1ECF, 0x1ECF, prLower}, // L& LATIN SMALL LETTER O WITH HOOK ABOVE + {0x1ED0, 0x1ED0, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE + {0x1ED1, 0x1ED1, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE + {0x1ED2, 0x1ED2, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE + {0x1ED3, 0x1ED3, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE + {0x1ED4, 0x1ED4, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + {0x1ED5, 0x1ED5, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + {0x1ED6, 0x1ED6, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE + {0x1ED7, 0x1ED7, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE + {0x1ED8, 0x1ED8, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW + {0x1ED9, 0x1ED9, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW + {0x1EDA, 0x1EDA, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND ACUTE + {0x1EDB, 0x1EDB, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND ACUTE + {0x1EDC, 0x1EDC, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND GRAVE + {0x1EDD, 0x1EDD, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND GRAVE + {0x1EDE, 0x1EDE, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE + {0x1EDF, 0x1EDF, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE + {0x1EE0, 0x1EE0, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND TILDE + {0x1EE1, 0x1EE1, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND TILDE + {0x1EE2, 0x1EE2, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW + {0x1EE3, 0x1EE3, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND DOT BELOW + {0x1EE4, 0x1EE4, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOT BELOW + {0x1EE5, 0x1EE5, prLower}, // L& LATIN SMALL LETTER U WITH DOT BELOW + {0x1EE6, 0x1EE6, prUpper}, // L& LATIN CAPITAL LETTER U WITH HOOK ABOVE + {0x1EE7, 0x1EE7, prLower}, // L& LATIN SMALL LETTER U WITH HOOK ABOVE + {0x1EE8, 0x1EE8, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND ACUTE + {0x1EE9, 0x1EE9, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND ACUTE + {0x1EEA, 0x1EEA, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND GRAVE + {0x1EEB, 0x1EEB, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND GRAVE + {0x1EEC, 0x1EEC, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE + {0x1EED, 0x1EED, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE + {0x1EEE, 0x1EEE, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND TILDE + {0x1EEF, 0x1EEF, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND TILDE + {0x1EF0, 0x1EF0, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW + {0x1EF1, 0x1EF1, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND DOT BELOW + {0x1EF2, 0x1EF2, prUpper}, // L& LATIN CAPITAL LETTER Y WITH GRAVE + {0x1EF3, 0x1EF3, prLower}, // L& LATIN SMALL LETTER Y WITH GRAVE + {0x1EF4, 0x1EF4, prUpper}, // L& LATIN CAPITAL LETTER Y WITH DOT BELOW + {0x1EF5, 0x1EF5, prLower}, // L& LATIN SMALL LETTER Y WITH DOT BELOW + {0x1EF6, 0x1EF6, prUpper}, // L& LATIN CAPITAL LETTER Y WITH HOOK ABOVE + {0x1EF7, 0x1EF7, prLower}, // L& LATIN SMALL LETTER Y WITH HOOK ABOVE + {0x1EF8, 0x1EF8, prUpper}, // L& LATIN CAPITAL LETTER Y WITH TILDE + {0x1EF9, 0x1EF9, prLower}, // L& LATIN SMALL LETTER Y WITH TILDE + {0x1EFA, 0x1EFA, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE-WELSH LL + {0x1EFB, 0x1EFB, prLower}, // L& LATIN SMALL LETTER MIDDLE-WELSH LL + {0x1EFC, 0x1EFC, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE-WELSH V + {0x1EFD, 0x1EFD, prLower}, // L& LATIN SMALL LETTER MIDDLE-WELSH V + {0x1EFE, 0x1EFE, prUpper}, // L& LATIN CAPITAL LETTER Y WITH LOOP + {0x1EFF, 0x1F07, prLower}, // L& [9] LATIN SMALL LETTER Y WITH LOOP..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI + {0x1F08, 0x1F0F, prUpper}, // L& [8] GREEK CAPITAL LETTER ALPHA WITH PSILI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI + {0x1F10, 0x1F15, prLower}, // L& [6] GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prUpper}, // L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F27, prLower}, // L& [8] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI + {0x1F28, 0x1F2F, prUpper}, // L& [8] GREEK CAPITAL LETTER ETA WITH PSILI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI + {0x1F30, 0x1F37, prLower}, // L& [8] GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI + {0x1F38, 0x1F3F, prUpper}, // L& [8] GREEK CAPITAL LETTER IOTA WITH PSILI..GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI + {0x1F40, 0x1F45, prLower}, // L& [6] GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prUpper}, // L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prLower}, // L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F5F, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F60, 0x1F67, prLower}, // L& [8] GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI + {0x1F68, 0x1F6F, prUpper}, // L& [8] GREEK CAPITAL LETTER OMEGA WITH PSILI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI + {0x1F70, 0x1F7D, prLower}, // L& [14] GREEK SMALL LETTER ALPHA WITH VARIA..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1F87, prLower}, // L& [8] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1F88, 0x1F8F, prUpper}, // L& [8] GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1F90, 0x1F97, prLower}, // L& [8] GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1F98, 0x1F9F, prUpper}, // L& [8] GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1FA0, 0x1FA7, prLower}, // L& [8] GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1FA8, 0x1FAF, prUpper}, // L& [8] GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1FB0, 0x1FB4, prLower}, // L& [5] GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FB7, prLower}, // L& [2] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FB8, 0x1FBC, prUpper}, // L& [5] GREEK CAPITAL LETTER ALPHA WITH VRACHY..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBE, 0x1FBE, prLower}, // L& GREEK PROSGEGRAMMENI + {0x1FC2, 0x1FC4, prLower}, // L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FC7, prLower}, // L& [2] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FC8, 0x1FCC, prUpper}, // L& [5] GREEK CAPITAL LETTER EPSILON WITH VARIA..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FD0, 0x1FD3, prLower}, // L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FD7, prLower}, // L& [2] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI + {0x1FD8, 0x1FDB, prUpper}, // L& [4] GREEK CAPITAL LETTER IOTA WITH VRACHY..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FE0, 0x1FE7, prLower}, // L& [8] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI + {0x1FE8, 0x1FEC, prUpper}, // L& [5] GREEK CAPITAL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FF2, 0x1FF4, prLower}, // L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FF7, prLower}, // L& [2] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FF8, 0x1FFC, prUpper}, // L& [5] GREEK CAPITAL LETTER OMICRON WITH VARIA..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x2000, 0x200A, prSp}, // Zs [11] EN QUAD..HAIR SPACE + {0x200B, 0x200B, prFormat}, // Cf ZERO WIDTH SPACE + {0x200C, 0x200D, prExtend}, // Cf [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER + {0x200E, 0x200F, prFormat}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2013, 0x2014, prSContinue}, // Pd [2] EN DASH..EM DASH + {0x2018, 0x2018, prClose}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prClose}, // Pf RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prClose}, // Ps SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201C, prClose}, // Pi [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prClose}, // Pf RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prClose}, // Ps DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prClose}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2024, 0x2024, prATerm}, // Po ONE DOT LEADER + {0x2028, 0x2028, prSep}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prSep}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prFormat}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prSp}, // Zs NARROW NO-BREAK SPACE + {0x2039, 0x2039, prClose}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prClose}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203C, 0x203D, prSTerm}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x2045, 0x2045, prClose}, // Ps LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prClose}, // Pe RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2049, prSTerm}, // Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK + {0x205F, 0x205F, prSp}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prFormat}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prFormat}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2071, 0x2071, prLower}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x207D, 0x207D, prClose}, // Ps SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prClose}, // Pe SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prLower}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x208D, 0x208D, prClose}, // Ps SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prClose}, // Pe SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prLower}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2102, 0x2102, prUpper}, // L& DOUBLE-STRUCK CAPITAL C + {0x2107, 0x2107, prUpper}, // L& EULER CONSTANT + {0x210A, 0x210A, prLower}, // L& SCRIPT SMALL G + {0x210B, 0x210D, prUpper}, // L& [3] SCRIPT CAPITAL H..DOUBLE-STRUCK CAPITAL H + {0x210E, 0x210F, prLower}, // L& [2] PLANCK CONSTANT..PLANCK CONSTANT OVER TWO PI + {0x2110, 0x2112, prUpper}, // L& [3] SCRIPT CAPITAL I..SCRIPT CAPITAL L + {0x2113, 0x2113, prLower}, // L& SCRIPT SMALL L + {0x2115, 0x2115, prUpper}, // L& DOUBLE-STRUCK CAPITAL N + {0x2119, 0x211D, prUpper}, // L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x2124, 0x2124, prUpper}, // L& DOUBLE-STRUCK CAPITAL Z + {0x2126, 0x2126, prUpper}, // L& OHM SIGN + {0x2128, 0x2128, prUpper}, // L& BLACK-LETTER CAPITAL Z + {0x212A, 0x212D, prUpper}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C + {0x212F, 0x212F, prLower}, // L& SCRIPT SMALL E + {0x2130, 0x2133, prUpper}, // L& [4] SCRIPT CAPITAL E..SCRIPT CAPITAL M + {0x2134, 0x2134, prLower}, // L& SCRIPT SMALL O + {0x2135, 0x2138, prOLetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prLower}, // L& INFORMATION SOURCE + {0x213C, 0x213D, prLower}, // L& [2] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK SMALL GAMMA + {0x213E, 0x213F, prUpper}, // L& [2] DOUBLE-STRUCK CAPITAL GAMMA..DOUBLE-STRUCK CAPITAL PI + {0x2145, 0x2145, prUpper}, // L& DOUBLE-STRUCK ITALIC CAPITAL D + {0x2146, 0x2149, prLower}, // L& [4] DOUBLE-STRUCK ITALIC SMALL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214E, 0x214E, prLower}, // L& TURNED SMALL F + {0x2160, 0x216F, prUpper}, // Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x217F, prLower}, // Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND + {0x2180, 0x2182, prOLetter}, // Nl [3] ROMAN NUMERAL ONE THOUSAND C D..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2183, prUpper}, // L& ROMAN NUMERAL REVERSED ONE HUNDRED + {0x2184, 0x2184, prLower}, // L& LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prOLetter}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2308, 0x2308, prClose}, // Ps LEFT CEILING + {0x2309, 0x2309, prClose}, // Pe RIGHT CEILING + {0x230A, 0x230A, prClose}, // Ps LEFT FLOOR + {0x230B, 0x230B, prClose}, // Pe RIGHT FLOOR + {0x2329, 0x2329, prClose}, // Ps LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prClose}, // Pe RIGHT-POINTING ANGLE BRACKET + {0x24B6, 0x24CF, prUpper}, // So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z + {0x24D0, 0x24E9, prLower}, // So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x275B, 0x2760, prClose}, // So [6] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x2768, 0x2768, prClose}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prClose}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prClose}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prClose}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prClose}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prClose}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prClose}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prClose}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prClose}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prClose}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prClose}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prClose}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prClose}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prClose}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x27C5, 0x27C5, prClose}, // Ps LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prClose}, // Pe RIGHT S-SHAPED BAG DELIMITER + {0x27E6, 0x27E6, prClose}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prClose}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prClose}, // Ps MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prClose}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prClose}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prClose}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prClose}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prClose}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prClose}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prClose}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x2983, 0x2983, prClose}, // Ps LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prClose}, // Pe RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prClose}, // Ps LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prClose}, // Pe RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prClose}, // Ps Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prClose}, // Pe Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prClose}, // Ps Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prClose}, // Pe Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prClose}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prClose}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prClose}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prClose}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prClose}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prClose}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prClose}, // Ps LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prClose}, // Pe RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prClose}, // Ps LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prClose}, // Pe RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prClose}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prClose}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prClose}, // Ps LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prClose}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET + {0x29D8, 0x29D8, prClose}, // Ps LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prClose}, // Pe RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prClose}, // Ps LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prClose}, // Pe RIGHT DOUBLE WIGGLY FENCE + {0x29FC, 0x29FC, prClose}, // Ps LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prClose}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET + {0x2C00, 0x2C2F, prUpper}, // L& [48] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI + {0x2C30, 0x2C5F, prLower}, // L& [48] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C60, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOUBLE BAR + {0x2C61, 0x2C61, prLower}, // L& LATIN SMALL LETTER L WITH DOUBLE BAR + {0x2C62, 0x2C64, prUpper}, // L& [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL + {0x2C65, 0x2C66, prLower}, // L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE + {0x2C67, 0x2C67, prUpper}, // L& LATIN CAPITAL LETTER H WITH DESCENDER + {0x2C68, 0x2C68, prLower}, // L& LATIN SMALL LETTER H WITH DESCENDER + {0x2C69, 0x2C69, prUpper}, // L& LATIN CAPITAL LETTER K WITH DESCENDER + {0x2C6A, 0x2C6A, prLower}, // L& LATIN SMALL LETTER K WITH DESCENDER + {0x2C6B, 0x2C6B, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DESCENDER + {0x2C6C, 0x2C6C, prLower}, // L& LATIN SMALL LETTER Z WITH DESCENDER + {0x2C6D, 0x2C70, prUpper}, // L& [4] LATIN CAPITAL LETTER ALPHA..LATIN CAPITAL LETTER TURNED ALPHA + {0x2C71, 0x2C71, prLower}, // L& LATIN SMALL LETTER V WITH RIGHT HOOK + {0x2C72, 0x2C72, prUpper}, // L& LATIN CAPITAL LETTER W WITH HOOK + {0x2C73, 0x2C74, prLower}, // L& [2] LATIN SMALL LETTER W WITH HOOK..LATIN SMALL LETTER V WITH CURL + {0x2C75, 0x2C75, prUpper}, // L& LATIN CAPITAL LETTER HALF H + {0x2C76, 0x2C7B, prLower}, // L& [6] LATIN SMALL LETTER HALF H..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prLower}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C80, prUpper}, // L& [3] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC CAPITAL LETTER ALFA + {0x2C81, 0x2C81, prLower}, // L& COPTIC SMALL LETTER ALFA + {0x2C82, 0x2C82, prUpper}, // L& COPTIC CAPITAL LETTER VIDA + {0x2C83, 0x2C83, prLower}, // L& COPTIC SMALL LETTER VIDA + {0x2C84, 0x2C84, prUpper}, // L& COPTIC CAPITAL LETTER GAMMA + {0x2C85, 0x2C85, prLower}, // L& COPTIC SMALL LETTER GAMMA + {0x2C86, 0x2C86, prUpper}, // L& COPTIC CAPITAL LETTER DALDA + {0x2C87, 0x2C87, prLower}, // L& COPTIC SMALL LETTER DALDA + {0x2C88, 0x2C88, prUpper}, // L& COPTIC CAPITAL LETTER EIE + {0x2C89, 0x2C89, prLower}, // L& COPTIC SMALL LETTER EIE + {0x2C8A, 0x2C8A, prUpper}, // L& COPTIC CAPITAL LETTER SOU + {0x2C8B, 0x2C8B, prLower}, // L& COPTIC SMALL LETTER SOU + {0x2C8C, 0x2C8C, prUpper}, // L& COPTIC CAPITAL LETTER ZATA + {0x2C8D, 0x2C8D, prLower}, // L& COPTIC SMALL LETTER ZATA + {0x2C8E, 0x2C8E, prUpper}, // L& COPTIC CAPITAL LETTER HATE + {0x2C8F, 0x2C8F, prLower}, // L& COPTIC SMALL LETTER HATE + {0x2C90, 0x2C90, prUpper}, // L& COPTIC CAPITAL LETTER THETHE + {0x2C91, 0x2C91, prLower}, // L& COPTIC SMALL LETTER THETHE + {0x2C92, 0x2C92, prUpper}, // L& COPTIC CAPITAL LETTER IAUDA + {0x2C93, 0x2C93, prLower}, // L& COPTIC SMALL LETTER IAUDA + {0x2C94, 0x2C94, prUpper}, // L& COPTIC CAPITAL LETTER KAPA + {0x2C95, 0x2C95, prLower}, // L& COPTIC SMALL LETTER KAPA + {0x2C96, 0x2C96, prUpper}, // L& COPTIC CAPITAL LETTER LAULA + {0x2C97, 0x2C97, prLower}, // L& COPTIC SMALL LETTER LAULA + {0x2C98, 0x2C98, prUpper}, // L& COPTIC CAPITAL LETTER MI + {0x2C99, 0x2C99, prLower}, // L& COPTIC SMALL LETTER MI + {0x2C9A, 0x2C9A, prUpper}, // L& COPTIC CAPITAL LETTER NI + {0x2C9B, 0x2C9B, prLower}, // L& COPTIC SMALL LETTER NI + {0x2C9C, 0x2C9C, prUpper}, // L& COPTIC CAPITAL LETTER KSI + {0x2C9D, 0x2C9D, prLower}, // L& COPTIC SMALL LETTER KSI + {0x2C9E, 0x2C9E, prUpper}, // L& COPTIC CAPITAL LETTER O + {0x2C9F, 0x2C9F, prLower}, // L& COPTIC SMALL LETTER O + {0x2CA0, 0x2CA0, prUpper}, // L& COPTIC CAPITAL LETTER PI + {0x2CA1, 0x2CA1, prLower}, // L& COPTIC SMALL LETTER PI + {0x2CA2, 0x2CA2, prUpper}, // L& COPTIC CAPITAL LETTER RO + {0x2CA3, 0x2CA3, prLower}, // L& COPTIC SMALL LETTER RO + {0x2CA4, 0x2CA4, prUpper}, // L& COPTIC CAPITAL LETTER SIMA + {0x2CA5, 0x2CA5, prLower}, // L& COPTIC SMALL LETTER SIMA + {0x2CA6, 0x2CA6, prUpper}, // L& COPTIC CAPITAL LETTER TAU + {0x2CA7, 0x2CA7, prLower}, // L& COPTIC SMALL LETTER TAU + {0x2CA8, 0x2CA8, prUpper}, // L& COPTIC CAPITAL LETTER UA + {0x2CA9, 0x2CA9, prLower}, // L& COPTIC SMALL LETTER UA + {0x2CAA, 0x2CAA, prUpper}, // L& COPTIC CAPITAL LETTER FI + {0x2CAB, 0x2CAB, prLower}, // L& COPTIC SMALL LETTER FI + {0x2CAC, 0x2CAC, prUpper}, // L& COPTIC CAPITAL LETTER KHI + {0x2CAD, 0x2CAD, prLower}, // L& COPTIC SMALL LETTER KHI + {0x2CAE, 0x2CAE, prUpper}, // L& COPTIC CAPITAL LETTER PSI + {0x2CAF, 0x2CAF, prLower}, // L& COPTIC SMALL LETTER PSI + {0x2CB0, 0x2CB0, prUpper}, // L& COPTIC CAPITAL LETTER OOU + {0x2CB1, 0x2CB1, prLower}, // L& COPTIC SMALL LETTER OOU + {0x2CB2, 0x2CB2, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P ALEF + {0x2CB3, 0x2CB3, prLower}, // L& COPTIC SMALL LETTER DIALECT-P ALEF + {0x2CB4, 0x2CB4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC AIN + {0x2CB5, 0x2CB5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC AIN + {0x2CB6, 0x2CB6, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE + {0x2CB7, 0x2CB7, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC EIE + {0x2CB8, 0x2CB8, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P KAPA + {0x2CB9, 0x2CB9, prLower}, // L& COPTIC SMALL LETTER DIALECT-P KAPA + {0x2CBA, 0x2CBA, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P NI + {0x2CBB, 0x2CBB, prLower}, // L& COPTIC SMALL LETTER DIALECT-P NI + {0x2CBC, 0x2CBC, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI + {0x2CBD, 0x2CBD, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC NI + {0x2CBE, 0x2CBE, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC OOU + {0x2CBF, 0x2CBF, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC OOU + {0x2CC0, 0x2CC0, prUpper}, // L& COPTIC CAPITAL LETTER SAMPI + {0x2CC1, 0x2CC1, prLower}, // L& COPTIC SMALL LETTER SAMPI + {0x2CC2, 0x2CC2, prUpper}, // L& COPTIC CAPITAL LETTER CROSSED SHEI + {0x2CC3, 0x2CC3, prLower}, // L& COPTIC SMALL LETTER CROSSED SHEI + {0x2CC4, 0x2CC4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC SHEI + {0x2CC5, 0x2CC5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC SHEI + {0x2CC6, 0x2CC6, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC ESH + {0x2CC7, 0x2CC7, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC ESH + {0x2CC8, 0x2CC8, prUpper}, // L& COPTIC CAPITAL LETTER AKHMIMIC KHEI + {0x2CC9, 0x2CC9, prLower}, // L& COPTIC SMALL LETTER AKHMIMIC KHEI + {0x2CCA, 0x2CCA, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P HORI + {0x2CCB, 0x2CCB, prLower}, // L& COPTIC SMALL LETTER DIALECT-P HORI + {0x2CCC, 0x2CCC, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HORI + {0x2CCD, 0x2CCD, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HORI + {0x2CCE, 0x2CCE, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HA + {0x2CCF, 0x2CCF, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HA + {0x2CD0, 0x2CD0, prUpper}, // L& COPTIC CAPITAL LETTER L-SHAPED HA + {0x2CD1, 0x2CD1, prLower}, // L& COPTIC SMALL LETTER L-SHAPED HA + {0x2CD2, 0x2CD2, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HEI + {0x2CD3, 0x2CD3, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HEI + {0x2CD4, 0x2CD4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HAT + {0x2CD5, 0x2CD5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HAT + {0x2CD6, 0x2CD6, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC GANGIA + {0x2CD7, 0x2CD7, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC GANGIA + {0x2CD8, 0x2CD8, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC DJA + {0x2CD9, 0x2CD9, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC DJA + {0x2CDA, 0x2CDA, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC SHIMA + {0x2CDB, 0x2CDB, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC SHIMA + {0x2CDC, 0x2CDC, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN SHIMA + {0x2CDD, 0x2CDD, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN SHIMA + {0x2CDE, 0x2CDE, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN NGI + {0x2CDF, 0x2CDF, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN NGI + {0x2CE0, 0x2CE0, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN NYI + {0x2CE1, 0x2CE1, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN NYI + {0x2CE2, 0x2CE2, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN WAU + {0x2CE3, 0x2CE4, prLower}, // L& [2] COPTIC SMALL LETTER OLD NUBIAN WAU..COPTIC SYMBOL KAI + {0x2CEB, 0x2CEB, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI + {0x2CEC, 0x2CEC, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI + {0x2CED, 0x2CED, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEE, 0x2CEE, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF2, prUpper}, // L& COPTIC CAPITAL LETTER BOHAIRIC KHEI + {0x2CF3, 0x2CF3, prLower}, // L& COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2D00, 0x2D25, prLower}, // L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prLower}, // L& GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prLower}, // L& GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prOLetter}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prOLetter}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prOLetter}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prClose}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prClose}, // Pi LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prClose}, // Pf RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prClose}, // Pi LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prClose}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prClose}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prClose}, // Pi LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prClose}, // Pf RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prClose}, // Po RAISED SQUARE + {0x2E0C, 0x2E0C, prClose}, // Pi LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prClose}, // Pf RIGHT RAISED OMISSION BRACKET + {0x2E1C, 0x2E1C, prClose}, // Pi LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prClose}, // Pf RIGHT LOW PARAPHRASE BRACKET + {0x2E20, 0x2E20, prClose}, // Pi LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prClose}, // Pf RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prClose}, // Ps TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prClose}, // Pe TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prClose}, // Ps BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prClose}, // Pe BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prClose}, // Ps LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prClose}, // Pe RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prClose}, // Ps LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prClose}, // Pe RIGHT DOUBLE PARENTHESIS + {0x2E2E, 0x2E2E, prSTerm}, // Po REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prOLetter}, // Lm VERTICAL TILDE + {0x2E3C, 0x2E3C, prSTerm}, // Po STENOGRAPHIC FULL STOP + {0x2E42, 0x2E42, prClose}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E53, 0x2E54, prSTerm}, // Po [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prClose}, // Ps LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prClose}, // Pe RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prClose}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prClose}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prClose}, // Ps TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prClose}, // Pe TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prClose}, // Ps BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prClose}, // Pe BOTTOM HALF RIGHT PARENTHESIS + {0x3000, 0x3000, prSp}, // Zs IDEOGRAPHIC SPACE + {0x3001, 0x3001, prSContinue}, // Po IDEOGRAPHIC COMMA + {0x3002, 0x3002, prSTerm}, // Po IDEOGRAPHIC FULL STOP + {0x3005, 0x3005, prOLetter}, // Lm IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prOLetter}, // Lo IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prOLetter}, // Nl IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prClose}, // Ps LEFT ANGLE BRACKET + {0x3009, 0x3009, prClose}, // Pe RIGHT ANGLE BRACKET + {0x300A, 0x300A, prClose}, // Ps LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prClose}, // Pe RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prClose}, // Ps LEFT CORNER BRACKET + {0x300D, 0x300D, prClose}, // Pe RIGHT CORNER BRACKET + {0x300E, 0x300E, prClose}, // Ps LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prClose}, // Pe RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prClose}, // Ps LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prClose}, // Pe RIGHT BLACK LENTICULAR BRACKET + {0x3014, 0x3014, prClose}, // Ps LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prClose}, // Pe RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prClose}, // Ps LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prClose}, // Pe RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prClose}, // Ps LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prClose}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prClose}, // Ps LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prClose}, // Pe RIGHT WHITE SQUARE BRACKET + {0x301D, 0x301D, prClose}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prClose}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3021, 0x3029, prOLetter}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3031, 0x3035, prOLetter}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x3038, 0x303A, prOLetter}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prOLetter}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prOLetter}, // Lo MASU MARK + {0x3041, 0x3096, prOLetter}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prOLetter}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prOLetter}, // Lo HIRAGANA DIGRAPH YORI + {0x30A1, 0x30FA, prOLetter}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FC, 0x30FE, prOLetter}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prOLetter}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prOLetter}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prOLetter}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x31A0, 0x31BF, prOLetter}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31F0, 0x31FF, prOLetter}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3400, 0x4DBF, prOLetter}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4E00, 0xA014, prOLetter}, // Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E + {0xA015, 0xA015, prOLetter}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prOLetter}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA4D0, 0xA4F7, prOLetter}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prOLetter}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FF, 0xA4FF, prSTerm}, // Po LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prOLetter}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prOLetter}, // Lm VAI SYLLABLE LENGTHENER + {0xA60E, 0xA60F, prSTerm}, // Po [2] VAI FULL STOP..VAI QUESTION MARK + {0xA610, 0xA61F, prOLetter}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNumeric}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prOLetter}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA640, prUpper}, // L& CYRILLIC CAPITAL LETTER ZEMLYA + {0xA641, 0xA641, prLower}, // L& CYRILLIC SMALL LETTER ZEMLYA + {0xA642, 0xA642, prUpper}, // L& CYRILLIC CAPITAL LETTER DZELO + {0xA643, 0xA643, prLower}, // L& CYRILLIC SMALL LETTER DZELO + {0xA644, 0xA644, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED DZE + {0xA645, 0xA645, prLower}, // L& CYRILLIC SMALL LETTER REVERSED DZE + {0xA646, 0xA646, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTA + {0xA647, 0xA647, prLower}, // L& CYRILLIC SMALL LETTER IOTA + {0xA648, 0xA648, prUpper}, // L& CYRILLIC CAPITAL LETTER DJERV + {0xA649, 0xA649, prLower}, // L& CYRILLIC SMALL LETTER DJERV + {0xA64A, 0xA64A, prUpper}, // L& CYRILLIC CAPITAL LETTER MONOGRAPH UK + {0xA64B, 0xA64B, prLower}, // L& CYRILLIC SMALL LETTER MONOGRAPH UK + {0xA64C, 0xA64C, prUpper}, // L& CYRILLIC CAPITAL LETTER BROAD OMEGA + {0xA64D, 0xA64D, prLower}, // L& CYRILLIC SMALL LETTER BROAD OMEGA + {0xA64E, 0xA64E, prUpper}, // L& CYRILLIC CAPITAL LETTER NEUTRAL YER + {0xA64F, 0xA64F, prLower}, // L& CYRILLIC SMALL LETTER NEUTRAL YER + {0xA650, 0xA650, prUpper}, // L& CYRILLIC CAPITAL LETTER YERU WITH BACK YER + {0xA651, 0xA651, prLower}, // L& CYRILLIC SMALL LETTER YERU WITH BACK YER + {0xA652, 0xA652, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED YAT + {0xA653, 0xA653, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED YAT + {0xA654, 0xA654, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED YU + {0xA655, 0xA655, prLower}, // L& CYRILLIC SMALL LETTER REVERSED YU + {0xA656, 0xA656, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED A + {0xA657, 0xA657, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED A + {0xA658, 0xA658, prUpper}, // L& CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS + {0xA659, 0xA659, prLower}, // L& CYRILLIC SMALL LETTER CLOSED LITTLE YUS + {0xA65A, 0xA65A, prUpper}, // L& CYRILLIC CAPITAL LETTER BLENDED YUS + {0xA65B, 0xA65B, prLower}, // L& CYRILLIC SMALL LETTER BLENDED YUS + {0xA65C, 0xA65C, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS + {0xA65D, 0xA65D, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS + {0xA65E, 0xA65E, prUpper}, // L& CYRILLIC CAPITAL LETTER YN + {0xA65F, 0xA65F, prLower}, // L& CYRILLIC SMALL LETTER YN + {0xA660, 0xA660, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED TSE + {0xA661, 0xA661, prLower}, // L& CYRILLIC SMALL LETTER REVERSED TSE + {0xA662, 0xA662, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT DE + {0xA663, 0xA663, prLower}, // L& CYRILLIC SMALL LETTER SOFT DE + {0xA664, 0xA664, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT EL + {0xA665, 0xA665, prLower}, // L& CYRILLIC SMALL LETTER SOFT EL + {0xA666, 0xA666, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT EM + {0xA667, 0xA667, prLower}, // L& CYRILLIC SMALL LETTER SOFT EM + {0xA668, 0xA668, prUpper}, // L& CYRILLIC CAPITAL LETTER MONOCULAR O + {0xA669, 0xA669, prLower}, // L& CYRILLIC SMALL LETTER MONOCULAR O + {0xA66A, 0xA66A, prUpper}, // L& CYRILLIC CAPITAL LETTER BINOCULAR O + {0xA66B, 0xA66B, prLower}, // L& CYRILLIC SMALL LETTER BINOCULAR O + {0xA66C, 0xA66C, prUpper}, // L& CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O + {0xA66D, 0xA66D, prLower}, // L& CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prOLetter}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67F, 0xA67F, prOLetter}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA680, prUpper}, // L& CYRILLIC CAPITAL LETTER DWE + {0xA681, 0xA681, prLower}, // L& CYRILLIC SMALL LETTER DWE + {0xA682, 0xA682, prUpper}, // L& CYRILLIC CAPITAL LETTER DZWE + {0xA683, 0xA683, prLower}, // L& CYRILLIC SMALL LETTER DZWE + {0xA684, 0xA684, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHWE + {0xA685, 0xA685, prLower}, // L& CYRILLIC SMALL LETTER ZHWE + {0xA686, 0xA686, prUpper}, // L& CYRILLIC CAPITAL LETTER CCHE + {0xA687, 0xA687, prLower}, // L& CYRILLIC SMALL LETTER CCHE + {0xA688, 0xA688, prUpper}, // L& CYRILLIC CAPITAL LETTER DZZE + {0xA689, 0xA689, prLower}, // L& CYRILLIC SMALL LETTER DZZE + {0xA68A, 0xA68A, prUpper}, // L& CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK + {0xA68B, 0xA68B, prLower}, // L& CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK + {0xA68C, 0xA68C, prUpper}, // L& CYRILLIC CAPITAL LETTER TWE + {0xA68D, 0xA68D, prLower}, // L& CYRILLIC SMALL LETTER TWE + {0xA68E, 0xA68E, prUpper}, // L& CYRILLIC CAPITAL LETTER TSWE + {0xA68F, 0xA68F, prLower}, // L& CYRILLIC SMALL LETTER TSWE + {0xA690, 0xA690, prUpper}, // L& CYRILLIC CAPITAL LETTER TSSE + {0xA691, 0xA691, prLower}, // L& CYRILLIC SMALL LETTER TSSE + {0xA692, 0xA692, prUpper}, // L& CYRILLIC CAPITAL LETTER TCHE + {0xA693, 0xA693, prLower}, // L& CYRILLIC SMALL LETTER TCHE + {0xA694, 0xA694, prUpper}, // L& CYRILLIC CAPITAL LETTER HWE + {0xA695, 0xA695, prLower}, // L& CYRILLIC SMALL LETTER HWE + {0xA696, 0xA696, prUpper}, // L& CYRILLIC CAPITAL LETTER SHWE + {0xA697, 0xA697, prLower}, // L& CYRILLIC SMALL LETTER SHWE + {0xA698, 0xA698, prUpper}, // L& CYRILLIC CAPITAL LETTER DOUBLE O + {0xA699, 0xA699, prLower}, // L& CYRILLIC SMALL LETTER DOUBLE O + {0xA69A, 0xA69A, prUpper}, // L& CYRILLIC CAPITAL LETTER CROSSED O + {0xA69B, 0xA69B, prLower}, // L& CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prLower}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prOLetter}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prOLetter}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F3, 0xA6F3, prSTerm}, // Po BAMUM FULL STOP + {0xA6F7, 0xA6F7, prSTerm}, // Po BAMUM QUESTION MARK + {0xA717, 0xA71F, prOLetter}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA722, 0xA722, prUpper}, // L& LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF + {0xA723, 0xA723, prLower}, // L& LATIN SMALL LETTER EGYPTOLOGICAL ALEF + {0xA724, 0xA724, prUpper}, // L& LATIN CAPITAL LETTER EGYPTOLOGICAL AIN + {0xA725, 0xA725, prLower}, // L& LATIN SMALL LETTER EGYPTOLOGICAL AIN + {0xA726, 0xA726, prUpper}, // L& LATIN CAPITAL LETTER HENG + {0xA727, 0xA727, prLower}, // L& LATIN SMALL LETTER HENG + {0xA728, 0xA728, prUpper}, // L& LATIN CAPITAL LETTER TZ + {0xA729, 0xA729, prLower}, // L& LATIN SMALL LETTER TZ + {0xA72A, 0xA72A, prUpper}, // L& LATIN CAPITAL LETTER TRESILLO + {0xA72B, 0xA72B, prLower}, // L& LATIN SMALL LETTER TRESILLO + {0xA72C, 0xA72C, prUpper}, // L& LATIN CAPITAL LETTER CUATRILLO + {0xA72D, 0xA72D, prLower}, // L& LATIN SMALL LETTER CUATRILLO + {0xA72E, 0xA72E, prUpper}, // L& LATIN CAPITAL LETTER CUATRILLO WITH COMMA + {0xA72F, 0xA731, prLower}, // L& [3] LATIN SMALL LETTER CUATRILLO WITH COMMA..LATIN LETTER SMALL CAPITAL S + {0xA732, 0xA732, prUpper}, // L& LATIN CAPITAL LETTER AA + {0xA733, 0xA733, prLower}, // L& LATIN SMALL LETTER AA + {0xA734, 0xA734, prUpper}, // L& LATIN CAPITAL LETTER AO + {0xA735, 0xA735, prLower}, // L& LATIN SMALL LETTER AO + {0xA736, 0xA736, prUpper}, // L& LATIN CAPITAL LETTER AU + {0xA737, 0xA737, prLower}, // L& LATIN SMALL LETTER AU + {0xA738, 0xA738, prUpper}, // L& LATIN CAPITAL LETTER AV + {0xA739, 0xA739, prLower}, // L& LATIN SMALL LETTER AV + {0xA73A, 0xA73A, prUpper}, // L& LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR + {0xA73B, 0xA73B, prLower}, // L& LATIN SMALL LETTER AV WITH HORIZONTAL BAR + {0xA73C, 0xA73C, prUpper}, // L& LATIN CAPITAL LETTER AY + {0xA73D, 0xA73D, prLower}, // L& LATIN SMALL LETTER AY + {0xA73E, 0xA73E, prUpper}, // L& LATIN CAPITAL LETTER REVERSED C WITH DOT + {0xA73F, 0xA73F, prLower}, // L& LATIN SMALL LETTER REVERSED C WITH DOT + {0xA740, 0xA740, prUpper}, // L& LATIN CAPITAL LETTER K WITH STROKE + {0xA741, 0xA741, prLower}, // L& LATIN SMALL LETTER K WITH STROKE + {0xA742, 0xA742, prUpper}, // L& LATIN CAPITAL LETTER K WITH DIAGONAL STROKE + {0xA743, 0xA743, prLower}, // L& LATIN SMALL LETTER K WITH DIAGONAL STROKE + {0xA744, 0xA744, prUpper}, // L& LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE + {0xA745, 0xA745, prLower}, // L& LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE + {0xA746, 0xA746, prUpper}, // L& LATIN CAPITAL LETTER BROKEN L + {0xA747, 0xA747, prLower}, // L& LATIN SMALL LETTER BROKEN L + {0xA748, 0xA748, prUpper}, // L& LATIN CAPITAL LETTER L WITH HIGH STROKE + {0xA749, 0xA749, prLower}, // L& LATIN SMALL LETTER L WITH HIGH STROKE + {0xA74A, 0xA74A, prUpper}, // L& LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY + {0xA74B, 0xA74B, prLower}, // L& LATIN SMALL LETTER O WITH LONG STROKE OVERLAY + {0xA74C, 0xA74C, prUpper}, // L& LATIN CAPITAL LETTER O WITH LOOP + {0xA74D, 0xA74D, prLower}, // L& LATIN SMALL LETTER O WITH LOOP + {0xA74E, 0xA74E, prUpper}, // L& LATIN CAPITAL LETTER OO + {0xA74F, 0xA74F, prLower}, // L& LATIN SMALL LETTER OO + {0xA750, 0xA750, prUpper}, // L& LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER + {0xA751, 0xA751, prLower}, // L& LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER + {0xA752, 0xA752, prUpper}, // L& LATIN CAPITAL LETTER P WITH FLOURISH + {0xA753, 0xA753, prLower}, // L& LATIN SMALL LETTER P WITH FLOURISH + {0xA754, 0xA754, prUpper}, // L& LATIN CAPITAL LETTER P WITH SQUIRREL TAIL + {0xA755, 0xA755, prLower}, // L& LATIN SMALL LETTER P WITH SQUIRREL TAIL + {0xA756, 0xA756, prUpper}, // L& LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER + {0xA757, 0xA757, prLower}, // L& LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER + {0xA758, 0xA758, prUpper}, // L& LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE + {0xA759, 0xA759, prLower}, // L& LATIN SMALL LETTER Q WITH DIAGONAL STROKE + {0xA75A, 0xA75A, prUpper}, // L& LATIN CAPITAL LETTER R ROTUNDA + {0xA75B, 0xA75B, prLower}, // L& LATIN SMALL LETTER R ROTUNDA + {0xA75C, 0xA75C, prUpper}, // L& LATIN CAPITAL LETTER RUM ROTUNDA + {0xA75D, 0xA75D, prLower}, // L& LATIN SMALL LETTER RUM ROTUNDA + {0xA75E, 0xA75E, prUpper}, // L& LATIN CAPITAL LETTER V WITH DIAGONAL STROKE + {0xA75F, 0xA75F, prLower}, // L& LATIN SMALL LETTER V WITH DIAGONAL STROKE + {0xA760, 0xA760, prUpper}, // L& LATIN CAPITAL LETTER VY + {0xA761, 0xA761, prLower}, // L& LATIN SMALL LETTER VY + {0xA762, 0xA762, prUpper}, // L& LATIN CAPITAL LETTER VISIGOTHIC Z + {0xA763, 0xA763, prLower}, // L& LATIN SMALL LETTER VISIGOTHIC Z + {0xA764, 0xA764, prUpper}, // L& LATIN CAPITAL LETTER THORN WITH STROKE + {0xA765, 0xA765, prLower}, // L& LATIN SMALL LETTER THORN WITH STROKE + {0xA766, 0xA766, prUpper}, // L& LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER + {0xA767, 0xA767, prLower}, // L& LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER + {0xA768, 0xA768, prUpper}, // L& LATIN CAPITAL LETTER VEND + {0xA769, 0xA769, prLower}, // L& LATIN SMALL LETTER VEND + {0xA76A, 0xA76A, prUpper}, // L& LATIN CAPITAL LETTER ET + {0xA76B, 0xA76B, prLower}, // L& LATIN SMALL LETTER ET + {0xA76C, 0xA76C, prUpper}, // L& LATIN CAPITAL LETTER IS + {0xA76D, 0xA76D, prLower}, // L& LATIN SMALL LETTER IS + {0xA76E, 0xA76E, prUpper}, // L& LATIN CAPITAL LETTER CON + {0xA76F, 0xA76F, prLower}, // L& LATIN SMALL LETTER CON + {0xA770, 0xA770, prLower}, // Lm MODIFIER LETTER US + {0xA771, 0xA778, prLower}, // L& [8] LATIN SMALL LETTER DUM..LATIN SMALL LETTER UM + {0xA779, 0xA779, prUpper}, // L& LATIN CAPITAL LETTER INSULAR D + {0xA77A, 0xA77A, prLower}, // L& LATIN SMALL LETTER INSULAR D + {0xA77B, 0xA77B, prUpper}, // L& LATIN CAPITAL LETTER INSULAR F + {0xA77C, 0xA77C, prLower}, // L& LATIN SMALL LETTER INSULAR F + {0xA77D, 0xA77E, prUpper}, // L& [2] LATIN CAPITAL LETTER INSULAR G..LATIN CAPITAL LETTER TURNED INSULAR G + {0xA77F, 0xA77F, prLower}, // L& LATIN SMALL LETTER TURNED INSULAR G + {0xA780, 0xA780, prUpper}, // L& LATIN CAPITAL LETTER TURNED L + {0xA781, 0xA781, prLower}, // L& LATIN SMALL LETTER TURNED L + {0xA782, 0xA782, prUpper}, // L& LATIN CAPITAL LETTER INSULAR R + {0xA783, 0xA783, prLower}, // L& LATIN SMALL LETTER INSULAR R + {0xA784, 0xA784, prUpper}, // L& LATIN CAPITAL LETTER INSULAR S + {0xA785, 0xA785, prLower}, // L& LATIN SMALL LETTER INSULAR S + {0xA786, 0xA786, prUpper}, // L& LATIN CAPITAL LETTER INSULAR T + {0xA787, 0xA787, prLower}, // L& LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prOLetter}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA78B, 0xA78B, prUpper}, // L& LATIN CAPITAL LETTER SALTILLO + {0xA78C, 0xA78C, prLower}, // L& LATIN SMALL LETTER SALTILLO + {0xA78D, 0xA78D, prUpper}, // L& LATIN CAPITAL LETTER TURNED H + {0xA78E, 0xA78E, prLower}, // L& LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prOLetter}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA790, prUpper}, // L& LATIN CAPITAL LETTER N WITH DESCENDER + {0xA791, 0xA791, prLower}, // L& LATIN SMALL LETTER N WITH DESCENDER + {0xA792, 0xA792, prUpper}, // L& LATIN CAPITAL LETTER C WITH BAR + {0xA793, 0xA795, prLower}, // L& [3] LATIN SMALL LETTER C WITH BAR..LATIN SMALL LETTER H WITH PALATAL HOOK + {0xA796, 0xA796, prUpper}, // L& LATIN CAPITAL LETTER B WITH FLOURISH + {0xA797, 0xA797, prLower}, // L& LATIN SMALL LETTER B WITH FLOURISH + {0xA798, 0xA798, prUpper}, // L& LATIN CAPITAL LETTER F WITH STROKE + {0xA799, 0xA799, prLower}, // L& LATIN SMALL LETTER F WITH STROKE + {0xA79A, 0xA79A, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK AE + {0xA79B, 0xA79B, prLower}, // L& LATIN SMALL LETTER VOLAPUK AE + {0xA79C, 0xA79C, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK OE + {0xA79D, 0xA79D, prLower}, // L& LATIN SMALL LETTER VOLAPUK OE + {0xA79E, 0xA79E, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK UE + {0xA79F, 0xA79F, prLower}, // L& LATIN SMALL LETTER VOLAPUK UE + {0xA7A0, 0xA7A0, prUpper}, // L& LATIN CAPITAL LETTER G WITH OBLIQUE STROKE + {0xA7A1, 0xA7A1, prLower}, // L& LATIN SMALL LETTER G WITH OBLIQUE STROKE + {0xA7A2, 0xA7A2, prUpper}, // L& LATIN CAPITAL LETTER K WITH OBLIQUE STROKE + {0xA7A3, 0xA7A3, prLower}, // L& LATIN SMALL LETTER K WITH OBLIQUE STROKE + {0xA7A4, 0xA7A4, prUpper}, // L& LATIN CAPITAL LETTER N WITH OBLIQUE STROKE + {0xA7A5, 0xA7A5, prLower}, // L& LATIN SMALL LETTER N WITH OBLIQUE STROKE + {0xA7A6, 0xA7A6, prUpper}, // L& LATIN CAPITAL LETTER R WITH OBLIQUE STROKE + {0xA7A7, 0xA7A7, prLower}, // L& LATIN SMALL LETTER R WITH OBLIQUE STROKE + {0xA7A8, 0xA7A8, prUpper}, // L& LATIN CAPITAL LETTER S WITH OBLIQUE STROKE + {0xA7A9, 0xA7A9, prLower}, // L& LATIN SMALL LETTER S WITH OBLIQUE STROKE + {0xA7AA, 0xA7AE, prUpper}, // L& [5] LATIN CAPITAL LETTER H WITH HOOK..LATIN CAPITAL LETTER SMALL CAPITAL I + {0xA7AF, 0xA7AF, prLower}, // L& LATIN LETTER SMALL CAPITAL Q + {0xA7B0, 0xA7B4, prUpper}, // L& [5] LATIN CAPITAL LETTER TURNED K..LATIN CAPITAL LETTER BETA + {0xA7B5, 0xA7B5, prLower}, // L& LATIN SMALL LETTER BETA + {0xA7B6, 0xA7B6, prUpper}, // L& LATIN CAPITAL LETTER OMEGA + {0xA7B7, 0xA7B7, prLower}, // L& LATIN SMALL LETTER OMEGA + {0xA7B8, 0xA7B8, prUpper}, // L& LATIN CAPITAL LETTER U WITH STROKE + {0xA7B9, 0xA7B9, prLower}, // L& LATIN SMALL LETTER U WITH STROKE + {0xA7BA, 0xA7BA, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL A + {0xA7BB, 0xA7BB, prLower}, // L& LATIN SMALL LETTER GLOTTAL A + {0xA7BC, 0xA7BC, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL I + {0xA7BD, 0xA7BD, prLower}, // L& LATIN SMALL LETTER GLOTTAL I + {0xA7BE, 0xA7BE, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL U + {0xA7BF, 0xA7BF, prLower}, // L& LATIN SMALL LETTER GLOTTAL U + {0xA7C0, 0xA7C0, prUpper}, // L& LATIN CAPITAL LETTER OLD POLISH O + {0xA7C1, 0xA7C1, prLower}, // L& LATIN SMALL LETTER OLD POLISH O + {0xA7C2, 0xA7C2, prUpper}, // L& LATIN CAPITAL LETTER ANGLICANA W + {0xA7C3, 0xA7C3, prLower}, // L& LATIN SMALL LETTER ANGLICANA W + {0xA7C4, 0xA7C7, prUpper}, // L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY + {0xA7C8, 0xA7C8, prLower}, // L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY + {0xA7C9, 0xA7C9, prUpper}, // L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY + {0xA7CA, 0xA7CA, prLower}, // L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D0, prUpper}, // L& LATIN CAPITAL LETTER CLOSED INSULAR G + {0xA7D1, 0xA7D1, prLower}, // L& LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prLower}, // L& LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D5, prLower}, // L& LATIN SMALL LETTER DOUBLE WYNN + {0xA7D6, 0xA7D6, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE SCOTS S + {0xA7D7, 0xA7D7, prLower}, // L& LATIN SMALL LETTER MIDDLE SCOTS S + {0xA7D8, 0xA7D8, prUpper}, // L& LATIN CAPITAL LETTER SIGMOID S + {0xA7D9, 0xA7D9, prLower}, // L& LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prLower}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F5, prUpper}, // L& LATIN CAPITAL LETTER REVERSED HALF H + {0xA7F6, 0xA7F6, prLower}, // L& LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prOLetter}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prLower}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prLower}, // L& LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA801, prOLetter}, // Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prOLetter}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prOLetter}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prOLetter}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prExtend}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prExtend}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA840, 0xA873, prOLetter}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA876, 0xA877, prSTerm}, // Po [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prExtend}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prOLetter}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prExtend}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prSTerm}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prNumeric}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prOLetter}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8FB, 0xA8FB, prOLetter}, // Lo DEVANAGARI HEADSTROKE + {0xA8FD, 0xA8FE, prOLetter}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNumeric}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prOLetter}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92F, 0xA92F, prSTerm}, // Po KAYAH LI SIGN SHYA + {0xA930, 0xA946, prOLetter}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prExtend}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prOLetter}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prExtend}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prOLetter}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prExtend}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C8, 0xA9C9, prSTerm}, // Po [2] JAVANESE PADA LINGSA..JAVANESE PADA LUNGSI + {0xA9CF, 0xA9CF, prOLetter}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNumeric}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9E0, 0xA9E4, prOLetter}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prOLetter}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prOLetter}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prNumeric}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prOLetter}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prOLetter}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prExtend}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prExtend}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prOLetter}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prOLetter}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prExtend}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNumeric}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5D, 0xAA5F, prSTerm}, // Po [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prOLetter}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prOLetter}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prOLetter}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA7A, 0xAA7A, prOLetter}, // Lo MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prExtend}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prExtend}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAAAF, prOLetter}, // Lo [50] MYANMAR LETTER SHWE PALAUNG CHA..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prOLetter}, // Lo TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prOLetter}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prOLetter}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prOLetter}, // Lo TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prOLetter}, // Lo TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prOLetter}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prOLetter}, // Lm TAI VIET SYMBOL SAM + {0xAAE0, 0xAAEA, prOLetter}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prSTerm}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prOLetter}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prOLetter}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prLower}, // L& [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5C, 0xAB5F, prLower}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prLower}, // L& [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prLower}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB70, 0xABBF, prLower}, // L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prOLetter}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prSTerm}, // Po MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prExtend}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNumeric}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prOLetter}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prOLetter}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prOLetter}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xF900, 0xFA6D, prOLetter}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA70, 0xFAD9, prOLetter}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFB00, 0xFB06, prLower}, // L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prLower}, // L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prOLetter}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prOLetter}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB2A, 0xFB36, prOLetter}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prOLetter}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prOLetter}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prOLetter}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prOLetter}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFBB1, prOLetter}, // Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBD3, 0xFD3D, prOLetter}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prClose}, // Pe ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prClose}, // Ps ORNATE RIGHT PARENTHESIS + {0xFD50, 0xFD8F, prOLetter}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prOLetter}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDF0, 0xFDFB, prOLetter}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE11, prSContinue}, // Po [2] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA + {0xFE13, 0xFE13, prSContinue}, // Po PRESENTATION FORM FOR VERTICAL COLON + {0xFE17, 0xFE17, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE31, 0xFE32, prSContinue}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE35, 0xFE35, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE47, 0xFE47, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE50, 0xFE51, prSContinue}, // Po [2] SMALL COMMA..SMALL IDEOGRAPHIC COMMA + {0xFE52, 0xFE52, prATerm}, // Po SMALL FULL STOP + {0xFE55, 0xFE55, prSContinue}, // Po SMALL COLON + {0xFE56, 0xFE57, prSTerm}, // Po [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prSContinue}, // Pd SMALL EM DASH + {0xFE59, 0xFE59, prClose}, // Ps SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prClose}, // Pe SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prClose}, // Ps SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prClose}, // Pe SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prClose}, // Ps SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prClose}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE63, 0xFE63, prSContinue}, // Pd SMALL HYPHEN-MINUS + {0xFE70, 0xFE74, prOLetter}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prOLetter}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prFormat}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF01, prSTerm}, // Po FULLWIDTH EXCLAMATION MARK + {0xFF08, 0xFF08, prClose}, // Ps FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prClose}, // Pe FULLWIDTH RIGHT PARENTHESIS + {0xFF0C, 0xFF0C, prSContinue}, // Po FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prSContinue}, // Pd FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0E, prATerm}, // Po FULLWIDTH FULL STOP + {0xFF10, 0xFF19, prNumeric}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1A, prSContinue}, // Po FULLWIDTH COLON + {0xFF1F, 0xFF1F, prSTerm}, // Po FULLWIDTH QUESTION MARK + {0xFF21, 0xFF3A, prUpper}, // L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prClose}, // Ps FULLWIDTH LEFT SQUARE BRACKET + {0xFF3D, 0xFF3D, prClose}, // Pe FULLWIDTH RIGHT SQUARE BRACKET + {0xFF41, 0xFF5A, prLower}, // L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prClose}, // Ps FULLWIDTH LEFT CURLY BRACKET + {0xFF5D, 0xFF5D, prClose}, // Pe FULLWIDTH RIGHT CURLY BRACKET + {0xFF5F, 0xFF5F, prClose}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prClose}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prSTerm}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prClose}, // Ps HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prClose}, // Pe HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF64, prSContinue}, // Po HALFWIDTH IDEOGRAPHIC COMMA + {0xFF66, 0xFF6F, prOLetter}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prOLetter}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prOLetter}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prOLetter}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prOLetter}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFF9, 0xFFFB, prFormat}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x10000, 0x1000B, prOLetter}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prOLetter}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prOLetter}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prOLetter}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prOLetter}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prOLetter}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prOLetter}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10140, 0x10174, prOLetter}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prOLetter}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prOLetter}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10300, 0x1031F, prOLetter}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x1032D, 0x10340, prOLetter}, // Lo [20] OLD ITALIC LETTER YE..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prOLetter}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prOLetter}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prOLetter}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prOLetter}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prOLetter}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x103A0, 0x103C3, prOLetter}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prOLetter}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D1, 0x103D5, prOLetter}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x10427, prUpper}, // L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW + {0x10428, 0x1044F, prLower}, // L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1049D, prOLetter}, // Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNumeric}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prUpper}, // L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prLower}, // L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prOLetter}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prOLetter}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x10570, 0x1057A, prUpper}, // L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prUpper}, // L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prUpper}, // L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prUpper}, // L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prLower}, // L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prLower}, // L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prLower}, // L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prLower}, // L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prOLetter}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prOLetter}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prOLetter}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10780, prLower}, // Lm MODIFIER LETTER SMALL CAPITAL AA + {0x10781, 0x10782, prOLetter}, // Lm [2] MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON..MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON + {0x10783, 0x10785, prLower}, // Lm [3] MODIFIER LETTER SMALL AE..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prLower}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prLower}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prOLetter}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prOLetter}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prOLetter}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prOLetter}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prOLetter}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x10855, prOLetter}, // Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW + {0x10860, 0x10876, prOLetter}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10880, 0x1089E, prOLetter}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108E0, 0x108F2, prOLetter}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prOLetter}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x10900, 0x10915, prOLetter}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10920, 0x10939, prOLetter}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x10980, 0x109B7, prOLetter}, // Lo [56] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BE, 0x109BF, prOLetter}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x10A00, 0x10A00, prOLetter}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prOLetter}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prOLetter}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prOLetter}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10A56, 0x10A57, prSTerm}, // Po [2] KHAROSHTHI PUNCTUATION DANDA..KHAROSHTHI PUNCTUATION DOUBLE DANDA + {0x10A60, 0x10A7C, prOLetter}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A80, 0x10A9C, prOLetter}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10AC0, 0x10AC7, prOLetter}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC9, 0x10AE4, prOLetter}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10B00, 0x10B35, prOLetter}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B40, 0x10B55, prOLetter}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B60, 0x10B72, prOLetter}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B80, 0x10B91, prOLetter}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10C00, 0x10C48, prOLetter}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prUpper}, // L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prLower}, // L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10D00, 0x10D23, prOLetter}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNumeric}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E80, 0x10EA9, prOLetter}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EB0, 0x10EB1, prOLetter}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prOLetter}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F27, 0x10F27, prOLetter}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prOLetter}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F55, 0x10F59, prSTerm}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prOLetter}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prSTerm}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prOLetter}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FE0, 0x10FF6, prOLetter}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prExtend}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prExtend}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prOLetter}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x11048, prSTerm}, // Po [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA + {0x11066, 0x1106F, prNumeric}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prOLetter}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prOLetter}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prExtend}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prOLetter}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prExtend}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prExtend}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prFormat}, // Cf KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prSTerm}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prFormat}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prOLetter}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNumeric}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prOLetter}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prExtend}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNumeric}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11141, 0x11143, prSTerm}, // Po [3] CHAKMA DANDA..CHAKMA QUESTION MARK + {0x11144, 0x11144, prOLetter}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prExtend}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prOLetter}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prOLetter}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11176, 0x11176, prOLetter}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prExtend}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prOLetter}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prExtend}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prExtend}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prOLetter}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C6, prSTerm}, // Po [2] SHARADA DANDA..SHARADA DOUBLE DANDA + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prSTerm}, // Po SHARADA SUTRA MARK + {0x111CE, 0x111CE, prExtend}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNumeric}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prOLetter}, // Lo SHARADA EKAM + {0x111DC, 0x111DC, prOLetter}, // Lo SHARADA HEADSTROKE + {0x111DE, 0x111DF, prSTerm}, // Po [2] SHARADA SECTION MARK-1..SHARADA SECTION MARK-2 + {0x11200, 0x11211, prOLetter}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prOLetter}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prExtend}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prExtend}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prExtend}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x11239, prSTerm}, // Po [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA + {0x1123B, 0x1123C, prSTerm}, // Po [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prOLetter}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prOLetter}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prOLetter}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prOLetter}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prOLetter}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prOLetter}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prSTerm}, // Po MULTANI SECTION MARK + {0x112B0, 0x112DE, prOLetter}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prExtend}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNumeric}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prExtend}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prOLetter}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prOLetter}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prOLetter}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prOLetter}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prOLetter}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prOLetter}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prOLetter}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prExtend}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prExtend}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prExtend}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prExtend}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prOLetter}, // Lo GRANTHA OM + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prOLetter}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prExtend}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prOLetter}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prExtend}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prExtend}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prExtend}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prOLetter}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144C, prSTerm}, // Po [2] NEWA DANDA..NEWA DOUBLE DANDA + {0x11450, 0x11459, prNumeric}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prOLetter}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prOLetter}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prExtend}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prExtend}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prExtend}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prExtend}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prOLetter}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C7, 0x114C7, prOLetter}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prNumeric}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prOLetter}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prExtend}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prExtend}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prExtend}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C2, 0x115C3, prSTerm}, // Po [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA + {0x115C9, 0x115D7, prSTerm}, // Po [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prOLetter}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prOLetter}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prExtend}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prExtend}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prExtend}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11642, prSTerm}, // Po [2] MODI DANDA..MODI DOUBLE DANDA + {0x11644, 0x11644, prOLetter}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prNumeric}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11680, 0x116AA, prOLetter}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prExtend}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prExtend}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prExtend}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prOLetter}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116C0, 0x116C9, prNumeric}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prOLetter}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prExtend}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prExtend}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNumeric}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173C, 0x1173E, prSTerm}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x11740, 0x11746, prOLetter}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prOLetter}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prExtend}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prExtend}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x118A0, 0x118BF, prUpper}, // L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO + {0x118C0, 0x118DF, prLower}, // L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNumeric}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118FF, 0x11906, prOLetter}, // Lo [8] WARANG CITI OM..DIVES AKURU LETTER E + {0x11909, 0x11909, prOLetter}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prOLetter}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prOLetter}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prOLetter}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prExtend}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prExtend}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prExtend}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prOLetter}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prExtend}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prOLetter}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prExtend}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x11944, 0x11944, prSTerm}, // Po DIVES AKURU DOUBLE DANDA + {0x11946, 0x11946, prSTerm}, // Po DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prNumeric}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prOLetter}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prOLetter}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prExtend}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prExtend}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prOLetter}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E3, 0x119E3, prOLetter}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prExtend}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prOLetter}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prOLetter}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prExtend}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prOLetter}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A42, 0x11A43, prSTerm}, // Po [2] ZANABAZAR SQUARE MARK SHAD..ZANABAZAR SQUARE MARK DOUBLE SHAD + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prOLetter}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prExtend}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prOLetter}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prExtend}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9B, 0x11A9C, prSTerm}, // Po [2] SOYOMBO MARK SHAD..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prOLetter}, // Lo SOYOMBO MARK PLUTA + {0x11AB0, 0x11AF8, prOLetter}, // Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL + {0x11C00, 0x11C08, prOLetter}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prOLetter}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prExtend}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prExtend}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prOLetter}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C42, prSTerm}, // Po [2] BHAIKSUKI DANDA..BHAIKSUKI DOUBLE DANDA + {0x11C50, 0x11C59, prNumeric}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C72, 0x11C8F, prOLetter}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prExtend}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prExtend}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prExtend}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prOLetter}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prOLetter}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prOLetter}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prOLetter}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNumeric}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prOLetter}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prOLetter}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prOLetter}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prExtend}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prExtend}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prExtend}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prOLetter}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNumeric}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prOLetter}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prExtend}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prSTerm}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prOLetter}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prExtend}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prOLetter}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prOLetter}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prExtend}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prExtend}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prExtend}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x11F43, 0x11F44, prSTerm}, // Po [2] KAWI DANDA..KAWI DOUBLE DANDA + {0x11F50, 0x11F59, prNumeric}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prOLetter}, // Lo LISU LETTER YHA + {0x12000, 0x12399, prOLetter}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prOLetter}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12480, 0x12543, prOLetter}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prOLetter}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x13000, 0x1342F, prOLetter}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prFormat}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prOLetter}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prOLetter}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prOLetter}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prOLetter}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNumeric}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prSTerm}, // Po [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prOLetter}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNumeric}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prOLetter}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prSTerm}, // Po BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prOLetter}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B38, prSTerm}, // Po [2] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS TSHAB CEEB + {0x16B40, 0x16B43, prOLetter}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prSTerm}, // Po PAHAWH HMONG SIGN XAUS + {0x16B50, 0x16B59, prNumeric}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B63, 0x16B77, prOLetter}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prOLetter}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E5F, prUpper}, // L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y + {0x16E60, 0x16E7F, prLower}, // L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E98, 0x16E98, prSTerm}, // Po MEDEFAIDRIN FULL STOP + {0x16F00, 0x16F4A, prOLetter}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prOLetter}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prExtend}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prOLetter}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prOLetter}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE3, 0x16FE3, prOLetter}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prExtend}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prOLetter}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18CD5, prOLetter}, // Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prOLetter}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prOLetter}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prOLetter}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prOLetter}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B122, prOLetter}, // Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prOLetter}, // Lo HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prOLetter}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prOLetter}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prOLetter}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prOLetter}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prOLetter}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prOLetter}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prOLetter}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prOLetter}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prSTerm}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prFormat}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D166, prExtend}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D172, prExtend}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prFormat}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D400, 0x1D419, prUpper}, // L& [26] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL BOLD CAPITAL Z + {0x1D41A, 0x1D433, prLower}, // L& [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z + {0x1D434, 0x1D44D, prUpper}, // L& [26] MATHEMATICAL ITALIC CAPITAL A..MATHEMATICAL ITALIC CAPITAL Z + {0x1D44E, 0x1D454, prLower}, // L& [7] MATHEMATICAL ITALIC SMALL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D467, prLower}, // L& [18] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL Z + {0x1D468, 0x1D481, prUpper}, // L& [26] MATHEMATICAL BOLD ITALIC CAPITAL A..MATHEMATICAL BOLD ITALIC CAPITAL Z + {0x1D482, 0x1D49B, prLower}, // L& [26] MATHEMATICAL BOLD ITALIC SMALL A..MATHEMATICAL BOLD ITALIC SMALL Z + {0x1D49C, 0x1D49C, prUpper}, // L& MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prUpper}, // L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prUpper}, // L& MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prUpper}, // L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prUpper}, // L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B5, prUpper}, // L& [8] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT CAPITAL Z + {0x1D4B6, 0x1D4B9, prLower}, // L& [4] MATHEMATICAL SCRIPT SMALL A..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prLower}, // L& MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prLower}, // L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D4CF, prLower}, // L& [11] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL SCRIPT SMALL Z + {0x1D4D0, 0x1D4E9, prUpper}, // L& [26] MATHEMATICAL BOLD SCRIPT CAPITAL A..MATHEMATICAL BOLD SCRIPT CAPITAL Z + {0x1D4EA, 0x1D503, prLower}, // L& [26] MATHEMATICAL BOLD SCRIPT SMALL A..MATHEMATICAL BOLD SCRIPT SMALL Z + {0x1D504, 0x1D505, prUpper}, // L& [2] MATHEMATICAL FRAKTUR CAPITAL A..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prUpper}, // L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prUpper}, // L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prUpper}, // L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D537, prLower}, // L& [26] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL FRAKTUR SMALL Z + {0x1D538, 0x1D539, prUpper}, // L& [2] MATHEMATICAL DOUBLE-STRUCK CAPITAL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prUpper}, // L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prUpper}, // L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prUpper}, // L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prUpper}, // L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D56B, prLower}, // L& [26] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL DOUBLE-STRUCK SMALL Z + {0x1D56C, 0x1D585, prUpper}, // L& [26] MATHEMATICAL BOLD FRAKTUR CAPITAL A..MATHEMATICAL BOLD FRAKTUR CAPITAL Z + {0x1D586, 0x1D59F, prLower}, // L& [26] MATHEMATICAL BOLD FRAKTUR SMALL A..MATHEMATICAL BOLD FRAKTUR SMALL Z + {0x1D5A0, 0x1D5B9, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF CAPITAL A..MATHEMATICAL SANS-SERIF CAPITAL Z + {0x1D5BA, 0x1D5D3, prLower}, // L& [26] MATHEMATICAL SANS-SERIF SMALL A..MATHEMATICAL SANS-SERIF SMALL Z + {0x1D5D4, 0x1D5ED, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF BOLD CAPITAL A..MATHEMATICAL SANS-SERIF BOLD CAPITAL Z + {0x1D5EE, 0x1D607, prLower}, // L& [26] MATHEMATICAL SANS-SERIF BOLD SMALL A..MATHEMATICAL SANS-SERIF BOLD SMALL Z + {0x1D608, 0x1D621, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z + {0x1D622, 0x1D63B, prLower}, // L& [26] MATHEMATICAL SANS-SERIF ITALIC SMALL A..MATHEMATICAL SANS-SERIF ITALIC SMALL Z + {0x1D63C, 0x1D655, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z + {0x1D656, 0x1D66F, prLower}, // L& [26] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z + {0x1D670, 0x1D689, prUpper}, // L& [26] MATHEMATICAL MONOSPACE CAPITAL A..MATHEMATICAL MONOSPACE CAPITAL Z + {0x1D68A, 0x1D6A5, prLower}, // L& [28] MATHEMATICAL MONOSPACE SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prUpper}, // L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C2, 0x1D6DA, prLower}, // L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DC, 0x1D6E1, prLower}, // L& [6] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL BOLD PI SYMBOL + {0x1D6E2, 0x1D6FA, prUpper}, // L& [25] MATHEMATICAL ITALIC CAPITAL ALPHA..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FC, 0x1D714, prLower}, // L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D716, 0x1D71B, prLower}, // L& [6] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL ITALIC PI SYMBOL + {0x1D71C, 0x1D734, prUpper}, // L& [25] MATHEMATICAL BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D736, 0x1D74E, prLower}, // L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D750, 0x1D755, prLower}, // L& [6] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC PI SYMBOL + {0x1D756, 0x1D76E, prUpper}, // L& [25] MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D770, 0x1D788, prLower}, // L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D78A, 0x1D78F, prLower}, // L& [6] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD PI SYMBOL + {0x1D790, 0x1D7A8, prUpper}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7AA, 0x1D7C2, prLower}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C4, 0x1D7C9, prLower}, // L& [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL + {0x1D7CA, 0x1D7CA, prUpper}, // L& MATHEMATICAL BOLD CAPITAL DIGAMMA + {0x1D7CB, 0x1D7CB, prLower}, // L& MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNumeric}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA88, 0x1DA88, prSTerm}, // Po SIGNWRITING FULL STOP + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prLower}, // L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prOLetter}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prLower}, // L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prLower}, // L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prLower}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prOLetter}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prOLetter}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNumeric}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prOLetter}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E290, 0x1E2AD, prOLetter}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prOLetter}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNumeric}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E4D0, 0x1E4EA, prOLetter}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prOLetter}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNumeric}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prOLetter}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prOLetter}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prOLetter}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E921, prUpper}, // L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA + {0x1E922, 0x1E943, prLower}, // L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prOLetter}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNumeric}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1EE00, 0x1EE03, prOLetter}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prOLetter}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prOLetter}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prOLetter}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prOLetter}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prOLetter}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prOLetter}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prOLetter}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prOLetter}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prOLetter}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prOLetter}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prOLetter}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prOLetter}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prOLetter}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prOLetter}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prOLetter}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1F130, 0x1F149, prUpper}, // So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z + {0x1F150, 0x1F169, prUpper}, // So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F170, 0x1F189, prUpper}, // So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z + {0x1F676, 0x1F678, prClose}, // So [3] SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT..SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x1FBF0, 0x1FBF9, prNumeric}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x20000, 0x2A6DF, prOLetter}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A700, 0x2B739, prOLetter}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B740, 0x2B81D, prOLetter}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B820, 0x2CEA1, prOLetter}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEB0, 0x2EBE0, prOLetter}, // Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2F800, 0x2FA1D, prOLetter}, // Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x30000, 0x3134A, prOLetter}, // Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x31350, 0x323AF, prOLetter}, // Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0xE0001, 0xE0001, prFormat}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 +} diff --git a/vendor/github.com/rivo/uniseg/sentencerules.go b/vendor/github.com/rivo/uniseg/sentencerules.go new file mode 100644 index 000000000000..0b29c7bdb8af --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentencerules.go @@ -0,0 +1,276 @@ +package uniseg + +import "unicode/utf8" + +// The states of the sentence break parser. +const ( + sbAny = iota + sbCR + sbParaSep + sbATerm + sbUpper + sbLower + sbSB7 + sbSB8Close + sbSB8Sp + sbSTerm + sbSB8aClose + sbSB8aSp +) + +// sbTransitions implements the sentence break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func sbTransitions(state, prop int) (newState int, sentenceBreak bool, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // SB3. + case sbAny | prCR<<32: + return sbCR, false, 9990 + case sbCR | prLF<<32: + return sbParaSep, false, 30 + + // SB4. + case sbAny | prSep<<32: + return sbParaSep, false, 9990 + case sbAny | prLF<<32: + return sbParaSep, false, 9990 + case sbParaSep | prAny<<32: + return sbAny, true, 40 + case sbCR | prAny<<32: + return sbAny, true, 40 + + // SB6. + case sbAny | prATerm<<32: + return sbATerm, false, 9990 + case sbATerm | prNumeric<<32: + return sbAny, false, 60 + case sbSB7 | prNumeric<<32: + return sbAny, false, 60 // Because ATerm also appears in SB7. + + // SB7. + case sbAny | prUpper<<32: + return sbUpper, false, 9990 + case sbAny | prLower<<32: + return sbLower, false, 9990 + case sbUpper | prATerm<<32: + return sbSB7, false, 70 + case sbLower | prATerm<<32: + return sbSB7, false, 70 + case sbSB7 | prUpper<<32: + return sbUpper, false, 70 + + // SB8a. + case sbAny | prSTerm<<32: + return sbSTerm, false, 9990 + case sbATerm | prSContinue<<32: + return sbAny, false, 81 + case sbATerm | prATerm<<32: + return sbATerm, false, 81 + case sbATerm | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB7 | prSContinue<<32: + return sbAny, false, 81 + case sbSB7 | prATerm<<32: + return sbATerm, false, 81 + case sbSB7 | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8Close | prSContinue<<32: + return sbAny, false, 81 + case sbSB8Close | prATerm<<32: + return sbATerm, false, 81 + case sbSB8Close | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8Sp | prSContinue<<32: + return sbAny, false, 81 + case sbSB8Sp | prATerm<<32: + return sbATerm, false, 81 + case sbSB8Sp | prSTerm<<32: + return sbSTerm, false, 81 + case sbSTerm | prSContinue<<32: + return sbAny, false, 81 + case sbSTerm | prATerm<<32: + return sbATerm, false, 81 + case sbSTerm | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8aClose | prSContinue<<32: + return sbAny, false, 81 + case sbSB8aClose | prATerm<<32: + return sbATerm, false, 81 + case sbSB8aClose | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8aSp | prSContinue<<32: + return sbAny, false, 81 + case sbSB8aSp | prATerm<<32: + return sbATerm, false, 81 + case sbSB8aSp | prSTerm<<32: + return sbSTerm, false, 81 + + // SB9. + case sbATerm | prClose<<32: + return sbSB8Close, false, 90 + case sbSB7 | prClose<<32: + return sbSB8Close, false, 90 + case sbSB8Close | prClose<<32: + return sbSB8Close, false, 90 + case sbATerm | prSp<<32: + return sbSB8Sp, false, 90 + case sbSB7 | prSp<<32: + return sbSB8Sp, false, 90 + case sbSB8Close | prSp<<32: + return sbSB8Sp, false, 90 + case sbSTerm | prClose<<32: + return sbSB8aClose, false, 90 + case sbSB8aClose | prClose<<32: + return sbSB8aClose, false, 90 + case sbSTerm | prSp<<32: + return sbSB8aSp, false, 90 + case sbSB8aClose | prSp<<32: + return sbSB8aSp, false, 90 + case sbATerm | prSep<<32: + return sbParaSep, false, 90 + case sbATerm | prCR<<32: + return sbParaSep, false, 90 + case sbATerm | prLF<<32: + return sbParaSep, false, 90 + case sbSB7 | prSep<<32: + return sbParaSep, false, 90 + case sbSB7 | prCR<<32: + return sbParaSep, false, 90 + case sbSB7 | prLF<<32: + return sbParaSep, false, 90 + case sbSB8Close | prSep<<32: + return sbParaSep, false, 90 + case sbSB8Close | prCR<<32: + return sbParaSep, false, 90 + case sbSB8Close | prLF<<32: + return sbParaSep, false, 90 + case sbSTerm | prSep<<32: + return sbParaSep, false, 90 + case sbSTerm | prCR<<32: + return sbParaSep, false, 90 + case sbSTerm | prLF<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prSep<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prCR<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prLF<<32: + return sbParaSep, false, 90 + + // SB10. + case sbSB8Sp | prSp<<32: + return sbSB8Sp, false, 100 + case sbSB8aSp | prSp<<32: + return sbSB8aSp, false, 100 + case sbSB8Sp | prSep<<32: + return sbParaSep, false, 100 + case sbSB8Sp | prCR<<32: + return sbParaSep, false, 100 + case sbSB8Sp | prLF<<32: + return sbParaSep, false, 100 + + // SB11. + case sbATerm | prAny<<32: + return sbAny, true, 110 + case sbSB7 | prAny<<32: + return sbAny, true, 110 + case sbSB8Close | prAny<<32: + return sbAny, true, 110 + case sbSB8Sp | prAny<<32: + return sbAny, true, 110 + case sbSTerm | prAny<<32: + return sbAny, true, 110 + case sbSB8aClose | prAny<<32: + return sbAny, true, 110 + case sbSB8aSp | prAny<<32: + return sbAny, true, 110 + // We'll always break after ParaSep due to SB4. + + default: + return -1, false, -1 + } +} + +// transitionSentenceBreakState determines the new state of the sentence break +// parser given the current state and the next code point. It also returns +// whether a sentence boundary was detected. If more than one code point is +// needed to determine the new state, the byte slice or the string starting +// after rune "r" can be used (whichever is not nil or empty) for further +// lookups. +func transitionSentenceBreakState(state int, r rune, b []byte, str string) (newState int, sentenceBreak bool) { + // Determine the property of the next character. + nextProperty := property(sentenceBreakCodePoints, r) + + // SB5 (Replacing Ignore Rules). + if nextProperty == prExtend || nextProperty == prFormat { + if state == sbParaSep || state == sbCR { + return sbAny, true // Make sure we don't apply SB5 to SB3 or SB4. + } + if state < 0 { + return sbAny, true // SB1. + } + return state, false + } + + // Find the applicable transition in the table. + var rule int + newState, sentenceBreak, rule = sbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropState, anyPropProp, anyPropRule := sbTransitions(state, prAny) + anyStateState, anyStateProp, anyStateRule := sbTransitions(sbAny, nextProperty) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule + if anyPropRule < anyStateRule { + sentenceBreak, rule = anyPropProp, anyPropRule + } + } else if anyPropState >= 0 { + // We only have a specific state. + newState, sentenceBreak, rule = anyPropState, anyPropProp, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateState >= 0 { + // We only have a specific property. + newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule + } else { + // No known transition. SB999: Any ร— Any. + newState, sentenceBreak, rule = sbAny, false, 9990 + } + } + + // SB8. + if rule > 80 && (state == sbATerm || state == sbSB8Close || state == sbSB8Sp || state == sbSB7) { + // Check the right side of the rule. + var length int + for nextProperty != prOLetter && + nextProperty != prUpper && + nextProperty != prLower && + nextProperty != prSep && + nextProperty != prCR && + nextProperty != prLF && + nextProperty != prATerm && + nextProperty != prSTerm { + // Move on to the next rune. + if b != nil { // Byte slice version. + r, length = utf8.DecodeRune(b) + b = b[length:] + } else { // String version. + r, length = utf8.DecodeRuneInString(str) + str = str[length:] + } + if r == utf8.RuneError { + break + } + nextProperty = property(sentenceBreakCodePoints, r) + } + if nextProperty == prLower { + return sbLower, false + } + } + + return +} diff --git a/vendor/github.com/rivo/uniseg/step.go b/vendor/github.com/rivo/uniseg/step.go new file mode 100644 index 000000000000..9b72c5e5969d --- /dev/null +++ b/vendor/github.com/rivo/uniseg/step.go @@ -0,0 +1,242 @@ +package uniseg + +import "unicode/utf8" + +// The bit masks used to extract boundary information returned by [Step]. +const ( + MaskLine = 3 + MaskWord = 4 + MaskSentence = 8 +) + +// The number of bits to shift the boundary information returned by [Step] to +// obtain the monospace width of the grapheme cluster. +const ShiftWidth = 4 + +// The bit positions by which boundary flags are shifted by the [Step] function. +// These must correspond to the Mask constants. +const ( + shiftWord = 2 + shiftSentence = 3 + // shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits. +) + +// The bit positions by which states are shifted by the [Step] function. These +// values must ensure state values defined for each of the boundary algorithms +// don't overlap (and that they all still fit in a single int). These must +// correspond to the Mask constants. +const ( + shiftWordState = 4 + shiftSentenceState = 9 + shiftLineState = 13 + shiftPropState = 21 // No mask as these are always the remaining bits. +) + +// The bit mask used to extract the state returned by the [Step] function, after +// shifting. These values must correspond to the shift constants. +const ( + maskGraphemeState = 0xf + maskWordState = 0x1f + maskSentenceState = 0xf + maskLineState = 0xff +) + +// Step returns the first grapheme cluster (user-perceived character) found in +// the given byte slice. It also returns information about the boundary between +// that grapheme cluster and the one following it as well as the monospace width +// of the grapheme cluster. There are three types of boundary information: word +// boundaries, sentence boundaries, and line breaks. This function is therefore +// a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and +// [FirstLineSegment]. +// +// The "boundaries" return value can be evaluated as follows: +// +// - boundaries&MaskWord != 0: The boundary is a word boundary. +// - boundaries&MaskWord == 0: The boundary is not a word boundary. +// - boundaries&MaskSentence != 0: The boundary is a sentence boundary. +// - boundaries&MaskSentence == 0: The boundary is not a sentence boundary. +// - boundaries&MaskLine == LineDontBreak: You must not break the line at the +// boundary. +// - boundaries&MaskLine == LineMustBreak: You must break the line at the +// boundary. +// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at +// the boundary. +// - boundaries >> ShiftWidth: The width of the grapheme cluster for most +// monospace fonts where a value of 1 represents one character cell. +// +// This function can be called continuously to extract all grapheme clusters +// from a byte slice, as illustrated in the examples below. +// +// If you don't know which state to pass, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified grapheme cluster. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "cluster" byte slice is the sub-slice of the input slice containing the +// first identified grapheme cluster. +// +// Given an empty byte slice "b", the function returns nil values. +// +// While slightly less convenient than using the Graphemes class, this function +// has much better performance and makes no allocations. It lends itself well to +// large byte slices. +// +// Note that in accordance with [UAX #14 LB3], the final segment will end with +// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose +// to ignore this by checking if the length of the "rest" slice is 0 and calling +// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune. +// +// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm +func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftPropState + } + return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + + // If we don't know the state, determine it now. + var graphemeState, wordState, sentenceState, lineState, firstProp int + remainder := b[length:] + if state < 0 { + graphemeState, firstProp, _ = transitionGraphemeState(state, r) + wordState, _ = transitionWordBreakState(state, r, remainder, "") + sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "") + lineState, _ = transitionLineBreakState(state, r, remainder, "") + } else { + graphemeState = state & maskGraphemeState + wordState = (state >> shiftWordState) & maskWordState + sentenceState = (state >> shiftSentenceState) & maskSentenceState + lineState = (state >> shiftLineState) & maskLineState + firstProp = state >> shiftPropState + } + + // Transition until we find a grapheme cluster boundary. + width := runeWidth(r, firstProp) + for { + var ( + graphemeBoundary, wordBoundary, sentenceBoundary bool + lineBreak, prop int + ) + + r, l := utf8.DecodeRune(remainder) + remainder = b[length+l:] + + graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r) + wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "") + sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "") + lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "") + + if graphemeBoundary { + boundary := lineBreak | (width << ShiftWidth) + if wordBoundary { + boundary |= 1 << shiftWord + } + if sentenceBoundary { + boundary |= 1 << shiftSentence + } + return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(b) <= length { + return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + } +} + +// StepString is like [Step] but its input and outputs are strings. +func StepString(str string, state int) (cluster, rest string, boundaries int, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + prop := propertyGraphemes(r) + return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) + } + + // If we don't know the state, determine it now. + var graphemeState, wordState, sentenceState, lineState, firstProp int + remainder := str[length:] + if state < 0 { + graphemeState, firstProp, _ = transitionGraphemeState(state, r) + wordState, _ = transitionWordBreakState(state, r, nil, remainder) + sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder) + lineState, _ = transitionLineBreakState(state, r, nil, remainder) + } else { + graphemeState = state & maskGraphemeState + wordState = (state >> shiftWordState) & maskWordState + sentenceState = (state >> shiftSentenceState) & maskSentenceState + lineState = (state >> shiftLineState) & maskLineState + firstProp = state >> shiftPropState + } + + // Transition until we find a grapheme cluster boundary. + width := runeWidth(r, firstProp) + for { + var ( + graphemeBoundary, wordBoundary, sentenceBoundary bool + lineBreak, prop int + ) + + r, l := utf8.DecodeRuneInString(remainder) + remainder = str[length+l:] + + graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r) + wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder) + sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder) + lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder) + + if graphemeBoundary { + boundary := lineBreak | (width << ShiftWidth) + if wordBoundary { + boundary |= 1 << shiftWord + } + if sentenceBoundary { + boundary |= 1 << shiftSentence + } + return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(str) <= length { + return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + } +} diff --git a/vendor/github.com/rivo/uniseg/width.go b/vendor/github.com/rivo/uniseg/width.go new file mode 100644 index 000000000000..975a9f134398 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/width.go @@ -0,0 +1,61 @@ +package uniseg + +// EastAsianAmbiguousWidth specifies the monospace width for East Asian +// characters classified as Ambiguous. The default is 1 but some rare fonts +// render them with a width of 2. +var EastAsianAmbiguousWidth = 1 + +// runeWidth returns the monospace width for the given rune. The provided +// grapheme property is a value mapped by the [graphemeCodePoints] table. +// +// Every rune has a width of 1, except for runes with the following properties +// (evaluated in this order): +// +// - Control, CR, LF, Extend, ZWJ: Width of 0 +// - \u2e3a, TWO-EM DASH: Width of 3 +// - \u2e3b, THREE-EM DASH: Width of 4 +// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral +// have a width of 1) +// - Regional Indicator: Width of 2 +// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No". +func runeWidth(r rune, graphemeProperty int) int { + switch graphemeProperty { + case prControl, prCR, prLF, prExtend, prZWJ: + return 0 + case prRegionalIndicator: + return 2 + case prExtendedPictographic: + if property(emojiPresentation, r) == prEmojiPresentation { + return 2 + } + return 1 + } + + switch r { + case 0x2e3a: + return 3 + case 0x2e3b: + return 4 + } + + switch propertyEastAsianWidth(r) { + case prW, prF: + return 2 + case prA: + return EastAsianAmbiguousWidth + } + + return 1 +} + +// StringWidth returns the monospace width for the given string, that is, the +// number of same-size cells to be occupied by the string. +func StringWidth(s string) (width int) { + state := -1 + for len(s) > 0 { + var w int + _, s, w, state = FirstGraphemeClusterInString(s, state) + width += w + } + return +} diff --git a/vendor/github.com/rivo/uniseg/word.go b/vendor/github.com/rivo/uniseg/word.go new file mode 100644 index 000000000000..34fba7f2918c --- /dev/null +++ b/vendor/github.com/rivo/uniseg/word.go @@ -0,0 +1,89 @@ +package uniseg + +import "unicode/utf8" + +// FirstWord returns the first word found in the given byte slice according to +// the rules of [Unicode Standard Annex #29, Word Boundaries]. This function can +// be called continuously to extract all words from a byte slice, as illustrated +// in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified word. If the length of the "rest" slice +// is 0, the entire byte slice "b" has been processed. The "word" byte slice is +// the sub-slice of the input slice containing the identified word. +// +// Given an empty byte slice "b", the function returns nil values. +// +// [Unicode Standard Annex #29, Word Boundaries]: http://unicode.org/reports/tr29/#Word_Boundaries +func FirstWord(b []byte, state int) (word, rest []byte, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, wbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionWordBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionWordBreakState(state, r, b[length+l:], "") + + if boundary { + return b[:length], b[length:], state + } + + length += l + if len(b) <= length { + return b, nil, wbAny + } + } +} + +// FirstWordInString is like [FirstWord] but its input and outputs are strings. +func FirstWordInString(str string, state int) (word, rest string, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", wbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionWordBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionWordBreakState(state, r, nil, str[length+l:]) + + if boundary { + return str[:length], str[length:], state + } + + length += l + if len(str) <= length { + return str, "", wbAny + } + } +} diff --git a/vendor/github.com/rivo/uniseg/wordproperties.go b/vendor/github.com/rivo/uniseg/wordproperties.go new file mode 100644 index 000000000000..277ca100686a --- /dev/null +++ b/vendor/github.com/rivo/uniseg/wordproperties.go @@ -0,0 +1,1883 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// workBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/WordBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var workBreakCodePoints = [][3]int{ + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prNewline}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x0020, 0x0020, prWSegSpace}, // Zs SPACE + {0x0022, 0x0022, prDoubleQuote}, // Po QUOTATION MARK + {0x0027, 0x0027, prSingleQuote}, // Po APOSTROPHE + {0x002C, 0x002C, prMidNum}, // Po COMMA + {0x002E, 0x002E, prMidNumLet}, // Po FULL STOP + {0x0030, 0x0039, prNumeric}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003A, prMidLetter}, // Po COLON + {0x003B, 0x003B, prMidNum}, // Po SEMICOLON + {0x0041, 0x005A, prALetter}, // L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005F, 0x005F, prExtendNumLet}, // Pc LOW LINE + {0x0061, 0x007A, prALetter}, // L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x0085, 0x0085, prNewline}, // Cc + {0x00A9, 0x00A9, prExtendedPictographic}, // E0.6 [1] (ยฉ๏ธ) copyright + {0x00AA, 0x00AA, prALetter}, // Lo FEMININE ORDINAL INDICATOR + {0x00AD, 0x00AD, prFormat}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prExtendedPictographic}, // E0.6 [1] (ยฎ๏ธ) registered + {0x00B5, 0x00B5, prALetter}, // L& MICRO SIGN + {0x00B7, 0x00B7, prMidLetter}, // Po MIDDLE DOT + {0x00BA, 0x00BA, prALetter}, // Lo MASCULINE ORDINAL INDICATOR + {0x00C0, 0x00D6, prALetter}, // L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D8, 0x00F6, prALetter}, // L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F8, 0x01BA, prALetter}, // L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prALetter}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prALetter}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prALetter}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x0293, prALetter}, // L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prALetter}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prALetter}, // L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prALetter}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C5, prALetter}, // Sk [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02D1, prALetter}, // Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prALetter}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02DE, 0x02DF, prALetter}, // Sk [2] MODIFIER LETTER RHOTIC HOOK..MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prALetter}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prALetter}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prALetter}, // Lm MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prALetter}, // Sk MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prALetter}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prALetter}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prALetter}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prALetter}, // Lm GREEK NUMERAL SIGN + {0x0376, 0x0377, prALetter}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prALetter}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prALetter}, // L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prMidNum}, // Po GREEK QUESTION MARK + {0x037F, 0x037F, prALetter}, // L& GREEK CAPITAL LETTER YOT + {0x0386, 0x0386, prALetter}, // L& GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prMidLetter}, // Po GREEK ANO TELEIA + {0x0388, 0x038A, prALetter}, // L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prALetter}, // L& GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x03A1, prALetter}, // L& [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03F5, prALetter}, // L& [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL + {0x03F7, 0x0481, prALetter}, // L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x052F, prALetter}, // L& [166] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prALetter}, // L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prALetter}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055C, prALetter}, // Po [3] ARMENIAN APOSTROPHE..ARMENIAN EXCLAMATION MARK + {0x055E, 0x055E, prALetter}, // Po ARMENIAN QUESTION MARK + {0x055F, 0x055F, prMidLetter}, // Po ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prALetter}, // L& [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prMidNum}, // Po ARMENIAN FULL STOP + {0x058A, 0x058A, prALetter}, // Pd ARMENIAN HYPHEN + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prHebrewLetter}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prHebrewLetter}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F3, prALetter}, // Po HEBREW PUNCTUATION GERESH + {0x05F4, 0x05F4, prMidLetter}, // Po HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prFormat}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x060C, 0x060D, prMidNum}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prFormat}, // Cf ARABIC LETTER MARK + {0x0620, 0x063F, prALetter}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prALetter}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prALetter}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNumeric}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066B, 0x066B, prNumeric}, // Po ARABIC DECIMAL SEPARATOR + {0x066C, 0x066C, prMidNum}, // Po ARABIC THOUSANDS SEPARATOR + {0x066E, 0x066F, prALetter}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prALetter}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D5, 0x06D5, prALetter}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prFormat}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prALetter}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prALetter}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNumeric}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prALetter}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FF, 0x06FF, prALetter}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x070F, 0x070F, prFormat}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prALetter}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prALetter}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x07A5, prALetter}, // Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prALetter}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prNumeric}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prALetter}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prALetter}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F8, 0x07F8, prMidNum}, // Po NKO COMMA + {0x07FA, 0x07FA, prALetter}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0800, 0x0815, prALetter}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prALetter}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prALetter}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prALetter}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0840, 0x0858, prALetter}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0860, 0x086A, prALetter}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prALetter}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0889, 0x088E, prALetter}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prFormat}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prALetter}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prALetter}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prFormat}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prExtend}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prALetter}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prExtend}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prALetter}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prExtend}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prExtend}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prExtend}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prALetter}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prALetter}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0966, 0x096F, prNumeric}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0971, 0x0971, prALetter}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x0980, prALetter}, // Lo [15] DEVANAGARI LETTER CANDRA A..BENGALI ANJI + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prExtend}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prALetter}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prALetter}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prALetter}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prALetter}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prALetter}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prALetter}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prALetter}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prExtend}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prExtend}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prExtend}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prALetter}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prALetter}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prALetter}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNumeric}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prALetter}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09FC, 0x09FC, prALetter}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prExtend}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prALetter}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prALetter}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prALetter}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prALetter}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prALetter}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prALetter}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prALetter}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prExtend}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prALetter}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prALetter}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNumeric}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prALetter}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prExtend}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prALetter}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prALetter}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prALetter}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prALetter}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prALetter}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prALetter}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prALetter}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prExtend}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prExtend}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prExtend}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prALetter}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prALetter}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNumeric}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF9, 0x0AF9, prALetter}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prExtend}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prALetter}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prALetter}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prALetter}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prALetter}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prALetter}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prALetter}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prALetter}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prExtend}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prExtend}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prExtend}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prALetter}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prALetter}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNumeric}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B71, 0x0B71, prALetter}, // Lo ORIYA LETTER WA + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prALetter}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prALetter}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prALetter}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prALetter}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prALetter}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prALetter}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prALetter}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prALetter}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prALetter}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prALetter}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prExtend}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prExtend}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prExtend}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prExtend}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prALetter}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNumeric}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prExtend}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prALetter}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prALetter}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prALetter}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prALetter}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prALetter}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prExtend}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prALetter}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prALetter}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prALetter}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNumeric}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C80, 0x0C80, prALetter}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prExtend}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C85, 0x0C8C, prALetter}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prALetter}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prALetter}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prALetter}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prALetter}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prALetter}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prExtend}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prExtend}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prExtend}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prExtend}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prALetter}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prALetter}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNumeric}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prALetter}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prExtend}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prExtend}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prALetter}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prALetter}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prALetter}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prALetter}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prALetter}, // Lo MALAYALAM LETTER DOT REPH + {0x0D54, 0x0D56, prALetter}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D5F, 0x0D61, prALetter}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNumeric}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D7A, 0x0D7F, prALetter}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prExtend}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prALetter}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prALetter}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prALetter}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prALetter}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prALetter}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prExtend}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prExtend}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNumeric}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prExtend}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E50, 0x0E59, prNumeric}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNumeric}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0F00, 0x0F00, prALetter}, // Lo TIBETAN SYLLABLE OM + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F20, 0x0F29, prNumeric}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3E, 0x0F3F, prExtend}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prALetter}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prALetter}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prExtend}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prALetter}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x102B, 0x102C, prExtend}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prExtend}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prExtend}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prExtend}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x1040, 0x1049, prNumeric}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x1056, 0x1057, prExtend}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1062, 0x1064, prExtend}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1067, 0x106D, prExtend}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prExtend}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prExtend}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108F, 0x108F, prExtend}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNumeric}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prExtend}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x10A0, 0x10C5, prALetter}, // L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prALetter}, // L& GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prALetter}, // L& GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prALetter}, // L& [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FC, 0x10FC, prALetter}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prALetter}, // L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x1248, prALetter}, // Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prALetter}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prALetter}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prALetter}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prALetter}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prALetter}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prALetter}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prALetter}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prALetter}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prALetter}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prALetter}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prALetter}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1380, 0x138F, prALetter}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x13A0, 0x13F5, prALetter}, // L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prALetter}, // L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1401, 0x166C, prALetter}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166F, 0x167F, prALetter}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prWSegSpace}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prALetter}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x16A0, 0x16EA, prALetter}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EE, 0x16F0, prALetter}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prALetter}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prALetter}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prExtend}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x1731, prALetter}, // Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prExtend}, // Mc HANUNOO SIGN PAMUDPOD + {0x1740, 0x1751, prALetter}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prALetter}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prALetter}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prExtend}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prExtend}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prExtend}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNumeric}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prFormat}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNumeric}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prALetter}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prALetter}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prALetter}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prALetter}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prALetter}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prALetter}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prALetter}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prALetter}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prExtend}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prExtend}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prExtend}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prExtend}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1946, 0x194F, prNumeric}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x19D0, 0x19D9, prNumeric}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x1A00, 0x1A16, prALetter}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prExtend}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A55, 0x1A55, prExtend}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prExtend}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prExtend}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prExtend}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prExtend}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNumeric}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNumeric}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prExtend}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prALetter}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prExtend}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prExtend}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prExtend}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prALetter}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNumeric}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prExtend}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prALetter}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prExtend}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prExtend}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prExtend}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prALetter}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNumeric}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BE5, prALetter}, // Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prExtend}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prExtend}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prExtend}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prExtend}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C00, 0x1C23, prALetter}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prExtend}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prExtend}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C40, 0x1C49, prNumeric}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prALetter}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNumeric}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prALetter}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prALetter}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C80, 0x1C88, prALetter}, // L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prALetter}, // L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prALetter}, // L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prExtend}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prALetter}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prALetter}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prALetter}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prExtend}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prALetter}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prALetter}, // L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prALetter}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prALetter}, // L& [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prALetter}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D9A, prALetter}, // L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prALetter}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1F15, prALetter}, // L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prALetter}, // L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prALetter}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prALetter}, // L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prALetter}, // L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prALetter}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prALetter}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prALetter}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBE, 0x1FBE, prALetter}, // L& GREEK PROSGEGRAMMENI + {0x1FC2, 0x1FC4, prALetter}, // L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prALetter}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FD0, 0x1FD3, prALetter}, // L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prALetter}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FE0, 0x1FEC, prALetter}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FF2, 0x1FF4, prALetter}, // L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prALetter}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x2000, 0x2006, prWSegSpace}, // Zs [7] EN QUAD..SIX-PER-EM SPACE + {0x2008, 0x200A, prWSegSpace}, // Zs [3] PUNCTUATION SPACE..HAIR SPACE + {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER + {0x200E, 0x200F, prFormat}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2018, 0x2018, prMidNumLet}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prMidNumLet}, // Pf RIGHT SINGLE QUOTATION MARK + {0x2024, 0x2024, prMidNumLet}, // Po ONE DOT LEADER + {0x2027, 0x2027, prMidLetter}, // Po HYPHENATION POINT + {0x2028, 0x2028, prNewline}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prNewline}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prFormat}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prExtendNumLet}, // Zs NARROW NO-BREAK SPACE + {0x203C, 0x203C, prExtendedPictographic}, // E0.6 [1] (โ€ผ๏ธ) double exclamation mark + {0x203F, 0x2040, prExtendNumLet}, // Pc [2] UNDERTIE..CHARACTER TIE + {0x2044, 0x2044, prMidNum}, // Sm FRACTION SLASH + {0x2049, 0x2049, prExtendedPictographic}, // E0.6 [1] (โ‰๏ธ) exclamation question mark + {0x2054, 0x2054, prExtendNumLet}, // Pc INVERTED UNDERTIE + {0x205F, 0x205F, prWSegSpace}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prFormat}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prFormat}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2071, 0x2071, prALetter}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x207F, 0x207F, prALetter}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x2090, 0x209C, prALetter}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2102, 0x2102, prALetter}, // L& DOUBLE-STRUCK CAPITAL C + {0x2107, 0x2107, prALetter}, // L& EULER CONSTANT + {0x210A, 0x2113, prALetter}, // L& [10] SCRIPT SMALL G..SCRIPT SMALL L + {0x2115, 0x2115, prALetter}, // L& DOUBLE-STRUCK CAPITAL N + {0x2119, 0x211D, prALetter}, // L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x2122, 0x2122, prExtendedPictographic}, // E0.6 [1] (โ„ข๏ธ) trade mark + {0x2124, 0x2124, prALetter}, // L& DOUBLE-STRUCK CAPITAL Z + {0x2126, 0x2126, prALetter}, // L& OHM SIGN + {0x2128, 0x2128, prALetter}, // L& BLACK-LETTER CAPITAL Z + {0x212A, 0x212D, prALetter}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C + {0x212F, 0x2134, prALetter}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prALetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] (โ„น๏ธ) information + {0x2139, 0x2139, prALetter}, // L& INFORMATION SOURCE + {0x213C, 0x213F, prALetter}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2145, 0x2149, prALetter}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214E, 0x214E, prALetter}, // L& TURNED SMALL F + {0x2160, 0x2182, prALetter}, // Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prALetter}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prALetter}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2194, 0x2199, prExtendedPictographic}, // E0.6 [6] (โ†”๏ธ..โ†™๏ธ) left-right arrow..down-left arrow + {0x21A9, 0x21AA, prExtendedPictographic}, // E0.6 [2] (โ†ฉ๏ธ..โ†ช๏ธ) right arrow curving left..left arrow curving right + {0x231A, 0x231B, prExtendedPictographic}, // E0.6 [2] (โŒš..โŒ›) watch..hourglass done + {0x2328, 0x2328, prExtendedPictographic}, // E1.0 [1] (โŒจ๏ธ) keyboard + {0x2388, 0x2388, prExtendedPictographic}, // E0.0 [1] (โŽˆ) HELM SYMBOL + {0x23CF, 0x23CF, prExtendedPictographic}, // E1.0 [1] (โ๏ธ) eject button + {0x23E9, 0x23EC, prExtendedPictographic}, // E0.6 [4] (โฉ..โฌ) fast-forward button..fast down button + {0x23ED, 0x23EE, prExtendedPictographic}, // E0.7 [2] (โญ๏ธ..โฎ๏ธ) next track button..last track button + {0x23EF, 0x23EF, prExtendedPictographic}, // E1.0 [1] (โฏ๏ธ) play or pause button + {0x23F0, 0x23F0, prExtendedPictographic}, // E0.6 [1] (โฐ) alarm clock + {0x23F1, 0x23F2, prExtendedPictographic}, // E1.0 [2] (โฑ๏ธ..โฒ๏ธ) stopwatch..timer clock + {0x23F3, 0x23F3, prExtendedPictographic}, // E0.6 [1] (โณ) hourglass not done + {0x23F8, 0x23FA, prExtendedPictographic}, // E0.7 [3] (โธ๏ธ..โบ๏ธ) pause button..record button + {0x24B6, 0x24E9, prALetter}, // So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24C2, 0x24C2, prExtendedPictographic}, // E0.6 [1] (โ“‚๏ธ) circled M + {0x25AA, 0x25AB, prExtendedPictographic}, // E0.6 [2] (โ–ช๏ธ..โ–ซ๏ธ) black small square..white small square + {0x25B6, 0x25B6, prExtendedPictographic}, // E0.6 [1] (โ–ถ๏ธ) play button + {0x25C0, 0x25C0, prExtendedPictographic}, // E0.6 [1] (โ—€๏ธ) reverse button + {0x25FB, 0x25FE, prExtendedPictographic}, // E0.6 [4] (โ—ป๏ธ..โ—พ) white medium square..black medium-small square + {0x2600, 0x2601, prExtendedPictographic}, // E0.6 [2] (โ˜€๏ธ..โ˜๏ธ) sun..cloud + {0x2602, 0x2603, prExtendedPictographic}, // E0.7 [2] (โ˜‚๏ธ..โ˜ƒ๏ธ) umbrella..snowman + {0x2604, 0x2604, prExtendedPictographic}, // E1.0 [1] (โ˜„๏ธ) comet + {0x2605, 0x2605, prExtendedPictographic}, // E0.0 [1] (โ˜…) BLACK STAR + {0x2607, 0x260D, prExtendedPictographic}, // E0.0 [7] (โ˜‡..โ˜) LIGHTNING..OPPOSITION + {0x260E, 0x260E, prExtendedPictographic}, // E0.6 [1] (โ˜Ž๏ธ) telephone + {0x260F, 0x2610, prExtendedPictographic}, // E0.0 [2] (โ˜..โ˜) WHITE TELEPHONE..BALLOT BOX + {0x2611, 0x2611, prExtendedPictographic}, // E0.6 [1] (โ˜‘๏ธ) check box with check + {0x2612, 0x2612, prExtendedPictographic}, // E0.0 [1] (โ˜’) BALLOT BOX WITH X + {0x2614, 0x2615, prExtendedPictographic}, // E0.6 [2] (โ˜”..โ˜•) umbrella with rain drops..hot beverage + {0x2616, 0x2617, prExtendedPictographic}, // E0.0 [2] (โ˜–..โ˜—) WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prExtendedPictographic}, // E1.0 [1] (โ˜˜๏ธ) shamrock + {0x2619, 0x261C, prExtendedPictographic}, // E0.0 [4] (โ˜™..โ˜œ) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prExtendedPictographic}, // E0.6 [1] (โ˜๏ธ) index pointing up + {0x261E, 0x261F, prExtendedPictographic}, // E0.0 [2] (โ˜ž..โ˜Ÿ) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2620, prExtendedPictographic}, // E1.0 [1] (โ˜ ๏ธ) skull and crossbones + {0x2621, 0x2621, prExtendedPictographic}, // E0.0 [1] (โ˜ก) CAUTION SIGN + {0x2622, 0x2623, prExtendedPictographic}, // E1.0 [2] (โ˜ข๏ธ..โ˜ฃ๏ธ) radioactive..biohazard + {0x2624, 0x2625, prExtendedPictographic}, // E0.0 [2] (โ˜ค..โ˜ฅ) CADUCEUS..ANKH + {0x2626, 0x2626, prExtendedPictographic}, // E1.0 [1] (โ˜ฆ๏ธ) orthodox cross + {0x2627, 0x2629, prExtendedPictographic}, // E0.0 [3] (โ˜ง..โ˜ฉ) CHI RHO..CROSS OF JERUSALEM + {0x262A, 0x262A, prExtendedPictographic}, // E0.7 [1] (โ˜ช๏ธ) star and crescent + {0x262B, 0x262D, prExtendedPictographic}, // E0.0 [3] (โ˜ซ..โ˜ญ) FARSI SYMBOL..HAMMER AND SICKLE + {0x262E, 0x262E, prExtendedPictographic}, // E1.0 [1] (โ˜ฎ๏ธ) peace symbol + {0x262F, 0x262F, prExtendedPictographic}, // E0.7 [1] (โ˜ฏ๏ธ) yin yang + {0x2630, 0x2637, prExtendedPictographic}, // E0.0 [8] (โ˜ฐ..โ˜ท) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH + {0x2638, 0x2639, prExtendedPictographic}, // E0.7 [2] (โ˜ธ๏ธ..โ˜น๏ธ) wheel of dharma..frowning face + {0x263A, 0x263A, prExtendedPictographic}, // E0.6 [1] (โ˜บ๏ธ) smiling face + {0x263B, 0x263F, prExtendedPictographic}, // E0.0 [5] (โ˜ป..โ˜ฟ) BLACK SMILING FACE..MERCURY + {0x2640, 0x2640, prExtendedPictographic}, // E4.0 [1] (โ™€๏ธ) female sign + {0x2641, 0x2641, prExtendedPictographic}, // E0.0 [1] (โ™) EARTH + {0x2642, 0x2642, prExtendedPictographic}, // E4.0 [1] (โ™‚๏ธ) male sign + {0x2643, 0x2647, prExtendedPictographic}, // E0.0 [5] (โ™ƒ..โ™‡) JUPITER..PLUTO + {0x2648, 0x2653, prExtendedPictographic}, // E0.6 [12] (โ™ˆ..โ™“) Aries..Pisces + {0x2654, 0x265E, prExtendedPictographic}, // E0.0 [11] (โ™”..โ™ž) WHITE CHESS KING..BLACK CHESS KNIGHT + {0x265F, 0x265F, prExtendedPictographic}, // E11.0 [1] (โ™Ÿ๏ธ) chess pawn + {0x2660, 0x2660, prExtendedPictographic}, // E0.6 [1] (โ™ ๏ธ) spade suit + {0x2661, 0x2662, prExtendedPictographic}, // E0.0 [2] (โ™ก..โ™ข) WHITE HEART SUIT..WHITE DIAMOND SUIT + {0x2663, 0x2663, prExtendedPictographic}, // E0.6 [1] (โ™ฃ๏ธ) club suit + {0x2664, 0x2664, prExtendedPictographic}, // E0.0 [1] (โ™ค) WHITE SPADE SUIT + {0x2665, 0x2666, prExtendedPictographic}, // E0.6 [2] (โ™ฅ๏ธ..โ™ฆ๏ธ) heart suit..diamond suit + {0x2667, 0x2667, prExtendedPictographic}, // E0.0 [1] (โ™ง) WHITE CLUB SUIT + {0x2668, 0x2668, prExtendedPictographic}, // E0.6 [1] (โ™จ๏ธ) hot springs + {0x2669, 0x267A, prExtendedPictographic}, // E0.0 [18] (โ™ฉ..โ™บ) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS + {0x267B, 0x267B, prExtendedPictographic}, // E0.6 [1] (โ™ป๏ธ) recycling symbol + {0x267C, 0x267D, prExtendedPictographic}, // E0.0 [2] (โ™ผ..โ™ฝ) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL + {0x267E, 0x267E, prExtendedPictographic}, // E11.0 [1] (โ™พ๏ธ) infinity + {0x267F, 0x267F, prExtendedPictographic}, // E0.6 [1] (โ™ฟ) wheelchair symbol + {0x2680, 0x2685, prExtendedPictographic}, // E0.0 [6] (โš€..โš…) DIE FACE-1..DIE FACE-6 + {0x2690, 0x2691, prExtendedPictographic}, // E0.0 [2] (โš..โš‘) WHITE FLAG..BLACK FLAG + {0x2692, 0x2692, prExtendedPictographic}, // E1.0 [1] (โš’๏ธ) hammer and pick + {0x2693, 0x2693, prExtendedPictographic}, // E0.6 [1] (โš“) anchor + {0x2694, 0x2694, prExtendedPictographic}, // E1.0 [1] (โš”๏ธ) crossed swords + {0x2695, 0x2695, prExtendedPictographic}, // E4.0 [1] (โš•๏ธ) medical symbol + {0x2696, 0x2697, prExtendedPictographic}, // E1.0 [2] (โš–๏ธ..โš—๏ธ) balance scale..alembic + {0x2698, 0x2698, prExtendedPictographic}, // E0.0 [1] (โš˜) FLOWER + {0x2699, 0x2699, prExtendedPictographic}, // E1.0 [1] (โš™๏ธ) gear + {0x269A, 0x269A, prExtendedPictographic}, // E0.0 [1] (โšš) STAFF OF HERMES + {0x269B, 0x269C, prExtendedPictographic}, // E1.0 [2] (โš›๏ธ..โšœ๏ธ) atom symbol..fleur-de-lis + {0x269D, 0x269F, prExtendedPictographic}, // E0.0 [3] (โš..โšŸ) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A1, prExtendedPictographic}, // E0.6 [2] (โš ๏ธ..โšก) warning..high voltage + {0x26A2, 0x26A6, prExtendedPictographic}, // E0.0 [5] (โšข..โšฆ) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN + {0x26A7, 0x26A7, prExtendedPictographic}, // E13.0 [1] (โšง๏ธ) transgender symbol + {0x26A8, 0x26A9, prExtendedPictographic}, // E0.0 [2] (โšจ..โšฉ) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prExtendedPictographic}, // E0.6 [2] (โšช..โšซ) white circle..black circle + {0x26AC, 0x26AF, prExtendedPictographic}, // E0.0 [4] (โšฌ..โšฏ) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL + {0x26B0, 0x26B1, prExtendedPictographic}, // E1.0 [2] (โšฐ๏ธ..โšฑ๏ธ) coffin..funeral urn + {0x26B2, 0x26BC, prExtendedPictographic}, // E0.0 [11] (โšฒ..โšผ) NEUTER..SESQUIQUADRATE + {0x26BD, 0x26BE, prExtendedPictographic}, // E0.6 [2] (โšฝ..โšพ) soccer ball..baseball + {0x26BF, 0x26C3, prExtendedPictographic}, // E0.0 [5] (โšฟ..โ›ƒ) SQUARED KEY..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prExtendedPictographic}, // E0.6 [2] (โ›„..โ›…) snowman without snow..sun behind cloud + {0x26C6, 0x26C7, prExtendedPictographic}, // E0.0 [2] (โ›†..โ›‡) RAIN..BLACK SNOWMAN + {0x26C8, 0x26C8, prExtendedPictographic}, // E0.7 [1] (โ›ˆ๏ธ) cloud with lightning and rain + {0x26C9, 0x26CD, prExtendedPictographic}, // E0.0 [5] (โ›‰..โ›) TURNED WHITE SHOGI PIECE..DISABLED CAR + {0x26CE, 0x26CE, prExtendedPictographic}, // E0.6 [1] (โ›Ž) Ophiuchus + {0x26CF, 0x26CF, prExtendedPictographic}, // E0.7 [1] (โ›๏ธ) pick + {0x26D0, 0x26D0, prExtendedPictographic}, // E0.0 [1] (โ›) CAR SLIDING + {0x26D1, 0x26D1, prExtendedPictographic}, // E0.7 [1] (โ›‘๏ธ) rescue workerโ€™s helmet + {0x26D2, 0x26D2, prExtendedPictographic}, // E0.0 [1] (โ›’) CIRCLED CROSSING LANES + {0x26D3, 0x26D3, prExtendedPictographic}, // E0.7 [1] (โ›“๏ธ) chains + {0x26D4, 0x26D4, prExtendedPictographic}, // E0.6 [1] (โ›”) no entry + {0x26D5, 0x26E8, prExtendedPictographic}, // E0.0 [20] (โ›•..โ›จ) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD + {0x26E9, 0x26E9, prExtendedPictographic}, // E0.7 [1] (โ›ฉ๏ธ) shinto shrine + {0x26EA, 0x26EA, prExtendedPictographic}, // E0.6 [1] (โ›ช) church + {0x26EB, 0x26EF, prExtendedPictographic}, // E0.0 [5] (โ›ซ..โ›ฏ) CASTLE..MAP SYMBOL FOR LIGHTHOUSE + {0x26F0, 0x26F1, prExtendedPictographic}, // E0.7 [2] (โ›ฐ๏ธ..โ›ฑ๏ธ) mountain..umbrella on ground + {0x26F2, 0x26F3, prExtendedPictographic}, // E0.6 [2] (โ›ฒ..โ›ณ) fountain..flag in hole + {0x26F4, 0x26F4, prExtendedPictographic}, // E0.7 [1] (โ›ด๏ธ) ferry + {0x26F5, 0x26F5, prExtendedPictographic}, // E0.6 [1] (โ›ต) sailboat + {0x26F6, 0x26F6, prExtendedPictographic}, // E0.0 [1] (โ›ถ) SQUARE FOUR CORNERS + {0x26F7, 0x26F9, prExtendedPictographic}, // E0.7 [3] (โ›ท๏ธ..โ›น๏ธ) skier..person bouncing ball + {0x26FA, 0x26FA, prExtendedPictographic}, // E0.6 [1] (โ›บ) tent + {0x26FB, 0x26FC, prExtendedPictographic}, // E0.0 [2] (โ›ป..โ›ผ) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prExtendedPictographic}, // E0.6 [1] (โ›ฝ) fuel pump + {0x26FE, 0x2701, prExtendedPictographic}, // E0.0 [4] (โ›พ..โœ) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS + {0x2702, 0x2702, prExtendedPictographic}, // E0.6 [1] (โœ‚๏ธ) scissors + {0x2703, 0x2704, prExtendedPictographic}, // E0.0 [2] (โœƒ..โœ„) LOWER BLADE SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prExtendedPictographic}, // E0.6 [1] (โœ…) check mark button + {0x2708, 0x270C, prExtendedPictographic}, // E0.6 [5] (โœˆ๏ธ..โœŒ๏ธ) airplane..victory hand + {0x270D, 0x270D, prExtendedPictographic}, // E0.7 [1] (โœ๏ธ) writing hand + {0x270E, 0x270E, prExtendedPictographic}, // E0.0 [1] (โœŽ) LOWER RIGHT PENCIL + {0x270F, 0x270F, prExtendedPictographic}, // E0.6 [1] (โœ๏ธ) pencil + {0x2710, 0x2711, prExtendedPictographic}, // E0.0 [2] (โœ..โœ‘) UPPER RIGHT PENCIL..WHITE NIB + {0x2712, 0x2712, prExtendedPictographic}, // E0.6 [1] (โœ’๏ธ) black nib + {0x2714, 0x2714, prExtendedPictographic}, // E0.6 [1] (โœ”๏ธ) check mark + {0x2716, 0x2716, prExtendedPictographic}, // E0.6 [1] (โœ–๏ธ) multiply + {0x271D, 0x271D, prExtendedPictographic}, // E0.7 [1] (โœ๏ธ) latin cross + {0x2721, 0x2721, prExtendedPictographic}, // E0.7 [1] (โœก๏ธ) star of David + {0x2728, 0x2728, prExtendedPictographic}, // E0.6 [1] (โœจ) sparkles + {0x2733, 0x2734, prExtendedPictographic}, // E0.6 [2] (โœณ๏ธ..โœด๏ธ) eight-spoked asterisk..eight-pointed star + {0x2744, 0x2744, prExtendedPictographic}, // E0.6 [1] (โ„๏ธ) snowflake + {0x2747, 0x2747, prExtendedPictographic}, // E0.6 [1] (โ‡๏ธ) sparkle + {0x274C, 0x274C, prExtendedPictographic}, // E0.6 [1] (โŒ) cross mark + {0x274E, 0x274E, prExtendedPictographic}, // E0.6 [1] (โŽ) cross mark button + {0x2753, 0x2755, prExtendedPictographic}, // E0.6 [3] (โ“..โ•) red question mark..white exclamation mark + {0x2757, 0x2757, prExtendedPictographic}, // E0.6 [1] (โ—) red exclamation mark + {0x2763, 0x2763, prExtendedPictographic}, // E1.0 [1] (โฃ๏ธ) heart exclamation + {0x2764, 0x2764, prExtendedPictographic}, // E0.6 [1] (โค๏ธ) red heart + {0x2765, 0x2767, prExtendedPictographic}, // E0.0 [3] (โฅ..โง) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2795, 0x2797, prExtendedPictographic}, // E0.6 [3] (โž•..โž—) plus..divide + {0x27A1, 0x27A1, prExtendedPictographic}, // E0.6 [1] (โžก๏ธ) right arrow + {0x27B0, 0x27B0, prExtendedPictographic}, // E0.6 [1] (โžฐ) curly loop + {0x27BF, 0x27BF, prExtendedPictographic}, // E1.0 [1] (โžฟ) double curly loop + {0x2934, 0x2935, prExtendedPictographic}, // E0.6 [2] (โคด๏ธ..โคต๏ธ) right arrow curving up..right arrow curving down + {0x2B05, 0x2B07, prExtendedPictographic}, // E0.6 [3] (โฌ…๏ธ..โฌ‡๏ธ) left arrow..down arrow + {0x2B1B, 0x2B1C, prExtendedPictographic}, // E0.6 [2] (โฌ›..โฌœ) black large square..white large square + {0x2B50, 0x2B50, prExtendedPictographic}, // E0.6 [1] (โญ) star + {0x2B55, 0x2B55, prExtendedPictographic}, // E0.6 [1] (โญ•) hollow red circle + {0x2C00, 0x2C7B, prALetter}, // L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prALetter}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2CE4, prALetter}, // L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI + {0x2CEB, 0x2CEE, prALetter}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prALetter}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2D00, 0x2D25, prALetter}, // L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prALetter}, // L& GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prALetter}, // L& GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prALetter}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prALetter}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prALetter}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E2F, 0x2E2F, prALetter}, // Lm VERTICAL TILDE + {0x3000, 0x3000, prWSegSpace}, // Zs IDEOGRAPHIC SPACE + {0x3005, 0x3005, prALetter}, // Lm IDEOGRAPHIC ITERATION MARK + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prExtendedPictographic}, // E0.6 [1] (ใ€ฐ๏ธ) wavy dash + {0x3031, 0x3035, prKatakana}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x303B, 0x303B, prALetter}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prALetter}, // Lo MASU MARK + {0x303D, 0x303D, prExtendedPictographic}, // E0.6 [1] (ใ€ฝ๏ธ) part alternation mark + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prKatakana}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x30A0, 0x30A0, prKatakana}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30FA, prKatakana}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FC, 0x30FE, prKatakana}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prKatakana}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prALetter}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prALetter}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x31A0, 0x31BF, prALetter}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31F0, 0x31FF, prKatakana}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3297, 0x3297, prExtendedPictographic}, // E0.6 [1] (ใŠ—๏ธ) Japanese โ€œcongratulationsโ€ button + {0x3299, 0x3299, prExtendedPictographic}, // E0.6 [1] (ใŠ™๏ธ) Japanese โ€œsecretโ€ button + {0x32D0, 0x32FE, prKatakana}, // So [47] CIRCLED KATAKANA A..CIRCLED KATAKANA WO + {0x3300, 0x3357, prKatakana}, // So [88] SQUARE APAATO..SQUARE WATTO + {0xA000, 0xA014, prALetter}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prALetter}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prALetter}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA4D0, 0xA4F7, prALetter}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prALetter}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA500, 0xA60B, prALetter}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prALetter}, // Lm VAI SYLLABLE LENGTHENER + {0xA610, 0xA61F, prALetter}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNumeric}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prALetter}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prALetter}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prALetter}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67F, 0xA67F, prALetter}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA69B, prALetter}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prALetter}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prALetter}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prALetter}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA708, 0xA716, prALetter}, // Sk [15] MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prALetter}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prALetter}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prALetter}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prALetter}, // Lm MODIFIER LETTER US + {0xA771, 0xA787, prALetter}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prALetter}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prALetter}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prALetter}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prALetter}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prALetter}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prALetter}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prALetter}, // L& LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prALetter}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prALetter}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prALetter}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prALetter}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prALetter}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prALetter}, // L& LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA801, prALetter}, // Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prALetter}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prALetter}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prALetter}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prExtend}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prExtend}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA840, 0xA873, prALetter}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA880, 0xA881, prExtend}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prALetter}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prExtend}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8D0, 0xA8D9, prNumeric}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prALetter}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8FB, 0xA8FB, prALetter}, // Lo DEVANAGARI HEADSTROKE + {0xA8FD, 0xA8FE, prALetter}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNumeric}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prALetter}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA930, 0xA946, prALetter}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prExtend}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prALetter}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prExtend}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prALetter}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prExtend}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9CF, 0xA9CF, prALetter}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNumeric}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xA9F0, 0xA9F9, prNumeric}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xAA00, 0xAA28, prALetter}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prExtend}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prExtend}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prALetter}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prALetter}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prExtend}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNumeric}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA7B, 0xAA7B, prExtend}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prExtend}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAE0, 0xAAEA, prALetter}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF2, 0xAAF2, prALetter}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prALetter}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prALetter}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prALetter}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prALetter}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prALetter}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prALetter}, // L& [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prALetter}, // Sk MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prALetter}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prALetter}, // L& [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prALetter}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB70, 0xABBF, prALetter}, // L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prALetter}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEC, 0xABEC, prExtend}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNumeric}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prALetter}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prALetter}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prALetter}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xFB00, 0xFB06, prALetter}, // L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prALetter}, // L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prHebrewLetter}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prHebrewLetter}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB2A, 0xFB36, prHebrewLetter}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prHebrewLetter}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prHebrewLetter}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prHebrewLetter}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prHebrewLetter}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prHebrewLetter}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prALetter}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBD3, 0xFD3D, prALetter}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD50, 0xFD8F, prALetter}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prALetter}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDF0, 0xFDFB, prALetter}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE10, prMidNum}, // Po PRESENTATION FORM FOR VERTICAL COMMA + {0xFE13, 0xFE13, prMidLetter}, // Po PRESENTATION FORM FOR VERTICAL COLON + {0xFE14, 0xFE14, prMidNum}, // Po PRESENTATION FORM FOR VERTICAL SEMICOLON + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE33, 0xFE34, prExtendNumLet}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE4D, 0xFE4F, prExtendNumLet}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE50, prMidNum}, // Po SMALL COMMA + {0xFE52, 0xFE52, prMidNumLet}, // Po SMALL FULL STOP + {0xFE54, 0xFE54, prMidNum}, // Po SMALL SEMICOLON + {0xFE55, 0xFE55, prMidLetter}, // Po SMALL COLON + {0xFE70, 0xFE74, prALetter}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prALetter}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prFormat}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF07, 0xFF07, prMidNumLet}, // Po FULLWIDTH APOSTROPHE + {0xFF0C, 0xFF0C, prMidNum}, // Po FULLWIDTH COMMA + {0xFF0E, 0xFF0E, prMidNumLet}, // Po FULLWIDTH FULL STOP + {0xFF10, 0xFF19, prNumeric}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1A, prMidLetter}, // Po FULLWIDTH COLON + {0xFF1B, 0xFF1B, prMidNum}, // Po FULLWIDTH SEMICOLON + {0xFF21, 0xFF3A, prALetter}, // L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3F, 0xFF3F, prExtendNumLet}, // Pc FULLWIDTH LOW LINE + {0xFF41, 0xFF5A, prALetter}, // L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF66, 0xFF6F, prKatakana}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prKatakana}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prKatakana}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prALetter}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prALetter}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFF9, 0xFFFB, prFormat}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x10000, 0x1000B, prALetter}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prALetter}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prALetter}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prALetter}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prALetter}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prALetter}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prALetter}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10140, 0x10174, prALetter}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prALetter}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prALetter}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10300, 0x1031F, prALetter}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x1032D, 0x10340, prALetter}, // Lo [20] OLD ITALIC LETTER YE..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prALetter}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prALetter}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prALetter}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prALetter}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prALetter}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x103A0, 0x103C3, prALetter}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prALetter}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D1, 0x103D5, prALetter}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prALetter}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1049D, prALetter}, // Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNumeric}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prALetter}, // L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prALetter}, // L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prALetter}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prALetter}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x10570, 0x1057A, prALetter}, // L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prALetter}, // L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prALetter}, // L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prALetter}, // L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prALetter}, // L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prALetter}, // L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prALetter}, // L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prALetter}, // L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prALetter}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prALetter}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prALetter}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prALetter}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prALetter}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prALetter}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prALetter}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prALetter}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prALetter}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prALetter}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prALetter}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x10855, prALetter}, // Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW + {0x10860, 0x10876, prALetter}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10880, 0x1089E, prALetter}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108E0, 0x108F2, prALetter}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prALetter}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x10900, 0x10915, prALetter}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10920, 0x10939, prALetter}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x10980, 0x109B7, prALetter}, // Lo [56] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BE, 0x109BF, prALetter}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x10A00, 0x10A00, prALetter}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prALetter}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prALetter}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prALetter}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10A60, 0x10A7C, prALetter}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A80, 0x10A9C, prALetter}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10AC0, 0x10AC7, prALetter}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC9, 0x10AE4, prALetter}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10B00, 0x10B35, prALetter}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B40, 0x10B55, prALetter}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B60, 0x10B72, prALetter}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B80, 0x10B91, prALetter}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10C00, 0x10C48, prALetter}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prALetter}, // L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prALetter}, // L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10D00, 0x10D23, prALetter}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNumeric}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E80, 0x10EA9, prALetter}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EB0, 0x10EB1, prALetter}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prALetter}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F27, 0x10F27, prALetter}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prALetter}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F70, 0x10F81, prALetter}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10FB0, 0x10FC4, prALetter}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FE0, 0x10FF6, prALetter}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prExtend}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prExtend}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prALetter}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11066, 0x1106F, prNumeric}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prALetter}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prALetter}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prExtend}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prALetter}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prExtend}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prExtend}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prFormat}, // Cf KAITHI NUMBER SIGN + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prFormat}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prALetter}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNumeric}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prALetter}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prExtend}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNumeric}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11144, 0x11144, prALetter}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prExtend}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prALetter}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prALetter}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11176, 0x11176, prALetter}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prExtend}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prALetter}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prExtend}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prExtend}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prALetter}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CE, 0x111CE, prExtend}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNumeric}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prALetter}, // Lo SHARADA EKAM + {0x111DC, 0x111DC, prALetter}, // Lo SHARADA HEADSTROKE + {0x11200, 0x11211, prALetter}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prALetter}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prExtend}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prExtend}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prExtend}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prALetter}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prALetter}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prALetter}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prALetter}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prALetter}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prALetter}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112B0, 0x112DE, prALetter}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prExtend}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNumeric}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prExtend}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prALetter}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prALetter}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prALetter}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prALetter}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prALetter}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prALetter}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prALetter}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prExtend}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prExtend}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prExtend}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prExtend}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prALetter}, // Lo GRANTHA OM + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prALetter}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prExtend}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prALetter}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prExtend}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prExtend}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prExtend}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prALetter}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x11450, 0x11459, prNumeric}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prALetter}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prALetter}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prExtend}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prExtend}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prExtend}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prExtend}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prALetter}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C7, 0x114C7, prALetter}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prNumeric}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prALetter}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prExtend}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prExtend}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prExtend}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115D8, 0x115DB, prALetter}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prALetter}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prExtend}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prExtend}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prExtend}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11644, 0x11644, prALetter}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prNumeric}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11680, 0x116AA, prALetter}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prExtend}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prExtend}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prExtend}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prALetter}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116C0, 0x116C9, prNumeric}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prExtend}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prExtend}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNumeric}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x11800, 0x1182B, prALetter}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prExtend}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prExtend}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x118A0, 0x118DF, prALetter}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNumeric}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118FF, 0x11906, prALetter}, // Lo [8] WARANG CITI OM..DIVES AKURU LETTER E + {0x11909, 0x11909, prALetter}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prALetter}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prALetter}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prALetter}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prExtend}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prExtend}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prExtend}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prALetter}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prExtend}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prALetter}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prExtend}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x11950, 0x11959, prNumeric}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prALetter}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prALetter}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prExtend}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prExtend}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prALetter}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E3, 0x119E3, prALetter}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prExtend}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prALetter}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prALetter}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prExtend}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prALetter}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prALetter}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prExtend}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prALetter}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prExtend}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9D, 0x11A9D, prALetter}, // Lo SOYOMBO MARK PLUTA + {0x11AB0, 0x11AF8, prALetter}, // Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL + {0x11C00, 0x11C08, prALetter}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prALetter}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prExtend}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prExtend}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prALetter}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C50, 0x11C59, prNumeric}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C72, 0x11C8F, prALetter}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prExtend}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prExtend}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prExtend}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prALetter}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prALetter}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prALetter}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prALetter}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNumeric}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prALetter}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prALetter}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prALetter}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prExtend}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prExtend}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prExtend}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prALetter}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNumeric}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prALetter}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prExtend}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prALetter}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prExtend}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prALetter}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prALetter}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prExtend}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prExtend}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prExtend}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x11F50, 0x11F59, prNumeric}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prALetter}, // Lo LISU LETTER YHA + {0x12000, 0x12399, prALetter}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prALetter}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12480, 0x12543, prALetter}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prALetter}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x13000, 0x1342F, prALetter}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prFormat}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prALetter}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prALetter}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prALetter}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prALetter}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNumeric}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A70, 0x16ABE, prALetter}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNumeric}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prALetter}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16B00, 0x16B2F, prALetter}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B40, 0x16B43, prALetter}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B50, 0x16B59, prNumeric}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B63, 0x16B77, prALetter}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prALetter}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prALetter}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16F00, 0x16F4A, prALetter}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prALetter}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prExtend}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prALetter}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prALetter}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE3, 0x16FE3, prALetter}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prExtend}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x1AFF0, 0x1AFF3, prKatakana}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prKatakana}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prKatakana}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B000, prKatakana}, // Lo KATAKANA LETTER ARCHAIC E + {0x1B120, 0x1B122, prKatakana}, // Lo [3] KATAKANA LETTER ARCHAIC YI..KATAKANA LETTER ARCHAIC WU + {0x1B155, 0x1B155, prKatakana}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prKatakana}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1BC00, 0x1BC6A, prALetter}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prALetter}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prALetter}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prALetter}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BCA0, 0x1BCA3, prFormat}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D166, prExtend}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D172, prExtend}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prFormat}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D400, 0x1D454, prALetter}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prALetter}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prALetter}, // L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prALetter}, // L& MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prALetter}, // L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prALetter}, // L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prALetter}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prALetter}, // L& MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prALetter}, // L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prALetter}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prALetter}, // L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prALetter}, // L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prALetter}, // L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prALetter}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prALetter}, // L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prALetter}, // L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prALetter}, // L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prALetter}, // L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prALetter}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prALetter}, // L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C2, 0x1D6DA, prALetter}, // L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DC, 0x1D6FA, prALetter}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FC, 0x1D714, prALetter}, // L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D716, 0x1D734, prALetter}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D736, 0x1D74E, prALetter}, // L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D750, 0x1D76E, prALetter}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D770, 0x1D788, prALetter}, // L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D78A, 0x1D7A8, prALetter}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7AA, 0x1D7C2, prALetter}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C4, 0x1D7CB, prALetter}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNumeric}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prALetter}, // L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prALetter}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prALetter}, // L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prALetter}, // L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prALetter}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prALetter}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prALetter}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNumeric}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prALetter}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E290, 0x1E2AD, prALetter}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prALetter}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNumeric}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E4D0, 0x1E4EA, prALetter}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prALetter}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNumeric}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prALetter}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prALetter}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prALetter}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prALetter}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prALetter}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prALetter}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNumeric}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1EE00, 0x1EE03, prALetter}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prALetter}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prALetter}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prALetter}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prALetter}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prALetter}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prALetter}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prALetter}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prALetter}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prALetter}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prALetter}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prALetter}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prALetter}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prALetter}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prALetter}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prALetter}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prALetter}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prALetter}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prALetter}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prALetter}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prALetter}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prALetter}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prALetter}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1F000, 0x1F003, prExtendedPictographic}, // E0.0 [4] (๐Ÿ€€..๐Ÿ€ƒ) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prExtendedPictographic}, // E0.6 [1] (๐Ÿ€„) mahjong red dragon + {0x1F005, 0x1F0CE, prExtendedPictographic}, // E0.0 [202] (๐Ÿ€…..๐ŸƒŽ) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prExtendedPictographic}, // E0.6 [1] (๐Ÿƒ) joker + {0x1F0D0, 0x1F0FF, prExtendedPictographic}, // E0.0 [48] (๐Ÿƒ..๐Ÿƒฟ) .. + {0x1F10D, 0x1F10F, prExtendedPictographic}, // E0.0 [3] (๐Ÿ„..๐Ÿ„) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F12F, 0x1F12F, prExtendedPictographic}, // E0.0 [1] (๐Ÿ„ฏ) COPYLEFT SYMBOL + {0x1F130, 0x1F149, prALetter}, // So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z + {0x1F150, 0x1F169, prALetter}, // So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16C, 0x1F16F, prExtendedPictographic}, // E0.0 [4] (๐Ÿ…ฌ..๐Ÿ…ฏ) RAISED MR SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F189, prALetter}, // So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z + {0x1F170, 0x1F171, prExtendedPictographic}, // E0.6 [2] (๐Ÿ…ฐ๏ธ..๐Ÿ…ฑ๏ธ) A button (blood type)..B button (blood type) + {0x1F17E, 0x1F17F, prExtendedPictographic}, // E0.6 [2] (๐Ÿ…พ๏ธ..๐Ÿ…ฟ๏ธ) O button (blood type)..P button + {0x1F18E, 0x1F18E, prExtendedPictographic}, // E0.6 [1] (๐Ÿ†Ž) AB button (blood type) + {0x1F191, 0x1F19A, prExtendedPictographic}, // E0.6 [10] (๐Ÿ†‘..๐Ÿ†š) CL button..VS button + {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // E0.0 [57] (๐Ÿ†ญ..๐Ÿ‡ฅ) MASK WORK SYMBOL.. + {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F201, 0x1F202, prExtendedPictographic}, // E0.6 [2] (๐Ÿˆ..๐Ÿˆ‚๏ธ) Japanese โ€œhereโ€ button..Japanese โ€œservice chargeโ€ button + {0x1F203, 0x1F20F, prExtendedPictographic}, // E0.0 [13] (๐Ÿˆƒ..๐Ÿˆ) .. + {0x1F21A, 0x1F21A, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆš) Japanese โ€œfree of chargeโ€ button + {0x1F22F, 0x1F22F, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆฏ) Japanese โ€œreservedโ€ button + {0x1F232, 0x1F23A, prExtendedPictographic}, // E0.6 [9] (๐Ÿˆฒ..๐Ÿˆบ) Japanese โ€œprohibitedโ€ button..Japanese โ€œopen for businessโ€ button + {0x1F23C, 0x1F23F, prExtendedPictographic}, // E0.0 [4] (๐Ÿˆผ..๐Ÿˆฟ) .. + {0x1F249, 0x1F24F, prExtendedPictographic}, // E0.0 [7] (๐Ÿ‰‰..๐Ÿ‰) .. + {0x1F250, 0x1F251, prExtendedPictographic}, // E0.6 [2] (๐Ÿ‰..๐Ÿ‰‘) Japanese โ€œbargainโ€ button..Japanese โ€œacceptableโ€ button + {0x1F252, 0x1F2FF, prExtendedPictographic}, // E0.0 [174] (๐Ÿ‰’..๐Ÿ‹ฟ) .. + {0x1F300, 0x1F30C, prExtendedPictographic}, // E0.6 [13] (๐ŸŒ€..๐ŸŒŒ) cyclone..milky way + {0x1F30D, 0x1F30E, prExtendedPictographic}, // E0.7 [2] (๐ŸŒ..๐ŸŒŽ) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ) globe showing Asia-Australia + {0x1F310, 0x1F310, prExtendedPictographic}, // E1.0 [1] (๐ŸŒ) globe with meridians + {0x1F311, 0x1F311, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ‘) new moon + {0x1F312, 0x1F312, prExtendedPictographic}, // E1.0 [1] (๐ŸŒ’) waxing crescent moon + {0x1F313, 0x1F315, prExtendedPictographic}, // E0.6 [3] (๐ŸŒ“..๐ŸŒ•) first quarter moon..full moon + {0x1F316, 0x1F318, prExtendedPictographic}, // E1.0 [3] (๐ŸŒ–..๐ŸŒ˜) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ™) crescent moon + {0x1F31A, 0x1F31A, prExtendedPictographic}, // E1.0 [1] (๐ŸŒš) new moon face + {0x1F31B, 0x1F31B, prExtendedPictographic}, // E0.6 [1] (๐ŸŒ›) first quarter moon face + {0x1F31C, 0x1F31C, prExtendedPictographic}, // E0.7 [1] (๐ŸŒœ) last quarter moon face + {0x1F31D, 0x1F31E, prExtendedPictographic}, // E1.0 [2] (๐ŸŒ..๐ŸŒž) full moon face..sun with face + {0x1F31F, 0x1F320, prExtendedPictographic}, // E0.6 [2] (๐ŸŒŸ..๐ŸŒ ) glowing star..shooting star + {0x1F321, 0x1F321, prExtendedPictographic}, // E0.7 [1] (๐ŸŒก๏ธ) thermometer + {0x1F322, 0x1F323, prExtendedPictographic}, // E0.0 [2] (๐ŸŒข..๐ŸŒฃ) BLACK DROPLET..WHITE SUN + {0x1F324, 0x1F32C, prExtendedPictographic}, // E0.7 [9] (๐ŸŒค๏ธ..๐ŸŒฌ๏ธ) sun behind small cloud..wind face + {0x1F32D, 0x1F32F, prExtendedPictographic}, // E1.0 [3] (๐ŸŒญ..๐ŸŒฏ) hot dog..burrito + {0x1F330, 0x1F331, prExtendedPictographic}, // E0.6 [2] (๐ŸŒฐ..๐ŸŒฑ) chestnut..seedling + {0x1F332, 0x1F333, prExtendedPictographic}, // E1.0 [2] (๐ŸŒฒ..๐ŸŒณ) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prExtendedPictographic}, // E0.6 [2] (๐ŸŒด..๐ŸŒต) palm tree..cactus + {0x1F336, 0x1F336, prExtendedPictographic}, // E0.7 [1] (๐ŸŒถ๏ธ) hot pepper + {0x1F337, 0x1F34A, prExtendedPictographic}, // E0.6 [20] (๐ŸŒท..๐ŸŠ) tulip..tangerine + {0x1F34B, 0x1F34B, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‹) lemon + {0x1F34C, 0x1F34F, prExtendedPictographic}, // E0.6 [4] (๐ŸŒ..๐Ÿ) banana..green apple + {0x1F350, 0x1F350, prExtendedPictographic}, // E1.0 [1] (๐Ÿ) pear + {0x1F351, 0x1F37B, prExtendedPictographic}, // E0.6 [43] (๐Ÿ‘..๐Ÿป) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prExtendedPictographic}, // E1.0 [1] (๐Ÿผ) baby bottle + {0x1F37D, 0x1F37D, prExtendedPictographic}, // E0.7 [1] (๐Ÿฝ๏ธ) fork and knife with plate + {0x1F37E, 0x1F37F, prExtendedPictographic}, // E1.0 [2] (๐Ÿพ..๐Ÿฟ) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prExtendedPictographic}, // E0.6 [20] (๐ŸŽ€..๐ŸŽ“) ribbon..graduation cap + {0x1F394, 0x1F395, prExtendedPictographic}, // E0.0 [2] (๐ŸŽ”..๐ŸŽ•) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS + {0x1F396, 0x1F397, prExtendedPictographic}, // E0.7 [2] (๐ŸŽ–๏ธ..๐ŸŽ—๏ธ) military medal..reminder ribbon + {0x1F398, 0x1F398, prExtendedPictographic}, // E0.0 [1] (๐ŸŽ˜) MUSICAL KEYBOARD WITH JACKS + {0x1F399, 0x1F39B, prExtendedPictographic}, // E0.7 [3] (๐ŸŽ™๏ธ..๐ŸŽ›๏ธ) studio microphone..control knobs + {0x1F39C, 0x1F39D, prExtendedPictographic}, // E0.0 [2] (๐ŸŽœ..๐ŸŽ) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F39F, prExtendedPictographic}, // E0.7 [2] (๐ŸŽž๏ธ..๐ŸŽŸ๏ธ) film frames..admission tickets + {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // E0.6 [37] (๐ŸŽ ..๐Ÿ„) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // E1.0 [1] (๐Ÿ…) sports medal + {0x1F3C6, 0x1F3C6, prExtendedPictographic}, // E0.6 [1] (๐Ÿ†) trophy + {0x1F3C7, 0x1F3C7, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‡) horse racing + {0x1F3C8, 0x1F3C8, prExtendedPictographic}, // E0.6 [1] (๐Ÿˆ) american football + {0x1F3C9, 0x1F3C9, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‰) rugby football + {0x1F3CA, 0x1F3CA, prExtendedPictographic}, // E0.6 [1] (๐ŸŠ) person swimming + {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // E0.7 [4] (๐Ÿ‹๏ธ..๐ŸŽ๏ธ) person lifting weights..racing car + {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // E1.0 [5] (๐Ÿ..๐Ÿ“) cricket game..ping pong + {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // E0.7 [12] (๐Ÿ”๏ธ..๐ŸŸ๏ธ) snow-capped mountain..stadium + {0x1F3E0, 0x1F3E3, prExtendedPictographic}, // E0.6 [4] (๐Ÿ ..๐Ÿฃ) house..Japanese post office + {0x1F3E4, 0x1F3E4, prExtendedPictographic}, // E1.0 [1] (๐Ÿค) post office + {0x1F3E5, 0x1F3F0, prExtendedPictographic}, // E0.6 [12] (๐Ÿฅ..๐Ÿฐ) hospital..castle + {0x1F3F1, 0x1F3F2, prExtendedPictographic}, // E0.0 [2] (๐Ÿฑ..๐Ÿฒ) WHITE PENNANT..BLACK PENNANT + {0x1F3F3, 0x1F3F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿณ๏ธ) white flag + {0x1F3F4, 0x1F3F4, prExtendedPictographic}, // E1.0 [1] (๐Ÿด) black flag + {0x1F3F5, 0x1F3F5, prExtendedPictographic}, // E0.7 [1] (๐Ÿต๏ธ) rosette + {0x1F3F6, 0x1F3F6, prExtendedPictographic}, // E0.0 [1] (๐Ÿถ) BLACK ROSETTE + {0x1F3F7, 0x1F3F7, prExtendedPictographic}, // E0.7 [1] (๐Ÿท๏ธ) label + {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // E1.0 [3] (๐Ÿธ..๐Ÿบ) badminton..amphora + {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F407, prExtendedPictographic}, // E1.0 [8] (๐Ÿ€..๐Ÿ‡) rat..rabbit + {0x1F408, 0x1F408, prExtendedPictographic}, // E0.7 [1] (๐Ÿˆ) cat + {0x1F409, 0x1F40B, prExtendedPictographic}, // E1.0 [3] (๐Ÿ‰..๐Ÿ‹) dragon..whale + {0x1F40C, 0x1F40E, prExtendedPictographic}, // E0.6 [3] (๐ŸŒ..๐ŸŽ) snail..horse + {0x1F40F, 0x1F410, prExtendedPictographic}, // E1.0 [2] (๐Ÿ..๐Ÿ) ram..goat + {0x1F411, 0x1F412, prExtendedPictographic}, // E0.6 [2] (๐Ÿ‘..๐Ÿ’) ewe..monkey + {0x1F413, 0x1F413, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“) rooster + {0x1F414, 0x1F414, prExtendedPictographic}, // E0.6 [1] (๐Ÿ”) chicken + {0x1F415, 0x1F415, prExtendedPictographic}, // E0.7 [1] (๐Ÿ•) dog + {0x1F416, 0x1F416, prExtendedPictographic}, // E1.0 [1] (๐Ÿ–) pig + {0x1F417, 0x1F429, prExtendedPictographic}, // E0.6 [19] (๐Ÿ—..๐Ÿฉ) boar..poodle + {0x1F42A, 0x1F42A, prExtendedPictographic}, // E1.0 [1] (๐Ÿช) camel + {0x1F42B, 0x1F43E, prExtendedPictographic}, // E0.6 [20] (๐Ÿซ..๐Ÿพ) two-hump camel..paw prints + {0x1F43F, 0x1F43F, prExtendedPictographic}, // E0.7 [1] (๐Ÿฟ๏ธ) chipmunk + {0x1F440, 0x1F440, prExtendedPictographic}, // E0.6 [1] (๐Ÿ‘€) eyes + {0x1F441, 0x1F441, prExtendedPictographic}, // E0.7 [1] (๐Ÿ‘๏ธ) eye + {0x1F442, 0x1F464, prExtendedPictographic}, // E0.6 [35] (๐Ÿ‘‚..๐Ÿ‘ค) ear..bust in silhouette + {0x1F465, 0x1F465, prExtendedPictographic}, // E1.0 [1] (๐Ÿ‘ฅ) busts in silhouette + {0x1F466, 0x1F46B, prExtendedPictographic}, // E0.6 [6] (๐Ÿ‘ฆ..๐Ÿ‘ซ) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prExtendedPictographic}, // E1.0 [2] (๐Ÿ‘ฌ..๐Ÿ‘ญ) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prExtendedPictographic}, // E0.6 [63] (๐Ÿ‘ฎ..๐Ÿ’ฌ) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prExtendedPictographic}, // E1.0 [1] (๐Ÿ’ญ) thought balloon + {0x1F4AE, 0x1F4B5, prExtendedPictographic}, // E0.6 [8] (๐Ÿ’ฎ..๐Ÿ’ต) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prExtendedPictographic}, // E1.0 [2] (๐Ÿ’ถ..๐Ÿ’ท) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prExtendedPictographic}, // E0.6 [52] (๐Ÿ’ธ..๐Ÿ“ซ) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prExtendedPictographic}, // E0.7 [2] (๐Ÿ“ฌ..๐Ÿ“ญ) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prExtendedPictographic}, // E0.6 [1] (๐Ÿ“ฎ) postbox + {0x1F4EF, 0x1F4EF, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ฏ) postal horn + {0x1F4F0, 0x1F4F4, prExtendedPictographic}, // E0.6 [5] (๐Ÿ“ฐ..๐Ÿ“ด) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ต) no mobile phones + {0x1F4F6, 0x1F4F7, prExtendedPictographic}, // E0.6 [2] (๐Ÿ“ถ..๐Ÿ“ท) antenna bars..camera + {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // E1.0 [1] (๐Ÿ“ธ) camera with flash + {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // E0.6 [4] (๐Ÿ“น..๐Ÿ“ผ) video camera..videocassette + {0x1F4FD, 0x1F4FD, prExtendedPictographic}, // E0.7 [1] (๐Ÿ“ฝ๏ธ) film projector + {0x1F4FE, 0x1F4FE, prExtendedPictographic}, // E0.0 [1] (๐Ÿ“พ) PORTABLE STEREO + {0x1F4FF, 0x1F502, prExtendedPictographic}, // E1.0 [4] (๐Ÿ“ฟ..๐Ÿ”‚) prayer beads..repeat single button + {0x1F503, 0x1F503, prExtendedPictographic}, // E0.6 [1] (๐Ÿ”ƒ) clockwise vertical arrows + {0x1F504, 0x1F507, prExtendedPictographic}, // E1.0 [4] (๐Ÿ”„..๐Ÿ”‡) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prExtendedPictographic}, // E0.7 [1] (๐Ÿ”ˆ) speaker low volume + {0x1F509, 0x1F509, prExtendedPictographic}, // E1.0 [1] (๐Ÿ”‰) speaker medium volume + {0x1F50A, 0x1F514, prExtendedPictographic}, // E0.6 [11] (๐Ÿ”Š..๐Ÿ””) speaker high volume..bell + {0x1F515, 0x1F515, prExtendedPictographic}, // E1.0 [1] (๐Ÿ”•) bell with slash + {0x1F516, 0x1F52B, prExtendedPictographic}, // E0.6 [22] (๐Ÿ”–..๐Ÿ”ซ) bookmark..water pistol + {0x1F52C, 0x1F52D, prExtendedPictographic}, // E1.0 [2] (๐Ÿ”ฌ..๐Ÿ”ญ) microscope..telescope + {0x1F52E, 0x1F53D, prExtendedPictographic}, // E0.6 [16] (๐Ÿ”ฎ..๐Ÿ”ฝ) crystal ball..downwards button + {0x1F546, 0x1F548, prExtendedPictographic}, // E0.0 [3] (๐Ÿ•†..๐Ÿ•ˆ) WHITE LATIN CROSS..CELTIC CROSS + {0x1F549, 0x1F54A, prExtendedPictographic}, // E0.7 [2] (๐Ÿ•‰๏ธ..๐Ÿ•Š๏ธ) om..dove + {0x1F54B, 0x1F54E, prExtendedPictographic}, // E1.0 [4] (๐Ÿ•‹..๐Ÿ•Ž) kaaba..menorah + {0x1F54F, 0x1F54F, prExtendedPictographic}, // E0.0 [1] (๐Ÿ•) BOWL OF HYGIEIA + {0x1F550, 0x1F55B, prExtendedPictographic}, // E0.6 [12] (๐Ÿ•..๐Ÿ•›) one oโ€™clock..twelve oโ€™clock + {0x1F55C, 0x1F567, prExtendedPictographic}, // E0.7 [12] (๐Ÿ•œ..๐Ÿ•ง) one-thirty..twelve-thirty + {0x1F568, 0x1F56E, prExtendedPictographic}, // E0.0 [7] (๐Ÿ•จ..๐Ÿ•ฎ) RIGHT SPEAKER..BOOK + {0x1F56F, 0x1F570, prExtendedPictographic}, // E0.7 [2] (๐Ÿ•ฏ๏ธ..๐Ÿ•ฐ๏ธ) candle..mantelpiece clock + {0x1F571, 0x1F572, prExtendedPictographic}, // E0.0 [2] (๐Ÿ•ฑ..๐Ÿ•ฒ) BLACK SKULL AND CROSSBONES..NO PIRACY + {0x1F573, 0x1F579, prExtendedPictographic}, // E0.7 [7] (๐Ÿ•ณ๏ธ..๐Ÿ•น๏ธ) hole..joystick + {0x1F57A, 0x1F57A, prExtendedPictographic}, // E3.0 [1] (๐Ÿ•บ) man dancing + {0x1F57B, 0x1F586, prExtendedPictographic}, // E0.0 [12] (๐Ÿ•ป..๐Ÿ–†) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE + {0x1F587, 0x1F587, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–‡๏ธ) linked paperclips + {0x1F588, 0x1F589, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–ˆ..๐Ÿ–‰) BLACK PUSHPIN..LOWER LEFT PENCIL + {0x1F58A, 0x1F58D, prExtendedPictographic}, // E0.7 [4] (๐Ÿ–Š๏ธ..๐Ÿ–๏ธ) pen..crayon + {0x1F58E, 0x1F58F, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–Ž..๐Ÿ–) LEFT WRITING HAND..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–๏ธ) hand with fingers splayed + {0x1F591, 0x1F594, prExtendedPictographic}, // E0.0 [4] (๐Ÿ–‘..๐Ÿ–”) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prExtendedPictographic}, // E1.0 [2] (๐Ÿ–•..๐Ÿ––) middle finger..vulcan salute + {0x1F597, 0x1F5A3, prExtendedPictographic}, // E0.0 [13] (๐Ÿ–—..๐Ÿ–ฃ) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // E3.0 [1] (๐Ÿ–ค) black heart + {0x1F5A5, 0x1F5A5, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–ฅ๏ธ) desktop computer + {0x1F5A6, 0x1F5A7, prExtendedPictographic}, // E0.0 [2] (๐Ÿ–ฆ..๐Ÿ–ง) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS + {0x1F5A8, 0x1F5A8, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–จ๏ธ) printer + {0x1F5A9, 0x1F5B0, prExtendedPictographic}, // E0.0 [8] (๐Ÿ–ฉ..๐Ÿ–ฐ) POCKET CALCULATOR..TWO BUTTON MOUSE + {0x1F5B1, 0x1F5B2, prExtendedPictographic}, // E0.7 [2] (๐Ÿ–ฑ๏ธ..๐Ÿ–ฒ๏ธ) computer mouse..trackball + {0x1F5B3, 0x1F5BB, prExtendedPictographic}, // E0.0 [9] (๐Ÿ–ณ..๐Ÿ–ป) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE + {0x1F5BC, 0x1F5BC, prExtendedPictographic}, // E0.7 [1] (๐Ÿ–ผ๏ธ) framed picture + {0x1F5BD, 0x1F5C1, prExtendedPictographic}, // E0.0 [5] (๐Ÿ–ฝ..๐Ÿ—) FRAME WITH TILES..OPEN FOLDER + {0x1F5C2, 0x1F5C4, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—‚๏ธ..๐Ÿ—„๏ธ) card index dividers..file cabinet + {0x1F5C5, 0x1F5D0, prExtendedPictographic}, // E0.0 [12] (๐Ÿ—…..๐Ÿ—) EMPTY NOTE..PAGES + {0x1F5D1, 0x1F5D3, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—‘๏ธ..๐Ÿ—“๏ธ) wastebasket..spiral calendar + {0x1F5D4, 0x1F5DB, prExtendedPictographic}, // E0.0 [8] (๐Ÿ—”..๐Ÿ—›) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5DE, prExtendedPictographic}, // E0.7 [3] (๐Ÿ—œ๏ธ..๐Ÿ—ž๏ธ) clamp..rolled-up newspaper + {0x1F5DF, 0x1F5E0, prExtendedPictographic}, // E0.0 [2] (๐Ÿ—Ÿ..๐Ÿ— ) PAGE WITH CIRCLED TEXT..STOCK CHART + {0x1F5E1, 0x1F5E1, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ก๏ธ) dagger + {0x1F5E2, 0x1F5E2, prExtendedPictographic}, // E0.0 [1] (๐Ÿ—ข) LIPS + {0x1F5E3, 0x1F5E3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ฃ๏ธ) speaking head + {0x1F5E4, 0x1F5E7, prExtendedPictographic}, // E0.0 [4] (๐Ÿ—ค..๐Ÿ—ง) THREE RAYS ABOVE..THREE RAYS RIGHT + {0x1F5E8, 0x1F5E8, prExtendedPictographic}, // E2.0 [1] (๐Ÿ—จ๏ธ) left speech bubble + {0x1F5E9, 0x1F5EE, prExtendedPictographic}, // E0.0 [6] (๐Ÿ—ฉ..๐Ÿ—ฎ) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE + {0x1F5EF, 0x1F5EF, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ฏ๏ธ) right anger bubble + {0x1F5F0, 0x1F5F2, prExtendedPictographic}, // E0.0 [3] (๐Ÿ—ฐ..๐Ÿ—ฒ) MOOD BUBBLE..LIGHTNING MOOD + {0x1F5F3, 0x1F5F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—ณ๏ธ) ballot box with ballot + {0x1F5F4, 0x1F5F9, prExtendedPictographic}, // E0.0 [6] (๐Ÿ—ด..๐Ÿ—น) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FA, prExtendedPictographic}, // E0.7 [1] (๐Ÿ—บ๏ธ) world map + {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // E0.6 [5] (๐Ÿ—ป..๐Ÿ—ฟ) mount fuji..moai + {0x1F600, 0x1F600, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜€) grinning face + {0x1F601, 0x1F606, prExtendedPictographic}, // E0.6 [6] (๐Ÿ˜..๐Ÿ˜†) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜‡..๐Ÿ˜ˆ) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prExtendedPictographic}, // E0.6 [5] (๐Ÿ˜‰..๐Ÿ˜) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜Ž) smiling face with sunglasses + {0x1F60F, 0x1F60F, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜) smirking face + {0x1F610, 0x1F610, prExtendedPictographic}, // E0.7 [1] (๐Ÿ˜) neutral face + {0x1F611, 0x1F611, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜‘) expressionless face + {0x1F612, 0x1F614, prExtendedPictographic}, // E0.6 [3] (๐Ÿ˜’..๐Ÿ˜”) unamused face..pensive face + {0x1F615, 0x1F615, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜•) confused face + {0x1F616, 0x1F616, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜–) confounded face + {0x1F617, 0x1F617, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜—) kissing face + {0x1F618, 0x1F618, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜˜) face blowing a kiss + {0x1F619, 0x1F619, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜™) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜š) kissing face with closed eyes + {0x1F61B, 0x1F61B, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜›) face with tongue + {0x1F61C, 0x1F61E, prExtendedPictographic}, // E0.6 [3] (๐Ÿ˜œ..๐Ÿ˜ž) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜Ÿ) worried face + {0x1F620, 0x1F625, prExtendedPictographic}, // E0.6 [6] (๐Ÿ˜ ..๐Ÿ˜ฅ) angry face..sad but relieved face + {0x1F626, 0x1F627, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜ฆ..๐Ÿ˜ง) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prExtendedPictographic}, // E0.6 [4] (๐Ÿ˜จ..๐Ÿ˜ซ) fearful face..tired face + {0x1F62C, 0x1F62C, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ฌ) grimacing face + {0x1F62D, 0x1F62D, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜ญ) loudly crying face + {0x1F62E, 0x1F62F, prExtendedPictographic}, // E1.0 [2] (๐Ÿ˜ฎ..๐Ÿ˜ฏ) face with open mouth..hushed face + {0x1F630, 0x1F633, prExtendedPictographic}, // E0.6 [4] (๐Ÿ˜ฐ..๐Ÿ˜ณ) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ด) sleeping face + {0x1F635, 0x1F635, prExtendedPictographic}, // E0.6 [1] (๐Ÿ˜ต) face with crossed-out eyes + {0x1F636, 0x1F636, prExtendedPictographic}, // E1.0 [1] (๐Ÿ˜ถ) face without mouth + {0x1F637, 0x1F640, prExtendedPictographic}, // E0.6 [10] (๐Ÿ˜ท..๐Ÿ™€) face with medical mask..weary cat + {0x1F641, 0x1F644, prExtendedPictographic}, // E1.0 [4] (๐Ÿ™..๐Ÿ™„) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prExtendedPictographic}, // E0.6 [11] (๐Ÿ™…..๐Ÿ™) person gesturing NO..folded hands + {0x1F680, 0x1F680, prExtendedPictographic}, // E0.6 [1] (๐Ÿš€) rocket + {0x1F681, 0x1F682, prExtendedPictographic}, // E1.0 [2] (๐Ÿš..๐Ÿš‚) helicopter..locomotive + {0x1F683, 0x1F685, prExtendedPictographic}, // E0.6 [3] (๐Ÿšƒ..๐Ÿš…) railway car..bullet train + {0x1F686, 0x1F686, prExtendedPictographic}, // E1.0 [1] (๐Ÿš†) train + {0x1F687, 0x1F687, prExtendedPictographic}, // E0.6 [1] (๐Ÿš‡) metro + {0x1F688, 0x1F688, prExtendedPictographic}, // E1.0 [1] (๐Ÿšˆ) light rail + {0x1F689, 0x1F689, prExtendedPictographic}, // E0.6 [1] (๐Ÿš‰) station + {0x1F68A, 0x1F68B, prExtendedPictographic}, // E1.0 [2] (๐ŸšŠ..๐Ÿš‹) tram..tram car + {0x1F68C, 0x1F68C, prExtendedPictographic}, // E0.6 [1] (๐ŸšŒ) bus + {0x1F68D, 0x1F68D, prExtendedPictographic}, // E0.7 [1] (๐Ÿš) oncoming bus + {0x1F68E, 0x1F68E, prExtendedPictographic}, // E1.0 [1] (๐ŸšŽ) trolleybus + {0x1F68F, 0x1F68F, prExtendedPictographic}, // E0.6 [1] (๐Ÿš) bus stop + {0x1F690, 0x1F690, prExtendedPictographic}, // E1.0 [1] (๐Ÿš) minibus + {0x1F691, 0x1F693, prExtendedPictographic}, // E0.6 [3] (๐Ÿš‘..๐Ÿš“) ambulance..police car + {0x1F694, 0x1F694, prExtendedPictographic}, // E0.7 [1] (๐Ÿš”) oncoming police car + {0x1F695, 0x1F695, prExtendedPictographic}, // E0.6 [1] (๐Ÿš•) taxi + {0x1F696, 0x1F696, prExtendedPictographic}, // E1.0 [1] (๐Ÿš–) oncoming taxi + {0x1F697, 0x1F697, prExtendedPictographic}, // E0.6 [1] (๐Ÿš—) automobile + {0x1F698, 0x1F698, prExtendedPictographic}, // E0.7 [1] (๐Ÿš˜) oncoming automobile + {0x1F699, 0x1F69A, prExtendedPictographic}, // E0.6 [2] (๐Ÿš™..๐Ÿšš) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prExtendedPictographic}, // E1.0 [7] (๐Ÿš›..๐Ÿšก) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prExtendedPictographic}, // E0.6 [1] (๐Ÿšข) ship + {0x1F6A3, 0x1F6A3, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฃ) person rowing boat + {0x1F6A4, 0x1F6A5, prExtendedPictographic}, // E0.6 [2] (๐Ÿšค..๐Ÿšฅ) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฆ) vertical traffic light + {0x1F6A7, 0x1F6AD, prExtendedPictographic}, // E0.6 [7] (๐Ÿšง..๐Ÿšญ) construction..no smoking + {0x1F6AE, 0x1F6B1, prExtendedPictographic}, // E1.0 [4] (๐Ÿšฎ..๐Ÿšฑ) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prExtendedPictographic}, // E0.6 [1] (๐Ÿšฒ) bicycle + {0x1F6B3, 0x1F6B5, prExtendedPictographic}, // E1.0 [3] (๐Ÿšณ..๐Ÿšต) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prExtendedPictographic}, // E0.6 [1] (๐Ÿšถ) person walking + {0x1F6B7, 0x1F6B8, prExtendedPictographic}, // E1.0 [2] (๐Ÿšท..๐Ÿšธ) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prExtendedPictographic}, // E0.6 [6] (๐Ÿšน..๐Ÿšพ) menโ€™s room..water closet + {0x1F6BF, 0x1F6BF, prExtendedPictographic}, // E1.0 [1] (๐Ÿšฟ) shower + {0x1F6C0, 0x1F6C0, prExtendedPictographic}, // E0.6 [1] (๐Ÿ›€) person taking bath + {0x1F6C1, 0x1F6C5, prExtendedPictographic}, // E1.0 [5] (๐Ÿ›..๐Ÿ›…) bathtub..left luggage + {0x1F6C6, 0x1F6CA, prExtendedPictographic}, // E0.0 [5] (๐Ÿ›†..๐Ÿ›Š) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL + {0x1F6CB, 0x1F6CB, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›‹๏ธ) couch and lamp + {0x1F6CC, 0x1F6CC, prExtendedPictographic}, // E1.0 [1] (๐Ÿ›Œ) person in bed + {0x1F6CD, 0x1F6CF, prExtendedPictographic}, // E0.7 [3] (๐Ÿ›๏ธ..๐Ÿ›๏ธ) shopping bags..bed + {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // E1.0 [1] (๐Ÿ›) place of worship + {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // E3.0 [2] (๐Ÿ›‘..๐Ÿ›’) stop sign..shopping cart + {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // E0.0 [2] (๐Ÿ›“..๐Ÿ›”) STUPA..PAGODA + {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // E12.0 [1] (๐Ÿ›•) hindu temple + {0x1F6D6, 0x1F6D7, prExtendedPictographic}, // E13.0 [2] (๐Ÿ›–..๐Ÿ›—) hut..elevator + {0x1F6D8, 0x1F6DB, prExtendedPictographic}, // E0.0 [4] (๐Ÿ›˜..๐Ÿ››) .. + {0x1F6DC, 0x1F6DC, prExtendedPictographic}, // E15.0 [1] (๐Ÿ›œ) wireless + {0x1F6DD, 0x1F6DF, prExtendedPictographic}, // E14.0 [3] (๐Ÿ›..๐Ÿ›Ÿ) playground slide..ring buoy + {0x1F6E0, 0x1F6E5, prExtendedPictographic}, // E0.7 [6] (๐Ÿ› ๏ธ..๐Ÿ›ฅ๏ธ) hammer and wrench..motor boat + {0x1F6E6, 0x1F6E8, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ฆ..๐Ÿ›จ) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE + {0x1F6E9, 0x1F6E9, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ฉ๏ธ) small airplane + {0x1F6EA, 0x1F6EA, prExtendedPictographic}, // E0.0 [1] (๐Ÿ›ช) NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prExtendedPictographic}, // E1.0 [2] (๐Ÿ›ซ..๐Ÿ›ฌ) airplane departure..airplane arrival + {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ญ..๐Ÿ›ฏ) .. + {0x1F6F0, 0x1F6F0, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ฐ๏ธ) satellite + {0x1F6F1, 0x1F6F2, prExtendedPictographic}, // E0.0 [2] (๐Ÿ›ฑ..๐Ÿ›ฒ) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE + {0x1F6F3, 0x1F6F3, prExtendedPictographic}, // E0.7 [1] (๐Ÿ›ณ๏ธ) passenger ship + {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // E3.0 [3] (๐Ÿ›ด..๐Ÿ›ถ) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // E5.0 [2] (๐Ÿ›ท..๐Ÿ›ธ) sled..flying saucer + {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // E11.0 [1] (๐Ÿ›น) skateboard + {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // E12.0 [1] (๐Ÿ›บ) auto rickshaw + {0x1F6FB, 0x1F6FC, prExtendedPictographic}, // E13.0 [2] (๐Ÿ›ป..๐Ÿ›ผ) pickup truck..roller skate + {0x1F6FD, 0x1F6FF, prExtendedPictographic}, // E0.0 [3] (๐Ÿ›ฝ..๐Ÿ›ฟ) .. + {0x1F774, 0x1F77F, prExtendedPictographic}, // E0.0 [12] (๐Ÿด..๐Ÿฟ) LOT OF FORTUNE..ORCUS + {0x1F7D5, 0x1F7DF, prExtendedPictographic}, // E0.0 [11] (๐ŸŸ•..๐ŸŸŸ) CIRCLED TRIANGLE.. + {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // E12.0 [12] (๐ŸŸ ..๐ŸŸซ) orange circle..brown square + {0x1F7EC, 0x1F7EF, prExtendedPictographic}, // E0.0 [4] (๐ŸŸฌ..๐ŸŸฏ) .. + {0x1F7F0, 0x1F7F0, prExtendedPictographic}, // E14.0 [1] (๐ŸŸฐ) heavy equals sign + {0x1F7F1, 0x1F7FF, prExtendedPictographic}, // E0.0 [15] (๐ŸŸฑ..๐ŸŸฟ) .. + {0x1F80C, 0x1F80F, prExtendedPictographic}, // E0.0 [4] (๐Ÿ Œ..๐Ÿ ) .. + {0x1F848, 0x1F84F, prExtendedPictographic}, // E0.0 [8] (๐Ÿกˆ..๐Ÿก) .. + {0x1F85A, 0x1F85F, prExtendedPictographic}, // E0.0 [6] (๐Ÿกš..๐ŸกŸ) .. + {0x1F888, 0x1F88F, prExtendedPictographic}, // E0.0 [8] (๐Ÿขˆ..๐Ÿข) .. + {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // E0.0 [82] (๐Ÿขฎ..๐Ÿฃฟ) .. + {0x1F90C, 0x1F90C, prExtendedPictographic}, // E13.0 [1] (๐ŸคŒ) pinched fingers + {0x1F90D, 0x1F90F, prExtendedPictographic}, // E12.0 [3] (๐Ÿค..๐Ÿค) white heart..pinching hand + {0x1F910, 0x1F918, prExtendedPictographic}, // E1.0 [9] (๐Ÿค..๐Ÿค˜) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prExtendedPictographic}, // E3.0 [6] (๐Ÿค™..๐Ÿคž) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prExtendedPictographic}, // E5.0 [1] (๐ŸคŸ) love-you gesture + {0x1F920, 0x1F927, prExtendedPictographic}, // E3.0 [8] (๐Ÿค ..๐Ÿคง) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prExtendedPictographic}, // E5.0 [8] (๐Ÿคจ..๐Ÿคฏ) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prExtendedPictographic}, // E3.0 [1] (๐Ÿคฐ) pregnant woman + {0x1F931, 0x1F932, prExtendedPictographic}, // E5.0 [2] (๐Ÿคฑ..๐Ÿคฒ) breast-feeding..palms up together + {0x1F933, 0x1F93A, prExtendedPictographic}, // E3.0 [8] (๐Ÿคณ..๐Ÿคบ) selfie..person fencing + {0x1F93C, 0x1F93E, prExtendedPictographic}, // E3.0 [3] (๐Ÿคผ..๐Ÿคพ) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prExtendedPictographic}, // E12.0 [1] (๐Ÿคฟ) diving mask + {0x1F940, 0x1F945, prExtendedPictographic}, // E3.0 [6] (๐Ÿฅ€..๐Ÿฅ…) wilted flower..goal net + {0x1F947, 0x1F94B, prExtendedPictographic}, // E3.0 [5] (๐Ÿฅ‡..๐Ÿฅ‹) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prExtendedPictographic}, // E5.0 [1] (๐ŸฅŒ) curling stone + {0x1F94D, 0x1F94F, prExtendedPictographic}, // E11.0 [3] (๐Ÿฅ..๐Ÿฅ) lacrosse..flying disc + {0x1F950, 0x1F95E, prExtendedPictographic}, // E3.0 [15] (๐Ÿฅ..๐Ÿฅž) croissant..pancakes + {0x1F95F, 0x1F96B, prExtendedPictographic}, // E5.0 [13] (๐ŸฅŸ..๐Ÿฅซ) dumpling..canned food + {0x1F96C, 0x1F970, prExtendedPictographic}, // E11.0 [5] (๐Ÿฅฌ..๐Ÿฅฐ) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prExtendedPictographic}, // E12.0 [1] (๐Ÿฅฑ) yawning face + {0x1F972, 0x1F972, prExtendedPictographic}, // E13.0 [1] (๐Ÿฅฒ) smiling face with tear + {0x1F973, 0x1F976, prExtendedPictographic}, // E11.0 [4] (๐Ÿฅณ..๐Ÿฅถ) partying face..cold face + {0x1F977, 0x1F978, prExtendedPictographic}, // E13.0 [2] (๐Ÿฅท..๐Ÿฅธ) ninja..disguised face + {0x1F979, 0x1F979, prExtendedPictographic}, // E14.0 [1] (๐Ÿฅน) face holding back tears + {0x1F97A, 0x1F97A, prExtendedPictographic}, // E11.0 [1] (๐Ÿฅบ) pleading face + {0x1F97B, 0x1F97B, prExtendedPictographic}, // E12.0 [1] (๐Ÿฅป) sari + {0x1F97C, 0x1F97F, prExtendedPictographic}, // E11.0 [4] (๐Ÿฅผ..๐Ÿฅฟ) lab coat..flat shoe + {0x1F980, 0x1F984, prExtendedPictographic}, // E1.0 [5] (๐Ÿฆ€..๐Ÿฆ„) crab..unicorn + {0x1F985, 0x1F991, prExtendedPictographic}, // E3.0 [13] (๐Ÿฆ…..๐Ÿฆ‘) eagle..squid + {0x1F992, 0x1F997, prExtendedPictographic}, // E5.0 [6] (๐Ÿฆ’..๐Ÿฆ—) giraffe..cricket + {0x1F998, 0x1F9A2, prExtendedPictographic}, // E11.0 [11] (๐Ÿฆ˜..๐Ÿฆข) kangaroo..swan + {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // E13.0 [2] (๐Ÿฆฃ..๐Ÿฆค) mammoth..dodo + {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // E12.0 [6] (๐Ÿฆฅ..๐Ÿฆช) sloth..oyster + {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // E13.0 [3] (๐Ÿฆซ..๐Ÿฆญ) beaver..seal + {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // E12.0 [2] (๐Ÿฆฎ..๐Ÿฆฏ) guide dog..white cane + {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // E11.0 [10] (๐Ÿฆฐ..๐Ÿฆน) red hair..supervillain + {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // E12.0 [6] (๐Ÿฆบ..๐Ÿฆฟ) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // E1.0 [1] (๐Ÿง€) cheese wedge + {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // E11.0 [2] (๐Ÿง..๐Ÿง‚) cupcake..salt + {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // E12.0 [8] (๐Ÿงƒ..๐ŸงŠ) beverage box..ice + {0x1F9CB, 0x1F9CB, prExtendedPictographic}, // E13.0 [1] (๐Ÿง‹) bubble tea + {0x1F9CC, 0x1F9CC, prExtendedPictographic}, // E14.0 [1] (๐ŸงŒ) troll + {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // E12.0 [3] (๐Ÿง..๐Ÿง) person standing..deaf person + {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // E5.0 [23] (๐Ÿง..๐Ÿงฆ) face with monocle..socks + {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // E11.0 [25] (๐Ÿงง..๐Ÿงฟ) red envelope..nazar amulet + {0x1FA00, 0x1FA6F, prExtendedPictographic}, // E0.0 [112] (๐Ÿจ€..๐Ÿฉฏ) NEUTRAL CHESS KING.. + {0x1FA70, 0x1FA73, prExtendedPictographic}, // E12.0 [4] (๐Ÿฉฐ..๐Ÿฉณ) ballet shoes..shorts + {0x1FA74, 0x1FA74, prExtendedPictographic}, // E13.0 [1] (๐Ÿฉด) thong sandal + {0x1FA75, 0x1FA77, prExtendedPictographic}, // E15.0 [3] (๐Ÿฉต..๐Ÿฉท) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prExtendedPictographic}, // E12.0 [3] (๐Ÿฉธ..๐Ÿฉบ) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prExtendedPictographic}, // E14.0 [2] (๐Ÿฉป..๐Ÿฉผ) x-ray..crutch + {0x1FA7D, 0x1FA7F, prExtendedPictographic}, // E0.0 [3] (๐Ÿฉฝ..๐Ÿฉฟ) .. + {0x1FA80, 0x1FA82, prExtendedPictographic}, // E12.0 [3] (๐Ÿช€..๐Ÿช‚) yo-yo..parachute + {0x1FA83, 0x1FA86, prExtendedPictographic}, // E13.0 [4] (๐Ÿชƒ..๐Ÿช†) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prExtendedPictographic}, // E15.0 [2] (๐Ÿช‡..๐Ÿชˆ) maracas..flute + {0x1FA89, 0x1FA8F, prExtendedPictographic}, // E0.0 [7] (๐Ÿช‰..๐Ÿช) .. + {0x1FA90, 0x1FA95, prExtendedPictographic}, // E12.0 [6] (๐Ÿช..๐Ÿช•) ringed planet..banjo + {0x1FA96, 0x1FAA8, prExtendedPictographic}, // E13.0 [19] (๐Ÿช–..๐Ÿชจ) military helmet..rock + {0x1FAA9, 0x1FAAC, prExtendedPictographic}, // E14.0 [4] (๐Ÿชฉ..๐Ÿชฌ) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prExtendedPictographic}, // E15.0 [3] (๐Ÿชญ..๐Ÿชฏ) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prExtendedPictographic}, // E13.0 [7] (๐Ÿชฐ..๐Ÿชถ) fly..feather + {0x1FAB7, 0x1FABA, prExtendedPictographic}, // E14.0 [4] (๐Ÿชท..๐Ÿชบ) lotus..nest with eggs + {0x1FABB, 0x1FABD, prExtendedPictographic}, // E15.0 [3] (๐Ÿชป..๐Ÿชฝ) hyacinth..wing + {0x1FABE, 0x1FABE, prExtendedPictographic}, // E0.0 [1] (๐Ÿชพ) + {0x1FABF, 0x1FABF, prExtendedPictographic}, // E15.0 [1] (๐Ÿชฟ) goose + {0x1FAC0, 0x1FAC2, prExtendedPictographic}, // E13.0 [3] (๐Ÿซ€..๐Ÿซ‚) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prExtendedPictographic}, // E14.0 [3] (๐Ÿซƒ..๐Ÿซ…) pregnant man..person with crown + {0x1FAC6, 0x1FACD, prExtendedPictographic}, // E0.0 [8] (๐Ÿซ†..๐Ÿซ) .. + {0x1FACE, 0x1FACF, prExtendedPictographic}, // E15.0 [2] (๐ŸซŽ..๐Ÿซ) moose..donkey + {0x1FAD0, 0x1FAD6, prExtendedPictographic}, // E13.0 [7] (๐Ÿซ..๐Ÿซ–) blueberries..teapot + {0x1FAD7, 0x1FAD9, prExtendedPictographic}, // E14.0 [3] (๐Ÿซ—..๐Ÿซ™) pouring liquid..jar + {0x1FADA, 0x1FADB, prExtendedPictographic}, // E15.0 [2] (๐Ÿซš..๐Ÿซ›) ginger root..pea pod + {0x1FADC, 0x1FADF, prExtendedPictographic}, // E0.0 [4] (๐Ÿซœ..๐ŸซŸ) .. + {0x1FAE0, 0x1FAE7, prExtendedPictographic}, // E14.0 [8] (๐Ÿซ ..๐Ÿซง) melting face..bubbles + {0x1FAE8, 0x1FAE8, prExtendedPictographic}, // E15.0 [1] (๐Ÿซจ) shaking face + {0x1FAE9, 0x1FAEF, prExtendedPictographic}, // E0.0 [7] (๐Ÿซฉ..๐Ÿซฏ) .. + {0x1FAF0, 0x1FAF6, prExtendedPictographic}, // E14.0 [7] (๐Ÿซฐ..๐Ÿซถ) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prExtendedPictographic}, // E15.0 [2] (๐Ÿซท..๐Ÿซธ) leftwards pushing hand..rightwards pushing hand + {0x1FAF9, 0x1FAFF, prExtendedPictographic}, // E0.0 [7] (๐Ÿซน..๐Ÿซฟ) .. + {0x1FBF0, 0x1FBF9, prNumeric}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x1FC00, 0x1FFFD, prExtendedPictographic}, // E0.0[1022] (๐Ÿฐ€..๐Ÿฟฝ) .. + {0xE0001, 0xE0001, prFormat}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 +} diff --git a/vendor/github.com/rivo/uniseg/wordrules.go b/vendor/github.com/rivo/uniseg/wordrules.go new file mode 100644 index 000000000000..57a8c683116d --- /dev/null +++ b/vendor/github.com/rivo/uniseg/wordrules.go @@ -0,0 +1,282 @@ +package uniseg + +import "unicode/utf8" + +// The states of the word break parser. +const ( + wbAny = iota + wbCR + wbLF + wbNewline + wbWSegSpace + wbHebrewLetter + wbALetter + wbWB7 + wbWB7c + wbNumeric + wbWB11 + wbKatakana + wbExtendNumLet + wbOddRI + wbEvenRI + wbZWJBit = 16 // This bit is set for any states followed by at least one zero-width joiner (see WB4 and WB3c). +) + +// wbTransitions implements the word break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func wbTransitions(state, prop int) (newState int, wordBreak bool, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // WB3b. + case wbAny | prNewline<<32: + return wbNewline, true, 32 + case wbAny | prCR<<32: + return wbCR, true, 32 + case wbAny | prLF<<32: + return wbLF, true, 32 + + // WB3a. + case wbNewline | prAny<<32: + return wbAny, true, 31 + case wbCR | prAny<<32: + return wbAny, true, 31 + case wbLF | prAny<<32: + return wbAny, true, 31 + + // WB3. + case wbCR | prLF<<32: + return wbLF, false, 30 + + // WB3d. + case wbAny | prWSegSpace<<32: + return wbWSegSpace, true, 9990 + case wbWSegSpace | prWSegSpace<<32: + return wbWSegSpace, false, 34 + + // WB5. + case wbAny | prALetter<<32: + return wbALetter, true, 9990 + case wbAny | prHebrewLetter<<32: + return wbHebrewLetter, true, 9990 + case wbALetter | prALetter<<32: + return wbALetter, false, 50 + case wbALetter | prHebrewLetter<<32: + return wbHebrewLetter, false, 50 + case wbHebrewLetter | prALetter<<32: + return wbALetter, false, 50 + case wbHebrewLetter | prHebrewLetter<<32: + return wbHebrewLetter, false, 50 + + // WB7. Transitions to wbWB7 handled by transitionWordBreakState(). + case wbWB7 | prALetter<<32: + return wbALetter, false, 70 + case wbWB7 | prHebrewLetter<<32: + return wbHebrewLetter, false, 70 + + // WB7a. + case wbHebrewLetter | prSingleQuote<<32: + return wbAny, false, 71 + + // WB7c. Transitions to wbWB7c handled by transitionWordBreakState(). + case wbWB7c | prHebrewLetter<<32: + return wbHebrewLetter, false, 73 + + // WB8. + case wbAny | prNumeric<<32: + return wbNumeric, true, 9990 + case wbNumeric | prNumeric<<32: + return wbNumeric, false, 80 + + // WB9. + case wbALetter | prNumeric<<32: + return wbNumeric, false, 90 + case wbHebrewLetter | prNumeric<<32: + return wbNumeric, false, 90 + + // WB10. + case wbNumeric | prALetter<<32: + return wbALetter, false, 100 + case wbNumeric | prHebrewLetter<<32: + return wbHebrewLetter, false, 100 + + // WB11. Transitions to wbWB11 handled by transitionWordBreakState(). + case wbWB11 | prNumeric<<32: + return wbNumeric, false, 110 + + // WB13. + case wbAny | prKatakana<<32: + return wbKatakana, true, 9990 + case wbKatakana | prKatakana<<32: + return wbKatakana, false, 130 + + // WB13a. + case wbAny | prExtendNumLet<<32: + return wbExtendNumLet, true, 9990 + case wbALetter | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbHebrewLetter | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbNumeric | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbKatakana | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbExtendNumLet | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + + // WB13b. + case wbExtendNumLet | prALetter<<32: + return wbALetter, false, 132 + case wbExtendNumLet | prHebrewLetter<<32: + return wbHebrewLetter, false, 132 + case wbExtendNumLet | prNumeric<<32: + return wbNumeric, false, 132 + case wbExtendNumLet | prKatakana<<32: + return wbKatakana, false, 132 + + default: + return -1, false, -1 + } +} + +// transitionWordBreakState determines the new state of the word break parser +// given the current state and the next code point. It also returns whether a +// word boundary was detected. If more than one code point is needed to +// determine the new state, the byte slice or the string starting after rune "r" +// can be used (whichever is not nil or empty) for further lookups. +func transitionWordBreakState(state int, r rune, b []byte, str string) (newState int, wordBreak bool) { + // Determine the property of the next character. + nextProperty := property(workBreakCodePoints, r) + + // "Replacing Ignore Rules". + if nextProperty == prZWJ { + // WB4 (for zero-width joiners). + if state == wbNewline || state == wbCR || state == wbLF { + return wbAny | wbZWJBit, true // Make sure we don't apply WB4 to WB3a. + } + if state < 0 { + return wbAny | wbZWJBit, false + } + return state | wbZWJBit, false + } else if nextProperty == prExtend || nextProperty == prFormat { + // WB4 (for Extend and Format). + if state == wbNewline || state == wbCR || state == wbLF { + return wbAny, true // Make sure we don't apply WB4 to WB3a. + } + if state == wbWSegSpace || state == wbAny|wbZWJBit { + return wbAny, false // We don't break but this is also not WB3d or WB3c. + } + if state < 0 { + return wbAny, false + } + return state, false + } else if nextProperty == prExtendedPictographic && state >= 0 && state&wbZWJBit != 0 { + // WB3c. + return wbAny, false + } + if state >= 0 { + state = state &^ wbZWJBit + } + + // Find the applicable transition in the table. + var rule int + newState, wordBreak, rule = wbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropState, anyPropWordBreak, anyPropRule := wbTransitions(state, prAny) + anyStateState, anyStateWordBreak, anyStateRule := wbTransitions(wbAny, nextProperty) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule + if anyPropRule < anyStateRule { + wordBreak, rule = anyPropWordBreak, anyPropRule + } + } else if anyPropState >= 0 { + // We only have a specific state. + newState, wordBreak, rule = anyPropState, anyPropWordBreak, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateState >= 0 { + // We only have a specific property. + newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule + } else { + // No known transition. WB999: Any รท Any. + newState, wordBreak, rule = wbAny, true, 9990 + } + } + + // For those rules that need to look up runes further in the string, we + // determine the property after nextProperty, skipping over Format, Extend, + // and ZWJ (according to WB4). It's -1 if not needed, if such a rune cannot + // be determined (because the text ends or the rune is faulty). + farProperty := -1 + if rule > 60 && + (state == wbALetter || state == wbHebrewLetter || state == wbNumeric) && + (nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote || // WB6. + nextProperty == prDoubleQuote || // WB7b. + nextProperty == prMidNum) { // WB12. + for { + var ( + r rune + length int + ) + if b != nil { // Byte slice version. + r, length = utf8.DecodeRune(b) + b = b[length:] + } else { // String version. + r, length = utf8.DecodeRuneInString(str) + str = str[length:] + } + if r == utf8.RuneError { + break + } + prop := property(workBreakCodePoints, r) + if prop == prExtend || prop == prFormat || prop == prZWJ { + continue + } + farProperty = prop + break + } + } + + // WB6. + if rule > 60 && + (state == wbALetter || state == wbHebrewLetter) && + (nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote) && + (farProperty == prALetter || farProperty == prHebrewLetter) { + return wbWB7, false + } + + // WB7b. + if rule > 72 && + state == wbHebrewLetter && + nextProperty == prDoubleQuote && + farProperty == prHebrewLetter { + return wbWB7c, false + } + + // WB12. + if rule > 120 && + state == wbNumeric && + (nextProperty == prMidNum || nextProperty == prMidNumLet || nextProperty == prSingleQuote) && + farProperty == prNumeric { + return wbWB11, false + } + + // WB15 and WB16. + if newState == wbAny && nextProperty == prRegionalIndicator { + if state != wbOddRI && state != wbEvenRI { // Includes state == -1. + // Transition into the first RI. + return wbOddRI, true + } + if state == wbOddRI { + // Don't break pairs of Regional Indicators. + return wbEvenRI, false + } + return wbOddRI, true // We can break after a pair. + } + + return +} diff --git a/vendor/github.com/schollz/progressbar/v3/.gitignore b/vendor/github.com/schollz/progressbar/v3/.gitignore new file mode 100644 index 000000000000..35c3bde50520 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/.gitignore @@ -0,0 +1,18 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +.idea/ +*.tar.gz diff --git a/vendor/github.com/schollz/progressbar/v3/.travis.yml b/vendor/github.com/schollz/progressbar/v3/.travis.yml new file mode 100644 index 000000000000..1d2338751fc3 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - tip + +script: go test -v . diff --git a/vendor/github.com/schollz/progressbar/v3/LICENSE b/vendor/github.com/schollz/progressbar/v3/LICENSE new file mode 100644 index 000000000000..0ca97652d894 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Zack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/schollz/progressbar/v3/README.md b/vendor/github.com/schollz/progressbar/v3/README.md new file mode 100644 index 000000000000..e94a1c122474 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/README.md @@ -0,0 +1,121 @@ +# progressbar + +[![CI](https://github.com/schollz/progressbar/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/schollz/progressbar/actions/workflows/ci.yml) +[![go report card](https://goreportcard.com/badge/github.com/schollz/progressbar)](https://goreportcard.com/report/github.com/schollz/progressbar) +[![coverage](https://img.shields.io/badge/coverage-84%25-brightgreen.svg)](https://gocover.io/github.com/schollz/progressbar) +[![godocs](https://godoc.org/github.com/schollz/progressbar?status.svg)](https://godoc.org/github.com/schollz/progressbar/v3) + +A very simple thread-safe progress bar which should work on every OS without problems. I needed a progressbar for [croc](https://github.com/schollz/croc) and everything I tried had problems, so I made another one. In order to be OS agnostic I do not plan to support [multi-line outputs](https://github.com/schollz/progressbar/issues/6). + + +## Install + +``` +go get -u github.com/schollz/progressbar/v3 +``` + +## Usage + +### Basic usage + +```golang +bar := progressbar.Default(100) +for i := 0; i < 100; i++ { + bar.Add(1) + time.Sleep(40 * time.Millisecond) +} +``` + +which looks like: + +![Example of basic bar](examples/basic/basic.gif) + + +### I/O operations + +The `progressbar` implements an `io.Writer` so it can automatically detect the number of bytes written to a stream, so you can use it as a progressbar for an `io.Reader`. + +```golang +req, _ := http.NewRequest("GET", "https://dl.google.com/go/go1.14.2.src.tar.gz", nil) +resp, _ := http.DefaultClient.Do(req) +defer resp.Body.Close() + +f, _ := os.OpenFile("go1.14.2.src.tar.gz", os.O_CREATE|os.O_WRONLY, 0644) +defer f.Close() + +bar := progressbar.DefaultBytes( + resp.ContentLength, + "downloading", +) +io.Copy(io.MultiWriter(f, bar), resp.Body) +``` + +which looks like: + +![Example of download bar](examples/download/download.gif) + + +### Progress bar with unknown length + +A progressbar with unknown length is a spinner. Any bar with -1 length will automatically convert it to a spinner with a customizable spinner type. For example, the above code can be run and set the `resp.ContentLength` to `-1`. + +which looks like: + +![Example of download bar with unknown length](examples/download-unknown/download-unknown.gif) + + +### Customization + +There is a lot of customization that you can do - change the writer, the color, the width, description, theme, etc. See [all the options](https://pkg.go.dev/github.com/schollz/progressbar/v3?tab=doc#Option). + +```golang +bar := progressbar.NewOptions(1000, + progressbar.OptionSetWriter(ansi.NewAnsiStdout()), //you should install "github.com/k0kubun/go-ansi" + progressbar.OptionEnableColorCodes(true), + progressbar.OptionShowBytes(true), + progressbar.OptionSetWidth(15), + progressbar.OptionSetDescription("[cyan][1/3][reset] Writing moshable file..."), + progressbar.OptionSetTheme(progressbar.Theme{ + Saucer: "[green]=[reset]", + SaucerHead: "[green]>[reset]", + SaucerPadding: " ", + BarStart: "[", + BarEnd: "]", + })) +for i := 0; i < 1000; i++ { + bar.Add(1) + time.Sleep(5 * time.Millisecond) +} +``` + +which looks like: + +![Example of customized bar](examples/customization/customization.gif) + + +## Contributing + +Pull requests are welcome. Feel free to... + +- Revise documentation +- Add new features +- Fix bugs +- Suggest improvements + +## Thanks + +Thanks [@Dynom](https://github.com/dynom) for massive improvements in version 2.0! + +Thanks [@CrushedPixel](https://github.com/CrushedPixel) for adding descriptions and color code support! + +Thanks [@MrMe42](https://github.com/MrMe42) for adding some minor features! + +Thanks [@tehstun](https://github.com/tehstun) for some great PRs! + +Thanks [@Benzammour](https://github.com/Benzammour) and [@haseth](https://github.com/haseth) for helping create v3! + +Thanks [@briandowns](https://github.com/briandowns) for compiling the list of spinners. + +## License + +MIT diff --git a/vendor/github.com/schollz/progressbar/v3/progressbar.go b/vendor/github.com/schollz/progressbar/v3/progressbar.go new file mode 100644 index 000000000000..067dd1917269 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/progressbar.go @@ -0,0 +1,1132 @@ +package progressbar + +import ( + "errors" + "fmt" + "io" + "math" + "os" + "regexp" + "strings" + "sync" + "time" + + "github.com/mitchellh/colorstring" + "github.com/rivo/uniseg" + "golang.org/x/term" +) + +// ProgressBar is a thread-safe, simple +// progress bar +type ProgressBar struct { + state state + config config + lock sync.Mutex +} + +// State is the basic properties of the bar +type State struct { + Max int64 + CurrentNum int64 + CurrentPercent float64 + CurrentBytes float64 + SecondsSince float64 + SecondsLeft float64 + KBsPerSecond float64 + Description string +} + +type state struct { + currentNum int64 + currentPercent int + lastPercent int + currentSaucerSize int + isAltSaucerHead bool + + lastShown time.Time + startTime time.Time + + counterTime time.Time + counterNumSinceLast int64 + counterLastTenRates []float64 + + maxLineWidth int + currentBytes float64 + finished bool + exit bool // Progress bar exit halfway + + rendered string +} + +type config struct { + max int64 // max number of the counter + maxHumanized string + maxHumanizedSuffix string + width int + writer io.Writer + theme Theme + renderWithBlankState bool + description string + iterationString string + ignoreLength bool // ignoreLength if max bytes not known + + // whether the output is expected to contain color codes + colorCodes bool + + // show rate of change in kB/sec or MB/sec + showBytes bool + // show the iterations per second + showIterationsPerSecond bool + showIterationsCount bool + + // whether the progress bar should show elapsed time. + // always enabled if predictTime is true. + elapsedTime bool + + showElapsedTimeOnFinish bool + + // whether the progress bar should attempt to predict the finishing + // time of the progress based on the start time and the average + // number of seconds between increments. + predictTime bool + + // minimum time to wait in between updates + throttleDuration time.Duration + + // clear bar once finished + clearOnFinish bool + + // spinnerType should be a number between 0-75 + spinnerType int + + // spinnerTypeOptionUsed remembers if the spinnerType was changed manually + spinnerTypeOptionUsed bool + + // spinner represents the spinner as a slice of string + spinner []string + + // fullWidth specifies whether to measure and set the bar to a specific width + fullWidth bool + + // invisible doesn't render the bar at all, useful for debugging + invisible bool + + onCompletion func() + + // whether the render function should make use of ANSI codes to reduce console I/O + useANSICodes bool + + // whether to use the IEC units (e.g. MiB) instead of the default SI units (e.g. MB) + useIECUnits bool + + // showDescriptionAtLineEnd specifies whether description should be written at line end instead of line start + showDescriptionAtLineEnd bool +} + +// Theme defines the elements of the bar +type Theme struct { + Saucer string + AltSaucerHead string + SaucerHead string + SaucerPadding string + BarStart string + BarEnd string +} + +// Option is the type all options need to adhere to +type Option func(p *ProgressBar) + +// OptionSetWidth sets the width of the bar +func OptionSetWidth(s int) Option { + return func(p *ProgressBar) { + p.config.width = s + } +} + +// OptionSpinnerType sets the type of spinner used for indeterminate bars +func OptionSpinnerType(spinnerType int) Option { + return func(p *ProgressBar) { + p.config.spinnerTypeOptionUsed = true + p.config.spinnerType = spinnerType + } +} + +// OptionSpinnerCustom sets the spinner used for indeterminate bars to the passed +// slice of string +func OptionSpinnerCustom(spinner []string) Option { + return func(p *ProgressBar) { + p.config.spinner = spinner + } +} + +// OptionSetTheme sets the elements the bar is constructed of +func OptionSetTheme(t Theme) Option { + return func(p *ProgressBar) { + p.config.theme = t + } +} + +// OptionSetVisibility sets the visibility +func OptionSetVisibility(visibility bool) Option { + return func(p *ProgressBar) { + p.config.invisible = !visibility + } +} + +// OptionFullWidth sets the bar to be full width +func OptionFullWidth() Option { + return func(p *ProgressBar) { + p.config.fullWidth = true + } +} + +// OptionSetWriter sets the output writer (defaults to os.StdOut) +func OptionSetWriter(w io.Writer) Option { + return func(p *ProgressBar) { + p.config.writer = w + } +} + +// OptionSetRenderBlankState sets whether or not to render a 0% bar on construction +func OptionSetRenderBlankState(r bool) Option { + return func(p *ProgressBar) { + p.config.renderWithBlankState = r + } +} + +// OptionSetDescription sets the description of the bar to render in front of it +func OptionSetDescription(description string) Option { + return func(p *ProgressBar) { + p.config.description = description + } +} + +// OptionEnableColorCodes enables or disables support for color codes +// using mitchellh/colorstring +func OptionEnableColorCodes(colorCodes bool) Option { + return func(p *ProgressBar) { + p.config.colorCodes = colorCodes + } +} + +// OptionSetElapsedTime will enable elapsed time. Always enabled if OptionSetPredictTime is true. +func OptionSetElapsedTime(elapsedTime bool) Option { + return func(p *ProgressBar) { + p.config.elapsedTime = elapsedTime + } +} + +// OptionSetPredictTime will also attempt to predict the time remaining. +func OptionSetPredictTime(predictTime bool) Option { + return func(p *ProgressBar) { + p.config.predictTime = predictTime + } +} + +// OptionShowCount will also print current count out of total +func OptionShowCount() Option { + return func(p *ProgressBar) { + p.config.showIterationsCount = true + } +} + +// OptionShowIts will also print the iterations/second +func OptionShowIts() Option { + return func(p *ProgressBar) { + p.config.showIterationsPerSecond = true + } +} + +// OptionShowElapsedOnFinish will keep the display of elapsed time on finish +func OptionShowElapsedTimeOnFinish() Option { + return func(p *ProgressBar) { + p.config.showElapsedTimeOnFinish = true + } +} + +// OptionSetItsString sets what's displayed for iterations a second. The default is "it" which would display: "it/s" +func OptionSetItsString(iterationString string) Option { + return func(p *ProgressBar) { + p.config.iterationString = iterationString + } +} + +// OptionThrottle will wait the specified duration before updating again. The default +// duration is 0 seconds. +func OptionThrottle(duration time.Duration) Option { + return func(p *ProgressBar) { + p.config.throttleDuration = duration + } +} + +// OptionClearOnFinish will clear the bar once its finished +func OptionClearOnFinish() Option { + return func(p *ProgressBar) { + p.config.clearOnFinish = true + } +} + +// OptionOnCompletion will invoke cmpl function once its finished +func OptionOnCompletion(cmpl func()) Option { + return func(p *ProgressBar) { + p.config.onCompletion = cmpl + } +} + +// OptionShowBytes will update the progress bar +// configuration settings to display/hide kBytes/Sec +func OptionShowBytes(val bool) Option { + return func(p *ProgressBar) { + p.config.showBytes = val + } +} + +// OptionUseANSICodes will use more optimized terminal i/o. +// +// Only useful in environments with support for ANSI escape sequences. +func OptionUseANSICodes(val bool) Option { + return func(p *ProgressBar) { + p.config.useANSICodes = val + } +} + +// OptionUseIECUnits will enable IEC units (e.g. MiB) instead of the default +// SI units (e.g. MB). +func OptionUseIECUnits(val bool) Option { + return func(p *ProgressBar) { + p.config.useIECUnits = val + } +} + +// OptionShowDescriptionAtLineEnd defines whether description should be written at line end instead of line start +func OptionShowDescriptionAtLineEnd() Option { + return func(p *ProgressBar) { + p.config.showDescriptionAtLineEnd = true + } +} + +var defaultTheme = Theme{Saucer: "โ–ˆ", SaucerPadding: " ", BarStart: "|", BarEnd: "|"} + +// NewOptions constructs a new instance of ProgressBar, with any options you specify +func NewOptions(max int, options ...Option) *ProgressBar { + return NewOptions64(int64(max), options...) +} + +// NewOptions64 constructs a new instance of ProgressBar, with any options you specify +func NewOptions64(max int64, options ...Option) *ProgressBar { + b := ProgressBar{ + state: getBasicState(), + config: config{ + writer: os.Stdout, + theme: defaultTheme, + iterationString: "it", + width: 40, + max: max, + throttleDuration: 0 * time.Nanosecond, + elapsedTime: true, + predictTime: true, + spinnerType: 9, + invisible: false, + }, + } + + for _, o := range options { + o(&b) + } + + if b.config.spinnerType < 0 || b.config.spinnerType > 75 { + panic("invalid spinner type, must be between 0 and 75") + } + + // ignoreLength if max bytes not known + if b.config.max == -1 { + b.config.ignoreLength = true + b.config.max = int64(b.config.width) + b.config.predictTime = false + } + + b.config.maxHumanized, b.config.maxHumanizedSuffix = humanizeBytes(float64(b.config.max), + b.config.useIECUnits) + + if b.config.renderWithBlankState { + b.RenderBlank() + } + + return &b +} + +func getBasicState() state { + now := time.Now() + return state{ + startTime: now, + lastShown: now, + counterTime: now, + } +} + +// New returns a new ProgressBar +// with the specified maximum +func New(max int) *ProgressBar { + return NewOptions(max) +} + +// DefaultBytes provides a progressbar to measure byte +// throughput with recommended defaults. +// Set maxBytes to -1 to use as a spinner. +func DefaultBytes(maxBytes int64, description ...string) *ProgressBar { + desc := "" + if len(description) > 0 { + desc = description[0] + } + return NewOptions64( + maxBytes, + OptionSetDescription(desc), + OptionSetWriter(os.Stderr), + OptionShowBytes(true), + OptionSetWidth(10), + OptionThrottle(65*time.Millisecond), + OptionShowCount(), + OptionOnCompletion(func() { + fmt.Fprint(os.Stderr, "\n") + }), + OptionSpinnerType(14), + OptionFullWidth(), + OptionSetRenderBlankState(true), + ) +} + +// DefaultBytesSilent is the same as DefaultBytes, but does not output anywhere. +// String() can be used to get the output instead. +func DefaultBytesSilent(maxBytes int64, description ...string) *ProgressBar { + // Mostly the same bar as DefaultBytes + + desc := "" + if len(description) > 0 { + desc = description[0] + } + return NewOptions64( + maxBytes, + OptionSetDescription(desc), + OptionSetWriter(io.Discard), + OptionShowBytes(true), + OptionSetWidth(10), + OptionThrottle(65*time.Millisecond), + OptionShowCount(), + OptionSpinnerType(14), + OptionFullWidth(), + ) +} + +// Default provides a progressbar with recommended defaults. +// Set max to -1 to use as a spinner. +func Default(max int64, description ...string) *ProgressBar { + desc := "" + if len(description) > 0 { + desc = description[0] + } + return NewOptions64( + max, + OptionSetDescription(desc), + OptionSetWriter(os.Stderr), + OptionSetWidth(10), + OptionThrottle(65*time.Millisecond), + OptionShowCount(), + OptionShowIts(), + OptionOnCompletion(func() { + fmt.Fprint(os.Stderr, "\n") + }), + OptionSpinnerType(14), + OptionFullWidth(), + OptionSetRenderBlankState(true), + ) +} + +// DefaultSilent is the same as Default, but does not output anywhere. +// String() can be used to get the output instead. +func DefaultSilent(max int64, description ...string) *ProgressBar { + // Mostly the same bar as Default + + desc := "" + if len(description) > 0 { + desc = description[0] + } + return NewOptions64( + max, + OptionSetDescription(desc), + OptionSetWriter(io.Discard), + OptionSetWidth(10), + OptionThrottle(65*time.Millisecond), + OptionShowCount(), + OptionShowIts(), + OptionSpinnerType(14), + OptionFullWidth(), + ) +} + +// String returns the current rendered version of the progress bar. +// It will never return an empty string while the progress bar is running. +func (p *ProgressBar) String() string { + return p.state.rendered +} + +// RenderBlank renders the current bar state, you can use this to render a 0% state +func (p *ProgressBar) RenderBlank() error { + p.lock.Lock() + defer p.lock.Unlock() + + if p.config.invisible { + return nil + } + if p.state.currentNum == 0 { + p.state.lastShown = time.Time{} + } + return p.render() +} + +// Reset will reset the clock that is used +// to calculate current time and the time left. +func (p *ProgressBar) Reset() { + p.lock.Lock() + defer p.lock.Unlock() + + p.state = getBasicState() +} + +// Finish will fill the bar to full +func (p *ProgressBar) Finish() error { + p.lock.Lock() + p.state.currentNum = p.config.max + p.lock.Unlock() + return p.Add(0) +} + +// Exit will exit the bar to keep current state +func (p *ProgressBar) Exit() error { + p.lock.Lock() + defer p.lock.Unlock() + + p.state.exit = true + if p.config.onCompletion != nil { + p.config.onCompletion() + } + return nil +} + +// Add will add the specified amount to the progressbar +func (p *ProgressBar) Add(num int) error { + return p.Add64(int64(num)) +} + +// Set will set the bar to a current number +func (p *ProgressBar) Set(num int) error { + return p.Set64(int64(num)) +} + +// Set64 will set the bar to a current number +func (p *ProgressBar) Set64(num int64) error { + p.lock.Lock() + toAdd := num - int64(p.state.currentBytes) + p.lock.Unlock() + return p.Add64(toAdd) +} + +// Add64 will add the specified amount to the progressbar +func (p *ProgressBar) Add64(num int64) error { + if p.config.invisible { + return nil + } + p.lock.Lock() + defer p.lock.Unlock() + + if p.state.exit { + return nil + } + + // error out since OptionSpinnerCustom will always override a manually set spinnerType + if p.config.spinnerTypeOptionUsed && len(p.config.spinner) > 0 { + return errors.New("OptionSpinnerType and OptionSpinnerCustom cannot be used together") + } + + if p.config.max == 0 { + return errors.New("max must be greater than 0") + } + + if p.state.currentNum < p.config.max { + if p.config.ignoreLength { + p.state.currentNum = (p.state.currentNum + num) % p.config.max + } else { + p.state.currentNum += num + } + } + + p.state.currentBytes += float64(num) + + // reset the countdown timer every second to take rolling average + p.state.counterNumSinceLast += num + if time.Since(p.state.counterTime).Seconds() > 0.5 { + p.state.counterLastTenRates = append(p.state.counterLastTenRates, float64(p.state.counterNumSinceLast)/time.Since(p.state.counterTime).Seconds()) + if len(p.state.counterLastTenRates) > 10 { + p.state.counterLastTenRates = p.state.counterLastTenRates[1:] + } + p.state.counterTime = time.Now() + p.state.counterNumSinceLast = 0 + } + + percent := float64(p.state.currentNum) / float64(p.config.max) + p.state.currentSaucerSize = int(percent * float64(p.config.width)) + p.state.currentPercent = int(percent * 100) + updateBar := p.state.currentPercent != p.state.lastPercent && p.state.currentPercent > 0 + + p.state.lastPercent = p.state.currentPercent + if p.state.currentNum > p.config.max { + return errors.New("current number exceeds max") + } + + // always update if show bytes/second or its/second + if updateBar || p.config.showIterationsPerSecond || p.config.showIterationsCount { + return p.render() + } + + return nil +} + +// Clear erases the progress bar from the current line +func (p *ProgressBar) Clear() error { + return clearProgressBar(p.config, p.state) +} + +// Describe will change the description shown before the progress, which +// can be changed on the fly (as for a slow running process). +func (p *ProgressBar) Describe(description string) { + p.lock.Lock() + defer p.lock.Unlock() + p.config.description = description + if p.config.invisible { + return + } + p.render() +} + +// New64 returns a new ProgressBar +// with the specified maximum +func New64(max int64) *ProgressBar { + return NewOptions64(max) +} + +// GetMax returns the max of a bar +func (p *ProgressBar) GetMax() int { + return int(p.config.max) +} + +// GetMax64 returns the current max +func (p *ProgressBar) GetMax64() int64 { + return p.config.max +} + +// ChangeMax takes in a int +// and changes the max value +// of the progress bar +func (p *ProgressBar) ChangeMax(newMax int) { + p.ChangeMax64(int64(newMax)) +} + +// ChangeMax64 is basically +// the same as ChangeMax, +// but takes in a int64 +// to avoid casting +func (p *ProgressBar) ChangeMax64(newMax int64) { + p.config.max = newMax + + if p.config.showBytes { + p.config.maxHumanized, p.config.maxHumanizedSuffix = humanizeBytes(float64(p.config.max), + p.config.useIECUnits) + } + + p.Add(0) // re-render +} + +// IsFinished returns true if progress bar is completed +func (p *ProgressBar) IsFinished() bool { + p.lock.Lock() + defer p.lock.Unlock() + + return p.state.finished +} + +// render renders the progress bar, updating the maximum +// rendered line width. this function is not thread-safe, +// so it must be called with an acquired lock. +func (p *ProgressBar) render() error { + // make sure that the rendering is not happening too quickly + // but always show if the currentNum reaches the max + if time.Since(p.state.lastShown).Nanoseconds() < p.config.throttleDuration.Nanoseconds() && + p.state.currentNum < p.config.max { + return nil + } + + if !p.config.useANSICodes { + // first, clear the existing progress bar + err := clearProgressBar(p.config, p.state) + if err != nil { + return err + } + } + + // check if the progress bar is finished + if !p.state.finished && p.state.currentNum >= p.config.max { + p.state.finished = true + if !p.config.clearOnFinish { + renderProgressBar(p.config, &p.state) + } + if p.config.onCompletion != nil { + p.config.onCompletion() + } + } + if p.state.finished { + // when using ANSI codes we don't pre-clean the current line + if p.config.useANSICodes && p.config.clearOnFinish { + err := clearProgressBar(p.config, p.state) + if err != nil { + return err + } + } + return nil + } + + // then, re-render the current progress bar + w, err := renderProgressBar(p.config, &p.state) + if err != nil { + return err + } + + if w > p.state.maxLineWidth { + p.state.maxLineWidth = w + } + + p.state.lastShown = time.Now() + + return nil +} + +// State returns the current state +func (p *ProgressBar) State() State { + p.lock.Lock() + defer p.lock.Unlock() + s := State{} + s.CurrentNum = p.state.currentNum + s.Max = p.config.max + if p.config.ignoreLength { + s.Max = -1 + } + s.CurrentPercent = float64(p.state.currentNum) / float64(p.config.max) + s.CurrentBytes = p.state.currentBytes + s.SecondsSince = time.Since(p.state.startTime).Seconds() + if p.state.currentNum > 0 { + s.SecondsLeft = s.SecondsSince / float64(p.state.currentNum) * (float64(p.config.max) - float64(p.state.currentNum)) + } + s.KBsPerSecond = float64(p.state.currentBytes) / 1024.0 / s.SecondsSince + s.Description = p.config.description + return s +} + +// regex matching ansi escape codes +var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`) + +func getStringWidth(c config, str string, colorize bool) int { + if c.colorCodes { + // convert any color codes in the progress bar into the respective ANSI codes + str = colorstring.Color(str) + } + + // the width of the string, if printed to the console + // does not include the carriage return character + cleanString := strings.Replace(str, "\r", "", -1) + + if c.colorCodes { + // the ANSI codes for the colors do not take up space in the console output, + // so they do not count towards the output string width + cleanString = ansiRegex.ReplaceAllString(cleanString, "") + } + + // get the amount of runes in the string instead of the + // character count of the string, as some runes span multiple characters. + // see https://stackoverflow.com/a/12668840/2733724 + stringWidth := uniseg.StringWidth(cleanString) + return stringWidth +} + +func renderProgressBar(c config, s *state) (int, error) { + var sb strings.Builder + + averageRate := average(s.counterLastTenRates) + if len(s.counterLastTenRates) == 0 || s.finished { + // if no average samples, or if finished, + // then average rate should be the total rate + if t := time.Since(s.startTime).Seconds(); t > 0 { + averageRate = s.currentBytes / t + } else { + averageRate = 0 + } + } + + // show iteration count in "current/total" iterations format + if c.showIterationsCount { + if sb.Len() == 0 { + sb.WriteString("(") + } else { + sb.WriteString(", ") + } + if !c.ignoreLength { + if c.showBytes { + currentHumanize, currentSuffix := humanizeBytes(s.currentBytes, c.useIECUnits) + if currentSuffix == c.maxHumanizedSuffix { + sb.WriteString(fmt.Sprintf("%s/%s%s", + currentHumanize, c.maxHumanized, c.maxHumanizedSuffix)) + } else { + sb.WriteString(fmt.Sprintf("%s%s/%s%s", + currentHumanize, currentSuffix, c.maxHumanized, c.maxHumanizedSuffix)) + } + } else { + sb.WriteString(fmt.Sprintf("%.0f/%d", s.currentBytes, c.max)) + } + } else { + if c.showBytes { + currentHumanize, currentSuffix := humanizeBytes(s.currentBytes, c.useIECUnits) + sb.WriteString(fmt.Sprintf("%s%s", currentHumanize, currentSuffix)) + } else { + sb.WriteString(fmt.Sprintf("%.0f/%s", s.currentBytes, "-")) + } + } + } + + // show rolling average rate + if c.showBytes && averageRate > 0 && !math.IsInf(averageRate, 1) { + if sb.Len() == 0 { + sb.WriteString("(") + } else { + sb.WriteString(", ") + } + currentHumanize, currentSuffix := humanizeBytes(averageRate, c.useIECUnits) + sb.WriteString(fmt.Sprintf("%s%s/s", currentHumanize, currentSuffix)) + } + + // show iterations rate + if c.showIterationsPerSecond { + if sb.Len() == 0 { + sb.WriteString("(") + } else { + sb.WriteString(", ") + } + if averageRate > 1 { + sb.WriteString(fmt.Sprintf("%0.0f %s/s", averageRate, c.iterationString)) + } else if averageRate*60 > 1 { + sb.WriteString(fmt.Sprintf("%0.0f %s/min", 60*averageRate, c.iterationString)) + } else { + sb.WriteString(fmt.Sprintf("%0.0f %s/hr", 3600*averageRate, c.iterationString)) + } + } + if sb.Len() > 0 { + sb.WriteString(")") + } + + leftBrac, rightBrac, saucer, saucerHead := "", "", "", "" + + // show time prediction in "current/total" seconds format + switch { + case c.predictTime: + rightBracNum := (time.Duration((1/averageRate)*(float64(c.max)-float64(s.currentNum))) * time.Second) + if rightBracNum.Seconds() < 0 { + rightBracNum = 0 * time.Second + } + rightBrac = rightBracNum.String() + fallthrough + case c.elapsedTime: + leftBrac = (time.Duration(time.Since(s.startTime).Seconds()) * time.Second).String() + } + + if c.fullWidth && !c.ignoreLength { + width, err := termWidth() + if err != nil { + width = 80 + } + + amend := 1 // an extra space at eol + switch { + case leftBrac != "" && rightBrac != "": + amend = 4 // space, square brackets and colon + case leftBrac != "" && rightBrac == "": + amend = 4 // space and square brackets and another space + case leftBrac == "" && rightBrac != "": + amend = 3 // space and square brackets + } + if c.showDescriptionAtLineEnd { + amend += 1 // another space + } + + c.width = width - getStringWidth(c, c.description, true) - 10 - amend - sb.Len() - len(leftBrac) - len(rightBrac) + s.currentSaucerSize = int(float64(s.currentPercent) / 100.0 * float64(c.width)) + } + if s.currentSaucerSize > 0 { + if c.ignoreLength { + saucer = strings.Repeat(c.theme.SaucerPadding, s.currentSaucerSize-1) + } else { + saucer = strings.Repeat(c.theme.Saucer, s.currentSaucerSize-1) + } + + // Check if an alternate saucer head is set for animation + if c.theme.AltSaucerHead != "" && s.isAltSaucerHead { + saucerHead = c.theme.AltSaucerHead + s.isAltSaucerHead = false + } else if c.theme.SaucerHead == "" || s.currentSaucerSize == c.width { + // use the saucer for the saucer head if it hasn't been set + // to preserve backwards compatibility + saucerHead = c.theme.Saucer + } else { + saucerHead = c.theme.SaucerHead + s.isAltSaucerHead = true + } + } + + /* + Progress Bar format + Description % |------ | (kb/s) (iteration count) (iteration rate) (predict time) + + or if showDescriptionAtLineEnd is enabled + % |------ | (kb/s) (iteration count) (iteration rate) (predict time) Description + */ + + repeatAmount := c.width - s.currentSaucerSize + if repeatAmount < 0 { + repeatAmount = 0 + } + + str := "" + + if c.ignoreLength { + selectedSpinner := spinners[c.spinnerType] + if len(c.spinner) > 0 { + selectedSpinner = c.spinner + } + spinner := selectedSpinner[int(math.Round(math.Mod(float64(time.Since(s.startTime).Milliseconds()/100), float64(len(selectedSpinner)))))] + if c.elapsedTime { + if c.showDescriptionAtLineEnd { + str = fmt.Sprintf("\r%s %s [%s] %s ", + spinner, + sb.String(), + leftBrac, + c.description) + } else { + str = fmt.Sprintf("\r%s %s %s [%s] ", + spinner, + c.description, + sb.String(), + leftBrac) + } + } else { + if c.showDescriptionAtLineEnd { + str = fmt.Sprintf("\r%s %s %s ", + spinner, + sb.String(), + c.description) + } else { + str = fmt.Sprintf("\r%s %s %s ", + spinner, + c.description, + sb.String()) + } + } + } else if rightBrac == "" { + str = fmt.Sprintf("%4d%% %s%s%s%s%s %s", + s.currentPercent, + c.theme.BarStart, + saucer, + saucerHead, + strings.Repeat(c.theme.SaucerPadding, repeatAmount), + c.theme.BarEnd, + sb.String()) + + if s.currentPercent == 100 && c.showElapsedTimeOnFinish { + str = fmt.Sprintf("%s [%s]", str, leftBrac) + } + + if c.showDescriptionAtLineEnd { + str = fmt.Sprintf("\r%s %s ", str, c.description) + } else { + str = fmt.Sprintf("\r%s%s ", c.description, str) + } + } else { + if s.currentPercent == 100 { + str = fmt.Sprintf("%4d%% %s%s%s%s%s %s", + s.currentPercent, + c.theme.BarStart, + saucer, + saucerHead, + strings.Repeat(c.theme.SaucerPadding, repeatAmount), + c.theme.BarEnd, + sb.String()) + + if c.showElapsedTimeOnFinish { + str = fmt.Sprintf("%s [%s]", str, leftBrac) + } + + if c.showDescriptionAtLineEnd { + str = fmt.Sprintf("\r%s %s", str, c.description) + } else { + str = fmt.Sprintf("\r%s%s", c.description, str) + } + } else { + str = fmt.Sprintf("%4d%% %s%s%s%s%s %s [%s:%s]", + s.currentPercent, + c.theme.BarStart, + saucer, + saucerHead, + strings.Repeat(c.theme.SaucerPadding, repeatAmount), + c.theme.BarEnd, + sb.String(), + leftBrac, + rightBrac) + + if c.showDescriptionAtLineEnd { + str = fmt.Sprintf("\r%s %s", str, c.description) + } else { + str = fmt.Sprintf("\r%s%s", c.description, str) + } + } + } + + if c.colorCodes { + // convert any color codes in the progress bar into the respective ANSI codes + str = colorstring.Color(str) + } + + s.rendered = str + + return getStringWidth(c, str, false), writeString(c, str) +} + +func clearProgressBar(c config, s state) error { + if s.maxLineWidth == 0 { + return nil + } + if c.useANSICodes { + // write the "clear current line" ANSI escape sequence + return writeString(c, "\033[2K\r") + } + // fill the empty content + // to overwrite the progress bar and jump + // back to the beginning of the line + str := fmt.Sprintf("\r%s\r", strings.Repeat(" ", s.maxLineWidth)) + return writeString(c, str) + // the following does not show correctly if the previous line is longer than subsequent line + // return writeString(c, "\r") +} + +func writeString(c config, str string) error { + if _, err := io.WriteString(c.writer, str); err != nil { + return err + } + + if f, ok := c.writer.(*os.File); ok { + // ignore any errors in Sync(), as stdout + // can't be synced on some operating systems + // like Debian 9 (Stretch) + f.Sync() + } + + return nil +} + +// Reader is the progressbar io.Reader struct +type Reader struct { + io.Reader + bar *ProgressBar +} + +// NewReader return a new Reader with a given progress bar. +func NewReader(r io.Reader, bar *ProgressBar) Reader { + return Reader{ + Reader: r, + bar: bar, + } +} + +// Read will read the data and add the number of bytes to the progressbar +func (r *Reader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + r.bar.Add(n) + return +} + +// Close the reader when it implements io.Closer +func (r *Reader) Close() (err error) { + if closer, ok := r.Reader.(io.Closer); ok { + return closer.Close() + } + r.bar.Finish() + return +} + +// Write implement io.Writer +func (p *ProgressBar) Write(b []byte) (n int, err error) { + n = len(b) + p.Add(n) + return +} + +// Read implement io.Reader +func (p *ProgressBar) Read(b []byte) (n int, err error) { + n = len(b) + p.Add(n) + return +} + +func (p *ProgressBar) Close() (err error) { + p.Finish() + return +} + +func average(xs []float64) float64 { + total := 0.0 + for _, v := range xs { + total += v + } + return total / float64(len(xs)) +} + +func humanizeBytes(s float64, iec bool) (string, string) { + sizes := []string{" B", " kB", " MB", " GB", " TB", " PB", " EB"} + base := 1000.0 + + if iec { + sizes = []string{" B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB"} + base = 1024.0 + } + + if s < 10 { + return fmt.Sprintf("%2.0f", s), sizes[0] + } + e := math.Floor(logn(float64(s), base)) + suffix := sizes[int(e)] + val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 + f := "%.0f" + if val < 10 { + f = "%.1f" + } + + return fmt.Sprintf(f, val), suffix +} + +func logn(n, b float64) float64 { + return math.Log(n) / math.Log(b) +} + +// termWidth function returns the visible width of the current terminal +// and can be redefined for testing +var termWidth = func() (width int, err error) { + width, _, err = term.GetSize(int(os.Stdout.Fd())) + if err == nil { + return width, nil + } + + return 0, err +} diff --git a/vendor/github.com/schollz/progressbar/v3/spinners.go b/vendor/github.com/schollz/progressbar/v3/spinners.go new file mode 100644 index 000000000000..c3ccd01f9058 --- /dev/null +++ b/vendor/github.com/schollz/progressbar/v3/spinners.go @@ -0,0 +1,80 @@ +package progressbar + +var spinners = map[int][]string{ + 0: {"โ†", "โ†–", "โ†‘", "โ†—", "โ†’", "โ†˜", "โ†“", "โ†™"}, + 1: {"โ–", "โ–ƒ", "โ–„", "โ–…", "โ–†", "โ–‡", "โ–ˆ", "โ–‡", "โ–†", "โ–…", "โ–„", "โ–ƒ", "โ–"}, + 2: {"โ––", "โ–˜", "โ–", "โ–—"}, + 3: {"โ”ค", "โ”˜", "โ”ด", "โ””", "โ”œ", "โ”Œ", "โ”ฌ", "โ”"}, + 4: {"โ—ข", "โ—ฃ", "โ—ค", "โ—ฅ"}, + 5: {"โ—ฐ", "โ—ณ", "โ—ฒ", "โ—ฑ"}, + 6: {"โ—ด", "โ—ท", "โ—ถ", "โ—ต"}, + 7: {"โ—", "โ—“", "โ—‘", "โ—’"}, + 8: {".", "o", "O", "@", "*"}, + 9: {"|", "/", "-", "\\"}, + 10: {"โ—กโ—ก", "โŠ™โŠ™", "โ— โ— "}, + 11: {"โฃพ", "โฃฝ", "โฃป", "โขฟ", "โกฟ", "โฃŸ", "โฃฏ", "โฃท"}, + 12: {">))'>", " >))'>", " >))'>", " >))'>", " >))'>", " <'((<", " <'((<", " <'((<"}, + 13: {"โ ", "โ ‚", "โ „", "โก€", "โข€", "โ  ", "โ ", "โ ˆ"}, + 14: {"โ ‹", "โ ™", "โ น", "โ ธ", "โ ผ", "โ ด", "โ ฆ", "โ ง", "โ ‡", "โ "}, + 15: {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}, + 16: {"โ–‰", "โ–Š", "โ–‹", "โ–Œ", "โ–", "โ–Ž", "โ–", "โ–Ž", "โ–", "โ–Œ", "โ–‹", "โ–Š", "โ–‰"}, + 17: {"โ– ", "โ–ก", "โ–ช", "โ–ซ"}, + 18: {"โ†", "โ†‘", "โ†’", "โ†“"}, + 19: {"โ•ซ", "โ•ช"}, + 20: {"โ‡", "โ‡–", "โ‡‘", "โ‡—", "โ‡’", "โ‡˜", "โ‡“", "โ‡™"}, + 21: {"โ ", "โ ", "โ ‰", "โ ™", "โ š", "โ ’", "โ ‚", "โ ‚", "โ ’", "โ ฒ", "โ ด", "โ ค", "โ „", "โ „", "โ ค", "โ  ", "โ  ", "โ ค", "โ ฆ", "โ –", "โ ’", "โ ", "โ ", "โ ’", "โ “", "โ ‹", "โ ‰", "โ ˆ", "โ ˆ"}, + 22: {"โ ˆ", "โ ‰", "โ ‹", "โ “", "โ ’", "โ ", "โ ", "โ ’", "โ –", "โ ฆ", "โ ค", "โ  ", "โ  ", "โ ค", "โ ฆ", "โ –", "โ ’", "โ ", "โ ", "โ ’", "โ “", "โ ‹", "โ ‰", "โ ˆ"}, + 23: {"โ ", "โ ‰", "โ ™", "โ š", "โ ’", "โ ‚", "โ ‚", "โ ’", "โ ฒ", "โ ด", "โ ค", "โ „", "โ „", "โ ค", "โ ด", "โ ฒ", "โ ’", "โ ‚", "โ ‚", "โ ’", "โ š", "โ ™", "โ ‰", "โ "}, + 24: {"โ ‹", "โ ™", "โ š", "โ ’", "โ ‚", "โ ‚", "โ ’", "โ ฒ", "โ ด", "โ ฆ", "โ –", "โ ’", "โ ", "โ ", "โ ’", "โ “", "โ ‹"}, + 25: {"๏ฝฆ", "๏ฝง", "๏ฝจ", "๏ฝฉ", "๏ฝช", "๏ฝซ", "๏ฝฌ", "๏ฝญ", "๏ฝฎ", "๏ฝฏ", "๏ฝฑ", "๏ฝฒ", "๏ฝณ", "๏ฝด", "๏ฝต", "๏ฝถ", "๏ฝท", "๏ฝธ", "๏ฝน", "๏ฝบ", "๏ฝป", "๏ฝผ", "๏ฝฝ", "๏ฝพ", "๏ฝฟ", "๏พ€", "๏พ", "๏พ‚", "๏พƒ", "๏พ„", "๏พ…", "๏พ†", "๏พ‡", "๏พˆ", "๏พ‰", "๏พŠ", "๏พ‹", "๏พŒ", "๏พ", "๏พŽ", "๏พ", "๏พ", "๏พ‘", "๏พ’", "๏พ“", "๏พ”", "๏พ•", "๏พ–", "๏พ—", "๏พ˜", "๏พ™", "๏พš", "๏พ›", "๏พœ", "๏พ"}, + 26: {".", "..", "..."}, + 27: {"โ–", "โ–‚", "โ–ƒ", "โ–„", "โ–…", "โ–†", "โ–‡", "โ–ˆ", "โ–‰", "โ–Š", "โ–‹", "โ–Œ", "โ–", "โ–Ž", "โ–", "โ–", "โ–Ž", "โ–", "โ–Œ", "โ–‹", "โ–Š", "โ–‰", "โ–ˆ", "โ–‡", "โ–†", "โ–…", "โ–„", "โ–ƒ", "โ–‚", "โ–"}, + 28: {".", "o", "O", "ยฐ", "O", "o", "."}, + 29: {"+", "x"}, + 30: {"v", "<", "^", ">"}, + 31: {">>--->", " >>--->", " >>--->", " >>--->", " >>--->", " <---<<", " <---<<", " <---<<", " <---<<", "<---<<"}, + 32: {"|", "||", "|||", "||||", "|||||", "|||||||", "||||||||", "|||||||", "||||||", "|||||", "||||", "|||", "||", "|"}, + 33: {"[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[===== ]", "[====== ]", "[======= ]", "[======== ]", "[========= ]", "[==========]"}, + 34: {"(*---------)", "(-*--------)", "(--*-------)", "(---*------)", "(----*-----)", "(-----*----)", "(------*---)", "(-------*--)", "(--------*-)", "(---------*)"}, + 35: {"โ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’", "โ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’", "โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’", "โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’", "โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ"}, + 36: {"[ ]", "[=> ]", "[===> ]", "[=====> ]", "[======> ]", "[========> ]", "[==========> ]", "[============> ]", "[==============> ]", "[================> ]", "[==================> ]", "[===================>]"}, + 37: {"แ€", "แ€"}, + 38: {"โ–Œ", "โ–€", "โ–โ–„"}, + 39: {"๐ŸŒ", "๐ŸŒŽ", "๐ŸŒ"}, + 40: {"โ—œ", "โ—", "โ—ž", "โ—Ÿ"}, + 41: {"โฌ’", "โฌ”", "โฌ“", "โฌ•"}, + 42: {"โฌ–", "โฌ˜", "โฌ—", "โฌ™"}, + 43: {"[>>> >]", "[]>>>> []", "[] >>>> []", "[] >>>> []", "[] >>>> []", "[] >>>>[]", "[>> >>]"}, + 44: {"โ™ ", "โ™ฃ", "โ™ฅ", "โ™ฆ"}, + 45: {"โžž", "โžŸ", "โž ", "โžก", "โž ", "โžŸ"}, + 46: {" | ", ` \ `, "_ ", ` \ `, " | ", " / ", " _", " / "}, + 47: {" . . . .", ". . . .", ". . . .", ". . . .", ". . . . ", ". . . . ."}, + 48: {" | ", " / ", " _ ", ` \ `, " | ", ` \ `, " _ ", " / "}, + 49: {"โŽบ", "โŽป", "โŽผ", "โŽฝ", "โŽผ", "โŽป"}, + 50: {"โ–นโ–นโ–นโ–นโ–น", "โ–ธโ–นโ–นโ–นโ–น", "โ–นโ–ธโ–นโ–นโ–น", "โ–นโ–นโ–ธโ–นโ–น", "โ–นโ–นโ–นโ–ธโ–น", "โ–นโ–นโ–นโ–นโ–ธ"}, + 51: {"[ ]", "[ =]", "[ ==]", "[ ===]", "[====]", "[=== ]", "[== ]", "[= ]"}, + 52: {"( โ— )", "( โ— )", "( โ— )", "( โ— )", "( โ—)", "( โ— )", "( โ— )", "( โ— )", "( โ— )"}, + 53: {"โœถ", "โœธ", "โœน", "โœบ", "โœน", "โœท"}, + 54: {"โ–|\\____________โ–Œ", "โ–_|\\___________โ–Œ", "โ–__|\\__________โ–Œ", "โ–___|\\_________โ–Œ", "โ–____|\\________โ–Œ", "โ–_____|\\_______โ–Œ", "โ–______|\\______โ–Œ", "โ–_______|\\_____โ–Œ", "โ–________|\\____โ–Œ", "โ–_________|\\___โ–Œ", "โ–__________|\\__โ–Œ", "โ–___________|\\_โ–Œ", "โ–____________|\\โ–Œ", "โ–____________/|โ–Œ", "โ–___________/|_โ–Œ", "โ–__________/|__โ–Œ", "โ–_________/|___โ–Œ", "โ–________/|____โ–Œ", "โ–_______/|_____โ–Œ", "โ–______/|______โ–Œ", "โ–_____/|_______โ–Œ", "โ–____/|________โ–Œ", "โ–___/|_________โ–Œ", "โ–__/|__________โ–Œ", "โ–_/|___________โ–Œ", "โ–/|____________โ–Œ"}, + 55: {"โ–โ ‚ โ–Œ", "โ–โ ˆ โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ   โ–Œ", "โ– โก€ โ–Œ", "โ– โ   โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ ˆ โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ   โ–Œ", "โ– โก€ โ–Œ", "โ– โ   โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ ˆ โ–Œ", "โ– โ ‚โ–Œ", "โ– โ  โ–Œ", "โ– โก€โ–Œ", "โ– โ   โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ ˆ โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ   โ–Œ", "โ– โก€ โ–Œ", "โ– โ   โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ ˆ โ–Œ", "โ– โ ‚ โ–Œ", "โ– โ   โ–Œ", "โ– โก€ โ–Œ", "โ–โ   โ–Œ"}, + 56: {"ยฟ", "?"}, + 57: {"โขน", "โขบ", "โขผ", "โฃธ", "โฃ‡", "โกง", "โก—", "โก"}, + 58: {"โข„", "โข‚", "โข", "โก", "โกˆ", "โก", "โก "}, + 59: {". ", ".. ", "...", " ..", " .", " "}, + 60: {".", "o", "O", "ยฐ", "O", "o", "."}, + 61: {"โ–“", "โ–’", "โ–‘"}, + 62: {"โ–Œ", "โ–€", "โ–", "โ–„"}, + 63: {"โŠถ", "โŠท"}, + 64: {"โ–ช", "โ–ซ"}, + 65: {"โ–ก", "โ– "}, + 66: {"โ–ฎ", "โ–ฏ"}, + 67: {"-", "=", "โ‰ก"}, + 68: {"d", "q", "p", "b"}, + 69: {"โˆ™โˆ™โˆ™", "โ—โˆ™โˆ™", "โˆ™โ—โˆ™", "โˆ™โˆ™โ—", "โˆ™โˆ™โˆ™"}, + 70: {"๐ŸŒ‘ ", "๐ŸŒ’ ", "๐ŸŒ“ ", "๐ŸŒ” ", "๐ŸŒ• ", "๐ŸŒ– ", "๐ŸŒ— ", "๐ŸŒ˜ "}, + 71: {"โ˜—", "โ˜–"}, + 72: {"โง‡", "โง†"}, + 73: {"โ—‰", "โ—Ž"}, + 74: {"ใŠ‚", "ใŠ€", "ใŠ"}, + 75: {"โฆพ", "โฆฟ"}, +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 090bcd546826..56191b28391f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1193,7 +1193,7 @@ github.com/mattn/go-colorable # github.com/mattn/go-ieproxy v0.0.1 ## explicit; go 1.14 github.com/mattn/go-ieproxy -# github.com/mattn/go-isatty v0.0.19 +# github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/miekg/dns v1.1.58 @@ -1424,9 +1424,15 @@ github.com/rcrowley/go-metrics github.com/richardartoul/molecule github.com/richardartoul/molecule/src/codec github.com/richardartoul/molecule/src/protowire +# github.com/rivo/uniseg v0.4.7 +## explicit; go 1.18 +github.com/rivo/uniseg # github.com/rs/xid v1.5.0 ## explicit; go 1.12 github.com/rs/xid +# github.com/schollz/progressbar/v3 v3.14.2 +## explicit; go 1.13 +github.com/schollz/progressbar/v3 # github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 ## explicit github.com/sean-/seed