mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-17 19:24:10 +01:00
Merge remote-tracking branch 'os_repo/5237-unified-layout-common-renderer' into alanaV11
This commit is contained in:
@@ -42,9 +42,6 @@ export const getArrowPoints = (
|
||||
// Padding to use, half of the node padding.
|
||||
const padding = node.padding / 2;
|
||||
|
||||
// Initialize an empty array to store points for the arrow.
|
||||
const points = [];
|
||||
|
||||
if (
|
||||
directions.has('right') &&
|
||||
directions.has('left') &&
|
||||
|
||||
@@ -110,12 +110,13 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
graph.edges().forEach(function (e) {
|
||||
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
});
|
||||
log.info('Graph before layout:', JSON.stringify(graphlibJson.write(graph)));
|
||||
log.info('#############################################');
|
||||
log.info('### Layout ###');
|
||||
log.info('#############################################');
|
||||
log.info(graph);
|
||||
dagreLayout(graph);
|
||||
log.info('Graph after layout:', graphlibJson.write(graph));
|
||||
log.info('Graph after layout:', JSON.stringify(graphlibJson.write(graph)));
|
||||
// Move the nodes to the correct place
|
||||
let diff = 0;
|
||||
const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig);
|
||||
|
||||
@@ -85,7 +85,7 @@ export const draw = async function (
|
||||
}
|
||||
|
||||
// Get color scheme for the graph
|
||||
const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||
// const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||
};
|
||||
|
||||
export default {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import parser from './parser/stateDiagram.jison';
|
||||
import db from './stateDb.js';
|
||||
import styles from './styles.js';
|
||||
//import renderer from './stateRenderer-v2.js';
|
||||
// import renderer from './stateRenderer-v2.js';
|
||||
import renderer from './stateRenderer-v3-unified.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
|
||||
@@ -15,6 +15,9 @@ export const LEVELS: Record<LogLevel, number> = {
|
||||
fatal: 5,
|
||||
};
|
||||
|
||||
console.log('apa');
|
||||
const apa = 1;
|
||||
|
||||
export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
||||
trace: (..._args: any[]) => {},
|
||||
debug: (..._args: any[]) => {},
|
||||
|
||||
@@ -71,7 +71,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||
if (node && node.clusterNode) {
|
||||
// const children = graph.children(v);
|
||||
log.info('Cluster identified XXX', v, node.width, graph.node(v));
|
||||
log.info('Cluster identified XBX', v, node.width, graph.node(v));
|
||||
// "o" will contain the full cluster not just the children
|
||||
const o = await recursiveRender(
|
||||
nodes,
|
||||
@@ -84,7 +84,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
const newEl = o.elem;
|
||||
updateNodeBounds(node, newEl);
|
||||
node.diff = o.diff || 0;
|
||||
log.trace(
|
||||
log.info(
|
||||
'New compound node after recursive render XAX',
|
||||
v,
|
||||
'width',
|
||||
@@ -100,7 +100,15 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
if (graph.children(v).length > 0) {
|
||||
// This is a cluster but not to be rendered recursively
|
||||
// Render as before
|
||||
log.info('Cluster - the non recursive path XXX', v, node.id, node, graph);
|
||||
log.info(
|
||||
'Cluster - the non recursive path XBX',
|
||||
v,
|
||||
node.id,
|
||||
node,
|
||||
node.width,
|
||||
'Graph:',
|
||||
graph
|
||||
);
|
||||
log.info(findNonClusterChild(node.id, graph));
|
||||
clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
|
||||
// insertCluster(clusters, graph.node(v));
|
||||
@@ -130,11 +138,38 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));
|
||||
});
|
||||
|
||||
graph.nodes().map(async function (v) {
|
||||
const node = graph.node(v);
|
||||
log.info(
|
||||
'Position PRE XBX => ' + v + ': (' + node.x,
|
||||
',' + node.y,
|
||||
') width: ',
|
||||
node.width,
|
||||
' height: ',
|
||||
node.height
|
||||
);
|
||||
});
|
||||
|
||||
log.info('Graph before layout:', JSON.stringify(graphlibJson.write(graph)));
|
||||
|
||||
log.info('############################################# XXX');
|
||||
log.info('### Layout ### XXX');
|
||||
log.info('############################################# XXX');
|
||||
|
||||
dagreLayout(graph);
|
||||
log.info('Graph after layout:', JSON.stringify(graphlibJson.write(graph)));
|
||||
|
||||
graph.nodes().map(async function (v) {
|
||||
const node = graph.node(v);
|
||||
log.info(
|
||||
'Position AFTER XBX => ' + v + ': (' + node.x,
|
||||
',' + node.y,
|
||||
') width: ',
|
||||
node.width,
|
||||
' height: ',
|
||||
node.height
|
||||
);
|
||||
});
|
||||
|
||||
log.info('Graph after layout:', graphlibJson.write(graph));
|
||||
// Move the nodes to the correct place
|
||||
@@ -148,7 +183,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
subGraphTitleTotalMargin = p?.offsetY || subGraphTitleTotalMargin;
|
||||
|
||||
log.info(
|
||||
'Position XAX' + v + ': (' + node.x,
|
||||
'Position XBX => ' + v + ': (' + node.x,
|
||||
',' + node.y,
|
||||
') width: ',
|
||||
node.width,
|
||||
@@ -158,11 +193,11 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
if (node && node.clusterNode) {
|
||||
const parentId = graph.parent(v);
|
||||
// Adjust for padding when on root level
|
||||
node.y = parentId ? node.y + 2 : node.y - 8;
|
||||
node.y = parentId ? node.y - 8 : node.y - 8;
|
||||
node.x -= 8;
|
||||
|
||||
log.info(
|
||||
'A pure cluster node XBX',
|
||||
'A tainted cluster node XBX1',
|
||||
v,
|
||||
node.id,
|
||||
node.width,
|
||||
@@ -174,10 +209,21 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
clusterDb[node.id].node = node;
|
||||
// node.y += subGraphTitleTotalMargin - 10;
|
||||
node.y -= (node.offsetY || 0) / 2;
|
||||
// node.y -= 10;
|
||||
positionNode(node);
|
||||
} else {
|
||||
// Non cluster node
|
||||
// A tainted cluster node
|
||||
if (graph.children(v).length > 0) {
|
||||
log.info(
|
||||
'A pure cluster node XBX1',
|
||||
v,
|
||||
node.id,
|
||||
node.x,
|
||||
node.y,
|
||||
node.width,
|
||||
node.height,
|
||||
graph.parent(v)
|
||||
);
|
||||
node.height += 0;
|
||||
const parent = graph.node(node.parentId);
|
||||
const halfPadding = node?.padding / 2 || 0;
|
||||
@@ -190,10 +236,11 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
// A cluster in the non-recursive way
|
||||
clusterDb[node.id].node = node;
|
||||
} else {
|
||||
// Regular node
|
||||
const parent = graph.node(node.parentId);
|
||||
node.y += (parent?.offsetY || 0) / 2;
|
||||
log.info(
|
||||
'A regular node XBX - using the padding',
|
||||
'A regular node XBX1 - using the padding',
|
||||
node.id,
|
||||
'parent',
|
||||
node.parentId,
|
||||
@@ -219,7 +266,8 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
const edge = graph.edge(e);
|
||||
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
|
||||
|
||||
edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2));
|
||||
// OBS HERE
|
||||
// edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2));
|
||||
const startNode = graph.node(e.v);
|
||||
var endNode = graph.node(e.w);
|
||||
const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, startNode, endNode, id);
|
||||
@@ -240,6 +288,9 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
* ###############################################################
|
||||
* Render the graph
|
||||
* ###############################################################
|
||||
* @param data4Layout
|
||||
* @param svg
|
||||
* @param element
|
||||
*/
|
||||
export const render = async (data4Layout, svg, element) => {
|
||||
// Create the input mermaid.graph
|
||||
|
||||
@@ -149,7 +149,7 @@ export const positionEdgeLabel = (edge, paths) => {
|
||||
// // debugger;
|
||||
const pos = utils.calcLabelPosition(path);
|
||||
log.info(
|
||||
'Moving label ' + edge.label + ' from (',
|
||||
'Moving label ' + edge?.id + ' from (',
|
||||
x,
|
||||
',',
|
||||
y,
|
||||
@@ -500,7 +500,7 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, startNod
|
||||
const tail = startNode;
|
||||
var head = endNode;
|
||||
|
||||
// log.info('abc88 InsertEdge SPLIT: ', points, edge.start, id);
|
||||
log.info('abc88 InsertEdge XBX: ', points, edge.start, id);
|
||||
if (head.intersect && tail.intersect) {
|
||||
// log.info('abc88 InsertEdge SPLIT: 0.5', points);
|
||||
points = points.slice(1, edge.points.length - 1);
|
||||
|
||||
@@ -112,8 +112,9 @@ export const clear = () => {
|
||||
export const positionNode = (node) => {
|
||||
const el = nodeElems[node.id];
|
||||
|
||||
log.trace(
|
||||
'Transforming node',
|
||||
log.debug(
|
||||
'Position node',
|
||||
node.id,
|
||||
node.diff,
|
||||
node,
|
||||
'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')'
|
||||
@@ -123,7 +124,7 @@ export const positionNode = (node) => {
|
||||
if (node.clusterNode) {
|
||||
el.attr(
|
||||
'transform',
|
||||
'translate(' + (node.x + diff - node.width / 2) + ', ' + (node.y - node.height / 2) + ')'
|
||||
'translate(' + (node.x - node.width / 2) + ', ' + (node.y - node.height / 2) + ')'
|
||||
);
|
||||
} else {
|
||||
el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
|
||||
|
||||
@@ -6,12 +6,7 @@ import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shape
|
||||
import rough from 'roughjs';
|
||||
|
||||
export const circle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
getNodeClasses(node),
|
||||
true
|
||||
);
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const radius = bbox.width / 2 + halfPadding;
|
||||
let circleElem;
|
||||
|
||||
@@ -50,7 +50,7 @@ export const createInnerCylinderPathD = (
|
||||
return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' ');
|
||||
};
|
||||
export const cylinder = async (parent: SVGAElement, node: Node) => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const rx = w / 2;
|
||||
|
||||
@@ -7,12 +7,7 @@ import rough from 'roughjs';
|
||||
//import d3 from 'd3';
|
||||
|
||||
export const doublecircle = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
getNodeClasses(node),
|
||||
true
|
||||
);
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
const gap = 5;
|
||||
const outerRadius = bbox.width / 2 + halfPadding + gap;
|
||||
const innerRadius = bbox.width / 2 + halfPadding;
|
||||
|
||||
@@ -7,15 +7,9 @@ import rough from 'roughjs';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
|
||||
export const drawRect = async (parent: SVGAElement, node: Node, options: RectOptions) => {
|
||||
const { themeVariables, handdrawnSeed, look } = getConfig();
|
||||
const { nodeBorder, mainBkg } = themeVariables;
|
||||
const { themeVariables, look } = getConfig();
|
||||
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
getNodeClasses(node),
|
||||
true
|
||||
);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const totalWidth = Math.max(bbox.width + options.labelPaddingX * 2, node?.width || 0);
|
||||
const totalHeight = Math.max(bbox.height + options.labelPaddingY * 2, node?.height || 0);
|
||||
@@ -76,7 +70,7 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
|
||||
};
|
||||
|
||||
export const labelRect = async (parent: SVGElement, node: Node) => {
|
||||
const { shapeSvg } = await labelHelper(parent, node, 'label', true);
|
||||
const { shapeSvg } = await labelHelper(parent, node, 'label');
|
||||
|
||||
// log.trace('Classes = ', node.class);
|
||||
// add the rect
|
||||
|
||||
@@ -26,12 +26,7 @@ export const createHexagonPathD = (
|
||||
};
|
||||
|
||||
export const hexagon = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
getNodeClasses(node),
|
||||
true
|
||||
);
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const f = 4;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -23,7 +23,7 @@ export const createInvertedTrapezoidPathD = (
|
||||
};
|
||||
|
||||
export const inv_trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -22,7 +22,7 @@ export const createLeanLeftPathD = (
|
||||
};
|
||||
|
||||
export const lean_left = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -22,7 +22,7 @@ export const createLeanRightPathD = (
|
||||
};
|
||||
|
||||
export const lean_right = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -16,8 +16,7 @@ export const note = async (parent: SVGAElement, node: Node) => {
|
||||
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||
parent,
|
||||
node,
|
||||
'node ' + node.cssClasses,
|
||||
true
|
||||
'node ' + node.cssClasses
|
||||
);
|
||||
|
||||
log.info('Classes = ', node.cssClasses);
|
||||
|
||||
@@ -17,7 +17,7 @@ export const createDecisionBoxPathD = (x: number, y: number, size: number): stri
|
||||
};
|
||||
|
||||
export const question = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -21,7 +21,7 @@ export const rect_left_inv_arrow = async (
|
||||
parent: SVGAElement,
|
||||
node: Node
|
||||
): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Node, RectOptions } from '$root/rendering-util/types.d.ts';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import { select } from 'd3';
|
||||
import { evaluate } from '$root/diagrams/common/common.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import { updateNodeBounds } from './util.js';
|
||||
import createLabel from '../createLabel.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
@@ -52,7 +51,7 @@ export const createStadiumPathD = (
|
||||
};
|
||||
|
||||
export const stadium = async (parent: SVGAElement, node: Node) => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const h = bbox.height + node.padding;
|
||||
const w = bbox.width + h / 4 + node.padding;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
@@ -33,7 +32,7 @@ export const createSubroutinePathD = (
|
||||
};
|
||||
|
||||
export const subroutine = async (parent: SVGAElement, node: Node) => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
const halfPadding = (node?.padding || 0) / 2;
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
@@ -58,7 +57,6 @@ export const subroutine = async (parent: SVGAElement, node: Node) => {
|
||||
// @ts-ignore - rough is not typed
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
const pathData = createSubroutinePathD(-w / 2, -h / 2, w, h);
|
||||
|
||||
const roughNode = rc.rectangle(x - 8, y, w + 16, h, options);
|
||||
const l1 = rc.line(x, y, x, y + h, options);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { log } from '$root/logger.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
@@ -22,7 +21,7 @@ export const createTrapezoidPathD = (
|
||||
};
|
||||
|
||||
export const trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node), true);
|
||||
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
|
||||
|
||||
const w = bbox.width + node.padding;
|
||||
const h = bbox.height + node.padding;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import createLabel from '../createLabel.js';
|
||||
import { createText } from '$root/rendering-util/createText.ts';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import { select } from 'd3';
|
||||
import { evaluate, sanitizeText } from '$root/diagrams/common/common.js';
|
||||
import { decodeEntities } from '$root/utils.js';
|
||||
|
||||
export const labelHelper = async (parent, node, _classes, isNode) => {
|
||||
export const labelHelper = async (parent, node, _classes) => {
|
||||
let cssClasses;
|
||||
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels);
|
||||
if (!_classes) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import config from '../../dist/defaultConfig';
|
||||
import type { MermaidConfig } from '../../dist/config.type';
|
||||
export type MarkdownWordType = 'normal' | 'strong' | 'emphasis';
|
||||
export interface MarkdownWord {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { darken, lighten, adjust, invert, isDark, toRgba } from 'khroma';
|
||||
import { darken, lighten, adjust, invert, isDark } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers.js';
|
||||
import {
|
||||
oldAttributeBackgroundColorEven,
|
||||
|
||||
18273
pnpm-lock.yaml
generated
18273
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user