PageSourceSearch

https://timeflies.buzz/js/fly.js?nocache-2025-08-04

js timeflies.buzz collected 2026-10-02 05:24:22 UTC 26,174 bytes, 666 lines download raw bytes

1let FRAME_DIM = 16;
2let multiplier = 1;
3let clampBleed = 0;
4const isMobile = () => {
5    let check = false;
6    // prettier-ignore
7    (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
8    return check;
9};
10
11if (!isMobile()) {
12    clampBleed = 0;
13    FRAME_DIM = 32;
14    multiplier = 1.5;
15}
16let spriteSheet = document.querySelector(`#spritesheet-${FRAME_DIM}`);
17
18// Normalize coordinate system to use CSS pixels.
19const flyCanvas = document.createElement("canvas");
20flyCanvas.style =
21    "position: absolute; top: 0; left: 0; pointer-events: none; image-rendering: crisp-edges; image-rendering: pixelated;";
22let bodyDimensions = document.body.parentElement.getBoundingClientRect();
23flyCanvas.width = bodyDimensions.width;
24flyCanvas.height = bodyDimensions.height;
25
26document.body.appendChild(flyCanvas);
27
28let obstacles = [];
29
30function run() {
31    let mouseX = undefined;
32    let mouseY = undefined;
33    document.body.addEventListener("mousemove", (event) => {
34        mouseX = event.pageX;
35        mouseY = event.pageY;
36    });
37    // document.body.addEventListener("click", (event) => {
38    //     fly.position.x = event.pageX;
39    //     fly.position.y = event.pageY;
40    // });
41
42    const TOP = 0;
43    const RIGHT = 1;
44    const BOTTOM = 2;
45    const LEFT = 3;
46    const ctx = flyCanvas.getContext("2d");
47
48    const extractFrame = (index = 0) => {
49        const canvas = document.createElement("canvas");
50        canvas.style.imageRendering = "pixelated";
51        canvas.width = FRAME_DIM;
52        canvas.height = FRAME_DIM;
53        const ctx = canvas.getContext("2d");
54        ctx.drawImage(
55            spriteSheet,
56            index * FRAME_DIM,
57            0,
58            FRAME_DIM,
59            FRAME_DIM,
60            0,
61            0,
62            FRAME_DIM,
63            FRAME_DIM
64        );
65        return canvas;
66    };
67
68    // my name is andy and i love javascript
69    const frames = Array.from({ length: 17 })
70        .map((_, i) => i)
71        .reduce((acc, _, i) => {
72            return acc.concat(extractFrame(i));
73        }, []);
74
75    const animationStates = {
76        idle: 0,
77        idleCleanLegs: 1,
78        idleCleanWings: 2,
79        walk: 3,
80        fly: 4,
81    };
82
83    const framesForAnimations = {
84        [animationStates.idle]: [10],
85        [animationStates.idleCleanWings]: [7, 8, 7, 8, 7, 8, 9, 10],
86        [animationStates.idleCleanLegs]: [4, 5, 4, 5, 4, 5, 6, 10],
87        [animationStates.walk]: [11, 12, 13, 14, 15, 16],
88        [animationStates.fly]: [0, 1],
89    };
90
91    const fpsForAnimations = {
92        [animationStates.idle]: 10,
93        [animationStates.idleCleanLegs]: 10,
94        [animationStates.idleCleanWings]: 10,
95        [animationStates.walk]: 30,
96        [animationStates.fly]: 30,
97    };
98
99    const lerp = (a, b, t) => {
100        return a + (b - a) * t;
101    };
102
103    const distance = (a, b) => {
104        return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2);
105    };
106
107    const clamp = (v, a, b) => {
108        return Math.min(b, Math.max(v, a));
109    };
110
111    const normalize = (vector, magnitude) => {
112        const m = Math.sqrt(vector.x ** 2 + vector.y ** 2);
113        return {
114            x: (vector.x / m) * magnitude,
115            y: (vector.y / m) * magnitude,
116        };
117    };
118
119    const obstacleNodes = Array.from(document.querySelectorAll(".blockfly"));
120    const getObstacleRects = () =>
121        obstacleNodes.map((element) => {
122            const rect = element.getBoundingClientRect();
123            const domRect = new DOMRect(
124                rect.left,
125                rect.top + window.scrollY,
126                rect.width,
127                rect.height
128            );
129            // make a new observer to enclose around domrect
130            return domRect;
131        });
132    obstacles = getObstacleRects();
133    const observer = new ResizeObserver((entries) => {
134        obstacles = getObstacleRects();
135    });
136    window.addEventListener("resize", () => {
137        // mobile fires resize when scrolling because the address bar smushes
138        obstacles = getObstacleRects();
139        let currentHeight = bodyDimensions.height;
140        let currentWidth = bodyDimensions.width;
141        bodyDimensions = document.body.parentElement.getBoundingClientRect();
142        flyCanvas.width = bodyDimensions.width;
143        flyCanvas.height = bodyDimensions.height;
144        if (
145            currentWidth != bodyDimensions.width &&
146            fly.animationState < animationStates.fly
147        ) {
148            fly.flee();
149        }
150        let newHeight = bodyDimensions.height;
151        if (newHeight < currentHeight) {
152            // its possible to get forced into an obstacle; to avoid that, move the fly vertically by oldH - newH
153            fly.position.y = clamp(
154                fly.position.y - (currentHeight - newHeight),
155                0,
156                bodyDimensions.height - fly.height
157            );
158        }
159    });
160    obstacleNodes.forEach((node) => observer.observe(node));
161
162    const intersectingObstacle = (x, y, w, h, excludeObject = undefined) => {
163        const obstacleRects = obstacles;
164        for (let i = 0; i < obstacleRects.length; i++) {
165            const rect = obstacleRects[i];
166            if (
167                excludeObject &&
168                rect.left == excludeObject.left &&
169                rect.top == excludeObject.top &&
170                rect.right == excludeObject.right &&
171                rect.bottom == excludeObject.bottom
172            ) {
173                continue;
174            }
175            if (
176                x + w > rect.left &&
177                x < rect.right &&
178                y + h > rect.top &&
179                y < rect.bottom
180            ) {
181                return rect;
182            }
183        }
184        return undefined;
185    };
186
187    FLYING = 0;
188    WALKING = 1;
189
190    class Fly {
191        state = FLYING;
192        animationState = animationStates.fly;
193        moveChance = 0.2;
194        last = performance.now();
195        frame = 0;
196        flipX = 0;
197        flipY = 0;
198        rot = 0;
199        velocity = { x: 6 * multiplier, y: 3 * multiplier };
200        height = FRAME_DIM;
201        width = FRAME_DIM;
202        clampDirection = LEFT;
203        localVelocity = this.velocity;
204        objectImSittingOn = undefined;
205        walkingDirection = 1;
206        fleeOnScrollListener = null;
207
208        constructor() {
209            this.position = {
210                x: 10,
211                y: 10,
212            };
213            this.boundFleeCB = this.flee.bind(this);
214        }
215        randomizedVelocity() {
216            // buzz around, like a fly
217            const magnitude = Math.sqrt(
218                this.localVelocity.x ** 2 + this.localVelocity.y ** 2
219            );
220            // only go a certain distance from your angle
221            let angle = Math.atan2(this.localVelocity.y, this.localVelocity.x);
222            angle += Math.PI * 2 * (0.5 - Math.random()) * 0.2;
223            const vx = lerp(magnitude * Math.cos(angle), this.velocity.x, 0.4);
224            const vy = lerp(magnitude * Math.sin(angle), this.velocity.y, 0.4);
225            return {
226                x: vx,
227                y: vy,
228            };
229        }
230        chooseRandomDestination() {
231            // pick a random place you want to go :) that is where you will go :)
232            const destination = {
233                x: Math.random() * bodyDimensions.width,
234                y: Math.random() * bodyDimensions.height,
235            };
236            const angle = Math.atan2(
237                this.position.y - destination.y,
238                destination.x - this.position.x
239            );
240            this.velocity = this.localVelocity = {
241                x: Math.cos(angle) * 5 * multiplier,
242                y: Math.sin(angle) * 5 * multiplier,
243            };
244        }
245        setRotationForClampDirection(clampDirection) {
246            switch (clampDirection) {
247                case LEFT:
248                    this.rot = 90;
249                    break;
250                case RIGHT:
251                    this.rot = -90;
252                    break;
253                case TOP:
254                    this.rot = 180;
255                    break;
256                case BOTTOM:
257                    this.rot = 0;
258                    break;
259            }
260        }
261        switchToIdle() {
262            this.setRotationForClampDirection(this.clampDirection);
263            this.frame = 0;
264            this.animationState = animationStates.idle;
265            this.enterIdleState(animationStates.idle);
266            this.velocity = { x: 0, y: 0 };
267        }
268        switchToFlying() {
269            this.flipX = 0;
270            this.flipY = 0;
271            this.rot = 0;
272            this.frame = 0;
273            this.objectImSittingOn = undefined;
274            this.animationState = animationStates.fly;
275            window.removeEventListener("scroll", this.boundFleeCB);
276            window.clearTimeout(this.idleTimeout);
277        }
278        flee() {
279            this.chooseRandomDestination();
280            if (this.clampDirection == RIGHT) {
281                this.velocity.x = -Math.abs(this.velocity.x);
282            } else if (this.clampDirection == LEFT) {
283                this.velocity.x = Math.abs(this.velocity.x);
284            } else if (this.clampDirection == TOP) {
285                this.velocity.y = Math.abs(this.velocity.y);
286            } else if (this.clampDirection == BOTTOM) {
287                this.velocity.y = -Math.abs(this.velocity.y);
288            }
289            // also apply that to the local one a bit. it's funny if not all the way
290            this.localVelocity.x = lerp(
291                this.localVelocity.x,
292                this.velocity.x,
293                0.4
294            );
295            this.localVelocity.y = lerp(
296                this.localVelocity.y,
297                this.velocity.y,
298                0.4
299            );
300            this.flipX = this.localVelocity.x < 0;
301            this.switchToFlying();
302        }
303        enterIdleState(state) {
304            const r = Math.random();
305            if (r < 1 - this.moveChance) {
306                this.setIdleTimeout(animationStates.idle);
307                this.moveChance += 0.1;
308            } else if (r < 0.8) {
309                this.numberOfWalkingFrames =
310                    10 + Math.floor(Math.random() * 40);
311                this.animationState = animationStates.walk;
312            } else if (r < 0.2) {
313                this.switchToFlying();
314            } else {
315                this.moveChance = 0.2;
316                this.animationState =
317                    Math.random() < 0.5
318                        ? animationStates.idleCleanLegs
319                        : animationStates.idleCleanWings;
320            }
321        }
322        setIdleTimeout(state) {
323            this.animationState = state;
324            this.idleTimeout = setTimeout(() => {
325                this.enterIdleState(state);
326            }, 1000);
327        }
328        clear(x, y, mirrorX, mirrorY) {
329            ctx.save();
330            ctx.translate(FRAME_DIM * mirrorX, FRAME_DIM * mirrorY);
331            ctx.scale(mirrorX ? -1 : 1, mirrorY ? -1 : 1);
332            ctx.clearRect(
333                x * (mirrorX ? -1 : 1),
334                y * (mirrorY ? -1 : 1),
335                FRAME_DIM,
336                FRAME_DIM
337            );
338            ctx.restore();
339        }
340        draw(frame, x, y, mirrorX, mirrorY) {
341            x |= x;
342            y |= y;
343            ctx.save();
344            // ctx.translate(FRAME_DIM * mirrorX, FRAME_DIM * mirrorY);
345            ctx.translate(x + this.width / 2, y + this.height / 2);
346            ctx.rotate((this.rot * Math.PI) / 180);
347            ctx.scale(mirrorX ? -1 : 1, mirrorY ? -1 : 1);
348            ctx.drawImage(
349                frame,
350                0,
351                0,
352                this.width,
353                this.height,
354                -this.width / 2,
355                -this.height / 2,
356                this.width,
357                this.height
358            );
359            ctx.restore();
360        }
361        clampToObject(direction) {
362            this.clampDirection = direction;
363            switch (direction) {
364                case LEFT:
365                    this.rot = 90;
366                    break;
367                case RIGHT:
368                    this.rot = -90;
369                    break;
370                case TOP:
371                    this.rot = 180;
372                    break;
373                case BOTTOM:
374                    this.rot = 0;
375                    break;
376            }
377        }
378        nextState(state) {
379            if (
380                state === animationStates.idleCleanLegs ||
381                state === animationStates.idleCleanWings
382            ) {
383                return animationStates.idle;
384            }
385            if (state === animationStates.fly) {
386                // keep on keeping on little fly
387                return animationStates.fly;
388            }
389            return state;
390        }
391        updateState(elapsed) {
392            let frameIndices = framesForAnimations[this.animationState];
393            let fps = fpsForAnimations[this.animationState];
394            let startAnimationState = this.animationState;
395            if (elapsed > 1000 / fps) {
396                this.last = this.last + elapsed;
397                const nAdvance = 1; //Math.floor(elapsed / (1000 / fps));
398                this.frame = this.frame + nAdvance;
399                if (this.frame > frameIndices.length - 1) {
400                    this.animationState = this.nextState(this.animationState);
401                    this.frame = 0;
402                }
403            }
404            if (
405                this.animationState !== startAnimationState &&
406                this.animationState === animationStates.idle
407            ) {
408                this.switchToIdle();
409                frameIndices = framesForAnimations[this.animationState];
410            }
411            return frames[frameIndices[this.frame]];
412        }
413        update(elapsed) {
414            let frame = this.updateState(elapsed);
415            this.clear(
416                this.position.x,
417                this.position.y,
418                this.flipX,
419                this.flipY
420            );
421            // if (this.animationState === animationStates.idle) {
422            //     // if idle for more than 1-4 seconds, go idle animations
423            // }
424            if (this.animationState === animationStates.fly) {
425                let velocity = this.randomizedVelocity();
426                velocity = normalize(velocity, 4 * multiplier);
427                this.localVelocity = { x: velocity.x, y: velocity.y };
428                let nextX = this.position.x + velocity.x;
429                let nextY = this.position.y + velocity.y;
430                const potentialIntersection = intersectingObstacle(
431                    nextX,
432                    nextY,
433                    this.width,
434                    this.height
435                );
436                if (potentialIntersection) {
437                    if (
438                        this.position.x + this.width <
439                            potentialIntersection.left &&
440                        nextX + this.width > potentialIntersection.left
441                    ) {
442                        this.clampToObject(RIGHT);
443                        nextX =
444                            potentialIntersection.left -
445                            this.width +
446                            clampBleed;
447                        nextY = clamp(
448                            this.position.y,
449                            potentialIntersection.top,
450                            potentialIntersection.bottom - this.height
451                        );
452                    } else if (
453                        this.position.x > potentialIntersection.right &&
454                        nextX < potentialIntersection.right
455                    ) {
456                        this.clampToObject(LEFT);
457                        nextX = potentialIntersection.right - clampBleed;
458                        nextY = clamp(
459                            this.position.y,
460                            potentialIntersection.top,
461                            potentialIntersection.bottom - this.height
462                        );
463                    } else if (
464                        this.position.y + this.height <
465                            potentialIntersection.top &&
466                        nextY + this.height > potentialIntersection.top
467                    ) {
468                        this.clampToObject(BOTTOM);
469                        nextY =
470                            potentialIntersection.top -
471                            this.height +
472                            clampBleed;
473                        nextX = clamp(
474                            this.position.x,
475                            potentialIntersection.left,
476                            potentialIntersection.right - this.width
477                        );
478                    } else if (
479                        this.position.y > potentialIntersection.bottom &&
480                        nextY < potentialIntersection.bottom
481                    ) {
482                        this.clampToObject(TOP);
483                        nextY = potentialIntersection.bottom - clampBleed;
484                        nextX = clamp(
485                            this.position.x,
486                            potentialIntersection.left,
487                            potentialIntersection.right - this.width
488                        );
489                    }
490                    this.objectImSittingOn = potentialIntersection;
491                    this.switchToIdle();
492                }
493                // special case the walls as like, thin boxes?
494                if (nextX + this.width > bodyDimensions.width) {
495                    nextX = bodyDimensions.width - this.width;
496                    this.objectImSittingOn = new DOMRect(
497                        bodyDimensions.width,
498                        0,
499                        10,
500                        bodyDimensions.height
501                    );
502                    this.clampToObject(RIGHT);
503                    this.switchToIdle();
504                }
505                if (nextX < 0) {
506                    nextX = 0;
507                    this.objectImSittingOn = new DOMRect(
508                        0,
509                        0,
510                        10,
511                        bodyDimensions.height
512                    );
513                    this.clampToObject(LEFT);
514                    this.switchToIdle();
515                }
516                if (nextY + this.height > bodyDimensions.height) {
517                    nextY = bodyDimensions.height - this.height;
518                    this.objectImSittingOn = new DOMRect(
519                        0,
520                        bodyDimensions.height,
521                        bodyDimensions.width,
522                        10
523                    );
524                    this.clampToObject(BOTTOM);
525                    this.switchToIdle();
526                }
527                if (nextY < 0) {
528                    nextY = 0;
529                    this.objectImSittingOn = new DOMRect(
530                        0,
531                        window.scrollY - 10,
532                        bodyDimensions.width,
533                        10
534                    );
535                    // flee when scrolling, since the top has moved
536                    window.addEventListener("scroll", this.boundFleeCB);
537                    this.clampToObject(TOP);
538                    this.switchToIdle();
539                }
540                this.position.x = nextX;
541                this.position.y = nextY;
542            } else if (this.animationState === animationStates.walk) {
543                switch (this.clampDirection) {
544                    case LEFT:
545                        this.flipX = this.walkingDirection === 1 ? 1 : 0;
546                        this.flipY = 0;
547                        break;
548                    case RIGHT:
549                        this.flipX = this.walkingDirection === -1 ? 1 : 0;
550                        this.flipY = 0;
551                        break;
552                    case TOP:
553                        this.flipY = 0;
554                        this.flipX = this.walkingDirection === -1 ? 1 : 0;
555                        break;
556                    case BOTTOM:
557                        this.flipY = 0;
558                        this.flipX = this.walkingDirection === 1 ? 1 : 0;
559                        break;
560                }
561
562                if (this.numberOfWalkingFrames-- > 0) {
563                    if (
564                        this.clampDirection === LEFT ||
565                        this.clampDirection === RIGHT
566                    ) {
567                        // dont walk into obstacles
568                        let nextY = clamp(
569                            this.position.y +
570                                this.walkingDirection * multiplier,
571                            this.objectImSittingOn.top,
572                            this.objectImSittingOn.bottom - this.height
573                        );
574                        const potentialIntersection = intersectingOb
574stacle(
575                            this.position.x,
576                            nextY,
577                            this.width,
578                            this.height,
579                            this.objectImSittingOn
580                        );
581                        if (
582                            potentialIntersection ||
583                            nextY <= this.objectImSittingOn.top ||
584                            nextY + this.height >= this.objectImSittingOn.bottom
585                        ) {
586                            this.walkingDirection *= -1;
587                            this.position.y +=
588                                (this.walkingDirection * this.height) / 4;
589                        } else {
590                            this.position.y = nextY;
591                        }
592                    } else {
593                        let nextX = clamp(
594                            this.position.x +
595                                this.walkingDirection * multiplier,
596                            this.objectImSittingOn.left,
597                            this.objectImSittingOn.right - this.width
598                        );
599                        const potentialIntersection = intersectingObstacle(
600                            nextX,
601                            this.position.y,
602                            this.width,
603                            this.height,
604                            this.objectImSittingOn
605                        );
606                        if (
607                            potentialIntersection ||
608                            nextX <= this.objectImSittingOn.left ||
609                            nextX + this.width >= this.objectImSittingOn.right
610                        ) {
611                            this.walkingDirection *= -1;
612                            this.position.x +=
613                                (this.walkingDirection * this.width) / 4;
614                        } else {
615                            this.position.x = nextX;
616                        }
617                    }
618                } else {
619                    this.switchToIdle();
620                }
621            }
622            if (
623                this.animationState < animationStates.fly &&
624                distance(this.position, { x: mouseX, y: mouseY }) < 30
625            ) {
626                this.flee();
627            }
628            if (
629                this.animationState < animationStates.fly &&
630                window.scrollY > this.position.y
631            ) {
632                this.flee();
633            }
634            // ctx.drawImage(frame, this.position.x, this.position.y);
635            this.draw(
636                frame,
637                this.position.x,
638                this.position.y,
639                this.flipX,
640                this.flipY
641            );
642        }
643    }
644
645    const fly = new Fly();
646    let frameMS = 1000 / 60;
647    let animTimer = 0;
648    const update = () => {
649        requestAnimationFrame(update);
650        let now = performance.now();
651        let elapsed = now - fly.last;
652        animTimer = 1 - animTimer;
653        if (elapsed > frameMS) {
654            fly.update(elapsed);
655        }
656    };
657    update();
658}
659
660if (spriteSheet.complete) {
661    run();
662} else {
663    spriteSheet.onload = function () {
664        run();
665    };
666}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.