├── .gitignore
├── LICENCE
├── README
├── README.rst
├── __init__.py
├── manage.py
├── rpg
├── __init__.py
├── fixtures
│ └── initial_data.json
├── models.py
└── views.py
├── run.py
├── settings.py
├── static
├── 1_blue.gif
├── character.js
├── characters.html
├── common.js
├── effects.js
├── face.html
├── face.svg
├── game.css
├── game.js
├── jquery.js
├── jquery.json-2.2.js
├── jquery.min.js
├── jscolor
│ ├── arrow.gif
│ ├── cross.gif
│ ├── demo.html
│ ├── hs.png
│ ├── hv.png
│ └── jscolor.js
├── output.py
├── sound.mp3
├── soundmanager2.js
├── soundmanager2.swf
├── svg2canvas.jar
├── tileset.png
├── walk.gif
├── walk2.png
└── walk2.xcf
├── templates
├── 404.html
├── 500.html
├── index.html
└── message.html
└── urls.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | dev.db
3 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008, Batiste Bieler
2 | All rights reserved.
3 |
4 | The graphic/sound contents in this package are the property of their
5 | authors and follow their own licence. The folowing licence
6 | apply only on the source code of this package.
7 |
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are
10 | met:
11 |
12 | * Redistributions of source code must retain the above copyright
13 | notice, this list of conditions and the following disclaimer.
14 | * Redistributions in binary form must reproduce the above
15 | copyright notice, this list of conditions and the following
16 | disclaimer in the documentation and/or other materials provided
17 | with the distribution.
18 | * Neither the name of the author nor the names of other
19 | contributors may be used to endorse or promote products derived
20 | from this software without specific prior written permission.
21 |
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 |
34 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | README.rst
2 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | A browser based Role Playing Game
2 | =================================
3 |
4 | A Role Playing Game skeleton that use django and gevent. To start the server, run::
5 |
6 | $ python run.py
7 |
8 | Example chat room from http://bitbucket.org/denis/gevent/src/tip/examples/webchat/chat/views.py
9 |
10 | Tested on Opera, Firefox, Chrome.
11 |
12 | Screenshot
13 | ==========
14 |
15 | .. image:: http://batiste.dosimple.ch/django-rpg-screenshot.png
16 |
17 |
18 | Install
19 | =======
20 |
21 | To install on a ubuntu distribution::
22 |
23 | $ sudo apt-get install python python-django python-pip git sqlite3
24 | $ sudo pip install gevent
25 | $ git clone git://github.com/batiste/django-rpg.git
26 | $ cd django-rpg/
27 | $ python manage.py syncdb
28 | $ python run.py
29 |
30 |
31 | Features
32 | ========
33 |
34 | * The goal is to be massively multiplayer
35 | * Room Chat
36 | * Non player characters example
37 | * Basic example of spell
38 | * Map editing
39 |
40 | Goals
41 | =====
42 |
43 | * Write down a gameplay
44 | * Player experience, spells learning, combact mode, quests, crafting
45 | * Add a second layer on the map for objects
46 | * Get some graphics designer involved
47 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/__init__.py
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from django.core.management import execute_manager
3 | try:
4 | import settings # Assumed to be in the same directory.
5 | except ImportError:
6 | import sys
7 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
8 | sys.exit(1)
9 |
10 | if __name__ == "__main__":
11 | execute_manager(settings)
12 |
--------------------------------------------------------------------------------
/rpg/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/rpg/__init__.py
--------------------------------------------------------------------------------
/rpg/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | import simplejson
3 | import math
4 | import uuid
5 |
6 | # not use right now
7 | class Map(models.Model):
8 |
9 | name = models.CharField(max_length=50, blank=True)
10 | x = models.IntegerField()
11 | y = models.IntegerField()
12 |
13 | forbidden = [
14 | [9, 1],[10, 2],[0, 9],[1, 9],[2, 9],[0, 10],[1, 10],
15 | [2, 10],[3, 10],[4, 10],[5, 10],[8, 9], [6, 8], [6, 10],
16 | [7, 9],[7, 8],[7, 10],[6, 7], [6, 9],[9, 7],[10, 7],
17 | [8, 8], [8 ,10], [9, 8],
18 | [10, 8],[9, 9],[9, 10],[10, 10]
19 | ]
20 |
21 | content = models.TextField()
22 |
23 | def serialized(self):
24 | return {
25 | "id":self.id,
26 | "x":self.x,
27 | "y":self.y,
28 | "name":self.name,
29 | "content":self.content.replace("\n", "")
30 | }
31 |
32 | # the grid is presented by vertical line first
33 | # then by horizontal line, eg: _ground[y][x]
34 | _ground = None
35 |
36 | def get_ground(self):
37 | try:
38 | self._ground = simplejson.loads(self.content.replace("\n", ""))
39 | except (ValueError):
40 | pass
41 | return self._ground
42 |
43 | def set_ground(self, content):
44 | self.content = content.replace("\n", "")
45 | self.get_ground()
46 |
47 | ground = property(get_ground, set_ground)
48 |
49 | def is_safe_position(self, pos):
50 | x = int(round(pos[0] / 16.))
51 | y = int(round(pos[1] / 16.))
52 | if self.ground is None:
53 | return False
54 | if x <= 0 or y <= 0:
55 | return False
56 | if y >= len(self.ground):
57 | return False
58 | if x >= len(self.ground[0]):
59 | return False
60 | block = self.ground[y][x]
61 | if block in self.forbidden:
62 | return False
63 | return True
64 |
65 |
66 | def __unicode__(self):
67 | return self.name
68 |
69 |
70 | class Player(models.Model):
71 |
72 | def __init__(self, *args, **kwargs):
73 | if not kwargs.get('private_key', False):
74 | kwargs['private_key'] = str(uuid.uuid4())
75 | if not kwargs.get('public_key', False):
76 | kwargs['public_key'] = str(uuid.uuid4())
77 |
78 | return super(Player, self).__init__(*args, **kwargs)
79 |
80 | public_key = models.CharField(max_length=50)
81 | private_key = models.CharField(max_length=50)
82 | name = models.CharField(max_length=50)
83 | xp = models.IntegerField(default=0)
84 | vitality = models.IntegerField(default=20)
85 | str_position = models.CharField(max_length=20, default='[32,32]')
86 |
87 | def set_position(self, pos):
88 | self.str_position = str(pos)
89 |
90 | def get_position(self):
91 | return simplejson.loads(self.str_position)
92 |
93 | position = property(get_position, set_position)
94 |
95 | map_id = models.IntegerField(null=True)
96 |
97 | def pub(self):
98 | return {
99 | 'name':self.name,
100 | 'key':self.public_key,
101 | 'position':self.position,
102 | }
103 |
104 | def priv(self):
105 | return {
106 | 'name':self.name,
107 | 'key':self.public_key,
108 | 'private_key':self.private_key,
109 | 'position':self.position,
110 | }
111 |
112 | def __unicode__(self):
113 | return self.private_key
114 |
115 |
116 | class Fight(object):
117 |
118 | def __init__(self, room_map, player, adversary):
119 | self.public_key = str(uuid.uuid4())
120 | self.player = player
121 | self.adversary = adversary
122 | self.room_map = room_map
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/rpg/views.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | import simplejson
3 | from django.shortcuts import render_to_response
4 | from django.template.loader import render_to_string
5 | from django.http import HttpResponse
6 | from gevent.event import Event
7 | from gevent import spawn_later
8 | from django.conf import settings
9 | from django.utils.html import escape
10 |
11 | from rpg.models import Map, Player, Fight
12 | import random
13 |
14 | def pub_key(request):
15 | return request.COOKIES.get('public_key', False)
16 |
17 | def priv_key(request):
18 | return request.COOKIES.get('private_key', False)
19 |
20 | class ChatRoom(object):
21 |
22 | def __init__(self, room_id):
23 | self.pk = room_id
24 | self.room_map = Map.objects.get(pk=self.pk)
25 | self.last_message = []
26 | self.players = []
27 | spawn_later(5, self.move_pnj)
28 | self.cache = []
29 | self.room_event = Event()
30 | self.event_cursor = 0
31 | self.event_buffer = []
32 | self.fights = []
33 | for v in range(0, 9):
34 | self.event_buffer.append(None)
35 | npc = Player(name='Wise man')
36 | self.npc = npc
37 | self.players.append(self.npc)
38 | self.new_event(['new_player', npc.pub()])
39 |
40 | def move_pnj(self):
41 | npc = self.npc
42 | if npc:
43 | pos = [npc.position[0], npc.position[1]]
44 | pos[0] += random.randint(-50, 50)
45 | pos[1] += random.randint(-50, 50)
46 | safe = self.room_map.is_safe_position(pos)
47 | if safe:
48 | npc.position = pos
49 | self.new_event(['update_player_position',
50 | [npc.public_key, npc.position]])
51 | spawn_later(5, self.move_pnj)
52 |
53 | def main(self, request):
54 | key = priv_key(request)
55 | player = self.get_player(key)
56 | return render_to_response(
57 | 'index.html',
58 | {
59 | 'player':player,
60 | 'map':self.room_map,
61 | 'map_content':self.room_map.content.replace("\n", ""),
62 | 'MEDIA_URL': settings.MEDIA_URL
63 | }
64 | )
65 |
66 | def new_event(self, value):
67 | self.event_cursor += 1
68 | if self.event_cursor >= len(self.event_buffer):
69 | self.event_cursor = 0
70 | self.event_buffer[self.event_cursor] = value
71 | self.room_event.set()
72 | self.room_event.clear()
73 |
74 | def get_player(self, key):
75 | for p in self.players:
76 | if p.public_key == key:
77 | return p
78 | if p.private_key == key:
79 | return p
80 | return None
81 |
82 | def remove_player(self, key):
83 | for p in self.players:
84 | if p.private_key == key:
85 | self.players.remove(p)
86 | return p
87 | return None
88 |
89 | def save_map(self, request):
90 | self.room_map.ground = request.POST['content']
91 | self.room_map.save()
92 | self.new_event({'update_map':self.room_map.serialized()})
93 | return json_response([1])
94 |
95 | def player_new(self, request):
96 | key = priv_key(request)
97 | new_player = self.get_player(key)
98 | if not new_player:
99 | name = escape(request.POST['body'])
100 | new_player = Player(
101 | name=name,
102 | position='[20,20]'
103 | )
104 | new_player.save()
105 | event_list = []
106 | # send all the other player to the new one
107 | for player in self.players:
108 | event_list.append(['new_player', player.pub()])
109 | self.players.append(new_player)
110 | self.new_event(['new_player', new_player.pub()])
111 | response = json_response({
112 | 'you':new_player.priv(),
113 | 'events':event_list
114 | })
115 | response.set_cookie('private_key', new_player.private_key)
116 | return response
117 |
118 | def player_update_position(self, request):
119 | key = priv_key(request)
120 | player = self.get_player(key)
121 | pos = request.POST.get('body', False)
122 | if(pos):
123 | player.position = pos
124 | self.new_event([
125 | 'update_player_position',
126 | [player.public_key, player.position]
127 | ])
128 | return json_response([1])
129 |
130 | def message_new(self, request):
131 | key = priv_key(request)
132 | player = self.get_player(key)
133 | msg = escape(request.POST['body'])
134 | #player.last_message = msg
135 | self.new_event(['last_message', [player.public_key, msg]])
136 | return json_response([1])
137 |
138 | def fight_new(self, request):
139 | key = priv_key(request)
140 | player = self.get_player(key)
141 | bad = Player(name='bad')
142 | self.new_event(['player_leave_room', player.pub()])
143 | new_room.new_event(['new_player', player.pub()])
144 | self.remove_player(key)
145 | adversary = Player(name='Rogue level 1')
146 | fight = Fight(
147 | player=player,
148 | adversary=adversary,
149 | room_map=self.room_map
150 | )
151 |
152 | response.set_cookie('fight_key', fight.key)
153 |
154 | return json_response([1])
155 |
156 | def room_updates(self, request):
157 |
158 | self.room_event.wait()
159 |
160 | cursor = int(request.POST.get('cursor', False))
161 | # up to date
162 | if cursor == self.event_cursor:
163 | return json_response([1])
164 | if cursor == False:
165 | cursor = self.event_cursor
166 | # increment to be at the same level that the last event
167 | cursor += 1
168 | if cursor >= len(self.event_buffer):
169 | cursor = 0
170 |
171 | event_list = []
172 | # if there is more than just on event
173 | while(cursor != self.event_cursor):
174 | event = self.event_buffer[cursor]
175 | if event:
176 | event_list.append(self.event_buffer[cursor])
177 | cursor += 1
178 | if cursor >= len(self.event_buffer):
179 | cursor = 0
180 |
181 | event_list.append(self.event_buffer[self.event_cursor])
182 | event_list.append(['update_cursor', self.event_cursor])
183 |
184 | return json_response(event_list)
185 |
186 | def effect(self, request):
187 | key = priv_key(request)
188 | player = self.get_player(key)
189 | effect_type = request.POST.get('type')
190 | self.new_event(['effect', [player.public_key,
191 | effect_type]])
192 | return json_response([1])
193 |
194 | def change_room(self, request):
195 | key = priv_key(request)
196 | player = self.get_player(key)
197 | direction = request.POST.get('direction')
198 | x = 0; y = 0
199 | pos = player.position
200 | if direction == 'left':
201 | pos[0] = 34 * 16
202 | x = -1
203 | if direction == 'right':
204 | pos[0] = 0
205 | x = +1
206 | if direction == 'top':
207 | pos[1] = 28 * 16
208 | y = -1
209 | if direction == 'bottom':
210 | pos[1] = 0
211 | y = +1
212 | player.position = pos
213 | old_map = Map.objects.get(pk=self.pk)
214 | room_map, created = Map.objects.get_or_create(x=old_map.x+x,
215 | y=old_map.y+y)
216 | self.new_event(['player_leave_room', player.pub()])
217 | new_room = get_room(room_map.id)
218 | new_room.players.append(player)
219 | new_room.new_event(['new_player', player.pub()])
220 | self.remove_player(key)
221 | # send all the other player
222 | event_list = []
223 | for player in new_room.players:
224 | event_list.append(['new_player', player.pub()])
225 | response = json_response({'change_room':room_map.serialized(),
226 | "events":event_list})
227 | response.set_cookie('room_id', new_room.pk)
228 | return response
229 |
230 | rooms = {}
231 | def get_room(room_id):
232 | if rooms.has_key(room_id):
233 | room = rooms[room_id]
234 | else:
235 | room = ChatRoom(room_id)
236 | rooms[room_id] = room
237 | return room
238 |
239 | def room_dispacher(method):
240 | def _method(request):
241 | room_id = int(request.COOKIES.get('room_id', 1))
242 | if rooms.has_key(room_id):
243 | room = rooms[room_id]
244 | else:
245 | room = ChatRoom(room_id)
246 | rooms[room_id] = room
247 | return getattr(room, method)(request)
248 | return _method
249 |
250 | # dispatch to rooms
251 | main = room_dispacher('main')
252 | message_new = room_dispacher('message_new')
253 | player_new = room_dispacher('player_new')
254 | player_update_position = room_dispacher('player_update_position')
255 | room_updates = room_dispacher('room_updates')
256 | change_room = room_dispacher('change_room')
257 | save_map = room_dispacher('save_map')
258 | effect = room_dispacher('effect')
259 | fight_new = room_dispacher('fight_new')
260 |
261 | def json_response(value, **kwargs):
262 | kwargs.setdefault('content_type', 'text/javascript; charset=UTF-8')
263 | return HttpResponse(simplejson.dumps(value), **kwargs)
264 |
265 |
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from gevent import monkey; monkey.patch_all()
3 | from gevent.wsgi import WSGIServer
4 | import sys
5 | import os
6 | import traceback
7 | from django.core.handlers.wsgi import WSGIHandler
8 | from django.core.management import call_command
9 | from django.core.signals import got_request_exception
10 |
11 | sys.path.append('..')
12 | os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
13 |
14 | def exception_printer(sender, **kwargs):
15 | traceback.print_exc()
16 |
17 | got_request_exception.connect(exception_printer)
18 |
19 | call_command('syncdb')
20 | print 'Serving on 8088...'
21 | WSGIServer(('', 8088), WSGIHandler()).serve_forever()
22 |
23 |
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | from os.path import dirname, join, abspath
2 | __dir__ = dirname(abspath(__file__))
3 |
4 | DEBUG = True
5 | TEMPLATE_DEBUG = DEBUG
6 | ADMINS = ()
7 | MANAGERS = ADMINS
8 | DATABASE_ENGINE = 'sqlite3'
9 | DATABASE_NAME = 'dev.db'
10 | DATABASE_USER = ''
11 | DATABASE_PASSWORD = ''
12 | DATABASE_HOST = ''
13 | DATABASE_PORT = ''
14 | TIME_ZONE = 'America/Chicago'
15 | LANGUAGE_CODE = 'en-us'
16 | SITE_ID = 1
17 | USE_I18N = True
18 | MEDIA_ROOT = join(__dir__, 'static')
19 |
20 | MEDIA_URL = '/static/'
21 | SECRET_KEY = 'nv8(yg*&1-lon-8i-3jcs0y!01+rem*54051^5xt#^tzujdj!c'
22 | TEMPLATE_LOADERS = (
23 | 'django.template.loaders.filesystem.load_template_source',
24 | 'django.template.loaders.app_directories.load_template_source',
25 | )
26 | MIDDLEWARE_CLASSES = (
27 | 'django.middleware.common.CommonMiddleware',
28 | 'django.contrib.sessions.middleware.SessionMiddleware',
29 | )
30 | ROOT_URLCONF = 'urls'
31 | TEMPLATE_DIRS = (
32 | join(__dir__, 'templates')
33 | )
34 | INSTALLED_APPS = (
35 | 'django.contrib.contenttypes',
36 | 'django.contrib.sessions',
37 | 'django.contrib.sites',
38 | 'rpg',
39 | )
40 |
--------------------------------------------------------------------------------
/static/1_blue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/1_blue.gif
--------------------------------------------------------------------------------
/static/characters.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/static/common.js:
--------------------------------------------------------------------------------
1 |
2 | // evil
3 | Array.prototype.remove = function(from, to) {
4 | var rest = this.slice((to || from) + 1 || this.length);
5 | this.length = from < 0 ? this.length + from : from;
6 | return this.push.apply(this, rest);
7 | };
8 |
9 | if (!window.console) window.console = {};
10 | if (!window.console.log) window.console.log = function() {};
11 |
12 | window.rpg = new Function();
13 |
14 | rpg.other_players = [];
15 |
16 | rpg.norm_vector = function norm_vector(vect) {
17 | return Math.sqrt(vect[0]*vect[0]+vect[1]*vect[1]);
18 | };
19 |
20 | rpg.normalize_vector = function normalize_vector(vect) {
21 | var norm = Math.sqrt(vect[0]*vect[0]+vect[1]*vect[1]);
22 | if(norm==0)
23 | return false
24 | vect[0] = vect[0] / norm;
25 | vect[1] = vect[1] / norm;
26 | return vect;
27 | };
28 |
29 | rpg.get_player = function get_player(key) {
30 | for(var i=0; i < rpg.other_players.length; i++) {
31 | if(rpg.other_players[i] && rpg.other_players[i].public_key == key)
32 | return rpg.other_players[i]
33 | }
34 | return false;
35 | }
36 |
37 | rpg.postJSON = function(url, args, callback) {
38 | $.ajax({
39 | url: url,
40 | data: $.param(args),
41 | dataType: "text",
42 | type: "POST",
43 | success: function(response) {
44 | callback(response);
45 | //console.log("SUCCESS:", response)
46 | },
47 | error: function(response) {
48 | //console.log("ERROR:", response)
49 | }
50 | });
51 | };
52 |
53 |
54 | rpg.event_cursor = false;
55 | // polling update
56 | rpg.updater = {
57 | errorSleepTime: 500,
58 | cursor: null,
59 |
60 | poll: function() {
61 | var args = {};
62 | if(rpg.event_cursor)
63 | args["cursor"] = rpg.event_cursor
64 | $.ajax({
65 | url: "/a/room/updates",
66 | type: "POST",
67 | dataType: "text",
68 | data: $.param(args),
69 | success: rpg.updater.onSuccess,
70 | error: rpg.updater.onError
71 | });
72 | },
73 |
74 | onSuccess: function(response) {
75 | var json = $.evalJSON(response);
76 | for(var i=0; i ');
181 | map.append(dom_bloc);
182 | dom_line.push(dom_bloc);
183 | line.push(false);
184 | };
185 | this.dom_blocs.push(dom_line);
186 | this.blocs.push(line);
187 | };
188 | //map.append($(''));
189 | this.load_new_map(blocs_init);
190 | };
191 |
192 | Grid.prototype.get_bloc = function(indexes) {
193 | return this.blocs[indexes[1]][indexes[0]];
194 | };
195 |
196 | Grid.prototype.paint_bloc = function(dom_bloc) {
197 | //var bloc = $(e.target);
198 | if(dom_bloc.hasClass('bloc')) {
199 | var b_string = dom_bloc.attr('id').split('-');
200 | var tile_pos_css = (-this.choosen_bloc[0]*17-1)+'px ' + (-this.choosen_bloc[1]*17-1)+'px';
201 | this.blocs[parseInt(b_string[1])][parseInt(b_string[2])] = this.choosen_bloc;
202 | dom_bloc.css('background-position', tile_pos_css);
203 | };
204 | };
205 |
206 | Grid.prototype.is_bloc_walkable = function(bloc) {
207 | for(var i=0; i < this.forbidden.length; i++) {
208 | if(this.forbidden[i][0] == bloc[0]
209 | && this.forbidden[i][1] == bloc[1])
210 | return false;
211 | };
212 | return true;
213 | };
214 |
215 | Grid.prototype.bloc_from_player_pos = function(pos) {
216 | if(this.is_loading_room)
217 | return;
218 | var bloc_indexes = [
219 | Math.floor((pos[0]) / 16),
220 | Math.floor((pos[1]) / 16)
221 | ];
222 | // check if the player is leaving the map
223 | var direction = false;
224 | if(bloc_indexes[0] < 0) {
225 | direction = "left";
226 | }
227 | if(bloc_indexes[0] > (rpg.grid.width-1)) {
228 | direction = "right";
229 | };
230 | if(bloc_indexes[1] < 0) {
231 | direction = "top";
232 | }
233 | if(bloc_indexes[1] > (rpg.grid.height-1)) {
234 | direction = "bottom";
235 | }
236 | // load another map
237 | if(direction) {
238 | this.is_loading_room = true;
239 | rpg.postJSON("/a/change_room", {'direction':direction}, function change_room(response) {
240 | var others_player_index = rpg.other_players.length - 1;
241 | while(others_player_index >= 0) {
242 | if(rpg.other_players[0]) {
243 | rpg.other_players[0].remove();
244 | };
245 | rpg.other_players.remove(0);
246 | others_player_index = others_player_index - 1;
247 | };
248 | rpg.other_players = [];
249 | json = $.evalJSON(response);
250 | var new_room = json["change_room"];
251 | var map_content = new_room["content"];
252 | if(map_content)
253 | map_content = $.evalJSON(map_content);
254 | rpg.grid.load_new_map(map_content);
255 | if(direction == "left")
256 | rpg.me.position[0] = (rpg.grid.width-1) * 16;
257 | if(direction == "right")
258 | rpg.me.position[0] = 0;
259 | if(direction == "top")
260 | rpg.me.position[1] = (rpg.grid.height-2) * 16;
261 | if(direction == "bottom")
262 | rpg.me.position[1] = 0;
263 | rpg.me.target_position = rpg.me.position;
264 | rpg.me.move();
265 | for(var i=0; i \
309 | '+this.pname+'\
310 | \
311 | ');
312 | this.cycle = 0;
313 | this.start_cycle = 0;
314 | rpg.map.append(this.element);
315 | this.message_element = this.element.find('.message')
316 | this.message_timeout = false;
317 | this.move(this.position);
318 | };
319 |
320 | Player.prototype.say = function(message) {
321 | clearTimeout(this.message_timeout);
322 | var el = this.message_element;
323 | var chat_log_item = $('');
324 | chat_log_item.html('' + this.pname + ': ' + message);
325 | $('#chat-log').append(chat_log_item)
326 | $('#chat-log').scrollTop(1000)
327 | this.message_element.html(message);
328 | this.message_element.slideDown("slow");
329 | var _hide_message = function(){el.slideUp("slow");}
330 | this.message_timeout = setTimeout(_hide_message, 12000);
331 | };
332 |
333 | // make the walking animation works
334 | Player.prototype.anim = function() {
335 | if(!this.walking) {
336 | this.cycle = 1;
337 | };
338 | var pos = this.start_cycle + 24 * this.cycle;
339 | this.element.css('background-position', -pos+'px');
340 | if(!this.walking) {
341 | return;
342 | }
343 | this.cycle += 1;
344 | if(this.cycle > 2)
345 | this.cycle = 0;
346 | };
347 |
348 | Player.prototype.move = function(pos) {
349 | if(!pos)
350 | pos = this.position;
351 | /*$('#indic')[0].style.left = (pos[0])+'px';
352 | $('#indic')[0].style.top = (pos[1])+'px';*/
353 | this.element[0].style.left = (pos[0] - 12)+'px';
354 | this.element[0].style.top = (pos[1] - 32)+'px';
355 | };
356 |
357 | Player.prototype.init_position = function() {
358 | this.move();
359 | };
360 |
361 | Player.prototype.remove = function() {
362 | this.element.remove();
363 | };
364 |
365 | Player.prototype.update_target_position = function() {
366 | var vect = rpg.keyboard_vector();
367 | if(vect) {
368 | var now = new Date().getTime();
369 | if(this.last_time) {
370 | var time_elapsed = now - this.last_time;
371 | } else {
372 | var time_elapsed = 20.0;
373 | }
374 | this.last_time = now;
375 | var factor = (time_elapsed / 1000.0) * this.speed;
376 |
377 | var next_pos = [
378 | this.target_position[0] + parseInt(vect[0]*factor),
379 | this.target_position[1] + parseInt(vect[1]*factor)
380 | ];
381 |
382 | var bloc = rpg.grid.bloc_from_player_pos(next_pos);
383 | if(bloc && rpg.grid.is_bloc_walkable(bloc)) {
384 | this.target_position = next_pos;
385 | };
386 | };
387 | };
388 |
389 | Player.prototype.set_start_cycle = function(vect) {
390 | // set the cycle animation according to the direction
391 | if(vect[1] > 0) {
392 | this.start_cycle = 24 * 9;
393 | }
394 | if(vect[1] < 0) {
395 | this.start_cycle = 24 * 3;
396 | }
397 | if(vect[0] > 0) {
398 | this.start_cycle = 24 * 6;
399 | };
400 | if(vect[0] < 0) {
401 | this.start_cycle = 0;
402 | };
403 | }
404 |
405 | Player.prototype.move_to_target = function() {
406 | var vect = [
407 | this.target_position[0] - this.position[0],
408 | this.target_position[1] - this.position[1]
409 | ];
410 | var norm = rpg.norm_vector(vect);
411 | if (norm > 0) {
412 | this.position[0] = this.target_position[0];
413 | this.position[1] = this.target_position[1];
414 | this.move();
415 | this.walking = true;
416 | this.set_start_cycle(vect);
417 | } else {
418 | this.walking = false;
419 | this.last_time = false;
420 | };
421 | /*} else {
422 | this.walking = true;
423 | var d = new Date().getTime();
424 | if(this.last_time) {
425 | var time_elapsed = Math.min(60.0, Math.max(20.0, d - this.last_time));
426 | } else {
427 | var time_elapsed = 20.0;
428 | }
429 | var factor = (time_elapsed / 1000.0) * this.speed;
430 | this.last_time = d;
431 | this.set_start_cycle(vect);
432 | vect[0] = vect[0] * factor;
433 | vect[1] = vect[1] * factor;
434 | console.log(factor)
435 | if(factor > 0) {
436 | this.position[0] += parseInt(vect[0]);
437 | this.position[1] += parseInt(vect[1]);
438 | this.move();
439 | }
440 | return;*/
441 | };
442 |
443 | Player.prototype.send_position = function () {
444 | if(this.last_sent_position[0] != this.target_position[0]
445 | || this.last_sent_position[1] != this.target_position[1])
446 | {
447 | var pos = $.toJSON(this.target_position)
448 | this.last_sent_position[0] = this.target_position[0];
449 | this.last_sent_position[1] = this.target_position[1];
450 | rpg.postJSON("/a/player/update_position", {
451 | 'body':pos
452 | },
453 | function(response) {}
454 | );
455 | };
456 | };
457 |
458 | rpg.Player = Player
459 |
460 |
--------------------------------------------------------------------------------
/static/effects.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function Animation(key, x, y) {
4 | var id = 'player-effect-'+key;
5 | var canvas = document.getElementById(id);
6 | if(canvas==undefined) {
7 | canvas = document.createElement("canvas");
8 | canvas.id = id;
9 | var map = document.getElementById('map');
10 | map.appendChild(canvas);
11 | }
12 |
13 | canvas.style.left = (x-45) + 'px';
14 | canvas.style.top = (y-120) + 'px';
15 | this.ctx = document.getElementById(canvas.id).getContext('2d');
16 | this.ctx.canvas.width = 100;
17 | this.ctx.canvas.height = 100;
18 | this.ctx.translate(50, 50);
19 | this.animation_step = 0;
20 | this.animation_timeout = false;
21 | };
22 |
23 | Animation.prototype.anim = function () {
24 | if(this.animation_step > 0)
25 | return;
26 | var that = this;
27 | var a = function() {
28 | that._anim();
29 | }
30 | clearTimeout(this.animation_timeout);
31 | this.animation_timeout = setInterval(a, 20);
32 | };
33 |
34 | Animation.prototype._anim = function () {
35 | if(this.animation_step > 60) {
36 | clearTimeout(this.animation_timeout);
37 | this.animation_step = 0;
38 | this.ctx.clearRect(-60, -60, 100, 100);
39 | return;
40 | }
41 | var alpha = (60 - this.animation_step) / 60;
42 | this.ctx.clearRect(-60, -60, 100, 100);
43 | this.ctx.fillStyle = "rgba(200,0,0, "+alpha+")";
44 | this.ctx.save();
45 | this.ctx.translate(-20, 0);
46 | this.ctx.rotate(this.animation_step/5);
47 | this.ctx.fillRect(-10, -10, 20, 20);
48 | this.ctx.restore();
49 | this.ctx.save();
50 | this.ctx.rotate(Math.PI * 2/3);
51 | this.ctx.translate(-20, 0);
52 | this.ctx.rotate(this.animation_step/5);
53 | this.ctx.fillRect(-10, -10, 20, 20);
54 | this.ctx.restore();
55 | this.ctx.save();
56 | this.ctx.rotate(2 * Math.PI * 2/3);
57 | this.ctx.translate(-20, 0);
58 | this.ctx.rotate(this.animation_step/5);
59 | this.ctx.fillRect(-10, -10, 20, 20);
60 | this.ctx.restore();
61 |
62 | this.ctx.rotate(0.1);
63 | this.animation_step++;
64 | };
65 |
--------------------------------------------------------------------------------
/static/face.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/static/face.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
189 |
--------------------------------------------------------------------------------
/static/game.css:
--------------------------------------------------------------------------------
1 |
2 | #main {
3 | width:770px;
4 | margin:0 auto;
5 | }
6 |
7 | canvas {
8 | position:absolute;
9 | }
10 |
11 | body {
12 | font-size:12px;
13 | font-family:verdana, arial, sans-serif;
14 | background:#333;
15 | }
16 |
17 | #map {
18 | position:relative;
19 | width:560px;
20 | height:480px;
21 | border:1px #eee solid;
22 | }
23 |
24 | #room_data {
25 | color:#fff;
26 | }
27 |
28 | #input {
29 | width:552px;
30 | padding:5px;
31 | background:#666;
32 | }
33 |
34 | #right-container {
35 | width:188px;
36 | float:right;
37 | color:#fff;
38 | }
39 |
40 | #chat-log {
41 | border:1px #444 solid;
42 | padding:10px;
43 | list-style:none;
44 | height:270px;
45 | overflow:auto;
46 | background:#222;
47 | }
48 |
49 | #chat-log li {
50 | padding:0;
51 | margin:0;
52 | color:#eee;
53 | }
54 |
55 | #chat-log li span{
56 | color:#aaa;
57 | }
58 |
59 | #grid-serialized {
60 | width:600px;
61 | height:100px;
62 | }
63 |
64 | .bloc {
65 | background:url(tileset.png) top left no-repeat;
66 | position:absolute;
67 | background-position:-18px -18px;
68 | width:16px;
69 | height:16px;
70 | }
71 |
72 | #select {
73 | position:absolute;
74 | width:16px;
75 | height:16px;
76 | border:1px red solid;
77 | left:-100px;
78 | }
79 |
80 | .player {
81 | position:absolute;
82 | background:url(walk2.png) top left no-repeat;
83 | width:24px;
84 | height:32px;
85 | /*border:1px red solid;*/
86 | }
87 |
88 | #indic {
89 | position:absolute;
90 | width:16px;
91 | height:16px;
92 | background:black;
93 | z-index:1000;
94 | }
95 |
96 | .player .text {
97 | color:#fff;
98 | background:#333;
99 | padding:2px 6px;
100 | margin-left:28px;
101 | margin-top:-20px;
102 | position:absolute;
103 | opacity:0.6;
104 | }
105 |
106 | .player .name {
107 | float:left;
108 | font-weight:bold;
109 | }
110 |
111 | .player .message {
112 | float:left;
113 | }
114 |
--------------------------------------------------------------------------------
/static/game.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var map = $('#map');
4 | rpg.map = map;
5 | var tileset = $('#tileset');
6 | var mouseDown = false;
7 |
8 | if(map_content)
9 | map_content = $.evalJSON(map_content);
10 |
11 | rpg.grid = new rpg.Grid(
12 | map, 35, 30, map_content
13 | );
14 |
15 | tileset.click(function(e) {
16 | var tile_pos = tileset.position();
17 | rpg.grid.choosen_bloc = [
18 | Math.floor((e.clientX-tile_pos.left) / 17),
19 | Math.floor((e.clientY-tile_pos.top) / 17)
20 | ];
21 | var tile_pos_css = (-rpg.grid.choosen_bloc[0]*17-1)+'px ' + (-rpg.grid.choosen_bloc[1]*17-1)+'px';
22 | $('#select').css('left', rpg.grid.choosen_bloc[0]*17 + tile_pos.left+'px');
23 | $('#select').css('top', rpg.grid.choosen_bloc[1]*17 + tile_pos.top+'px');
24 | });
25 |
26 | map.click(function(e) {
27 | rpg.grid.paint_bloc($(e.target));
28 | });
29 |
30 | map.mousedown(function(e) {
31 | mouseDown = true;
32 | });
33 |
34 | map.mouseup(function(e) {
35 | mouseDown = false;
36 | //$('#grid-serialized').val($.toJSON(grid));
37 | });
38 |
39 | map.mousemove(function(e) {
40 | if(mouseDown) {
41 | rpg.grid.paint_bloc($(e.target));
42 | return false;
43 | };
44 | });
45 |
46 |
47 | // Start of the mundane things
48 |
49 | $("#messageform").submit(function(e) {
50 | e.preventDefault();
51 | var message = $('#message');
52 | message.focus();
53 | rpg.postJSON("/a/message/new", {'body':message.val()}, function(response) {
54 | rpg.me.say(message.val());
55 | $('#message').val('');
56 | });
57 | return false;
58 | });
59 |
60 | var me = false;
61 | rpg.other_players = [];
62 |
63 | function bootstrap() {
64 |
65 | rpg.me = new rpg.Player(window.player_position, window.private_key, window.player_name);
66 | rpg.me.init_position();
67 | // start polling events
68 | rpg.updater.poll();
69 |
70 | // animation
71 |
72 | var _players_move = function() {
73 | rpg.me.update_target_position();
74 | rpg.me.move_to_target();
75 | for(var i=0; i >> jQuery.quoteString("apple")
147 | "apple"
148 |
149 | >>> jQuery.quoteString('"Where are we going?", she asked.')
150 | "\"Where are we going?\", she asked."
151 | **/
152 | $.quoteString = function(string)
153 | {
154 | if (string.match(_escapeable))
155 | {
156 | return '"' + string.replace(_escapeable, function (a)
157 | {
158 | var c = _meta[a];
159 | if (typeof c === 'string') return c;
160 | c = a.charCodeAt();
161 | return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
162 | }) + '"';
163 | }
164 | return '"' + string + '"';
165 | };
166 |
167 | var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
168 |
169 | var _meta = {
170 | '\b': '\\b',
171 | '\t': '\\t',
172 | '\n': '\\n',
173 | '\f': '\\f',
174 | '\r': '\\r',
175 | '"' : '\\"',
176 | '\\': '\\\\'
177 | };
178 | })(jQuery);
179 |
--------------------------------------------------------------------------------
/static/jquery.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery JavaScript Library v1.3.2
3 | * http://jquery.com/
4 | *
5 | * Copyright (c) 2009 John Resig
6 | * Dual licensed under the MIT and GPL licenses.
7 | * http://docs.jquery.com/License
8 | *
9 | * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
10 | * Revision: 6246
11 | */
12 | (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,""]||!O.indexOf("
",""]||(!O.indexOf(" | ","
"]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
13 | /*
14 | * Sizzle CSS Selector Engine - v0.9.3
15 | * Copyright 2009, The Dojo Foundation
16 | * Released under the MIT, BSD, and GPL Licenses.
17 | * More information: http://sizzlejs.com/
18 | */
19 | (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(Fa';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("").append(M.responseText.replace(/
8 |
9 | Click here:
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/static/jscolor/hs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/hs.png
--------------------------------------------------------------------------------
/static/jscolor/hv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/jscolor/hv.png
--------------------------------------------------------------------------------
/static/jscolor/jscolor.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jscolor, JavaScript Color Picker
3 | *
4 | * @version 1.3.0
5 | * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
6 | * @author Honza Odvarko http://odvarko.cz
7 | * @created 2008-06-15
8 | * @updated 2009-10-16
9 | * @link http://jscolor.com
10 | */
11 |
12 |
13 | var jscolor = {
14 |
15 |
16 | dir : '', // location of jscolor directory (leave empty to autodetect)
17 | bindClass : 'color', // class name
18 | binding : true, // automatic binding via
19 | preloading : true, // use image preloading?
20 |
21 |
22 | install : function() {
23 | jscolor.addEvent(window, 'load', jscolor.init);
24 | },
25 |
26 |
27 | init : function() {
28 | if(jscolor.binding) {
29 | jscolor.bind();
30 | }
31 | if(jscolor.preloading) {
32 | jscolor.preload();
33 | }
34 | },
35 |
36 |
37 | getDir : function() {
38 | if(!jscolor.dir) {
39 | var detected = jscolor.detectDir();
40 | jscolor.dir = detected!==false ? detected : 'jscolor/';
41 | }
42 | return jscolor.dir;
43 | },
44 |
45 |
46 | detectDir : function() {
47 | var base = location.href;
48 |
49 | var e = document.getElementsByTagName('base');
50 | for(var i=0; i vs[a] ?
383 | (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
384 | tp[a],
385 | -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
386 | (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
387 | (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
388 | ];
389 | drawPicker(pp[a], pp[b]);
390 | }
391 | };
392 |
393 |
394 | this.importColor = function() {
395 | if(!valueElement) {
396 | this.exportColor();
397 | } else {
398 | if(!this.adjust) {
399 | if(!this.fromString(valueElement.value, leaveValue)) {
400 | styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
401 | styleElement.style.color = styleElement.jscStyle.color;
402 | this.exportColor(leaveValue | leaveStyle);
403 | }
404 | } else if(!this.required && /^\s*$/.test(valueElement.value)) {
405 | valueElement.value = '';
406 | styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
407 | styleElement.style.color = styleElement.jscStyle.color;
408 | this.exportColor(leaveValue | leaveStyle);
409 |
410 | } else if(this.fromString(valueElement.value)) {
411 | // OK
412 | } else {
413 | this.exportColor();
414 | }
415 | }
416 | };
417 |
418 |
419 | this.exportColor = function(flags) {
420 | if(!(flags & leaveValue) && valueElement) {
421 | var value = this.toString();
422 | if(this.caps) { value = value.toUpperCase(); }
423 | if(this.hash) { value = '#'+value; }
424 | valueElement.value = value;
425 | }
426 | if(!(flags & leaveStyle) && styleElement) {
427 | styleElement.style.backgroundColor =
428 | '#'+this.toString();
429 | styleElement.style.color =
430 | 0.213 * this.rgb[0] +
431 | 0.715 * this.rgb[1] +
432 | 0.072 * this.rgb[2]
433 | < 0.5 ? '#FFF' : '#000';
434 | }
435 | if(!(flags & leavePad) && isPickerOwner()) {
436 | redrawPad();
437 | }
438 | if(!(flags & leaveSld) && isPickerOwner()) {
439 | redrawSld();
440 | }
441 | };
442 |
443 |
444 | this.fromHSV = function(h, s, v, flags) { // null = don't change
445 | h<0 && (h=0) || h>6 && (h=6);
446 | s<0 && (s=0) || s>1 && (s=1);
447 | v<0 && (v=0) || v>1 && (v=1);
448 | this.rgb = HSV_RGB(
449 | h===null ? this.hsv[0] : (this.hsv[0]=h),
450 | s===null ? this.hsv[1] : (this.hsv[1]=s),
451 | v===null ? this.hsv[2] : (this.hsv[2]=v)
452 | );
453 | this.exportColor(flags);
454 | };
455 |
456 |
457 | this.fromRGB = function(r, g, b, flags) { // null = don't change
458 | r<0 && (r=0) || r>1 && (r=1);
459 | g<0 && (g=0) || g>1 && (g=1);
460 | b<0 && (b=0) || b>1 && (b=1);
461 | var hsv = RGB_HSV(
462 | r===null ? this.rgb[0] : (this.rgb[0]=r),
463 | g===null ? this.rgb[1] : (this.rgb[1]=g),
464 | b===null ? this.rgb[2] : (this.rgb[2]=b)
465 | );
466 | if(hsv[0] !== null) {
467 | this.hsv[0] = hsv[0];
468 | }
469 | if(hsv[2] !== 0) {
470 | this.hsv[1] = hsv[1];
471 | }
472 | this.hsv[2] = hsv[2];
473 | this.exportColor(flags);
474 | };
475 |
476 |
477 | this.fromString = function(hex, flags) {
478 | var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
479 | if(!m) {
480 | return false;
481 | } else {
482 | if(m[1].length === 6) { // 6-char notation
483 | this.fromRGB(
484 | parseInt(m[1].substr(0,2),16) / 255,
485 | parseInt(m[1].substr(2,2),16) / 255,
486 | parseInt(m[1].substr(4,2),16) / 255,
487 | flags
488 | );
489 | } else { // 3-char notation
490 | this.fromRGB(
491 | parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
492 | parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
493 | parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
494 | flags
495 | );
496 | }
497 | return true;
498 | }
499 | };
500 |
501 |
502 | this.toString = function() {
503 | return (
504 | Math.round(255*this.rgb[0]) + ', ' +
505 | Math.round(255*this.rgb[1]) + ', ' +
506 | Math.round(255*this.rgb[2])
507 | );
508 | };
509 |
510 |
511 | function RGB_HSV(r, g, b) {
512 | var n = Math.min(Math.min(r,g),b);
513 | var v = Math.max(Math.max(r,g),b);
514 | var m = v - n;
515 | if(m === 0) { return [ null, 0, v ]; }
516 | var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
517 | return [ h===6?0:h, m/v, v ];
518 | }
519 |
520 |
521 | function HSV_RGB(h, s, v) {
522 | if(h === null) { return [ v, v, v ]; }
523 | var i = Math.floor(h);
524 | var f = i%2 ? h-i : 1-(h-i);
525 | var m = v * (1 - s);
526 | var n = v * (1 - s*f);
527 | switch(i) {
528 | case 6:
529 | case 0: return [v,n,m];
530 | case 1: return [n,v,m];
531 | case 2: return [m,v,n];
532 | case 3: return [m,n,v];
533 | case 4: return [n,m,v];
534 | case 5: return [v,m,n];
535 | }
536 | }
537 |
538 |
539 | function removePicker() {
540 | delete jscolor.picker.owner;
541 | document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
542 | }
543 |
544 |
545 | function drawPicker(x, y) {
546 | if(!jscolor.picker) {
547 | jscolor.picker = {
548 | box : document.createElement('div'),
549 | boxB : document.createElement('div'),
550 | pad : document.createElement('div'),
551 | padB : document.createElement('div'),
552 | padM : document.createElement('div'),
553 | sld : document.createElement('div'),
554 | sldB : document.createElement('div'),
555 | sldM : document.createElement('div')
556 | };
557 | for(var i=0,segSize=4; i 8) {
156 | _s.defaultOptions = _s._mergeObjects(_s.defaultOptions, _s.flash9Options);
157 | _s.features.buffering = true;
158 | }
159 | if (_s.flashVersion > 8 && _s.useMovieStar) {
160 | // flash 9+ support for movieStar formats as well as MP3
161 | _s.defaultOptions = _s._mergeObjects(_s.defaultOptions, _s.movieStarOptions);
162 | _s.filePatterns.flash9 = new RegExp('\\.(mp3|'+_s.netStreamTypes.join('|')+')(\\?.*)?$', 'i');
163 | _s.features.movieStar = true;
164 | } else {
165 | _s.useMovieStar = false;
166 | _s.features.movieStar = false;
167 | }
168 | _s.filePattern = _s.filePatterns[(_s.flashVersion != 8?'flash9':'flash8')];
169 | _s.movieURL = (_s.flashVersion == 8?'soundmanager2.swf':'soundmanager2_flash9.swf');
170 | _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion > 8);
171 | };
172 |
173 | this._overHTTP = (document.location?document.location.protocol.match(/http/i):null);
174 | this._waitingforEI = false;
175 | this._initPending = false;
176 | this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined');
177 | this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null);
178 | this._okToDisable = !this._tryInitOnFocus;
179 |
180 | this.useAltURL = !this._overHTTP; // use altURL if not "online"
181 | var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html';
182 |
183 | this.strings = {
184 | notReady: 'Not loaded yet - wait for soundManager.onload() before calling sound-related methods',
185 | appXHTML: _sm+'_createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.',
186 | swf404: _sm+': Verify that %s is a valid path.',
187 | tryDebug: 'Try '+_sm+'.debugFlash = true for more security details (output goes to SWF.)',
188 | checkSWF: 'See SWF output for more debug info.',
189 | localFail: _sm+': Non-HTTP page ('+document.location.protocol+' URL?) Review Flash player security settings for this special case:\n'+flashCPLink+'\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/',
190 | waitFocus: _sm+': Special case: Waiting for focus-related event..',
191 | waitImpatient: _sm+': Getting impatient, still waiting for Flash%s...',
192 | waitForever: _sm+': Waiting indefinitely for Flash...',
193 | needFunction: _sm+'.onready(): Function object expected',
194 | badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',
195 | fl9Vid: 'flash 9 required for video. Exiting.',
196 | noMS: 'MovieStar mode not enabled. Exiting.',
197 | spcWmode: _sm+'._createMovie(): Removing wmode, preventing win32 below-the-fold SWF loading issue',
198 | currentObj: '--- '+_sm+'._debug(): Current sound objects ---',
199 | waitEI: _sm+'._initMovie(): Waiting for ExternalInterface call from Flash..',
200 | waitOnload: _sm+': Waiting for window.onload()',
201 | docLoaded: _sm+': Document already loaded',
202 | onload: _sm+'.initComplete(): calling soundManager.onload()',
203 | onloadOK: _sm+'.onload() complete',
204 | init: '-- '+_sm+'.init() --',
205 | didInit: _sm+'.init(): Already called?',
206 | flashJS: _sm+': Attempting to call Flash from JS..',
207 | noPolling: _sm+': Polling (whileloading()/whileplaying() support) is disabled.',
208 | secNote: 'Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html',
209 | badRemove: 'Warning: Failed to remove flash movie.',
210 | peakWave: 'Warning: peak/waveform/eqData features unsupported for non-MP3 formats',
211 | shutdown: _sm+'.disable(): Shutting down',
212 | queue: _sm+'.onready(): Queueing handler',
213 | smFail: _sm+': Failed to initialise.',
214 | smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',
215 | manURL: 'SMSound.load(): Using manually-assigned URL',
216 | onURL: _sm+'.load(): current URL already assigned.',
217 | badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.'
218 | };
219 |
220 | this._str = function() { // o [,items to replace]
221 | var params = Array.prototype.slice.call(arguments); // real array, please
222 | var o = params.shift(); // first arg
223 | var str = _s.strings && _s.strings[o]?_s.strings[o]:'';
224 | if (str && params && params.length) {
225 | for (var i=0, j=params.length; i 8 && _s.useMovieStar) {
273 | if (_tO.isMovieStar === null) {
274 | _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false);
275 | }
276 | if (_tO.isMovieStar) {
277 | _s._wD(_cs+'using MovieStar handling');
278 | }
279 | if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) {
280 | _s._wDS('peakWave');
281 | _tO.usePeakData = false;
282 | _tO.useWaveformData = false;
283 | _tO.useEQData = false;
284 | }
285 | }
286 | _s.sounds[_tO.id] = new SMSound(_tO);
287 | _s.soundIDs[_s.soundIDs.length] = _tO.id;
288 | // AS2:
289 | if (_s.flashVersion == 8) {
290 | _s.o._createSound(_tO.id, _tO.onjustbeforefinishtime);
291 | } else {
292 | _s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.useVideo:false), (_tO.isMovieStar?_tO.bufferTime:false));
293 | }
294 | if (_tO.autoLoad || _tO.autoPlay) {
295 | // TODO: does removing timeout here cause problems?
296 | if (_s.sounds[_tO.id]) {
297 | _s.sounds[_tO.id].load(_tO);
298 | }
299 | }
300 | if (_tO.autoPlay) {
301 | _s.sounds[_tO.id].play();
302 | }
303 | return _s.sounds[_tO.id];
304 | };
305 |
306 | this.createVideo = function(oOptions) {
307 | var fN = 'soundManager.createVideo(): ';
308 | if (arguments.length == 2) {
309 | oOptions = {
310 | 'id': arguments[0],
311 | 'url': arguments[1]
312 | };
313 | }
314 | if (_s.flashVersion >= 9) {
315 | oOptions.isMovieStar = true;
316 | oOptions.useVideo = true;
317 | } else {
318 | _s._wD(fN+_s._str('f9Vid'), 2);
319 | return false;
320 | }
321 | if (!_s.useMovieStar) {
322 | _s._wD(fN+_s._str('noMS'), 2);
323 | }
324 | return _s.createSound(oOptions);
325 | };
326 |
327 | this.destroySound = function(sID, bFromSound) {
328 | // explicitly destroy a sound before normal page unload, etc.
329 | if (!_s._idCheck(sID)) {
330 | return false;
331 | }
332 | for (var i=0; i<_s.soundIDs.length; i++) {
333 | if (_s.soundIDs[i] == sID) {
334 | _s.soundIDs.splice(i, 1);
335 | continue;
336 | }
337 | }
338 | // conservative option: avoid crash with flash 8
339 | // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP+flash 8??
340 | // if (_s.flashVersion != 8) {
341 | _s.sounds[sID].unload();
342 | // }
343 | if (!bFromSound) {
344 | // ignore if being called from SMSound instance
345 | _s.sounds[sID].destruct();
346 | }
347 | delete _s.sounds[sID];
348 | };
349 |
350 | this.destroyVideo = this.destroySound;
351 |
352 | this.load = function(sID, oOptions) {
353 | if (!_s._idCheck(sID)) {
354 | return false;
355 | }
356 | _s.sounds[sID].load(oOptions);
357 | };
358 |
359 | this.unload = function(sID) {
360 | if (!_s._idCheck(sID)) {
361 | return false;
362 | }
363 | _s.sounds[sID].unload();
364 | };
365 |
366 | this.play = function(sID, oOptions) {
367 | var fN = 'soundManager.play(): ';
368 | if (!_s._didInit) {
369 | throw _s._complain(fN+_s._str('notReady'), arguments.callee.caller);
370 | }
371 | if (!_s._idCheck(sID)) {
372 | if (typeof oOptions != 'Object') {
373 | oOptions = {
374 | url: oOptions
375 | }; // overloading use case: play('mySound','/path/to/some.mp3');
376 | }
377 | if (oOptions && oOptions.url) {
378 | // overloading use case, creation+playing of sound: .play('someID',{url:'/path/to.mp3'});
379 | _s._wD(fN+'attempting to create "'+sID+'"', 1);
380 | oOptions.id = sID;
381 | _s.createSound(oOptions);
382 | } else {
383 | return false;
384 | }
385 | }
386 | _s.sounds[sID].play(oOptions);
387 | };
388 |
389 | this.start = this.play; // just for convenience
390 |
391 | this.setPosition = function(sID, nMsecOffset) {
392 | if (!_s._idCheck(sID)) {
393 | return false;
394 | }
395 | _s.sounds[sID].setPosition(nMsecOffset);
396 | };
397 |
398 | this.stop = function(sID) {
399 | if (!_s._idCheck(sID)) {
400 | return false;
401 | }
402 | _s._wD('soundManager.stop('+sID+')', 1);
403 | _s.sounds[sID].stop();
404 | };
405 |
406 | this.stopAll = function() {
407 | _s._wD('soundManager.stopAll()', 1);
408 | for (var oSound in _s.sounds) {
409 | if (_s.sounds[oSound] instanceof SMSound) {
410 | _s.sounds[oSound].stop(); // apply only to sound objects
411 | }
412 | }
413 | };
414 |
415 | this.pause = function(sID) {
416 | if (!_s._idCheck(sID)) {
417 | return false;
418 | }
419 | _s.sounds[sID].pause();
420 | };
421 |
422 | this.pauseAll = function() {
423 | for (var i=_s.soundIDs.length; i--;) {
424 | _s.sounds[_s.soundIDs[i]].pause();
425 | }
426 | };
427 |
428 | this.resume = function(sID) {
429 | if (!_s._idCheck(sID)) {
430 | return false;
431 | }
432 | _s.sounds[sID].resume();
433 | };
434 |
435 | this.resumeAll = function() {
436 | for (var i=_s.soundIDs.length; i--;) {
437 | _s.sounds[_s.soundIDs[i]].resume();
438 | }
439 | };
440 |
441 | this.togglePause = function(sID) {
442 | if (!_s._idCheck(sID)) {
443 | return false;
444 | }
445 | _s.sounds[sID].togglePause();
446 | };
447 |
448 | this.setPan = function(sID, nPan) {
449 | if (!_s._idCheck(sID)) {
450 | return false;
451 | }
452 | _s.sounds[sID].setPan(nPan);
453 | };
454 |
455 | this.setVolume = function(sID, nVol) {
456 | if (!_s._idCheck(sID)) {
457 | return false;
458 | }
459 | _s.sounds[sID].setVolume(nVol);
460 | };
461 |
462 | this.mute = function(sID) {
463 | var fN = 'soundManager.mute(): ';
464 | if (typeof sID != 'string') {
465 | sID = null;
466 | }
467 | if (!sID) {
468 | _s._wD(fN+'Muting all sounds');
469 | for (var i=_s.soundIDs.length; i--;) {
470 | _s.sounds[_s.soundIDs[i]].mute();
471 | }
472 | _s.muted = true;
473 | } else {
474 | if (!_s._idCheck(sID)) {
475 | return false;
476 | }
477 | _s._wD(fN+'Muting "'+sID+'"');
478 | _s.sounds[sID].mute();
479 | }
480 | };
481 |
482 | this.muteAll = function() {
483 | _s.mute();
484 | };
485 |
486 | this.unmute = function(sID) {
487 | var fN = 'soundManager.unmute(): ';
488 | if (typeof sID != 'string') {
489 | sID = null;
490 | }
491 | if (!sID) {
492 | _s._wD(fN+'Unmuting all sounds');
493 | for (var i=_s.soundIDs.length; i--;) {
494 | _s.sounds[_s.soundIDs[i]].unmute();
495 | }
496 | _s.muted = false;
497 | } else {
498 | if (!_s._idCheck(sID)) {
499 | return false;
500 | }
501 | _s._wD(fN+'Unmuting "'+sID+'"');
502 | _s.sounds[sID].unmute();
503 | }
504 | };
505 |
506 | this.unmuteAll = function() {
507 | _s.unmute();
508 | };
509 |
510 | this.toggleMute = function(sID) {
511 | if (!_s._idCheck(sID)) {
512 | return false;
513 | }
514 | _s.sounds[sID].toggleMute();
515 | };
516 |
517 | this.getMemoryUse = function() {
518 | if (_s.flashVersion == 8) {
519 | // not supported in Flash 8
520 | return 0;
521 | }
522 | if (_s.o) {
523 | return parseInt(_s.o._getMemoryUse(), 10);
524 | }
525 | };
526 |
527 | this.disable = function(bNoDisable) {
528 | // destroy all functions
529 | if (typeof bNoDisable == 'undefined') {
530 | bNoDisable = false;
531 | }
532 | if (_s._disabled) {
533 | return false;
534 | }
535 | _s._disabled = true;
536 | _s._wDS('shutdown', 1);
537 | for (var i=_s.soundIDs.length; i--;) {
538 | _s._disableObject(_s.sounds[_s.soundIDs[i]]);
539 | }
540 | _s.initComplete(bNoDisable); // fire "complete", despite fail
541 | // _s._disableObject(_s); // taken out to allow reboot()
542 | };
543 |
544 | this.canPlayURL = function(sURL) {
545 | return (sURL?(sURL.match(_s.filePattern)?true:false):null);
546 | };
547 |
548 | this.getSoundById = function(sID, suppressDebug) {
549 | if (!sID) {
550 | throw new Error('SoundManager.getSoundById(): sID is null/undefined');
551 | }
552 | var result = _s.sounds[sID];
553 | if (!result && !suppressDebug) {
554 | _s._wD('"'+sID+'" is an invalid sound ID.', 2);
555 | // soundManager._wD('trace: '+arguments.callee.caller);
556 | }
557 | return result;
558 | };
559 |
560 | this.onready = function(oMethod, oScope) {
561 | // queue a callback, with optional scope
562 | // a status object will be passed to your handler
563 | /*
564 | soundManager.onready(function(oStatus) {
565 | alert('SM2 init success: '+oStatus.success);
566 | });
567 | */
568 | if (oMethod && oMethod instanceof Function) {
569 | if (_s._didInit) {
570 | _s._wDS('queue');
571 | }
572 | if (!oScope) {
573 | oScope = window;
574 | }
575 | _s._addOnReady(oMethod, oScope);
576 | _s._processOnReady();
577 | return true;
578 | } else {
579 | throw _s._str('needFunction');
580 | }
581 | };
582 |
583 | this.oninitmovie = function() {
584 | // called after SWF has been appended to the DOM via JS (or retrieved from HTML)
585 | // this is a stub for your own scripts.
586 | };
587 |
588 | this.onload = function() {
589 | // window.onload() equivalent for SM2, ready to create sounds etc.
590 | // this is a stub for your own scripts.
591 | soundManager._wD('soundManager.onload()', 1);
592 | };
593 |
594 | this.onerror = function() {
595 | // stub for user handler, called when SM2 fails to load/init
596 | };
597 |
598 | // --- "private" methods ---
599 | this._idCheck = this.getSoundById;
600 |
601 | this._complain = function(sMsg, oCaller) {
602 | // Try to create meaningful custom errors, w/stack trace to the "offending" line
603 | var sPre = 'Error: ';
604 | if (!oCaller) {
605 | return new Error(sPre+sMsg);
606 | }
607 | var e = new Error(''); // make a mistake.
608 | var stackMsg = null;
609 | if (e.stack) {
610 | // potentially dangerous: Try to return a meaningful stacktrace where provided (Mozilla)
611 | try {
612 | var splitChar = '@';
613 | var stackTmp = e.stack.split(splitChar);
614 | stackMsg = stackTmp[4]; // try to return only the relevant bit, skipping internal SM2 shiz
615 | } catch(ee) {
616 | // oops.
617 | stackMsg = e.stack;
618 | }
619 | }
620 | if (typeof console != 'undefined' && typeof console.trace != 'undefined') {
621 | console.trace();
622 | }
623 | var errorDesc = sPre+sMsg+'. \nCaller: '+oCaller.toString()+(e.stack?' \nTop of stacktrace: '+stackMsg:(e.message?' \nMessage: '+e.message:''));
624 | // See JS error/debug/console output for real error source, stack trace / message detail where possible.
625 | return new Error(errorDesc);
626 | };
627 |
628 | var _doNothing = function() {
629 | return false;
630 | };
631 |
632 | _doNothing._protected = true;
633 |
634 | this._disableObject = function(o) {
635 | for (var oProp in o) {
636 | if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') {
637 | o[oProp] = _doNothing;
638 | }
639 | }
640 | oProp = null;
641 | };
642 |
643 | this._failSafely = function(bNoDisable) {
644 | // general failure exception handler
645 | if (typeof bNoDisable == 'undefined') {
646 | bNoDisable = false;
647 | }
648 | if (!_s._disabled || bNoDisable) {
649 | _s._wDS('smFail', 2);
650 | _s.disable(bNoDisable);
651 | }
652 | };
653 |
654 | this._normalizeMovieURL = function(smURL) {
655 | var urlParams = null;
656 | if (smURL) {
657 | if (smURL.match(/\.swf(\?.*)?$/i)) {
658 | urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?')+4);
659 | if (urlParams) {
660 | return smURL; // assume user knows what they're doing
661 | }
662 | } else if (smURL.lastIndexOf('/') != smURL.length - 1) {
663 | smURL = smURL+'/';
664 | }
665 | }
666 | return (smURL && smURL.lastIndexOf('/') != -1?smURL.substr(0, smURL.lastIndexOf('/')+1):'./')+_s.movieURL;
667 | };
668 |
669 | this._getDocument = function() {
670 | return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0]));
671 | };
672 |
673 | this._getDocument._protected = true;
674 |
675 | this._setPolling = function(bPolling, bHighPerformance) {
676 | if (!_s.o || !_s.allowPolling) {
677 | return false;
678 | }
679 | _s.o._setPolling(bPolling, bHighPerformance);
680 | };
681 |
682 | this._createMovie = function(smID, smURL) {
683 | var specialCase = null;
684 | var remoteURL = (smURL?smURL:_s.url);
685 | var localURL = (_s.altURL?_s.altURL:remoteURL);
686 | if (_s.debugURLParam.test(window.location.href.toString())) {
687 | _s.debugMode = true; // allow force of debug mode via URL
688 | }
689 | if (_s._didAppend && _s._appendSuccess) {
690 | return false; // ignore if already succeeded
691 | }
692 | _s._didAppend = true;
693 |
694 | // safety check for legacy (change to Flash 9 URL)
695 | _s._setVersionInfo();
696 | _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL);
697 | smURL = _s.url;
698 |
699 | if (_s.useHighPerformance && _s.useMovieStar && _s.defaultOptions.useVideo === true) {
700 | specialCase = 'soundManager note: disabling highPerformance, not applicable with movieStar mode+useVideo';
701 | _s.useHighPerformance = false;
702 | }
703 |
704 | _s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode);
705 |
706 |
707 | if (_s.wmode !== null && _s.flashLoadTimeout !== 0 && (!_s.useHighPerformance || _s.debugFlash) && !_s.isIE && navigator.platform.match(/win32/i)) {
708 | _s.specialWmodeCase = true;
709 | // extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here
710 | // does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout
711 | _s._wDS('spcWmode');
712 | _s.wmode = null;
713 | }
714 |
715 | if (_s.flashVersion == 8) {
716 | _s.allowFullScreen = false;
717 | }
718 |
719 | var oEmbed = {
720 | name: smID,
721 | id: smID,
722 | src: smURL,
723 | width: '100%',
724 | height: '100%',
725 | quality: 'high',
726 | allowScriptAccess: _s.allowScriptAccess,
727 | bgcolor: _s.bgColor,
728 | pluginspage: 'http://www.macromedia.com/go/getflashplayer',
729 | type: 'application/x-shockwave-flash',
730 | wmode: _s.wmode,
731 | allowfullscreen: (_s.allowFullScreen?'true':'false')
732 | };
733 |
734 | if (_s.debugFlash) {
735 | oEmbed.FlashVars = 'debug=1';
736 | }
737 |
738 | if (!_s.wmode) {
739 | delete oEmbed.wmode; // don't write empty attribute
740 | }
741 |
742 | var oMovie = null;
743 | var tmp = null;
744 | var movieHTML = null;
745 | var oEl = null;
746 |
747 | if (_s.isIE) {
748 | // IE is "special".
749 | oMovie = document.createElement('div');
750 | movieHTML = '';
751 | } else {
752 | oMovie = document.createElement('embed');
753 | for (tmp in oEmbed) {
754 | if (oEmbed.hasOwnProperty(tmp)) {
755 | oMovie.setAttribute(tmp, oEmbed[tmp]);
756 | }
757 | }
758 | }
759 |
760 | var oD = null;
761 | var oToggle = null;
762 |
763 | if (_s.debugMode) {
764 |
765 | oD = document.createElement('div');
766 | oD.id = _s.debugID+'-toggle';
767 | oToggle = {
768 | position: 'fixed',
769 | bottom: '0px',
770 | right: '0px',
771 | width: '1.2em',
772 | height: '1.2em',
773 | lineHeight: '1.2em',
774 | margin: '2px',
775 | textAlign: 'center',
776 | border: '1px solid #999',
777 | cursor: 'pointer',
778 | background: '#fff',
779 | color: '#333',
780 | zIndex: 10001
781 | };
782 |
783 | oD.appendChild(document.createTextNode('-'));
784 | oD.onclick = _s._toggleDebug;
785 | oD.title = 'Toggle SM2 debug console';
786 |
787 | if (navigator.userAgent.match(/msie 6/i)) {
788 | oD.style.position = 'absolute';
789 | oD.style.cursor = 'hand';
790 | }
791 |
792 | for (tmp in oToggle) {
793 | if (oToggle.hasOwnProperty(tmp)) {
794 | oD.style[tmp] = oToggle[tmp];
795 | }
796 | }
797 |
798 | }
799 |
800 | var oTarget = _s._getDocument();
801 |
802 | if (oTarget) {
803 |
804 | _s.oMC = _$('sm2-container')?_$('sm2-container'):document.createElement('div');
805 |
806 | var extraClass = (_s.debugMode?' sm2-debug':'')+(_s.debugFlash?' flash-debug':'');
807 |
808 | if (!_s.oMC.id) {
809 | _s.oMC.id = 'sm2-container';
810 | _s.oMC.className = 'movieContainer'+extraClass;
811 | // "hide" flash movie
812 | var s = null;
813 | oEl = null;
814 | if (_s.useHighPerformance) {
815 | s = {
816 | position: 'fixed',
817 | width: '8px',
818 | height: '8px',
819 | // must be at least 6px for flash to run fast. odd? yes.
820 | bottom: '0px',
821 | left: '0px',
822 | overflow: 'hidden'
823 | // zIndex:-1 // sit behind everything else - potentially dangerous/buggy?
824 | };
825 | } else {
826 | s = {
827 | position: 'absolute',
828 | width: '8px',
829 | height: '8px',
830 | top: '-9999px',
831 | left: '-9999px'
832 | };
833 | }
834 | var x = null;
835 | if (!_s.debugFlash) {
836 | for (x in s) {
837 | if (s.hasOwnProperty(x)) {
838 | _s.oMC.style[x] = s[x];
839 | }
840 | }
841 | }
842 | try {
843 | if (!_s.isIE) {
844 | _s.oMC.appendChild(oMovie);
845 | }
846 | oTarget.appendChild(_s.oMC);
847 | if (_s.isIE) {
848 | oEl = _s.oMC.appendChild(document.createElement('div'));
849 | oEl.className = 'sm2-object-box';
850 | oEl.innerHTML = movieHTML;
851 | }
852 | _s._appendSuccess = true;
853 | } catch(e) {
854 | throw new Error(_s._str('appXHTML'));
855 | }
856 | } else {
857 | // it's already in the document.
858 | if (_s.debugMode || _s.debugFlash) {
859 | _s.oMC.className += extraClass;
860 | }
861 | _s.oMC.appendChild(oMovie);
862 | if (_s.isIE) {
863 | oEl = _s.oMC.appendChild(document.createElement('div'));
864 | oEl.className = 'sm2-object-box';
865 | oEl.innerHTML = movieHTML;
866 | }
867 | _s._appendSuccess = true;
868 | }
869 |
870 | if (_s.debugMode && !_$(_s.debugID) && ((!_s._hasConsole || !_s.useConsole) || (_s.useConsole && _s._hasConsole && !_s.consoleOnly))) {
871 | var oDebug = document.createElement('div');
872 | oDebug.id = _s.debugID;
873 | oDebug.style.display = (_s.debugMode?'block':'none');
874 | if (_s.debugMode && !_$(oD.id)) {
875 | try {
876 | oTarget.appendChild(oD);
877 | } catch(e2) {
878 | throw new Error(_s._str('appXHTML'));
879 | }
880 | oTarget.appendChild(oDebug);
881 | }
882 | }
883 | oTarget = null;
884 | }
885 |
886 | if (specialCase) {
887 | _s._wD(specialCase);
888 | }
889 |
890 | _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s.useHighPerformance?', high performance mode, ':', ')+((_s.useFastPolling?'fast':'normal')+' polling')+(_s.wmode?', wmode: '+_s.wmode:'')+(_s.debugFlash?', flash debug mode':'')+' --', 1);
891 | _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?' (alternate URL)':''), 1);
892 | };
893 |
894 | this._writeDebug = function(sText, sType, bTimestamp) { // aliased to this._wD()
895 | if (!_s.debugMode) {
896 | return false;
897 | }
898 | if (typeof bTimestamp != 'undefined' && bTimestamp) {
899 | sText = sText+' | '+new Date().getTime();
900 | }
901 | if (_s._hasConsole && _s.useConsole) {
902 | var sMethod = _s._debugLevels[sType];
903 | if (typeof console[sMethod] != 'undefined') {
904 | console[sMethod](sText);
905 | } else {
906 | console.log(sText);
907 | }
908 | if (_s.useConsoleOnly) {
909 | return true;
910 | }
911 | }
912 | var sDID = 'soundmanager-debug';
913 | var o = null;
914 | try {
915 | o = _$(sDID);
916 | if (!o) {
917 | return false;
918 | }
919 | var oItem = document.createElement('div');
920 | if (++_s._wdCount % 2 === 0) {
921 | oItem.className = 'sm2-alt';
922 | }
923 | // sText = sText.replace(/\n/g,'
');
924 | if (typeof sType == 'undefined') {
925 | sType = 0;
926 | } else {
927 | sType = parseInt(sType, 10);
928 | }
929 | oItem.appendChild(document.createTextNode(sText));
930 | if (sType) {
931 | if (sType >= 2) {
932 | oItem.style.fontWeight = 'bold';
933 | }
934 | if (sType == 3) {
935 | oItem.style.color = '#ff3333';
936 | }
937 | }
938 | // o.appendChild(oItem); // top-to-bottom
939 | o.insertBefore(oItem, o.firstChild); // bottom-to-top
940 | } catch(e) {
941 | // oh well
942 | }
943 | o = null;
944 | };
945 | this._writeDebug._protected = true;
946 | this._wdCount = 0;
947 | this._wdCount._protected = true;
948 | this._wD = this._writeDebug;
949 |
950 | this._wDS = function(o,errorLevel) {
951 | if (!o) {
952 | return '';
953 | } else {
954 | return _s._wD(_s._str(o),errorLevel);
955 | }
956 | };
957 | this._wDS._protected = true;
958 |
959 | this._wDAlert = function(sText) {
960 | alert(sText);
961 | };
962 |
963 | if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) {
964 | _s._wD = _s._wDAlert;
965 | }
966 |
967 | this._toggleDebug = function() {
968 | var o = _$(_s.debugID);
969 | var oT = _$(_s.debugID+'-toggle');
970 | if (!o) {
971 | return false;
972 | }
973 | if (_s._debugOpen) {
974 | // minimize
975 | oT.innerHTML = '+';
976 | o.style.display = 'none';
977 | } else {
978 | oT.innerHTML = '-';
979 | o.style.display = 'block';
980 | }
981 | _s._debugOpen = !_s._debugOpen;
982 | };
983 |
984 | this._toggleDebug._protected = true;
985 |
986 | this._debug = function() {
987 | _s._wDS('currentObj', 1);
988 | for (var i=0, j = _s.soundIDs.length; i 0) {
1057 | _s._wDS('waitEI');
1058 | }
1059 | }
1060 | if (typeof _s.oninitmovie == 'function') {
1061 | setTimeout(_s.oninitmovie, 1);
1062 | }
1063 | };
1064 |
1065 | this.waitForExternalInterface = function() {
1066 | if (_s._waitingForEI) {
1067 | return false;
1068 | }
1069 | _s._waitingForEI = true;
1070 | if (_s._tryInitOnFocus && !_s._isFocused) {
1071 | _s._wDS('waitFocus');
1072 | return false;
1073 | }
1074 | if (_s.flashLoadTimeout > 0) {
1075 | if (!_s._didInit) {
1076 | var p = _s.getMoviePercent();
1077 | _s._wD(_s._str('waitImpatient',(p == 100?' (SWF loaded)':(p > 0?' (SWF '+p+'% loaded)':''))));
1078 | }
1079 | setTimeout(function() {
1080 | var p = _s.getMoviePercent();
1081 | if (!_s._didInit) {
1082 | _s._wD(_sm+': No Flash response within reasonable time after document load.\nLikely causes: '+(p === null || p === 0?'Loading '+_s.movieURL+' may have failed (and/or Flash '+_s.flashVersion+'+ not present?), ':'')+'Flash blocked or JS-Flash security error.'+(_s.debugFlash?' '+_s._str('checkSWF'): ''), 2);
1083 | if (!_s._overHTTP) {
1084 | _s._wDS('localFail', 2);
1085 | if (!_s.debugFlash) {
1086 | _s._wDS('tryDebug', 2);
1087 | }
1088 | }
1089 | if (p === 0) {
1090 | // 404, or blocked from loading?
1091 | _s._wD(_s._str('swf404',_s.url));
1092 | }
1093 | _s._debugTS('flashtojs', false, ': Timed out'+(_s._overHTTP)?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');
1094 | }
1095 | // if still not initialized and no other options, give up
1096 | if (!_s._didInit && _s._okToDisable) {
1097 | _s._failSafely(true); // don't disable, for reboot()
1098 | }
1099 | },
1100 | _s.flashLoadTimeout);
1101 | } else if (!_s._didInit) {
1102 | _s._wDS('waitForever');
1103 | }
1104 | };
1105 |
1106 | this.getMoviePercent = function() {
1107 | return (_s.o && typeof _s.o.PercentLoaded != 'undefined'?_s.o.PercentLoaded():null);
1108 | };
1109 |
1110 | this.handleFocus = function() {
1111 | if (_s._isFocused || !_s._tryInitOnFocus) {
1112 | return true;
1113 | }
1114 | _s._okToDisable = true;
1115 | _s._isFocused = true;
1116 | _s._wD('soundManager.handleFocus()');
1117 | if (_s._tryInitOnFocus) {
1118 | // giant Safari 3.1 hack - assume window in focus if mouse is moving, since document.hasFocus() not currently implemented.
1119 | window.removeEventListener('mousemove', _s.handleFocus, false);
1120 | }
1121 | // allow init to restart
1122 | _s._waitingForEI = false;
1123 | setTimeout(_s.waitForExternalInterface, 500);
1124 | // detach event
1125 | if (window.removeEventListener) {
1126 | window.removeEventListener('focus', _s.handleFocus, false);
1127 | } else if (window.detachEvent) {
1128 | window.detachEvent('onfocus', _s.handleFocus);
1129 | }
1130 | };
1131 |
1132 | this.initComplete = function(bNoDisable) {
1133 | if (_s._didInit) {
1134 | return false;
1135 | }
1136 | _s._didInit = true;
1137 | _s._wD('-- SoundManager 2 '+(_s._disabled?'failed to load':'loaded')+' ('+(_s._disabled?'security/load error':'OK')+') --', 1);
1138 | if (_s._disabled || bNoDisable) {
1139 | // _s._wD('soundManager.initComplete(): calling soundManager.onerror()',1);
1140 | _s._processOnReady();
1141 | _s._debugTS('onload', false);
1142 | _s.onerror.apply(window);
1143 | return false;
1144 | } else {
1145 | _s._debugTS('onload', true);
1146 | }
1147 | if (_s.waitForWindowLoad && !_s._windowLoaded) {
1148 | _s._wDS('waitOnload');
1149 | if (window.addEventListener) {
1150 | window.addEventListener('load', _s._initUserOnload, false);
1151 | } else if (window.attachEvent) {
1152 | window.attachEvent('onload', _s._initUserOnload);
1153 | }
1154 | return false;
1155 | } else {
1156 | if (_s.waitForWindowLoad && _s._windowLoaded) {
1157 | _s._wDS('docLoaded');
1158 | }
1159 | _s._initUserOnload();
1160 | }
1161 | };
1162 |
1163 | this._addOnReady = function(oMethod, oScope) {
1164 | _s._onready.push({
1165 | 'method': oMethod,
1166 | 'scope': (oScope || null),
1167 | 'fired': false
1168 | });
1169 | };
1170 |
1171 | this._processOnReady = function() {
1172 | if (!_s._didInit) {
1173 | // not ready yet.
1174 | return false;
1175 | }
1176 | var status = {
1177 | success: (!_s._disabled)
1178 | };
1179 | var queue = [];
1180 | for (var i=0, j = _s._onready.length; i 1?'s':''));
1187 | for (i = 0, j = queue.length; i 8) {
1550 | _t.instanceCount++;
1551 | }
1552 | _t.position = (typeof _t._iO.position != 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);
1553 | if (_t._iO.onplay) {
1554 | _t._iO.onplay.apply(_t);
1555 | }
1556 | _t.setVolume(_t._iO.volume, true); // restrict volume to instance options only
1557 | _t.setPan(_t._iO.pan, true);
1558 | _s.o._start(_t.sID, _t._iO.loop || 1, (_s.flashVersion == 9?_t.position:_t.position / 1000));
1559 | }
1560 | };
1561 |
1562 | this.start = this.play; // just for convenience
1563 | this.stop = function(bAll) {
1564 | if (_t.playState == 1) {
1565 | _t.playState = 0;
1566 | _t.paused = false;
1567 | // if (_s.defaultOptions.onstop) _s.defaultOptions.onstop.apply(_s);
1568 | if (_t._iO.onstop) {
1569 | _t._iO.onstop.apply(_t);
1570 | }
1571 | _s.o._stop(_t.sID, bAll);
1572 | _t.instanceCount = 0;
1573 | _t._iO = {};
1574 | // _t.instanceOptions = _t._iO;
1575 | }
1576 | };
1577 |
1578 | this.setPosition = function(nMsecOffset, bNoDebug) {
1579 | if (typeof nMsecOffset == 'undefined') {
1580 | nMsecOffset = 0;
1581 | }
1582 | var offset = Math.min(_t.duration, Math.max(nMsecOffset, 0)); // position >= 0 and <= current available (loaded) duration
1583 | _t._iO.position = offset;
1584 | if (!bNoDebug) {
1585 | // _s._wD('SMSound.setPosition('+nMsecOffset+')'+(nMsecOffset != offset?', corrected value: '+offset:''));
1586 | }
1587 | _s.o._setPosition(_t.sID, (_s.flashVersion == 9?_t._iO.position:_t._iO.position / 1000), (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing)
1588 | };
1589 |
1590 | this.pause = function() {
1591 | if (_t.paused || _t.playState === 0) {
1592 | return false;
1593 | }
1594 | _s._wD('SMSound.pause()');
1595 | _t.paused = true;
1596 | _s.o._pause(_t.sID);
1597 | if (_t._iO.onpause) {
1598 | _t._iO.onpause.apply(_t);
1599 | }
1600 | };
1601 |
1602 | this.resume = function() {
1603 | if (!_t.paused || _t.playState === 0) {
1604 | return false;
1605 | }
1606 | _s._wD('SMSound.resume()');
1607 | _t.paused = false;
1608 | _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume)
1609 | if (_t._iO.onresume) {
1610 | _t._iO.onresume.apply(_t);
1611 | }
1612 | };
1613 |
1614 | this.togglePause = function() {
1615 | _s._wD('SMSound.togglePause()');
1616 | if (_t.playState === 0) {
1617 | _t.play({
1618 | position: (_s.flashVersion == 9?_t.position:_t.position / 1000)
1619 | });
1620 | return false;
1621 | }
1622 | if (_t.paused) {
1623 | _t.resume();
1624 | } else {
1625 | _t.pause();
1626 | }
1627 | };
1628 |
1629 | this.setPan = function(nPan, bInstanceOnly) {
1630 | if (typeof nPan == 'undefined') {
1631 | nPan = 0;
1632 | }
1633 | if (typeof bInstanceOnly == 'undefined') {
1634 | bInstanceOnly = false;
1635 | }
1636 | _s.o._setPan(_t.sID, nPan);
1637 | _t._iO.pan = nPan;
1638 | if (!bInstanceOnly) {
1639 | _t.pan = nPan;
1640 | }
1641 | };
1642 |
1643 | this.setVolume = function(nVol, bInstanceOnly) {
1644 | if (typeof nVol == 'undefined') {
1645 | nVol = 100;
1646 | }
1647 | if (typeof bInstanceOnly == 'undefined') {
1648 | bInstanceOnly = false;
1649 | }
1650 | _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol);
1651 | _t._iO.volume = nVol;
1652 | if (!bInstanceOnly) {
1653 | _t.volume = nVol;
1654 | }
1655 | };
1656 |
1657 | this.mute = function() {
1658 | _t.muted = true;
1659 | _s.o._setVolume(_t.sID, 0);
1660 | };
1661 |
1662 | this.unmute = function() {
1663 | _t.muted = false;
1664 | var hasIO = typeof _t._iO.volume != 'undefined';
1665 | _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume);
1666 | };
1667 |
1668 | this.toggleMute = function() {
1669 | if (_t.muted) {
1670 | _t.unmute();
1671 | } else {
1672 | _t.mute();
1673 | }
1674 | };
1675 |
1676 | // --- "private" methods called by Flash ---
1677 |
1678 | this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration) {
1679 | if (!_t._iO.isMovieStar) {
1680 | _t.bytesLoaded = nBytesLoaded;
1681 | _t.bytesTotal = nBytesTotal;
1682 | _t.duration = Math.floor(nDuration);
1683 | _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);
1684 | if (_t.durationEstimate === undefined) {
1685 | // reported bug?
1686 | _t.durationEstimate = _t.duration;
1687 | }
1688 | if (_t.readyState != 3 && _t._iO.whileloading) {
1689 | _t._iO.whileloading.apply(_t);
1690 | }
1691 | } else {
1692 | _t.bytesLoaded = nBytesLoaded;
1693 | _t.bytesTotal = nBytesTotal;
1694 | _t.duration = Math.floor(nDuration);
1695 | _t.durationEstimate = _t.duration;
1696 | if (_t.readyState != 3 && _t._iO.whileloading) {
1697 | _t._iO.whileloading.apply(_t);
1698 | }
1699 | }
1700 | };
1701 |
1702 | this._onid3 = function(oID3PropNames, oID3Data) {
1703 | // oID3PropNames: string array (names)
1704 | // ID3Data: string array (data)
1705 | _s._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.');
1706 | var oData = [];
1707 | for (var i=0, j = oID3PropNames.length; i 0) {
1723 | // can happen at the end of a video where nPosition == 33 for some reason, after finishing.???
1724 | // can also happen with a normal stop operation. This resets the position to 0.
1725 | // _s._writeDebug('Note: Not playing, but position = '+nPosition);
1726 | nPosition = 0;
1727 | }
1728 | _t.position = nPosition;
1729 |
1730 | if (_s.flashVersion > 8) {
1731 | if (_t._iO.usePeakData && typeof oPeakData != 'undefined' && oPeakData) {
1732 | _t.peakData = {
1733 | left: oPeakData.leftPeak,
1734 | right: oPeakData.rightPeak
1735 | };
1736 | }
1737 | if (_t._iO.useWaveformData && typeof oWaveformDataLeft != 'undefined' && oWaveformDataLeft) {
1738 | _t.waveformData = {
1739 | left: oWaveformDataLeft.split(','),
1740 | right: oWaveformDataRight.split(',')
1741 | };
1742 | }
1743 | if (_t._iO.useEQData) {
1744 | if (typeof oEQData != 'undefined' && oEQData.leftEQ) {
1745 | var eqLeft = oEQData.leftEQ.split(',');
1746 | _t.eqData = eqLeft;
1747 | _t.eqData.left = eqLeft;
1748 | if (typeof oEQData.rightEQ != 'undefined' && oEQData.rightEQ) {
1749 | _t.eqData.right = oEQData.rightEQ.split(',');
1750 | }
1751 | }
1752 | }
1753 | }
1754 |
1755 | if (_t.playState == 1) {
1756 | // special case/hack: ensure buffering is false (instant load from cache, thus buffering stuck at 1?)
1757 | if (_t.isBuffering) {
1758 | _t._onbufferchange(0);
1759 | }
1760 | if (_t._iO.whileplaying) {
1761 | _t._iO.whileplaying.apply(_t); // flash may call after actual finish
1762 | }
1763 | if (_t.loaded && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) {
1764 | _s._wD('duration-position <= onbeforefinishtime: '+_t.duration+' - '+_t.position+' <= '+_t._iO.onbeforefinishtime+' ('+(_t.duration - _t.position)+')');
1765 | _t._onbeforefinish();
1766 | }
1767 | }
1768 | };
1769 |
1770 | this._onload = function(bSuccess) {
1771 | var fN = 'SMSound._onload(): ';
1772 | bSuccess = (bSuccess == 1?true:false);
1773 | _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' loaded.':' failed to load? - '+_t.url), (bSuccess?1:2));
1774 | if (!bSuccess) {
1775 | if (_s.sandbox.noRemote === true) {
1776 | _s._wD(fN+_s._str('noNet'), 1);
1777 | }
1778 | if (_s.sandbox.noLocal === true) {
1779 | _s._wD(fN+_s._str('noLocal'), 1);
1780 | }
1781 | }
1782 | _t.loaded = bSuccess;
1783 | _t.readyState = bSuccess?3:2;
1784 | if (_t._iO.onload) {
1785 | _t._iO.onload.apply(_t);
1786 | }
1787 | };
1788 |
1789 | this._onbeforefinish = function() {
1790 | if (!_t.didBeforeFinish) {
1791 | _t.didBeforeFinish = true;
1792 | if (_t._iO.onbeforefinish) {
1793 | _s._wD('SMSound._onbeforefinish(): "'+_t.sID+'"');
1794 | _t._iO.onbeforefinish.apply(_t);
1795 | }
1796 | }
1797 | };
1798 |
1799 | this._onjustbeforefinish = function(msOffset) {
1800 | // msOffset: "end of sound" delay actual value (eg. 200 msec, value at event fire time was 187)
1801 | if (!_t.didJustBeforeFinish) {
1802 | _t.didJustBeforeFinish = true;
1803 | if (_t._iO.onjustbeforefinish) {
1804 | _s._wD('SMSound._onjustbeforefinish(): "'+_t.sID+'"');
1805 | _t._iO.onjustbeforefinish.apply(_t);
1806 | }
1807 | }
1808 | };
1809 |
1810 | this._onfinish = function() {
1811 | // sound has finished playing
1812 | // TODO: calling user-defined onfinish() should happen after setPosition(0)
1813 | // OR: onfinish() and then setPosition(0) is bad.
1814 | if (_t._iO.onbeforefinishcomplete) {
1815 | _t._iO.onbeforefinishcomplete.apply(_t);
1816 | }
1817 | // reset some state items
1818 | _t.didBeforeFinish = false;
1819 | _t.didJustBeforeFinish = false;
1820 | if (_t.instanceCount) {
1821 | _t.instanceCount--;
1822 | if (!_t.instanceCount) {
1823 | // reset instance options
1824 | // _t.setPosition(0);
1825 | _t.playState = 0;
1826 | _t.paused = false;
1827 | _t.instanceCount = 0;
1828 | _t.instanceOptions = {};
1829 | }
1830 | if (!_t.instanceCount || _t._iO.multiShotEvents) {
1831 | // fire onfinish for last, or every instance
1832 | if (_t._iO.onfinish) {
1833 | _s._wD('SMSound._onfinish(): "'+_t.sID+'"');
1834 | _t._iO.onfinish.apply(_t);
1835 | }
1836 | }
1837 | } else {
1838 | if (_t.useVideo) {
1839 | // video has finished
1840 | // may need to reset position for next play call, "rewind"
1841 | // _t.setPosition(0);
1842 | }
1843 | // _t.setPosition(0);
1844 | }
1845 |
1846 | };
1847 |
1848 | this._onmetadata = function(oMetaData) {
1849 | // movieStar mode only
1850 | var fN = 'SMSound.onmetadata()';
1851 | _s._wD(fN);
1852 | // Contains a subset of metadata. Note that files may have their own unique metadata.
1853 | // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html
1854 | if (!oMetaData.width && !oMetaData.height) {
1855 | _s._wDS('noWH');
1856 | oMetaData.width = 320;
1857 | oMetaData.height = 240;
1858 | }
1859 | _t.metadata = oMetaData; // potentially-large object from flash
1860 | _t.width = oMetaData.width;
1861 | _t.height = oMetaData.height;
1862 | if (_t._iO.onmetadata) {
1863 | _s._wD(fN+': "'+_t.sID+'"');
1864 | _t._iO.onmetadata.apply(_t);
1865 | }
1866 | _s._wD(fN+' complete');
1867 | };
1868 |
1869 | this._onbufferchange = function(bIsBuffering) {
1870 | var fN = 'SMSound._onbufferchange()';
1871 | if (_t.playState === 0) {
1872 | // ignore if not playing
1873 | return false;
1874 | }
1875 | if (bIsBuffering == _t.isBuffering) {
1876 | // ignore initial "false" default, if matching
1877 | _s._wD(fN+': ignoring false default / loaded sound');
1878 | return false;
1879 | }
1880 | _t.isBuffering = (bIsBuffering == 1?true:false);
1881 | if (_t._iO.onbufferchange) {
1882 | _s._wD(fN+': '+bIsBuffering);
1883 | _t._iO.onbufferchange.apply(_t);
1884 | }
1885 | };
1886 |
1887 | this._ondataerror = function(sError) {
1888 | // flash 9 wave/eq data handler
1889 | if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish().
1890 | _s._wD('SMSound._ondataerror(): '+sError);
1891 | if (_t._iO.ondataerror) {
1892 | _t._iO.ondataerror.apply(_t);
1893 | }
1894 | } else {
1895 | // _s._wD('SMSound._ondataerror(): ignoring');
1896 | }
1897 | };
1898 |
1899 | }; // SMSound()
1900 |
1901 | this._onfullscreenchange = function(bFullScreen) {
1902 | _s._wD('onfullscreenchange(): '+bFullScreen);
1903 | _s.isFullScreen = (bFullScreen == 1?true:false);
1904 | if (!_s.isFullScreen) {
1905 | // attempt to restore window focus after leaving full-screen
1906 | try {
1907 | window.focus();
1908 | _s._wD('window.focus()');
1909 | } catch(e) {
1910 | // oh well
1911 | }
1912 | }
1913 | };
1914 |
1915 | // register a few event handlers
1916 | if (window.addEventListener) {
1917 | window.addEventListener('focus', _s.handleFocus, false);
1918 | window.addEventListener('load', _s.beginDelayedInit, false);
1919 | window.addEventListener('unload', _s.destruct, false);
1920 | if (_s._tryInitOnFocus) {
1921 | window.addEventListener('mousemove', _s.handleFocus, false); // massive Safari focus hack
1922 | }
1923 | } else if (window.attachEvent) {
1924 | window.attachEvent('onfocus', _s.handleFocus);
1925 | window.attachEvent('onload', _s.beginDelayedInit);
1926 | window.attachEvent('unload', _s.destruct);
1927 | } else {
1928 | // no add/attachevent support - safe to assume no JS -> Flash either.
1929 | _s._debugTS('onload', false);
1930 | soundManager.onerror();
1931 | soundManager.disable();
1932 | }
1933 |
1934 | if (document.addEventListener) {
1935 | document.addEventListener('DOMContentLoaded', _s.domContentLoaded, false);
1936 | }
1937 |
1938 | } // SoundManager()
1939 |
1940 | // var SM2_DEFER = true; // un-comment or define in your own script to prevent immediate SoundManager() constructor call+start-up.
1941 | // if deferring, construct later with window.soundManager = new SoundManager(); followed by soundManager.beginDelayedInit();
1942 |
1943 | if (typeof SM2_DEFER == 'undefined' || !SM2_DEFER) {
1944 | soundManager = new SoundManager();
1945 | }
--------------------------------------------------------------------------------
/static/soundmanager2.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/soundmanager2.swf
--------------------------------------------------------------------------------
/static/svg2canvas.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/svg2canvas.jar
--------------------------------------------------------------------------------
/static/tileset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/tileset.png
--------------------------------------------------------------------------------
/static/walk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk.gif
--------------------------------------------------------------------------------
/static/walk2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk2.png
--------------------------------------------------------------------------------
/static/walk2.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batiste/django-rpg/6222bdca162da68f6a2906a2d73d6e79b6acfdc7/static/walk2.xcf
--------------------------------------------------------------------------------
/templates/404.html:
--------------------------------------------------------------------------------
1 | Not Found
2 |
--------------------------------------------------------------------------------
/templates/500.html:
--------------------------------------------------------------------------------
1 | Internal Server Error
2 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Rpg Chat Demo
6 |
7 |
8 |
9 |
10 |
{{ map.name }}
11 | ({{ map.x }}, {{ map.y }})
12 |
13 |

14 |
15 |
16 |
Map saved.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
41 |
42 |
43 |
44 |
45 |
46 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/templates/message.html:
--------------------------------------------------------------------------------
1 | {{ message.from }}: {{ message.body }}
2 |
--------------------------------------------------------------------------------
/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.conf import settings
3 |
4 | urlpatterns = patterns('rpg.views',
5 | ('^$', 'main'),
6 | ('^a/message/new$', 'message_new'),
7 | ('^a/room/updates$', 'room_updates'),
8 | ('^a/player/new$', 'player_new'),
9 | ('^a/player/update_position$', 'player_update_position'),
10 | ('^a/change_room$', 'change_room'),
11 | ('^a/save_map', 'save_map'),
12 | ('^a/effect', 'effect'),
13 | ('^a/fight/new', 'fight_new'),
14 |
15 | )
16 |
17 | urlpatterns += patterns('',
18 | ('^static/(?P.*)$', 'django.views.static.serve',
19 | {'document_root': settings.MEDIA_ROOT, 'show_indexes':True}),
20 | )
21 |
22 |
--------------------------------------------------------------------------------