@backthread/extractor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/cluster/domain-grouping.d.ts +113 -0
- package/dist/cluster/domain-grouping.d.ts.map +1 -0
- package/dist/cluster/domain-grouping.js +277 -0
- package/dist/cluster/domain-grouping.js.map +1 -0
- package/dist/cluster/grouping-gate.d.ts +54 -0
- package/dist/cluster/grouping-gate.d.ts.map +1 -0
- package/dist/cluster/grouping-gate.js +0 -0
- package/dist/cluster/grouping-gate.js.map +1 -0
- package/dist/cluster/louvain.d.ts +88 -0
- package/dist/cluster/louvain.d.ts.map +1 -0
- package/dist/cluster/louvain.js +674 -0
- package/dist/cluster/louvain.js.map +1 -0
- package/dist/cluster/overrides.d.ts +19 -0
- package/dist/cluster/overrides.d.ts.map +1 -0
- package/dist/cluster/overrides.js +32 -0
- package/dist/cluster/overrides.js.map +1 -0
- package/dist/cluster/subsystem.d.ts +45 -0
- package/dist/cluster/subsystem.d.ts.map +1 -0
- package/dist/cluster/subsystem.js +299 -0
- package/dist/cluster/subsystem.js.map +1 -0
- package/dist/cluster/workspaces.d.ts +64 -0
- package/dist/cluster/workspaces.d.ts.map +1 -0
- package/dist/cluster/workspaces.js +739 -0
- package/dist/cluster/workspaces.js.map +1 -0
- package/dist/extract.d.ts +52 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +48 -0
- package/dist/extract.js.map +1 -0
- package/dist/framework/celery/celery.d.ts +17 -0
- package/dist/framework/celery/celery.d.ts.map +1 -0
- package/dist/framework/celery/celery.js +524 -0
- package/dist/framework/celery/celery.js.map +1 -0
- package/dist/framework/contribute-step.d.ts +38 -0
- package/dist/framework/contribute-step.d.ts.map +1 -0
- package/dist/framework/contribute-step.js +403 -0
- package/dist/framework/contribute-step.js.map +1 -0
- package/dist/framework/detect-step.d.ts +8 -0
- package/dist/framework/detect-step.d.ts.map +1 -0
- package/dist/framework/detect-step.js +54 -0
- package/dist/framework/detect-step.js.map +1 -0
- package/dist/framework/detect-util.d.ts +24 -0
- package/dist/framework/detect-util.d.ts.map +1 -0
- package/dist/framework/detect-util.js +59 -0
- package/dist/framework/detect-util.js.map +1 -0
- package/dist/framework/django/django.d.ts +22 -0
- package/dist/framework/django/django.d.ts.map +1 -0
- package/dist/framework/django/django.js +940 -0
- package/dist/framework/django/django.js.map +1 -0
- package/dist/framework/fastapi/fastapi.d.ts +27 -0
- package/dist/framework/fastapi/fastapi.d.ts.map +1 -0
- package/dist/framework/fastapi/fastapi.js +477 -0
- package/dist/framework/fastapi/fastapi.js.map +1 -0
- package/dist/framework/faststream/faststream.d.ts +19 -0
- package/dist/framework/faststream/faststream.d.ts.map +1 -0
- package/dist/framework/faststream/faststream.js +765 -0
- package/dist/framework/faststream/faststream.js.map +1 -0
- package/dist/framework/flask/flask.d.ts +17 -0
- package/dist/framework/flask/flask.d.ts.map +1 -0
- package/dist/framework/flask/flask.js +507 -0
- package/dist/framework/flask/flask.js.map +1 -0
- package/dist/framework/graphql/graphql.d.ts +17 -0
- package/dist/framework/graphql/graphql.d.ts.map +1 -0
- package/dist/framework/graphql/graphql.js +708 -0
- package/dist/framework/graphql/graphql.js.map +1 -0
- package/dist/framework/grpc/grpc.d.ts +22 -0
- package/dist/framework/grpc/grpc.d.ts.map +1 -0
- package/dist/framework/grpc/grpc.js +618 -0
- package/dist/framework/grpc/grpc.js.map +1 -0
- package/dist/framework/litestar/litestar.d.ts +17 -0
- package/dist/framework/litestar/litestar.d.ts.map +1 -0
- package/dist/framework/litestar/litestar.js +536 -0
- package/dist/framework/litestar/litestar.js.map +1 -0
- package/dist/framework/nest/nest.d.ts +19 -0
- package/dist/framework/nest/nest.d.ts.map +1 -0
- package/dist/framework/nest/nest.js +613 -0
- package/dist/framework/nest/nest.js.map +1 -0
- package/dist/framework/next/next.d.ts +22 -0
- package/dist/framework/next/next.d.ts.map +1 -0
- package/dist/framework/next/next.js +449 -0
- package/dist/framework/next/next.js.map +1 -0
- package/dist/framework/node/node.d.ts +24 -0
- package/dist/framework/node/node.d.ts.map +1 -0
- package/dist/framework/node/node.js +1009 -0
- package/dist/framework/node/node.js.map +1 -0
- package/dist/framework/orchestrator/orchestrator.d.ts +34 -0
- package/dist/framework/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/framework/orchestrator/orchestrator.js +691 -0
- package/dist/framework/orchestrator/orchestrator.js.map +1 -0
- package/dist/framework/orm/orm.d.ts +61 -0
- package/dist/framework/orm/orm.d.ts.map +1 -0
- package/dist/framework/orm/orm.js +620 -0
- package/dist/framework/orm/orm.js.map +1 -0
- package/dist/framework/python/analyze.d.ts +38 -0
- package/dist/framework/python/analyze.d.ts.map +1 -0
- package/dist/framework/python/analyze.js +98 -0
- package/dist/framework/python/analyze.js.map +1 -0
- package/dist/framework/python/py-ast.d.ts +130 -0
- package/dist/framework/python/py-ast.d.ts.map +1 -0
- package/dist/framework/python/py-ast.js +344 -0
- package/dist/framework/python/py-ast.js.map +1 -0
- package/dist/framework/python-orm/python-orm.d.ts +19 -0
- package/dist/framework/python-orm/python-orm.d.ts.map +1 -0
- package/dist/framework/python-orm/python-orm.js +516 -0
- package/dist/framework/python-orm/python-orm.js.map +1 -0
- package/dist/framework/react-native/react-native.d.ts +35 -0
- package/dist/framework/react-native/react-native.d.ts.map +1 -0
- package/dist/framework/react-native/react-native.js +1181 -0
- package/dist/framework/react-native/react-native.js.map +1 -0
- package/dist/framework/register.d.ts +2 -0
- package/dist/framework/register.d.ts.map +1 -0
- package/dist/framework/register.js +59 -0
- package/dist/framework/register.js.map +1 -0
- package/dist/framework/registry.d.ts +31 -0
- package/dist/framework/registry.d.ts.map +1 -0
- package/dist/framework/registry.js +70 -0
- package/dist/framework/registry.js.map +1 -0
- package/dist/framework/routing/expo-router.d.ts +31 -0
- package/dist/framework/routing/expo-router.d.ts.map +1 -0
- package/dist/framework/routing/expo-router.js +356 -0
- package/dist/framework/routing/expo-router.js.map +1 -0
- package/dist/framework/routing/index.d.ts +4 -0
- package/dist/framework/routing/index.d.ts.map +1 -0
- package/dist/framework/routing/index.js +16 -0
- package/dist/framework/routing/index.js.map +1 -0
- package/dist/framework/routing/next-router.d.ts +45 -0
- package/dist/framework/routing/next-router.d.ts.map +1 -0
- package/dist/framework/routing/next-router.js +378 -0
- package/dist/framework/routing/next-router.js.map +1 -0
- package/dist/framework/routing/route-tree.d.ts +73 -0
- package/dist/framework/routing/route-tree.d.ts.map +1 -0
- package/dist/framework/routing/route-tree.js +120 -0
- package/dist/framework/routing/route-tree.js.map +1 -0
- package/dist/framework/types.d.ts +230 -0
- package/dist/framework/types.d.ts.map +1 -0
- package/dist/framework/types.js +25 -0
- package/dist/framework/types.js.map +1 -0
- package/dist/graph/cross-language.d.ts +11 -0
- package/dist/graph/cross-language.d.ts.map +1 -0
- package/dist/graph/cross-language.js +123 -0
- package/dist/graph/cross-language.js.map +1 -0
- package/dist/graph/extract.d.ts +13 -0
- package/dist/graph/extract.d.ts.map +1 -0
- package/dist/graph/extract.js +79 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/file-graph.d.ts +186 -0
- package/dist/graph/file-graph.d.ts.map +1 -0
- package/dist/graph/file-graph.js +427 -0
- package/dist/graph/file-graph.js.map +1 -0
- package/dist/graph/http-callsites.d.ts +14 -0
- package/dist/graph/http-callsites.d.ts.map +1 -0
- package/dist/graph/http-callsites.js +107 -0
- package/dist/graph/http-callsites.js.map +1 -0
- package/dist/graph/incremental.d.ts +122 -0
- package/dist/graph/incremental.d.ts.map +1 -0
- package/dist/graph/incremental.js +448 -0
- package/dist/graph/incremental.js.map +1 -0
- package/dist/graph/language.d.ts +31 -0
- package/dist/graph/language.d.ts.map +1 -0
- package/dist/graph/language.js +146 -0
- package/dist/graph/language.js.map +1 -0
- package/dist/graph/noise-filter.d.ts +46 -0
- package/dist/graph/noise-filter.d.ts.map +1 -0
- package/dist/graph/noise-filter.js +199 -0
- package/dist/graph/noise-filter.js.map +1 -0
- package/dist/graph/python-adapter.d.ts +36 -0
- package/dist/graph/python-adapter.d.ts.map +1 -0
- package/dist/graph/python-adapter.js +402 -0
- package/dist/graph/python-adapter.js.map +1 -0
- package/dist/graph/python-manifest.d.ts +22 -0
- package/dist/graph/python-manifest.d.ts.map +1 -0
- package/dist/graph/python-manifest.js +137 -0
- package/dist/graph/python-manifest.js.map +1 -0
- package/dist/graph/python-stdlib.d.ts +2 -0
- package/dist/graph/python-stdlib.d.ts.map +1 -0
- package/dist/graph/python-stdlib.js +53 -0
- package/dist/graph/python-stdlib.js.map +1 -0
- package/dist/graph/ts-morph-adapter.d.ts +65 -0
- package/dist/graph/ts-morph-adapter.d.ts.map +1 -0
- package/dist/graph/ts-morph-adapter.js +265 -0
- package/dist/graph/ts-morph-adapter.js.map +1 -0
- package/dist/graph/types.d.ts +37 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +50 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/aws/aws-parse.d.ts +39 -0
- package/dist/infra/aws/aws-parse.d.ts.map +1 -0
- package/dist/infra/aws/aws-parse.js +149 -0
- package/dist/infra/aws/aws-parse.js.map +1 -0
- package/dist/infra/aws/aws.d.ts +6 -0
- package/dist/infra/aws/aws.d.ts.map +1 -0
- package/dist/infra/aws/aws.js +425 -0
- package/dist/infra/aws/aws.js.map +1 -0
- package/dist/infra/azure/azure-parse.d.ts +73 -0
- package/dist/infra/azure/azure-parse.d.ts.map +1 -0
- package/dist/infra/azure/azure-parse.js +178 -0
- package/dist/infra/azure/azure-parse.js.map +1 -0
- package/dist/infra/azure/azure.d.ts +12 -0
- package/dist/infra/azure/azure.d.ts.map +1 -0
- package/dist/infra/azure/azure.js +673 -0
- package/dist/infra/azure/azure.js.map +1 -0
- package/dist/infra/cloudflare/cloudflare.d.ts +50 -0
- package/dist/infra/cloudflare/cloudflare.d.ts.map +1 -0
- package/dist/infra/cloudflare/cloudflare.js +382 -0
- package/dist/infra/cloudflare/cloudflare.js.map +1 -0
- package/dist/infra/cloudflare/wrangler-parse.d.ts +6 -0
- package/dist/infra/cloudflare/wrangler-parse.d.ts.map +1 -0
- package/dist/infra/cloudflare/wrangler-parse.js +278 -0
- package/dist/infra/cloudflare/wrangler-parse.js.map +1 -0
- package/dist/infra/compose/compose-parse.d.ts +24 -0
- package/dist/infra/compose/compose-parse.d.ts.map +1 -0
- package/dist/infra/compose/compose-parse.js +77 -0
- package/dist/infra/compose/compose-parse.js.map +1 -0
- package/dist/infra/compose/compose.d.ts +12 -0
- package/dist/infra/compose/compose.d.ts.map +1 -0
- package/dist/infra/compose/compose.js +201 -0
- package/dist/infra/compose/compose.js.map +1 -0
- package/dist/infra/convex/convex-parse.d.ts +28 -0
- package/dist/infra/convex/convex-parse.d.ts.map +1 -0
- package/dist/infra/convex/convex-parse.js +74 -0
- package/dist/infra/convex/convex-parse.js.map +1 -0
- package/dist/infra/convex/convex.d.ts +18 -0
- package/dist/infra/convex/convex.d.ts.map +1 -0
- package/dist/infra/convex/convex.js +199 -0
- package/dist/infra/convex/convex.js.map +1 -0
- package/dist/infra/digitalocean/digitalocean.d.ts +33 -0
- package/dist/infra/digitalocean/digitalocean.d.ts.map +1 -0
- package/dist/infra/digitalocean/digitalocean.js +204 -0
- package/dist/infra/digitalocean/digitalocean.js.map +1 -0
- package/dist/infra/firebase/firebase.d.ts +43 -0
- package/dist/infra/firebase/firebase.d.ts.map +1 -0
- package/dist/infra/firebase/firebase.js +271 -0
- package/dist/infra/firebase/firebase.js.map +1 -0
- package/dist/infra/fly/fly-parse.d.ts +52 -0
- package/dist/infra/fly/fly-parse.d.ts.map +1 -0
- package/dist/infra/fly/fly-parse.js +114 -0
- package/dist/infra/fly/fly-parse.js.map +1 -0
- package/dist/infra/fly/fly.d.ts +15 -0
- package/dist/infra/fly/fly.d.ts.map +1 -0
- package/dist/infra/fly/fly.js +265 -0
- package/dist/infra/fly/fly.js.map +1 -0
- package/dist/infra/gcp/gcp-parse.d.ts +24 -0
- package/dist/infra/gcp/gcp-parse.d.ts.map +1 -0
- package/dist/infra/gcp/gcp-parse.js +123 -0
- package/dist/infra/gcp/gcp-parse.js.map +1 -0
- package/dist/infra/gcp/gcp.d.ts +10 -0
- package/dist/infra/gcp/gcp.d.ts.map +1 -0
- package/dist/infra/gcp/gcp.js +502 -0
- package/dist/infra/gcp/gcp.js.map +1 -0
- package/dist/infra/heroku/heroku-parse.d.ts +33 -0
- package/dist/infra/heroku/heroku-parse.d.ts.map +1 -0
- package/dist/infra/heroku/heroku-parse.js +63 -0
- package/dist/infra/heroku/heroku-parse.js.map +1 -0
- package/dist/infra/heroku/heroku.d.ts +24 -0
- package/dist/infra/heroku/heroku.d.ts.map +1 -0
- package/dist/infra/heroku/heroku.js +253 -0
- package/dist/infra/heroku/heroku.js.map +1 -0
- package/dist/infra/image-resolve.d.ts +56 -0
- package/dist/infra/image-resolve.d.ts.map +1 -0
- package/dist/infra/image-resolve.js +229 -0
- package/dist/infra/image-resolve.js.map +1 -0
- package/dist/infra/infra-step.d.ts +39 -0
- package/dist/infra/infra-step.d.ts.map +1 -0
- package/dist/infra/infra-step.js +57 -0
- package/dist/infra/infra-step.js.map +1 -0
- package/dist/infra/k8s/index.d.ts +78 -0
- package/dist/infra/k8s/index.d.ts.map +1 -0
- package/dist/infra/k8s/index.js +251 -0
- package/dist/infra/k8s/index.js.map +1 -0
- package/dist/infra/kamal/kamal-parse.d.ts +23 -0
- package/dist/infra/kamal/kamal-parse.d.ts.map +1 -0
- package/dist/infra/kamal/kamal-parse.js +66 -0
- package/dist/infra/kamal/kamal-parse.js.map +1 -0
- package/dist/infra/kamal/kamal.d.ts +17 -0
- package/dist/infra/kamal/kamal.d.ts.map +1 -0
- package/dist/infra/kamal/kamal.js +162 -0
- package/dist/infra/kamal/kamal.js.map +1 -0
- package/dist/infra/netlify/netlify.d.ts +33 -0
- package/dist/infra/netlify/netlify.d.ts.map +1 -0
- package/dist/infra/netlify/netlify.js +247 -0
- package/dist/infra/netlify/netlify.js.map +1 -0
- package/dist/infra/opentofu/opentofu.d.ts +3 -0
- package/dist/infra/opentofu/opentofu.d.ts.map +1 -0
- package/dist/infra/opentofu/opentofu.js +157 -0
- package/dist/infra/opentofu/opentofu.js.map +1 -0
- package/dist/infra/pulumi/pulumi-parse.d.ts +60 -0
- package/dist/infra/pulumi/pulumi-parse.d.ts.map +1 -0
- package/dist/infra/pulumi/pulumi-parse.js +155 -0
- package/dist/infra/pulumi/pulumi-parse.js.map +1 -0
- package/dist/infra/pulumi/pulumi.d.ts +23 -0
- package/dist/infra/pulumi/pulumi.d.ts.map +1 -0
- package/dist/infra/pulumi/pulumi.js +260 -0
- package/dist/infra/pulumi/pulumi.js.map +1 -0
- package/dist/infra/railway/railway-parse.d.ts +54 -0
- package/dist/infra/railway/railway-parse.d.ts.map +1 -0
- package/dist/infra/railway/railway-parse.js +200 -0
- package/dist/infra/railway/railway-parse.js.map +1 -0
- package/dist/infra/railway/railway.d.ts +19 -0
- package/dist/infra/railway/railway.d.ts.map +1 -0
- package/dist/infra/railway/railway.js +397 -0
- package/dist/infra/railway/railway.js.map +1 -0
- package/dist/infra/register.d.ts +2 -0
- package/dist/infra/register.d.ts.map +1 -0
- package/dist/infra/register.js +81 -0
- package/dist/infra/register.js.map +1 -0
- package/dist/infra/registry.d.ts +64 -0
- package/dist/infra/registry.d.ts.map +1 -0
- package/dist/infra/registry.js +205 -0
- package/dist/infra/registry.js.map +1 -0
- package/dist/infra/relevance.d.ts +16 -0
- package/dist/infra/relevance.d.ts.map +1 -0
- package/dist/infra/relevance.js +132 -0
- package/dist/infra/relevance.js.map +1 -0
- package/dist/infra/render/render-parse.d.ts +76 -0
- package/dist/infra/render/render-parse.d.ts.map +1 -0
- package/dist/infra/render/render-parse.js +155 -0
- package/dist/infra/render/render-parse.js.map +1 -0
- package/dist/infra/render/render.d.ts +11 -0
- package/dist/infra/render/render.d.ts.map +1 -0
- package/dist/infra/render/render.js +303 -0
- package/dist/infra/render/render.js.map +1 -0
- package/dist/infra/sst/sst-parse.d.ts +25 -0
- package/dist/infra/sst/sst-parse.d.ts.map +1 -0
- package/dist/infra/sst/sst-parse.js +45 -0
- package/dist/infra/sst/sst-parse.js.map +1 -0
- package/dist/infra/sst/sst.d.ts +19 -0
- package/dist/infra/sst/sst.d.ts.map +1 -0
- package/dist/infra/sst/sst.js +236 -0
- package/dist/infra/sst/sst.js.map +1 -0
- package/dist/infra/supabase/supabase-parse.d.ts +34 -0
- package/dist/infra/supabase/supabase-parse.d.ts.map +1 -0
- package/dist/infra/supabase/supabase-parse.js +113 -0
- package/dist/infra/supabase/supabase-parse.js.map +1 -0
- package/dist/infra/supabase/supabase.d.ts +15 -0
- package/dist/infra/supabase/supabase.d.ts.map +1 -0
- package/dist/infra/supabase/supabase.js +198 -0
- package/dist/infra/supabase/supabase.js.map +1 -0
- package/dist/infra/terraform/hcl-parse.d.ts +34 -0
- package/dist/infra/terraform/hcl-parse.d.ts.map +1 -0
- package/dist/infra/terraform/hcl-parse.js +203 -0
- package/dist/infra/terraform/hcl-parse.js.map +1 -0
- package/dist/infra/terraform/terraform.d.ts +14 -0
- package/dist/infra/terraform/terraform.d.ts.map +1 -0
- package/dist/infra/terraform/terraform.js +264 -0
- package/dist/infra/terraform/terraform.js.map +1 -0
- package/dist/infra/types.d.ts +151 -0
- package/dist/infra/types.d.ts.map +1 -0
- package/dist/infra/types.js +14 -0
- package/dist/infra/types.js.map +1 -0
- package/dist/infra/vercel/vercel-parse.d.ts +70 -0
- package/dist/infra/vercel/vercel-parse.d.ts.map +1 -0
- package/dist/infra/vercel/vercel-parse.js +194 -0
- package/dist/infra/vercel/vercel-parse.js.map +1 -0
- package/dist/infra/vercel/vercel.d.ts +30 -0
- package/dist/infra/vercel/vercel.d.ts.map +1 -0
- package/dist/infra/vercel/vercel.js +523 -0
- package/dist/infra/vercel/vercel.js.map +1 -0
- package/dist/infra/walk.d.ts +36 -0
- package/dist/infra/walk.d.ts.map +1 -0
- package/dist/infra/walk.js +85 -0
- package/dist/infra/walk.js.map +1 -0
- package/dist/safety.d.ts +13 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +67 -0
- package/dist/safety.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +111 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +35 -0
- package/dist/version.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
// the gRPC FrameworkAdapter. Net-new adapter following the FastAPI
|
|
2
|
+
// / Flask template, reusing the shared Python core
|
|
3
|
+
// (py-ast + parsePythonScope). gRPC's request surface is NOT HTTP
|
|
4
|
+
// routes — it's a set of RPC services declared in `.proto` files and IMPLEMENTED
|
|
5
|
+
// as Python `XServicer` subclasses, wired to a server, and consumed via generated
|
|
6
|
+
// client `XStub` classes. We read all of it STATICALLY (install-free,
|
|
7
|
+
// never-store-source — a pure syntactic Pyright parse + a light `.proto` line
|
|
8
|
+
// scan; never executes repo code), and persist only the derived groups/edges/roles:
|
|
9
|
+
//
|
|
10
|
+
// * detect() — the `grpcio` (/`grpcio-tools`) dependency; a SECONDARY
|
|
11
|
+
// signal is `.proto` files alongside generated
|
|
12
|
+
// `*_pb2_grpc.py` stubs (a repo that vendors the codegen
|
|
13
|
+
// output without declaring the runtime dep). Shallow nested
|
|
14
|
+
// scan for a `backend/`|`server/` package (mirrors FastAPI's
|
|
15
|
+
// ). EXISTENCE-only — never parses source in detect.
|
|
16
|
+
// * groupingPrior — one FrameworkGroup per gRPC SERVICE (the servicer impl
|
|
17
|
+
// file(s) for that service), so each service becomes its own
|
|
18
|
+
// named subsystem instead of one folder box. Same mechanism
|
|
19
|
+
// the FastAPI router / Flask blueprint / Nest @Module prior
|
|
20
|
+
// use: the contribute-step makes each group its own subsystem.
|
|
21
|
+
// * syntheticEdges — the wiring the import graph doesn't name as verbs:
|
|
22
|
+
// `add_XServicer_to_server(impl, server)` (server-setup file
|
|
23
|
+
// → the servicer impl file, kind 'calls') and a client
|
|
24
|
+
// `stub.SomeMethod(...)` call (the client file → the in-repo
|
|
25
|
+
// servicer impl of that service, kind 'calls' — the RPC
|
|
26
|
+
// boundary the structural graph can't see).
|
|
27
|
+
// * roleTags — an `XServicer` SUBCLASS (the RPC request entry) → `gateway`.
|
|
28
|
+
// The generated `*_pb2.py`/`*_pb2_grpc.py` stubs are
|
|
29
|
+
// recognized + SKIPPED (they're codegen noise, not a role).
|
|
30
|
+
// METADATA onto the LOCKED MODULE_KINDS enum; never a new
|
|
31
|
+
// kind (only `role` renders).
|
|
32
|
+
//
|
|
33
|
+
// Unresolvable wiring targets / client-only stub calls (no in-repo servicer for
|
|
34
|
+
// the service) DEGRADE + LOG — no silent caps.
|
|
35
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
36
|
+
import { join } from 'node:path';
|
|
37
|
+
import { clampConfidence, resolveBase } from '../detect-util.js';
|
|
38
|
+
import { readPythonDeps } from '../../graph/python-manifest.js';
|
|
39
|
+
import { parsePythonScope } from '../python/analyze.js';
|
|
40
|
+
import { callCallee, classBaseChains, memberChain, nameValue, positionalArgs, PN, } from '../python/py-ast.js';
|
|
41
|
+
// Non-source dirs the artifact scan skips (cheap + can't hold first-party protos).
|
|
42
|
+
const NESTED_SKIP_DIRS = new Set([
|
|
43
|
+
'node_modules',
|
|
44
|
+
'dist',
|
|
45
|
+
'build',
|
|
46
|
+
'out',
|
|
47
|
+
'coverage',
|
|
48
|
+
'venv',
|
|
49
|
+
'.venv',
|
|
50
|
+
'__pycache__',
|
|
51
|
+
'site-packages',
|
|
52
|
+
]);
|
|
53
|
+
// A generated gRPC/protobuf stub file (`foo_pb2.py`, `foo_pb2_grpc.py`, `.pyi`).
|
|
54
|
+
// These are codegen output — never a servicer role, never in a service group.
|
|
55
|
+
function isGeneratedStub(fileId) {
|
|
56
|
+
const base = fileId.split('/').pop() ?? fileId;
|
|
57
|
+
return /_pb2(_grpc)?\.pyi?$/.test(base);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Bounded recursive scan for gRPC artifacts (existence only — never reads file
|
|
61
|
+
* CONTENT). Returns whether a `.proto` and a generated `*_pb2_grpc.py` exist
|
|
62
|
+
* under `base`, and stops early once BOTH are found. Depth- and budget-capped so
|
|
63
|
+
* detect stays cheap on a large repo. Skips dot-dirs + non-source dirs.
|
|
64
|
+
*/
|
|
65
|
+
function scanGrpcArtifacts(base, maxDepth = 6, budget = 4000) {
|
|
66
|
+
let hasProto = false;
|
|
67
|
+
let hasGeneratedGrpc = false;
|
|
68
|
+
let visited = 0;
|
|
69
|
+
const walk = (dir, depth) => {
|
|
70
|
+
if (depth > maxDepth || visited > budget || (hasProto && hasGeneratedGrpc))
|
|
71
|
+
return;
|
|
72
|
+
let entries;
|
|
73
|
+
try {
|
|
74
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
for (const e of entries) {
|
|
80
|
+
if (++visited > budget)
|
|
81
|
+
return;
|
|
82
|
+
if (e.isDirectory()) {
|
|
83
|
+
if (e.name.startsWith('.') || NESTED_SKIP_DIRS.has(e.name))
|
|
84
|
+
continue;
|
|
85
|
+
walk(join(dir, e.name), depth + 1);
|
|
86
|
+
if (hasProto && hasGeneratedGrpc)
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
else if (e.isFile()) {
|
|
90
|
+
if (e.name.endsWith('.proto'))
|
|
91
|
+
hasProto = true;
|
|
92
|
+
else if (/_pb2_grpc\.pyi?$/.test(e.name))
|
|
93
|
+
hasGeneratedGrpc = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
walk(base, 0);
|
|
98
|
+
return { hasProto, hasGeneratedGrpc };
|
|
99
|
+
}
|
|
100
|
+
/** Gather the signal set for a single root dir (deps + artifact existence). */
|
|
101
|
+
export function gatherGrpcSignals(baseDir) {
|
|
102
|
+
const deps = readPythonDeps(baseDir);
|
|
103
|
+
// Always run the (bounded, early-terminating) artifact scan so the proto/stub
|
|
104
|
+
// signals are accurate regardless of the declared dep — the secondary match
|
|
105
|
+
// needs them WITHOUT a dep, and the `+0.1 proto` confidence bump then applies
|
|
106
|
+
// UNIFORMLY (not only on the depless path). The scan already runs for every
|
|
107
|
+
// non-grpc repo's detect anyway, so a grpc repo paying for it too is negligible.
|
|
108
|
+
const artifacts = scanGrpcArtifacts(baseDir);
|
|
109
|
+
return {
|
|
110
|
+
hasGrpcio: deps.has('grpcio'),
|
|
111
|
+
hasGrpcioTools: deps.has('grpcio-tools'),
|
|
112
|
+
hasProtoFiles: artifacts.hasProto,
|
|
113
|
+
hasGeneratedGrpc: artifacts.hasGeneratedGrpc,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/** True if `dir` holds a Python manifest worth scanning for deps. */
|
|
117
|
+
function hasPythonManifest(dir) {
|
|
118
|
+
return (existsSync(join(dir, 'pyproject.toml')) ||
|
|
119
|
+
existsSync(join(dir, 'setup.py')) ||
|
|
120
|
+
existsSync(join(dir, 'setup.cfg')) ||
|
|
121
|
+
existsSync(join(dir, 'requirements.txt')));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Immediate subdirs (depth 1) that contain a Python manifest — the shallow search
|
|
125
|
+
* for a nested gRPC backend (`backend/` | `server/` | `api/`). Sorted, so the
|
|
126
|
+
* first-match pick is deterministic; skips dot-dirs + non-source dirs.
|
|
127
|
+
*/
|
|
128
|
+
function shallowManifestSubdirs(base) {
|
|
129
|
+
let entries;
|
|
130
|
+
try {
|
|
131
|
+
entries = readdirSync(base, { withFileTypes: true });
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
const out = [];
|
|
137
|
+
for (const e of entries) {
|
|
138
|
+
if (!e.isDirectory() || e.name.startsWith('.') || NESTED_SKIP_DIRS.has(e.name))
|
|
139
|
+
continue;
|
|
140
|
+
if (hasPythonManifest(join(base, e.name)))
|
|
141
|
+
out.push(e.name);
|
|
142
|
+
}
|
|
143
|
+
return out.sort();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Decide gRPC from the signal set. `grpcio`/`grpcio-tools` is the authoritative
|
|
147
|
+
* signal; a SECONDARY match is `.proto` files alongside generated `*_pb2_grpc.py`
|
|
148
|
+
* (a repo that vendors the codegen output without declaring the runtime dep).
|
|
149
|
+
* Returns null → generic-Python fallthrough, byte-for-byte unchanged.
|
|
150
|
+
*/
|
|
151
|
+
export function scoreGrpc(s, rootPath = '') {
|
|
152
|
+
const hasDep = s.hasGrpcio || s.hasGrpcioTools;
|
|
153
|
+
const hasSecondary = s.hasProtoFiles && s.hasGeneratedGrpc;
|
|
154
|
+
if (!hasDep && !hasSecondary)
|
|
155
|
+
return null;
|
|
156
|
+
let confidence;
|
|
157
|
+
if (hasDep) {
|
|
158
|
+
confidence = 0.8;
|
|
159
|
+
if (s.hasGrpcioTools)
|
|
160
|
+
confidence += 0.05;
|
|
161
|
+
if (s.hasProtoFiles)
|
|
162
|
+
confidence += 0.1;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Proto + generated stubs, no declared dep — a real but weaker signal.
|
|
166
|
+
confidence = 0.6;
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
adapter: 'grpc',
|
|
170
|
+
confidence: clampConfidence(confidence),
|
|
171
|
+
rootPath,
|
|
172
|
+
metadata: {
|
|
173
|
+
signals: {
|
|
174
|
+
grpcio: s.hasGrpcio,
|
|
175
|
+
grpcioTools: s.hasGrpcioTools,
|
|
176
|
+
protoFiles: s.hasProtoFiles,
|
|
177
|
+
generatedGrpc: s.hasGeneratedGrpc,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const ROLE_PRIORITY = { servicer: 7 };
|
|
183
|
+
const ROLE_KIND = { servicer: 'gateway' };
|
|
184
|
+
// A servicer base class name ends in `Servicer` (generated `add_XServicer…`, the
|
|
185
|
+
// `XServicer` base in `*_pb2_grpc.py`); a client stub var is built from `XStub`.
|
|
186
|
+
const SERVICER_SUFFIX = 'Servicer';
|
|
187
|
+
const STUB_SUFFIX = 'Stub';
|
|
188
|
+
// The generated wiring function: `add_<Service>Servicer_to_server(impl, server)`.
|
|
189
|
+
const ADD_TO_SERVER_RE = /^add_(.+)Servicer_to_server$/;
|
|
190
|
+
// The async/future stub-call forms: `stub.Method.future(req)` / `.with_call(req)`
|
|
191
|
+
// — the RPC method is the FIRST segment, the callable modifier the second.
|
|
192
|
+
const STUB_CALL_MODIFIERS = new Set(['future', 'with_call']);
|
|
193
|
+
// Memoized on the FrameworkContext OBJECT (not repoDir) so groupingPrior +
|
|
194
|
+
// syntheticEdges + roleTags share ONE parse, while the merge walk's per-checkpoint
|
|
195
|
+
// ctx gets a fresh analysis — no cross-tree staleness. Mirrors fastapi / flask.
|
|
196
|
+
const ANALYSIS_CACHE = new WeakMap();
|
|
197
|
+
function slugify(s) {
|
|
198
|
+
return s
|
|
199
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
200
|
+
.toLowerCase()
|
|
201
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
202
|
+
.replace(/^-+|-+$/g, '');
|
|
203
|
+
}
|
|
204
|
+
function humanize(s) {
|
|
205
|
+
const words = s
|
|
206
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
207
|
+
.replace(/[_\-.]+/g, ' ')
|
|
208
|
+
.trim()
|
|
209
|
+
.split(/\s+/)
|
|
210
|
+
.filter(Boolean);
|
|
211
|
+
if (words.length === 0)
|
|
212
|
+
return s;
|
|
213
|
+
return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
214
|
+
}
|
|
215
|
+
function dirSegment(fileId) {
|
|
216
|
+
const slash = fileId.indexOf('/');
|
|
217
|
+
return slash > 0 ? slugify(fileId.slice(0, slash)) : 'root';
|
|
218
|
+
}
|
|
219
|
+
function addEdge(edges, from, to, kind, relation) {
|
|
220
|
+
if (from === to)
|
|
221
|
+
return; // intra-file wiring collapses; the step drops self-edges too
|
|
222
|
+
const key = `${from}→${to}:${kind}`;
|
|
223
|
+
if (!edges.has(key)) {
|
|
224
|
+
edges.set(key, { source: from, target: to, kind, metadata: { framework: 'grpc', relation } });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// The leaf name of a base-class / callee chain (`a.b.GreeterServicer` →
|
|
228
|
+
// 'GreeterServicer'; a bare `GreeterServicer` → 'GreeterServicer').
|
|
229
|
+
function chainLeaf(chain) {
|
|
230
|
+
return chain.path.length ? chain.path[chain.path.length - 1] : chain.root;
|
|
231
|
+
}
|
|
232
|
+
// The constructor name of an `x = Ctor(...)` assignment RHS (last chain segment,
|
|
233
|
+
// so both `GreeterStub(...)` and `pb2_grpc.GreeterStub(...)` read as 'GreeterStub'),
|
|
234
|
+
// or undefined when the RHS isn't a plain call.
|
|
235
|
+
function assignedCtorName(rhs) {
|
|
236
|
+
if (rhs.nodeType !== PN.Call)
|
|
237
|
+
return undefined;
|
|
238
|
+
const callee = callCallee(rhs);
|
|
239
|
+
if (!callee)
|
|
240
|
+
return undefined;
|
|
241
|
+
return chainLeaf(callee);
|
|
242
|
+
}
|
|
243
|
+
// The constructed class name of an expression used as an argument: a direct
|
|
244
|
+
// `Greeter()` call → 'Greeter'; anything else (a Name, a subscript) → undefined
|
|
245
|
+
// (the caller falls back to a same-file `var = Ctor()` lookup / the service name).
|
|
246
|
+
function constructedClassName(expr) {
|
|
247
|
+
if (!expr || expr.nodeType !== PN.Call)
|
|
248
|
+
return undefined;
|
|
249
|
+
const callee = callCallee(expr);
|
|
250
|
+
return callee ? chainLeaf(callee) : undefined;
|
|
251
|
+
}
|
|
252
|
+
// Assign each service its final, collision-free group id ORDER-INDEPENDENTLY:
|
|
253
|
+
// process seeds by service name so the id set is identical run-to-run (the
|
|
254
|
+
// snapshot grouping-stability invariant); collisions take a `-<dirSegment>` then
|
|
255
|
+
// `-<n>` suffix.
|
|
256
|
+
function assignServiceGroups(seeds) {
|
|
257
|
+
const taken = new Set();
|
|
258
|
+
const ordered = [...seeds].sort((a, b) => (a.service < b.service ? -1 : a.service > b.service ? 1 : 0));
|
|
259
|
+
const groups = [];
|
|
260
|
+
for (const seed of ordered) {
|
|
261
|
+
const firstFile = [...seed.fileIds].sort()[0] ?? '';
|
|
262
|
+
let id = seed.baseSlug;
|
|
263
|
+
if (taken.has(id))
|
|
264
|
+
id = `${seed.baseSlug}-${dirSegment(firstFile)}`;
|
|
265
|
+
let n = 2;
|
|
266
|
+
while (taken.has(id))
|
|
267
|
+
id = `${seed.baseSlug}-${n++}`;
|
|
268
|
+
taken.add(id);
|
|
269
|
+
groups.push({ id, label: seed.label, fileIds: [...seed.fileIds].sort() });
|
|
270
|
+
}
|
|
271
|
+
return groups.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
272
|
+
}
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
// `.proto` service parsing (a light line/regex scan — enrichment only). The
|
|
275
|
+
// service/method structure partly lives in the proto; we surface the RPC method
|
|
276
|
+
// inventory onto the servicer role metadata. Never install-dependent.
|
|
277
|
+
// Word-boundary anchored (not line-start) so both the conventional multiline
|
|
278
|
+
// layout AND an inline `service X { rpc M(...) }` are recognized. `\bservice X {`
|
|
279
|
+
// won't match a `string service = 1;` field (no `{` follows the name).
|
|
280
|
+
const PROTO_SERVICE_RE = /\bservice\s+([A-Za-z_]\w*)\s*\{/g;
|
|
281
|
+
const PROTO_RPC_RE = /\brpc\s+([A-Za-z_]\w*)\s*\(/g;
|
|
282
|
+
/** Parse `service X { rpc M(...) … }` blocks → service name → sorted rpc methods. */
|
|
283
|
+
export function parseProtoServices(text) {
|
|
284
|
+
const out = new Map();
|
|
285
|
+
PROTO_SERVICE_RE.lastIndex = 0;
|
|
286
|
+
let m;
|
|
287
|
+
// Find each service block's body by brace matching from the service header.
|
|
288
|
+
while ((m = PROTO_SERVICE_RE.exec(text)) !== null) {
|
|
289
|
+
const service = m[1];
|
|
290
|
+
const bodyStart = text.indexOf('{', m.index);
|
|
291
|
+
if (bodyStart < 0)
|
|
292
|
+
continue;
|
|
293
|
+
// Walk to the matching close brace (proto service bodies don't nest braces
|
|
294
|
+
// except in message-less rpc option blocks — a depth counter handles those).
|
|
295
|
+
let depth = 0;
|
|
296
|
+
let i = bodyStart;
|
|
297
|
+
for (; i < text.length; i++) {
|
|
298
|
+
if (text[i] === '{')
|
|
299
|
+
depth++;
|
|
300
|
+
else if (text[i] === '}') {
|
|
301
|
+
depth--;
|
|
302
|
+
if (depth === 0)
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const body = text.slice(bodyStart, i);
|
|
307
|
+
const methods = new Set();
|
|
308
|
+
PROTO_RPC_RE.lastIndex = 0;
|
|
309
|
+
let r;
|
|
310
|
+
while ((r = PROTO_RPC_RE.exec(body)) !== null)
|
|
311
|
+
methods.add(r[1]);
|
|
312
|
+
const existing = out.get(service) ?? [];
|
|
313
|
+
out.set(service, [...new Set([...existing, ...methods])].sort());
|
|
314
|
+
}
|
|
315
|
+
return out;
|
|
316
|
+
}
|
|
317
|
+
// Bounded recursive scan for in-scope `.proto` files (reads CONTENT — this is
|
|
318
|
+
// analysis, which declares scansSourcePath, not detect). Depth/budget-capped.
|
|
319
|
+
function collectProtoServices(baseDir) {
|
|
320
|
+
const services = new Map();
|
|
321
|
+
let visited = 0;
|
|
322
|
+
const walk = (dir, depth) => {
|
|
323
|
+
if (depth > 8 || visited > 8000)
|
|
324
|
+
return;
|
|
325
|
+
let entries;
|
|
326
|
+
try {
|
|
327
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
for (const e of entries.sort((a, b) => (a.name < b.name ? -1 : 1))) {
|
|
333
|
+
if (++visited > 8000)
|
|
334
|
+
return;
|
|
335
|
+
if (e.isDirectory()) {
|
|
336
|
+
if (e.name.startsWith('.') || NESTED_SKIP_DIRS.has(e.name))
|
|
337
|
+
continue;
|
|
338
|
+
walk(join(dir, e.name), depth + 1);
|
|
339
|
+
}
|
|
340
|
+
else if (e.isFile() && e.name.endsWith('.proto')) {
|
|
341
|
+
let text;
|
|
342
|
+
try {
|
|
343
|
+
text = readFileSync(join(dir, e.name), 'utf8');
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
for (const [svc, methods] of parseProtoServices(text)) {
|
|
349
|
+
const merged = new Set([...(services.get(svc) ?? []), ...methods]);
|
|
350
|
+
services.set(svc, [...merged].sort());
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
walk(baseDir, 0);
|
|
356
|
+
return services;
|
|
357
|
+
}
|
|
358
|
+
function analyzeGrpc(ctx) {
|
|
359
|
+
const { repoDir, rootPath } = ctx;
|
|
360
|
+
const { parsed } = parsePythonScope(ctx);
|
|
361
|
+
// Pass 1 — servicer impl classes + client stub vars + same-file ctor vars.
|
|
362
|
+
// servicerClassesByFile : file → its servicer impl CLASS names (same-file resolve)
|
|
363
|
+
// servicerFilesByService : service name → the impl file(s) (wiring/stub target)
|
|
364
|
+
// servicesByFile : file → the services it implements (role metadata)
|
|
365
|
+
// stubServiceByVar : file → (stub var → service) (client stub calls)
|
|
366
|
+
// ctorVarByFile : file → (var → constructed class) (wiring var-arg)
|
|
367
|
+
const servicerClassesByFile = new Map();
|
|
368
|
+
const servicerFilesByService = new Map();
|
|
369
|
+
const servicesByFile = new Map();
|
|
370
|
+
const stubServiceByVar = new Map();
|
|
371
|
+
const ctorVarByFile = new Map();
|
|
372
|
+
const roleByFile = new Map();
|
|
373
|
+
for (const [id, file] of parsed) {
|
|
374
|
+
const generated = isGeneratedStub(id);
|
|
375
|
+
const stubVars = new Map();
|
|
376
|
+
const ctorVars = new Map();
|
|
377
|
+
for (const a of file.nodes.assignments) {
|
|
378
|
+
const target = nameValue(a.d.leftExpr);
|
|
379
|
+
if (!target)
|
|
380
|
+
continue;
|
|
381
|
+
const ctor = assignedCtorName(a.d.rightExpr);
|
|
382
|
+
if (!ctor)
|
|
383
|
+
continue;
|
|
384
|
+
ctorVars.set(target, ctor);
|
|
385
|
+
// A client stub var: `x = GreeterStub(channel)` → service 'Greeter'.
|
|
386
|
+
if (ctor.endsWith(STUB_SUFFIX) && ctor.length > STUB_SUFFIX.length) {
|
|
387
|
+
stubVars.set(target, ctor.slice(0, -STUB_SUFFIX.length));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
stubServiceByVar.set(id, stubVars);
|
|
391
|
+
ctorVarByFile.set(id, ctorVars);
|
|
392
|
+
if (generated)
|
|
393
|
+
continue; // never a servicer role / group; codegen noise
|
|
394
|
+
for (const cls of file.nodes.classes) {
|
|
395
|
+
const className = nameValue(cls.d.name);
|
|
396
|
+
if (!className)
|
|
397
|
+
continue;
|
|
398
|
+
for (const base of classBaseChains(cls)) {
|
|
399
|
+
const leaf = chainLeaf(base);
|
|
400
|
+
if (!leaf.endsWith(SERVICER_SUFFIX) || leaf.length === SERVICER_SUFFIX.length)
|
|
401
|
+
continue;
|
|
402
|
+
const service = leaf.slice(0, -SERVICER_SUFFIX.length);
|
|
403
|
+
(servicerClassesByFile.get(id) ?? servicerClassesByFile.set(id, new Set()).get(id)).add(className);
|
|
404
|
+
(servicerFilesByService.get(service) ?? servicerFilesByService.set(service, new Set()).get(service)).add(id);
|
|
405
|
+
(servicesByFile.get(id) ?? servicesByFile.set(id, new Set()).get(id)).add(service);
|
|
406
|
+
roleByFile.set(id, 'servicer');
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const edges = new Map();
|
|
411
|
+
const diag = {
|
|
412
|
+
unresolvedWiring: new Set(),
|
|
413
|
+
clientOnlyStubs: new Set(),
|
|
414
|
+
ambiguousWiring: new Set(),
|
|
415
|
+
};
|
|
416
|
+
// The unique in-repo servicer impl file for a service, or undefined (0 or >1).
|
|
417
|
+
// A service with >1 impl is logged as ambiguous (can't pick a wiring/stub target).
|
|
418
|
+
const uniqueImpl = (service) => {
|
|
419
|
+
const files = servicerFilesByService.get(service);
|
|
420
|
+
if (!files || files.size === 0)
|
|
421
|
+
return undefined;
|
|
422
|
+
if (files.size > 1) {
|
|
423
|
+
diag.ambiguousWiring.add(`${service} (${[...files].sort().join(', ')})`);
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
return [...files][0];
|
|
427
|
+
};
|
|
428
|
+
// Pass 2 — wiring + stub-call edges. Generated stubs are skipped (a
|
|
429
|
+
// `*_pb2_grpc.py` never CALLS add_*_to_server / instantiates a stub — it only
|
|
430
|
+
// DEFINES them — but skipping keeps codegen strictly out of the contribution).
|
|
431
|
+
for (const [id, file] of parsed) {
|
|
432
|
+
if (isGeneratedStub(id))
|
|
433
|
+
continue;
|
|
434
|
+
const stubVars = stubServiceByVar.get(id);
|
|
435
|
+
const ctorVars = ctorVarByFile.get(id);
|
|
436
|
+
const binds = file.bindings;
|
|
437
|
+
for (const call of file.nodes.calls) {
|
|
438
|
+
const callee = callCallee(call);
|
|
439
|
+
if (!callee)
|
|
440
|
+
continue;
|
|
441
|
+
const leaf = chainLeaf(callee);
|
|
442
|
+
// (a) `add_<Service>Servicer_to_server(impl, server)` wiring.
|
|
443
|
+
const wire = ADD_TO_SERVER_RE.exec(leaf);
|
|
444
|
+
if (wire) {
|
|
445
|
+
const service = wire[1];
|
|
446
|
+
// Resolve the impl instance to its servicer file. Prefer the constructed-
|
|
447
|
+
// class arg (`Greeter()` / a `var = Greeter()`), resolved SAME-FILE FIRST
|
|
448
|
+
// (the common grpc layout: impl + bootstrap in one module → a self-edge,
|
|
449
|
+
// dropped), then the file it was IMPORTED from (the production layout:
|
|
450
|
+
// impl in a `servicers/` module → a real cross-module edge). Fall back to
|
|
451
|
+
// the service's UNIQUE in-repo impl only when the impl arg isn't a plain
|
|
452
|
+
// ctor/var — never a global class-name guess (name collisions mis-resolve).
|
|
453
|
+
const firstArg = positionalArgs(call)[0];
|
|
454
|
+
let implClass = constructedClassName(firstArg);
|
|
455
|
+
if (!implClass) {
|
|
456
|
+
const varName = firstArg ? nameValue(firstArg) : undefined;
|
|
457
|
+
if (varName)
|
|
458
|
+
implClass = ctorVars.get(varName);
|
|
459
|
+
}
|
|
460
|
+
let target;
|
|
461
|
+
if (implClass) {
|
|
462
|
+
if (servicerClassesByFile.get(id)?.has(implClass))
|
|
463
|
+
target = id; // same-file
|
|
464
|
+
else {
|
|
465
|
+
const bound = binds.get(implClass); // imported from another module
|
|
466
|
+
if (bound && roleByFile.has(bound))
|
|
467
|
+
target = bound;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!target)
|
|
471
|
+
target = uniqueImpl(service);
|
|
472
|
+
if (target)
|
|
473
|
+
addEdge(edges, id, target, 'calls', 'add-servicer-to-server');
|
|
474
|
+
else
|
|
475
|
+
diag.unresolvedWiring.add(`${id}: add_${service}Servicer_to_server(…)`);
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
// (b) a client stub call — `stub` is a known stub var. Two shapes: the
|
|
479
|
+
// direct `stub.SomeMethod(req)` (RPC method = the one segment) and the
|
|
480
|
+
// async/future `stub.SomeMethod.future(req)` / `.with_call(req)` (RPC method
|
|
481
|
+
// = the first segment, a modifier second). Skip dunder methods. Either →
|
|
482
|
+
// a cross-module call to the in-repo servicer impl of that service.
|
|
483
|
+
const service = stubVars.get(callee.root);
|
|
484
|
+
const isDirectRpc = callee.path.length === 1 && !callee.path[0].startsWith('_');
|
|
485
|
+
const isFutureRpc = callee.path.length === 2 &&
|
|
486
|
+
!callee.path[0].startsWith('_') &&
|
|
487
|
+
STUB_CALL_MODIFIERS.has(callee.path[1]);
|
|
488
|
+
if (service && (isDirectRpc || isFutureRpc)) {
|
|
489
|
+
const rpc = callee.path[0];
|
|
490
|
+
const target = uniqueImpl(service);
|
|
491
|
+
if (target)
|
|
492
|
+
addEdge(edges, id, target, 'calls', 'stub-call');
|
|
493
|
+
else
|
|
494
|
+
diag.clientOnlyStubs.add(`${id}: ${callee.root}.${rpc}(…) [service ${service}]`);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// `.proto` enrichment — the RPC method inventory per service, attached to the
|
|
499
|
+
// servicer role metadata (the service structure partly lives in the proto).
|
|
500
|
+
const protoServices = collectProtoServices(join(repoDir, rootPath));
|
|
501
|
+
// Grouping seeds — one per service (its impl file(s)).
|
|
502
|
+
const seeds = [];
|
|
503
|
+
for (const [service, files] of servicerFilesByService) {
|
|
504
|
+
seeds.push({
|
|
505
|
+
service,
|
|
506
|
+
fileIds: new Set(files),
|
|
507
|
+
baseSlug: slugify(service) || 'service',
|
|
508
|
+
label: humanize(service) || service,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
const groups = assignServiceGroups(seeds);
|
|
512
|
+
const roles = new Map();
|
|
513
|
+
for (const [fileId, role] of roleByFile) {
|
|
514
|
+
const services = [...(servicesByFile.get(fileId) ?? [])].sort();
|
|
515
|
+
const rpcMethods = [
|
|
516
|
+
...new Set(services.flatMap((s) => protoServices.get(s) ?? [])),
|
|
517
|
+
].sort();
|
|
518
|
+
roles.set(fileId, {
|
|
519
|
+
role,
|
|
520
|
+
kind: ROLE_KIND[role],
|
|
521
|
+
priority: ROLE_PRIORITY[role],
|
|
522
|
+
metadata: {
|
|
523
|
+
framework: 'grpc',
|
|
524
|
+
services,
|
|
525
|
+
...(rpcMethods.length ? { rpcMethods } : {}),
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
const sortedEdges = [...edges.values()].sort((a, b) => a.source < b.source
|
|
530
|
+
? -1
|
|
531
|
+
: a.source > b.source
|
|
532
|
+
? 1
|
|
533
|
+
: a.target < b.target
|
|
534
|
+
? -1
|
|
535
|
+
: a.target > b.target
|
|
536
|
+
? 1
|
|
537
|
+
: a.kind < b.kind
|
|
538
|
+
? -1
|
|
539
|
+
: a.kind > b.kind
|
|
540
|
+
? 1
|
|
541
|
+
: 0);
|
|
542
|
+
// Positive signal for validation (mirrors fastapi/flask's log line).
|
|
543
|
+
if (groups.length > 0 || roleByFile.size > 0 || sortedEdges.length > 0) {
|
|
544
|
+
console.log(` [grpc] ${roleByFile.size} servicer role(s) · ${groups.length} service group(s) · ${sortedEdges.length} edge(s)` +
|
|
545
|
+
(protoServices.size ? ` · ${protoServices.size} proto service(s)` : ''));
|
|
546
|
+
}
|
|
547
|
+
// No silent caps (locked): log everything that degraded.
|
|
548
|
+
if (diag.unresolvedWiring.size > 0 || diag.clientOnlyStubs.size > 0 || diag.ambiguousWiring.size > 0) {
|
|
549
|
+
const parts = [];
|
|
550
|
+
if (diag.unresolvedWiring.size > 0) {
|
|
551
|
+
parts.push(`${diag.unresolvedWiring.size} unresolvable wiring: ${[...diag.unresolvedWiring].sort().slice(0, 10).join(' · ')}`);
|
|
552
|
+
}
|
|
553
|
+
if (diag.clientOnlyStubs.size > 0) {
|
|
554
|
+
parts.push(`${diag.clientOnlyStubs.size} client-only stub call(s) (no in-repo servicer): ${[...diag.clientOnlyStubs].sort().slice(0, 10).join(' · ')}`);
|
|
555
|
+
}
|
|
556
|
+
if (diag.ambiguousWiring.size > 0) {
|
|
557
|
+
parts.push(`${diag.ambiguousWiring.size} service(s) with multiple impls: ${[...diag.ambiguousWiring].sort().slice(0, 10).join(' · ')}`);
|
|
558
|
+
}
|
|
559
|
+
console.log(` [grpc] degraded: ${parts.join(' · ')} (logged, not silently dropped)`);
|
|
560
|
+
}
|
|
561
|
+
return { groups, edges: sortedEdges, roles };
|
|
562
|
+
}
|
|
563
|
+
function getAnalysis(ctx) {
|
|
564
|
+
let a = ANALYSIS_CACHE.get(ctx);
|
|
565
|
+
if (!a) {
|
|
566
|
+
a = analyzeGrpc(ctx);
|
|
567
|
+
ANALYSIS_CACHE.set(ctx, a);
|
|
568
|
+
}
|
|
569
|
+
return a;
|
|
570
|
+
}
|
|
571
|
+
// ---------------------------------------------------------------------------
|
|
572
|
+
// The adapter.
|
|
573
|
+
export const grpcAdapter = {
|
|
574
|
+
name: 'grpc',
|
|
575
|
+
async detect(ctx) {
|
|
576
|
+
const { base, rootPath } = resolveBase(ctx);
|
|
577
|
+
// Root scan first (a repo whose manifest is at root reports rootPath '').
|
|
578
|
+
const rootMatch = scoreGrpc(gatherGrpcSignals(base), rootPath);
|
|
579
|
+
if (rootMatch)
|
|
580
|
+
return rootMatch;
|
|
581
|
+
// A gRPC backend often lives one dir down (a `backend/` | `server/` package
|
|
582
|
+
// in a frontend+backend monorepo), so a root-only scan misses it. Shallow-scan
|
|
583
|
+
// immediate subdirs for a grpc manifest and scope to it. Only when NOT already
|
|
584
|
+
// scoped to a workspace package (the path).
|
|
585
|
+
if (!ctx.packageDir) {
|
|
586
|
+
for (const sub of shallowManifestSubdirs(base)) {
|
|
587
|
+
const m = scoreGrpc(gatherGrpcSignals(join(base, sub)), sub);
|
|
588
|
+
if (m)
|
|
589
|
+
return m;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
return null;
|
|
593
|
+
},
|
|
594
|
+
// One grouping prior per gRPC SERVICE → its own subsystem, authoritative over
|
|
595
|
+
// directory grouping (the fastapi/flask/nest mechanism). Fully deterministic
|
|
596
|
+
// (service-name-derived) → no classificationsNeeded.
|
|
597
|
+
async groupingPrior(ctx) {
|
|
598
|
+
return { groups: getAnalysis(ctx).groups };
|
|
599
|
+
},
|
|
600
|
+
// add_XServicer_to_server wiring + client stub.Method() calls (kind 'calls').
|
|
601
|
+
// File-id endpoints; the step resolves to modules, drops self-edges, dedupes,
|
|
602
|
+
// 8-verb-validates.
|
|
603
|
+
async syntheticEdges(ctx) {
|
|
604
|
+
return getAnalysis(ctx).edges;
|
|
605
|
+
},
|
|
606
|
+
// An XServicer subclass → gateway (RPC request entry). METADATA; the module's
|
|
607
|
+
// `kind` is unchanged. Generated `*_pb2_grpc.py` stubs are skipped.
|
|
608
|
+
async roleTags(ctx) {
|
|
609
|
+
return getAnalysis(ctx).roles;
|
|
610
|
+
},
|
|
611
|
+
// The hooks READ SOURCE (Python + `.proto`). Declare the paths the diff-driven
|
|
612
|
+
// hosted walk must treat as framework-relevant. Never-store-source holds: parse
|
|
613
|
+
// server-side, persist only the derived groups/edges/roles.
|
|
614
|
+
scansSourcePath(path) {
|
|
615
|
+
return path.endsWith('.py') || path.endsWith('.pyi') || path.endsWith('.proto');
|
|
616
|
+
},
|
|
617
|
+
};
|
|
618
|
+
//# sourceMappingURL=grpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grpc.js","sourceRoot":"","sources":["../../../src/framework/grpc/grpc.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,mDAAmD;AACnD,kEAAkE;AAClE,iFAAiF;AACjF,kFAAkF;AAClF,sEAAsE;AACtE,8EAA8E;AAC9E,oFAAoF;AACpF,EAAE;AACF,+EAA+E;AAC/E,qEAAqE;AACrE,+EAA+E;AAC/E,kFAAkF;AAClF,mFAAmF;AACnF,2EAA2E;AAC3E,+EAA+E;AAC/E,mFAAmF;AACnF,kFAAkF;AAClF,kFAAkF;AAClF,qFAAqF;AACrF,2EAA2E;AAC3E,mFAAmF;AACnF,6EAA6E;AAC7E,mFAAmF;AACnF,8EAA8E;AAC9E,kEAAkE;AAClE,qFAAqF;AACrF,2EAA2E;AAC3E,kFAAkF;AAClF,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,gFAAgF;AAChF,+CAA+C;AAE/C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,UAAU,EACV,eAAe,EACf,WAAW,EACX,SAAS,EACT,cAAc,EACd,EAAE,GACH,MAAM,qBAAqB,CAAC;AA6B7B,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,cAAc;IACd,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;CAChB,CAAC,CAAC;AAEH,iFAAiF;AACjF,8EAA8E;AAC9E,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC;IAC/C,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAClE,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,KAAa,EAAQ,EAAE;QAChD,IAAI,KAAK,GAAG,QAAQ,IAAI,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,IAAI,gBAAgB,CAAC;YAAE,OAAO;QACnF,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,EAAE,OAAO,GAAG,MAAM;gBAAE,OAAO;YAC/B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpB,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACrE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACnC,IAAI,QAAQ,IAAI,gBAAgB;oBAAE,OAAO;YAC3C,CAAC;iBAAM,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAAE,QAAQ,GAAG,IAAI,CAAC;qBAC1C,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,gBAAgB,GAAG,IAAI,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACd,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,8EAA8E;IAC9E,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,iFAAiF;IACjF,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;QACxC,aAAa,EAAE,SAAS,CAAC,QAAQ;QACjC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC7C,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACvC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACjC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAClC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAC1C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,SAAS;QACzF,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,CAAc,EAAE,QAAQ,GAAG,EAAE;IACrD,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,cAAc,CAAC;IAC/C,MAAM,YAAY,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,gBAAgB,CAAC;IAC3D,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,UAAkB,CAAC;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,UAAU,GAAG,GAAG,CAAC;QACjB,IAAI,CAAC,CAAC,cAAc;YAAE,UAAU,IAAI,IAAI,CAAC;QACzC,IAAI,CAAC,CAAC,aAAa;YAAE,UAAU,IAAI,GAAG,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,uEAAuE;QACvE,UAAU,GAAG,GAAG,CAAC;IACnB,CAAC;IACD,OAAO;QACL,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,eAAe,CAAC,UAAU,CAAC;QACvC,QAAQ;QACR,QAAQ,EAAE;YACR,OAAO,EAAE;gBACP,MAAM,EAAE,CAAC,CAAC,SAAS;gBACnB,WAAW,EAAE,CAAC,CAAC,cAAc;gBAC7B,UAAU,EAAE,CAAC,CAAC,aAAa;gBAC3B,aAAa,EAAE,CAAC,CAAC,gBAAgB;aAClC;SACF;KACF,CAAC;AACJ,CAAC;AAMD,MAAM,aAAa,GAA6B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AAChE,MAAM,SAAS,GAAiC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAExE,iFAAiF;AACjF,iFAAiF;AACjF,MAAM,eAAe,GAAG,UAAU,CAAC;AACnC,MAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,kFAAkF;AAClF,MAAM,gBAAgB,GAAG,8BAA8B,CAAC;AACxD,kFAAkF;AAClF,2EAA2E;AAC3E,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAiB7D,2EAA2E;AAC3E,mFAAmF;AACnF,gFAAgF;AAChF,MAAM,cAAc,GAAG,IAAI,OAAO,EAAkC,CAAC;AAErE,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC;SACL,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,MAAM,KAAK,GAAG,CAAC;SACZ,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9D,CAAC;AAED,SAAS,OAAO,CACd,KAAiC,EACjC,IAAY,EACZ,EAAU,EACV,IAA2B,EAC3B,QAAgB;IAEhB,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,CAAC,6DAA6D;IACtF,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,oEAAoE;AACpE,SAAS,SAAS,CAAC,KAAuC;IACxD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,iFAAiF;AACjF,qFAAqF;AACrF,gDAAgD;AAChD,SAAS,gBAAgB,CAAC,GAAmB;IAC3C,IAAK,GAAiB,CAAC,QAAQ,KAAK,EAAE,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,GAAe,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,4EAA4E;AAC5E,gFAAgF;AAChF,mFAAmF;AACnF,SAAS,oBAAoB,CAAC,IAAgC;IAC5D,IAAI,CAAC,IAAI,IAAK,IAAkB,CAAC,QAAQ,KAAK,EAAE,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IACxE,MAAM,MAAM,GAAG,UAAU,CAAC,IAAgB,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAWD,8EAA8E;AAC9E,2EAA2E;AAC3E,iFAAiF;AACjF,iBAAiB;AACjB,SAAS,mBAAmB,CAAC,KAAyB;IACpD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACvB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;QACrD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,8EAA8E;AAC9E,4EAA4E;AAC5E,gFAAgF;AAChF,sEAAsE;AAEtE,6EAA6E;AAC7E,kFAAkF;AAClF,uEAAuE;AACvE,MAAM,gBAAgB,GAAG,kCAAkC,CAAC;AAC5D,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,gBAAgB,CAAC,SAAS,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAyB,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,SAAS,GAAG,CAAC;YAAE,SAAS;QAC5B,2EAA2E;QAC3E,6EAA6E;QAC7E,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,GAAG,SAAS,CAAC;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,KAAK,EAAE,CAAC;iBACxB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACzB,KAAK,EAAE,CAAC;gBACR,IAAI,KAAK,KAAK,CAAC;oBAAE,MAAM;YACzB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACxC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC7C,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,KAAa,EAAQ,EAAE;QAChD,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,IAAI;YAAE,OAAO;QACxC,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,IAAI,EAAE,OAAO,GAAG,IAAI;gBAAE,OAAO;YAC7B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpB,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACrE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnD,IAAI,IAAY,CAAC;gBACjB,IAAI,CAAC;oBACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;gBACD,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;oBACnE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACjB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,GAAqB;IACxC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;IAClC,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEzC,2EAA2E;IAC3E,sFAAsF;IACtF,kFAAkF;IAClF,+EAA+E;IAC/E,6EAA6E;IAC7E,+EAA+E;IAC/E,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7D,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAuB,CAAC;IACtD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA+B,CAAC;IAChE,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE/C,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC3B,qEAAqE;YACrE,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;gBACnE,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QACD,gBAAgB,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACnC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAEhC,IAAI,SAAS;YAAE,SAAS,CAAC,+CAA+C;QAExE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,eAAe,CAAC,MAAM;oBAAE,SAAS;gBACxF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBACvD,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACpG,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC9G,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACpF,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,MAAM,IAAI,GAAa;QACrB,gBAAgB,EAAE,IAAI,GAAG,EAAE;QAC3B,eAAe,EAAE,IAAI,GAAG,EAAE;QAC1B,eAAe,EAAE,IAAI,GAAG,EAAE;KAC3B,CAAC;IAEF,+EAA+E;IAC/E,mFAAmF;IACnF,MAAM,UAAU,GAAG,CAAC,OAAe,EAAsB,EAAE;QACzD,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACjD,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,oEAAoE;IACpE,8EAA8E;IAC9E,+EAA+E;IAC/E,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QAChC,IAAI,eAAe,CAAC,EAAE,CAAC;YAAE,SAAS;QAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAE/B,8DAA8D;YAC9D,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACxB,0EAA0E;gBAC1E,0EAA0E;gBAC1E,yEAAyE;gBACzE,uEAAuE;gBACvE,0EAA0E;gBAC1E,yEAAyE;gBACzE,4EAA4E;gBAC5E,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzC,IAAI,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;gBAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC3D,IAAI,OAAO;wBAAE,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACjD,CAAC;gBACD,IAAI,MAA0B,CAAC;gBAC/B,IAAI,SAAS,EAAE,CAAC;oBACd,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC;wBAAE,MAAM,GAAG,EAAE,CAAC,CAAC,YAAY;yBACvE,CAAC;wBACJ,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,+BAA+B;wBACnE,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;4BAAE,MAAM,GAAG,KAAK,CAAC;oBACrD,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,MAAM;oBAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC1C,IAAI,MAAM;oBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,CAAC,CAAC;;oBACrE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,OAAO,uBAAuB,CAAC,CAAC;gBAC7E,SAAS;YACX,CAAC;YAED,uEAAuE;YACvE,uEAAuE;YACvE,6EAA6E;YAC7E,yEAAyE;YACzE,oEAAoE;YACpE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAChF,MAAM,WAAW,GACf,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;gBACxB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;gBAC/B,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,OAAO,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC;gBAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;gBACnC,IAAI,MAAM;oBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;;oBACxD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,GAAG,gBAAgB,OAAO,GAAG,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,4EAA4E;IAC5E,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEpE,uDAAuD;IACvD,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,sBAAsB,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC;YACT,OAAO;YACP,OAAO,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC;YACvB,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,SAAS;YACvC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO;SACpC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,UAAU,GAAG;YACjB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SAChE,CAAC,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;YAChB,IAAI;YACJ,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC;YACrB,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC;YAC7B,QAAQ,EAAE;gBACR,SAAS,EAAE,MAAM;gBACjB,QAAQ;gBACR,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7C;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACpD,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;QACjB,CAAC,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;YACnB,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;gBACnB,CAAC,CAAC,CAAC,CAAC;gBACJ,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;oBACnB,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI;wBACf,CAAC,CAAC,CAAC,CAAC;wBACJ,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI;4BACf,CAAC,CAAC,CAAC;4BACH,CAAC,CAAC,CAAC,CAChB,CAAC;IAEF,qEAAqE;IACrE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CACT,YAAY,UAAU,CAAC,IAAI,uBAAuB,MAAM,CAAC,MAAM,uBAAuB,WAAW,CAAC,MAAM,UAAU;YAChH,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,CAC1E,CAAC;IACJ,CAAC;IACD,yDAAyD;IACzD,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrG,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,yBAAyB,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjI,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,oDAAoD,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1J,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,oCAAoC,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1I,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW,CAAC,GAAqB;IACxC,IAAI,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACrB,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,8EAA8E;AAC9E,eAAe;AAEf,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,IAAI,EAAE,MAAM;IAEZ,KAAK,CAAC,MAAM,CAAC,GAA2B;QACtC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5C,0EAA0E;QAC1E,MAAM,SAAS,GAAG,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/D,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,4EAA4E;QAC5E,+EAA+E;QAC/E,+EAA+E;QAC/E,6CAA6C;QAC7C,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC7D,IAAI,CAAC;oBAAE,OAAO,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,6EAA6E;IAC7E,qDAAqD;IACrD,KAAK,CAAC,aAAa,CAAC,GAAqB;QACvC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7C,CAAC;IAED,8EAA8E;IAC9E,8EAA8E;IAC9E,oBAAoB;IACpB,KAAK,CAAC,cAAc,CAAC,GAAqB;QACxC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,8EAA8E;IAC9E,oEAAoE;IACpE,KAAK,CAAC,QAAQ,CAAC,GAAqB;QAClC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,+EAA+E;IAC/E,gFAAgF;IAChF,4DAA4D;IAC5D,eAAe,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClF,CAAC;CACF,CAAC"}
|