@canvas-harness/core 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +172 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +172 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4884,7 +4884,7 @@ var drawWithNodeTransform = (ctx, node, fn) => {
|
|
|
4884
4884
|
};
|
|
4885
4885
|
|
|
4886
4886
|
// src/render/renderer.ts
|
|
4887
|
-
var
|
|
4887
|
+
var SCENE_CACHE_MARGIN_PX = 256;
|
|
4888
4888
|
var MIN_ON_SCREEN_SIZE_PX = 1.5;
|
|
4889
4889
|
var MIN_READABLE_FONT_PX = 3;
|
|
4890
4890
|
var createRenderer = (opts) => {
|
|
@@ -4901,6 +4901,30 @@ var createRenderer = (opts) => {
|
|
|
4901
4901
|
let interactiveDirty = false;
|
|
4902
4902
|
let overlaySet = /* @__PURE__ */ new Set();
|
|
4903
4903
|
let lastDrawn = 0;
|
|
4904
|
+
let cacheSurface = null;
|
|
4905
|
+
let cacheCamX = 0;
|
|
4906
|
+
let cacheCamY = 0;
|
|
4907
|
+
let cacheCamZ = 1;
|
|
4908
|
+
let cacheStale = true;
|
|
4909
|
+
const ensureCacheSurface = () => {
|
|
4910
|
+
const dpr = staticSurface.dpr;
|
|
4911
|
+
const cssW = staticSurface.cssWidth + 2 * SCENE_CACHE_MARGIN_PX;
|
|
4912
|
+
const cssH = staticSurface.cssHeight + 2 * SCENE_CACHE_MARGIN_PX;
|
|
4913
|
+
if (!cacheSurface) {
|
|
4914
|
+
const canvas = document.createElement("canvas");
|
|
4915
|
+
const ctx = canvas.getContext("2d");
|
|
4916
|
+
if (!ctx) throw new Error("Canvas 2d context unavailable");
|
|
4917
|
+
cacheSurface = { canvas, ctx, cssWidth: 0, cssHeight: 0, dpr: 1 };
|
|
4918
|
+
}
|
|
4919
|
+
if (cacheSurface.cssWidth !== cssW || cacheSurface.cssHeight !== cssH || cacheSurface.dpr !== dpr) {
|
|
4920
|
+
cacheSurface.cssWidth = cssW;
|
|
4921
|
+
cacheSurface.cssHeight = cssH;
|
|
4922
|
+
cacheSurface.dpr = dpr;
|
|
4923
|
+
cacheSurface.canvas.width = Math.max(1, Math.round(cssW * dpr));
|
|
4924
|
+
cacheSurface.canvas.height = Math.max(1, Math.round(cssH * dpr));
|
|
4925
|
+
}
|
|
4926
|
+
return cacheSurface;
|
|
4927
|
+
};
|
|
4904
4928
|
let sortedNodeIdsCache = null;
|
|
4905
4929
|
let sortedEdgeIdsCache = null;
|
|
4906
4930
|
const invalidateSortedCaches = () => {
|
|
@@ -4909,6 +4933,7 @@ var createRenderer = (opts) => {
|
|
|
4909
4933
|
};
|
|
4910
4934
|
const requestRepaint = () => {
|
|
4911
4935
|
staticDirty = true;
|
|
4936
|
+
cacheStale = true;
|
|
4912
4937
|
loop.requestFrame();
|
|
4913
4938
|
};
|
|
4914
4939
|
const assetCache = createAssetCache({ onReady: requestRepaint });
|
|
@@ -4923,16 +4948,12 @@ var createRenderer = (opts) => {
|
|
|
4923
4948
|
interactiveDirty = false;
|
|
4924
4949
|
}
|
|
4925
4950
|
};
|
|
4926
|
-
const
|
|
4927
|
-
const
|
|
4928
|
-
clearSurface(staticSurface);
|
|
4929
|
-
applyCameraTransform(staticSurface, camera);
|
|
4930
|
-
const scale = camera.z * staticSurface.dpr;
|
|
4951
|
+
const paintSceneBody = (surface, camera, viewport, fullRender = true) => {
|
|
4952
|
+
const scale = camera.z * surface.dpr;
|
|
4931
4953
|
const interaction = store.getInteractionState();
|
|
4932
4954
|
const excludedNodes = interaction.mode === "dragging" || interaction.mode === "resizing" ? new Set(interaction.draggedIds) : null;
|
|
4933
4955
|
const excludedEdges = excludedNodes ? incidentEdgeIds(excludedNodes) : null;
|
|
4934
|
-
|
|
4935
|
-
paintBackground(staticSurface.ctx, { viewport, zoom: camera.z, background });
|
|
4956
|
+
paintBackground(surface.ctx, { viewport, zoom: camera.z, background });
|
|
4936
4957
|
const visible = visibleNodes(camera, viewport);
|
|
4937
4958
|
const isMoving2 = interaction.mode === "panning" || interaction.mode === "zooming" || interaction.mode === "dragging" || interaction.mode === "resizing" || interaction.mode === "rotating";
|
|
4938
4959
|
const minOnScreen = MIN_ON_SCREEN_SIZE_PX;
|
|
@@ -4954,8 +4975,8 @@ var createRenderer = (opts) => {
|
|
|
4954
4975
|
for (const node of visible) {
|
|
4955
4976
|
if (node.type !== "frame") continue;
|
|
4956
4977
|
if (excludedNodes?.has(node.id)) continue;
|
|
4957
|
-
drawWithNodeTransform(
|
|
4958
|
-
paintFrameNode(
|
|
4978
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
4979
|
+
paintFrameNode(surface.ctx, node, scale, theme);
|
|
4959
4980
|
});
|
|
4960
4981
|
drawn++;
|
|
4961
4982
|
}
|
|
@@ -4968,52 +4989,53 @@ var createRenderer = (opts) => {
|
|
|
4968
4989
|
const useRough = roughEnabled && (node.style?.roughness ?? 0) > 0;
|
|
4969
4990
|
const roughReady = useRough ? getRoughCanvasCtor() !== null : false;
|
|
4970
4991
|
const composite = isCompositePrimitive(node.type);
|
|
4971
|
-
drawWithNodeTransform(
|
|
4992
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
4972
4993
|
if (useRough && roughReady) {
|
|
4973
4994
|
if (composite) {
|
|
4974
|
-
drawCompositeRough(
|
|
4995
|
+
drawCompositeRough(surface.ctx, node, camera.z, theme);
|
|
4975
4996
|
} else {
|
|
4976
|
-
|
|
4977
|
-
drawShape(
|
|
4978
|
-
|
|
4979
|
-
drawRoughShape(
|
|
4997
|
+
surface.ctx.translate(ROUGH_FILL_MISREGISTER_X, ROUGH_FILL_MISREGISTER_Y);
|
|
4998
|
+
drawShape(surface.ctx, node, scale, theme, { skipStroke: true });
|
|
4999
|
+
surface.ctx.translate(-ROUGH_FILL_MISREGISTER_X, -ROUGH_FILL_MISREGISTER_Y);
|
|
5000
|
+
drawRoughShape(surface.ctx, node, camera.z, theme);
|
|
4980
5001
|
}
|
|
4981
5002
|
} else {
|
|
4982
|
-
drawShape(
|
|
5003
|
+
drawShape(surface.ctx, node, scale, theme);
|
|
4983
5004
|
if (useRough && !roughReady) {
|
|
4984
5005
|
onRoughReady(() => {
|
|
4985
5006
|
staticDirty = true;
|
|
5007
|
+
cacheStale = true;
|
|
4986
5008
|
loop.requestFrame();
|
|
4987
5009
|
});
|
|
4988
5010
|
}
|
|
4989
5011
|
}
|
|
4990
|
-
if (!isEditingThis) paintNodeContent(
|
|
5012
|
+
if (!isEditingThis) paintNodeContent(surface.ctx, node, renderEnv);
|
|
4991
5013
|
});
|
|
4992
5014
|
drawn++;
|
|
4993
5015
|
continue;
|
|
4994
5016
|
}
|
|
4995
5017
|
if (node.type === "image") {
|
|
4996
|
-
drawWithNodeTransform(
|
|
4997
|
-
paintImageNode(
|
|
5018
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5019
|
+
paintImageNode(surface.ctx, node, assetCache, theme);
|
|
4998
5020
|
});
|
|
4999
5021
|
drawn++;
|
|
5000
5022
|
continue;
|
|
5001
5023
|
}
|
|
5002
5024
|
if (node.type === "icon") {
|
|
5003
|
-
drawWithNodeTransform(
|
|
5004
|
-
paintIconNode(
|
|
5025
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5026
|
+
paintIconNode(surface.ctx, node, assetCache, scale, theme);
|
|
5005
5027
|
});
|
|
5006
5028
|
drawn++;
|
|
5007
5029
|
continue;
|
|
5008
5030
|
}
|
|
5009
5031
|
if (node.type === "text") {
|
|
5010
|
-
drawWithNodeTransform(
|
|
5032
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5011
5033
|
if (isEditingThis) return;
|
|
5012
5034
|
const hasContent = node.content && node.content.trim().length > 0;
|
|
5013
5035
|
if (hasContent) {
|
|
5014
|
-
paintNodeContent(
|
|
5036
|
+
paintNodeContent(surface.ctx, node, renderEnv);
|
|
5015
5037
|
} else {
|
|
5016
|
-
paintEmptyTextPlaceholder(
|
|
5038
|
+
paintEmptyTextPlaceholder(surface.ctx, node, camera.z);
|
|
5017
5039
|
}
|
|
5018
5040
|
});
|
|
5019
5041
|
drawn++;
|
|
@@ -5025,7 +5047,7 @@ var createRenderer = (opts) => {
|
|
|
5025
5047
|
if (camera.z < def.lod.minZoomForPlaceholder) continue;
|
|
5026
5048
|
const preferCanvas = camera.z < def.lod.minZoomForReact || isMoving2;
|
|
5027
5049
|
if (preferCanvas) {
|
|
5028
|
-
if (paintCustomCanvasFallback(
|
|
5050
|
+
if (paintCustomCanvasFallback(surface.ctx, node, def, scale, renderEnv)) {
|
|
5029
5051
|
drawn++;
|
|
5030
5052
|
}
|
|
5031
5053
|
continue;
|
|
@@ -5035,10 +5057,10 @@ var createRenderer = (opts) => {
|
|
|
5035
5057
|
continue;
|
|
5036
5058
|
}
|
|
5037
5059
|
if (def.renderCanvas) {
|
|
5038
|
-
drawWithNodeTransform(
|
|
5039
|
-
|
|
5040
|
-
def.renderCanvas(
|
|
5041
|
-
|
|
5060
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5061
|
+
surface.ctx.save();
|
|
5062
|
+
def.renderCanvas(surface.ctx, node, renderEnv);
|
|
5063
|
+
surface.ctx.restore();
|
|
5042
5064
|
});
|
|
5043
5065
|
drawn++;
|
|
5044
5066
|
}
|
|
@@ -5047,15 +5069,120 @@ var createRenderer = (opts) => {
|
|
|
5047
5069
|
const edgeRoughEnabled = !cameraIsMoving && movingNodeCount <= ROUGH_MAX_MOVING_NODES && camera.z >= ROUGH_MIN_ZOOM && visEdges.length <= ROUGH_MAX_NODES;
|
|
5048
5070
|
for (const edge of visEdges) {
|
|
5049
5071
|
if (excludedEdges?.has(edge.id)) continue;
|
|
5050
|
-
paintOneEdge(
|
|
5072
|
+
paintOneEdge(surface.ctx, edge, scale, edgeRoughEnabled, camera.z, isMoving2);
|
|
5051
5073
|
drawn++;
|
|
5052
5074
|
}
|
|
5075
|
+
if (!fullRender) return;
|
|
5053
5076
|
lastDrawn = drawn;
|
|
5054
5077
|
if (!setsEqual(nextOverlaySet, overlaySet)) {
|
|
5055
5078
|
overlaySet = nextOverlaySet;
|
|
5056
5079
|
onOverlayChange?.([...overlaySet]);
|
|
5057
5080
|
}
|
|
5058
5081
|
};
|
|
5082
|
+
const applyCacheTransform = (cache5, centerX, centerY, z) => {
|
|
5083
|
+
const s = z * cache5.dpr;
|
|
5084
|
+
const m = SCENE_CACHE_MARGIN_PX * cache5.dpr;
|
|
5085
|
+
cache5.ctx.setTransform(s, 0, 0, s, -centerX * s + m, -centerY * s + m);
|
|
5086
|
+
};
|
|
5087
|
+
const renderFullCache = (camera) => {
|
|
5088
|
+
const cache5 = ensureCacheSurface();
|
|
5089
|
+
clearSurface(cache5);
|
|
5090
|
+
applyCacheTransform(cache5, camera.x, camera.y, camera.z);
|
|
5091
|
+
const marginWorld = SCENE_CACHE_MARGIN_PX / camera.z;
|
|
5092
|
+
const viewport = inflateRect(worldViewport(staticSurface, camera), marginWorld);
|
|
5093
|
+
paintSceneBody(cache5, camera, viewport);
|
|
5094
|
+
cacheCamX = camera.x;
|
|
5095
|
+
cacheCamY = camera.y;
|
|
5096
|
+
cacheCamZ = camera.z;
|
|
5097
|
+
cacheStale = false;
|
|
5098
|
+
};
|
|
5099
|
+
const canExtend = (camera) => {
|
|
5100
|
+
if (!cacheSurface) return false;
|
|
5101
|
+
const s = camera.z * staticSurface.dpr;
|
|
5102
|
+
const dx = Math.abs((cacheCamX - camera.x) * s);
|
|
5103
|
+
const dy = Math.abs((cacheCamY - camera.y) * s);
|
|
5104
|
+
return dx < cacheSurface.canvas.width && dy < cacheSurface.canvas.height;
|
|
5105
|
+
};
|
|
5106
|
+
const renderCacheStrip = (cache5, centerX, centerY, z, px, py, pw, ph) => {
|
|
5107
|
+
const ctx = cache5.ctx;
|
|
5108
|
+
const s = z * cache5.dpr;
|
|
5109
|
+
const m = SCENE_CACHE_MARGIN_PX * cache5.dpr;
|
|
5110
|
+
ctx.save();
|
|
5111
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5112
|
+
ctx.beginPath();
|
|
5113
|
+
ctx.rect(px, py, pw, ph);
|
|
5114
|
+
ctx.clip();
|
|
5115
|
+
ctx.clearRect(px, py, pw, ph);
|
|
5116
|
+
applyCacheTransform(cache5, centerX, centerY, z);
|
|
5117
|
+
const viewport = {
|
|
5118
|
+
x: (px - m) / s + centerX,
|
|
5119
|
+
y: (py - m) / s + centerY,
|
|
5120
|
+
w: pw / s,
|
|
5121
|
+
h: ph / s
|
|
5122
|
+
};
|
|
5123
|
+
paintSceneBody(cache5, { z }, viewport, false);
|
|
5124
|
+
ctx.restore();
|
|
5125
|
+
};
|
|
5126
|
+
const extendCache = (camera) => {
|
|
5127
|
+
const cache5 = ensureCacheSurface();
|
|
5128
|
+
const s = camera.z * cache5.dpr;
|
|
5129
|
+
const cacheW = cache5.canvas.width;
|
|
5130
|
+
const cacheH = cache5.canvas.height;
|
|
5131
|
+
const dx = Math.round((cacheCamX - camera.x) * s);
|
|
5132
|
+
const dy = Math.round((cacheCamY - camera.y) * s);
|
|
5133
|
+
const newCamX = cacheCamX - dx / s;
|
|
5134
|
+
const newCamY = cacheCamY - dy / s;
|
|
5135
|
+
cache5.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5136
|
+
cache5.ctx.drawImage(cache5.canvas, 0, 0, cacheW, cacheH, dx, dy, cacheW, cacheH);
|
|
5137
|
+
cacheCamX = newCamX;
|
|
5138
|
+
cacheCamY = newCamY;
|
|
5139
|
+
cacheCamZ = camera.z;
|
|
5140
|
+
const hw = Math.abs(dx);
|
|
5141
|
+
const vh = Math.abs(dy);
|
|
5142
|
+
const hx = dx > 0 ? 0 : cacheW - hw;
|
|
5143
|
+
const vy = dy > 0 ? 0 : cacheH - vh;
|
|
5144
|
+
const vx = dx > 0 ? hw : 0;
|
|
5145
|
+
const vw = cacheW - hw;
|
|
5146
|
+
if (hw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, hx, 0, hw, cacheH);
|
|
5147
|
+
if (vh > 0 && vw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, vx, vy, vw, vh);
|
|
5148
|
+
};
|
|
5149
|
+
const cacheSourceOffset = (camera) => {
|
|
5150
|
+
const dpr = staticSurface.dpr;
|
|
5151
|
+
return {
|
|
5152
|
+
x: Math.round(((camera.x - cacheCamX) * cacheCamZ + SCENE_CACHE_MARGIN_PX) * dpr),
|
|
5153
|
+
y: Math.round(((camera.y - cacheCamY) * cacheCamZ + SCENE_CACHE_MARGIN_PX) * dpr)
|
|
5154
|
+
};
|
|
5155
|
+
};
|
|
5156
|
+
const viewportFitsInCache = (camera) => {
|
|
5157
|
+
if (!cacheSurface) return false;
|
|
5158
|
+
const { x, y } = cacheSourceOffset(camera);
|
|
5159
|
+
return x >= 0 && y >= 0 && x + staticSurface.canvas.width <= cacheSurface.canvas.width && y + staticSurface.canvas.height <= cacheSurface.canvas.height;
|
|
5160
|
+
};
|
|
5161
|
+
const presentStatic = (camera) => {
|
|
5162
|
+
const cache5 = ensureCacheSurface();
|
|
5163
|
+
const w = staticSurface.canvas.width;
|
|
5164
|
+
const h = staticSurface.canvas.height;
|
|
5165
|
+
const { x: srcX, y: srcY } = cacheSourceOffset(camera);
|
|
5166
|
+
staticSurface.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5167
|
+
staticSurface.ctx.clearRect(0, 0, w, h);
|
|
5168
|
+
staticSurface.ctx.drawImage(cache5.canvas, srcX, srcY, w, h, 0, 0, w, h);
|
|
5169
|
+
};
|
|
5170
|
+
const paintStatic = () => {
|
|
5171
|
+
const camera = store.getCamera();
|
|
5172
|
+
if (!cacheStale && camera.z === cacheCamZ) {
|
|
5173
|
+
if (viewportFitsInCache(camera)) {
|
|
5174
|
+
presentStatic(camera);
|
|
5175
|
+
return;
|
|
5176
|
+
}
|
|
5177
|
+
if (canExtend(camera)) {
|
|
5178
|
+
extendCache(camera);
|
|
5179
|
+
presentStatic(camera);
|
|
5180
|
+
return;
|
|
5181
|
+
}
|
|
5182
|
+
}
|
|
5183
|
+
renderFullCache(camera);
|
|
5184
|
+
presentStatic(camera);
|
|
5185
|
+
};
|
|
5059
5186
|
const paintCustomCanvasFallback = (ctx, node, def, drawScale, env) => {
|
|
5060
5187
|
if (def.getSnapshot) {
|
|
5061
5188
|
const snap = def.getSnapshot(node, {
|
|
@@ -5340,6 +5467,7 @@ var createRenderer = (opts) => {
|
|
|
5340
5467
|
const onStoreChange = () => {
|
|
5341
5468
|
invalidateSortedCaches();
|
|
5342
5469
|
staticDirty = true;
|
|
5470
|
+
cacheStale = true;
|
|
5343
5471
|
interactiveDirty = true;
|
|
5344
5472
|
loop.requestFrame();
|
|
5345
5473
|
};
|
|
@@ -5356,6 +5484,7 @@ var createRenderer = (opts) => {
|
|
|
5356
5484
|
interactiveDirty = true;
|
|
5357
5485
|
if (state.mode === "dragging" || state.mode === "resizing" || state.mode === "rotating" || state.mode === "panning" || state.mode === "zooming" || state.mode === "idle") {
|
|
5358
5486
|
staticDirty = true;
|
|
5487
|
+
cacheStale = true;
|
|
5359
5488
|
}
|
|
5360
5489
|
loop.requestFrame();
|
|
5361
5490
|
};
|
|
@@ -5365,16 +5494,19 @@ var createRenderer = (opts) => {
|
|
|
5365
5494
|
const unsubInteraction = store.subscribe("interaction", onInteractionChange);
|
|
5366
5495
|
const unsubFontEpoch = subscribeFontEpoch(() => {
|
|
5367
5496
|
staticDirty = true;
|
|
5497
|
+
cacheStale = true;
|
|
5368
5498
|
loop.requestFrame();
|
|
5369
5499
|
});
|
|
5370
5500
|
const unsubMathEpoch = subscribeMathEpoch(() => {
|
|
5371
5501
|
staticDirty = true;
|
|
5502
|
+
cacheStale = true;
|
|
5372
5503
|
loop.requestFrame();
|
|
5373
5504
|
});
|
|
5374
5505
|
return {
|
|
5375
5506
|
start() {
|
|
5376
5507
|
loop.start();
|
|
5377
5508
|
staticDirty = true;
|
|
5509
|
+
cacheStale = true;
|
|
5378
5510
|
interactiveDirty = isInteractive(store.getInteractionState());
|
|
5379
5511
|
loop.requestFrame();
|
|
5380
5512
|
},
|
|
@@ -5383,6 +5515,7 @@ var createRenderer = (opts) => {
|
|
|
5383
5515
|
},
|
|
5384
5516
|
invalidate() {
|
|
5385
5517
|
staticDirty = true;
|
|
5518
|
+
cacheStale = true;
|
|
5386
5519
|
interactiveDirty = true;
|
|
5387
5520
|
loop.requestFrame();
|
|
5388
5521
|
},
|
|
@@ -5391,6 +5524,7 @@ var createRenderer = (opts) => {
|
|
|
5391
5524
|
const b = sizeSurface(interactiveSurface, cssW, cssH, maxDpr);
|
|
5392
5525
|
if (a || b) {
|
|
5393
5526
|
staticDirty = true;
|
|
5527
|
+
cacheStale = true;
|
|
5394
5528
|
interactiveDirty = true;
|
|
5395
5529
|
loop.requestFrame();
|
|
5396
5530
|
}
|
|
@@ -5398,6 +5532,7 @@ var createRenderer = (opts) => {
|
|
|
5398
5532
|
setBackground(bg) {
|
|
5399
5533
|
background = bg;
|
|
5400
5534
|
staticDirty = true;
|
|
5535
|
+
cacheStale = true;
|
|
5401
5536
|
loop.requestFrame();
|
|
5402
5537
|
},
|
|
5403
5538
|
setSelectionColor(color) {
|
|
@@ -5408,6 +5543,7 @@ var createRenderer = (opts) => {
|
|
|
5408
5543
|
setHideFrames(hidden) {
|
|
5409
5544
|
hideFrames = hidden;
|
|
5410
5545
|
staticDirty = true;
|
|
5546
|
+
cacheStale = true;
|
|
5411
5547
|
loop.requestFrame();
|
|
5412
5548
|
},
|
|
5413
5549
|
stats: () => loop.stats(),
|
|
@@ -5422,6 +5558,11 @@ var createRenderer = (opts) => {
|
|
|
5422
5558
|
unsubFontEpoch();
|
|
5423
5559
|
unsubMathEpoch();
|
|
5424
5560
|
assetCache.dispose();
|
|
5561
|
+
if (cacheSurface) {
|
|
5562
|
+
cacheSurface.canvas.width = 0;
|
|
5563
|
+
cacheSurface.canvas.height = 0;
|
|
5564
|
+
cacheSurface = null;
|
|
5565
|
+
}
|
|
5425
5566
|
}
|
|
5426
5567
|
};
|
|
5427
5568
|
};
|