PageSourceSearch

https://cupcakes2048.org/template/default/js/doge2048.js

js cupcakes2048.org collected 2026-09-28 13:19:57 UTC 25,513 bytes, 493 lines download raw bytes

1(function () {
2    "use strict";
3    var undef_type = "undefined",
4      string_type = "string",
5      nav = self.navigator,
6      String_ctr = String,
7      has_own_prop = Object.prototype.hasOwnProperty,
8      load_queues = {},
9      localizations = {},
10      FALSE = !1,
11      TRUE = !0,
12      l10n_js_media_type =
13        /^\s*application\/(?:vnd\.oftn\.|x-)?l10n\+json\s*(?:$|;)/i,
14      XHR,
15      $locale = "locale",
16      $default_locale = "defaultLocale",
17      $to_locale_string = "toLocaleString",
18      $to_lowercase = "toLowerCase",
19      array_index_of =
20        Array.prototype.indexOf ||
21        function (item) {
22          var len = this.length,
23            i = 0;
24          for (; i < len; i++) {
25            if (i in this && this[i] === item) {
26              return i;
27            }
28          }
29          return -1;
30        },
31      request_JSON = function (uri) {
32        var req = new XHR();
33        req.open("GET", uri, FALSE);
34        req.send(null);
35        if (req.status !== 200) {
36          setTimeout(function () {
37            var l10n_err = new Error("Unable to load localization data: " + uri);
38            l10n_err.name = "Localization Error";
39            throw l10n_err;
40          }, 0);
41          return {};
42        } else {
43          return JSON.parse(req.responseText);
44        }
45      },
46      load = (String_ctr[$to_locale_string] = function (data) {
47        if (arguments.length > 0 && typeof data !== "number") {
48          if (typeof data === string_type) {
49            load(request_JSON(data));
50          } else if (data === FALSE) {
51            localizations = {};
52          } else {
53            var locale, localization, message;
54            for (locale in data) {
55              if (has_own_prop.call(data, locale)) {
56                localization = data[locale];
57                locale = locale[$to_lowercase]();
58                if (!(locale in localizations) || localization === FALSE) {
59                  localizations[locale] = {};
60                }
61                if (localization === FALSE) {
62                  continue;
63                }
64                if (typeof localization === string_type) {
65                  if (
66                    String_ctr[$locale][$to_lowercase]().indexOf(locale) === 0
67                  ) {
68                    localization = request_JSON(localization);
69                  } else {
70                    if (!(locale in load_queues)) {
71                      load_queues[locale] = [];
72                    }
73                    load_queues[locale].push(localization);
74                    continue;
75                  }
76                }
77  
78                for (message in localization) {
79                  if (has_own_prop.call(localization, message)) {
80                    localizations[locale][message] = localization[message];
81                  }
82                }
83              }
84            }
85          }
86        }
87        return Function.prototype[$to_locale_string].apply(String_ctr, arguments);
88      }),
89      process_load_queue = function (locale) {
90        var queue = load_queues[locale],
91          i = 0,
92          len = queue.length,
93          localization;
94        for (; i < len; i++) {
95          localization = {};
96          localization[locale] = request_JSON(queue[i]);
97          load(localization);
98        }
99        delete load_queues[locale];
100      },
101      use_default,
102      localize = (String_ctr.prototype[$to_locale_string] = function () {
103        if (typeof this === undef_type) {
104          return this;
105        }
106  
107        var using_default = use_default,
108          current_locale = String_ctr[using_default ? $default_locale : $locale],
109          parts = current_locale[$to_lowercase]().split("-"),
110          i = parts.length,
111          this_val = this.valueOf(),
112          locale;
113  
114        use_default = FALSE;
115  
116        do {
117          locale = parts.slice(0, i).join("-");
118          if (locale in load_queues) {
119            process_load_queue(locale);
120          }
121          if (locale in localizations && this_val in localizations[locale]) {
122            return localizations[locale][this_val];
123          }
124        } while (i-- > 1);
125  
126        if (!using_default && String_ctr[$default_locale]) {
127          use_default = TRUE;
128          return localize.call(this_val);
129        }
130  
131        return this_val;
132      });
133    if (
134      typeof XMLHttpRequest === undef_type &&
135      typeof ActiveXObject !== undef_type
136    ) {
137      var AXO = ActiveXObject;
138  
139      XHR = function () {
140        try {
141          return new AXO("Msxml2.XMLHTTP.6.0");
142        } catch (xhrEx1) {}
143        try {
144          return new AXO("Msxml2.XMLHTTP.3.0");
145        } catch (xhrEx2) {}
146        try {
147          return new AXO("Msxml2.XMLHTTP");
148        } catch (xhrEx3) {}
149  
150        throw new Error("XMLHttpRequest not supported by this browser.");
151      };
152    } else {
153      XHR = XMLHttpRequest;
154    }
155    String_ctr[$default_locale] = String_ctr[$default_locale] || "";
156    String_ctr[$locale] = (nav && (nav.language || nav.userLanguage)) || "";
157    if (typeof document !== undef_type) {
158      var elts = document.getElementsByTagName("link"),
159        i = elts.length,
160        localization;
161      while (i--) {
162        var elt = elts[i],
163          rel = (elt.getAttribute("rel") || "")[$to_lowercase]().split(/\s+/);
164        if (l10n_js_media_type.test(elt.type)) {
165          if (array_index_of.call(rel, "localizations") !== -1) {
166            load(elt.getAttribute("href"));
167          } else if (array_index_of.call(rel, "localization") !== -1) {
168            localization = {};
169            localization[(elt.getAttribute("hreflang") || "")[$to_lowercase]()] =
170              elt.getAttribute("href");
171            load(localization);
172          }
173        }
174      }
175    }
176  })();
177  function Localize(key) {}
178  function LocalizeElement(className) {}
179  function KeyboardInputManager() {
180    this.events = {};
181    if (window.navigator.msPointerEnabled) {
182      this.eventTouchstart    = "MSPointerDown";
183      this.eventTouchmove     = "MSPointerMove";
184      this.eventTouchend      = "MSPointerUp";
185    } else {
186      this.eventTouchstart    = "touchstart";
187      this.eventTouchmove     = "touchmove";
188      this.eventTouchend      = "touchend";
189    }
190  
191    this.listen();
192  }
193  
194  KeyboardInputManager.prototype.on = function (event, callback) {
195    if (!this.events[event]) {
196      this.events[event] = [];
197    }
198    this.events[event].push(callback);
199  };
200  
201  KeyboardInputManager.prototype.emit = function (event, data) {
202    var callbacks = this.events[event];
203    if (callbacks) {
204      callbacks.forEach(function (callback) {
205        callback(data);
206      });
207    }
208  };
209  
210  KeyboardInputManager.prototype.listen = function () {
211    var self = this;
212  
213    var map = {
214      38: 0, // Up
215      39: 1, // Right
216      40: 2, // Down
217      37: 3, // Left
218      75: 0, // Vim up
219      76: 1, // Vim right
220      74: 2, // Vim down
221      72: 3, // Vim left
222      87: 0, // W
223      68: 1, // D
224      83: 2, // S
225      65: 3  // A
226    };
227    document.addEventListener("keydown", function (event) {
228      var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
229                      event.shiftKey;
230      var mapped    = map[event.which];
231  
232      if (!modifiers) {
233        if (mapped !== undefined) {
234          event.preventDefault();
235          self.emit("move", mapped);
236        }
237      }
238  
239      if (!modifiers && event.which === 82) {
240        self.restart.call(self, event);
241      }
242    });
243  
244    this.bindButtonPress(".retry-button", this.restart);
245    this.bindButtonPress(".restart-button", this.restart);
246    this.bindButtonPress(".keep-playing-button", this.keepPlaying);
247  
248    var touchStartClientX, touchStartClientY;
249    var gameContainer = document.getElementsByClassName("game-container")[0];
250  
251    gameContainer.addEventListener(this.eventTouchstart, function (event) {
252      if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
253          event.targetTouches > 1) {
254        return;
255      }
256  
257      if (window.navigator.msPointerEnabled) {
258        touchStartClientX = event.pageX;
259        touchStartClientY = event.pageY;
260      } else {
261        touchStartClientX = event.touches[0].clientX;
262        touchStartClientY = event.touches[0].clientY;
263      }
264  
265      event.preventDefault();
266    });
267  
268    gameContainer.addEventListener(this.eventTouchmove, function (event) {
269      event.preventDefault();
270    });
271  
272    gameContainer.addEventListener(this.eventTouchend, function (event) {
273      if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
274          event.targetTouches > 0) {
275        return;
276      }
277  
278      var touchEndClientX, touchEndClientY;
279  
280      if (window.navigator.msPointerEnabled) {
281        touchEndClientX = event.pageX;
282        touchEndClientY = event.pageY;
283      } else {
284        touchEndClientX = event.changedTouches[0].clientX;
285        touchEndClientY = event.changedTouches[0].clientY;
286      }
287  
288      var dx = touchEndClientX - touchStartClientX;
289      var absDx = Math.abs(dx);
290  
291      var dy = touchEndClientY - touchStartClientY;
292      var absDy = Math.abs(dy);
293  
294      if (Math.max(absDx, absDy) > 10) {
295        self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0));
296      }
297    });
298  };
299  
300  KeyboardInputManager.prototype.restart = function (event) {
301    event.preventDefault();
302    this.emit("restart");
303  };
304  
305  KeyboardInputManager.prototype.keepPlaying = function (event) {
306    event.preventDefault();
307    this.emit("keepPlaying");
308  };
309  
310  KeyboardInputManager.prototype.crowd = function (event) {
311    event.preventDefault();
312    this.emit("crowd");
313  };
314  
315  KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) {
316    var button = document.querySelector(selector);
317    button.addEventListener("click", fn.bind(this));
318    button.addEventListener(this.eventTouchend, fn.bind(this));
319  };
320
321  function HTMLActuator() {
322    this.tileContainer = document.querySelector(".tile-container");
323    this.scoreContainer = document.querySelector(".score-container");
324    this.scorePoints = document.querySelector(".score-points");
325    this.bestContainer = document.querySelector(".best-container");
326    this.bestPoints = document.querySelector(".best-points");
327    this.messageContainer = document.querySelector(".game-message");
328    this.sharingContainer = document.querySelector(".score-sharing");
329    this.score = 0;
330    this.points = 0
331}
332HTMLActuator.prototype.actuate = function(c, d) {
333    var e = this;
334    window.requestAnimationFrame(function() {
335        e.clearContainer(e.tileContainer);
336        c.cells.forEach(function(b) {
337            b.forEach(function(a) {
338                if (a) {
339                    e.addTile(a)
340                }
341            })
342        });
343        e.updateScore(d.score, d.points);
344        e.updateBestScore(d.bestScore, d.bestPoints);
345        if (d.terminated) {
346            if (d.over) {
347                e.message(false)
348            } else if (d.won) {
349                e.message(true)
350            }
351        }
352    })
353}
354;
355HTMLActuator.prototype.continueGame = function() {
356    this.clearMessage()
357}
358;
359HTMLActuator.prototype.clearContainer = function(a) {
360    while (a.firstChild) {
361        a.removeChild(a.firstChild)
362    }
363}
364;
365HTMLActuator.prototype.addTile = function(b) {
366    var c = this;
367    var d = document.createElement("div");
368    var e = document.createElement("div");
369    var f = document.createElement("img");
370    var g = b.previousPosition || {
371        x: b.x,
372        y: b.y
373    };
374    var h = this.positionClass(g);
375    var i = ["tile", "tile-" + b.value, h];
376    if (b.value > 2048)
377        i.push("tile-super");
378    this.applyClasses(d, i);
379    e.classList.add("tile-inner");
380    f.src = "/template/default/images/doge-2048/" + b.value + ".png";
381    e.appendChild(f);
382    if (b.previousPosition) {
383        window.requestAnimationFrame(function() {
384            i[2] = c.positionClass({
385                x: b.x,
386                y: b.y
387            });
388            c.applyClasses(d, i)
389        })
390    } else if (b.mergedFrom) {
391        i.push("tile-merged");
392        this.applyClasses(d, i);
393        b.mergedFrom.forEach(function(a) {
394            c.addTile(a)
395        })
396    } else {
397        i.push("tile-new");
398        this.applyClasses(d, i)
399    }
400    d.appendChild(e);
401    this.tileContainer.appendChild(d)
402}
403;
404HTMLActuator.prototype.applyClasses = function(a, b) {
405    a.setAttribute("class", b.join(" "))
406}
407;
408HTMLActuator.prototype.normalizePosition = function(a) {
409    return {
410        x: a.x + 1,
411        y: a.y + 1
412    }
413}
414;
415HTMLActuator.prototype.positionClass = function(a) {
416    a = this.normalizePosition(a);
417    return "tile-position-" + a.x + "-" + a.y
418}
419;
420HTMLActuator.prototype.updateScore = function(a, b) {
421    this.clearContainer(this.scoreContainer);
422    this.clearContainer(this.scorePoints);
423    var c = a - this.score;
424    this.score = a;
425    var d = b - this.points;
426    this.points = b;
427    this.scorePoints.textContent = this.points;
428    this.scoreContainer.textContent = Localize("p" + this.score);
429    if (c > 0) {
430        var e = document.createElement("div");
431        e.classList.add("score-addition");
432        e.textContent = Localize("p" + this.score);
433        this.scoreContainer.appendChild(e)
434    }
435    if (d > 0) {
436        var f = document.createElement("div");
437        f.classList.add("score-addition");
438        f.textContent = "+" + d;
439        this.scorePoints.appendChild(f)
440    }
441}
442;
443HTMLActuator.prototype.updateBestScore = function(a, b) {
444    this.bestContainer.textContent = Localize("p" + a);
445    this.bestPoints.textContent = b
446}
447;
448HTMLActuator.prototype.message = function(d) {
449    var e = d ? "game-won" : "game-over";
450    var f = Localize(e);
451    this.playtime = Math.floor((Date.now() - this.manager.startTime) / 1000);
452    var a = new XMLHttpRequest();
453    a.open("POST", "/records.html", true);
454    a.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
455    if (e == "game-won") {
456        var b = 1
457    } else {
458        var b = 0
459    }
460    var c = this.points;
461    a.send("playtime=" + encodeURIComponent(this.playtime) + "&score=" + encodeURIComponent(c) + "&type=6&success=" + encodeURIComponent(b));
462    this.messageContainer.classList.add(e);
463    this.messageContainer.getElementsByTagName("p")[0].textContent = f;
464    this.clearContainer(this.sharingContainer);
465    // Add global leaderboard button
466    var leaderboardBtn = document.createElement("a");
467    leaderboardBtn.href = "/global-leaderboard";
468    leaderboardBtn.target = "_blank";
469    leaderboardBtn.textContent = "🌍 Global Leaderboard";
470    leaderboardBtn.style.cssText = "display:inline-block;background:#f888a9;border-radius:3px;padding:0 20px;text-decoration:none;
470color:#3c1b1a;height:40px;line-height:42px;margin-left:9px;font-size:14px;font-weight:bold;";
471    this.sharingContainer.appendChild(leaderboardBtn);
472    //twttr.widgets.load()
473}
474;
475HTMLActuator.prototype.clearMessage = function() {
476    this.messageContainer.classList.remove("game-won");
477    this.messageContainer.classList.remove("game-over")
478}
479;
480HTMLActuator.prototype.scoreTweetButton = function() {}
481;
482function Localize(a) {
483    return a
484}
485
486function Grid(size,previousState){this.size=size;this.cells=previousState?this.fromState(previousState):this.empty()}Grid.prototype.empty=function(){var cells=[];for(var x=0;x<this.size;x++){var row=cells[x]=[];for(var y=0;y<this.size;y++){row.push(null)}}return cells};Grid.prototype.fromState=function(state){var cells=[];for(var x=0;x<this.size;x++){var row=cells[x]=[];for(var y=0;y<this.size;y++){var tile=state[x][y];row.push(tile?new Tile(tile.position,tile.value):null)}}return cells};Grid.prototype.randomAvailableCell=function(){var cells=this.availableCells();if(cells.length){return cells[Math.floor(Math.random()*cells.length)]}};Grid.prototype.availableCells=function(){var cells=[];this.eachCell(function(x,y,tile){if(!tile){cells.push({x:x,y:y})}});return cells};Grid.prototype.eachCell=function(callback){for(var x=0;x<this.size;x++){for(var y=0;y<this.size;y++){callback(x,y,this.cells[x][y])}}};Grid.prototype.cellsAvailable=function(){return!!this.availableCells().length};Grid.prototype.cellAvailable=function(cell){return!this.cellOccupied(cell)};Grid.prototype.cellOccupied=function(cell){return!!this.cellContent(cell)};Grid.prototype.cellContent=function(cell){if(this.withinBounds(cell)){return this.cells[cell.x][cell.y]}else{return null}};Grid.prototype.insertTile=function(tile){this.cells[tile.x][tile.y]=tile};Grid.prototype.removeTile=function(tile){this.cells[tile.x][tile.y]=null};Grid.prototype.withinBounds=function(position){return position.x>=0&&position.x<this.size&&position.y>=0&&position.y<this.size};Grid.prototype.serialize=function(){var cellState=[];for(var x=0;x<this.size;x++){var row=cellState[x]=[];for(var y=0;y<this.size;y++){row.push(this.cells[x][y]?this.cells[x][y].serialize():null)}}return{size:this.size,cells:cellState}};function Tile(position,value){this.x=position.x;this.y=position.y;this.value=value||2;this.previousPosition=null;this.mergedFrom=null}Tile.prototype.savePosition=function(){this.previousPosition={x:this.x,y:this.y}};Tile.prototype.updatePosition=function(position){this.x=position.x;this.y=position.y};Tile.prototype.serialize=function(){return{position:{x:this.x,y:this.y},value:this.value}};
487window.fakeStorage={_data:{},setItem:function(id,val){return this._data[id]=String(val)},getItem:function(id){return this._data.hasOwnProperty(id)?this._data[id]:undefined},removeItem:function(id){return delete this._data[id]},clear:function(){return this._data={}}};function LocalStorageManager(){this.bestScoreKey="bestScoreCupcakes";this.bestPointsKey="bestPointsCupcakes";this.gameStateKey="gameStateCupcakes";var supported=this.localStorageSupported();this.storage=supported?window.localStorage:window.fakeStorage}LocalStorageManager.prototype.localStorageSupported=function(){var testKey="test";var storage=window.localStorage;try{storage.setItem(testKey,"1");storage.removeItem(testKey);return true}catch(error){return false}};LocalStorageManager.prototype.getBestScore=function(){return this.storage.getItem(this.bestScoreKey)||0};LocalStorageManager.prototype.setBestScore=function(score){this.storage.setItem(this.bestScoreKey,score)};LocalStorageManager.prototype.getBestPoints=function(){return this.storage.getItem(this.bestPointsKey)||0};LocalStorageManager.prototype.setBestPoints=function(points){this.storage.setItem(this.bestPointsKey,points)};LocalStorageManager.prototype.getGameState=function(){var stateJSON=this.storage.getItem(this.gameStateKey);return stateJSON?JSON.parse(stateJSON):null};LocalStorageManager.prototype.setGameState=function(gameState){this.storage.setItem(this.gameStateKey,JSON.stringify(gameState))};LocalStorageManager.prototype.clearGameState=function(){this.storage.removeItem(this.gameStateKey)};
488
489//(function(){const crjg=window.location.hostname;if(!crjg.includes("rg")||crjg.includes("os")){throw new Error("");}})();
490
491function GameManager(size,InputManager,Actuator,StorageManager){this.startTime=Date.now();this.playtime=0;this.size=size;this.inputManager=new InputManager;this.storageManager=new StorageManager;this.actuator=new Actuator;this.actuator.manager=this;this.actuator.playtime=0;this.startTiles=2;this.inputManager.on("move",this.move.bind(this));this.inputManager.on("restart",this.restart.bind(this));this.inputManager.on("keepPlaying",this.keepPlaying.bind(this));this.setup()}function kcal(exp){var kcal=[];kcal[2]=200;kcal[4]=250;kcal[8]=320;kcal[16]=400;kcal[32]=500;kcal[64]=650;kcal[128]=820;kcal[256]=1000;kcal[512]=1200;kcal[1024]=1500;kcal[2048]=2000;kcal[4096]=3000;kcal[8192]=5000;return kcal[exp]}GameManager.prototype.restart=function(){this.storageManager.clearGameState();this.actuator.continueGame();this.setup()};GameManager.prototype.crowd=function(){this.storageManager.clearGameState();this.actuator.continueGame();this.grid=new Grid(this.size);this.score=0;this.points=0;this.over=false;this.won=false;this.keepPlaying=false;this.actuate();var counter=0;for(var i=0;i<3;i++){for(var j=0;j<4;j++){counter++;var value=Math.pow(2,counter);var tile=new Tile({x:j,y:i},value);if(value<=8192)this.grid.insertTile(tile)}}};GameManager.prototype.keepPlaying=function(){this.keepPlaying=true;this.actuator.continueGame()};GameManager.prototype.isGameTerminated=function(){if(this.over||(this.won&&!this.keepPlaying)){return true}else{return false}};GameManager.prototype.setup=function(){var previousState=this.storageManager.getGameState();if(previousState){this.grid=new Grid(previousState.grid.size,previousState.grid.cells);this.score=previousState.score;this.points=previousState.points;this.over=previousState.over;
491this.won=previousState.won;this.keepPlaying=previousState.keepPlaying}else{this.grid=new Grid(this.size);this.score=0;this.points=0;this.over=false;this.won=false;this.keepPlaying=false;this.addStartTiles()}this.localizeElements();this.actuate()};GameManager.prototype.localizeElements=function(){var elementArray=['game-intro','restart-button','retry-button','keep-playing-button','disclaimer','credits'];for(var i in elementArray){LocalizeElement(elementArray[i])}};GameManager.prototype.addStartTiles=function(){for(var i=0;i<this.startTiles;i++){this.addRandomTile()}};GameManager.prototype.addRandomTile=function(){if(this.grid.cellsAvailable()){var value=Math.random()<0.9?2:4;var tile=new Tile(this.grid.randomAvailableCell(),value);this.grid.insertTile(tile)}};GameManager.prototype.actuate=function(){if(this.storageManager.getBestScore()<this.score){this.storageManager.setBestScore(this.score)}if(this.storageManager.getBestPoints()<this.points){this.storageManager.setBestPoints(this.points)}if(this.over){this.storageManager.clearGameState()}else{this.storageManager.setGameState(this.serialize())}this.actuator.actuate(this.grid,{score:this.score,points:this.points,over:this.over,won:this.won,bestScore:this.storageManager.getBestScore(),bestPoints:this.storageManager.getBestPoints(),terminated:this.isGameTerminated()})};GameManager.prototype.serialize=function(){return{grid:this.grid.serialize(),score:this.score,points:this.points,over:this.over,won:this.won,keepPlaying:this.keepPlaying}};GameManager.prototype.prepareTiles=function(){this.grid.eachCell(function(x,y,tile){if(tile){tile.mergedFrom=null;tile.savePosition()}})};GameManager.prototype.moveTile=function(tile,cell){this.grid.cells[tile.x][tile.y]=null;this.grid.cells[cell.x][cell.y]=tile;tile.updatePosition(cell)};GameManager.prototype.move=function(direction){var self=this;if(this.isGameTerminated())return;var cell,tile;var vector=this.getVector(direction);var traversals=this.buildTraversals(vector);var moved=false;this.prepareTiles();traversals.x.forEach(function(x){traversals.y.forEach(function(y){cell={x:x,y:y};tile=self.grid.cellContent(cell);if(tile){var positions=self.findFarthestPosition(cell,vector);var next=self.grid.cellContent(positions.next);if(next&&next.value===tile.value&&!next.mergedFrom){var merged=new Tile(positions.next,tile.value*2);merged.mergedFrom=[tile,next];self.grid.insertTile(merged);self.grid.removeTile(tile);tile.updatePosition(positions.next);self.points+=kcal(tile.value)*2;if(merged.value>self.score)self.score=merged.value;if(merged.value===2048||merged.value===2048)self.won=true}else{self.moveTile(tile,positions.farthest)}if(!self.positionsEqual(cell,tile)){moved=true}}})});if(moved){this.addRandomTile();if(!this.movesAvailable()){this.over=true}this.actuate()}};GameManager.prototype.getVector=function(direction){var map={0:{x:0,y:-1},1:{x:1,y:0},2:{x:0,y:1},3:{x:-1,y:0}};return map[direction]};GameManager.prototype.buildTraversals=function(vector){var traversals={x:[],y:[]};for(var pos=0;pos<this.size;pos++){traversals.x.push(pos);traversals.y.push(pos)}if(vector.x===1)traversals.x=traversals.x.reverse();if(vector.y===1)traversals.y=traversals.y.reverse();return traversals};GameManager.prototype.findFarthestPosition=function(cell,vector){var previous;do{previous=cell;cell={x:previous.x+vector.x,y:previous.y+vector.y}}while(this.grid.withinBounds(cell)&&this.grid.cellAvailable(cell));return{farthest:previous,next:cell}};GameManager.prototype.movesAvailable=function(){return this.grid.cellsAvailable()||this.tileMatchesAvailable()};GameManager.prototype.tileMatchesAvailable=function(){var self=this;var tile;for(var x=0;x<this.size;x++){for(var y=0;y<this.size;y++){tile=this.grid.cellContent({x:x,y:y});if(tile){for(var direction=0;direction<4;direction++){var vector=self.getVector(direction);var cell={x:x+vector.x,y:y+vector.y};var other=self.grid.cellContent(cell);if(other&&other.value===tile.value){return true}}}}}return false};GameManager.prototype.positionsEqual=function(first,second){return first.x===second.x&&first.y===second.y};window.requestAnimationFrame(function () {
492    new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
493  });

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.