:param player: catan.game.Player
        :param location: string, see hexgrid.location()
175390
def log_player_buys_city(self, player, location):
        
        self._logln('{0} buys city, builds at {1}'.format(
            player.color,
            location
        ))
150724
def make_spot(self, place):
        
        if place["name"] in self.spot:
            raise KeyError("Already have a Spot for this Place")
        r = self.spot_cls(
            board=self,
            place=place
        )
        self.spot[place["name"]] = r
        if '_x' in place and '_y' in place:
            r.pos = (
                self.width * place['_x'],
                self.height * place['_y']
            )
        return r
56801
def resp_set_location(self, resp, location=None):
        
        if location:
            self.location=location
        elif resp:
            self.location=resp.label.decode().replace("\x00", "")
397476
function GameTimer(node, options) {
        options = options || {};

        // ## Public properties

        /**
         * ### node
         *
         * Internal reference to node
         */
        this.node = node;

        /**
         * ### name
         *
         * Internal name of the timer
         */
        this.name = options.name || 'timer_' + J.randomInt(0, 1000000);

        /**
         * ### GameTimer.status
         *
         * Numerical index keeping the current the state of the GameTimer obj
         */
        this.status = GameTimer.UNINITIALIZED;

        /**
         * ### GameTimer.options
         *
         * The current settings for the GameTimer
         */
        this.options = options;

        /**
         * ### GameTimer.timerId
         *
         * The ID of the javascript interval
         */
        this.timerId = null;

        /**
         * ### GameTimer.timeLeft
         *
         * Total running time of timer
         */
        this.milliseconds = null;

        /**
         * ### GameTimer.timeLeft
         *
         * Milliseconds left before time is up
         */
        this.timeLeft = null;

        /**
         * ### GameTimer.timeLeft
         *
         * Milliseconds left when the last stop was called
         */
        this.timeLeftAtStop = null;

        /**
         * ### GameTimer.timePassed
         *
         * Milliseconds already passed from the start of the timer
         */
        this.timePassed = 0;

        /**
         * ### GameTimer.timePassed
         *
         * Milliseconds already passed when the last stop was called
         */
        this.timePassedAtStop = null;

        /**
         * ### GameTimer.update
         *
         * The frequency of update for the timer (in milliseconds)
         */
        this.update = undefined;

        /**
         * ### GameTimer.updateRemaining
         *
         * Milliseconds remaining for current update
         */
        this.updateRemaining = 0;

        /**
         * ### GameTimer.updateStart
         *
         * Timestamp of the start of the last update
         */
        this.updateStart = 0;

        /**
         * ### GameTimer.startPaused
         *
         * Whether to enter the pause state when starting
         */
        this.startPaused = null;

        /**
         * ### GameTimer.timeup
         *
         * Event string or function to fire when the time is up
         *
         * @see GameTimer.fire
         */
        this.timeup = 'TIMEUP';

        /**
         * ### GameTimer.hooks
         *
         * Array of hook functions to fire at every update
         *
         * The array works as a LIFO queue
         *
         * @see GameTimer.fire
         */
        this.hooks = [];

        /**
         * ### GameTimer.hookNames
         *
         * Object containing all names used for the hooks
         *
         * @see GameTimer.hooks
         */
        this.hookNames = {};

        /**
         * ### GameTimer.hookNames
         *
         * The name of the event emitter where the timer was registered
         *
         * @see EventEmitter
         */
        this.eventEmitterName = null;

        /**
         * ## GameTimer.stagerSync
         *
         * TRUE if the timer is synced with stager
         *
         * It will use GameTimer.stagerProperty to sync
         *
         * @see GameTimer.stagerProperty
         * @see GameTimer.syncWithStager
         */
        this.stagerSync = false;

        /**
         * ## GameTimer.stagerProperty
         *
         * The name of the property used to sync with the stager
         *
         * @see GameTimer.stagerSync
         */
        this.stagerProperty = 'timer';

        // Init!
        this.init(this.options);
    }
512263
function WaitingRoom(options) {

        /**
         * ### WaitingRoom.connected
         *
         * Number of players connected
         */
        this.connected = 0;

        /**
         * ### WaitingRoom.poolSize
         *
         * Number of players connected before groups are made
         */
        this.poolSize = 0;

        /**
         * ### WaitingRoom.nGames
         *
         * Total number of games to be dispatched
         *
         * Server will close the waiting room afterwards.
         *
         * Undefined means no limit.
         */
        this.nGames = undefined;

        /**
         * ### WaitingRoom.groupSize
         *
         * The size of the group
         */
        this.groupSize = 0;

        /**
         * ### WaitingRoom.waitTime
         *
         * The time in milliseconds for the timeout to expire
         */
        this.waitTime = null;

        /**
         * ### WaitingRoom.executionMode
         *
         * The execution mode.
         */
        this.executionMode = null;

        /**
         * ### WaitingRoom.startDate
         *
         * The exact date and time when the game starts
         */
        this.startDate = null;

        /**
         * ### WaitingRoom.timeoutId
         *
         * The id of the timeout, if created
         */
        this.timeoutId = null;

        /**
         * ### WaitingRoom.execModeDiv
         *
         * Div containing the span for displaying the number of players
         *
         * @see WaitingRoom.playerCount
         */
        this.execModeDiv = null;

        /**
         * ### WaitingRoom.playerCount
         *
         * Span displaying the number of connected players
         */
        this.playerCount = null;

        /**
         * ### WaitingRoom.startDateDiv
         *
         * Div containing the start date
         */
        this.startDateDiv = null;

        /**
         * ### WaitingRoom.msgDiv
         *
         * Div containing optional messages to display
         */
        this.msgDiv = null;

        /**
         * ### WaitingRoom.timerDiv
         *
         * Div containing the timer
         *
         * @see WaitingRoom.timer
         */
        this.timerDiv = null;

        /**
         * ### WaitingRoom.timer
         *
         * VisualTimer instance for max wait time.
         *
         * @see VisualTimer
         */
        this.timer = null;

        /**
         * ### WaitingRoom.dots
         *
         * Looping dots to give the user the feeling of code execution
         */
        this.dots = null;

        /**
         * ### WaitingRoom.onTimeout
         *
         * Callback to be executed if the timer expires
         */
        this.onTimeout = null;

        /**
         * ### WaitingRoom.disconnectIfNotSelected
         *
         * Flag that indicates whether to disconnect an not selected player
         */
        this.disconnectIfNotSelected = null;

        /**
         * ### WaitingRoom.playWithBotOption
         *
         * If TRUE, it displays a button to begin the game with bots
         *
         * This option is set by the server, local modifications will
         * not have an effect if server does not allow it
         *
         * @see WaitingRoom.playBotBtn
         */
        this.playWithBotOption = null;

        /**
         * ### WaitingRoom.playBotBtn
         *
         * Reference to the button to play with bots
         *
         * Will be created if requested by options.
         *
         * @see WaitingRoom.playWithBotOption
         */
        this.playBotBtn = null;

        /**
         * ### WaitingRoom.selectTreatmentOption
         *
         * If TRUE, it displays a selector to choose the treatment of the game
         *
         * This option is set by the server, local modifications will
         * not have an effect if server does not allow it
         */
        this.selectTreatmentOption = null;

        /**
         * ### WaitingRoom.treatmentBtn
         *
         * Holds the name of selected treatment
         *
         * Only used if `selectTreatmentOption` is enabled
         *
         * @see WaitingRoom.selectTreatmentOption
         */
        this.selectedTreatment = null;

    }
1373467
def push_location(
            self,
            element_path,  # type: Text
            array_index=None  # type: Optional[int]
    ):
        # type: (...) -> None
        """"""
        location = ProcessorLocation(element_path=element_path, array_index=array_index)
        self._locations.append(location)
915384
function(dist) {
    var dx = Math.cos(this.dir) * dist;
    var dy = Math.sin(this.dir) * dist;

    // Move the player if they can walk here.
    this.x += (game.map.check(this.x + dx, this.y) <= 0) ? dx : 0;
    this.y += (game.map.check(this.x, this.y + dy) <= 0) ? dy : 0;

    this.steps += dist;

    // Update the position of the audio listener.
    Howler.pos(this.x, this.y, -0.5);
  }
868461
def set_location(self, location):
        
        if location is None:
            self._location = location

        elif isinstance(location, *six.string_types):  # from device cloud, convert from csv
            parts = str(location).split(",")
            if len(parts) == 3:
                self._location = tuple(map(float, parts))
                return
            else:
                raise ValueError("Location string %r has unexpected format" % location)

        # TODO: could maybe try to allow any iterable but this covers the most common cases
        elif (isinstance(location, (tuple, list))
                and len(location) == 3
                and all([isinstance(x, (float, six.integer_types)) for x in location])):
            self._location = tuple(map(float, location))  # coerce ints to float
        else:
            raise TypeError("Location must be None or 3-tuple of floats")

        self._location = location
158463
async def can_place(self, building: Union[AbilityData, AbilityId, UnitTypeId], position: Point2) -> bool:
        """"""

        assert isinstance(building, (AbilityData, AbilityId, UnitTypeId))

        if isinstance(building, UnitTypeId):
            building = self._game_data.units[building.value].creation_ability
        elif isinstance(building, AbilityId):
            building = self._game_data.abilities[building.value]

        r = await self._client.query_building_placement(building, [position])
        return r[0] == ActionResult.Success
121869
public static Location getObjectLocation(ShanksSimulation simulation,
            PercipientShanksAgent agent, Object object) {
        try {
            if (agent.getCurrentLocation().is3DLocation()) {
                ContinuousPortrayal3D devicesPortrayal;
                devicesPortrayal = (ContinuousPortrayal3D) simulation
                        .getScenarioPortrayal().getPortrayals()
                        .get(Scenario3DPortrayal.MAIN_DISPLAY_ID)
                        .get(ScenarioPortrayal.DEVICES_PORTRAYAL);
                Continuous3D devicesField = (Continuous3D) devicesPortrayal
                        .getField();
                Double3D loc = devicesField.getObjectLocation(object);
                return new Location(loc);
            } else if (agent.getCurrentLocation().is2DLocation()) {
                ContinuousPortrayal2D devicesPortrayal = (ContinuousPortrayal2D) simulation
                        .getScenarioPortrayal().getPortrayals()
                        .get(Scenario2DPortrayal.MAIN_DISPLAY_ID)
                        .get(ScenarioPortrayal.DEVICES_PORTRAYAL);
                Continuous2D devicesField = (Continuous2D) devicesPortrayal
                        .getField();
                Double2D loc = devicesField.getObjectLocation(object);
                return new Location(loc);
            }
        } catch (DuplicatedPortrayalIDException e) {
            e.printStackTrace();
        } catch (ScenarioNotFoundException e) {
            e.printStackTrace();
        } catch (ShanksException e) {
            e.printStackTrace();
        }
        return null;

    }
867957
def sprite_position(map, sprite, offset_x=None, offset_y=None):
    
    map = map.render()
    sprite_maps = _get_cache('sprite_maps')
    sprite_map = sprite_maps.get(map)
    sprite_name = String.unquoted(sprite).value
    sprite = sprite_map and sprite_map.get(sprite_name)
    if not sprite_map:
        log.error("No sprite map found: %s", map, extra={'stack': True})
    elif not sprite:
        log.error("No sprite found: %s in %s", sprite_name, sprite_map['*n*'], extra={'stack': True})
    if sprite:
        x = None
        if offset_x is not None and not isinstance(offset_x, Number):
            x = offset_x
        if not x or x.value not in ('left', 'right', 'center'):
            if x:
                offset_x = None
            x = Number(offset_x or 0, 'px')
            if not x.value or (x.value <= -1 or x.value >= 1) and not x.is_simple_unit('%'):
                x -= Number(sprite[2], 'px')
        y = None
        if offset_y is not None and not isinstance(offset_y, Number):
            y = offset_y
        if not y or y.value not in ('top', 'bottom', 'center'):
            if y:
                offset_y = None
            y = Number(offset_y or 0, 'px')
            if not y.value or (y.value <= -1 or y.value >= 1) and not y.is_simple_unit('%'):
                y -= Number(sprite[3], 'px')
        return List([x, y])
    return List([Number(0), Number(0)])
17938
def InitLocCheck(self):
        """"""
        self.panel = wx.Panel(self, style=wx.SIMPLE_BORDER)

        text = """Step 5:
Check that locations are correctly named.
Fill in any blank cells using controlled vocabularies.
(See Help button for details)

** Denotes controlled vocabulary"""
        label = wx.StaticText(self.panel, label=text)
        #self.Data_hierarchy = self.ErMagic.Data_hierarchy
        self.locations = self.er_magic_data.locations
        #
        if not self.er_magic_data.locations:
            msg = "You have no data in er_locations, so we are skipping step 5.\n Note that location names must be entered at the measurements level,so you may need to re-import your data, or you can add a location in step 3"
            dlg = wx.MessageDialog(None, caption="Message:", message=msg, style=wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.panel.Destroy()
            self.InitAgeCheck()
            return

        self.grid_builder = grid_frame2.GridBuilder(self.er_magic_data, 'location',
                                                   self.er_magic_data.headers, self.panel)
        self.loc_grid = self.grid_builder.make_grid(incl_pmag=False)
        self.loc_grid.InitUI()
        self.grid_builder.add_data_to_grid(self.loc_grid, 'location', incl_pmag=False)
        self.grid = self.loc_grid
        # initialize all needed drop-down menus
        self.drop_down_menu = drop_down_menus.Menus("location", self,
                                                     self.loc_grid, None)

        # need to find max/min lat/lon here IF they were added in the previous grid
        sites = self.er_magic_data.sites
        location_lat_lon = self.er_magic_data.get_min_max_lat_lon(self.er_magic_data.locations)

        col_names = ('location_begin_lat', 'location_end_lat', 'location_begin_lon', 'location_end_lon')
        col_inds = [self.grid.col_labels.index(name) for name in col_names]
        col_info = list(zip(col_names, col_inds))
        for loc in self.er_magic_data.locations:
            row_ind = self.grid.row_labels.index(loc.name)
            for col_name, col_ind in col_info:
                info = location_lat_lon[loc.name][col_name]
                self.grid.SetCellValue(row_ind, col_ind, str(info))

        ### Create Buttons ###
        hbox_one = wx.BoxSizer(wx.HORIZONTAL)
        self.helpButton = wx.Button(self.panel, label="Help")
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_helpButton(event, "ErMagicLocationHelp.html"), self.helpButton)
        hbox_one.Add(self.helpButton)

        hboxok = wx.BoxSizer(wx.HORIZONTAL)
        self.saveButton = wx.Button(self.panel, id=-1, label='Save')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_saveButton(event, self.loc_grid), self.saveButton)
        self.cancelButton = wx.Button(self.panel, wx.ID_CANCEL, '&Cancel')
        self.Bind(wx.EVT_BUTTON, self.on_cancelButton, self.cancelButton)
        self.continueButton = wx.Button(self.panel, id=-1, label='Save and continue')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_continueButton(event, self.loc_grid, next_dia=self.InitAgeCheck), self.continueButton)
        self.backButton = wx.Button(self.panel, wx.ID_ANY, "&Back")
        previous_dia = self.InitSampCheck
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_backButton(event, previous_dia, current_dia=self.InitLocCheck), self.backButton)

        hboxok.Add(self.saveButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.cancelButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.continueButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.backButton)

        #
        hboxgrid = pw.hbox_grid(self.panel, self.onDeleteRow, 'location', self.grid)
        self.deleteRowButton = hboxgrid.deleteRowButton

        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.onLeftClickLabel, self.grid)


        ### Make Containers ###
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(label, flag=wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, border=20)
        vbox.Add(hbox_one, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(hboxok, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(hboxgrid, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(self.loc_grid, flag=wx.TOP|wx.BOTTOM, border=10)
        vbox.AddSpacer(20)

        self.hbox_all = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox_all.AddSpacer(20)
        self.hbox_all.Add(vbox)
        self.hbox_all.AddSpacer(20)

        self.panel.SetSizer(self.hbox_all)
        #if sys.platform in ['win32', 'win64']:
        #    self.panel.SetScrollbars(20, 20, 50, 50)
        self.hbox_all.Fit(self)
        self.Centre()
        self.Show()
        self.Hide()
        self.Show()
1307912
function playerFromReq(request, response, game) {
    var jar = new cookies(request, response);
    var p = decodeURIComponent(jar.get('player'));
    return game.players[p];
}
779559
def locator(self, value):
        
        self._locator = value
        self._latitude, self._longitude = utils.from_grid_locator(value)
3196
private void setCurrentLocationToNextValidPosition(Point aLocation)    {
        // set latest location to next valid position
        int i, j;
        i = aLocation.x;
        j = aLocation.y;
        do {
            if ( (j + 1)  == columns ) {    // goto next row
                i++;
                j = 0;
            }
            else {
                j++;
            }
        }
        while (
        (i < rows.size()) && (j < columns) && (((Row) rows.get(i)).isReserved(j))
        );
        curPosition = new Point(i, j);
    }
423830
def play(self, target=None, index=None, choose=None):
		
		if choose:
			if self.must_choose_one:
				choose = card = self.choose_cards.filter(id=choose)[0]
				self.log("%r: choosing %r", self, choose)
			else:
				raise InvalidAction("%r cannot be played with choice %r" % (self, choose))
		else:
			if self.must_choose_one:
				raise InvalidAction("%r requires a choice (one of %r)" % (self, self.choose_cards))
			card = self
		if not self.is_playable():
			raise InvalidAction("%r isn't playable." % (self))
		if card.requires_target():
			if not target:
				raise InvalidAction("%r requires a target to play." % (self))
			elif target not in self.play_targets:
				raise InvalidAction("%r is not a valid target for %r." % (target, self))
		elif target:
			self.logger.warning("%r does not require a target, ignoring target %r", self, target)
		self.game.play_card(self, target, index, choose)
		return self
493785
function WaitingRoom(config) {
    // Supercall
    HostRoom.call(this, 'Waiting', config);
    if (!this.logicPath) this.logicPath = ngt.resolve('waitroom/waitroom.js');

    /**
     * ### WaitingRoom.roomOpen
     *
     * Flag indicating whether the room is open
     */
    this.roomOpen = config.roomOpen || true;

    /**
     * ### WaitingRoom.dispatching
     *
     * Numeric flag indicating whether the room is dispatching a new game
     *
     *
     */
    this.dispatching = 0;

    /**
     * ### WaitingRoom.timeOuts
     *
     * Array of setTimeout return values indexed by playerIDs
     */
    this.timeOuts = {};

    /**
     * ### WaitingRoom.notifyTimeout
     *
     * A timeout to notify players about updates in the number of players
     *
     * @see WaitingRoom.notifyPlayers
     */
    this.notifyTimeout = null;

    /**
     * ### WaitingRoom.numberOfDispatches
     *
     * Non-negative integer indicating the number of game dispatches
     */
    this.numberOfDispatches = config.numberOfDispatches || 0;

    /**
     * ### WaitingRoom.lastGameRoom
     *
     * Reference to the last created game room
     */
    this.lastGameRoom = null;

    /**
     * ### WaitingRoom.GROUP_SIZE
     *
     * Positive non-zero integer indicating the size of each group
     */
    this.GROUP_SIZE = null;

    /**
     * ### WaitingRoom.POOL_SIZE
     *
     * Positive non-zero integer indicating number of clients for group forming
     */
    this.POOL_SIZE = null;

    /**
     * ### WaitingRoom.DISCONNECT_IF_NOT_SELECTED
     *
     * Boolean or null, indicating whether unselected players are disconnected
     */
    this.DISCONNECT_IF_NOT_SELECTED = null;

    /**
     * ### WaitingRoom.timeOuts
     *
     * Array of setTimeout return values indexed by playerIDs
     */
    this.N_GAMES = null;

    /**
     * ### WaitingRoom.START_DATE
     *
     * Time and date of game start
     *
     * Must be valid input for `Date` constructor
     */
    this.START_DATE = null;

    /**
     * ### WaitingRoom.EXECUTION_MODE
     *
     * String indicating execution mode
     *
     * In the execution mode `'TIMEOUT`, one waits until the time is up, then
     * it will be checked whether enough players are there to start the game.
     * In the execution mode `WAIT_FOR_N_PLAYERS`, the game starts right away
     * if there are the desired number of players. Otherwise, when the time is
     * up, it will be checked if there are at least a certain minimum number of
     * players to start the game. If the execution mode is `WAIT_FOR_DISPATCH`,
     * it simply waits for a dispatch command from monitor, the number of
     * connected players is not taken into account.
     */
    this.EXECUTION_MODE = null;

    /**
     * ### WaitingRoom.MAX_WAIT_TIME
     *
     * Positive non-zero integer indicating max number of milliseconds to start
     *
     * Cannot be defined at the same time as `WaitingRoom.START_DATE`
     */
    this.MAX_WAIT_TIME = null;

    /**
     * ### WaitingRoom.ON_TIMEOUT
     *
     * Callback to be executed client-side after waiting time has elapsed
     */
    this.ON_TIMEOUT = null;

    /**
     * ### WaitingRoom.ON_TIMEOUT_SERVER
     *
     * Callback to be executed after a timeout has expired
     */
    this.ON_TIMEOUT_SERVER = null;

    /**
     * ### WaitingRoom.ON_OPEN
     *
     * Callback to be executed when the waiting room becomes open
     */
    this.ON_OPEN = null;

    /**
     * ### WaitingRoom.ON_CLOSE
     *
     * Callback to be executed when the waiting room becomes close
     */
    this.ON_CLOSE = null;

    /**
     * ### WaitingRoom.ON_CONNECT
     *
     * Callback to be executed when a player connects
     */
    this.ON_CONNECT = null;

    /**
     * ### WaitingRoom.ON_DISCONNECT
     *
     * Callback to be executed when a player disconnects
     */
    this.ON_DISCONNECT = null;

    /**
     * ### WaitingRoom.ON_INIT
     *
     * Callback to be executed after the settings have been parsed
     */
    this.ON_INIT = null;

    /**
     * ### WaitingRoom.ON_DISPATCH
     *
     * Callback to be executed just before starting dispatching
     *
     * Receives the options of the dispatch call as second param
     */
    this.ON_DISPATCH = null;

    /**
     * ### WaitingRoom.ON_DISPATCHED
     *
     * Callback to be executed at the end of a dispatch call
     */
    this.ON_DISPATCHED = null;

    /**
     * ### WaitingRoom.ON_FAILED_DISPATCH
     *
     * Callback to be executed if a dispatch attempt failed
     */
    this.ON_FAILED_DISPATCH = null;

    /**
     * ### WaitingRoom.CHOSEN_TREATMENT
     *
     * String or undefined indicating chosen treatment
     */
    this.CHOSEN_TREATMENT = null;

    /**
     * ### WaitingRoom.OVERWRITE_CHOSEN_TREATMENT
     *
     * If set, it overwrites chosen treatment for the next dispatch only
     *
     * When dispatch is invoked remotely, users may specify a treatment.
     *
     * It is set to null at every dispatch.
     *
     * @see WaitingRoom.ALLOW_SELECT_TREATMENT
     */
    this.OVERWRITE_CHOSEN_TREATMENT = null;

    /**
     * ### WaitingRoom.PLAYER_SORTING
     *
     * Callback to sort the list of players before dispatching
     *
     * If NULL, random sorting takes place. Default: 'timesNotSelected'
     */
    this.PLAYER_SORTING = WaitingRoom.sortingCallbacks.timesNotSelected;

    /**
     * ### WaitingRoom.PING_BEFORE_DISPATCH
     *
     * If TRUE, all players are pinged before a dispatch (Default: TRUE)
     *
     * Non-responding clients are disconnected.
     *
     * If only one player is needed and mode is 'WAIT_FOR_N_PLAYERS',
     * pinging is skipped.
     *
     * @see PING_MAX_REPLY_TIME
     */
    this.PING_BEFORE_DISPATCH = true;

    /**
     * ### WaitingRoom.PING_MAX_REPLY_TIME
     *
     * The time to wait to receive a ping back
     *
     * Clients will be disconnected if they do not reply in time.
     *
     * @see PING_BEFORE_DISPATCH
     */
    this.PING_MAX_REPLY_TIME = 3000;

    /**
     * ### WaitingRoom.PING_DISPATCH_ANYWAY
     *
     * If TRUE, dispatch continues even if disconnections occur during PING
     *
     * @see PING_BEFORE_DISPATCH
     * @see PING_MAX_REPLY_TIME
     */
    this.PING_DISPATCH_ANYWAY = false;

    /**
     * ### WaitingRoom.TEXTS
     *
     * List of texts replacing default ones in WaitingRoom widget
     *
     * @see WaitingRoom.texts (widget)
     */
    this.TEXTS = {};

    /**
     * ### WaitingRoom.SOUNDS
     *
     * List of paths to sounds replacing default ones in WaitingRoom widget
     *
     * @see WaitingRoom.sounds (widget)
     */
    this.SOUNDS = {};

    /**
     * ### WaitingRoom.PAGE_TITLE
     *
     * Sets the page title, optionally adds to page
     *
     */
    this.PAGE_TITLE =  { title: 'Welcome!', addToBody: true };

    /**
     * ### WaitingRoom.isPingInProgress
     *
     * Flag to indicate whether currently pinging for unresponsive players
     */
    this.isPingInProgress = false;

    /**
     * ### WaitingRoom.suspendedPings
     *
     * Flag to indicate whether currently pinging for unresponsive players
     */
    this.suspendedPings = [];

    /**
     * ### WaitingRoom.closeAfterDispatch
     *
     * Flag that the waiting room will close after next dispatch
     *
     * Note: waiting room can dispatch multiple groups, and then will close.
     */
    this.closeAfterDispatch = false;

    /**
     * ### WaitingRoom.makeClientTimeouts
     *
     * TRUE, if it makes timeouts for connecting clients
     *
     * Makes timeout if START_DATE or MAX_WAIT_TIME is set.
     *
     * @see WaitingRoom.makeTimeOut
     * @see WaitingRoom.clearTimeOut
     * @see WaitingRoom.START_DATE
     * @see WaitingRoom.MAX_WAIT_TIME
     */
    this.makeClientTimeOuts = false;

    /**
     * ### WaitingRoom.NOTIFY_INTERVAL
     *
     * The number of milliseconds to wait before sending a player-update message
     *
     * @see WaitingRoom.notifyPlayerUpdate
     */
    this.NOTIFY_INTERVAL = 200;

    /**
     * ### WaitingRoom.availableTreatments
     *
     * List of available treatments including treatment callbacks
     *
     * Maps names to descriptions.
     */
    this.availableTreatments = (function(that) {
        var o, t, key;
        if (that.gameLevel) {
            // Treatments are not yet parsed.
            t = that.game.levels[that.gameLevel].settings.treatments;
        }
        else {
            // Treatments are already parsed at this point.
            t = that.game.settings;
        }
        // Hard-cloned, check names in treatmentCallbacks.
        o = {
            treatment_random:
            WaitingRoom.treatmentCallbacks['treatment_random'],
            treatment_rotate:
            WaitingRoom.treatmentCallbacks['treatment_rotate']
        };
        for (key in t) {
            if (t.hasOwnProperty(key)) {
                o[key] = t[key].description || 'no description';
            }
        }
        return o;
    })(this);
}