procesio-cli 0.1.1__py3-none-any.whl
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.
- procesio_cli/__init__.py +18 -0
- procesio_cli/_cli.py +71 -0
- procesio_cli/agents/__init__.py +0 -0
- procesio_cli/agents/_lib/__init__.py +0 -0
- procesio_cli/agents/_lib/actiondef.py +24 -0
- procesio_cli/agents/_lib/errors.py +40 -0
- procesio_cli/agents/_lib/reversibility.py +236 -0
- procesio_cli/agents/_lib/toolrunner.py +141 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PLAYBOOK.md +62 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PROCESIO-INTEROP.md +76 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-TROUBLESHOOTING.md +60 -0
- procesio_cli/agents/connector-builder/README.md +51 -0
- procesio_cli/agents/connector-builder/agent.yaml +61 -0
- procesio_cli/agents/connector-builder/context.py +19 -0
- procesio_cli/agents/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/agents/connector-builder/handlers/checklist.py +71 -0
- procesio_cli/agents/connector-builder/handlers/guidance.py +37 -0
- procesio_cli/agents/connector-builder/handlers/nextstep.py +221 -0
- procesio_cli/agents/connector-builder/handlers/status.py +35 -0
- procesio_cli/agents/connector-builder/knowledge.py +47 -0
- procesio_cli/agents/connector-builder/main.py +93 -0
- procesio_cli/agents/connector-builder/tests/conftest.py +95 -0
- procesio_cli/agents/connector-builder/tests/test_cba_agent.py +148 -0
- procesio_cli/agents/orchestrator/__init__.py +0 -0
- procesio_cli/agents/orchestrator/bootstraplib.py +166 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/00-INDEX.md +60 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/01-PROCESSES.md +230 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/02-FORMS.md +287 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/03-INTEGRATIONS.md +384 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/04-DATABASE.md +293 -0
- procesio_cli/agents/procesio/PROCESIO-API-RELIABILITY-DOCTRINE.md +113 -0
- procesio_cli/agents/procesio/PROCESIO-BEST-PRACTICES.md +316 -0
- procesio_cli/agents/procesio/PROCESIO-BUILD-AND-TEST-PLAYBOOK.md +217 -0
- procesio_cli/agents/procesio/PROCESIO-DATASTORE.md +72 -0
- procesio_cli/agents/procesio/PROCESIO-ENVIRONMENTS.md +62 -0
- procesio_cli/agents/procesio/PROCESIO-SCHEDULING.md +47 -0
- procesio_cli/agents/procesio/PROCESIO-VISUAL-ORGANIZATION.md +175 -0
- procesio_cli/agents/procesio/README.md +97 -0
- procesio_cli/agents/procesio/__init__.py +0 -0
- procesio_cli/agents/procesio/agent.yaml +73 -0
- procesio_cli/agents/procesio/audit.py +226 -0
- procesio_cli/agents/procesio/checklist.py +135 -0
- procesio_cli/agents/procesio/context.py +19 -0
- procesio_cli/agents/procesio/handlers/__init__.py +0 -0
- procesio_cli/agents/procesio/handlers/audit.py +39 -0
- procesio_cli/agents/procesio/handlers/checklist.py +34 -0
- procesio_cli/agents/procesio/handlers/guidance.py +36 -0
- procesio_cli/agents/procesio/handlers/status.py +33 -0
- procesio_cli/agents/procesio/handlers/verify.py +39 -0
- procesio_cli/agents/procesio/knowledge.py +115 -0
- procesio_cli/agents/procesio/main.py +89 -0
- procesio_cli/agents/procesio/tests/__init__.py +0 -0
- procesio_cli/agents/procesio/tests/conftest.py +62 -0
- procesio_cli/agents/procesio/tests/test_audit.py +91 -0
- procesio_cli/agents/procesio/tests/test_checklist.py +28 -0
- procesio_cli/agents/procesio/tests/test_guidance.py +78 -0
- procesio_cli/agents/procesio/tests/test_manifest_sync.py +48 -0
- procesio_cli/agents/procesio/tests/test_verify.py +134 -0
- procesio_cli/agents/procesio/tests/test_workspace_scope.py +97 -0
- procesio_cli/agents/procesio/verifylib.py +222 -0
- procesio_cli/dashboard/README.md +117 -0
- procesio_cli/dashboard/__init__.py +18 -0
- procesio_cli/dashboard/serve.py +98 -0
- procesio_cli/dashboard/server/__init__.py +1 -0
- procesio_cli/dashboard/server/config_schemas.py +92 -0
- procesio_cli/dashboard/server/google.py +103 -0
- procesio_cli/dashboard/server/handler.py +160 -0
- procesio_cli/dashboard/server/inventory.py +213 -0
- procesio_cli/dashboard/server/jobs.py +118 -0
- procesio_cli/dashboard/server/llmtest.py +181 -0
- procesio_cli/dashboard/server/procesio_env.py +94 -0
- procesio_cli/dashboard/server/routes.py +74 -0
- procesio_cli/dashboard/server/runner.py +150 -0
- procesio_cli/dashboard/server/security.py +29 -0
- procesio_cli/dashboard/server/setup.py +211 -0
- procesio_cli/dashboard/server/validate.py +152 -0
- procesio_cli/dashboard/tests/conftest.py +16 -0
- procesio_cli/dashboard/tests/test_dashboard.py +225 -0
- procesio_cli/dashboard/tests/test_procesio_env.py +159 -0
- procesio_cli/dashboard/web/actions.js +274 -0
- procesio_cli/dashboard/web/api.js +79 -0
- procesio_cli/dashboard/web/app.js +385 -0
- procesio_cli/dashboard/web/copilot.js +72 -0
- procesio_cli/dashboard/web/google.js +121 -0
- procesio_cli/dashboard/web/index.html +67 -0
- procesio_cli/dashboard/web/procesio_env.js +187 -0
- procesio_cli/dashboard/web/styles.css +207 -0
- procesio_cli/registry.py +370 -0
- procesio_cli/scripts/build-router.py +249 -0
- procesio_cli/scripts/build-tool-skill.py +202 -0
- procesio_cli/scripts/check-requirements.py +131 -0
- procesio_cli/scripts/check-skill-governance.py +174 -0
- procesio_cli/scripts/evaluate-skill-routing.py +217 -0
- procesio_cli/scripts/evaluate-skills.py +316 -0
- procesio_cli/scripts/get-skill.py +122 -0
- procesio_cli/scripts/list-skills.py +68 -0
- procesio_cli/scripts/list-tools.py +73 -0
- procesio_cli/scripts/run-agent.py +59 -0
- procesio_cli/scripts/run-tool.py +123 -0
- procesio_cli/scripts/secret_scan.py +584 -0
- procesio_cli/scripts/set-credential.py +126 -0
- procesio_cli/scripts/validate-skills.py +530 -0
- procesio_cli/skills/PORTFOLIO.md +134 -0
- procesio_cli/skills/__init__.py +6 -0
- procesio_cli/skills/agent-skill-engineer/SKILL.md +226 -0
- procesio_cli/skills/agent-skill-engineer/evals/evals.json +422 -0
- procesio_cli/skills/agent-skill-engineer/references/authoring-standard.md +178 -0
- procesio_cli/skills/agent-skill-engineer/references/decision-framework.md +107 -0
- procesio_cli/skills/agent-skill-engineer/references/domain-evidence-protocol.md +248 -0
- procesio_cli/skills/agent-skill-engineer/references/evaluation-standard.md +191 -0
- procesio_cli/skills/agent-skill-engineer/references/expert-lenses.md +167 -0
- procesio_cli/skills/agent-skill-engineer/references/field-gate-standard.md +231 -0
- procesio_cli/skills/agent-skill-engineer/references/optimization-protocol.md +233 -0
- procesio_cli/skills/agent-skill-engineer/references/optimizer-contract.md +268 -0
- procesio_cli/skills/agent-skill-engineer/references/portability-standard.md +99 -0
- procesio_cli/skills/agent-skill-engineer/references/research-basis.md +128 -0
- procesio_cli/skills/agent-skill-engineer/references/review-standard.md +143 -0
- procesio_cli/skills/agent-skill-engineer/scripts/audit_skill.py +959 -0
- procesio_cli/skills/agent-skill-engineer/scripts/optimize_skill.py +891 -0
- procesio_cli/skills/agent-skill-engineer/scripts/scaffold_skill.py +397 -0
- procesio_cli/skills/evals/baseline-catalog.json +14 -0
- procesio_cli/skills/evals/baseline-routing-v2.json +38 -0
- procesio_cli/skills/evals/baseline.json +37 -0
- procesio_cli/skills/evals/behavioral.json +367 -0
- procesio_cli/skills/evals/field-boundary-development-v1.json +126 -0
- procesio_cli/skills/evals/field-closeout-correction-development-v1.json +23 -0
- procesio_cli/skills/evals/field-closeout-development-v1.json +89 -0
- procesio_cli/skills/evals/portfolio-pressure-training-v1.json +83 -0
- procesio_cli/skills/evals/routing.json +363 -0
- procesio_cli/skills/evals/validation-baseline.json +4 -0
- procesio_cli/skills/procesio-cli/SKILL.md +134 -0
- procesio_cli/skills/procesio-cli/evals/evals.json +111 -0
- procesio_cli/skills/procesio-cli/evals/workflows.json +16 -0
- procesio_cli/skills/procesio-cli/references/connector-lifecycle.md +47 -0
- procesio_cli/skills/procesio-cli/references/credentials-admin.md +113 -0
- procesio_cli/skills/procesio-cli/references/data-verification.md +71 -0
- procesio_cli/skills/procesio-cli/references/documents-files.md +44 -0
- procesio_cli/skills/procesio-cli/references/form-e2e.md +57 -0
- procesio_cli/skills/procesio-cli/references/operation-contract.md +138 -0
- procesio_cli/skills/procesio-cli/references/process-debugging.md +65 -0
- procesio_cli/skills/procesio-cli/references/process-lifecycle.md +88 -0
- procesio_cli/skills/procesio-cli/references/schedules-webhooks.md +58 -0
- procesio_cli/skills/procesio-cli/references/transport-environments.md +53 -0
- procesio_cli/skills/procesio-cli-maintainer/SKILL.md +84 -0
- procesio_cli/skills/procesio-cli-maintainer/evals/evals.json +116 -0
- procesio_cli/skills/procesio-cli-maintainer/references/change-contract.md +34 -0
- procesio_cli/skills/procesio-cli-maintainer/references/mcp-compatibility.md +13 -0
- procesio_cli/skills/procesio-cli-maintainer/references/skill-authoring.md +51 -0
- procesio_cli/skills/procesio-platform-advisor/SKILL.md +82 -0
- procesio_cli/skills/procesio-platform-advisor/evals/evals.json +116 -0
- procesio_cli/skills/procesio-platform-advisor/references/capability-map.md +22 -0
- procesio_cli/skills/procesio-platform-advisor/references/fit-framework.md +35 -0
- procesio_cli/skills/procesio-platform-advisor/references/freshness-policy.md +25 -0
- procesio_cli/skills/procesio-platform-advisor/references/sizing-method.md +70 -0
- procesio_cli/skills/procesio-platform-advisor/scripts/estimate_capacity.py +99 -0
- procesio_cli/skills/procesio-setup/SKILL.md +180 -0
- procesio_cli/skills/sql-server-optimizer/SKILL.md +86 -0
- procesio_cli/skills/sql-server-optimizer/evals/evals.json +116 -0
- procesio_cli/skills/sql-server-optimizer/references/db-context.md +44 -0
- procesio_cli/skills/sql-server-optimizer/references/generic-mode.md +32 -0
- procesio_cli/skills/sql-server-optimizer/references/procesio-mode.md +40 -0
- procesio_cli/skills/sql-server-optimizer/references/sql-rules.md +43 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-indexes.sql +178 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-procs-and-functions.sql +118 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-tables.sql +367 -0
- procesio_cli/skills/tests/__init__.py +0 -0
- procesio_cli/skills/tests/test_agent_skill_engineer.py +240 -0
- procesio_cli/skills/tests/test_auth_failure_stop.py +25 -0
- procesio_cli/skills/tests/test_capacity_estimator.py +85 -0
- procesio_cli/skills/tests/test_field_boundary_learning.py +100 -0
- procesio_cli/skills/tests/test_field_closeout_learning.py +123 -0
- procesio_cli/skills/tests/test_field_gate_standard.py +76 -0
- procesio_cli/skills/tests/test_operational_playbooks.py +51 -0
- procesio_cli/skills/tests/test_portfolio_pressure_training.py +35 -0
- procesio_cli/skills/tests/test_process_lifecycle_single_run.py +25 -0
- procesio_cli/skills/tests/test_skill_evaluator.py +67 -0
- procesio_cli/skills/tests/test_skill_optimizer.py +473 -0
- procesio_cli/skills/tests/test_skill_portfolio_review.py +70 -0
- procesio_cli/skills/tests/test_skill_release_binding.py +204 -0
- procesio_cli/skills/tests/test_skill_routing.py +74 -0
- procesio_cli/skills/tests/test_skill_scaffold_v2.py +116 -0
- procesio_cli/skills/tests/test_validate_skills.py +115 -0
- procesio_cli/tools/__init__.py +0 -0
- procesio_cli/tools/_lib/README.md +119 -0
- procesio_cli/tools/_lib/__init__.py +0 -0
- procesio_cli/tools/_lib/accounting.py +120 -0
- procesio_cli/tools/_lib/contacts.py +544 -0
- procesio_cli/tools/_lib/creds.py +83 -0
- procesio_cli/tools/_lib/creds_backends.py +578 -0
- procesio_cli/tools/_lib/dbprofiles.py +147 -0
- procesio_cli/tools/_lib/dbquery.py +286 -0
- procesio_cli/tools/_lib/dbschema.py +225 -0
- procesio_cli/tools/_lib/io.py +54 -0
- procesio_cli/tools/_lib/manifest.py +297 -0
- procesio_cli/tools/_lib/skill_release.py +127 -0
- procesio_cli/tools/_lib/skill_resources.py +118 -0
- procesio_cli/tools/_lib/userdata.py +228 -0
- procesio_cli/tools/_lib/webserialize/__init__.py +16 -0
- procesio_cli/tools/_lib/webserialize/admin.py +61 -0
- procesio_cli/tools/_lib/webserialize/client.py +264 -0
- procesio_cli/tools/_lib/webserialize/config.py +96 -0
- procesio_cli/tools/_lib/webserialize/errors.py +27 -0
- procesio_cli/tools/_lib/webserialize/framing.py +45 -0
- procesio_cli/tools/_lib/webserialize/registry.py +47 -0
- procesio_cli/tools/_lib/webserialize/runtime.py +61 -0
- procesio_cli/tools/_lib/webserialize/server.py +510 -0
- procesio_cli/tools/_lib/websession.py +194 -0
- procesio_cli/tools/connector-builder/CONNECTOR-BUILDER-API-NOTES.md +91 -0
- procesio_cli/tools/connector-builder/README.md +101 -0
- procesio_cli/tools/connector-builder/SKILL.md +248 -0
- procesio_cli/tools/connector-builder/__init__.py +7 -0
- procesio_cli/tools/connector-builder/actiondef.py +24 -0
- procesio_cli/tools/connector-builder/client.py +251 -0
- procesio_cli/tools/connector-builder/errors.py +44 -0
- procesio_cli/tools/connector-builder/gen_manifest.py +142 -0
- procesio_cli/tools/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/tools/connector-builder/handlers/admin.py +182 -0
- procesio_cli/tools/connector-builder/handlers/auth.py +74 -0
- procesio_cli/tools/connector-builder/handlers/builds.py +396 -0
- procesio_cli/tools/connector-builder/handlers/common.py +104 -0
- procesio_cli/tools/connector-builder/handlers/files.py +111 -0
- procesio_cli/tools/connector-builder/handlers/raw.py +38 -0
- procesio_cli/tools/connector-builder/handlers/telemetry.py +39 -0
- procesio_cli/tools/connector-builder/main.py +94 -0
- procesio_cli/tools/connector-builder/tests/conftest.py +146 -0
- procesio_cli/tools/connector-builder/tests/test_cb_client.py +86 -0
- procesio_cli/tools/connector-builder/tests/test_cb_dispatch.py +105 -0
- procesio_cli/tools/connector-builder/tests/test_cb_manifest_sync.py +76 -0
- procesio_cli/tools/connector-builder/tests/test_cb_wait.py +123 -0
- procesio_cli/tools/connector-builder/tool.yaml +671 -0
- procesio_cli/tools/framework-map/.gitattributes +2 -0
- procesio_cli/tools/framework-map/README.md +98 -0
- procesio_cli/tools/framework-map/SKILL.md +30 -0
- procesio_cli/tools/framework-map/app.js +188 -0
- procesio_cli/tools/framework-map/fm_builder.py +476 -0
- procesio_cli/tools/framework-map/fm_catalog.py +19 -0
- procesio_cli/tools/framework-map/fm_ro_catalog.py +94 -0
- procesio_cli/tools/framework-map/fm_strings.py +101 -0
- procesio_cli/tools/framework-map/main.py +95 -0
- procesio_cli/tools/framework-map/styles.css +214 -0
- procesio_cli/tools/framework-map/tests/conftest.py +33 -0
- procesio_cli/tools/framework-map/tests/test_fm_build.py +126 -0
- procesio_cli/tools/framework-map/tests/test_fm_manifest_sync.py +63 -0
- procesio_cli/tools/framework-map/tests/test_fm_store_tree.py +75 -0
- procesio_cli/tools/framework-map/tool.yaml +61 -0
- procesio_cli/tools/mysql/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/mysql/README.md +196 -0
- procesio_cli/tools/mysql/SKILL.md +37 -0
- procesio_cli/tools/mysql/__init__.py +0 -0
- procesio_cli/tools/mysql/connection.py +191 -0
- procesio_cli/tools/mysql/main.py +487 -0
- procesio_cli/tools/mysql/profiles.template.json +1 -0
- procesio_cli/tools/mysql/schema.py +434 -0
- procesio_cli/tools/mysql/tests/__init__.py +0 -0
- procesio_cli/tools/mysql/tests/conftest.py +21 -0
- procesio_cli/tools/mysql/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/mysql/tests/test_mysql.py +201 -0
- procesio_cli/tools/mysql/tests/test_mysql_schema.py +337 -0
- procesio_cli/tools/mysql/tool.yaml +112 -0
- procesio_cli/tools/procesio/DTO-SUBTOOLS-NOTE.md +360 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/00-INDEX.md +67 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/01-ANATOMY.md +209 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/02-CODE-INJECTION.md +309 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/03-DOM-CONTRACT.md +370 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/04-INTERACTION-RECIPES.md +600 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/05-STEPPER-AND-MOTION.md +426 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/06-PROCESS-INTEGRATION.md +347 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/07-DEPLOY-WORKFLOW.md +294 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/08-PITFALLS.md +569 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/09-NAVIGATION-AND-HOSTING.md +308 -0
- procesio_cli/tools/procesio/PHASE4-E2E-NOTES.md +594 -0
- procesio_cli/tools/procesio/PROCESIO-API-CORRECTIONS.md +295 -0
- procesio_cli/tools/procesio/PROCESIO-API-NOTES.md +6976 -0
- procesio_cli/tools/procesio/PROCESIO-AUTH-NOTES.md +226 -0
- procesio_cli/tools/procesio/PROCESIO-CARD-BUILD-NOTES.md +183 -0
- procesio_cli/tools/procesio/PROCESIO-CONNECTORS-NOTES.md +141 -0
- procesio_cli/tools/procesio/PROCESIO-CUSTOM-ACTION-NOTES.md +179 -0
- procesio_cli/tools/procesio/PROCESIO-DOCS-FIX-REPORT.md +123 -0
- procesio_cli/tools/procesio/PROCESIO-ENVIRONMENTS-NOTES.md +94 -0
- procesio_cli/tools/procesio/PROCESIO-FE-VALIDATION-NOTES.md +107 -0
- procesio_cli/tools/procesio/PROCESIO-FOREACH-NOTES.md +199 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-API-HANG-NOTE.md +101 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-SUBMISSION-NOTES.md +172 -0
- procesio_cli/tools/procesio/PROCESIO-HTML-TO-DOCX-NOTES.md +110 -0
- procesio_cli/tools/procesio/PROCESIO-INSTANCE-HISTORY-NOTES.md +242 -0
- procesio_cli/tools/procesio/PROCESIO-METERING-NOTES.md +201 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-CODE-NOTES.md +279 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-MODULE-WHITELIST.md +113 -0
- procesio_cli/tools/procesio/PROCESIO-PYTHON-ACTION-NOTES.md +165 -0
- procesio_cli/tools/procesio/PROCESIO-QUERY-STORE-NOTES.md +826 -0
- procesio_cli/tools/procesio/PROCESIO-RECONCILIATION-PATTERNS.md +104 -0
- procesio_cli/tools/procesio/PROCESIO-RESOURCE-MODEL-NOTES.md +1100 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-CRED-OPTIONALITY.md +45 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-NOTES.md +252 -0
- procesio_cli/tools/procesio/PROCESIO-SQL-ACTIONS-NOTES.md +284 -0
- procesio_cli/tools/procesio/PROCESIO-USAGE-GUIDE.md +219 -0
- procesio_cli/tools/procesio/README.md +341 -0
- procesio_cli/tools/procesio/SCHEDULE-INPUT-SECURITY-NOTES.md +63 -0
- procesio_cli/tools/procesio/SKILL.md +694 -0
- procesio_cli/tools/procesio/__init__.py +1 -0
- procesio_cli/tools/procesio/actiondef.py +27 -0
- procesio_cli/tools/procesio/assets/html2docx/html2docx.js +2155 -0
- procesio_cli/tools/procesio/auth.py +354 -0
- procesio_cli/tools/procesio/autogen.py +121 -0
- procesio_cli/tools/procesio/client.py +355 -0
- procesio_cli/tools/procesio/config.py +96 -0
- procesio_cli/tools/procesio/data/endpoints.json +2901 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/01-authentication.md +180 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/02-conventions.md +116 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/ANONYMOUS-SURFACE.md +51 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/README.md +104 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/SYMBOL-INDEX.md +444 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/03-auth-users-workspaces.md +731 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/04-processes.md +913 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/05-actions.md +605 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/06-files.md +237 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/07-forms-documents.md +985 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/08-credentials.md +532 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/09-datastore-datatypes.md +830 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/10-custom-urls.md +319 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/11-subscriptions-resources-analytics.md +455 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/12-webhooks-notifications-misc.md +519 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/13-realtime-signalr.md +153 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/99-internal-and-other-services.md +52 -0
- procesio_cli/tools/procesio/docs_info/FormBuilder mock.ts +5725 -0
- procesio_cli/tools/procesio/docs_info/Procesio Platform Actions.json +30219 -0
- procesio_cli/tools/procesio/docs_info/form-config-enums.ts +92 -0
- procesio_cli/tools/procesio/docs_info/form-theme.ts +1603 -0
- procesio_cli/tools/procesio/docs_info/process-validation-reference-1.md +2739 -0
- procesio_cli/tools/procesio/dto/__init__.py +13 -0
- procesio_cli/tools/procesio/dto/credential/builder.py +179 -0
- procesio_cli/tools/procesio/dto/credential/config.schema.json +19 -0
- procesio_cli/tools/procesio/dto/credential/description.md +193 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.config.json +11 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.dto.json +28 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.template.json +44 -0
- procesio_cli/tools/procesio/dto/credential/template.dto.json +16 -0
- procesio_cli/tools/procesio/dto/data/_refresh.py +147 -0
- procesio_cli/tools/procesio/dto/data/action_catalog.json +30825 -0
- procesio_cli/tools/procesio/dto/data/action_families.json +55 -0
- procesio_cli/tools/procesio/dto/data/platform_types.json +182 -0
- procesio_cli/tools/procesio/dto/datatype/builder.py +223 -0
- procesio_cli/tools/procesio/dto/datatype/config.schema.json +47 -0
- procesio_cli/tools/procesio/dto/datatype/description.md +85 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.config.json +41 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.dto.json +164 -0
- procesio_cli/tools/procesio/dto/datatype/template.dto.json +37 -0
- procesio_cli/tools/procesio/dto/document/builder.py +193 -0
- procesio_cli/tools/procesio/dto/document/config.schema.json +33 -0
- procesio_cli/tools/procesio/dto/document/description.md +124 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.config.json +16 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.dto.json +32 -0
- procesio_cli/tools/procesio/dto/document/template.dto.json +14 -0
- procesio_cli/tools/procesio/dto/form/FORM-STYLING-NOTES.md +142 -0
- procesio_cli/tools/procesio/dto/form/GOLDEN-DRIFT-NOTES.md +72 -0
- procesio_cli/tools/procesio/dto/form/RUN-PROCESS-RESULT-NOTES.md +80 -0
- procesio_cli/tools/procesio/dto/form/addelement.py +277 -0
- procesio_cli/tools/procesio/dto/form/builder.py +1009 -0
- procesio_cli/tools/procesio/dto/form/capture_goldens.py +106 -0
- procesio_cli/tools/procesio/dto/form/code_cipher.py +67 -0
- procesio_cli/tools/procesio/dto/form/config.schema.json +76 -0
- procesio_cli/tools/procesio/dto/form/data_shell.json +1 -0
- procesio_cli/tools/procesio/dto/form/description.md +346 -0
- procesio_cli/tools/procesio/dto/form/elements/approval.json +259 -0
- procesio_cli/tools/procesio/dto/form/elements/assignee.json +137 -0
- procesio_cli/tools/procesio/dto/form/elements/button.json +125 -0
- procesio_cli/tools/procesio/dto/form/elements/chart.json +341 -0
- procesio_cli/tools/procesio/dto/form/elements/chat.json +199 -0
- procesio_cli/tools/procesio/dto/form/elements/checkbox.json +153 -0
- procesio_cli/tools/procesio/dto/form/elements/column.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/columns.json +78 -0
- procesio_cli/tools/procesio/dto/form/elements/datetime-input.json +304 -0
- procesio_cli/tools/procesio/dto/form/elements/divider.json +54 -0
- procesio_cli/tools/procesio/dto/form/elements/dropdown.json +130 -0
- procesio_cli/tools/procesio/dto/form/elements/dynamic-table-row.json +253 -0
- procesio_cli/tools/procesio/dto/form/elements/file-upload.json +196 -0
- procesio_cli/tools/procesio/dto/form/elements/file-viewer.json +169 -0
- procesio_cli/tools/procesio/dto/form/elements/heading.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/icon.json +107 -0
- procesio_cli/tools/procesio/dto/form/elements/image.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/input.json +206 -0
- procesio_cli/tools/procesio/dto/form/elements/list.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/number-input.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/paragraph.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/radiobox.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/section.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/select.json +217 -0
- procesio_cli/tools/procesio/dto/form/elements/side-panel.json +146 -0
- procesio_cli/tools/procesio/dto/form/elements/signature-pad.json +141 -0
- procesio_cli/tools/procesio/dto/form/elements/static-table-row.json +84 -0
- procesio_cli/tools/procesio/dto/form/elements/step.json +105 -0
- procesio_cli/tools/procesio/dto/form/elements/stepper.json +126 -0
- procesio_cli/tools/procesio/dto/form/elements/tab.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/table.json +279 -0
- procesio_cli/tools/procesio/dto/form/elements/tabs.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/textarea.json +213 -0
- procesio_cli/tools/procesio/dto/form/enum_map.json +68 -0
- procesio_cli/tools/procesio/dto/form/fieldpath.py +284 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.config.json +32 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.elements.json +638 -0
- procesio_cli/tools/procesio/dto/form/sync_from_mock.py +386 -0
- procesio_cli/tools/procesio/dto/framework.py +125 -0
- procesio_cli/tools/procesio/dto/process/builder.py +1991 -0
- procesio_cli/tools/procesio/dto/process/config.schema.json +159 -0
- procesio_cli/tools/procesio/dto/process/description.md +218 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.config.json +32 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.dto.json +317 -0
- procesio_cli/tools/procesio/dto/process/naming.py +305 -0
- procesio_cli/tools/procesio/dto/process/normalize.py +74 -0
- procesio_cli/tools/procesio/dto/process/template.dto.json +32 -0
- procesio_cli/tools/procesio/dto/refdata.py +87 -0
- procesio_cli/tools/procesio/dto/registry.py +27 -0
- procesio_cli/tools/procesio/dto/webhook/builder.py +142 -0
- procesio_cli/tools/procesio/dto/webhook/config.schema.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/description.md +92 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.config.json +10 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.dto.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/template.dto.json +14 -0
- procesio_cli/tools/procesio/environments.py +264 -0
- procesio_cli/tools/procesio/errors.py +166 -0
- procesio_cli/tools/procesio/flowmodel/README.md +37 -0
- procesio_cli/tools/procesio/flowmodel/__init__.py +14 -0
- procesio_cli/tools/procesio/flowmodel/digest.py +223 -0
- procesio_cli/tools/procesio/flowmodel/families.py +34 -0
- procesio_cli/tools/procesio/flowmodel/fevalidation.py +1098 -0
- procesio_cli/tools/procesio/flowmodel/formdigest.py +232 -0
- procesio_cli/tools/procesio/flowmodel/inspect.py +78 -0
- procesio_cli/tools/procesio/flowmodel/model.py +82 -0
- procesio_cli/tools/procesio/flowmodel/nodeparam.py +871 -0
- procesio_cli/tools/procesio/flowmodel/reader.py +191 -0
- procesio_cli/tools/procesio/flowmodel/sqlparam.py +410 -0
- procesio_cli/tools/procesio/form_code_keys.py +50 -0
- procesio_cli/tools/procesio/formlint.py +292 -0
- procesio_cli/tools/procesio/gen_manifest.py +118 -0
- procesio_cli/tools/procesio/handlers/__init__.py +1 -0
- procesio_cli/tools/procesio/handlers/auth_actions.py +103 -0
- procesio_cli/tools/procesio/handlers/catalog.py +147 -0
- procesio_cli/tools/procesio/handlers/common.py +90 -0
- procesio_cli/tools/procesio/handlers/customaction_ops.py +146 -0
- procesio_cli/tools/procesio/handlers/datastore_ops.py +482 -0
- procesio_cli/tools/procesio/handlers/datatype_ops.py +275 -0
- procesio_cli/tools/procesio/handlers/dto_actions.py +258 -0
- procesio_cli/tools/procesio/handlers/environment_admin.py +146 -0
- procesio_cli/tools/procesio/handlers/fevalidate.py +236 -0
- procesio_cli/tools/procesio/handlers/files.py +141 -0
- procesio_cli/tools/procesio/handlers/flowgraph.py +229 -0
- procesio_cli/tools/procesio/handlers/flowlint.py +269 -0
- procesio_cli/tools/procesio/handlers/form_chains.py +336 -0
- procesio_cli/tools/procesio/handlers/form_code.py +277 -0
- procesio_cli/tools/procesio/handlers/form_element.py +199 -0
- procesio_cli/tools/procesio/handlers/form_events.py +441 -0
- procesio_cli/tools/procesio/handlers/form_update.py +270 -0
- procesio_cli/tools/procesio/handlers/formprocess.py +211 -0
- procesio_cli/tools/procesio/handlers/generic.py +135 -0
- procesio_cli/tools/procesio/handlers/layout.py +137 -0
- procesio_cli/tools/procesio/handlers/nodeparams.py +1018 -0
- procesio_cli/tools/procesio/handlers/process_layout.py +189 -0
- procesio_cli/tools/procesio/handlers/process_naming.py +213 -0
- procesio_cli/tools/procesio/handlers/processes.py +416 -0
- procesio_cli/tools/procesio/handlers/profile_admin.py +184 -0
- procesio_cli/tools/procesio/handlers/resource_ops.py +447 -0
- procesio_cli/tools/procesio/handlers/schedules.py +320 -0
- procesio_cli/tools/procesio/handlers/sqlactions.py +232 -0
- procesio_cli/tools/procesio/handlers/transport.py +463 -0
- procesio_cli/tools/procesio/handlers/usageguide.py +222 -0
- procesio_cli/tools/procesio/layout/README.md +196 -0
- procesio_cli/tools/procesio/layout/__init__.py +11 -0
- procesio_cli/tools/procesio/layout/adapter.py +736 -0
- procesio_cli/tools/procesio/layout/cycles.py +186 -0
- procesio_cli/tools/procesio/layout/dispatch.py +39 -0
- procesio_cli/tools/procesio/layout/elk/elk_runner.mjs +50 -0
- procesio_cli/tools/procesio/layout/elk/package-lock.json +21 -0
- procesio_cli/tools/procesio/layout/elk/package.json +11 -0
- procesio_cli/tools/procesio/layout/elk_engine.py +568 -0
- procesio_cli/tools/procesio/layout/engine.py +1311 -0
- procesio_cli/tools/procesio/layout/report.py +187 -0
- procesio_cli/tools/procesio/main.py +179 -0
- procesio_cli/tools/procesio/profiles.py +193 -0
- procesio_cli/tools/procesio/reliability.py +193 -0
- procesio_cli/tools/procesio/sqlformat.py +167 -0
- procesio_cli/tools/procesio/swagger.py +51 -0
- procesio_cli/tools/procesio/tests/__init__.py +0 -0
- procesio_cli/tools/procesio/tests/conftest.py +129 -0
- procesio_cli/tools/procesio/tests/test_auth.py +200 -0
- procesio_cli/tools/procesio/tests/test_autogen.py +78 -0
- procesio_cli/tools/procesio/tests/test_builder_attrpath_sqlbind.py +180 -0
- procesio_cli/tools/procesio/tests/test_builder_custom_action_catalog.py +72 -0
- procesio_cli/tools/procesio/tests/test_client.py +114 -0
- procesio_cli/tools/procesio/tests/test_client_reliability.py +139 -0
- procesio_cli/tools/procesio/tests/test_customaction.py +103 -0
- procesio_cli/tools/procesio/tests/test_customaction_test.py +80 -0
- procesio_cli/tools/procesio/tests/test_cycles.py +69 -0
- procesio_cli/tools/procesio/tests/test_datastore.py +378 -0
- procesio_cli/tools/procesio/tests/test_datastore_node.py +94 -0
- procesio_cli/tools/procesio/tests/test_dispatch.py +170 -0
- procesio_cli/tools/procesio/tests/test_document_page_size.py +19 -0
- procesio_cli/tools/procesio/tests/test_dto.py +734 -0
- procesio_cli/tools/procesio/tests/test_edit_dryrun_preview.py +96 -0
- procesio_cli/tools/procesio/tests/test_elk_layout.py +221 -0
- procesio_cli/tools/procesio/tests/test_environments.py +214 -0
- procesio_cli/tools/procesio/tests/test_fevalidate_gate.py +104 -0
- procesio_cli/tools/procesio/tests/test_fevalidation.py +317 -0
- procesio_cli/tools/procesio/tests/test_fieldpath_variables.py +87 -0
- procesio_cli/tools/procesio/tests/test_files.py +72 -0
- procesio_cli/tools/procesio/tests/test_flow_digest.py +202 -0
- procesio_cli/tools/procesio/tests/test_flowlint.py +114 -0
- procesio_cli/tools/procesio/tests/test_flowmodel.py +158 -0
- procesio_cli/tools/procesio/tests/test_form_add_element.py +256 -0
- procesio_cli/tools/procesio/tests/test_form_approval_gaps.py +319 -0
- procesio_cli/tools/procesio/tests/test_form_auto_names.py +60 -0
- procesio_cli/tools/procesio/tests/test_form_chains.py +217 -0
- procesio_cli/tools/procesio/tests/test_form_code_actions.py +188 -0
- procesio_cli/tools/procesio/tests/test_form_code_keys.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_code_style.py +178 -0
- procesio_cli/tools/procesio/tests/test_form_delete_element.py +99 -0
- procesio_cli/tools/procesio/tests/test_form_element_config.py +141 -0
- procesio_cli/tools/procesio/tests/test_form_event_maps.py +135 -0
- procesio_cli/tools/procesio/tests/test_form_event_ops.py +376 -0
- procesio_cli/tools/procesio/tests/test_form_event_replace.py +86 -0
- procesio_cli/tools/procesio/tests/test_form_events.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_parity.py +171 -0
- procesio_cli/tools/procesio/tests/test_form_select_source.py +74 -0
- procesio_cli/tools/procesio/tests/test_form_sync.py +35 -0
- procesio_cli/tools/procesio/tests/test_form_update.py +133 -0
- procesio_cli/tools/procesio/tests/test_formlint.py +155 -0
- procesio_cli/tools/procesio/tests/test_formlint_css_scope.py +38 -0
- procesio_cli/tools/procesio/tests/test_formlint_field_names.py +83 -0
- procesio_cli/tools/procesio/tests/test_guards.py +110 -0
- procesio_cli/tools/procesio/tests/test_hidden_setting_types.py +39 -0
- procesio_cli/tools/procesio/tests/test_html2docx_asset.py +132 -0
- procesio_cli/tools/procesio/tests/test_key_handle_terminology.py +45 -0
- procesio_cli/tools/procesio/tests/test_layout.py +574 -0
- procesio_cli/tools/procesio/tests/test_layout_report.py +88 -0
- procesio_cli/tools/procesio/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/procesio/tests/test_nodedelete.py +151 -0
- procesio_cli/tools/procesio/tests/test_nodeparam.py +826 -0
- procesio_cli/tools/procesio/tests/test_normalize.py +70 -0
- procesio_cli/tools/procesio/tests/test_payload_docs.py +86 -0
- procesio_cli/tools/procesio/tests/test_process_action_naming.py +170 -0
- procesio_cli/tools/procesio/tests/test_process_call_api_seed.py +46 -0
- procesio_cli/tools/procesio/tests/test_process_ext.py +373 -0
- procesio_cli/tools/procesio/tests/test_process_invariants.py +183 -0
- procesio_cli/tools/procesio/tests/test_process_layout.py +117 -0
- procesio_cli/tools/procesio/tests/test_process_naming.py +188 -0
- procesio_cli/tools/procesio/tests/test_process_query_store.py +172 -0
- procesio_cli/tools/procesio/tests/test_processinfo_variable.py +56 -0
- procesio_cli/tools/procesio/tests/test_profiles.py +127 -0
- procesio_cli/tools/procesio/tests/test_put_projects.py +41 -0
- procesio_cli/tools/procesio/tests/test_reliability.py +107 -0
- procesio_cli/tools/procesio/tests/test_removal_gate.py +95 -0
- procesio_cli/tools/procesio/tests/test_resource_ops.py +173 -0
- procesio_cli/tools/procesio/tests/test_save_validity.py +207 -0
- procesio_cli/tools/procesio/tests/test_schedule_cron_shape.py +111 -0
- procesio_cli/tools/procesio/tests/test_schedules.py +309 -0
- procesio_cli/tools/procesio/tests/test_sqlconvert.py +234 -0
- procesio_cli/tools/procesio/tests/test_sqlformat.py +83 -0
- procesio_cli/tools/procesio/tests/test_sqlparam.py +187 -0
- procesio_cli/tools/procesio/tests/test_superseded_actions.py +54 -0
- procesio_cli/tools/procesio/tests/test_surgical_concurrency.py +156 -0
- procesio_cli/tools/procesio/tests/test_tier4.py +123 -0
- procesio_cli/tools/procesio/tests/test_transport.py +147 -0
- procesio_cli/tools/procesio/tests/test_transport_data_stores.py +168 -0
- procesio_cli/tools/procesio/tests/test_transport_mapper_repair.py +150 -0
- procesio_cli/tools/procesio/tests/test_transport_webhook_strip.py +253 -0
- procesio_cli/tools/procesio/tests/test_usage_guide.py +96 -0
- procesio_cli/tools/procesio/tool.yaml +12486 -0
- procesio_cli/tools/sqlserver/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/sqlserver/README.md +192 -0
- procesio_cli/tools/sqlserver/SKILL.md +37 -0
- procesio_cli/tools/sqlserver/SQLSERVER-SCHEMA-NOTES.md +284 -0
- procesio_cli/tools/sqlserver/__init__.py +0 -0
- procesio_cli/tools/sqlserver/connection.py +242 -0
- procesio_cli/tools/sqlserver/main.py +521 -0
- procesio_cli/tools/sqlserver/profiles.template.json +1 -0
- procesio_cli/tools/sqlserver/schema.py +600 -0
- procesio_cli/tools/sqlserver/tests/__init__.py +0 -0
- procesio_cli/tools/sqlserver/tests/conftest.py +21 -0
- procesio_cli/tools/sqlserver/tests/test_connection.py +75 -0
- procesio_cli/tools/sqlserver/tests/test_dbprofiles.py +92 -0
- procesio_cli/tools/sqlserver/tests/test_dbquery.py +220 -0
- procesio_cli/tools/sqlserver/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver.py +326 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver_schema.py +488 -0
- procesio_cli/tools/sqlserver/tool.yaml +123 -0
- procesio_cli/tools/web/README.md +381 -0
- procesio_cli/tools/web/SKILL.md +37 -0
- procesio_cli/tools/web/WEB-AUTOMATION-NOTES.md +277 -0
- procesio_cli/tools/web/__init__.py +21 -0
- procesio_cli/tools/web/actiondef.py +24 -0
- procesio_cli/tools/web/api.py +444 -0
- procesio_cli/tools/web/brokered.py +107 -0
- procesio_cli/tools/web/driver.py +839 -0
- procesio_cli/tools/web/drivercontract.py +44 -0
- procesio_cli/tools/web/errors.py +54 -0
- procesio_cli/tools/web/handlers/__init__.py +1 -0
- procesio_cli/tools/web/handlers/archive.py +367 -0
- procesio_cli/tools/web/handlers/browse.py +182 -0
- procesio_cli/tools/web/handlers/contacts.py +74 -0
- procesio_cli/tools/web/handlers/sessmgmt.py +120 -0
- procesio_cli/tools/web/main.py +128 -0
- procesio_cli/tools/web/sessions.py +253 -0
- procesio_cli/tools/web/steps.py +162 -0
- procesio_cli/tools/web/tests/__init__.py +0 -0
- procesio_cli/tools/web/tests/conftest.py +197 -0
- procesio_cli/tools/web/tests/test_api.py +330 -0
- procesio_cli/tools/web/tests/test_archive.py +190 -0
- procesio_cli/tools/web/tests/test_brokered.py +138 -0
- procesio_cli/tools/web/tests/test_dispatch.py +132 -0
- procesio_cli/tools/web/tests/test_errors.py +60 -0
- procesio_cli/tools/web/tests/test_manifest_sync.py +76 -0
- procesio_cli/tools/web/tests/test_page_contacts.py +68 -0
- procesio_cli/tools/web/tests/test_sessions.py +145 -0
- procesio_cli/tools/web/tests/test_steps.py +210 -0
- procesio_cli/tools/web/tool.yaml +184 -0
- procesio_cli/tools/xlsx/README.md +34 -0
- procesio_cli/tools/xlsx/SKILL.md +28 -0
- procesio_cli/tools/xlsx/__init__.py +0 -0
- procesio_cli/tools/xlsx/main.py +129 -0
- procesio_cli/tools/xlsx/reader.py +91 -0
- procesio_cli/tools/xlsx/tests/__init__.py +0 -0
- procesio_cli/tools/xlsx/tests/conftest.py +39 -0
- procesio_cli/tools/xlsx/tests/test_xlsx.py +103 -0
- procesio_cli/tools/xlsx/tool.yaml +30 -0
- procesio_cli/webplatform/aat_mcp/AAT-MCP-NOTES.md +244 -0
- procesio_cli/webplatform/aat_mcp/README.md +78 -0
- procesio_cli/webplatform/aat_mcp/bridge.py +705 -0
- procesio_cli/webplatform/aat_mcp/chat_server.py +194 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.snapshot.json +668 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.yaml +372 -0
- procesio_cli/webplatform/aat_mcp/gate.py +68 -0
- procesio_cli/webplatform/aat_mcp/http_server.py +139 -0
- procesio_cli/webplatform/aat_mcp/protocol.py +175 -0
- procesio_cli/webplatform/aat_mcp/server.py +306 -0
- procesio_cli/webplatform/aat_mcp/tests/conftest.py +8 -0
- procesio_cli/webplatform/aat_mcp/tests/test_aat_mcp.py +255 -0
- procesio_cli/webplatform/aat_mcp/tests/test_chat_surface.py +247 -0
- procesio_cli/webplatform/aat_mcp/tests/test_discovery.py +489 -0
- procesio_cli/webplatform/aat_mcp/tests/test_multiuser.py +86 -0
- procesio_cli/webplatform/aat_mcp/tests/test_progressive_discovery.py +89 -0
- procesio_cli/webplatform/aat_mcp/tests/test_protocol.py +180 -0
- procesio_cli/webplatform/aat_mcp/tests/test_skill_discovery.py +23 -0
- procesio_cli-0.1.1.dist-info/METADATA +467 -0
- procesio_cli-0.1.1.dist-info/RECORD +647 -0
- procesio_cli-0.1.1.dist-info/WHEEL +4 -0
- procesio_cli-0.1.1.dist-info/entry_points.txt +7 -0
- procesio_cli-0.1.1.dist-info/licenses/LICENSE +201 -0
- procesio_cli-0.1.1.dist-info/licenses/NOTICE +5 -0
|
@@ -0,0 +1,2155 @@
|
|
|
1
|
+
// HTML -> DOCX (Word) converter for the PROCESIO Node action.
|
|
2
|
+
// Pure JavaScript: the sandbox has no require of fs/zlib/buffer, so base64, UTF-8, CRC-32 and a
|
|
3
|
+
// STORED zip are implemented here. Pipeline: parse HTML -> CSS cascade (style blocks, inline
|
|
4
|
+
// style, presentational attributes, a browser default sheet) -> layout into Word paragraphs and
|
|
5
|
+
// tables -> WordprocessingML -> .docx package -> base64.
|
|
6
|
+
var H2D = (function () {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
// ======================= 1. bytes: base64, UTF-8, CRC-32, zip =======================
|
|
10
|
+
var B64C = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
11
|
+
var B64R = new Int16Array(256);
|
|
12
|
+
(function () {
|
|
13
|
+
var i;
|
|
14
|
+
for (i = 0; i < 256; i++) B64R[i] = -1;
|
|
15
|
+
for (i = 0; i < 64; i++) B64R[B64C.charCodeAt(i)] = i;
|
|
16
|
+
B64R[45] = 62; B64R[95] = 63; // url-safe alphabet
|
|
17
|
+
})();
|
|
18
|
+
|
|
19
|
+
function b64decode(s) {
|
|
20
|
+
s = String(s == null ? '' : s);
|
|
21
|
+
var n = s.length, out = new Uint8Array(((n * 3) >> 2) + 4), o = 0, acc = 0, bits = 0;
|
|
22
|
+
for (var i = 0; i < n; i++) {
|
|
23
|
+
var c = s.charCodeAt(i);
|
|
24
|
+
if (c === 61) break;
|
|
25
|
+
var v = c < 256 ? B64R[c] : -1;
|
|
26
|
+
if (v < 0) continue;
|
|
27
|
+
acc = ((acc << 6) | v) & 0xFFFFFF; bits += 6;
|
|
28
|
+
if (bits >= 8) { bits -= 8; out[o++] = (acc >> bits) & 255; }
|
|
29
|
+
}
|
|
30
|
+
return out.subarray(0, o);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function b64encode(b) {
|
|
34
|
+
var parts = [], n = b.length, CH = 3 * 8192;
|
|
35
|
+
for (var i = 0; i < n; i += CH) {
|
|
36
|
+
var end = Math.min(i + CH, n), arr = [];
|
|
37
|
+
for (var j = i; j < end; j += 3) {
|
|
38
|
+
var a = b[j], has1 = j + 1 < end, has2 = j + 2 < end;
|
|
39
|
+
var t = (a << 16) | ((has1 ? b[j + 1] : 0) << 8) | (has2 ? b[j + 2] : 0);
|
|
40
|
+
arr.push(B64C.charAt((t >> 18) & 63) + B64C.charAt((t >> 12) & 63) +
|
|
41
|
+
(has1 ? B64C.charAt((t >> 6) & 63) : '=') + (has2 ? B64C.charAt(t & 63) : '='));
|
|
42
|
+
}
|
|
43
|
+
parts.push(arr.join(''));
|
|
44
|
+
}
|
|
45
|
+
return parts.join('');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var CP1252 = [8364, 0, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 0, 381, 0,
|
|
49
|
+
0, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 0, 382, 376];
|
|
50
|
+
|
|
51
|
+
function fromCP(cp) {
|
|
52
|
+
if (cp > 0xFFFF) { cp -= 0x10000; return String.fromCharCode(0xD800 + (cp >> 10), 0xDC00 + (cp & 1023)); }
|
|
53
|
+
return String.fromCharCode(cp);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function decodeUtf16(b, start, le) {
|
|
57
|
+
var out = [], chunk = [];
|
|
58
|
+
for (var i = start; i + 1 < b.length; i += 2) {
|
|
59
|
+
chunk.push(le ? (b[i] | (b[i + 1] << 8)) : ((b[i] << 8) | b[i + 1]));
|
|
60
|
+
if (chunk.length >= 8192) { out.push(String.fromCharCode.apply(null, chunk)); chunk = []; }
|
|
61
|
+
}
|
|
62
|
+
out.push(String.fromCharCode.apply(null, chunk));
|
|
63
|
+
return out.join('');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function decodeText(b) {
|
|
67
|
+
var n = b.length, i = 0;
|
|
68
|
+
if (n >= 2 && b[0] === 0xFF && b[1] === 0xFE) return decodeUtf16(b, 2, true);
|
|
69
|
+
if (n >= 2 && b[0] === 0xFE && b[1] === 0xFF) return decodeUtf16(b, 2, false);
|
|
70
|
+
if (n >= 3 && b[0] === 0xEF && b[1] === 0xBB && b[2] === 0xBF) i = 3;
|
|
71
|
+
else if (n >= 8) {
|
|
72
|
+
var z = 0, m = Math.min(n, 4000);
|
|
73
|
+
for (var k = 1; k < m; k += 2) if (b[k] === 0) z++;
|
|
74
|
+
if (z > m / 4) return decodeUtf16(b, 0, true);
|
|
75
|
+
}
|
|
76
|
+
var out = [], chunk = [];
|
|
77
|
+
while (i < n) {
|
|
78
|
+
var c = b[i++], cp;
|
|
79
|
+
if (c < 0x80) cp = c;
|
|
80
|
+
else if (c >= 0xC2 && c < 0xE0 && i < n && (b[i] & 0xC0) === 0x80) cp = ((c & 31) << 6) | (b[i++] & 63);
|
|
81
|
+
else if (c >= 0xE0 && c < 0xF0 && i + 1 < n && (b[i] & 0xC0) === 0x80 && (b[i + 1] & 0xC0) === 0x80) {
|
|
82
|
+
cp = ((c & 15) << 12) | ((b[i] & 63) << 6) | (b[i + 1] & 63); i += 2;
|
|
83
|
+
} else if (c >= 0xF0 && c < 0xF5 && i + 2 < n && (b[i] & 0xC0) === 0x80 && (b[i + 1] & 0xC0) === 0x80 && (b[i + 2] & 0xC0) === 0x80) {
|
|
84
|
+
cp = ((c & 7) << 18) | ((b[i] & 63) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63); i += 3;
|
|
85
|
+
} else cp = (c >= 0x80 && c < 0xA0 && CP1252[c - 0x80]) ? CP1252[c - 0x80] : c; // not UTF-8: Windows-1252
|
|
86
|
+
if (cp > 0xFFFF) { cp -= 0x10000; chunk.push(0xD800 + (cp >> 10), 0xDC00 + (cp & 1023)); } else chunk.push(cp);
|
|
87
|
+
if (chunk.length >= 8192) { out.push(String.fromCharCode.apply(null, chunk)); chunk = []; }
|
|
88
|
+
}
|
|
89
|
+
out.push(String.fromCharCode.apply(null, chunk));
|
|
90
|
+
return out.join('');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function utf8encode(s) {
|
|
94
|
+
var n = s.length, buf = new Uint8Array(n * 3 + 8), o = 0;
|
|
95
|
+
for (var i = 0; i < n; i++) {
|
|
96
|
+
var c = s.charCodeAt(i);
|
|
97
|
+
if (c < 0x80) buf[o++] = c;
|
|
98
|
+
else if (c < 0x800) { buf[o++] = 0xC0 | (c >> 6); buf[o++] = 0x80 | (c & 63); }
|
|
99
|
+
else if (c >= 0xD800 && c < 0xDC00 && i + 1 < n && (s.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
|
|
100
|
+
var cp = 0x10000 + ((c - 0xD800) << 10) + (s.charCodeAt(++i) - 0xDC00);
|
|
101
|
+
buf[o++] = 0xF0 | (cp >> 18); buf[o++] = 0x80 | ((cp >> 12) & 63);
|
|
102
|
+
buf[o++] = 0x80 | ((cp >> 6) & 63); buf[o++] = 0x80 | (cp & 63);
|
|
103
|
+
} else {
|
|
104
|
+
if (c >= 0xD800 && c < 0xE000) c = 0xFFFD;
|
|
105
|
+
buf[o++] = 0xE0 | (c >> 12); buf[o++] = 0x80 | ((c >> 6) & 63); buf[o++] = 0x80 | (c & 63);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return buf.subarray(0, o);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
var CRC_T = (function () {
|
|
112
|
+
var t = new Int32Array(256);
|
|
113
|
+
for (var n = 0; n < 256; n++) {
|
|
114
|
+
var c = n;
|
|
115
|
+
for (var k = 0; k < 8; k++) c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
|
|
116
|
+
t[n] = c;
|
|
117
|
+
}
|
|
118
|
+
return t;
|
|
119
|
+
})();
|
|
120
|
+
|
|
121
|
+
function crc32(b) {
|
|
122
|
+
var c = -1;
|
|
123
|
+
for (var i = 0; i < b.length; i++) c = CRC_T[(c ^ b[i]) & 255] ^ (c >>> 8);
|
|
124
|
+
return (c ^ -1) >>> 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// STORED (uncompressed) zip: Word reads it, and it needs no deflate.
|
|
128
|
+
function zipStore(files) {
|
|
129
|
+
var d = new Date();
|
|
130
|
+
var dosTime = (d.getHours() << 11) | (d.getMinutes() << 5) | (d.getSeconds() >> 1);
|
|
131
|
+
var dosDate = ((d.getFullYear() - 1980) << 9) | ((d.getMonth() + 1) << 5) | d.getDate();
|
|
132
|
+
var recs = [], total = 22, i;
|
|
133
|
+
for (i = 0; i < files.length; i++) {
|
|
134
|
+
var nm = utf8encode(files[i].name);
|
|
135
|
+
recs.push({ nm: nm, data: files[i].data, crc: crc32(files[i].data), off: 0 });
|
|
136
|
+
total += 30 + nm.length + files[i].data.length + 46 + nm.length;
|
|
137
|
+
}
|
|
138
|
+
var out = new Uint8Array(total), p = 0;
|
|
139
|
+
function u16(v) { out[p++] = v & 255; out[p++] = (v >>> 8) & 255; }
|
|
140
|
+
function u32(v) { out[p++] = v & 255; out[p++] = (v >>> 8) & 255; out[p++] = (v >>> 16) & 255; out[p++] = (v >>> 24) & 255; }
|
|
141
|
+
for (i = 0; i < recs.length; i++) {
|
|
142
|
+
var f = recs[i];
|
|
143
|
+
f.off = p;
|
|
144
|
+
u32(0x04034b50); u16(20); u16(0); u16(0); u16(dosTime); u16(dosDate);
|
|
145
|
+
u32(f.crc); u32(f.data.length); u32(f.data.length); u16(f.nm.length); u16(0);
|
|
146
|
+
out.set(f.nm, p); p += f.nm.length;
|
|
147
|
+
out.set(f.data, p); p += f.data.length;
|
|
148
|
+
}
|
|
149
|
+
var cd = p;
|
|
150
|
+
for (i = 0; i < recs.length; i++) {
|
|
151
|
+
var g = recs[i];
|
|
152
|
+
u32(0x02014b50); u16(20); u16(20); u16(0); u16(0); u16(dosTime); u16(dosDate);
|
|
153
|
+
u32(g.crc); u32(g.data.length); u32(g.data.length); u16(g.nm.length);
|
|
154
|
+
u16(0); u16(0); u16(0); u16(0); u32(0); u32(g.off);
|
|
155
|
+
out.set(g.nm, p); p += g.nm.length;
|
|
156
|
+
}
|
|
157
|
+
var cdSize = p - cd;
|
|
158
|
+
u32(0x06054b50); u16(0); u16(0); u16(recs.length); u16(recs.length); u32(cdSize); u32(cd); u16(0);
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ======================= 2. small helpers =======================
|
|
163
|
+
function toSet(s) { var o = Object.create(null); s.split(/\s+/).forEach(function (k) { if (k) o[k] = true; }); return o; }
|
|
164
|
+
function isSp(c) { return c === 32 || c === 9 || c === 10 || c === 13 || c === 12; }
|
|
165
|
+
function clamp(v, a, b) { return v < a ? a : v > b ? b : v; }
|
|
166
|
+
function twip(pt) { return Math.round(pt * 20); }
|
|
167
|
+
function xesc(s) {
|
|
168
|
+
return String(s).replace(/[&<>"]/g, function (c) { return c === '&' ? '&' : c === '<' ? '<' : c === '>' ? '>' : '"'; })
|
|
169
|
+
.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, '')
|
|
170
|
+
.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]/g, '$1');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ======================= 3. HTML entities + parser =======================
|
|
174
|
+
var ENT = Object.create(null);
|
|
175
|
+
(function () {
|
|
176
|
+
var l1 = ('nbsp iexcl cent pound curren yen brvbar sect uml copy ordf laquo not shy reg macr deg plusmn sup2 sup3 ' +
|
|
177
|
+
'acute micro para middot cedil sup1 ordm raquo frac14 frac12 frac34 iquest Agrave Aacute Acirc Atilde Auml Aring ' +
|
|
178
|
+
'AElig Ccedil Egrave Eacute Ecirc Euml Igrave Iacute Icirc Iuml ETH Ntilde Ograve Oacute Ocirc Otilde Ouml times ' +
|
|
179
|
+
'Oslash Ugrave Uacute Ucirc Uuml Yacute THORN szlig agrave aacute acirc atilde auml aring aelig ccedil egrave eacute ' +
|
|
180
|
+
'ecirc euml igrave iacute icirc iuml eth ntilde ograve oacute ocirc otilde ouml divide oslash ugrave uacute ucirc ' +
|
|
181
|
+
'uuml yacute thorn yuml').split(' ');
|
|
182
|
+
for (var i = 0; i < l1.length; i++) ENT[l1[i]] = 160 + i;
|
|
183
|
+
var more = 'amp:38 lt:60 gt:62 quot:34 apos:39 OElig:338 oelig:339 Scaron:352 scaron:353 Yuml:376 fnof:402 circ:710 ' +
|
|
184
|
+
'tilde:732 ensp:8194 emsp:8195 thinsp:8201 zwnj:8204 zwj:8205 lrm:8206 rlm:8207 ndash:8211 mdash:8212 lsquo:8216 ' +
|
|
185
|
+
'rsquo:8217 sbquo:8218 ldquo:8220 rdquo:8221 bdquo:8222 dagger:8224 Dagger:8225 bull:8226 hellip:8230 permil:8240 ' +
|
|
186
|
+
'prime:8242 Prime:8243 lsaquo:8249 rsaquo:8250 oline:8254 frasl:8260 euro:8364 trade:8482 larr:8592 uarr:8593 ' +
|
|
187
|
+
'rarr:8594 darr:8595 harr:8596 minus:8722 lowast:8727 le:8804 ge:8805 ne:8800 asymp:8776 infin:8734 sum:8721 ' +
|
|
188
|
+
'prod:8719 radic:8730 part:8706 isin:8712 cap:8745 cup:8746 int:8747 there4:8756 sim:8764 equiv:8801 sub:8834 ' +
|
|
189
|
+
'sup:8835 loz:9674 spades:9824 clubs:9827 hearts:9829 diams:9830 check:10003 cross:10007 Abreve:258 abreve:259 ' +
|
|
190
|
+
'Scedil:350 scedil:351 Tcedil:354 tcedil:355 Zcaron:381 zcaron:382 alpha:945 beta:946 gamma:947 delta:948 ' +
|
|
191
|
+
'epsilon:949 lambda:955 mu:956 pi:960 sigma:963 omega:969 Delta:916 Omega:937 nbhy:8209 hyphen:8208 dash:8208 ' +
|
|
192
|
+
'Tab:9 NewLine:10 nobreak:8288 ballot:9744 boxv:9474';
|
|
193
|
+
more.split(' ').forEach(function (kv) { var p = kv.split(':'); ENT[p[0]] = +p[1]; });
|
|
194
|
+
})();
|
|
195
|
+
|
|
196
|
+
function decodeEntities(s) {
|
|
197
|
+
if (s.indexOf('&') < 0) return s;
|
|
198
|
+
return s.replace(/&(#[xX][0-9a-fA-F]{1,6}|#[0-9]{1,7}|[a-zA-Z][a-zA-Z0-9]{1,31});?/g, function (m, e) {
|
|
199
|
+
if (e.charAt(0) === '#') {
|
|
200
|
+
var hex = e.charAt(1) === 'x' || e.charAt(1) === 'X';
|
|
201
|
+
var cp = hex ? parseInt(e.slice(2), 16) : parseInt(e.slice(1), 10);
|
|
202
|
+
if (!(cp > 0) || cp > 0x10FFFF || (cp >= 0xD800 && cp < 0xE000)) cp = 0xFFFD;
|
|
203
|
+
if (cp >= 0x80 && cp < 0xA0 && CP1252[cp - 0x80]) cp = CP1252[cp - 0x80];
|
|
204
|
+
return fromCP(cp);
|
|
205
|
+
}
|
|
206
|
+
if (ENT[e] !== undefined) return fromCP(ENT[e]);
|
|
207
|
+
return m;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
var VOID = toSet('area base br col embed hr img input keygen link meta param source track wbr');
|
|
212
|
+
var RAWTXT = toSet('script style textarea title xmp noscript iframe noembed noframes template svg math');
|
|
213
|
+
var P_CLOSERS = toSet('address article aside blockquote center details dialog dir div dl fieldset figcaption figure footer ' +
|
|
214
|
+
'form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul li dd dt');
|
|
215
|
+
var SCOPE = toSet('table td th caption html template applet marquee object button');
|
|
216
|
+
var LIST_SCOPE = toSet('table td th caption html template applet marquee object button ol ul');
|
|
217
|
+
var TABLE_SCOPE = toSet('table html template');
|
|
218
|
+
var ROW_SCOPE = toSet('tr table html template');
|
|
219
|
+
var NO_SCOPE = toSet('html');
|
|
220
|
+
|
|
221
|
+
function mkEl(tag, attrs, parent) { return { tag: tag, attrs: attrs || Object.create(null), children: [], parent: parent || null }; }
|
|
222
|
+
|
|
223
|
+
function parseStartTag(src, i) {
|
|
224
|
+
var n = src.length, j = i + 1, s0 = j, c;
|
|
225
|
+
while (j < n) { c = src.charCodeAt(j); if (isSp(c) || c === 47 || c === 62) break; j++; }
|
|
226
|
+
var tag = src.slice(s0, j).toLowerCase(), attrs = Object.create(null), selfClose = false;
|
|
227
|
+
while (j < n) {
|
|
228
|
+
c = src.charCodeAt(j);
|
|
229
|
+
if (isSp(c)) { j++; continue; }
|
|
230
|
+
if (c === 62) { j++; break; }
|
|
231
|
+
if (c === 47) { j++; if (src.charCodeAt(j) === 62) { selfClose = true; j++; break; } continue; }
|
|
232
|
+
var a0 = j;
|
|
233
|
+
while (j < n) {
|
|
234
|
+
c = src.charCodeAt(j);
|
|
235
|
+
if (isSp(c) || c === 61 || c === 62 || (c === 47 && src.charCodeAt(j + 1) === 62)) break;
|
|
236
|
+
j++;
|
|
237
|
+
}
|
|
238
|
+
if (j === a0) { j++; continue; }
|
|
239
|
+
var an = src.slice(a0, j).toLowerCase(), av = '';
|
|
240
|
+
while (j < n && isSp(src.charCodeAt(j))) j++;
|
|
241
|
+
if (src.charCodeAt(j) === 61) {
|
|
242
|
+
j++;
|
|
243
|
+
while (j < n && isSp(src.charCodeAt(j))) j++;
|
|
244
|
+
var q = src.charCodeAt(j);
|
|
245
|
+
if (q === 34 || q === 39) {
|
|
246
|
+
var qe = src.indexOf(q === 34 ? '"' : "'", j + 1);
|
|
247
|
+
if (qe < 0) qe = n;
|
|
248
|
+
av = src.slice(j + 1, qe); j = qe + 1;
|
|
249
|
+
} else {
|
|
250
|
+
var v0 = j;
|
|
251
|
+
while (j < n && !isSp(src.charCodeAt(j)) && src.charCodeAt(j) !== 62) j++;
|
|
252
|
+
av = src.slice(v0, j);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (!(an in attrs)) attrs[an] = decodeEntities(av);
|
|
256
|
+
}
|
|
257
|
+
return { tag: tag, attrs: attrs, selfClose: selfClose, end: j };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function parseHTML(src) {
|
|
261
|
+
var root = mkEl('#root'), stack = [root], i = 0, n = src.length, lower = null;
|
|
262
|
+
function top() { return stack[stack.length - 1]; }
|
|
263
|
+
function addText(t) {
|
|
264
|
+
if (!t) return;
|
|
265
|
+
var p = top(), last = p.children[p.children.length - 1];
|
|
266
|
+
if (last && last.tag === '#text') last.text += t; else p.children.push({ tag: '#text', text: t, parent: p });
|
|
267
|
+
}
|
|
268
|
+
function findOpen(tag, scope) {
|
|
269
|
+
for (var k = stack.length - 1; k > 0; k--) {
|
|
270
|
+
var t = stack[k].tag;
|
|
271
|
+
if (t === tag) return k;
|
|
272
|
+
if (scope[t]) return -1;
|
|
273
|
+
}
|
|
274
|
+
return -1;
|
|
275
|
+
}
|
|
276
|
+
function closeTo(k) { if (k > 0) stack.length = k; }
|
|
277
|
+
function start(tag, attrs, selfClose) {
|
|
278
|
+
if (P_CLOSERS[tag]) closeTo(findOpen('p', SCOPE));
|
|
279
|
+
if (tag === 'li') closeTo(findOpen('li', LIST_SCOPE));
|
|
280
|
+
else if (tag === 'dt' || tag === 'dd') { closeTo(findOpen('dt', SCOPE)); closeTo(findOpen('dd', SCOPE)); }
|
|
281
|
+
else if (tag === 'tr') closeTo(findOpen('tr', TABLE_SCOPE));
|
|
282
|
+
else if (tag === 'td' || tag === 'th') { closeTo(findOpen('td', ROW_SCOPE)); closeTo(findOpen('th', ROW_SCOPE)); }
|
|
283
|
+
else if (tag === 'thead' || tag === 'tbody' || tag === 'tfoot') {
|
|
284
|
+
closeTo(findOpen('thead', TABLE_SCOPE)); closeTo(findOpen('tbody', TABLE_SCOPE)); closeTo(findOpen('tfoot', TABLE_SCOPE));
|
|
285
|
+
} else if (tag === 'option') closeTo(findOpen('option', SCOPE));
|
|
286
|
+
else if (tag === 'a') closeTo(findOpen('a', SCOPE));
|
|
287
|
+
else if (/^h[1-6]$/.test(tag) && /^h[1-6]$/.test(top().tag)) stack.pop();
|
|
288
|
+
var p = top(), e = mkEl(tag, attrs, p);
|
|
289
|
+
p.children.push(e);
|
|
290
|
+
if (!VOID[tag] && !selfClose && stack.length < 400) stack.push(e);
|
|
291
|
+
return e;
|
|
292
|
+
}
|
|
293
|
+
function end(tag) {
|
|
294
|
+
if (tag === 'br') { start('br', Object.create(null), true); return; }
|
|
295
|
+
if (VOID[tag]) return;
|
|
296
|
+
if (tag === 'p' && findOpen('p', SCOPE) < 0) { start('p', Object.create(null), true); return; }
|
|
297
|
+
var scope = tag === 'table' ? NO_SCOPE
|
|
298
|
+
: /^(td|th|tr|thead|tbody|tfoot|caption|colgroup)$/.test(tag) ? TABLE_SCOPE : SCOPE;
|
|
299
|
+
closeTo(findOpen(tag, scope));
|
|
300
|
+
}
|
|
301
|
+
while (i < n) {
|
|
302
|
+
var lt = src.indexOf('<', i);
|
|
303
|
+
if (lt < 0) { addText(decodeEntities(src.slice(i))); break; }
|
|
304
|
+
if (lt > i) addText(decodeEntities(src.slice(i, lt)));
|
|
305
|
+
i = lt;
|
|
306
|
+
var c1 = src.charCodeAt(i + 1);
|
|
307
|
+
if (c1 === 33) {
|
|
308
|
+
if (src.substr(i, 4) === '<!--') { var ce = src.indexOf('-->', i + 4); i = ce < 0 ? n : ce + 3; }
|
|
309
|
+
else if (src.substr(i, 9).toUpperCase() === '<![CDATA[') {
|
|
310
|
+
var cd = src.indexOf(']]>', i + 9); addText(src.slice(i + 9, cd < 0 ? n : cd)); i = cd < 0 ? n : cd + 3;
|
|
311
|
+
} else { var ge = src.indexOf('>', i); i = ge < 0 ? n : ge + 1; }
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (c1 === 63) { var qe = src.indexOf('>', i); i = qe < 0 ? n : qe + 1; continue; }
|
|
315
|
+
if (c1 === 47) {
|
|
316
|
+
var j = i + 2, s0 = j;
|
|
317
|
+
while (j < n) { var cc = src.charCodeAt(j); if (isSp(cc) || cc === 62 || cc === 47) break; j++; }
|
|
318
|
+
var ee = src.indexOf('>', j);
|
|
319
|
+
if (j > s0) end(src.slice(s0, j).toLowerCase());
|
|
320
|
+
i = ee < 0 ? n : ee + 1;
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
if ((c1 >= 65 && c1 <= 90) || (c1 >= 97 && c1 <= 122)) {
|
|
324
|
+
var st = parseStartTag(src, i);
|
|
325
|
+
i = st.end;
|
|
326
|
+
var node = start(st.tag, st.attrs, st.selfClose);
|
|
327
|
+
if (RAWTXT[st.tag] && !st.selfClose) {
|
|
328
|
+
if (!lower) lower = src.toLowerCase();
|
|
329
|
+
var close = lower.indexOf('</' + st.tag, i);
|
|
330
|
+
var raw = src.slice(i, close < 0 ? n : close);
|
|
331
|
+
if (raw) node.children.push({ tag: '#text', text: (st.tag === 'textarea' || st.tag === 'title') ? decodeEntities(raw) : raw, parent: node });
|
|
332
|
+
var k = stack.lastIndexOf(node);
|
|
333
|
+
if (k > 0) stack.length = k;
|
|
334
|
+
if (close < 0) i = n; else { var gt = src.indexOf('>', close); i = gt < 0 ? n : gt + 1; }
|
|
335
|
+
}
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
addText('<'); i++;
|
|
339
|
+
}
|
|
340
|
+
return root;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// a fragment without <body> gets one, the way a browser builds it
|
|
344
|
+
function ensureBody(root) {
|
|
345
|
+
var html = null, found = false;
|
|
346
|
+
(function walk(n) {
|
|
347
|
+
if (found) return;
|
|
348
|
+
if (n.tag === 'body') { found = true; return; }
|
|
349
|
+
if (n.tag === 'html' && !html) html = n;
|
|
350
|
+
for (var i = 0; i < n.children.length; i++) if (n.children[i].tag !== '#text') walk(n.children[i]);
|
|
351
|
+
})(root);
|
|
352
|
+
if (found) return;
|
|
353
|
+
var host = html || root, body = mkEl('body', Object.create(null), host), keep = [];
|
|
354
|
+
host.children.forEach(function (c) {
|
|
355
|
+
if (c.tag === 'head' || (c.tag === 'html' && c !== host)) keep.push(c);
|
|
356
|
+
else { c.parent = body; body.children.push(c); }
|
|
357
|
+
});
|
|
358
|
+
keep.push(body);
|
|
359
|
+
host.children = keep;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function annotate(node) {
|
|
363
|
+
var els = [];
|
|
364
|
+
for (var k = 0; k < node.children.length; k++) {
|
|
365
|
+
var ch = node.children[k];
|
|
366
|
+
ch.parent = node;
|
|
367
|
+
if (ch.tag !== '#text') { ch.eidx = els.length; els.push(ch); annotate(ch); }
|
|
368
|
+
}
|
|
369
|
+
node.els = els;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// ======================= 4. CSS: values =======================
|
|
373
|
+
var NAMED = Object.create(null);
|
|
374
|
+
('aliceblue:f0f8ff antiquewhite:faebd7 aqua:00ffff aquamarine:7fffd4 azure:f0ffff beige:f5f5dc bisque:ffe4c4 black:000000 ' +
|
|
375
|
+
'blanchedalmond:ffebcd blue:0000ff blueviolet:8a2be2 brown:a52a2a burlywood:deb887 cadetblue:5f9ea0 chartreuse:7fff00 ' +
|
|
376
|
+
'chocolate:d2691e coral:ff7f50 cornflowerblue:6495ed cornsilk:fff8dc crimson:dc143c cyan:00ffff darkblue:00008b ' +
|
|
377
|
+
'darkcyan:008b8b darkgoldenrod:b8860b darkgray:a9a9a9 darkgreen:006400 darkgrey:a9a9a9 darkkhaki:bdb76b ' +
|
|
378
|
+
'darkmagenta:8b008b darkolivegreen:556b2f darkorange:ff8c00 darkorchid:9932cc darkred:8b0000 darksalmon:e9967a ' +
|
|
379
|
+
'darkseagreen:8fbc8f darkslateblue:483d8b darkslategray:2f4f4f darkslategrey:2f4f4f darkturquoise:00ced1 ' +
|
|
380
|
+
'darkviolet:9400d3 deeppink:ff1493 deepskyblue:00bfff dimgray:696969 dimgrey:696969 dodgerblue:1e90ff ' +
|
|
381
|
+
'firebrick:b22222 floralwhite:fffaf0 forestgreen:228b22 fuchsia:ff00ff gainsboro:dcdcdc ghostwhite:f8f8ff gold:ffd700 ' +
|
|
382
|
+
'goldenrod:daa520 gray:808080 green:008000 greenyellow:adff2f grey:808080 honeydew:f0fff0 hotpink:ff69b4 ' +
|
|
383
|
+
'indianred:cd5c5c indigo:4b0082 ivory:fffff0 khaki:f0e68c lavender:e6e6fa lavenderblush:fff0f5 lawngreen:7cfc00 ' +
|
|
384
|
+
'lemonchiffon:fffacd lightblue:add8e6 lightcoral:f08080 lightcyan:e0ffff lightgoldenrodyellow:fafad2 lightgray:d3d3d3 ' +
|
|
385
|
+
'lightgreen:90ee90 lightgrey:d3d3d3 lightpink:ffb6c1 lightsalmon:ffa07a lightseagreen:20b2aa lightskyblue:87cefa ' +
|
|
386
|
+
'lightslategray:778899 lightslategrey:778899 lightsteelblue:b0c4de lightyellow:ffffe0 lime:00ff00 limegreen:32cd32 ' +
|
|
387
|
+
'linen:faf0e6 magenta:ff00ff maroon:800000 mediumaquamarine:66cdaa mediumblue:0000cd mediumorchid:ba55d3 ' +
|
|
388
|
+
'mediumpurple:9370db mediumseagreen:3cb371 mediumslateblue:7b68ee mediumspringgreen:00fa9a mediumturquoise:48d1cc ' +
|
|
389
|
+
'mediumvioletred:c71585 midnightblue:191970 mintcream:f5fffa mistyrose:ffe4e1 moccasin:ffe4b5 navajowhite:ffdead ' +
|
|
390
|
+
'navy:000080 oldlace:fdf5e6 olive:808000 olivedrab:6b8e23 orange:ffa500 orangered:ff4500 orchid:da70d6 ' +
|
|
391
|
+
'palegoldenrod:eee8aa palegreen:98fb98 paleturquoise:afeeee palevioletred:db7093 papayawhip:ffefd5 peachpuff:ffdab9 ' +
|
|
392
|
+
'peru:cd853f pink:ffc0cb plum:dda0dd powderblue:b0e0e6 purple:800080 rebeccapurple:663399 red:ff0000 ' +
|
|
393
|
+
'rosybrown:bc8f8f royalblue:4169e1 saddlebrown:8b4513 salmon:fa8072 sandybrown:f4a460 seagreen:2e8b57 ' +
|
|
394
|
+
'seashell:fff5ee sienna:a0522d silver:c0c0c0 skyblue:87ceeb slateblue:6a5acd slategray:708090 slategrey:708090 ' +
|
|
395
|
+
'snow:fffafa springgreen:00ff7f steelblue:4682b4 tan:d2b48c teal:008080 thistle:d8bfd8 tomato:ff6347 ' +
|
|
396
|
+
'turquoise:40e0d0 violet:ee82ee wheat:f5deb3 white:ffffff whitesmoke:f5f5f5 yellow:ffff00 yellowgreen:9acd32 ' +
|
|
397
|
+
'windowtext:000000 buttontext:000000 canvastext:000000 canvas:ffffff window:ffffff')
|
|
398
|
+
.split(' ').forEach(function (kv) { var p = kv.split(':'); NAMED[p[0]] = p[1].toUpperCase(); });
|
|
399
|
+
|
|
400
|
+
function hex2(n) { n = clamp(Math.round(n), 0, 255); return (n < 16 ? '0' : '') + n.toString(16).toUpperCase(); }
|
|
401
|
+
function blend(r, g, b, a) { // alpha over white
|
|
402
|
+
if (a >= 1) return hex2(r) + hex2(g) + hex2(b);
|
|
403
|
+
if (a <= 0.02) return null;
|
|
404
|
+
return hex2(r * a + 255 * (1 - a)) + hex2(g * a + 255 * (1 - a)) + hex2(b * a + 255 * (1 - a));
|
|
405
|
+
}
|
|
406
|
+
function hsl2rgb(h, s, l) {
|
|
407
|
+
h = ((h % 360) + 360) % 360 / 360; s = clamp(s, 0, 1); l = clamp(l, 0, 1);
|
|
408
|
+
function f(t) { t = (t + 1) % 1; return t < 1 / 6 ? p + (q - p) * 6 * t : t < 0.5 ? q : t < 2 / 3 ? p + (q - p) * (2 / 3 - t) * 6 : p; }
|
|
409
|
+
var q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;
|
|
410
|
+
return [f(h + 1 / 3) * 255, f(h) * 255, f(h - 1 / 3) * 255];
|
|
411
|
+
}
|
|
412
|
+
// returns 'RRGGBB', null (transparent) or undefined (not a colour)
|
|
413
|
+
function parseColor(v, current) {
|
|
414
|
+
v = String(v).trim().toLowerCase();
|
|
415
|
+
if (!v) return undefined;
|
|
416
|
+
if (v === 'transparent' || v === 'none') return null;
|
|
417
|
+
if (v === 'currentcolor') return current;
|
|
418
|
+
if (v.charAt(0) === '#') {
|
|
419
|
+
var h = v.slice(1);
|
|
420
|
+
if (!/^[0-9a-f]+$/.test(h)) return undefined;
|
|
421
|
+
if (h.length === 3 || h.length === 4) {
|
|
422
|
+
var a3 = h.length === 4 ? parseInt(h.charAt(3) + h.charAt(3), 16) / 255 : 1;
|
|
423
|
+
return blend(parseInt(h.charAt(0) + h.charAt(0), 16), parseInt(h.charAt(1) + h.charAt(1), 16), parseInt(h.charAt(2) + h.charAt(2), 16), a3);
|
|
424
|
+
}
|
|
425
|
+
if (h.length === 6 || h.length === 8) {
|
|
426
|
+
var a6 = h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;
|
|
427
|
+
return blend(parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16), a6);
|
|
428
|
+
}
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
var m = /^(rgba?|hsla?)\(([^)]*)\)$/.exec(v);
|
|
432
|
+
if (m) {
|
|
433
|
+
var parts = m[2].replace(/\//g, ' ').split(/[\s,]+/).filter(Boolean);
|
|
434
|
+
if (parts.length < 3) return undefined;
|
|
435
|
+
var al = parts.length > 3 ? (parts[3].slice(-1) === '%' ? parseFloat(parts[3]) / 100 : parseFloat(parts[3])) : 1;
|
|
436
|
+
if (m[1].charAt(0) === 'r') {
|
|
437
|
+
var ch = parts.slice(0, 3).map(function (x) { return x.slice(-1) === '%' ? parseFloat(x) * 2.55 : parseFloat(x); });
|
|
438
|
+
return blend(ch[0], ch[1], ch[2], al);
|
|
439
|
+
}
|
|
440
|
+
var rgb = hsl2rgb(parseFloat(parts[0]), parseFloat(parts[1]) / 100, parseFloat(parts[2]) / 100);
|
|
441
|
+
return blend(rgb[0], rgb[1], rgb[2], al);
|
|
442
|
+
}
|
|
443
|
+
if (NAMED[v]) return NAMED[v];
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
var PT = { pt: 1, px: 0.75, cm: 28.3464567, mm: 2.83464567, 'in': 72, pc: 12, q: 0.708661 };
|
|
448
|
+
// length -> {pt} | {pct} | {auto:true} | null
|
|
449
|
+
function parseLen(v, fs, rootFs) {
|
|
450
|
+
if (v == null) return null;
|
|
451
|
+
v = String(v).trim().toLowerCase();
|
|
452
|
+
if (!v) return null;
|
|
453
|
+
if (v === 'auto') return { auto: true };
|
|
454
|
+
var m = /^(-?(?:\d+\.?\d*|\.\d+)(?:e-?\d+)?)\s*([a-z%]*)$/.exec(v);
|
|
455
|
+
if (!m) return null;
|
|
456
|
+
var x = parseFloat(m[1]), u = m[2];
|
|
457
|
+
if (u === '' || u === 'px') return { pt: x * 0.75 };
|
|
458
|
+
if (PT[u]) return { pt: x * PT[u] };
|
|
459
|
+
if (u === 'em') return { pt: x * fs };
|
|
460
|
+
if (u === 'rem') return { pt: x * rootFs };
|
|
461
|
+
if (u === 'ex' || u === 'ch') return { pt: x * fs * 0.5 };
|
|
462
|
+
if (u === '%') return { pct: x };
|
|
463
|
+
if (u === 'vw') return { pct: x };
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
function res(L, ref) { if (!L || L.auto) return null; return L.pct != null ? L.pct * (ref || 0) / 100 : L.pt; }
|
|
467
|
+
function res0(L, ref) { var r = res(L, ref); return r == null ? 0 : r; }
|
|
468
|
+
|
|
469
|
+
var FS_KEY = { 'xx-small': 6.75, 'x-small': 7.5, small: 9.75, medium: 12, large: 13.5, 'x-large': 18, 'xx-large': 24, 'xxx-large': 36 };
|
|
470
|
+
var BW_KEY = { thin: 0.75, medium: 2.25, thick: 3.75 };
|
|
471
|
+
var GENERIC = { serif: 'Times New Roman', 'sans-serif': 'Arial', monospace: 'Courier New', cursive: 'Comic Sans MS',
|
|
472
|
+
fantasy: 'Impact', 'system-ui': 'Arial', '-apple-system': 'Arial', blinkmacsystemfont: 'Arial', 'ui-sans-serif': 'Arial',
|
|
473
|
+
'ui-serif': 'Times New Roman', 'ui-monospace': 'Courier New', 'liberation sans': 'Arial', arimo: 'Arial', helvetica: 'Arial',
|
|
474
|
+
'helvetica neue': 'Arial', 'liberation serif': 'Times New Roman', tinos: 'Times New Roman', 'liberation mono': 'Courier New',
|
|
475
|
+
cousine: 'Courier New', carlito: 'Calibri', caladea: 'Cambria', times: 'Times New Roman' };
|
|
476
|
+
var LINE_FACTOR = { arial: 1.149, 'times new roman': 1.149, calibri: 1.2207, cambria: 1.1724, 'courier new': 1.1328,
|
|
477
|
+
verdana: 1.2153, tahoma: 1.2075, georgia: 1.1362, 'segoe ui': 1.33, 'trebuchet ms': 1.1621, garamond: 1.12,
|
|
478
|
+
'book antiqua': 1.17, 'century gothic': 1.2, 'comic sans ms': 1.394, impact: 1.22, 'palatino linotype': 1.32,
|
|
479
|
+
'dejavu sans': 1.164, 'open sans': 1.362, roboto: 1.172, lato: 1.2, 'arial narrow': 1.149 };
|
|
480
|
+
|
|
481
|
+
function splitTop(s, sep) {
|
|
482
|
+
var out = [], depth = 0, q = 0, last = 0;
|
|
483
|
+
for (var i = 0; i < s.length; i++) {
|
|
484
|
+
var c = s.charAt(i);
|
|
485
|
+
if (q) { if (c === '\\') i++; else if (c === q) q = 0; continue; }
|
|
486
|
+
if (c === '"' || c === "'") q = c;
|
|
487
|
+
else if (c === '(' || c === '[') depth++;
|
|
488
|
+
else if (c === ')' || c === ']') depth--;
|
|
489
|
+
else if (c === sep && depth <= 0) { out.push(s.slice(last, i)); last = i + 1; }
|
|
490
|
+
}
|
|
491
|
+
out.push(s.slice(last));
|
|
492
|
+
return out;
|
|
493
|
+
}
|
|
494
|
+
function tokens(v) { return splitTop(String(v).trim().replace(/\s+/g, ' '), ' ').filter(Boolean); }
|
|
495
|
+
|
|
496
|
+
function firstFamily(v) {
|
|
497
|
+
var fams = splitTop(v, ',');
|
|
498
|
+
for (var i = 0; i < fams.length; i++) {
|
|
499
|
+
var f = fams[i].trim().replace(/^["']|["']$/g, '').trim();
|
|
500
|
+
if (!f || /^(inherit|initial|unset)$/i.test(f)) continue;
|
|
501
|
+
var g = GENERIC[f.toLowerCase()];
|
|
502
|
+
return g || f;
|
|
503
|
+
}
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// ======================= 5. CSS: parser =======================
|
|
508
|
+
var BORDER_STYLES = toSet('none hidden dotted dashed solid double groove ridge inset outset');
|
|
509
|
+
var SIDES = ['top', 'right', 'bottom', 'left'];
|
|
510
|
+
|
|
511
|
+
function box4(v) {
|
|
512
|
+
var t = tokens(v);
|
|
513
|
+
if (!t.length) return null;
|
|
514
|
+
return [t[0], t[1] || t[0], t[2] || t[0], t[3] || t[1] || t[0]];
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function expandDecl(name, val, imp, out) {
|
|
518
|
+
function put(p, v) { out.push({ p: p, v: v, imp: imp }); }
|
|
519
|
+
var lv = val.toLowerCase(), t, i, k;
|
|
520
|
+
if (/^(inherit|initial|unset)$/.test(lv) && /^(margin|padding|border|border-(top|right|bottom|left)|background|font|list-style|text-decoration)$/.test(name)) {
|
|
521
|
+
if (name === 'margin' || name === 'padding') { SIDES.forEach(function (s) { put(name + '-' + s, lv); }); return; }
|
|
522
|
+
}
|
|
523
|
+
switch (name) {
|
|
524
|
+
case 'margin': case 'padding':
|
|
525
|
+
t = box4(val); if (t) for (i = 0; i < 4; i++) put(name + '-' + SIDES[i], t[i]);
|
|
526
|
+
return;
|
|
527
|
+
case 'border': case 'border-top': case 'border-right': case 'border-bottom': case 'border-left':
|
|
528
|
+
var w = null, s = null, c = null;
|
|
529
|
+
tokens(val).forEach(function (tk) {
|
|
530
|
+
var l = tk.toLowerCase();
|
|
531
|
+
if (BORDER_STYLES[l]) s = l;
|
|
532
|
+
else if (BW_KEY[l] !== undefined || /^-?[\d.]/.test(l)) w = l;
|
|
533
|
+
else c = tk;
|
|
534
|
+
});
|
|
535
|
+
var sides = name === 'border' ? SIDES : [name.slice(7)];
|
|
536
|
+
sides.forEach(function (sd) {
|
|
537
|
+
put('border-' + sd + '-style', s || 'none');
|
|
538
|
+
put('border-' + sd + '-width', w || 'medium');
|
|
539
|
+
put('border-' + sd + '-color', c || 'currentcolor');
|
|
540
|
+
});
|
|
541
|
+
return;
|
|
542
|
+
case 'border-width': case 'border-style': case 'border-color':
|
|
543
|
+
t = box4(val); k = name.slice(7);
|
|
544
|
+
if (t) for (i = 0; i < 4; i++) put('border-' + SIDES[i] + '-' + k, t[i]);
|
|
545
|
+
return;
|
|
546
|
+
case 'background':
|
|
547
|
+
var col = null;
|
|
548
|
+
tokens(val).forEach(function (tk) { if (col == null && parseColor(tk, null) !== undefined) col = tk; });
|
|
549
|
+
put('background-color', col || 'transparent');
|
|
550
|
+
return;
|
|
551
|
+
case 'font':
|
|
552
|
+
var tk = tokens(val), idx = -1;
|
|
553
|
+
for (i = 0; i < tk.length; i++) {
|
|
554
|
+
var x = tk[i].toLowerCase();
|
|
555
|
+
if (FS_KEY[x] !== undefined || x === 'smaller' || x === 'larger' || /^[\d.]+(px|pt|em|rem|%|cm|mm|in|pc|ex|ch)(\/.*)?$/.test(x)) { idx = i; break; }
|
|
556
|
+
}
|
|
557
|
+
if (idx < 0) return;
|
|
558
|
+
put('font-style', 'normal'); put('font-weight', 'normal'); put('font-variant', 'normal'); put('line-height', 'normal');
|
|
559
|
+
for (i = 0; i < idx; i++) {
|
|
560
|
+
var y = tk[i].toLowerCase();
|
|
561
|
+
if (y === 'italic' || y === 'oblique') put('font-style', y);
|
|
562
|
+
else if (y === 'bold' || y === 'bolder' || y === 'lighter' || /^\d{3}$/.test(y)) put('font-weight', y);
|
|
563
|
+
else if (y === 'small-caps') put('font-variant', y);
|
|
564
|
+
}
|
|
565
|
+
var sz = tk[idx], sl = sz.indexOf('/'), rest = tk.slice(idx + 1);
|
|
566
|
+
if (sl >= 0) { var lh = sz.slice(sl + 1); sz = sz.slice(0, sl); if (lh) put('line-height', lh); else if (rest.length) put('line-height', rest.shift()); }
|
|
567
|
+
else if (rest.length && rest[0].charAt(0) === '/') { var lh2 = rest.shift().slice(1) || rest.shift(); if (lh2) put('line-height', lh2); }
|
|
568
|
+
put('font-size', sz);
|
|
569
|
+
if (rest.length) put('font-family', rest.join(' '));
|
|
570
|
+
return;
|
|
571
|
+
case 'list-style':
|
|
572
|
+
tokens(val).forEach(function (tk2) {
|
|
573
|
+
var l = tk2.toLowerCase();
|
|
574
|
+
if (l === 'inside' || l === 'outside') put('list-style-position', l);
|
|
575
|
+
else if (!/^url\(/.test(l)) put('list-style-type', l);
|
|
576
|
+
});
|
|
577
|
+
return;
|
|
578
|
+
case 'text-decoration':
|
|
579
|
+
var line = [], st = null, cl = null;
|
|
580
|
+
tokens(val).forEach(function (tk3) {
|
|
581
|
+
var l = tk3.toLowerCase();
|
|
582
|
+
if (/^(underline|line-through|overline|none|blink)$/.test(l)) line.push(l);
|
|
583
|
+
else if (/^(solid|double|dotted|dashed|wavy)$/.test(l)) st = l;
|
|
584
|
+
else cl = tk3;
|
|
585
|
+
});
|
|
586
|
+
put('text-decoration-line', line.length ? line.join(' ') : 'none');
|
|
587
|
+
if (st) put('text-decoration-style', st);
|
|
588
|
+
if (cl) put('text-decoration-color', cl);
|
|
589
|
+
return;
|
|
590
|
+
case 'break-before': case 'break-after':
|
|
591
|
+
put('page-break-' + name.slice(6), /^(page|always|left|right|recto|verso)$/.test(lv) ? 'always' : lv === 'avoid' || lv === 'avoid-page' ? 'avoid' : 'auto');
|
|
592
|
+
return;
|
|
593
|
+
case 'break-inside':
|
|
594
|
+
put('page-break-inside', /^avoid/.test(lv) ? 'avoid' : 'auto');
|
|
595
|
+
return;
|
|
596
|
+
case 'background-image': case 'background-repeat': case 'background-position': case 'background-size':
|
|
597
|
+
return;
|
|
598
|
+
case 'margin-inline-start': put('margin-left', val); return;
|
|
599
|
+
case 'margin-inline-end': put('margin-right', val); return;
|
|
600
|
+
case 'margin-block-start': put('margin-top', val); return;
|
|
601
|
+
case 'margin-block-end': put('margin-bottom', val); return;
|
|
602
|
+
case 'padding-inline-start': put('padding-left', val); return;
|
|
603
|
+
case 'padding-inline-end': put('padding-right', val); return;
|
|
604
|
+
case 'padding-block-start': put('padding-top', val); return;
|
|
605
|
+
case 'padding-block-end': put('padding-bottom', val); return;
|
|
606
|
+
case 'word-wrap': case 'overflow-wrap': case 'word-break': case 'hyphens': return;
|
|
607
|
+
}
|
|
608
|
+
put(name, val);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function parseDecls(body) {
|
|
612
|
+
var out = [], parts = splitTop(body, ';');
|
|
613
|
+
for (var i = 0; i < parts.length; i++) {
|
|
614
|
+
var p = parts[i], k = p.indexOf(':');
|
|
615
|
+
if (k < 0) continue;
|
|
616
|
+
var name = p.slice(0, k).trim().toLowerCase(), val = p.slice(k + 1).trim(), imp = false;
|
|
617
|
+
var m = /!\s*important\s*$/i.exec(val);
|
|
618
|
+
if (m) { imp = true; val = val.slice(0, m.index).trim(); }
|
|
619
|
+
if (!name || !val || name.charAt(0) === '-' && name.indexOf('-webkit-') !== 0 && name.indexOf('-moz-') !== 0 && name.indexOf('--') === 0) continue;
|
|
620
|
+
expandDecl(name, val, imp, out);
|
|
621
|
+
}
|
|
622
|
+
return out;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
function matchBrace(css, open) {
|
|
626
|
+
var depth = 0, q = 0;
|
|
627
|
+
for (var i = open; i < css.length; i++) {
|
|
628
|
+
var c = css.charAt(i);
|
|
629
|
+
if (q) { if (c === '\\') i++; else if (c === q) q = 0; continue; }
|
|
630
|
+
if (c === '"' || c === "'") q = c;
|
|
631
|
+
else if (c === '{') depth++;
|
|
632
|
+
else if (c === '}') { depth--; if (!depth) return i; }
|
|
633
|
+
}
|
|
634
|
+
return css.length;
|
|
635
|
+
}
|
|
636
|
+
function findTop(css, from, chars) {
|
|
637
|
+
var q = 0, depth = 0;
|
|
638
|
+
for (var i = from; i < css.length; i++) {
|
|
639
|
+
var c = css.charAt(i);
|
|
640
|
+
if (q) { if (c === '\\') i++; else if (c === q) q = 0; continue; }
|
|
641
|
+
if (c === '"' || c === "'") q = c;
|
|
642
|
+
else if (c === '(') depth++;
|
|
643
|
+
else if (c === ')') depth--;
|
|
644
|
+
else if (!depth && chars.indexOf(c) >= 0) return i;
|
|
645
|
+
}
|
|
646
|
+
return -1;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
function mediaMatches(prelude, env) {
|
|
650
|
+
var list = splitTop(prelude.toLowerCase(), ',');
|
|
651
|
+
for (var i = 0; i < list.length; i++) {
|
|
652
|
+
var q = list[i].trim(), neg = false, ok = true;
|
|
653
|
+
if (!q) continue;
|
|
654
|
+
if (/^not\s/.test(q)) { neg = true; q = q.slice(4); } else if (/^only\s/.test(q)) q = q.slice(5);
|
|
655
|
+
q.split(/\s+and\s+/).forEach(function (part) {
|
|
656
|
+
part = part.trim();
|
|
657
|
+
if (!part) return;
|
|
658
|
+
if (part.charAt(0) === '(') {
|
|
659
|
+
var f = /^\(\s*([\w-]+)\s*(?::\s*([^)]+))?\)$/.exec(part);
|
|
660
|
+
if (!f) { ok = false; return; }
|
|
661
|
+
var name = f[1], val = f[2] ? f[2].trim() : null, L = val ? parseLen(val, 12, 12) : null, px = L && L.pt != null ? L.pt / 0.75 : null;
|
|
662
|
+
if (name === 'min-width') ok = ok && px != null && env.widthPx >= px;
|
|
663
|
+
else if (name === 'max-width') ok = ok && px != null && env.widthPx <= px;
|
|
664
|
+
else if (name === 'min-height') ok = ok && px != null && env.heightPx >= px;
|
|
665
|
+
else if (name === 'max-height') ok = ok && px != null && env.heightPx <= px;
|
|
666
|
+
else if (name === 'orientation') ok = ok && val === (env.widthPx > env.heightPx ? 'landscape' : 'portrait');
|
|
667
|
+
else if (name === 'color') ok = ok && true;
|
|
668
|
+
else ok = false;
|
|
669
|
+
} else if (part !== 'all' && part !== env.type) ok = false;
|
|
670
|
+
});
|
|
671
|
+
if (neg ? !ok : ok) return true;
|
|
672
|
+
}
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
var PSEUDO_EL = toSet('before after first-line first-letter marker selection placeholder backdrop');
|
|
677
|
+
|
|
678
|
+
function readIdent(s, i) {
|
|
679
|
+
var j = i;
|
|
680
|
+
while (j < s.length) {
|
|
681
|
+
var c = s.charAt(j);
|
|
682
|
+
if (c === '\\') { j += 2; continue; }
|
|
683
|
+
if (/[\w --]/.test(c)) j++; else break;
|
|
684
|
+
}
|
|
685
|
+
return { v: s.slice(i, j).replace(/\\(.)/g, '$1'), i: j };
|
|
686
|
+
}
|
|
687
|
+
function matchParen(s, i) {
|
|
688
|
+
var d = 0;
|
|
689
|
+
for (var j = i; j < s.length; j++) { var c = s.charAt(j); if (c === '(') d++; else if (c === ')') { d--; if (!d) return j; } }
|
|
690
|
+
return s.length;
|
|
691
|
+
}
|
|
692
|
+
function parseAttrSel(body) {
|
|
693
|
+
var m = /^\s*([\w:-]+)\s*(?:([~|^$*]?=)\s*("[^"]*"|'[^']*'|[^\s\]]+)\s*(i)?)?\s*$/.exec(body);
|
|
694
|
+
if (!m) return null;
|
|
695
|
+
var v = m[3] || '';
|
|
696
|
+
if (/^["']/.test(v)) v = v.slice(1, -1);
|
|
697
|
+
return { n: m[1].toLowerCase(), op: m[2] || '', v: v, ci: !!m[4] };
|
|
698
|
+
}
|
|
699
|
+
function parseNth(arg) {
|
|
700
|
+
arg = String(arg || '').replace(/\s+/g, '').toLowerCase();
|
|
701
|
+
if (arg === 'odd') return [2, 1];
|
|
702
|
+
if (arg === 'even') return [2, 0];
|
|
703
|
+
var m = /^([+-]?\d*)n([+-]\d+)?$/.exec(arg);
|
|
704
|
+
if (m) { var a = m[1] === '' || m[1] === '+' ? 1 : m[1] === '-' ? -1 : parseInt(m[1], 10); return [a, m[2] ? parseInt(m[2], 10) : 0]; }
|
|
705
|
+
if (/^[+-]?\d+$/.test(arg)) return [0, parseInt(arg, 10)];
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
function parseCompoundOnly(s) { var r = parseComplex(s); return r && r.parts.length === 1 ? r.parts[0].c : null; }
|
|
709
|
+
function parseComplex(s) {
|
|
710
|
+
s = s.trim();
|
|
711
|
+
if (!s) return null;
|
|
712
|
+
var parts = [], i = 0, n = s.length, cur = { tag: null, id: null, cls: [], attrs: [], ps: [] }, has = false, comb = null, a = 0, b = 0, c = 0;
|
|
713
|
+
function push() { parts.push({ c: cur, comb: comb }); cur = { tag: null, id: null, cls: [], attrs: [], ps: [] }; has = false; }
|
|
714
|
+
while (i < n) {
|
|
715
|
+
var ch = s.charAt(i), r;
|
|
716
|
+
if (/[\s>+~]/.test(ch)) {
|
|
717
|
+
var cb = ' ';
|
|
718
|
+
while (i < n && /[\s>+~]/.test(s.charAt(i))) { if (!/\s/.test(s.charAt(i))) cb = s.charAt(i); i++; }
|
|
719
|
+
if (has) { push(); comb = cb; }
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (ch === '*') { i++; has = true; continue; }
|
|
723
|
+
if (ch === '#') { r = readIdent(s, i + 1); cur.id = r.v; i = r.i; a++; has = true; continue; }
|
|
724
|
+
if (ch === '.') { r = readIdent(s, i + 1); if (!r.v) return null; cur.cls.push(r.v); i = r.i; b++; has = true; continue; }
|
|
725
|
+
if (ch === '[') {
|
|
726
|
+
var e = s.indexOf(']', i);
|
|
727
|
+
if (e < 0) return null;
|
|
728
|
+
var at = parseAttrSel(s.slice(i + 1, e));
|
|
729
|
+
if (!at) return null;
|
|
730
|
+
cur.attrs.push(at); i = e + 1; b++; has = true; continue;
|
|
731
|
+
}
|
|
732
|
+
if (ch === ':') {
|
|
733
|
+
var dbl = s.charAt(i + 1) === ':';
|
|
734
|
+
i += dbl ? 2 : 1;
|
|
735
|
+
r = readIdent(s, i);
|
|
736
|
+
var name = r.v.toLowerCase(), arg = null;
|
|
737
|
+
i = r.i;
|
|
738
|
+
if (s.charAt(i) === '(') { var pe = matchParen(s, i); arg = s.slice(i + 1, pe); i = pe + 1; }
|
|
739
|
+
if (dbl || PSEUDO_EL[name]) return null;
|
|
740
|
+
var ps = { n: name, a: arg };
|
|
741
|
+
if (name === 'not' && arg) { ps.sub = splitTop(arg, ',').map(parseCompoundOnly); if (ps.sub.some(function (x) { return !x; })) return null; }
|
|
742
|
+
if (/^nth-/.test(name)) { ps.nth = parseNth(arg); if (!ps.nth) return null; }
|
|
743
|
+
cur.ps.push(ps); b++; has = true; continue;
|
|
744
|
+
}
|
|
745
|
+
if (/[\w --]/.test(ch) || ch === '\\') { r = readIdent(s, i); cur.tag = r.v.toLowerCase(); i = r.i; c++; has = true; continue; }
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
if (has) push(); else return null;
|
|
749
|
+
return { parts: parts, spec: a * 10000 + b * 100 + c };
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
function parseCSS(css, sheet, env, origin, pageOnly) {
|
|
753
|
+
css = css.replace(/\/\*[\s\S]*?\*\//g, '').replace(/<!--|-->/g, ' ');
|
|
754
|
+
var i = 0, n = css.length;
|
|
755
|
+
while (i < n) {
|
|
756
|
+
while (i < n && /\s/.test(css.charAt(i))) i++;
|
|
757
|
+
if (i >= n) break;
|
|
758
|
+
if (css.charAt(i) === '@') {
|
|
759
|
+
var km = /^@([\w-]+)/.exec(css.slice(i, i + 40)), kw = km ? km[1].toLowerCase() : '';
|
|
760
|
+
var stop = findTop(css, i, '{;');
|
|
761
|
+
if (stop < 0) break;
|
|
762
|
+
if (css.charAt(stop) === ';') { i = stop + 1; continue; }
|
|
763
|
+
var close = matchBrace(css, stop), prelude = css.slice(i + 1 + kw.length, stop).trim(), inner = css.slice(stop + 1, close);
|
|
764
|
+
if (kw === 'media') parseCSS(inner, sheet, env, origin, pageOnly || !mediaMatches(prelude, env));
|
|
765
|
+
else if (kw === 'supports') parseCSS(inner, sheet, env, origin, pageOnly);
|
|
766
|
+
else if (kw === 'page' && !/:(left|right|blank)/i.test(prelude)) sheet.page.push(parseDecls(inner.replace(/@[\w-]+\s*\{[^}]*\}/g, '')));
|
|
767
|
+
i = close + 1;
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
var ob = findTop(css, i, '{');
|
|
771
|
+
if (ob < 0) break;
|
|
772
|
+
var cb = matchBrace(css, ob), selText = css.slice(i, ob).trim(), body = css.slice(ob + 1, cb);
|
|
773
|
+
i = cb + 1;
|
|
774
|
+
if (pageOnly || !selText) continue;
|
|
775
|
+
var decls = parseDecls(body);
|
|
776
|
+
if (!decls.length) continue;
|
|
777
|
+
var sels = splitTop(selText, ',');
|
|
778
|
+
for (var k = 0; k < sels.length; k++) {
|
|
779
|
+
var sel = parseComplex(sels[k]);
|
|
780
|
+
if (sel) sheet[origin].push({ parts: sel.parts, spec: sel.spec, decls: decls, order: sheet.seq++ });
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// ======================= 6. selector matching =======================
|
|
786
|
+
function clsSet(e) {
|
|
787
|
+
if (!e.cset) { e.cset = Object.create(null); String(e.attrs['class'] || '').split(/\s+/).forEach(function (c) { if (c) e.cset[c] = true; }); }
|
|
788
|
+
return e.cset;
|
|
789
|
+
}
|
|
790
|
+
function nthOk(nth, pos) { // pos is 1-based
|
|
791
|
+
var a = nth[0], b = nth[1];
|
|
792
|
+
if (a === 0) return pos === b;
|
|
793
|
+
var k = (pos - b) / a;
|
|
794
|
+
return k >= 0 && Math.floor(k) === k;
|
|
795
|
+
}
|
|
796
|
+
function sameTypeIndex(e, fromEnd) {
|
|
797
|
+
var sib = e.parent ? e.parent.els : [e], pos = 0;
|
|
798
|
+
if (!fromEnd) { for (var i = 0; i <= e.eidx; i++) if (sib[i].tag === e.tag) pos++; }
|
|
799
|
+
else { for (var j = sib.length - 1; j >= e.eidx; j--) if (sib[j].tag === e.tag) pos++; }
|
|
800
|
+
return pos;
|
|
801
|
+
}
|
|
802
|
+
function matchCompound(e, c) {
|
|
803
|
+
if (c.tag && c.tag !== e.tag) return false;
|
|
804
|
+
if (c.id && e.attrs.id !== c.id) return false;
|
|
805
|
+
var k;
|
|
806
|
+
if (c.cls.length) { var cs = clsSet(e); for (k = 0; k < c.cls.length; k++) if (!cs[c.cls[k]]) return false; }
|
|
807
|
+
for (k = 0; k < c.attrs.length; k++) {
|
|
808
|
+
var at = c.attrs[k], v = e.attrs[at.n];
|
|
809
|
+
if (v === undefined) return false;
|
|
810
|
+
if (!at.op) continue;
|
|
811
|
+
var x = at.v, y = v;
|
|
812
|
+
if (at.ci) { x = x.toLowerCase(); y = y.toLowerCase(); }
|
|
813
|
+
if (at.op === '=' && y !== x) return false;
|
|
814
|
+
if (at.op === '~=' && y.split(/\s+/).indexOf(x) < 0) return false;
|
|
815
|
+
if (at.op === '|=' && y !== x && y.indexOf(x + '-') !== 0) return false;
|
|
816
|
+
if (at.op === '^=' && (!x || y.indexOf(x) !== 0)) return false;
|
|
817
|
+
if (at.op === '$=' && (!x || y.slice(-x.length) !== x)) return false;
|
|
818
|
+
if (at.op === '*=' && (!x || y.indexOf(x) < 0)) return false;
|
|
819
|
+
}
|
|
820
|
+
for (k = 0; k < c.ps.length; k++) {
|
|
821
|
+
var ps = c.ps[k], sib = e.parent ? e.parent.els : [e];
|
|
822
|
+
switch (ps.n) {
|
|
823
|
+
case 'first-child': if (e.eidx !== 0) return false; break;
|
|
824
|
+
case 'last-child': if (e.eidx !== sib.length - 1) return false; break;
|
|
825
|
+
case 'only-child': if (sib.length !== 1) return false; break;
|
|
826
|
+
case 'nth-child': if (!nthOk(ps.nth, e.eidx + 1)) return false; break;
|
|
827
|
+
case 'nth-last-child': if (!nthOk(ps.nth, sib.length - e.eidx)) return false; break;
|
|
828
|
+
case 'first-of-type': if (sameTypeIndex(e, false) !== 1) return false; break;
|
|
829
|
+
case 'last-of-type': if (sameTypeIndex(e, true) !== 1) return false; break;
|
|
830
|
+
case 'only-of-type': if (sameTypeIndex(e, false) !== 1 || sameTypeIndex(e, true) !== 1) return false; break;
|
|
831
|
+
case 'nth-of-type': if (!nthOk(ps.nth, sameTypeIndex(e, false))) return false; break;
|
|
832
|
+
case 'nth-last-of-type': if (!nthOk(ps.nth, sameTypeIndex(e, true))) return false; break;
|
|
833
|
+
case 'root': if (e.tag !== 'html') return false; break;
|
|
834
|
+
case 'empty':
|
|
835
|
+
for (var q = 0; q < e.children.length; q++) if (e.children[q].tag !== '#text' || e.children[q].text) return false;
|
|
836
|
+
break;
|
|
837
|
+
case 'link': case 'any-link': if (!(e.tag === 'a' && e.attrs.href !== undefined)) return false; break;
|
|
838
|
+
case 'checked': if (e.attrs.checked === undefined && e.attrs.selected === undefined) return false; break;
|
|
839
|
+
case 'disabled': if (e.attrs.disabled === undefined) return false; break;
|
|
840
|
+
case 'not': for (var z = 0; z < ps.sub.length; z++) if (matchCompound(e, ps.sub[z])) return false; break;
|
|
841
|
+
default: return false; // hover, focus, visited ...
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return true;
|
|
845
|
+
}
|
|
846
|
+
function matchComplex(e, parts, idx) {
|
|
847
|
+
if (!matchCompound(e, parts[idx].c)) return false;
|
|
848
|
+
if (idx === 0) return true;
|
|
849
|
+
var comb = parts[idx].comb, p;
|
|
850
|
+
if (comb === ' ') {
|
|
851
|
+
for (p = e.parent; p && p.tag !== '#root'; p = p.parent) if (matchComplex(p, parts, idx - 1)) return true;
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
if (comb === '>') return !!(e.parent && e.parent.tag !== '#root' && matchComplex(e.parent, parts, idx - 1));
|
|
855
|
+
var sib = e.parent ? e.parent.els : [];
|
|
856
|
+
if (comb === '+') return e.eidx > 0 && matchComplex(sib[e.eidx - 1], parts, idx - 1);
|
|
857
|
+
if (comb === '~') { for (var k = e.eidx - 1; k >= 0; k--) if (matchComplex(sib[k], parts, idx - 1)) return true; return false; }
|
|
858
|
+
return false;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// ======================= 7. default (browser) stylesheet =======================
|
|
862
|
+
var UA_CSS =
|
|
863
|
+
'html,address,blockquote,body,dd,div,dl,dt,fieldset,form,frame,frameset,h1,h2,h3,h4,h5,h6,noframes,ol,p,ul,center,dir,hr,menu,pre,' +
|
|
864
|
+
'article,aside,footer,header,hgroup,main,nav,section,figure,figcaption,details,summary,legend,address{display:block}' +
|
|
865
|
+
'li{display:list-item}' +
|
|
866
|
+
'head,script,style,title,meta,link,template,noscript,base,param,datalist,map,area,svg,canvas,video,audio,iframe,object,embed,select,math{display:none}' +
|
|
867
|
+
'[hidden]{display:none}' +
|
|
868
|
+
'table{display:table;border-collapse:separate}tr{display:table-row;vertical-align:middle}thead{display:table-header-group;vertical-align:middle}' +
|
|
869
|
+
'tbody{display:table-row-group;vertical-align:middle}tfoot{display:table-footer-group;vertical-align:middle}col{display:table-column}' +
|
|
870
|
+
'colgroup{display:table-column-group}td,th{display:table-cell;padding:1px}caption{display:table-caption;text-align:center}' +
|
|
871
|
+
'th{font-weight:bold;text-align:center}' +
|
|
872
|
+
'body{margin:8px}p{margin:1em 0}' +
|
|
873
|
+
'h1{font-size:2em;margin:.67em 0;font-weight:bold;page-break-after:avoid}h2{font-size:1.5em;margin:.83em 0;font-weight:bold;page-break-after:avoid}' +
|
|
874
|
+
'h3{font-size:1.17em;margin:1em 0;font-weight:bold;page-break-after:avoid}h4{margin:1.33em 0;font-weight:bold;page-break-after:avoid}' +
|
|
875
|
+
'h5{font-size:.83em;margin:1.67em 0;font-weight:bold;page-break-after:avoid}h6{font-size:.67em;margin:2.33em 0;font-weight:bold;page-break-after:avoid}' +
|
|
876
|
+
'blockquote,figure{margin:1em 40px}ul,ol,menu,dir{margin:1em 0;padding-left:40px}ul,menu,dir{list-style-type:disc}ol{list-style-type:decimal}' +
|
|
877
|
+
'ul ul,ol ul,menu ul,ul menu{list-style-type:circle}ul ul ul,ul ol ul,ol ul ul,ol ol ul{list-style-type:square}' +
|
|
878
|
+
'ol ol,ol ul,ul ol,ul ul{margin-top:0;margin-bottom:0}dl{margin:1em 0}dd{margin-left:40px}' +
|
|
879
|
+
'b,strong{font-weight:bold}i,em,cite,var,dfn,address{font-style:italic}u,ins{text-decoration:underline}s,strike,del{text-decoration:line-through}' +
|
|
880
|
+
'sub{vertical-align:sub;font-size:smaller}sup{vertical-align:super;font-size:smaller}small{font-size:smaller}big{font-size:larger}' +
|
|
881
|
+
'pre,code,kbd,samp,tt,xmp,listing,plaintext{font-family:monospace}pre,xmp,listing,plaintext{white-space:pre;margin:1em 0}' +
|
|
882
|
+
'a[href]{color:#0000EE;text-decoration:underline}mark{background-color:yellow;color:black}center{text-align:center}' +
|
|
883
|
+
'hr{border:1px inset gray;margin:.5em 0}nobr{white-space:nowrap}fieldset{margin:0 2px;padding:.35em .75em .625em;border:2px groove #c0c0c0}';
|
|
884
|
+
var QUIRKS_CSS = 'table{font-size:medium;font-weight:normal;font-style:normal;font-variant:normal;line-height:normal;white-space:normal;text-align:left}';
|
|
885
|
+
var FROALA_CSS =
|
|
886
|
+
'.fr-view table{border:none;border-collapse:collapse;empty-cells:show}.fr-view table td,.fr-view table th{border:1px solid #dddddd}' +
|
|
887
|
+
'.fr-view table th{background:#ececec}.fr-view table.fr-dashed-borders td,.fr-view table.fr-dashed-borders th{border-style:dashed}' +
|
|
888
|
+
'.fr-view table.fr-alternate-rows tbody tr:nth-child(2n){background:#f5f5f5}.fr-view table td.fr-thick,.fr-view table th.fr-thick{border-width:2px}' +
|
|
889
|
+
'.fr-view table td.fr-highlighted,.fr-view table th.fr-highlighted{border:1px double red}' +
|
|
890
|
+
'.fr-view blockquote{border-left:solid 2px #5e35b1;margin-left:0;padding-left:5px;color:#5e35b1}' +
|
|
891
|
+
'.fr-view .fr-text-gray{color:#AAA}.fr-view .fr-text-bordered{border-top:solid 1px #222;border-bottom:solid 1px #222;padding:10px 0}' +
|
|
892
|
+
'.fr-view .fr-text-spaced{letter-spacing:1px}.fr-view .fr-text-uppercase{text-transform:uppercase}' +
|
|
893
|
+
'.fr-view img.fr-dib{display:block;margin:5px auto}.fr-view img.fr-dib.fr-fil{margin-left:0}.fr-view img.fr-dib.fr-fir{margin-right:0}' +
|
|
894
|
+
'.fr-view hr{border:0;border-bottom:1px solid #cccccc}';
|
|
895
|
+
|
|
896
|
+
// ======================= 8. presentational attributes =======================
|
|
897
|
+
var FONT_SIZE_ATTR = { 1: '7.5pt', 2: '10pt', 3: '12pt', 4: '13.5pt', 5: '18pt', 6: '24pt', 7: '36pt' };
|
|
898
|
+
function pxOrPct(v) { v = String(v).trim(); return /%$/.test(v) ? v : /^[\d.]+$/.test(v) ? v + 'px' : v; }
|
|
899
|
+
function hintDecls(e, out) {
|
|
900
|
+
var a = e.attrs, t = e.tag;
|
|
901
|
+
function put(p, v) { expandDecl(p, v, false, out); }
|
|
902
|
+
if (a.align) {
|
|
903
|
+
var al = a.align.toLowerCase();
|
|
904
|
+
if (t === 'table') { if (al === 'center') { put('margin-left', 'auto'); put('margin-right', 'auto'); } else if (al === 'right') put('margin-left', 'auto'); }
|
|
905
|
+
else if (t === 'img') { if (al === 'middle' || al === 'top' || al === 'bottom') put('vertical-align', al); }
|
|
906
|
+
else if (/^(p|div|h[1-6]|td|th|tr|tbody|thead|tfoot|caption|li|legend|center)$/.test(t)) put('text-align', al === 'middle' ? 'center' : al);
|
|
907
|
+
}
|
|
908
|
+
if (a.valign && /^(td|th|tr|tbody|thead|tfoot|col)$/.test(t)) put('vertical-align', a.valign.toLowerCase());
|
|
909
|
+
if (a.bgcolor) put('background-color', a.bgcolor);
|
|
910
|
+
if (t === 'font') {
|
|
911
|
+
if (a.color) put('color', a.color);
|
|
912
|
+
if (a.face) put('font-family', a.face);
|
|
913
|
+
if (a.size) {
|
|
914
|
+
var sz = String(a.size).trim(), base = /^[+-]/.test(sz) ? 3 + parseInt(sz, 10) : parseInt(sz, 10);
|
|
915
|
+
if (base > 0) put('font-size', FONT_SIZE_ATTR[clamp(base, 1, 7)]);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (t === 'body' && a.text) put('color', a.text);
|
|
919
|
+
if (a.width && /^(table|td|th|col|colgroup|img|hr)$/.test(t)) put('width', pxOrPct(a.width));
|
|
920
|
+
if (a.height && /^(td|th|tr|img|table)$/.test(t)) put('height', pxOrPct(a.height));
|
|
921
|
+
if (t === 'table' && a.border !== undefined) {
|
|
922
|
+
var bw = a.border === '' ? 1 : parseInt(a.border, 10);
|
|
923
|
+
if (bw > 0) put('border', bw + 'px outset gray');
|
|
924
|
+
}
|
|
925
|
+
if (t === 'img' && a.border && parseInt(a.border, 10) > 0) put('border', parseInt(a.border, 10) + 'px solid');
|
|
926
|
+
if ((t === 'td' || t === 'th') && a.nowrap !== undefined) put('white-space', 'nowrap');
|
|
927
|
+
if (t === 'td' || t === 'th') {
|
|
928
|
+
var tbl = e.parent;
|
|
929
|
+
while (tbl && tbl.tag !== 'table' && tbl.tag !== '#root') tbl = tbl.parent;
|
|
930
|
+
if (tbl && tbl.tag === 'table') {
|
|
931
|
+
if (tbl.attrs.border !== undefined && (tbl.attrs.border === '' || parseInt(tbl.attrs.border, 10) > 0)) put('border', '1px inset gray');
|
|
932
|
+
if (tbl.attrs.cellpadding !== undefined) put('padding', pxOrPct(tbl.attrs.cellpadding));
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
if (t === 'hr') { if (a.color) { put('border-color', a.color); } if (a.size) put('border-top-width', pxOrPct(a.size)); }
|
|
936
|
+
if ((t === 'ol' || t === 'li') && a.type) {
|
|
937
|
+
var tp = { '1': 'decimal', a: 'lower-alpha', A: 'upper-alpha', i: 'lower-roman', I: 'upper-roman' }[a.type];
|
|
938
|
+
if (tp) put('list-style-type', tp);
|
|
939
|
+
}
|
|
940
|
+
if ((t === 'ul' || t === 'li') && /^(disc|circle|square)$/i.test(a.type || '')) put('list-style-type', a.type.toLowerCase());
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// ======================= 9. computed style =======================
|
|
944
|
+
var INHERITED = toSet('color font-family font-size font-weight font-style font-variant line-height text-align text-indent ' +
|
|
945
|
+
'text-transform letter-spacing white-space visibility list-style-type list-style-position border-collapse direction');
|
|
946
|
+
|
|
947
|
+
function rootStyle(o) {
|
|
948
|
+
return {
|
|
949
|
+
display: 'block', fontSize: o.fontSizePt || 12, fontFamily: o.fontFamily || 'Times New Roman', fontWeight: 400,
|
|
950
|
+
fontStyle: 'normal', fontVariant: 'normal', color: null, lineHeight: null, textAlign: 'left', textIndent: null,
|
|
951
|
+
textTransform: 'none', letterSpacing: 0, whiteSpace: 'normal', visibility: 'visible', listStyleType: 'disc',
|
|
952
|
+
listStylePosition: 'outside', borderCollapse: 'separate', deco: { u: null, s: false }, direction: 'ltr'
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
var U_STYLE = { solid: 'single', double: 'double', dotted: 'dotted', dashed: 'dash', wavy: 'wave' };
|
|
957
|
+
|
|
958
|
+
function computeStyle(e, d, p, rootFs) {
|
|
959
|
+
var cs = {};
|
|
960
|
+
function sv(prop) { var v = d[prop]; return v === undefined ? undefined : v; }
|
|
961
|
+
function isInh(v) { return v === 'inherit'; }
|
|
962
|
+
// font-size first (em units depend on it)
|
|
963
|
+
var fsv = sv('font-size'), fs = p.fontSize;
|
|
964
|
+
if (fsv !== undefined && !isInh(fsv) && fsv !== 'unset') {
|
|
965
|
+
var lf = fsv.toLowerCase();
|
|
966
|
+
if (lf === 'initial') fs = 12;
|
|
967
|
+
else if (FS_KEY[lf] !== undefined) fs = FS_KEY[lf];
|
|
968
|
+
else if (lf === 'smaller') fs = p.fontSize / 1.2;
|
|
969
|
+
else if (lf === 'larger') fs = p.fontSize * 1.2;
|
|
970
|
+
else { var L = parseLen(lf, p.fontSize, rootFs); if (L) fs = L.pct != null ? p.fontSize * L.pct / 100 : L.pt; }
|
|
971
|
+
}
|
|
972
|
+
cs.fontSize = Math.max(0, fs);
|
|
973
|
+
var ff = sv('font-family');
|
|
974
|
+
cs.fontFamily = ff && !isInh(ff) ? (firstFamily(ff) || p.fontFamily) : p.fontFamily;
|
|
975
|
+
var fw = sv('font-weight'), w = p.fontWeight;
|
|
976
|
+
if (fw && !isInh(fw)) {
|
|
977
|
+
fw = fw.toLowerCase();
|
|
978
|
+
w = fw === 'bold' ? 700 : fw === 'normal' ? 400 : fw === 'bolder' ? (p.fontWeight < 600 ? 700 : 900) : fw === 'lighter' ? (p.fontWeight > 500 ? 400 : 100) : (parseInt(fw, 10) || w);
|
|
979
|
+
}
|
|
980
|
+
cs.fontWeight = w;
|
|
981
|
+
var fst = sv('font-style');
|
|
982
|
+
cs.fontStyle = fst && !isInh(fst) ? (/italic|oblique/i.test(fst) ? 'italic' : 'normal') : p.fontStyle;
|
|
983
|
+
var fv = sv('font-variant');
|
|
984
|
+
cs.fontVariant = fv && !isInh(fv) ? (/small-caps/i.test(fv) ? 'small-caps' : 'normal') : p.fontVariant;
|
|
985
|
+
var col = sv('color');
|
|
986
|
+
if (col && !isInh(col)) { var pc = parseColor(col, p.color); cs.color = pc === undefined ? p.color : pc; } else cs.color = p.color;
|
|
987
|
+
var lh = sv('line-height');
|
|
988
|
+
if (lh && !isInh(lh)) {
|
|
989
|
+
var ll = lh.toLowerCase();
|
|
990
|
+
if (ll === 'normal' || ll === 'initial') cs.lineHeight = null;
|
|
991
|
+
else if (/^[\d.]+$/.test(ll)) cs.lineHeight = { m: parseFloat(ll) };
|
|
992
|
+
else { var LL = parseLen(ll, cs.fontSize, rootFs); cs.lineHeight = LL ? (LL.pct != null ? { pt: cs.fontSize * LL.pct / 100 } : { pt: LL.pt }) : p.lineHeight; }
|
|
993
|
+
} else cs.lineHeight = p.lineHeight;
|
|
994
|
+
var ta = sv('text-align');
|
|
995
|
+
if (ta && !isInh(ta)) {
|
|
996
|
+
ta = ta.toLowerCase().replace('-webkit-', '').replace('-moz-', '');
|
|
997
|
+
cs.textAlign = ta === 'start' ? 'left' : ta === 'end' ? 'right' : /^(left|right|center|justify)$/.test(ta) ? ta : p.textAlign;
|
|
998
|
+
} else cs.textAlign = p.textAlign;
|
|
999
|
+
var ti = sv('text-indent');
|
|
1000
|
+
cs.textIndent = ti && !isInh(ti) ? parseLen(ti, cs.fontSize, rootFs) : p.textIndent;
|
|
1001
|
+
var tt = sv('text-transform');
|
|
1002
|
+
cs.textTransform = tt && !isInh(tt) ? tt.toLowerCase() : p.textTransform;
|
|
1003
|
+
var ls = sv('letter-spacing');
|
|
1004
|
+
cs.letterSpacing = ls && !isInh(ls) ? (ls === 'normal' ? 0 : res0(parseLen(ls, cs.fontSize, rootFs), 0)) : p.letterSpacing;
|
|
1005
|
+
var ws = sv('white-space');
|
|
1006
|
+
cs.whiteSpace = ws && !isInh(ws) ? ws.toLowerCase() : p.whiteSpace;
|
|
1007
|
+
var vis = sv('visibility');
|
|
1008
|
+
cs.visibility = vis && !isInh(vis) ? vis.toLowerCase() : p.visibility;
|
|
1009
|
+
var lst = sv('list-style-type');
|
|
1010
|
+
cs.listStyleType = lst && !isInh(lst) ? lst.toLowerCase() : p.listStyleType;
|
|
1011
|
+
var lsp = sv('list-style-position');
|
|
1012
|
+
cs.listStylePosition = lsp && !isInh(lsp) ? lsp.toLowerCase() : p.listStylePosition;
|
|
1013
|
+
var bc = sv('border-collapse');
|
|
1014
|
+
cs.borderCollapse = bc && !isInh(bc) ? bc.toLowerCase() : p.borderCollapse;
|
|
1015
|
+
cs.direction = p.direction;
|
|
1016
|
+
// decorations propagate (union with the parent's)
|
|
1017
|
+
var tdl = sv('text-decoration-line'), tds = (sv('text-decoration-style') || 'solid').toLowerCase();
|
|
1018
|
+
var deco = { u: p.deco.u, s: p.deco.s };
|
|
1019
|
+
if (tdl && !isInh(tdl)) {
|
|
1020
|
+
tdl = tdl.toLowerCase();
|
|
1021
|
+
if (/underline/.test(tdl)) deco.u = U_STYLE[tds] || 'single';
|
|
1022
|
+
if (/line-through/.test(tdl)) deco.s = true;
|
|
1023
|
+
}
|
|
1024
|
+
cs.deco = deco;
|
|
1025
|
+
// non-inherited
|
|
1026
|
+
var disp = sv('display');
|
|
1027
|
+
cs.display = disp && !isInh(disp) ? disp.toLowerCase().replace(/^(-webkit-|-moz-)/, '') : 'inline';
|
|
1028
|
+
if (cs.display === 'contents') cs.display = 'inline';
|
|
1029
|
+
var bg = sv('background-color');
|
|
1030
|
+
cs.background = bg && !isInh(bg) ? (parseColor(bg, cs.color) || null) : null;
|
|
1031
|
+
cs.verticalAlign = (sv('vertical-align') || 'baseline').toLowerCase();
|
|
1032
|
+
if (cs.verticalAlign === 'inherit') cs.verticalAlign = p.verticalAlign || 'baseline';
|
|
1033
|
+
var fsz = cs.fontSize;
|
|
1034
|
+
function len(prop) { var v = sv(prop); if (v === undefined || v === 'initial' || v === 'unset') return null; if (isInh(v)) return p['_' + prop] || null; return parseLen(v, fsz, rootFs); }
|
|
1035
|
+
cs.m = [len('margin-top'), len('margin-right'), len('margin-bottom'), len('margin-left')];
|
|
1036
|
+
cs.pd = [len('padding-top'), len('padding-right'), len('padding-bottom'), len('padding-left')];
|
|
1037
|
+
cs.bd = SIDES.map(function (sd) {
|
|
1038
|
+
var st = (sv('border-' + sd + '-style') || 'none').toLowerCase();
|
|
1039
|
+
if (st === 'none' || st === 'hidden' || !BORDER_STYLES[st]) return null;
|
|
1040
|
+
var wv = (sv('border-' + sd + '-width') || 'medium').toLowerCase();
|
|
1041
|
+
var wpt = BW_KEY[wv] !== undefined ? BW_KEY[wv] : res0(parseLen(wv, fsz, rootFs), 0);
|
|
1042
|
+
if (!(wpt > 0)) return null;
|
|
1043
|
+
var cv = sv('border-' + sd + '-color'), cc = cv ? parseColor(cv, cs.color) : cs.color;
|
|
1044
|
+
if (cc === undefined) cc = cs.color;
|
|
1045
|
+
if (cc === null && cv && /transparent/i.test(cv)) return null;
|
|
1046
|
+
return { w: wpt, s: st, c: cc || '000000' };
|
|
1047
|
+
});
|
|
1048
|
+
cs.width = len('width'); cs.height = len('height');
|
|
1049
|
+
cs.minHeight = len('min-height'); cs.maxWidth = len('max-width'); cs.maxHeight = len('max-height');
|
|
1050
|
+
cs.pbBefore = (sv('page-break-before') || 'auto').toLowerCase();
|
|
1051
|
+
cs.pbAfter = (sv('page-break-after') || 'auto').toLowerCase();
|
|
1052
|
+
cs.pbInside = (sv('page-break-inside') || 'auto').toLowerCase();
|
|
1053
|
+
cs.tableLayout = (sv('table-layout') || 'auto').toLowerCase();
|
|
1054
|
+
cs.boxSizing = (sv('box-sizing') || 'content-box').toLowerCase();
|
|
1055
|
+
cs.float = (sv('float') || 'none').toLowerCase();
|
|
1056
|
+
var ta2 = sv('text-align-last');
|
|
1057
|
+
cs.textAlignLast = ta2 ? ta2.toLowerCase() : null;
|
|
1058
|
+
return cs;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
function computeAll(root, sheet, opts) {
|
|
1062
|
+
var rcs = rootStyle(opts), rootFs = 12;
|
|
1063
|
+
var uaRules = sheet.ua.slice().sort(function (a, b) { return a.spec - b.spec || a.order - b.order; });
|
|
1064
|
+
var auRules = sheet.author.slice().sort(function (a, b) { return a.spec - b.spec || a.order - b.order; });
|
|
1065
|
+
function matched(e, rules) {
|
|
1066
|
+
var out = [];
|
|
1067
|
+
for (var i = 0; i < rules.length; i++) { var r = rules[i]; if (matchComplex(e, r.parts, r.parts.length - 1)) out.push(r); }
|
|
1068
|
+
return out;
|
|
1069
|
+
}
|
|
1070
|
+
function walk(e, pcs) {
|
|
1071
|
+
var d = Object.create(null), i, j, k, dd;
|
|
1072
|
+
var mu = matched(e, uaRules), ma = matched(e, auRules), hints = [], inline = [];
|
|
1073
|
+
hintDecls(e, hints);
|
|
1074
|
+
if (e.attrs.style) inline = parseDecls(e.attrs.style);
|
|
1075
|
+
function apply(list, imp) { for (j = 0; j < list.length; j++) { dd = list[j]; if (dd.imp === imp) d[dd.p] = dd.v; } }
|
|
1076
|
+
for (i = 0; i < mu.length; i++) apply(mu[i].decls, false);
|
|
1077
|
+
apply(hints, false);
|
|
1078
|
+
for (i = 0; i < ma.length; i++) apply(ma[i].decls, false);
|
|
1079
|
+
apply(inline, false);
|
|
1080
|
+
for (i = 0; i < mu.length; i++) apply(mu[i].decls, true);
|
|
1081
|
+
for (i = 0; i < ma.length; i++) apply(ma[i].decls, true);
|
|
1082
|
+
apply(inline, true);
|
|
1083
|
+
var cs = computeStyle(e, d, pcs, rootFs);
|
|
1084
|
+
if (e.tag === 'html') rootFs = cs.fontSize;
|
|
1085
|
+
e.cs = cs;
|
|
1086
|
+
for (k = 0; k < e.els.length; k++) walk(e.els[k], cs);
|
|
1087
|
+
}
|
|
1088
|
+
root.cs = rcs;
|
|
1089
|
+
for (var k = 0; k < root.els.length; k++) walk(root.els[k], rcs);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
// ======================= 10. images =======================
|
|
1093
|
+
function imageInfo(bytes) {
|
|
1094
|
+
var b = bytes, n = b.length;
|
|
1095
|
+
if (n > 24 && b[0] === 0x89 && b[1] === 0x50 && b[2] === 0x4E && b[3] === 0x47)
|
|
1096
|
+
return { ext: 'png', mime: 'image/png', w: ((b[16] << 24) | (b[17] << 16) | (b[18] << 8) | b[19]) >>> 0, h: ((b[20] << 24) | (b[21] << 16) | (b[22] << 8) | b[23]) >>> 0 };
|
|
1097
|
+
if (n > 10 && b[0] === 0x47 && b[1] === 0x49 && b[2] === 0x46) return { ext: 'gif', mime: 'image/gif', w: b[6] | (b[7] << 8), h: b[8] | (b[9] << 8) };
|
|
1098
|
+
if (n > 26 && b[0] === 0x42 && b[1] === 0x4D) return { ext: 'bmp', mime: 'image/bmp', w: Math.abs(b[18] | (b[19] << 8) | (b[20] << 16) | (b[21] << 24)), h: Math.abs(b[22] | (b[23] << 8) | (b[24] << 16) | (b[25] << 24)) };
|
|
1099
|
+
if (n > 4 && b[0] === 0xFF && b[1] === 0xD8) {
|
|
1100
|
+
var i = 2;
|
|
1101
|
+
while (i + 9 < n) {
|
|
1102
|
+
if (b[i] !== 0xFF) { i++; continue; }
|
|
1103
|
+
var m = b[i + 1];
|
|
1104
|
+
if (m === 0xD8 || m === 0x01 || (m >= 0xD0 && m <= 0xD7) || m === 0xFF) { i += m === 0xFF ? 1 : 2; continue; }
|
|
1105
|
+
var len = (b[i + 2] << 8) | b[i + 3];
|
|
1106
|
+
if ((m >= 0xC0 && m <= 0xCF) && m !== 0xC4 && m !== 0xC8 && m !== 0xCC)
|
|
1107
|
+
return { ext: 'jpeg', mime: 'image/jpeg', h: (b[i + 5] << 8) | b[i + 6], w: (b[i + 7] << 8) | b[i + 8] };
|
|
1108
|
+
i += 2 + len;
|
|
1109
|
+
}
|
|
1110
|
+
return { ext: 'jpeg', mime: 'image/jpeg', w: 0, h: 0 };
|
|
1111
|
+
}
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
function loadImageSrc(src, remote) {
|
|
1116
|
+
src = String(src || '').trim();
|
|
1117
|
+
var m = /^data:([^;,]*)((?:;[^;,]*)*?);base64,/i.exec(src.slice(0, 200));
|
|
1118
|
+
if (m) {
|
|
1119
|
+
var bytes = b64decode(src.slice(m[0].length));
|
|
1120
|
+
var info = imageInfo(bytes);
|
|
1121
|
+
if (!info) return { error: 'unsupported image type ' + (m[1] || '?') };
|
|
1122
|
+
info.bytes = bytes;
|
|
1123
|
+
return info;
|
|
1124
|
+
}
|
|
1125
|
+
if (/^data:/i.test(src)) return { error: 'non-base64 data URI (' + src.slice(5, 30) + ')' };
|
|
1126
|
+
if (remote && remote[src]) {
|
|
1127
|
+
var rb = remote[src];
|
|
1128
|
+
if (rb.error) return rb;
|
|
1129
|
+
var inf = imageInfo(rb);
|
|
1130
|
+
if (!inf) return { error: 'unsupported image type at ' + src.slice(0, 80) };
|
|
1131
|
+
inf.bytes = rb;
|
|
1132
|
+
return inf;
|
|
1133
|
+
}
|
|
1134
|
+
return { error: 'image not embedded: ' + src.slice(0, 80) };
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
// ======================= 11. layout =======================
|
|
1138
|
+
var JC = { left: 'left', right: 'right', center: 'center', justify: 'both' };
|
|
1139
|
+
var HL = { FFFF00: 'yellow', '00FF00': 'green', '00FFFF': 'cyan', FF00FF: 'magenta', '0000FF': 'blue', FF0000: 'red',
|
|
1140
|
+
'000080': 'darkBlue', '008080': 'darkCyan', '008000': 'darkGreen', '800080': 'darkMagenta', '800000': 'darkRed',
|
|
1141
|
+
'808000': 'darkYellow', '808080': 'darkGray', C0C0C0: 'lightGray', '000000': 'black' };
|
|
1142
|
+
var LIST_FMT = {
|
|
1143
|
+
disc: ['bullet', '•', 'Arial'], circle: ['bullet', 'o', 'Courier New'], square: ['bullet', '▪', 'Arial'],
|
|
1144
|
+
decimal: ['decimal', '.'], 'decimal-leading-zero': ['decimalZero', '.'], 'lower-alpha': ['lowerLetter', '.'],
|
|
1145
|
+
'lower-latin': ['lowerLetter', '.'], 'upper-alpha': ['upperLetter', '.'], 'upper-latin': ['upperLetter', '.'],
|
|
1146
|
+
'lower-roman': ['lowerRoman', '.'], 'upper-roman': ['upperRoman', '.'], none: ['none', '']
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
function Layout(opts, page, warn) {
|
|
1150
|
+
this.opts = opts; this.page = page; this.warn = warn;
|
|
1151
|
+
this.media = []; this.mediaBySrc = Object.create(null); this.links = []; this.linkByUrl = Object.create(null);
|
|
1152
|
+
this.lists = []; this.absByFmt = Object.create(null); this.stats = { paragraphs: 0, tables: 0, images: 0, links: 0, lists: 0 };
|
|
1153
|
+
this.remote = null;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
function Flow() { this.items = []; this.para = null; this.pb = 0; this.pbFixed = 0; this.brk = false; }
|
|
1157
|
+
|
|
1158
|
+
function isBlockDisplay(d) { return d === 'block' || d === 'list-item' || d === 'table-caption' || d === 'flex' || d === 'grid' || d === 'flow-root' || d === 'table-row' || d === 'table-cell' || d === 'table-row-group' || d === 'table-header-group' || d === 'table-footer-group'; }
|
|
1159
|
+
|
|
1160
|
+
function hasBlockChild(e) {
|
|
1161
|
+
for (var i = 0; i < e.els.length; i++) {
|
|
1162
|
+
var c = e.els[i];
|
|
1163
|
+
if (c.cs.display !== 'none' && (isBlockDisplay(c.cs.display) || c.cs.display === 'table' || c.tag === 'table' || c.tag === 'hr')) return true;
|
|
1164
|
+
}
|
|
1165
|
+
return false;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
function hasContent(e) {
|
|
1169
|
+
if (e._hc !== undefined) return e._hc;
|
|
1170
|
+
var r = false;
|
|
1171
|
+
for (var i = 0; i < e.children.length && !r; i++) {
|
|
1172
|
+
var c = e.children[i];
|
|
1173
|
+
if (c.tag === '#text') { if (/[^ \t\n\r\f]/.test(c.text)) r = true; }
|
|
1174
|
+
else if (c.cs && c.cs.display === 'none') continue;
|
|
1175
|
+
else if (/^(img|br|hr|table|input|textarea)$/.test(c.tag)) r = true;
|
|
1176
|
+
else if (hasContent(c)) r = true;
|
|
1177
|
+
else if (isBlockDisplay(c.cs.display) && (res0(c.cs.height, 0) > 0 || res0(c.cs.minHeight, 0) > 0)) r = true;
|
|
1178
|
+
}
|
|
1179
|
+
e._hc = r;
|
|
1180
|
+
return r;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
Layout.prototype.runProps = function (cs, ctx) {
|
|
1184
|
+
var rp = {
|
|
1185
|
+
f: cs.fontFamily, sz: cs.fontSize, b: cs.fontWeight >= 600, i: cs.fontStyle === 'italic', u: cs.deco.u, s: cs.deco.s,
|
|
1186
|
+
c: cs.color, bg: ctx.bg || null, va: ctx.va || null, caps: cs.textTransform === 'uppercase',
|
|
1187
|
+
sc: cs.fontVariant === 'small-caps', ls: cs.letterSpacing || 0, hid: cs.visibility === 'hidden'
|
|
1188
|
+
};
|
|
1189
|
+
if (ctx.va && ctx.vaBase) rp.sz = ctx.vaBase;
|
|
1190
|
+
return rp;
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
Layout.prototype.openPara = function (flow, ctx) {
|
|
1194
|
+
var b = ctx.block, cs = b.cs;
|
|
1195
|
+
var p = {
|
|
1196
|
+
kind: 'p', runs: [], cs: cs, before: flow.pbFixed + flow.pb, after: 0, lastSpace: true,
|
|
1197
|
+
ind: { l: ctx.indL, r: ctx.indR, first: 0, hang: 0 }, jc: cs.textAlign, lh: cs.lineHeight, family: cs.fontFamily,
|
|
1198
|
+
shd: ctx.blockBg || null, outline: b.outline, markRp: this.runProps(cs, { bg: null, va: null })
|
|
1199
|
+
};
|
|
1200
|
+
flow.pb = 0; flow.pbFixed = 0;
|
|
1201
|
+
if (flow.brk) { p.pageBreakBefore = true; flow.brk = false; }
|
|
1202
|
+
if (!b.used) { b.used = true; p.ind.first = res0(cs.textIndent, ctx.W); }
|
|
1203
|
+
if (ctx.li && !ctx.li.used) {
|
|
1204
|
+
ctx.li.used = true;
|
|
1205
|
+
if (ctx.li.numId) { p.num = { id: ctx.li.numId, ilvl: ctx.li.ilvl }; p.ind.hang = Math.min(18, Math.max(0, p.ind.l)); }
|
|
1206
|
+
}
|
|
1207
|
+
if (b.keepNext) p.keepNextBlock = true;
|
|
1208
|
+
flow.para = p;
|
|
1209
|
+
this.stats.paragraphs++;
|
|
1210
|
+
return p;
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
function runVisible(r) { return r.img || r.tab || r.br || (r.t && /[^ ]/.test(r.t)); }
|
|
1214
|
+
|
|
1215
|
+
Layout.prototype.flush = function (flow) {
|
|
1216
|
+
var p = flow.para;
|
|
1217
|
+
if (!p) return;
|
|
1218
|
+
flow.para = null;
|
|
1219
|
+
var runs = p.runs;
|
|
1220
|
+
while (runs.length) { // trim trailing collapsible spaces
|
|
1221
|
+
var r = runs[runs.length - 1];
|
|
1222
|
+
if (r.t !== undefined && !r.pre) {
|
|
1223
|
+
r.t = r.t.replace(/ +$/, '');
|
|
1224
|
+
if (!r.t) { runs.pop(); continue; }
|
|
1225
|
+
}
|
|
1226
|
+
break;
|
|
1227
|
+
}
|
|
1228
|
+
var vis = runs.some(runVisible);
|
|
1229
|
+
if (!vis) {
|
|
1230
|
+
this.stats.paragraphs--;
|
|
1231
|
+
flow.pb = Math.max(flow.pb, p.before);
|
|
1232
|
+
if (p.pageBreakBefore) flow.brk = true;
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
if (runs.length > 1 && runs[runs.length - 1].br && !runs[runs.length - 1].pageBr) runs.pop();
|
|
1236
|
+
else if (runs.length === 1 && runs[0].br) runs.pop(); // a lone <br> is an empty line
|
|
1237
|
+
flow.items.push(p);
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
Layout.prototype.addRun = function (flow, ctx, run) {
|
|
1241
|
+
var p = flow.para || this.openPara(flow, ctx);
|
|
1242
|
+
if (ctx.link) run.link = ctx.link;
|
|
1243
|
+
p.runs.push(run);
|
|
1244
|
+
return p;
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
Layout.prototype.addText = function (text, cs, ctx, flow) {
|
|
1248
|
+
var ws = cs.whiteSpace || 'normal';
|
|
1249
|
+
var pre = ws === 'pre' || ws === 'pre-wrap' || ws === 'break-spaces', preLine = ws === 'pre-line';
|
|
1250
|
+
if (!pre) text = preLine ? text.replace(/[ \t\f\r]+/g, ' ').replace(/ ?\n ?/g, '\n') : text.replace(/[ \t\n\r\f]+/g, ' ');
|
|
1251
|
+
if (!text) return;
|
|
1252
|
+
var p = flow.para;
|
|
1253
|
+
if (!pre) {
|
|
1254
|
+
if (!p || p.lastSpace) text = text.replace(/^ /, '');
|
|
1255
|
+
if (!text) return;
|
|
1256
|
+
}
|
|
1257
|
+
var endsSpace = !pre && / $/.test(text);
|
|
1258
|
+
if (ws === 'nowrap') text = text.replace(/ (?=.)/g, ' ');
|
|
1259
|
+
if (cs.textTransform === 'lowercase') text = text.toLowerCase();
|
|
1260
|
+
else if (cs.textTransform === 'capitalize') {
|
|
1261
|
+
var prevSpace = !p || p.lastSpace;
|
|
1262
|
+
text = text.replace(/(^|[\s ("'“„«\[-])([^\s ])/g, function (m, a, c, off) {
|
|
1263
|
+
return off === 0 && !a && !prevSpace ? m : a + c.toUpperCase();
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
var rp = this.runProps(cs, ctx), self = this;
|
|
1267
|
+
if (pre || preLine) {
|
|
1268
|
+
var lines = text.split('\n');
|
|
1269
|
+
lines.forEach(function (ln, idx) {
|
|
1270
|
+
if (idx > 0) self.addRun(flow, ctx, { br: true, rp: rp });
|
|
1271
|
+
if (pre) {
|
|
1272
|
+
ln.split('\t').forEach(function (seg, k) {
|
|
1273
|
+
if (k > 0) self.addRun(flow, ctx, { tab: true, rp: rp });
|
|
1274
|
+
if (seg) self.addRun(flow, ctx, { t: seg, rp: rp, pre: true });
|
|
1275
|
+
});
|
|
1276
|
+
} else if (ln) self.addRun(flow, ctx, { t: ln, rp: rp });
|
|
1277
|
+
});
|
|
1278
|
+
if (flow.para) flow.para.lastSpace = false;
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
p = this.addRun(flow, ctx, { t: text, rp: rp });
|
|
1282
|
+
p.lastSpace = endsSpace;
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
Layout.prototype.children = function (e, ctx, flow) {
|
|
1286
|
+
for (var k = 0; k < e.children.length; k++) {
|
|
1287
|
+
var ch = e.children[k];
|
|
1288
|
+
if (ch.tag === '#text') this.addText(ch.text, e.cs, ctx, flow);
|
|
1289
|
+
else this.node(ch, ctx, flow);
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
Layout.prototype.node = function (e, ctx, flow) {
|
|
1294
|
+
var cs = e.cs, d = cs.display, t = e.tag;
|
|
1295
|
+
if (d === 'none') return;
|
|
1296
|
+
if (t === 'br') { var p = this.addRun(flow, ctx, { br: true, rp: this.runProps(cs, ctx) }); p.lastSpace = true; return; }
|
|
1297
|
+
if (t === 'img') { this.image(e, ctx, flow); return; }
|
|
1298
|
+
if (t === 'hr') { this.hr(e, ctx, flow); return; }
|
|
1299
|
+
if (t === 'input') { this.input(e, ctx, flow); return; }
|
|
1300
|
+
if (t === 'table' || d === 'table' || d === 'inline-table') { this.table(e, ctx, flow); return; }
|
|
1301
|
+
if (isBlockDisplay(d) || (d === 'inline-block' && hasBlockChild(e))) { this.block(e, ctx, flow); return; }
|
|
1302
|
+
// inline
|
|
1303
|
+
var c2 = ctx, va = cs.verticalAlign;
|
|
1304
|
+
var isVa = va === 'super' || va === 'sub';
|
|
1305
|
+
var href = t === 'a' && e.attrs.href ? String(e.attrs.href).trim() : null;
|
|
1306
|
+
if (href && (href.charAt(0) === '#' || /^javascript:/i.test(href))) href = null;
|
|
1307
|
+
if (cs.background || isVa || href) {
|
|
1308
|
+
c2 = Object.create(ctx);
|
|
1309
|
+
if (cs.background) c2.bg = cs.background;
|
|
1310
|
+
if (isVa && !ctx.va) { c2.va = va; c2.vaBase = e.parent && e.parent.cs ? e.parent.cs.fontSize : cs.fontSize; }
|
|
1311
|
+
if (href) { c2.link = href; this.stats.links++; }
|
|
1312
|
+
}
|
|
1313
|
+
this.children(e, c2, flow);
|
|
1314
|
+
if (d === 'inline-block' && cs.width && !cs.width.auto && res0(cs.width, ctx.W) > 0) {
|
|
1315
|
+
var pp = this.addRun(flow, c2, { tab: true, rp: this.runProps(cs, c2) });
|
|
1316
|
+
pp.lastSpace = true;
|
|
1317
|
+
}
|
|
1318
|
+
};
|
|
1319
|
+
|
|
1320
|
+
Layout.prototype.input = function (e, ctx, flow) {
|
|
1321
|
+
var ty = String(e.attrs.type || 'text').toLowerCase(), on = e.attrs.checked !== undefined, txt;
|
|
1322
|
+
if (ty === 'hidden') return;
|
|
1323
|
+
if (ty === 'checkbox') txt = on ? '☒' : '☐';
|
|
1324
|
+
else if (ty === 'radio') txt = on ? '◉' : '○';
|
|
1325
|
+
else txt = e.attrs.value || '';
|
|
1326
|
+
if (!txt) return;
|
|
1327
|
+
var p = this.addRun(flow, ctx, { t: txt, rp: this.runProps(e.cs, ctx) });
|
|
1328
|
+
p.lastSpace = false;
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
function boxH(cs, W, folded) {
|
|
1332
|
+
if (folded) return { ml: 0, mr: 0, pl: 0, pr: 0, bl: 0, br: 0 };
|
|
1333
|
+
return {
|
|
1334
|
+
ml: res0(cs.m[3], W), mr: res0(cs.m[1], W), pl: Math.max(0, res0(cs.pd[3], W)), pr: Math.max(0, res0(cs.pd[1], W)),
|
|
1335
|
+
bl: cs.bd[3] ? cs.bd[3].w : 0, br: cs.bd[1] ? cs.bd[1].w : 0
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
function isBreak(v) { return v === 'always' || v === 'page' || v === 'left' || v === 'right'; }
|
|
1339
|
+
|
|
1340
|
+
Layout.prototype.newList = function (e, cs) {
|
|
1341
|
+
var type = LIST_FMT[cs.listStyleType] ? cs.listStyleType : (e.tag === 'ol' ? 'decimal' : 'disc');
|
|
1342
|
+
if (!this.absByFmt[type]) this.absByFmt[type] = { id: Object.keys(this.absByFmt).length, type: type };
|
|
1343
|
+
var start = parseInt(e.attrs.start, 10);
|
|
1344
|
+
var lst = { numId: this.lists.length + 1, abs: this.absByFmt[type].id, start: start > 0 ? start : 1, ilvl: 0 };
|
|
1345
|
+
this.lists.push(lst);
|
|
1346
|
+
this.stats.lists++;
|
|
1347
|
+
return lst;
|
|
1348
|
+
};
|
|
1349
|
+
|
|
1350
|
+
Layout.prototype.block = function (e, ctx, flow) {
|
|
1351
|
+
var cs = e.cs, W = ctx.W;
|
|
1352
|
+
this.flush(flow);
|
|
1353
|
+
var h = boxH(cs, W, e.folded);
|
|
1354
|
+
var mt = res0(cs.m[0], W), mb = res0(cs.m[2], W), ptop = Math.max(0, res0(cs.pd[0], W)), pbot = Math.max(0, res0(cs.pd[2], W));
|
|
1355
|
+
var bt = cs.bd[0] ? cs.bd[0].w : 0, bb = cs.bd[2] ? cs.bd[2].w : 0;
|
|
1356
|
+
var wv = e.folded ? null : res(cs.width, W);
|
|
1357
|
+
if (wv != null && wv > 0) {
|
|
1358
|
+
var cw = cs.boxSizing === 'border-box' ? wv - h.pl - h.pr - h.bl - h.br : wv;
|
|
1359
|
+
var free = W - (cw + h.pl + h.pr + h.bl + h.br);
|
|
1360
|
+
var la = cs.m[3] && cs.m[3].auto, ra = cs.m[1] && cs.m[1].auto;
|
|
1361
|
+
if (la && ra) h.ml = h.mr = free / 2; else if (la) h.ml = free - h.mr; else h.mr = free - h.ml;
|
|
1362
|
+
}
|
|
1363
|
+
if (isBreak(cs.pbBefore)) flow.brk = true;
|
|
1364
|
+
if (ptop > 0 || bt > 0) { flow.pbFixed += Math.max(flow.pb, mt) + ptop + bt; flow.pb = 0; }
|
|
1365
|
+
else flow.pb = Math.max(flow.pb, mt);
|
|
1366
|
+
var start = flow.items.length;
|
|
1367
|
+
var hl = /^h([1-6])$/.exec(e.tag);
|
|
1368
|
+
var nctx = Object.create(ctx);
|
|
1369
|
+
nctx.W = Math.max(1, W - h.ml - h.mr - h.pl - h.pr - h.bl - h.br);
|
|
1370
|
+
nctx.indL = ctx.indL + h.ml + h.bl + h.pl;
|
|
1371
|
+
nctx.indR = ctx.indR + h.mr + h.br + h.pr;
|
|
1372
|
+
nctx.block = { cs: cs, el: e, used: false, outline: hl ? +hl[1] - 1 : null, keepNext: cs.pbAfter === 'avoid' };
|
|
1373
|
+
nctx.bg = null; nctx.va = null; nctx.vaBase = 0;
|
|
1374
|
+
if (cs.background) nctx.blockBg = cs.background;
|
|
1375
|
+
if (e.tag === 'ul' || e.tag === 'ol' || e.tag === 'menu' || e.tag === 'dir') {
|
|
1376
|
+
var lst = this.newList(e, cs);
|
|
1377
|
+
lst.ilvl = ctx.listDepth || 0;
|
|
1378
|
+
nctx.list = lst; nctx.listDepth = (ctx.listDepth || 0) + 1; nctx.li = null;
|
|
1379
|
+
} else if (cs.display === 'list-item') {
|
|
1380
|
+
var L = ctx.list;
|
|
1381
|
+
if (!L) { L = this.newList(e, cs); ctx.list = L; }
|
|
1382
|
+
var none = cs.listStyleType === 'none';
|
|
1383
|
+
nctx.li = { numId: none ? 0 : L.numId, ilvl: Math.min(8, L.ilvl), used: false };
|
|
1384
|
+
if (!none && cs.listStyleType !== this.lists[L.numId - 1].typeName) this.lists[L.numId - 1].typeName = cs.listStyleType;
|
|
1385
|
+
}
|
|
1386
|
+
if (!hasContent(e)) {
|
|
1387
|
+
var hh = res(cs.height, W);
|
|
1388
|
+
if (hh == null) hh = res(cs.minHeight, W);
|
|
1389
|
+
if (hh > 0.5) {
|
|
1390
|
+
var sp = { kind: 'p', runs: [], cs: cs, before: flow.pbFixed + flow.pb, after: 0, ind: { l: nctx.indL, r: nctx.indR, first: 0, hang: 0 }, exact: hh, markRp: { f: cs.fontFamily, sz: 1 }, shd: nctx.blockBg || null };
|
|
1391
|
+
if (flow.brk) { sp.pageBreakBefore = true; flow.brk = false; }
|
|
1392
|
+
flow.pb = 0; flow.pbFixed = 0;
|
|
1393
|
+
flow.items.push(sp);
|
|
1394
|
+
}
|
|
1395
|
+
} else this.children(e, nctx, flow);
|
|
1396
|
+
this.flush(flow);
|
|
1397
|
+
var last = flow.items.length > start ? flow.items[flow.items.length - 1] : null;
|
|
1398
|
+
var edgeB = pbot + bb;
|
|
1399
|
+
if (last && last.kind === 'p') {
|
|
1400
|
+
var a = Math.max(last.after, flow.pb);
|
|
1401
|
+
flow.pb = 0;
|
|
1402
|
+
last.after = edgeB > 0 ? a + edgeB + mb : Math.max(a, mb);
|
|
1403
|
+
if (flow.pbFixed) { last.after += flow.pbFixed; flow.pbFixed = 0; }
|
|
1404
|
+
} else if (last) flow.pb = Math.max(flow.pb, mb + edgeB);
|
|
1405
|
+
else { flow.pb = Math.max(flow.pb, mb); flow.pbFixed += edgeB; }
|
|
1406
|
+
if (isBreak(cs.pbAfter)) flow.brk = true;
|
|
1407
|
+
var bds = cs.bd;
|
|
1408
|
+
if (!e.folded && (bds[0] || bds[1] || bds[2] || bds[3])) {
|
|
1409
|
+
var bd = { t: bds[0], r: bds[1], b: bds[2], l: bds[3], sp: [ptop, h.pr, pbot, h.pl] };
|
|
1410
|
+
for (var k = start; k < flow.items.length; k++) if (flow.items[k].kind === 'p' && !flow.items[k].bdr) flow.items[k].bdr = bd;
|
|
1411
|
+
}
|
|
1412
|
+
if (cs.pbInside === 'avoid') applyKeep(flow.items, start);
|
|
1413
|
+
if (cs.pbAfter === 'avoid' && last && last.kind === 'p') last.keepNext = true;
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
function eachPara(item, fn) {
|
|
1417
|
+
if (item.kind === 'p') { fn(item); return; }
|
|
1418
|
+
item.rows.forEach(function (r) { r.cells.forEach(function (c) { c.items.forEach(function (it) { eachPara(it, fn); }); }); });
|
|
1419
|
+
}
|
|
1420
|
+
function applyKeep(items, start) {
|
|
1421
|
+
for (var k = start; k < items.length; k++) {
|
|
1422
|
+
var it = items[k], isLast = k === items.length - 1;
|
|
1423
|
+
if (it.kind === 'p') { it.keepLines = true; if (!isLast) it.keepNext = true; }
|
|
1424
|
+
else {
|
|
1425
|
+
it.rows.forEach(function (r, ri) {
|
|
1426
|
+
r.cant = true;
|
|
1427
|
+
if (!isLast || ri < it.rows.length - 1) r.cells.forEach(function (c) { c.items.forEach(function (x) { eachPara(x, function (p) { p.keepNext = true; }); }); });
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
Layout.prototype.hr = function (e, ctx, flow) {
|
|
1434
|
+
var cs = e.cs, W = ctx.W;
|
|
1435
|
+
this.flush(flow);
|
|
1436
|
+
flow.pb = Math.max(flow.pb, res0(cs.m[0], W));
|
|
1437
|
+
var b = cs.bd[0] || cs.bd[2] || { w: 0.75, s: 'solid', c: '808080' };
|
|
1438
|
+
var p = { kind: 'p', runs: [], cs: cs, before: flow.pbFixed + flow.pb, after: 0, ind: { l: ctx.indL, r: ctx.indR, first: 0, hang: 0 }, exact: 1, markRp: { f: cs.fontFamily, sz: 1 }, bdr: { b: { w: b.w, s: b.s === 'inset' || b.s === 'outset' ? 'solid' : b.s, c: b.c }, sp: [0, 0, 0, 0] } };
|
|
1439
|
+
flow.pb = 0; flow.pbFixed = 0;
|
|
1440
|
+
if (flow.brk) { p.pageBreakBefore = true; flow.brk = false; }
|
|
1441
|
+
flow.items.push(p);
|
|
1442
|
+
p.after = res0(cs.m[2], W);
|
|
1443
|
+
};
|
|
1444
|
+
|
|
1445
|
+
Layout.prototype.image = function (e, ctx, flow) {
|
|
1446
|
+
var cs = e.cs, src = e.attrs.src || '';
|
|
1447
|
+
var info = this.mediaBySrc[src];
|
|
1448
|
+
if (!info) {
|
|
1449
|
+
info = loadImageSrc(src, this.remote);
|
|
1450
|
+
if (info.error) { this.warn(info.error); info = { error: info.error }; }
|
|
1451
|
+
else {
|
|
1452
|
+
info.idx = this.media.length + 1;
|
|
1453
|
+
info.name = 'image' + info.idx + '.' + info.ext;
|
|
1454
|
+
info.rid = 'rIdImg' + info.idx;
|
|
1455
|
+
this.media.push(info);
|
|
1456
|
+
}
|
|
1457
|
+
this.mediaBySrc[src] = info;
|
|
1458
|
+
}
|
|
1459
|
+
if (info.error) {
|
|
1460
|
+
var alt = e.attrs.alt;
|
|
1461
|
+
if (alt) { var pa = this.addRun(flow, ctx, { t: '[' + alt + ']', rp: this.runProps(cs, ctx) }); pa.lastSpace = false; }
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
var W = ctx.W;
|
|
1465
|
+
var w = res(cs.width, W), hgt = res(cs.height, null);
|
|
1466
|
+
var iw = info.w * 0.75, ih = info.h * 0.75;
|
|
1467
|
+
if (w == null && hgt == null) { w = iw; hgt = ih; }
|
|
1468
|
+
else if (w == null) w = ih ? hgt * iw / ih : hgt;
|
|
1469
|
+
else if (hgt == null) hgt = iw ? w * ih / iw : w;
|
|
1470
|
+
var mw = res(cs.maxWidth, W);
|
|
1471
|
+
if (mw != null && w > mw) { hgt = hgt * mw / w; w = mw; }
|
|
1472
|
+
if (w > W && W > 10) { hgt = hgt * W / w; w = W; }
|
|
1473
|
+
if (!(w > 0) || !(hgt > 0)) { w = w || 72; hgt = hgt || 72; }
|
|
1474
|
+
this.stats.images++;
|
|
1475
|
+
var run = { img: info, w: w, h: hgt, alt: e.attrs.alt || '', rp: this.runProps(cs, ctx) };
|
|
1476
|
+
if (cs.display === 'block') {
|
|
1477
|
+
this.flush(flow);
|
|
1478
|
+
var mt = res0(cs.m[0], W), mb = res0(cs.m[2], W);
|
|
1479
|
+
flow.pb = Math.max(flow.pb, mt);
|
|
1480
|
+
var bctx = Object.create(ctx);
|
|
1481
|
+
var la = cs.m[3] && cs.m[3].auto, ra = cs.m[1] && cs.m[1].auto;
|
|
1482
|
+
var jc = la && ra ? 'center' : la ? 'right' : 'left';
|
|
1483
|
+
bctx.block = { cs: Object.create(ctx.block.cs, { textAlign: { value: jc }, textIndent: { value: null }, lineHeight: { value: null } }), used: true };
|
|
1484
|
+
var p = this.openPara(flow, bctx);
|
|
1485
|
+
p.runs.push(run); p.lastSpace = false;
|
|
1486
|
+
this.flush(flow);
|
|
1487
|
+
p.after = Math.max(p.after, mb);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
var pp = this.addRun(flow, ctx, run);
|
|
1491
|
+
pp.lastSpace = false;
|
|
1492
|
+
pp.hasImage = true;
|
|
1493
|
+
};
|
|
1494
|
+
|
|
1495
|
+
// ---------- tables ----------
|
|
1496
|
+
function textMetrics(e) { // rough min/max content widths in pt
|
|
1497
|
+
var mn = 0, mx = 0, line = 0;
|
|
1498
|
+
function walk(n, fs, bold) {
|
|
1499
|
+
if (n.tag === '#text') {
|
|
1500
|
+
var t = n.text.replace(/[ \t\n\r\f]+/g, ' ');
|
|
1501
|
+
var k = fs * (bold ? 0.56 : 0.52);
|
|
1502
|
+
t.split(' ').forEach(function (wd) { if (wd) mn = Math.max(mn, wd.length * k); });
|
|
1503
|
+
line += t.length * k;
|
|
1504
|
+
mx = Math.max(mx, line);
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
if (!n.cs || n.cs.display === 'none') return;
|
|
1508
|
+
if (n.tag === 'br') { line = 0; return; }
|
|
1509
|
+
if (n.tag === 'img') { var iw = res(n.cs.width, null) || 72; mn = Math.max(mn, iw); line += iw; mx = Math.max(mx, line); return; }
|
|
1510
|
+
var blk = isBlockDisplay(n.cs.display) || n.tag === 'table';
|
|
1511
|
+
if (blk) line = 0;
|
|
1512
|
+
for (var i = 0; i < n.children.length; i++) walk(n.children[i], n.cs.fontSize, n.cs.fontWeight >= 600);
|
|
1513
|
+
if (blk) line = 0;
|
|
1514
|
+
}
|
|
1515
|
+
walk(e, e.cs.fontSize, e.cs.fontWeight >= 600);
|
|
1516
|
+
return { min: mn, max: mx };
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
Layout.prototype.table = function (e, ctx, flow) {
|
|
1520
|
+
var cs = e.cs, W = ctx.W, self = this;
|
|
1521
|
+
this.flush(flow);
|
|
1522
|
+
if (isBreak(cs.pbBefore)) flow.brk = true;
|
|
1523
|
+
var mt = res0(cs.m[0], W), mb = res0(cs.m[2], W);
|
|
1524
|
+
var before = flow.pbFixed + Math.max(flow.pb, mt);
|
|
1525
|
+
flow.pb = 0; flow.pbFixed = 0;
|
|
1526
|
+
var prev = flow.items[flow.items.length - 1];
|
|
1527
|
+
if (flow.brk) { flow.items.push(this.tinyPara(ctx, true)); flow.brk = false; }
|
|
1528
|
+
else if (before > 0.5) {
|
|
1529
|
+
if (prev && prev.kind === 'p') prev.after = Math.max(prev.after, before);
|
|
1530
|
+
else flow.items.push({ kind: 'p', runs: [], cs: cs, before: 0, after: 0, ind: { l: ctx.indL, r: ctx.indR, first: 0, hang: 0 }, exact: before, markRp: { f: cs.fontFamily, sz: 1 } });
|
|
1531
|
+
}
|
|
1532
|
+
// rows and columns
|
|
1533
|
+
var head = [], body = [], foot = [], cols = [], caption = null;
|
|
1534
|
+
function rowOf(tr, header) { return { el: tr, header: header, cells: tr.els.filter(function (c) { return (c.tag === 'td' || c.tag === 'th') && c.cs.display !== 'none'; }) }; }
|
|
1535
|
+
function scan(container, target, header) {
|
|
1536
|
+
var loose = null;
|
|
1537
|
+
container.els.forEach(function (c) {
|
|
1538
|
+
if (c.cs.display === 'none') return;
|
|
1539
|
+
if (c.tag === 'tr') { loose = null; target.push(rowOf(c, header)); }
|
|
1540
|
+
else if (c.tag === 'td' || c.tag === 'th') { if (!loose) { loose = { el: null, header: header, cells: [] }; target.push(loose); } loose.cells.push(c); }
|
|
1541
|
+
else if (c.tag === 'thead') scan(c, head, true);
|
|
1542
|
+
else if (c.tag === 'tbody') scan(c, body, false);
|
|
1543
|
+
else if (c.tag === 'tfoot') scan(c, foot, false);
|
|
1544
|
+
else if (c.tag === 'caption') caption = c;
|
|
1545
|
+
else if (c.tag === 'colgroup') {
|
|
1546
|
+
if (c.els.length) c.els.forEach(function (col) { if (col.tag === 'col') cols.push({ el: col, span: Math.max(1, parseInt(col.attrs.span, 10) || 1) }); });
|
|
1547
|
+
else cols.push({ el: c, span: Math.max(1, parseInt(c.attrs.span, 10) || 1) });
|
|
1548
|
+
} else if (c.tag === 'col') cols.push({ el: c, span: Math.max(1, parseInt(c.attrs.span, 10) || 1) });
|
|
1549
|
+
else if (c.tag === 'form') scan(c, target, header);
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
scan(e, body, false);
|
|
1553
|
+
if (caption) this.block(caption, ctx, flow);
|
|
1554
|
+
var rows = head.concat(body, foot).filter(function (r) { return r.cells.length; });
|
|
1555
|
+
if (!rows.length) { flow.pb = Math.max(flow.pb, mb); return; }
|
|
1556
|
+
var R = rows.length, grid = [], cells = [], nC = 0, r, c;
|
|
1557
|
+
for (r = 0; r < R; r++) grid[r] = grid[r] || [];
|
|
1558
|
+
for (r = 0; r < R; r++) {
|
|
1559
|
+
c = 0;
|
|
1560
|
+
rows[r].cells.forEach(function (td) {
|
|
1561
|
+
while (grid[r][c]) c++;
|
|
1562
|
+
var csn = clamp(parseInt(td.attrs.colspan, 10) || 1, 1, 1000);
|
|
1563
|
+
var rsn = parseInt(td.attrs.rowspan, 10);
|
|
1564
|
+
rsn = isNaN(rsn) ? 1 : rsn === 0 ? R - r : clamp(rsn, 1, R - r);
|
|
1565
|
+
var cell = { el: td, r: r, c: c, cs: csn, rs: rsn };
|
|
1566
|
+
for (var rr = r; rr < r + rsn; rr++) for (var cc = c; cc < c + csn; cc++) grid[rr][cc] = (rr === r && cc === c) ? cell : { cont: cell, top: rr === r };
|
|
1567
|
+
cells.push(cell);
|
|
1568
|
+
c += csn;
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
for (r = 0; r < R; r++) nC = Math.max(nC, grid[r].length);
|
|
1572
|
+
// widths
|
|
1573
|
+
var tw = res(cs.width, W);
|
|
1574
|
+
var mlL = cs.m[3], mrL = cs.m[1];
|
|
1575
|
+
var colL = new Array(nC), colPt = new Array(nC), i;
|
|
1576
|
+
for (i = 0; i < nC; i++) colL[i] = null;
|
|
1577
|
+
var ci = 0;
|
|
1578
|
+
cols.forEach(function (col) { for (var k = 0; k < col.span && ci < nC; k++, ci++) if (col.el.cs.width && !col.el.cs.width.auto) colL[ci] = col.el.cs.width; });
|
|
1579
|
+
cells.forEach(function (cl) {
|
|
1580
|
+
if (cl.cs === 1 && !colL[cl.c] && cl.el.cs.width && !cl.el.cs.width.auto) {
|
|
1581
|
+
var L = cl.el.cs.width;
|
|
1582
|
+
if (L.pt != null && cl.el.cs.boxSizing !== 'border-box') {
|
|
1583
|
+
var ccs = cl.el.cs, ref = tw || W;
|
|
1584
|
+
L = { pt: L.pt + res0(ccs.pd[1], ref) + res0(ccs.pd[3], ref) };
|
|
1585
|
+
}
|
|
1586
|
+
colL[cl.c] = L;
|
|
1587
|
+
}
|
|
1588
|
+
});
|
|
1589
|
+
var ref = tw != null ? tw : W, known = 0, unknown = [];
|
|
1590
|
+
for (i = 0; i < nC; i++) {
|
|
1591
|
+
var v = res(colL[i], ref);
|
|
1592
|
+
if (v != null && v > 0) { colPt[i] = v; known += v; } else { colPt[i] = null; unknown.push(i); }
|
|
1593
|
+
}
|
|
1594
|
+
if (unknown.length) {
|
|
1595
|
+
var mins = [], maxs = [];
|
|
1596
|
+
for (i = 0; i < nC; i++) { mins[i] = 0; maxs[i] = 0; }
|
|
1597
|
+
cells.forEach(function (cl) {
|
|
1598
|
+
if (cl.cs !== 1) return;
|
|
1599
|
+
var m = textMetrics(cl.el), ccs = cl.el.cs, padx = res0(ccs.pd[1], W) + res0(ccs.pd[3], W) + 2;
|
|
1600
|
+
mins[cl.c] = Math.max(mins[cl.c], m.min + padx);
|
|
1601
|
+
maxs[cl.c] = Math.max(maxs[cl.c], m.max + padx);
|
|
1602
|
+
});
|
|
1603
|
+
var avail = (tw != null ? tw : W) - known, smin = 0, smax = 0;
|
|
1604
|
+
unknown.forEach(function (k) { mins[k] = Math.max(mins[k], 14); maxs[k] = Math.max(maxs[k], mins[k]); smin += mins[k]; smax += maxs[k]; });
|
|
1605
|
+
if (tw == null && smax <= avail) unknown.forEach(function (k) { colPt[k] = maxs[k]; });
|
|
1606
|
+
else if (tw != null && smax <= avail) unknown.forEach(function (k) { colPt[k] = maxs[k] + (avail - smax) * (smax ? maxs[k] / smax : 1 / unknown.length); });
|
|
1607
|
+
else if (smin >= avail) unknown.forEach(function (k) { colPt[k] = Math.max(14, avail > 0 ? mins[k] * avail / smin : mins[k]); });
|
|
1608
|
+
else unknown.forEach(function (k) { colPt[k] = mins[k] + (maxs[k] - mins[k]) * (avail - smin) / (smax - smin); });
|
|
1609
|
+
}
|
|
1610
|
+
var sum = 0;
|
|
1611
|
+
for (i = 0; i < nC; i++) sum += colPt[i];
|
|
1612
|
+
if (tw == null) tw = sum;
|
|
1613
|
+
if (sum > 0 && Math.abs(sum - tw) > 0.5) for (i = 0; i < nC; i++) colPt[i] = colPt[i] * tw / sum;
|
|
1614
|
+
// position
|
|
1615
|
+
var ind;
|
|
1616
|
+
if (mlL && mlL.auto && mrL && mrL.auto) ind = ctx.indL + (W - tw) / 2;
|
|
1617
|
+
else if (mlL && mlL.auto) ind = ctx.indL + W - tw - res0(mrL, W);
|
|
1618
|
+
else ind = ctx.indL + res0(mlL, W);
|
|
1619
|
+
// twips grid
|
|
1620
|
+
var colTw = colPt.map(function (x) { return Math.max(1, twip(x)); });
|
|
1621
|
+
var tbl = { kind: 'tbl', ind: ind, cols: colTw, rows: [], borders: cs.bd, bg: cs.background };
|
|
1622
|
+
this.stats.tables++;
|
|
1623
|
+
var tableBg = cs.background;
|
|
1624
|
+
for (r = 0; r < R; r++) {
|
|
1625
|
+
var rowEl = rows[r].el, rcs = rowEl ? rowEl.cs : null;
|
|
1626
|
+
var row = { cells: [], h: rcs ? res0(rcs.height, null) : 0, cant: !!(rcs && rcs.pbInside === 'avoid'), header: rows[r].header && r < head.length };
|
|
1627
|
+
var rowBg = (rcs && rcs.background) || (rowEl && rowEl.parent && rowEl.parent.cs && rowEl.parent.tag !== 'table' ? rowEl.parent.cs.background : null);
|
|
1628
|
+
for (c = 0; c < nC;) {
|
|
1629
|
+
var g = grid[r][c];
|
|
1630
|
+
if (!g) {
|
|
1631
|
+
var c0 = c;
|
|
1632
|
+
while (c < nC && !grid[r][c]) c++;
|
|
1633
|
+
row.cells.push({ w: sumTw(colTw, c0, c), span: c - c0, items: [this.tinyPara(ctx, false)], bd: [null, null, null, null], pad: [0, 0, 0, 0], vAlign: 'top' });
|
|
1634
|
+
continue;
|
|
1635
|
+
}
|
|
1636
|
+
var cell = g.cont || g;
|
|
1637
|
+
var info = this.cell(cell, colTw, rowBg || tableBg, g.cont ? 'continue' : (cell.rs > 1 ? 'restart' : null), ctx);
|
|
1638
|
+
if (!g.cont) row.h = Math.max(row.h, info.h || 0);
|
|
1639
|
+
row.cells.push(info);
|
|
1640
|
+
c += cell.cs;
|
|
1641
|
+
}
|
|
1642
|
+
tbl.rows.push(row);
|
|
1643
|
+
}
|
|
1644
|
+
flow.items.push(tbl);
|
|
1645
|
+
flow.pb = mb;
|
|
1646
|
+
if (isBreak(cs.pbAfter)) flow.brk = true;
|
|
1647
|
+
if (cs.pbInside === 'avoid') applyKeep(flow.items, flow.items.length - 1);
|
|
1648
|
+
};
|
|
1649
|
+
|
|
1650
|
+
function sumTw(arr, a, b) { var s = 0; for (var i = a; i < b; i++) s += arr[i]; return s; }
|
|
1651
|
+
|
|
1652
|
+
Layout.prototype.tinyPara = function (ctx, pageBreak) {
|
|
1653
|
+
var p = { kind: 'p', runs: [], cs: ctx.block.cs, before: 0, after: 0, ind: { l: 0, r: 0, first: 0, hang: 0 }, exact: 1, markRp: { f: ctx.block.cs.fontFamily, sz: 1 } };
|
|
1654
|
+
if (pageBreak) p.pageBreakBefore = true;
|
|
1655
|
+
return p;
|
|
1656
|
+
};
|
|
1657
|
+
|
|
1658
|
+
Layout.prototype.cell = function (cell, colTw, bgFallback, vMerge, ctx) {
|
|
1659
|
+
var td = cell.el, ccs = td.cs;
|
|
1660
|
+
var wTw = sumTw(colTw, cell.c, cell.c + cell.cs), wPt = wTw / 20;
|
|
1661
|
+
var pad = [res0(ccs.pd[0], wPt), res0(ccs.pd[1], wPt), res0(ccs.pd[2], wPt), res0(ccs.pd[3], wPt)].map(function (x) { return Math.max(0, x); });
|
|
1662
|
+
var va = ccs.verticalAlign, vAlign = va === 'middle' ? 'center' : va === 'bottom' ? 'bottom' : 'top';
|
|
1663
|
+
var info = { w: wTw, span: cell.cs, vMerge: vMerge, bd: ccs.bd, pad: pad, shd: ccs.background || bgFallback || null, vAlign: vAlign, noWrap: ccs.whiteSpace === 'nowrap', h: res0(ccs.height, null) };
|
|
1664
|
+
var cflow = new Flow();
|
|
1665
|
+
var cctx = Object.create(ctx);
|
|
1666
|
+
cctx.W = Math.max(1, wPt - pad[1] - pad[3]); cctx.indL = 0; cctx.indR = 0;
|
|
1667
|
+
cctx.block = { cs: ccs, el: td, used: false, outline: null };
|
|
1668
|
+
cctx.bg = null; cctx.va = null; cctx.vaBase = 0; cctx.link = null; cctx.blockBg = null; cctx.li = null; cctx.list = null; cctx.listDepth = 0;
|
|
1669
|
+
if (vMerge !== 'continue') { this.children(td, cctx, cflow); this.flush(cflow); }
|
|
1670
|
+
var items = cflow.items, last = items[items.length - 1];
|
|
1671
|
+
if (last && last.kind === 'p' && cflow.pb > 0) last.after = Math.max(last.after, cflow.pb);
|
|
1672
|
+
if (!last || last.kind !== 'p') {
|
|
1673
|
+
var ep = { kind: 'p', runs: [], cs: ccs, before: 0, after: 0, ind: { l: 0, r: 0, first: 0, hang: 0 }, jc: ccs.textAlign, lh: ccs.lineHeight, family: ccs.fontFamily, markRp: this.runProps(ccs, { bg: null, va: null }) };
|
|
1674
|
+
if (last) { ep.exact = 1; ep.markRp = { f: ccs.fontFamily, sz: 1 }; }
|
|
1675
|
+
items.push(ep);
|
|
1676
|
+
}
|
|
1677
|
+
info.items = items;
|
|
1678
|
+
return info;
|
|
1679
|
+
};
|
|
1680
|
+
|
|
1681
|
+
// ======================= 12. serialization =======================
|
|
1682
|
+
var BSTYLE = { solid: 'single', dashed: 'dashed', dotted: 'dotted', double: 'double', groove: 'threeDEngrave', ridge: 'threeDEmboss', inset: 'single', outset: 'single' };
|
|
1683
|
+
|
|
1684
|
+
function bdrXml(tag, b, space) {
|
|
1685
|
+
if (!b) return '<w:' + tag + ' w:val="nil"/>';
|
|
1686
|
+
var st = BSTYLE[b.s] || 'single', w = b.w;
|
|
1687
|
+
if (st === 'double') w = w / 3;
|
|
1688
|
+
var sz = clamp(Math.round(w * 8), 2, 96);
|
|
1689
|
+
return '<w:' + tag + ' w:val="' + st + '" w:sz="' + sz + '" w:space="' + clamp(Math.round(space || 0), 0, 31) + '" w:color="' + (b.c || 'auto') + '"/>';
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
function Writer(layout, defaults) {
|
|
1693
|
+
this.L = layout; this.D = defaults; this.docPr = 0; this.rels = []; this.relByUrl = Object.create(null);
|
|
1694
|
+
}
|
|
1695
|
+
Writer.prototype.rPr = function (rp) {
|
|
1696
|
+
if (!rp) return '';
|
|
1697
|
+
var D = this.D, x = '';
|
|
1698
|
+
if (rp.f && rp.f !== D.f) { var f = xesc(rp.f); x += '<w:rFonts w:ascii="' + f + '" w:hAnsi="' + f + '" w:eastAsia="' + f + '" w:cs="' + f + '"/>'; }
|
|
1699
|
+
if (rp.b) x += '<w:b/><w:bCs/>';
|
|
1700
|
+
if (rp.i) x += '<w:i/><w:iCs/>';
|
|
1701
|
+
if (rp.caps) x += '<w:caps/>';
|
|
1702
|
+
if (rp.sc) x += '<w:smallCaps/>';
|
|
1703
|
+
if (rp.s) x += '<w:strike/>';
|
|
1704
|
+
if (rp.hid) x += '<w:vanish/>';
|
|
1705
|
+
if (rp.c && rp.c !== '000000') x += '<w:color w:val="' + rp.c + '"/>';
|
|
1706
|
+
if (rp.ls) x += '<w:spacing w:val="' + twip(rp.ls) + '"/>';
|
|
1707
|
+
var hs = Math.max(2, Math.round((rp.sz || 1) * 2));
|
|
1708
|
+
if (hs !== D.sz2) x += '<w:sz w:val="' + hs + '"/><w:szCs w:val="' + hs + '"/>';
|
|
1709
|
+
if (rp.bg && HL[rp.bg]) x += '<w:highlight w:val="' + HL[rp.bg] + '"/>';
|
|
1710
|
+
if (rp.u) x += '<w:u w:val="' + rp.u + '"/>';
|
|
1711
|
+
if (rp.bg && !HL[rp.bg]) x += '<w:shd w:val="clear" w:color="auto" w:fill="' + rp.bg + '"/>';
|
|
1712
|
+
if (rp.va) x += '<w:vertAlign w:val="' + (rp.va === 'super' ? 'superscript' : 'subscript') + '"/>';
|
|
1713
|
+
return x ? '<w:rPr>' + x + '</w:rPr>' : '';
|
|
1714
|
+
};
|
|
1715
|
+
Writer.prototype.linkRel = function (url) {
|
|
1716
|
+
if (!this.relByUrl[url]) { var id = 'rIdLnk' + (this.rels.length + 1); this.relByUrl[url] = id; this.rels.push({ id: id, url: url }); }
|
|
1717
|
+
return this.relByUrl[url];
|
|
1718
|
+
};
|
|
1719
|
+
Writer.prototype.drawing = function (r) {
|
|
1720
|
+
var id = ++this.docPr, img = r.img, cx = Math.max(1, Math.round(r.w * 12700)), cy = Math.max(1, Math.round(r.h * 12700));
|
|
1721
|
+
return '<w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="' + cx + '" cy="' + cy + '"/>' +
|
|
1722
|
+
'<wp:effectExtent l="0" t="0" r="0" b="0"/><wp:docPr id="' + id + '" name="Picture ' + id + '"' + (r.alt ? ' descr="' + xesc(r.alt) + '"' : '') + '/>' +
|
|
1723
|
+
'<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr>' +
|
|
1724
|
+
'<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">' +
|
|
1725
|
+
'<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="' + id + '" name="' + img.name + '"/><pic:cNvPicPr/></pic:nvPicPr>' +
|
|
1726
|
+
'<pic:blipFill><a:blip r:embed="' + img.rid + '"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>' +
|
|
1727
|
+
'<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="' + cx + '" cy="' + cy + '"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>' +
|
|
1728
|
+
'</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>';
|
|
1729
|
+
};
|
|
1730
|
+
Writer.prototype.runs = function (runs, out) {
|
|
1731
|
+
// merge adjacent text runs with identical formatting
|
|
1732
|
+
var merged = [], i;
|
|
1733
|
+
for (i = 0; i < runs.length; i++) {
|
|
1734
|
+
var r = runs[i];
|
|
1735
|
+
r.key = this.rPr(r.rp);
|
|
1736
|
+
var prev = merged[merged.length - 1];
|
|
1737
|
+
if (r.t !== undefined && prev && prev.t !== undefined && prev.key === r.key && prev.link === r.link) prev.t += r.t;
|
|
1738
|
+
else merged.push({ t: r.t, tab: r.tab, br: r.br, img: r.img ? r : null, key: r.key, link: r.link });
|
|
1739
|
+
}
|
|
1740
|
+
i = 0;
|
|
1741
|
+
while (i < merged.length) {
|
|
1742
|
+
var link = merged[i].link;
|
|
1743
|
+
if (link) {
|
|
1744
|
+
out.push('<w:hyperlink r:id="' + this.linkRel(link) + '" w:history="1">');
|
|
1745
|
+
while (i < merged.length && merged[i].link === link) this.run(merged[i++], out);
|
|
1746
|
+
out.push('</w:hyperlink>');
|
|
1747
|
+
} else this.run(merged[i++], out);
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
Writer.prototype.run = function (m, out) {
|
|
1751
|
+
var body;
|
|
1752
|
+
if (m.t !== undefined) body = '<w:t xml:space="preserve">' + xesc(m.t) + '</w:t>';
|
|
1753
|
+
else if (m.tab) body = '<w:tab/>';
|
|
1754
|
+
else if (m.br) body = '<w:br/>';
|
|
1755
|
+
else if (m.img) body = this.drawing(m.img);
|
|
1756
|
+
else return;
|
|
1757
|
+
out.push('<w:r>' + m.key + body + '</w:r>');
|
|
1758
|
+
};
|
|
1759
|
+
Writer.prototype.para = function (p, out) {
|
|
1760
|
+
var x = '';
|
|
1761
|
+
if (p.keepNext) x += '<w:keepNext/>';
|
|
1762
|
+
if (p.keepLines) x += '<w:keepLines/>';
|
|
1763
|
+
if (p.pageBreakBefore) x += '<w:pageBreakBefore/>';
|
|
1764
|
+
if (p.num) x += '<w:numPr><w:ilvl w:val="' + p.num.ilvl + '"/><w:numId w:val="' + p.num.id + '"/></w:numPr>';
|
|
1765
|
+
if (p.bdr) {
|
|
1766
|
+
var b = p.bdr;
|
|
1767
|
+
x += '<w:pBdr>' + (b.t ? bdrXml('top', b.t, b.sp[0]) : '') + (b.l ? bdrXml('left', b.l, b.sp[3]) : '') +
|
|
1768
|
+
(b.b ? bdrXml('bottom', b.b, b.sp[2]) : '') + (b.r ? bdrXml('right', b.r, b.sp[1]) : '') + '</w:pBdr>';
|
|
1769
|
+
}
|
|
1770
|
+
if (p.shd) x += '<w:shd w:val="clear" w:color="auto" w:fill="' + p.shd + '"/>';
|
|
1771
|
+
var line = 240, rule = 'auto';
|
|
1772
|
+
if (p.exact != null) { line = Math.max(2, twip(p.exact)); rule = 'exact'; }
|
|
1773
|
+
else if (p.lh && p.lh.pt != null && p.lh.pt > 0) { line = Math.max(2, twip(p.lh.pt)); rule = p.hasImage ? 'atLeast' : 'exact'; }
|
|
1774
|
+
else if (p.lh && p.lh.m > 0) {
|
|
1775
|
+
var fac = LINE_FACTOR[String(p.family || '').toLowerCase()] || 1.15;
|
|
1776
|
+
line = Math.max(24, Math.round(240 * p.lh.m / fac));
|
|
1777
|
+
}
|
|
1778
|
+
x += '<w:spacing w:before="' + clamp(twip(p.before), 0, 31680) + '" w:after="' + clamp(twip(p.after), 0, 31680) + '" w:line="' + line + '" w:lineRule="' + rule + '"/>';
|
|
1779
|
+
var l = twip(p.ind.l), r = twip(p.ind.r), f = twip(p.ind.first || 0);
|
|
1780
|
+
if (p.num) x += '<w:ind w:left="' + l + '" w:right="' + r + '" w:hanging="' + twip(p.ind.hang) + '"/>';
|
|
1781
|
+
else if (l || r || f) x += '<w:ind w:left="' + l + '" w:right="' + r + '"' + (f > 0 ? ' w:firstLine="' + f + '"' : f < 0 ? ' w:hanging="' + (-f) + '"' : '') + '/>';
|
|
1782
|
+
var jc = JC[p.jc];
|
|
1783
|
+
if (jc && jc !== 'left') x += '<w:jc w:val="' + jc + '"/>';
|
|
1784
|
+
if (p.outline != null) x += '<w:outlineLvl w:val="' + p.outline + '"/>';
|
|
1785
|
+
x += this.rPr(p.markRp);
|
|
1786
|
+
out.push('<w:p>' + (x ? '<w:pPr>' + x + '</w:pPr>' : ''));
|
|
1787
|
+
this.runs(p.runs, out);
|
|
1788
|
+
out.push('</w:p>');
|
|
1789
|
+
};
|
|
1790
|
+
Writer.prototype.table = function (t, out) {
|
|
1791
|
+
var W = 0;
|
|
1792
|
+
t.cols.forEach(function (c) { W += c; });
|
|
1793
|
+
var x = '<w:tbl><w:tblPr><w:tblW w:w="' + W + '" w:type="dxa"/><w:tblInd w:w="' + twip(t.ind) + '" w:type="dxa"/>';
|
|
1794
|
+
var b = t.borders || [];
|
|
1795
|
+
x += '<w:tblBorders>' + bdrXml('top', b[0]) + bdrXml('left', b[3]) + bdrXml('bottom', b[2]) + bdrXml('right', b[1]) +
|
|
1796
|
+
'<w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders>';
|
|
1797
|
+
if (t.bg) x += '<w:shd w:val="clear" w:color="auto" w:fill="' + t.bg + '"/>';
|
|
1798
|
+
x += '<w:tblLayout w:type="fixed"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="0" w:type="dxa"/>' +
|
|
1799
|
+
'<w:bottom w:w="0" w:type="dxa"/><w:right w:w="0" w:type="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>';
|
|
1800
|
+
t.cols.forEach(function (c) { x += '<w:gridCol w:w="' + c + '"/>'; });
|
|
1801
|
+
out.push(x + '</w:tblGrid>');
|
|
1802
|
+
var self = this;
|
|
1803
|
+
t.rows.forEach(function (row) {
|
|
1804
|
+
var tr = '';
|
|
1805
|
+
if (row.cant) tr += '<w:cantSplit/>';
|
|
1806
|
+
if (row.h > 0.5) tr += '<w:trHeight w:val="' + twip(row.h) + '" w:hRule="atLeast"/>';
|
|
1807
|
+
if (row.header) tr += '<w:tblHeader/>';
|
|
1808
|
+
out.push('<w:tr>' + (tr ? '<w:trPr>' + tr + '</w:trPr>' : ''));
|
|
1809
|
+
row.cells.forEach(function (cl) {
|
|
1810
|
+
var bd = cl.bd || [], pd = cl.pad || [0, 0, 0, 0];
|
|
1811
|
+
var tc = '<w:tcW w:w="' + cl.w + '" w:type="dxa"/>';
|
|
1812
|
+
if (cl.span > 1) tc += '<w:gridSpan w:val="' + cl.span + '"/>';
|
|
1813
|
+
if (cl.vMerge === 'restart') tc += '<w:vMerge w:val="restart"/>';
|
|
1814
|
+
else if (cl.vMerge === 'continue') tc += '<w:vMerge/>';
|
|
1815
|
+
tc += '<w:tcBorders>' + bdrXml('top', bd[0]) + bdrXml('left', bd[3]) + bdrXml('bottom', bd[2]) + bdrXml('right', bd[1]) + '</w:tcBorders>';
|
|
1816
|
+
if (cl.shd) tc += '<w:shd w:val="clear" w:color="auto" w:fill="' + cl.shd + '"/>';
|
|
1817
|
+
if (cl.noWrap) tc += '<w:noWrap/>';
|
|
1818
|
+
tc += '<w:tcMar><w:top w:w="' + twip(pd[0]) + '" w:type="dxa"/><w:left w:w="' + twip(pd[3]) + '" w:type="dxa"/>' +
|
|
1819
|
+
'<w:bottom w:w="' + twip(pd[2]) + '" w:type="dxa"/><w:right w:w="' + twip(pd[1]) + '" w:type="dxa"/></w:tcMar>';
|
|
1820
|
+
tc += '<w:vAlign w:val="' + (cl.vAlign || 'top') + '"/>';
|
|
1821
|
+
out.push('<w:tc><w:tcPr>' + tc + '</w:tcPr>');
|
|
1822
|
+
self.items(cl.items, out);
|
|
1823
|
+
out.push('</w:tc>');
|
|
1824
|
+
});
|
|
1825
|
+
out.push('</w:tr>');
|
|
1826
|
+
});
|
|
1827
|
+
out.push('</w:tbl>');
|
|
1828
|
+
};
|
|
1829
|
+
Writer.prototype.items = function (items, out) {
|
|
1830
|
+
for (var i = 0; i < items.length; i++) {
|
|
1831
|
+
if (items[i].kind === 'p') this.para(items[i], out); else this.table(items[i], out);
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
|
|
1835
|
+
function collapse(items) {
|
|
1836
|
+
for (var k = 0; k < items.length; k++) {
|
|
1837
|
+
var b = items[k], a = items[k - 1];
|
|
1838
|
+
if (b.kind === 'p') {
|
|
1839
|
+
b.before = Math.max(0, b.before); b.after = Math.max(0, b.after);
|
|
1840
|
+
if (b.keepNextBlock) b.keepNext = true;
|
|
1841
|
+
if (a && a.kind === 'p' && !b.pageBreakBefore) b.before = Math.max(0, b.before - Math.max(0, a.after));
|
|
1842
|
+
} else b.rows.forEach(function (r) { r.cells.forEach(function (c) { collapse(c.items); }); });
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
function countFonts(items, acc) {
|
|
1847
|
+
items.forEach(function (it) {
|
|
1848
|
+
if (it.kind === 'p') it.runs.forEach(function (r) {
|
|
1849
|
+
if (r.t && r.rp) { var k = r.rp.f + '|' + Math.round(r.rp.sz * 2); acc[k] = (acc[k] || 0) + r.t.length; }
|
|
1850
|
+
});
|
|
1851
|
+
else it.rows.forEach(function (r) { r.cells.forEach(function (c) { countFonts(c.items, acc); }); });
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
function lvlXml(fmt, ilvl, start) {
|
|
1856
|
+
var F = LIST_FMT[fmt] || LIST_FMT.disc, isBullet = F[0] === 'bullet';
|
|
1857
|
+
var text = isBullet ? F[1] : F[0] === 'none' ? '' : '%' + (ilvl + 1) + F[1];
|
|
1858
|
+
var x = '<w:lvl w:ilvl="' + ilvl + '"><w:start w:val="' + (start || 1) + '"/><w:numFmt w:val="' + F[0] + '"/><w:lvlText w:val="' + xesc(text) + '"/>' +
|
|
1859
|
+
'<w:lvlJc w:val="left"/><w:pPr><w:ind w:left="' + (720 * (ilvl + 1)) + '" w:hanging="360"/></w:pPr>';
|
|
1860
|
+
if (isBullet) x += '<w:rPr><w:rFonts w:ascii="' + F[2] + '" w:hAnsi="' + F[2] + '" w:hint="default"/></w:rPr>';
|
|
1861
|
+
return x + '</w:lvl>';
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
function numberingXml(L) {
|
|
1865
|
+
var x = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">';
|
|
1866
|
+
var abs = L.absByFmt;
|
|
1867
|
+
Object.keys(abs).forEach(function (fmt) {
|
|
1868
|
+
x += '<w:abstractNum w:abstractNumId="' + abs[fmt].id + '"><w:multiLevelType w:val="hybridMultilevel"/>';
|
|
1869
|
+
for (var i = 0; i < 9; i++) x += lvlXml(fmt, i, 1);
|
|
1870
|
+
x += '</w:abstractNum>';
|
|
1871
|
+
});
|
|
1872
|
+
L.lists.forEach(function (l) {
|
|
1873
|
+
var absId = l.abs;
|
|
1874
|
+
if (l.typeName && LIST_FMT[l.typeName]) {
|
|
1875
|
+
if (!abs[l.typeName]) { /* registered lazily below */ } else absId = abs[l.typeName].id;
|
|
1876
|
+
}
|
|
1877
|
+
x += '<w:num w:numId="' + l.numId + '"><w:abstractNumId w:val="' + absId + '"/><w:lvlOverride w:ilvl="' + Math.min(8, l.ilvl) + '"><w:startOverride w:val="' + l.start + '"/></w:lvlOverride></w:num>';
|
|
1878
|
+
});
|
|
1879
|
+
return x + '</w:numbering>';
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
var PAGE_SIZES = { a3: [841.89, 1190.55], a4: [595.28, 841.89], a5: [419.53, 595.28], letter: [612, 792], legal: [612, 1008], b5: [498.9, 708.66] };
|
|
1883
|
+
|
|
1884
|
+
function pageSetup(sheet, opts) {
|
|
1885
|
+
var w = 595.28, h = 841.89, m = { t: 28.35, r: 28.35, b: 28.35, l: 28.35 }, land = false;
|
|
1886
|
+
sheet.page.forEach(function (decls) {
|
|
1887
|
+
decls.forEach(function (d) {
|
|
1888
|
+
if (d.p === 'size') {
|
|
1889
|
+
var tk = tokens(d.v.toLowerCase()), lens = [];
|
|
1890
|
+
tk.forEach(function (x) {
|
|
1891
|
+
if (PAGE_SIZES[x]) { w = PAGE_SIZES[x][0]; h = PAGE_SIZES[x][1]; }
|
|
1892
|
+
else if (x === 'landscape') land = true;
|
|
1893
|
+
else if (x === 'portrait') land = false;
|
|
1894
|
+
else { var L = parseLen(x, 12, 12); if (L && L.pt) lens.push(L.pt); }
|
|
1895
|
+
});
|
|
1896
|
+
if (lens.length) { w = lens[0]; h = lens[1] || lens[0]; }
|
|
1897
|
+
}
|
|
1898
|
+
var mm = /^margin-(top|right|bottom|left)$/.exec(d.p);
|
|
1899
|
+
if (mm) { var L2 = parseLen(d.v, 12, 12); if (L2 && L2.pt != null) m[mm[1].charAt(0)] = L2.pt; }
|
|
1900
|
+
});
|
|
1901
|
+
});
|
|
1902
|
+
if (opts.pageSize) {
|
|
1903
|
+
var ps = opts.pageSize;
|
|
1904
|
+
if (typeof ps === 'string' && PAGE_SIZES[ps.toLowerCase()]) { w = PAGE_SIZES[ps.toLowerCase()][0]; h = PAGE_SIZES[ps.toLowerCase()][1]; }
|
|
1905
|
+
else if (ps && ps.widthCm && ps.heightCm) { w = ps.widthCm * PT.cm; h = ps.heightCm * PT.cm; }
|
|
1906
|
+
}
|
|
1907
|
+
if (opts.orientation) land = String(opts.orientation).toLowerCase() === 'landscape';
|
|
1908
|
+
if (land && w < h) { var tmp = w; w = h; h = tmp; }
|
|
1909
|
+
if (!land && opts.orientation && w > h) { var tmp2 = w; w = h; h = tmp2; }
|
|
1910
|
+
return { w: w, h: h, m: m, landscape: w > h };
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
function findBody(root) {
|
|
1914
|
+
var stack = [root];
|
|
1915
|
+
while (stack.length) {
|
|
1916
|
+
var n = stack.shift();
|
|
1917
|
+
if (n.tag === 'body') return n;
|
|
1918
|
+
if (n.els) for (var i = 0; i < n.els.length; i++) stack.push(n.els[i]);
|
|
1919
|
+
}
|
|
1920
|
+
return null;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
// fold body + single wrapper chain horizontal box into the page margins
|
|
1924
|
+
function foldChain(body, page, contentW) {
|
|
1925
|
+
var el = body, addL = 0, addR = 0, W = contentW;
|
|
1926
|
+
while (el) {
|
|
1927
|
+
var cs = el.cs, h = boxH(cs, W, false);
|
|
1928
|
+
if (cs.width && !cs.width.auto && el !== body) break;
|
|
1929
|
+
if (h.ml < 0 || h.mr < 0) break;
|
|
1930
|
+
el.folded = true;
|
|
1931
|
+
addL += h.ml + h.bl + h.pl; addR += h.mr + h.br + h.pr;
|
|
1932
|
+
W -= h.ml + h.bl + h.pl + h.mr + h.br + h.pr;
|
|
1933
|
+
var kids = el.els.filter(function (c) { return c.cs.display !== 'none'; });
|
|
1934
|
+
var textual = el.children.some(function (c) { return c.tag === '#text' && /\S/.test(c.text); });
|
|
1935
|
+
if (kids.length !== 1 || textual) break;
|
|
1936
|
+
var k = kids[0];
|
|
1937
|
+
if (k.cs.display !== 'block' || k.tag === 'p' || /^h[1-6]$/.test(k.tag) || k.tag === 'ul' || k.tag === 'ol' || k.tag === 'pre' || k.tag === 'blockquote') break;
|
|
1938
|
+
if (k.cs.bd.some(Boolean) || k.cs.background) break;
|
|
1939
|
+
el = k;
|
|
1940
|
+
}
|
|
1941
|
+
page.m.l += addL; page.m.r += addR;
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
// ======================= 13. driver =======================
|
|
1945
|
+
function normalizeOpts(o) {
|
|
1946
|
+
if (typeof o === 'string') { try { o = JSON.parse(o); } catch (e) { o = {}; } }
|
|
1947
|
+
if (!o || typeof o !== 'object') o = {};
|
|
1948
|
+
if (o.v && typeof o.v === 'object' && !o.pageSize && !o.marginsCm) o = o.v;
|
|
1949
|
+
return o;
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
function collectRemote(root, out) {
|
|
1953
|
+
(function walk(n) {
|
|
1954
|
+
if (n.tag === 'img' && /^https:\/\//i.test(String(n.attrs.src || '').trim())) out[String(n.attrs.src).trim()] = true;
|
|
1955
|
+
if (n.els) n.els.forEach(walk);
|
|
1956
|
+
})(root);
|
|
1957
|
+
return Object.keys(out);
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
function fetchAll(urls, done) {
|
|
1961
|
+
var req = null;
|
|
1962
|
+
try { req = typeof require === 'function' ? require('https') : null; } catch (e) { req = null; }
|
|
1963
|
+
var result = Object.create(null);
|
|
1964
|
+
if (!req || !urls.length) { done(result); return; }
|
|
1965
|
+
var pending = urls.length, finished = false;
|
|
1966
|
+
var timer = setTimeout(function () { if (!finished) { finished = true; done(result); } }, 30000);
|
|
1967
|
+
function one(url, hops) {
|
|
1968
|
+
var fin = function (val) { result[url] = val; if (--pending === 0 && !finished) { finished = true; clearTimeout(timer); done(result); } };
|
|
1969
|
+
try {
|
|
1970
|
+
req.get(url, { timeout: 15000 }, function (res) {
|
|
1971
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location && hops < 3) {
|
|
1972
|
+
res.resume();
|
|
1973
|
+
var loc = res.headers.location;
|
|
1974
|
+
if (/^https:/i.test(loc)) { pending++; one(loc, hops + 1); result[url] = null; var redirected = loc; pending--; setTimeout(function () { result[url] = result[redirected]; }, 0); }
|
|
1975
|
+
else fin({ error: 'redirect to non-https ' + loc });
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
if (res.statusCode !== 200) { res.resume(); fin({ error: 'HTTP ' + res.statusCode + ' for ' + url }); return; }
|
|
1979
|
+
var chunks = [], total = 0;
|
|
1980
|
+
res.on('data', function (c) { chunks.push(c); total += c.length; });
|
|
1981
|
+
res.on('end', function () { var b = new Uint8Array(total), o = 0; chunks.forEach(function (c) { b.set(c, o); o += c.length; }); fin(b); });
|
|
1982
|
+
res.on('error', function (e) { fin({ error: String(e && e.message || e) }); });
|
|
1983
|
+
}).on('error', function (e) { fin({ error: String(e && e.message || e) }); });
|
|
1984
|
+
} catch (e) { fin({ error: String(e && e.message || e) }); }
|
|
1985
|
+
}
|
|
1986
|
+
urls.forEach(function (u) { one(u, 0); });
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
function build(html, opts, remote) {
|
|
1990
|
+
var t0 = Date.now(), warnings = [];
|
|
1991
|
+
function warn(m) { if (warnings.length < 50 && warnings.indexOf(m) < 0) warnings.push(m); }
|
|
1992
|
+
var root = parseHTML(html);
|
|
1993
|
+
ensureBody(root);
|
|
1994
|
+
annotate(root);
|
|
1995
|
+
// style sources
|
|
1996
|
+
var styles = [];
|
|
1997
|
+
(function walk(n) { if (n.tag === 'style' && n.children[0]) styles.push(n.children[0].text); if (n.tag === 'svg') warn('inline <svg> is not rendered'); if (n.els) n.els.forEach(walk); })(root);
|
|
1998
|
+
var pageGuess = PAGE_SIZES.a4;
|
|
1999
|
+
var env = { type: opts.media === 'print' ? 'print' : 'screen', widthPx: pageGuess[0] / 0.75, heightPx: pageGuess[1] / 0.75 };
|
|
2000
|
+
var sheet = { ua: [], author: [], page: [], seq: 0 };
|
|
2001
|
+
parseCSS(UA_CSS + (opts.quirks === false ? '' : QUIRKS_CSS), sheet, env, 'ua', false);
|
|
2002
|
+
parseCSS(FROALA_CSS, sheet, env, 'author', false);
|
|
2003
|
+
styles.forEach(function (css) { parseCSS(css, sheet, env, 'author', false); });
|
|
2004
|
+
if (opts.css) parseCSS(String(opts.css), sheet, env, 'author', false);
|
|
2005
|
+
computeAll(root, sheet, opts);
|
|
2006
|
+
(function preflight(n) {
|
|
2007
|
+
var cs = n.cs;
|
|
2008
|
+
if (cs && cs.display !== 'none') {
|
|
2009
|
+
if (cs.display === 'flex' || cs.display === 'inline-flex') warn('CSS flex layout is not supported: flex items stack as blocks. Use a table for side-by-side layout.');
|
|
2010
|
+
else if (cs.display === 'grid' || cs.display === 'inline-grid') warn('CSS grid layout is not supported: grid items stack as blocks. Use a table for side-by-side layout.');
|
|
2011
|
+
if (cs.float === 'left' || cs.float === 'right') warn('CSS float is not supported: floated elements stay in normal flow.');
|
|
2012
|
+
}
|
|
2013
|
+
if (n.els) n.els.forEach(preflight);
|
|
2014
|
+
})(root);
|
|
2015
|
+
var page = pageSetup(sheet, opts);
|
|
2016
|
+
var body = findBody(root) || root;
|
|
2017
|
+
if (!body.cs) body.cs = root.cs;
|
|
2018
|
+
var contentW = page.w - page.m.l - page.m.r;
|
|
2019
|
+
var userMargins = opts.marginsCm != null;
|
|
2020
|
+
if (opts.foldWrapper !== false && !userMargins) foldChain(body, page, contentW);
|
|
2021
|
+
if (userMargins) {
|
|
2022
|
+
var mc = opts.marginsCm, all = typeof mc === 'number' ? mc : null;
|
|
2023
|
+
['top', 'right', 'bottom', 'left'].forEach(function (s) {
|
|
2024
|
+
var v = all != null ? all : mc[s];
|
|
2025
|
+
if (typeof v === 'number' && v >= 0) page.m[s.charAt(0)] = v * PT.cm;
|
|
2026
|
+
});
|
|
2027
|
+
if (opts.foldWrapper !== false) foldChain(body, { m: { l: 0, r: 0 } }, contentW); // still neutralise the wrapper indents
|
|
2028
|
+
}
|
|
2029
|
+
contentW = Math.max(36, page.w - page.m.l - page.m.r);
|
|
2030
|
+
var L = new Layout(opts, page, warn);
|
|
2031
|
+
L.remote = remote;
|
|
2032
|
+
var flow = new Flow();
|
|
2033
|
+
var ctx = { W: contentW, indL: 0, indR: 0, block: { cs: body.cs, el: body, used: false }, bg: null, va: null, vaBase: 0, link: null, blockBg: null, li: null, list: null, listDepth: 0 };
|
|
2034
|
+
if (body === root) L.children(root, ctx, flow); else L.block(body, ctx, flow);
|
|
2035
|
+
L.flush(flow);
|
|
2036
|
+
var items = flow.items;
|
|
2037
|
+
if (!items.length) items.push({ kind: 'p', runs: [], cs: body.cs, before: 0, after: 0, ind: { l: 0, r: 0, first: 0, hang: 0 }, markRp: L.runProps(body.cs, {}) });
|
|
2038
|
+
if (items[items.length - 1].kind === 'tbl') items.push(L.tinyPara(ctx, false));
|
|
2039
|
+
collapse(items);
|
|
2040
|
+
// document defaults = dominant font
|
|
2041
|
+
var acc = {};
|
|
2042
|
+
countFonts(items, acc);
|
|
2043
|
+
var best = null, bn = -1;
|
|
2044
|
+
Object.keys(acc).forEach(function (k) { if (acc[k] > bn) { bn = acc[k]; best = k; } });
|
|
2045
|
+
var D = { f: best ? best.split('|')[0] : body.cs.fontFamily, sz2: best ? +best.split('|')[1] : Math.round(body.cs.fontSize * 2) };
|
|
2046
|
+
var lang = opts.lang || (function () {
|
|
2047
|
+
var h = root.els.filter(function (e) { return e.tag === 'html'; })[0], l = h && h.attrs.lang ? h.attrs.lang : 'ro';
|
|
2048
|
+
l = l.replace('_', '-');
|
|
2049
|
+
if (!/-/.test(l)) l = { ro: 'ro-RO', en: 'en-US', de: 'de-DE', fr: 'fr-FR', it: 'it-IT', es: 'es-ES', hu: 'hu-HU', ru: 'ru-RU' }[l.toLowerCase()] || l;
|
|
2050
|
+
return l;
|
|
2051
|
+
})();
|
|
2052
|
+
var Wr = new Writer(L, D), out = [];
|
|
2053
|
+
Wr.items(items, out);
|
|
2054
|
+
var mT = twip(page.m.t), mB = twip(page.m.b);
|
|
2055
|
+
var sect = '<w:sectPr><w:pgSz w:w="' + twip(page.w) + '" w:h="' + twip(page.h) + '"' + (page.landscape ? ' w:orient="landscape"' : '') + '/>' +
|
|
2056
|
+
'<w:pgMar w:top="' + mT + '" w:right="' + twip(page.m.r) + '" w:bottom="' + mB + '" w:left="' + twip(page.m.l) + '" w:header="' + Math.min(708, mT) + '" w:footer="' + Math.min(708, mB) + '" w:gutter="0"/>' +
|
|
2057
|
+
'<w:cols w:space="708"/></w:sectPr>';
|
|
2058
|
+
var NS = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" ' +
|
|
2059
|
+
'xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" ' +
|
|
2060
|
+
'xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"';
|
|
2061
|
+
var docXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:document ' + NS + '><w:body>' + out.join('') + sect + '</w:body></w:document>';
|
|
2062
|
+
// most common paragraph spacing for the Normal style
|
|
2063
|
+
var fam = xesc(D.f);
|
|
2064
|
+
var stylesXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">' +
|
|
2065
|
+
'<w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="' + fam + '" w:hAnsi="' + fam + '" w:eastAsia="' + fam + '" w:cs="' + fam + '"/>' +
|
|
2066
|
+
'<w:sz w:val="' + D.sz2 + '"/><w:szCs w:val="' + D.sz2 + '"/><w:lang w:val="' + xesc(lang) + '" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault>' +
|
|
2067
|
+
'<w:pPrDefault><w:pPr><w:widowControl/><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults>' +
|
|
2068
|
+
'<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style>' +
|
|
2069
|
+
'<w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style>' +
|
|
2070
|
+
'<w:style w:type="table" w:default="1" w:styleId="TableNormal"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/>' +
|
|
2071
|
+
'<w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style>' +
|
|
2072
|
+
'<w:style w:type="numbering" w:default="1" w:styleId="NoList"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style>' +
|
|
2073
|
+
'</w:styles>';
|
|
2074
|
+
var settingsXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">' +
|
|
2075
|
+
'<w:zoom w:percent="100"/><w:defaultTabStop w:val="720"/><w:characterSpacingControl w:val="doNotCompress"/>' +
|
|
2076
|
+
'<w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/>' +
|
|
2077
|
+
'<w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>' +
|
|
2078
|
+
'<w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>' +
|
|
2079
|
+
'<w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/></w:compat></w:settings>';
|
|
2080
|
+
var hasNum = L.lists.length > 0;
|
|
2081
|
+
var rels = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' +
|
|
2082
|
+
'<Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>' +
|
|
2083
|
+
'<Relationship Id="rIdSettings" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>' +
|
|
2084
|
+
(hasNum ? '<Relationship Id="rIdNumbering" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/>' : '');
|
|
2085
|
+
L.media.forEach(function (m) { rels += '<Relationship Id="' + m.rid + '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/' + m.name + '"/>'; });
|
|
2086
|
+
Wr.rels.forEach(function (l) { rels += '<Relationship Id="' + l.id + '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="' + xesc(l.url) + '" TargetMode="External"/>'; });
|
|
2087
|
+
rels += '</Relationships>';
|
|
2088
|
+
var title = opts.title;
|
|
2089
|
+
if (!title) { var te = null; (function f(n) { if (te) return; if (n.tag === 'title') te = n; else if (n.els) n.els.forEach(f); })(root); title = te && te.children[0] ? te.children[0].text.trim() : ''; }
|
|
2090
|
+
var now = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
|
|
2091
|
+
var core = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" ' +
|
|
2092
|
+
'xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
|
|
2093
|
+
(title ? '<dc:title>' + xesc(title) + '</dc:title>' : '') + '<dc:creator>' + xesc(opts.author || 'PROCESIO') + '</dc:creator>' +
|
|
2094
|
+
'<dcterms:created xsi:type="dcterms:W3CDTF">' + now + '</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">' + now + '</dcterms:modified></cp:coreProperties>';
|
|
2095
|
+
var app = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" ' +
|
|
2096
|
+
'xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Application>PROCESIO HTML to DOCX</Application></Properties>';
|
|
2097
|
+
var exts = {};
|
|
2098
|
+
L.media.forEach(function (m) { exts[m.ext] = m.mime; });
|
|
2099
|
+
var ct = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">' +
|
|
2100
|
+
'<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/>';
|
|
2101
|
+
Object.keys(exts).forEach(function (e) { ct += '<Default Extension="' + e + '" ContentType="' + exts[e] + '"/>'; });
|
|
2102
|
+
ct += '<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>' +
|
|
2103
|
+
'<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>' +
|
|
2104
|
+
'<Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/>' +
|
|
2105
|
+
(hasNum ? '<Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>' : '') +
|
|
2106
|
+
'<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>' +
|
|
2107
|
+
'<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>';
|
|
2108
|
+
var rootRels = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' +
|
|
2109
|
+
'<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>' +
|
|
2110
|
+
'<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>' +
|
|
2111
|
+
'<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>';
|
|
2112
|
+
var files = [
|
|
2113
|
+
{ name: '[Content_Types].xml', data: utf8encode(ct) },
|
|
2114
|
+
{ name: '_rels/.rels', data: utf8encode(rootRels) },
|
|
2115
|
+
{ name: 'docProps/core.xml', data: utf8encode(core) },
|
|
2116
|
+
{ name: 'docProps/app.xml', data: utf8encode(app) },
|
|
2117
|
+
{ name: 'word/document.xml', data: utf8encode(docXml) },
|
|
2118
|
+
{ name: 'word/styles.xml', data: utf8encode(stylesXml) },
|
|
2119
|
+
{ name: 'word/settings.xml', data: utf8encode(settingsXml) },
|
|
2120
|
+
{ name: 'word/_rels/document.xml.rels', data: utf8encode(rels) }
|
|
2121
|
+
];
|
|
2122
|
+
if (hasNum) files.push({ name: 'word/numbering.xml', data: utf8encode(numberingXml(L)) });
|
|
2123
|
+
L.media.forEach(function (m) { files.push({ name: 'word/media/' + m.name, data: m.bytes }); });
|
|
2124
|
+
var zip = zipStore(files);
|
|
2125
|
+
var st = L.stats;
|
|
2126
|
+
return {
|
|
2127
|
+
base64: b64encode(zip),
|
|
2128
|
+
report: {
|
|
2129
|
+
ok: true, bytes: zip.length, ms: Date.now() - t0, paragraphs: st.paragraphs, tables: st.tables, images: st.images,
|
|
2130
|
+
links: st.links, lists: st.lists, page: { widthCm: +(page.w / PT.cm).toFixed(2), heightCm: +(page.h / PT.cm).toFixed(2),
|
|
2131
|
+
marginsCm: { top: +(page.m.t / PT.cm).toFixed(3), right: +(page.m.r / PT.cm).toFixed(3), bottom: +(page.m.b / PT.cm).toFixed(3), left: +(page.m.l / PT.cm).toFixed(3) } },
|
|
2132
|
+
defaultFont: D.f + ' ' + (D.sz2 / 2) + 'pt', warnings: warnings
|
|
2133
|
+
}
|
|
2134
|
+
};
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
// html: the HTML text, or { base64: '...' } when it arrives base64-encoded
|
|
2138
|
+
function convert(htmlOrB64, opts, isB64) {
|
|
2139
|
+
opts = normalizeOpts(opts);
|
|
2140
|
+
var html = isB64 ? decodeText(b64decode(htmlOrB64)) : String(htmlOrB64 == null ? '' : htmlOrB64);
|
|
2141
|
+
if (!/\S/.test(html)) throw new Error('HTML input is empty');
|
|
2142
|
+
var remoteUrls = opts.fetchImages === true ? collectRemote(annotateQuick(html), {}) : [];
|
|
2143
|
+
if (!remoteUrls.length) return build(html, opts, null);
|
|
2144
|
+
return new Promise(function (resolve, reject) {
|
|
2145
|
+
fetchAll(remoteUrls, function (remote) { try { resolve(build(html, opts, remote)); } catch (e) { reject(e); } });
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2148
|
+
function annotateQuick(html) {
|
|
2149
|
+
var r = parseHTML(html);
|
|
2150
|
+
annotate(r);
|
|
2151
|
+
return r;
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
return { convert: convert, b64decode: b64decode, decodeText: decodeText, _parseHTML: parseHTML };
|
|
2155
|
+
})();
|