UNPKG

pddl-gantt

Version:

Plan visualization for AI-Planning plans. The package includes HTML components for Gantt, swimlane and line plot visualization of plan originating from AI Planning solvers.

627 lines 31.5 kB
"use strict"; /* -------------------------------------------------------------------------------------------- * Copyright (c) Jan Dolejsi 2020. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.appendPlanView = exports.createPlanView = exports.px = exports.PlanView = exports.PLAN_VIEW_CLASS = exports.ATTR_PLAN = exports.View = exports.getHostElement = exports.DIGITS = void 0; /* eslint-disable @typescript-eslint/no-use-before-define */ const vscode_uri_1 = require("vscode-uri"); const pddl_workspace_1 = require("pddl-workspace"); const pddl_workspace_2 = require("pddl-workspace"); const charts_1 = require("./charts"); const planCapitalization_1 = require("./planCapitalization"); const SwimLane_1 = require("./SwimLane"); exports.DIGITS = 4; function getHostElement(hostElementId) { const host = document.getElementById(hostElementId); if (host === null) { throw new Error(`Element with id#${hostElementId} not found in the document.`); } return host; } exports.getHostElement = getHostElement; class View { constructor(hostElement, options) { this.options = options; this.host = hostElement; } /** * Sets new display width. Does not trigger (re-)drawing. * @param displayWidth new width in pixels, the width is used to fit all gantt chart bars (not necessarily the labels next to them) */ setDisplayWidth(displayWidth) { this.options.displayWidth = displayWidth; } getOrCreateBlankChildElement(className) { const el = this.host.querySelector('.' + className); if (el) { el.innerHTML = ''; } return el !== null && el !== void 0 ? el : this.createChildElement(className); } createChildElement(className) { const child = document.createElement('div'); child.className = className; return this.host.appendChild(child); } } exports.View = View; const CUSTOM_PLAN_VIZ = 'planViz'; const GANTT = 'gantt'; const RESOURCE_UTILIZATION = 'resourceUtilization'; const LINE_CHARTS = 'lineCharts'; exports.ATTR_PLAN = "plan"; exports.PLAN_VIEW_CLASS = "planView"; /** Single-plan view. */ class PlanView extends View { constructor(hostElement, planIndex, options) { super(hostElement, options); this.planIndex = planIndex; this.planStepHeight = 20; this.linePlotsGenerated = false; this.visible = true; this.colors = ['#ff0000', '#ff4000', '#ff8000', '#ffbf00', '#ffff00', '#bfff00', '#80ff00', '#40ff00', '#00ff00', '#00ff40', '#00ff80', '#00ffbf', '#00ffff', '#00bfff', '#0080ff', '#0040ff', '#0000ff', '#4000ff', '#8000ff', '#bf00ff', '#ff00ff', '#ff00bf', '#ff0080', '#ff0040']; if (this.host.style.width.length == 0) { this.host.style.width = px(options.displayWidth + 100); } } clear() { this.getOrCreateBlankChildElement(CUSTOM_PLAN_VIZ); this.getOrCreateBlankChildElement(GANTT); this.getOrCreateBlankChildElement(RESOURCE_UTILIZATION); this.getOrCreateBlankChildElement(LINE_CHARTS); this.plan = undefined; this.customVisualization = undefined; this.deactivateLinePlotPlaceholder(); } setVisible(visible) { if (this.visible !== visible) { this.visible = visible; const newDisplayStyle = visible ? "block" : "none"; this.host.style.display = newDisplayStyle; if (!this.linePlotsGenerated && this.plan) { // line plots were not generated yet if (!visible) { // unsubscribe scroll event this.deactivateLinePlotPlaceholder(); } else { this.lineCharts && this.activateLinePlotPlaceholder(this.lineCharts, this.plan); } } } } showPlan(plan, configuration) { this.plan = plan = defaultDomain((0, planCapitalization_1.capitalize)(plan)); const planVizDiv = this.getOrCreateBlankChildElement(CUSTOM_PLAN_VIZ); this.tryVisualizePlan(planVizDiv, plan, configuration); const stepsToDisplay = plan.steps .filter(step => PlanView.shouldDisplay(step, configuration)); const ganttDiv = this.getOrCreateBlankChildElement(GANTT); this.showGantt(ganttDiv, plan, stepsToDisplay); const swimLanes = this.getOrCreateBlankChildElement(RESOURCE_UTILIZATION); this.showSwimLanes(swimLanes, plan, configuration); this.lineCharts = this.getOrCreateBlankChildElement(LINE_CHARTS); this.activateLinePlotPlaceholder(this.lineCharts, plan); } tryVisualizePlan(planVizDiv, plan, configuration) { var _a; try { this.visualizePlan(planVizDiv, plan, configuration); } catch (ex) { planVizDiv.style.width = px(this.options.displayWidth); const error = ex; this.addError(planVizDiv, (_a = error.message) !== null && _a !== void 0 ? _a : '' + error); } } addError(planVizDiv, ex) { const errorSpan = document.createElement('span'); errorSpan.className = 'error'; errorSpan.innerText = `Error: ` + ex; planVizDiv.appendChild(errorSpan); } visualizePlan(planVizDiv, plan, configuration) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { this.customVisualization = yield (configuration === null || configuration === void 0 ? void 0 : configuration.getCustomVisualization()); if (this.customVisualization) { if (this.customVisualization.visualizePlanHtml) { const vizHtml = this.customVisualization.visualizePlanHtml(plan, this.options.displayWidth); planVizDiv.innerHTML = vizHtml; } else if (this.customVisualization.visualizePlanInDiv) { this.customVisualization.visualizePlanInDiv(planVizDiv, plan, this.options.displayWidth); } else if (this.customVisualization.visualizePlanSvg) { const vizSvg = this.customVisualization.visualizePlanSvg(plan, this.options.displayWidth); planVizDiv.appendChild(vizSvg); } else if (this.customVisualization.visualizeStateHtml || this.customVisualization.visualizeStateInDiv || this.customVisualization.visualizeStateSvg) { (_b = (_a = this.options).onFinalStateVisible) === null || _b === void 0 ? void 0 : _b.call(_a, this); } } }); } showPlanLinePlots(title, yAxisUnit, objects, data) { if (this.lineCharts) { this.hideLinePlotLoadingProgress(); this.addLinePlot(title, yAxisUnit, objects, data); } } showFinalState(finalState) { if (!this.customVisualization || !this.plan) { return; } const planVizDiv = this.getOrCreateBlankChildElement(CUSTOM_PLAN_VIZ); if (this.customVisualization.visualizeStateHtml) { const vizHtml = this.customVisualization.visualizeStateHtml(this.plan, finalState, this.options.displayWidth); planVizDiv.innerHTML = vizHtml; } else if (this.customVisualization.visualizeStateInDiv) { this.customVisualization.visualizeStateInDiv(planVizDiv, this.plan, finalState, this.options.displayWidth); } else if (this.customVisualization.visualizeStateSvg) { const vizSvg = this.customVisualization.visualizeStateSvg(this.plan, finalState, this.options.displayWidth); planVizDiv.appendChild(vizSvg); } } showGantt(ganttDiv, plan, stepsToDisplay) { // split this to two batches and insert helpful actions in between const planHeadSteps = stepsToDisplay .filter(step => this.isPlanHeadStep(step, plan.now)); const relaxedPlanSteps = stepsToDisplay .filter(step => !this.isPlanHeadStep(step, plan.now)); const oneIfHelpfulActionsPresent = (plan.hasHelpfulActions() ? 1 : 0); const relaxedPlanStepIndexOffset = planHeadSteps.length + oneIfHelpfulActionsPresent; const ganttChartHeight = (stepsToDisplay.length + oneIfHelpfulActionsPresent) * this.planStepHeight; ganttDiv.style.height = px(ganttChartHeight); planHeadSteps .map((step, stepIndex) => this.renderGanttStep(ganttDiv, step, stepIndex, plan)); this.renderHelpfulActions(ganttDiv, plan, planHeadSteps.length); relaxedPlanSteps .map((step, stepIndex) => this.renderGanttStep(ganttDiv, step, stepIndex + relaxedPlanStepIndexOffset, plan)); } renderGanttStep(ganttDiv, step, index, plan) { const fromTop = index * this.planStepHeight; const fromLeft = this.computeLeftOffset(step, plan); const planHeadDuration = this.computePlanHeadDuration(step, plan); const width = this.computeWidth(planHeadDuration, plan); const widthRelaxed = this.computeRelaxedWidth(planHeadDuration, step, plan); const actionColor = plan.domain ? this.getActionColor(step, plan.domain) : 'gray'; const actionIterations = step.getIterations() > 1 ? `${step.getIterations()}x` : ''; const planStep = document.createElement('div'); planStep.id = "plan${planIndex}step${index}"; planStep.className = "planstep"; planStep.style.left = px(fromLeft); planStep.style.top = px(fromTop); const planStepBar = document.createElement('div'); planStepBar.className = "planstep-bar"; planStepBar.title = this.toActionTooltipPlain(step); planStepBar.style.width = px(width); planStepBar.style.backgroundColor = actionColor; const planStepBarRelaxed = document.createElement('div'); planStepBarRelaxed.className = "planstep-bar-relaxed whitecarbon"; planStepBarRelaxed.style.width = px(widthRelaxed); const actionLink = this.toActionLink(step.getActionName(), plan); const text = document.createTextNode(` ${step.getObjects().join(' ')} ${actionIterations}`); planStep.append(planStepBar, planStepBarRelaxed, actionLink, text); ganttDiv.appendChild(planStep); } renderHelpfulActions(ganttDiv, plan, planHeadLength) { var _a; if (plan.hasHelpfulActions()) { const fromTop = planHeadLength * this.planStepHeight; const fromLeft = this.toViewCoordinates(plan.now, plan); const helpfulActions = document.createElement("div"); helpfulActions.className = "planstep"; helpfulActions.style.top = px(fromTop); helpfulActions.style.left = px(fromLeft); helpfulActions.style.marginTop = px(3); const arrow = document.createTextNode(`▶ `); helpfulActions.appendChild(arrow); (_a = plan.helpfulActions) === null || _a === void 0 ? void 0 : _a.forEach((helpfulAction, index) => this.renderHelpfulAction(helpfulActions, index, helpfulAction)); ganttDiv.appendChild(helpfulActions); } } renderHelpfulAction(helpfulActions, index, helpfulAction) { const suffix = PlanView.getActionSuffix(helpfulAction); const beautifiedName = `${helpfulAction.actionName}<sub>${suffix}</sub> `; helpfulActions.appendChild(document.createTextNode(`${index + 1}. `)); const a = document.createElement("a"); a.className = "action"; a.onclick = () => { var _a, _b; return (_b = (_a = this.options).onHelpfulActionSelected) === null || _b === void 0 ? void 0 : _b.call(_a, helpfulAction.actionName); }; a.innerHTML = beautifiedName; helpfulActions.appendChild(a); } static getActionSuffix(helpfulAction) { switch (helpfulAction.kind) { case pddl_workspace_2.HappeningType.START: return '├'; case pddl_workspace_2.HappeningType.END: return '┤'; } return ''; } computeLeftOffset(step, plan) { return this.toViewCoordinates(step.getStartTime(), plan); } /** Converts the _time_ argument to view coordinates */ toViewCoordinates(time, plan) { return (time !== null && time !== void 0 ? time : 0) / (plan.makespan + this.options.epsilon) * this.options.displayWidth; } toActionLink(actionName, plan) { if (this.options.selfContained || !plan.domain) { return document.createTextNode(actionName); } else { const a = document.createElement("a"); a.className = "action"; a.onclick = () => { var _a, _b; return (_b = (_a = this.options).onActionSelected) === null || _b === void 0 ? void 0 : _b.call(_a, actionName); }; a.title = `Reveal '${actionName}' action in the domain file`; a.innerText = actionName; return a; } } toActionTooltip(tooltipHost, step) { var _a, _b; const table = document.createElement("table"); { const tr = document.createElement("tr"); const th = document.createElement("th"); th.className = "actionToolTip"; th.setAttribute("colspan", "" + 2); th.innerText = `${step.getActionName()} ${step.getObjects().join(' ')}`; tr.appendChild(th); table.appendChild(tr); } { const tr = document.createElement("tr"); { const td = document.createElement("td"); td.className = "actionToolTip"; td.style.width = px(50); td.innerText = "Start: "; tr.appendChild(td); } { const td = document.createElement("td"); td.className = "actionToolTip"; td.innerText = `${step.getStartTime().toFixed(exports.DIGITS)}`; tr.appendChild(td); } table.appendChild(tr); } if (step.isDurative && step.getDuration() !== undefined) { { const tr = document.createElement("tr"); { const td = document.createElement("td"); td.className = "actionToolTip"; td.innerText = "Duration: "; tr.appendChild(td); } { const td = document.createElement("td"); td.className = "actionToolTip"; td.innerText = (_b = (_a = step.getDuration()) === null || _a === void 0 ? void 0 : _a.toFixed(exports.DIGITS)) !== null && _b !== void 0 ? _b : ''; tr.appendChild(td); } table.appendChild(tr); } { const tr = document.createElement("tr"); { const td = document.createElement("td"); td.className = "actionToolTip"; td.innerText = "End: "; tr.appendChild(td); } { const td = document.createElement("td"); td.className = "actionToolTip"; td.innerText = step.getEndTime().toFixed(exports.DIGITS); tr.appendChild(td); } table.appendChild(tr); } } tooltipHost.appendChild(table); } toActionTooltipPlain(step) { var _a; const durationRow = step.isDurative && step.getDuration() !== undefined ? `Duration: ${(_a = step.getDuration()) === null || _a === void 0 ? void 0 : _a.toFixed(exports.DIGITS)}, End: ${step.getEndTime().toFixed(exports.DIGITS)}` : ''; const startTime = step.getStartTime() !== undefined ? `, Start: ${step.getStartTime().toFixed(exports.DIGITS)}` : ''; return `${step.getActionName()} ${step.getObjects().join(' ')}${startTime} ${durationRow}`; } computePlanHeadDuration(step, plan) { var _a, _b, _c; if (plan.now === undefined) { return (_a = step.getDuration()) !== null && _a !== void 0 ? _a : this.options.epsilon; } else if (step.getEndTime() < plan.now) { if (step.commitment === undefined || step.commitment === pddl_workspace_2.PlanStepCommitment.Committed) { return (_b = step.getDuration()) !== null && _b !== void 0 ? _b : this.options.epsilon; } else { return 0; } // the end was not committed yet } else if (step.getStartTime() >= plan.now) { return 0; } else { switch (step.commitment) { case undefined: case pddl_workspace_2.PlanStepCommitment.Committed: return (_c = step.getDuration()) !== null && _c !== void 0 ? _c : this.options.epsilon; case pddl_workspace_2.PlanStepCommitment.EndsInRelaxedPlan: return 0; case pddl_workspace_2.PlanStepCommitment.StartsInRelaxedPlan: return plan.now - step.getStartTime(); default: return 0; // should not happen } } } computeWidth(planHeadDuration, plan) { // remove the part of the planStep duration that belongs to the relaxed plan return Math.max(1, this.toViewCoordinates(planHeadDuration, plan)); } computeRelaxedWidth(planHeadDuration, step, plan) { var _a; // remove the part of the planStep duration that belongs to the planhead part const relaxedDuration = ((_a = step.getDuration()) !== null && _a !== void 0 ? _a : this.options.epsilon) - planHeadDuration; return this.toViewCoordinates(relaxedDuration, plan); } isPlanHeadStep(step, timeNow) { return timeNow === undefined || step.commitment === undefined || step.commitment === pddl_workspace_2.PlanStepCommitment.Committed || step.commitment === pddl_workspace_2.PlanStepCommitment.EndsInRelaxedPlan; } static shouldDisplay(planStep, configuration) { var _a; return (_a = configuration === null || configuration === void 0 ? void 0 : configuration.shouldDisplay(planStep)) !== null && _a !== void 0 ? _a : true; } static shouldDisplayObject(step, obj, domain, configuration) { var _a; if (!(PlanView.shouldDisplay(step, configuration))) { return false; } const liftedAction = domain === null || domain === void 0 ? void 0 : domain.getActions().find(a => a.getNameOrEmpty().toLowerCase() === step.getActionName().toLowerCase()); if (!liftedAction) { console.debug('Unexpected plan action: ' + step.getActionName()); return step.getObjects().includes(obj); } let fromArgument = 0; // search from this argument positional index do { const indexOfArgument = step.getObjects().indexOf(obj, fromArgument); fromArgument = indexOfArgument + 1; if (indexOfArgument > -1 && indexOfArgument < liftedAction.parameters.length) { const parameter = liftedAction.parameters[indexOfArgument]; if (!parameter) { console.warn(`Parameter #${indexOfArgument} of action ${liftedAction.getNameOrEmpty()} corresponding to plan step ${step.fullActionName} is null`); return true; } const shouldIgnoreThisArgument = configuration === null || configuration === void 0 ? void 0 : configuration.shouldIgnoreActionParameter((_a = liftedAction.name) !== null && _a !== void 0 ? _a : 'unnamed', parameter.name); if (!shouldIgnoreThisArgument) { return true; } } } while (fromArgument > 0); return false; } getActionColor(step, domain) { const actionIndex = domain === null || domain === void 0 ? void 0 : domain.getActions().findIndex(action => action.getNameOrEmpty().toLowerCase() === step.getActionName().toLowerCase()); if (actionIndex === undefined || actionIndex < 0) { return 'gray'; } else { return this.colors[actionIndex * 7 % this.colors.length]; } } showSwimLanes(swimLanes, plan, configuration) { if (this.options.disableSwimlanes || !plan.domain || !plan.problem) { swimLanes.remove(); return; } const allTypeObjects = plan.domain.getConstants().merge(plan.problem.getObjectsTypeMap()); const table = document.createElement("table"); plan.domain.getTypesInclObject() .filter(type => { var _a, _b; return type !== "object" || ((_b = (_a = allTypeObjects.getTypeCaseInsensitive(type)) === null || _a === void 0 ? void 0 : _a.getObjects().length) !== null && _b !== void 0 ? _b : 0) > 0; }) .forEach(type => { const typeObjects = allTypeObjects.getTypeCaseInsensitive(type); typeObjects && this.renderTypeSwimLanes(table, type, typeObjects.getObjects(), plan, configuration); }); swimLanes.appendChild(table); } renderTypeSwimLanes(table, type, objects, plan, configuration) { const tr = document.createElement("tr"); const tableHeaderTypeName = document.createElement("th"); tableHeaderTypeName.innerText = type; const tableHeaderFill = document.createElement("th"); tableHeaderFill.style.width = px(this.options.displayWidth); tr.append(tableHeaderTypeName, tableHeaderFill); table.appendChild(tr); objects.forEach(obj => this.renderObjectSwimLane(table, obj, plan, configuration)); } renderObjectSwimLane(table, obj, plan, configuration) { const subLanes = new SwimLane_1.SwimLane(1); const tr = document.createElement("tr"); const tdName = document.createElement("td"); tdName.className = "objectName"; tdName.innerText = obj; const tdLane = document.createElement("td"); tdLane.style.position = "relative"; plan.steps .filter(step => PlanView.shouldDisplayObject(step, obj, plan.domain, configuration)) .forEach(step => this.renderSwimLaneStep(tdLane, step, plan, obj, subLanes)); // now size the row appropriately tdLane.style.height = px(subLanes.laneCount() * this.planStepHeight); tr.append(tdName, tdLane); table.appendChild(tr); } renderSwimLaneStep(tdLane, step, plan, thisObj, swimLanes) { const actionColor = this.getActionColor(step, plan.domain); const leftOffset = this.computeLeftOffset(step, plan); const planHeadDuration = this.computePlanHeadDuration(step, plan); const width = this.computeWidth(planHeadDuration, plan) + this.computeRelaxedWidth(planHeadDuration, step, plan); const objects = step.getObjects() .map(obj => obj.toLowerCase() === thisObj.toLowerCase() ? '@' : obj) .join(' '); const availableLane = swimLanes.placeNext(leftOffset, width); const fromTop = availableLane * this.planStepHeight + 1; const div = document.createElement("div"); div.className = "resourceTaskTooltip"; div.style.backgroundColor = actionColor; div.style.left = px(leftOffset); div.style.width = px(width); div.style.top = px(fromTop); const tooltipText = document.createElement("span"); tooltipText.className = "resourceTaskTooltipText"; this.toActionTooltip(tooltipText, step); div.append(`${step.getActionName()} ${objects}`, tooltipText); tdLane.appendChild(div); } /** * Line plots get populated lazily, when they get scrolled to the view. * @param lineCharts line chart element * @param plan plan being displayed */ activateLinePlotPlaceholder(lineCharts, plan) { var _a, _b; if (this.options.disableLinePlots || !plan.domain || !plan.problem) { return; } this.deactivateLinePlotPlaceholder(); if ((0, charts_1.isInViewport)(lineCharts)) { // load charts immediately (_b = (_a = this.options).onLinePlotsVisible) === null || _b === void 0 ? void 0 : _b.call(_a, this); } else { // defer chart loading // show loader this.addLoader(lineCharts); // eslint-disable-next-line @typescript-eslint/no-this-alias const planView = this; const scrollHandler = function handleScrollEvent() { var _a, _b; const lineChartVisible = (0, charts_1.isInViewport)(lineCharts); if (lineChartVisible) { (_b = (_a = planView.options).onLinePlotsVisible) === null || _b === void 0 ? void 0 : _b.call(_a, planView); // unsubscribe the scroll events planView.deactivateLinePlotPlaceholder(); } }; document.addEventListener('scroll', scrollHandler, { passive: true }); document.addEventListener("resize", scrollHandler, { passive: true }); // also sign-up to the mouse over, in case the window gets expanded without the content scrolling lineCharts.addEventListener("mouseenter", scrollHandler); // retain the handler, so it may be cleared along with the plan this.handleScrollEvent = scrollHandler; } } /** Removes the scroll events to avoid generating charts for plans that have been cleared from the view */ deactivateLinePlotPlaceholder() { var _a; if (this.handleScrollEvent !== undefined) { document.removeEventListener("scroll", this.handleScrollEvent); document.removeEventListener("resize", this.handleScrollEvent); (_a = this.lineCharts) === null || _a === void 0 ? void 0 : _a.removeEventListener("mouseenter", this.handleScrollEvent); this.handleScrollEvent = undefined; } } addLoader(lineCharts) { // <div class="loader"></div> if (!lineCharts.querySelector("div.loader")) { // only ever add one loader, even if the scroll handler is activated/deactivated many times const loader = document.createElement("div"); loader.className = "loader"; lineCharts.appendChild(loader); } } hideLinePlotLoadingProgress() { var _a, _b; (_b = (_a = this.lineCharts) === null || _a === void 0 ? void 0 : _a.querySelector(".loader")) === null || _b === void 0 ? void 0 : _b.remove(); } addLinePlot(title, yAxisUnit, objects, data) { var _a; this.linePlotsGenerated = true; const linePlot = document.createElement("div"); linePlot.className = "lineChart"; linePlot.style.width = px(this.options.displayWidth + 100); linePlot.style.height = px(Math.round(this.options.displayWidth / 2)); (_a = this.lineCharts) === null || _a === void 0 ? void 0 : _a.appendChild(linePlot); if (!this.options.selfContained) { (0, charts_1.drawChart)(linePlot, title, yAxisUnit, objects, data); } else { console.error("Line plots are not implemented in self-contained mode."); // todo: lineChartScripts += ` drawChart('${chartDivId}', '${chartTitleWithUnit}', '', ${JSON.stringify(values.legend)}, ${JSON.stringify(values.values)}, ${this.options.displayWidth});\n`; } } } exports.PlanView = PlanView; function px(valueInPx) { return `${valueInPx}px`; } exports.px = px; function createPlanView(hostElementId, options) { const hostElement = getHostElement(hostElementId); return new PlanView(hostElement, 0, options); } exports.createPlanView = createPlanView; function appendPlanView(parent, planIndex, options) { const hostElement = document.createElement('div'); hostElement.setAttribute(exports.ATTR_PLAN, planIndex.toString()); hostElement.className = exports.PLAN_VIEW_CLASS; const planView = new PlanView(hostElement, planIndex, options); parent.appendChild(hostElement); return planView; } exports.appendPlanView = appendPlanView; /** Creates a default domain and problem, if the plan does not have one associated. */ function defaultDomain(plan) { if (plan.domain === undefined && plan.problem === undefined) { const defaultDomain = new pddl_workspace_2.DomainInfo(vscode_uri_1.URI.parse('file:///mock/domain'), 0, 'mock', pddl_workspace_2.parser.PddlSyntaxTree.EMPTY, new pddl_workspace_2.SimpleDocumentPositionResolver('')); const actions = new Set(plan.steps.map(step => toDefaultAction(step))); defaultDomain.setActions([...actions]); defaultDomain.setTypeInheritance(new pddl_workspace_1.utils.DirectionalGraph().addEdge("object")); const defaultProblem = new pddl_workspace_2.ProblemInfo(vscode_uri_1.URI.parse('file:///mock/problem'), 0, 'mock', 'mock', pddl_workspace_2.parser.PddlSyntaxTree.EMPTY, new pddl_workspace_2.SimpleDocumentPositionResolver('')); const objectNames = plan.steps.map(step => step.getObjects()).reduce((prev, curr) => prev.concat(curr), []).sort(); const objectMap = new pddl_workspace_2.TypeObjectMap().addAll('object', objectNames); defaultProblem.setObjects(objectMap); return new pddl_workspace_2.Plan(plan.steps, defaultDomain, defaultProblem, plan.now, plan.helpfulActions); } else { return plan; } } /** Creates a default action from the plan step. */ function toDefaultAction(planStep) { const parameters = planStep.getObjects().map((_o, index) => new pddl_workspace_2.Parameter("p" + index, "object")); if (planStep.isDurative) { return new pddl_workspace_2.DurativeAction(planStep.getActionName(), parameters, pddl_workspace_2.PddlRange.createUnknown(), undefined); } else { return new pddl_workspace_2.InstantAction(planStep.getActionName(), parameters, pddl_workspace_2.PddlRange.createUnknown()); } } //# sourceMappingURL=PlanView.js.map