Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js

Issue 2493373002: DevTools: rename WebInspector into modules. (Closed)
Patch Set: for bots Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 /** 31 /**
32 * @unrestricted 32 * @unrestricted
33 */ 33 */
34 WebInspector.OverviewGrid = class { 34 UI.OverviewGrid = class {
35 /** 35 /**
36 * @param {string} prefix 36 * @param {string} prefix
37 */ 37 */
38 constructor(prefix) { 38 constructor(prefix) {
39 this.element = createElement('div'); 39 this.element = createElement('div');
40 this.element.id = prefix + '-overview-container'; 40 this.element.id = prefix + '-overview-container';
41 41
42 this._grid = new WebInspector.TimelineGrid(); 42 this._grid = new UI.TimelineGrid();
43 this._grid.element.id = prefix + '-overview-grid'; 43 this._grid.element.id = prefix + '-overview-grid';
44 this._grid.setScrollTop(0); 44 this._grid.setScrollTop(0);
45 45
46 this.element.appendChild(this._grid.element); 46 this.element.appendChild(this._grid.element);
47 47
48 this._window = new WebInspector.OverviewGrid.Window(this.element, this._grid .dividersLabelBarElement); 48 this._window = new UI.OverviewGrid.Window(this.element, this._grid.dividersL abelBarElement);
49 } 49 }
50 50
51 /** 51 /**
52 * @return {number} 52 * @return {number}
53 */ 53 */
54 clientWidth() { 54 clientWidth() {
55 return this.element.clientWidth; 55 return this.element.clientWidth;
56 } 56 }
57 57
58 /** 58 /**
59 * @param {!WebInspector.TimelineGrid.Calculator} calculator 59 * @param {!UI.TimelineGrid.Calculator} calculator
60 */ 60 */
61 updateDividers(calculator) { 61 updateDividers(calculator) {
62 this._grid.updateDividers(calculator); 62 this._grid.updateDividers(calculator);
63 } 63 }
64 64
65 /** 65 /**
66 * @param {!Array.<!Element>} dividers 66 * @param {!Array.<!Element>} dividers
67 */ 67 */
68 addEventDividers(dividers) { 68 addEventDividers(dividers) {
69 this._grid.addEventDividers(dividers); 69 this._grid.addEventDividers(dividers);
(...skipping 24 matching lines...) Expand all
94 /** 94 /**
95 * @param {number} left 95 * @param {number} left
96 * @param {number} right 96 * @param {number} right
97 */ 97 */
98 setWindow(left, right) { 98 setWindow(left, right) {
99 this._window._setWindow(left, right); 99 this._window._setWindow(left, right);
100 } 100 }
101 101
102 /** 102 /**
103 * @param {string} eventType 103 * @param {string} eventType
104 * @param {function(!WebInspector.Event)} listener 104 * @param {function(!Common.Event)} listener
105 * @param {!Object=} thisObject 105 * @param {!Object=} thisObject
106 * @return {!WebInspector.EventTarget.EventDescriptor} 106 * @return {!Common.EventTarget.EventDescriptor}
107 */ 107 */
108 addEventListener(eventType, listener, thisObject) { 108 addEventListener(eventType, listener, thisObject) {
109 return this._window.addEventListener(eventType, listener, thisObject); 109 return this._window.addEventListener(eventType, listener, thisObject);
110 } 110 }
111 111
112 /** 112 /**
113 * @param {number} zoomFactor 113 * @param {number} zoomFactor
114 * @param {number} referencePoint 114 * @param {number} referencePoint
115 */ 115 */
116 zoom(zoomFactor, referencePoint) { 116 zoom(zoomFactor, referencePoint) {
117 this._window._zoom(zoomFactor, referencePoint); 117 this._window._zoom(zoomFactor, referencePoint);
118 } 118 }
119 119
120 /** 120 /**
121 * @param {boolean} enabled 121 * @param {boolean} enabled
122 */ 122 */
123 setResizeEnabled(enabled) { 123 setResizeEnabled(enabled) {
124 this._window.setEnabled(enabled); 124 this._window.setEnabled(enabled);
125 } 125 }
126 }; 126 };
127 127
128 WebInspector.OverviewGrid.MinSelectableSize = 14; 128 UI.OverviewGrid.MinSelectableSize = 14;
129 129
130 WebInspector.OverviewGrid.WindowScrollSpeedFactor = .3; 130 UI.OverviewGrid.WindowScrollSpeedFactor = .3;
131 131
132 WebInspector.OverviewGrid.ResizerOffset = 3.5; // half pixel because offset val ues are not rounded but ceiled 132 UI.OverviewGrid.ResizerOffset = 3.5; // half pixel because offset values are no t rounded but ceiled
133 133
134 /** 134 /**
135 * @unrestricted 135 * @unrestricted
136 */ 136 */
137 WebInspector.OverviewGrid.Window = class extends WebInspector.Object { 137 UI.OverviewGrid.Window = class extends Common.Object {
138 /** 138 /**
139 * @param {!Element} parentElement 139 * @param {!Element} parentElement
140 * @param {!Element=} dividersLabelBarElement 140 * @param {!Element=} dividersLabelBarElement
141 */ 141 */
142 constructor(parentElement, dividersLabelBarElement) { 142 constructor(parentElement, dividersLabelBarElement) {
143 super(); 143 super();
144 this._parentElement = parentElement; 144 this._parentElement = parentElement;
145 145
146 WebInspector.installDragHandle( 146 UI.installDragHandle(
147 this._parentElement, this._startWindowSelectorDragging.bind(this), this. _windowSelectorDragging.bind(this), 147 this._parentElement, this._startWindowSelectorDragging.bind(this), this. _windowSelectorDragging.bind(this),
148 this._endWindowSelectorDragging.bind(this), 'text', null); 148 this._endWindowSelectorDragging.bind(this), 'text', null);
149 if (dividersLabelBarElement) 149 if (dividersLabelBarElement)
150 WebInspector.installDragHandle( 150 UI.installDragHandle(
151 dividersLabelBarElement, this._startWindowDragging.bind(this), this._w indowDragging.bind(this), null, 151 dividersLabelBarElement, this._startWindowDragging.bind(this), this._w indowDragging.bind(this), null,
152 '-webkit-grabbing', '-webkit-grab'); 152 '-webkit-grabbing', '-webkit-grab');
153 153
154 this._parentElement.addEventListener('mousewheel', this._onMouseWheel.bind(t his), true); 154 this._parentElement.addEventListener('mousewheel', this._onMouseWheel.bind(t his), true);
155 this._parentElement.addEventListener('dblclick', this._resizeWindowMaximum.b ind(this), true); 155 this._parentElement.addEventListener('dblclick', this._resizeWindowMaximum.b ind(this), true);
156 WebInspector.appendStyle(this._parentElement, 'ui_lazy/overviewGrid.css'); 156 UI.appendStyle(this._parentElement, 'ui_lazy/overviewGrid.css');
157 157
158 this._leftResizeElement = parentElement.createChild('div', 'overview-grid-wi ndow-resizer'); 158 this._leftResizeElement = parentElement.createChild('div', 'overview-grid-wi ndow-resizer');
159 WebInspector.installDragHandle( 159 UI.installDragHandle(
160 this._leftResizeElement, this._resizerElementStartDragging.bind(this), 160 this._leftResizeElement, this._resizerElementStartDragging.bind(this),
161 this._leftResizeElementDragging.bind(this), null, 'ew-resize'); 161 this._leftResizeElementDragging.bind(this), null, 'ew-resize');
162 this._rightResizeElement = parentElement.createChild('div', 'overview-grid-w indow-resizer'); 162 this._rightResizeElement = parentElement.createChild('div', 'overview-grid-w indow-resizer');
163 WebInspector.installDragHandle( 163 UI.installDragHandle(
164 this._rightResizeElement, this._resizerElementStartDragging.bind(this), 164 this._rightResizeElement, this._resizerElementStartDragging.bind(this),
165 this._rightResizeElementDragging.bind(this), null, 'ew-resize'); 165 this._rightResizeElementDragging.bind(this), null, 'ew-resize');
166 166
167 this._leftCurtainElement = parentElement.createChild('div', 'window-curtain- left'); 167 this._leftCurtainElement = parentElement.createChild('div', 'window-curtain- left');
168 this._rightCurtainElement = parentElement.createChild('div', 'window-curtain -right'); 168 this._rightCurtainElement = parentElement.createChild('div', 'window-curtain -right');
169 this.reset(); 169 this.reset();
170 } 170 }
171 171
172 reset() { 172 reset() {
173 this.windowLeft = 0.0; 173 this.windowLeft = 0.0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 212
213 /** 213 /**
214 * @param {!Event} event 214 * @param {!Event} event
215 * @return {boolean} 215 * @return {boolean}
216 */ 216 */
217 _startWindowSelectorDragging(event) { 217 _startWindowSelectorDragging(event) {
218 if (!this._enabled) 218 if (!this._enabled)
219 return false; 219 return false;
220 this._offsetLeft = this._parentElement.totalOffsetLeft(); 220 this._offsetLeft = this._parentElement.totalOffsetLeft();
221 var position = event.x - this._offsetLeft; 221 var position = event.x - this._offsetLeft;
222 this._overviewWindowSelector = new WebInspector.OverviewGrid.WindowSelector( this._parentElement, position); 222 this._overviewWindowSelector = new UI.OverviewGrid.WindowSelector(this._pare ntElement, position);
223 return true; 223 return true;
224 } 224 }
225 225
226 /** 226 /**
227 * @param {!Event} event 227 * @param {!Event} event
228 */ 228 */
229 _windowSelectorDragging(event) { 229 _windowSelectorDragging(event) {
230 this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft); 230 this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft);
231 event.preventDefault(); 231 event.preventDefault();
232 } 232 }
233 233
234 /** 234 /**
235 * @param {!Event} event 235 * @param {!Event} event
236 */ 236 */
237 _endWindowSelectorDragging(event) { 237 _endWindowSelectorDragging(event) {
238 var window = this._overviewWindowSelector._close(event.x - this._offsetLeft) ; 238 var window = this._overviewWindowSelector._close(event.x - this._offsetLeft) ;
239 delete this._overviewWindowSelector; 239 delete this._overviewWindowSelector;
240 var clickThreshold = 3; 240 var clickThreshold = 3;
241 if (window.end - window.start < clickThreshold) { 241 if (window.end - window.start < clickThreshold) {
242 if (this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.Click, event)) 242 if (this.dispatchEventToListeners(UI.OverviewGrid.Events.Click, event))
243 return; 243 return;
244 var middle = window.end; 244 var middle = window.end;
245 window.start = Math.max(0, middle - WebInspector.OverviewGrid.MinSelectabl eSize / 2); 245 window.start = Math.max(0, middle - UI.OverviewGrid.MinSelectableSize / 2) ;
246 window.end = Math.min(this._parentElement.clientWidth, middle + WebInspect or.OverviewGrid.MinSelectableSize / 2); 246 window.end = Math.min(this._parentElement.clientWidth, middle + UI.Overvie wGrid.MinSelectableSize / 2);
247 } else if (window.end - window.start < WebInspector.OverviewGrid.MinSelectab leSize) { 247 } else if (window.end - window.start < UI.OverviewGrid.MinSelectableSize) {
248 if (this._parentElement.clientWidth - window.end > WebInspector.OverviewGr id.MinSelectableSize) 248 if (this._parentElement.clientWidth - window.end > UI.OverviewGrid.MinSele ctableSize)
249 window.end = window.start + WebInspector.OverviewGrid.MinSelectableSize; 249 window.end = window.start + UI.OverviewGrid.MinSelectableSize;
250 else 250 else
251 window.start = window.end - WebInspector.OverviewGrid.MinSelectableSize; 251 window.start = window.end - UI.OverviewGrid.MinSelectableSize;
252 } 252 }
253 this._setWindowPosition(window.start, window.end); 253 this._setWindowPosition(window.start, window.end);
254 } 254 }
255 255
256 /** 256 /**
257 * @param {!Event} event 257 * @param {!Event} event
258 * @return {boolean} 258 * @return {boolean}
259 */ 259 */
260 _startWindowDragging(event) { 260 _startWindowDragging(event) {
261 this._dragStartPoint = event.pageX; 261 this._dragStartPoint = event.pageX;
(...skipping 30 matching lines...) Expand all
292 this._setWindowPosition(start, null); 292 this._setWindowPosition(start, null);
293 } 293 }
294 294
295 /** 295 /**
296 * @param {number} end 296 * @param {number} end
297 */ 297 */
298 _resizeWindowRight(end) { 298 _resizeWindowRight(end) {
299 // Glue to edge. 299 // Glue to edge.
300 if (end > this._parentElement.clientWidth - 10) 300 if (end > this._parentElement.clientWidth - 10)
301 end = this._parentElement.clientWidth; 301 end = this._parentElement.clientWidth;
302 else if (end < this._leftResizeElement.offsetLeft + WebInspector.OverviewGri d.MinSelectableSize) 302 else if (end < this._leftResizeElement.offsetLeft + UI.OverviewGrid.MinSelec tableSize)
303 end = this._leftResizeElement.offsetLeft + WebInspector.OverviewGrid.MinSe lectableSize; 303 end = this._leftResizeElement.offsetLeft + UI.OverviewGrid.MinSelectableSi ze;
304 this._setWindowPosition(null, end); 304 this._setWindowPosition(null, end);
305 } 305 }
306 306
307 _resizeWindowMaximum() { 307 _resizeWindowMaximum() {
308 this._setWindowPosition(0, this._parentElement.clientWidth); 308 this._setWindowPosition(0, this._parentElement.clientWidth);
309 } 309 }
310 310
311 /** 311 /**
312 * @param {number} windowLeft 312 * @param {number} windowLeft
313 * @param {number} windowRight 313 * @param {number} windowRight
314 */ 314 */
315 _setWindow(windowLeft, windowRight) { 315 _setWindow(windowLeft, windowRight) {
316 this.windowLeft = windowLeft; 316 this.windowLeft = windowLeft;
317 this.windowRight = windowRight; 317 this.windowRight = windowRight;
318 this._updateCurtains(); 318 this._updateCurtains();
319 this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged ); 319 this.dispatchEventToListeners(UI.OverviewGrid.Events.WindowChanged);
320 } 320 }
321 321
322 _updateCurtains() { 322 _updateCurtains() {
323 var left = this.windowLeft; 323 var left = this.windowLeft;
324 var right = this.windowRight; 324 var right = this.windowRight;
325 var width = right - left; 325 var width = right - left;
326 326
327 // We allow actual time window to be arbitrarily small but don't want the UI window to be too small. 327 // We allow actual time window to be arbitrarily small but don't want the UI window to be too small.
328 var widthInPixels = width * this._parentElement.clientWidth; 328 var widthInPixels = width * this._parentElement.clientWidth;
329 var minWidthInPixels = WebInspector.OverviewGrid.MinSelectableSize / 2; 329 var minWidthInPixels = UI.OverviewGrid.MinSelectableSize / 2;
330 if (widthInPixels < minWidthInPixels) { 330 if (widthInPixels < minWidthInPixels) {
331 var factor = minWidthInPixels / widthInPixels; 331 var factor = minWidthInPixels / widthInPixels;
332 left = ((this.windowRight + this.windowLeft) - width * factor) / 2; 332 left = ((this.windowRight + this.windowLeft) - width * factor) / 2;
333 right = ((this.windowRight + this.windowLeft) + width * factor) / 2; 333 right = ((this.windowRight + this.windowLeft) + width * factor) / 2;
334 } 334 }
335 this._leftResizeElement.style.left = (100 * left).toFixed(2) + '%'; 335 this._leftResizeElement.style.left = (100 * left).toFixed(2) + '%';
336 this._rightResizeElement.style.left = (100 * right).toFixed(2) + '%'; 336 this._rightResizeElement.style.left = (100 * right).toFixed(2) + '%';
337 337
338 this._leftCurtainElement.style.width = (100 * left).toFixed(2) + '%'; 338 this._leftCurtainElement.style.width = (100 * left).toFixed(2) + '%';
339 this._rightCurtainElement.style.width = (100 * (1 - right)).toFixed(2) + '%' ; 339 this._rightCurtainElement.style.width = (100 * (1 - right)).toFixed(2) + '%' ;
(...skipping 17 matching lines...) Expand all
357 if (!this._enabled) 357 if (!this._enabled)
358 return; 358 return;
359 if (typeof event.wheelDeltaY === 'number' && event.wheelDeltaY) { 359 if (typeof event.wheelDeltaY === 'number' && event.wheelDeltaY) {
360 const zoomFactor = 1.1; 360 const zoomFactor = 1.1;
361 const mouseWheelZoomSpeed = 1 / 120; 361 const mouseWheelZoomSpeed = 1 / 120;
362 362
363 var reference = event.offsetX / event.target.clientWidth; 363 var reference = event.offsetX / event.target.clientWidth;
364 this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference); 364 this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference);
365 } 365 }
366 if (typeof event.wheelDeltaX === 'number' && event.wheelDeltaX) { 366 if (typeof event.wheelDeltaX === 'number' && event.wheelDeltaX) {
367 var offset = Math.round(event.wheelDeltaX * WebInspector.OverviewGrid.Wind owScrollSpeedFactor); 367 var offset = Math.round(event.wheelDeltaX * UI.OverviewGrid.WindowScrollSp eedFactor);
368 var windowLeft = this._leftResizeElement.offsetLeft + WebInspector.Overvie wGrid.ResizerOffset; 368 var windowLeft = this._leftResizeElement.offsetLeft + UI.OverviewGrid.Resi zerOffset;
369 var windowRight = this._rightResizeElement.offsetLeft + WebInspector.Overv iewGrid.ResizerOffset; 369 var windowRight = this._rightResizeElement.offsetLeft + UI.OverviewGrid.Re sizerOffset;
370 370
371 if (windowLeft - offset < 0) 371 if (windowLeft - offset < 0)
372 offset = windowLeft; 372 offset = windowLeft;
373 373
374 if (windowRight - offset > this._parentElement.clientWidth) 374 if (windowRight - offset > this._parentElement.clientWidth)
375 offset = windowRight - this._parentElement.clientWidth; 375 offset = windowRight - this._parentElement.clientWidth;
376 376
377 this._setWindowPosition(windowLeft - offset, windowRight - offset); 377 this._setWindowPosition(windowLeft - offset, windowRight - offset);
378 378
379 event.preventDefault(); 379 event.preventDefault();
(...skipping 16 matching lines...) Expand all
396 left = reference + (left - reference) * factor; 396 left = reference + (left - reference) * factor;
397 left = Number.constrain(left, 0, 1 - newWindowSize); 397 left = Number.constrain(left, 0, 1 - newWindowSize);
398 398
399 right = reference + (right - reference) * factor; 399 right = reference + (right - reference) * factor;
400 right = Number.constrain(right, newWindowSize, 1); 400 right = Number.constrain(right, newWindowSize, 1);
401 this._setWindow(left, right); 401 this._setWindow(left, right);
402 } 402 }
403 }; 403 };
404 404
405 /** @enum {symbol} */ 405 /** @enum {symbol} */
406 WebInspector.OverviewGrid.Events = { 406 UI.OverviewGrid.Events = {
407 WindowChanged: Symbol('WindowChanged'), 407 WindowChanged: Symbol('WindowChanged'),
408 Click: Symbol('Click') 408 Click: Symbol('Click')
409 }; 409 };
410 410
411 /** 411 /**
412 * @unrestricted 412 * @unrestricted
413 */ 413 */
414 WebInspector.OverviewGrid.WindowSelector = class { 414 UI.OverviewGrid.WindowSelector = class {
415 constructor(parent, position) { 415 constructor(parent, position) {
416 this._startPosition = position; 416 this._startPosition = position;
417 this._width = parent.offsetWidth; 417 this._width = parent.offsetWidth;
418 this._windowSelector = createElement('div'); 418 this._windowSelector = createElement('div');
419 this._windowSelector.className = 'overview-grid-window-selector'; 419 this._windowSelector.className = 'overview-grid-window-selector';
420 this._windowSelector.style.left = this._startPosition + 'px'; 420 this._windowSelector.style.left = this._startPosition + 'px';
421 this._windowSelector.style.right = this._width - this._startPosition + 'px'; 421 this._windowSelector.style.right = this._width - this._startPosition + 'px';
422 parent.appendChild(this._windowSelector); 422 parent.appendChild(this._windowSelector);
423 } 423 }
424 424
425 _close(position) { 425 _close(position) {
426 position = Math.max(0, Math.min(position, this._width)); 426 position = Math.max(0, Math.min(position, this._width));
427 this._windowSelector.remove(); 427 this._windowSelector.remove();
428 return this._startPosition < position ? {start: this._startPosition, end: po sition} : 428 return this._startPosition < position ? {start: this._startPosition, end: po sition} :
429 {start: position, end: this._startPo sition}; 429 {start: position, end: this._startPo sition};
430 } 430 }
431 431
432 _updatePosition(position) { 432 _updatePosition(position) {
433 position = Math.max(0, Math.min(position, this._width)); 433 position = Math.max(0, Math.min(position, this._width));
434 if (position < this._startPosition) { 434 if (position < this._startPosition) {
435 this._windowSelector.style.left = position + 'px'; 435 this._windowSelector.style.left = position + 'px';
436 this._windowSelector.style.right = this._width - this._startPosition + 'px '; 436 this._windowSelector.style.right = this._width - this._startPosition + 'px ';
437 } else { 437 } else {
438 this._windowSelector.style.left = this._startPosition + 'px'; 438 this._windowSelector.style.left = this._startPosition + 'px';
439 this._windowSelector.style.right = this._width - position + 'px'; 439 this._windowSelector.style.right = this._width - position + 'px';
440 } 440 }
441 } 441 }
442 }; 442 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698