mirror of
https://mau.dev/maunium/synapse.git
synced 2024-12-23 21:44:13 +01:00
Merge branch 'release-v0.2.3' of github.com:matrix-org/synapse
Conflicts: webclient/room/room-controller.js
This commit is contained in:
commit
e3aec9bc81
61 changed files with 8121 additions and 3917 deletions
19
CHANGES.rst
19
CHANGES.rst
|
@ -1,3 +1,22 @@
|
||||||
|
Changes in synapse 0.2.3 (2014-09-12)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Homeserver:
|
||||||
|
* Fix bug where we stopped sending events to remote home servers if a
|
||||||
|
user from that home server left, even if there were some still in the
|
||||||
|
room.
|
||||||
|
* Fix bugs in the state conflict resolution where it was incorrectly
|
||||||
|
rejecting events.
|
||||||
|
|
||||||
|
Webclient:
|
||||||
|
* Display room names and topics.
|
||||||
|
* Allow setting/editing of room names and topics.
|
||||||
|
* Display information about rooms on the main page.
|
||||||
|
* Handle ban and kick events in real time.
|
||||||
|
* VoIP UI and reliabilty improvements.
|
||||||
|
* Improvements to initial startup speed.
|
||||||
|
* Don't display duplicate join events.
|
||||||
|
|
||||||
Changes in synapse 0.2.2 (2014-09-06)
|
Changes in synapse 0.2.2 (2014-09-06)
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2.2
|
0.2.3
|
||||||
|
|
|
@ -24,7 +24,7 @@ If you already have an account, you must **login** into it.
|
||||||
|
|
||||||
`Try out the fiddle`__
|
`Try out the fiddle`__
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/4q2jyxng/
|
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/synapse/tree/master/jsfiddles/register_login
|
||||||
|
|
||||||
Registration
|
Registration
|
||||||
------------
|
------------
|
||||||
|
@ -87,7 +87,7 @@ user and **send a message** to that room.
|
||||||
|
|
||||||
`Try out the fiddle`__
|
`Try out the fiddle`__
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/zL3zto9g/
|
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/synapse/tree/master/jsfiddles/create_room_send_msg
|
||||||
|
|
||||||
Creating a room
|
Creating a room
|
||||||
---------------
|
---------------
|
||||||
|
@ -137,7 +137,7 @@ join a room **via a room alias** if one was set up.
|
||||||
|
|
||||||
`Try out the fiddle`__
|
`Try out the fiddle`__
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/7fhotf1b/
|
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/synapse/tree/master/jsfiddles/room_memberships
|
||||||
|
|
||||||
Inviting a user to a room
|
Inviting a user to a room
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -183,7 +183,7 @@ of getting events, depending on what the client already knows.
|
||||||
|
|
||||||
`Try out the fiddle`__
|
`Try out the fiddle`__
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/vw11mg37/
|
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/synapse/tree/master/jsfiddles/event_stream
|
||||||
|
|
||||||
Getting all state
|
Getting all state
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -633,4 +633,4 @@ application.
|
||||||
|
|
||||||
`Try out the fiddle`__
|
`Try out the fiddle`__
|
||||||
|
|
||||||
.. __: http://jsfiddle.net/uztL3yme/
|
.. __: http://jsfiddle.net/gh/get/jquery/1.8.3/matrix-org/synapse/tree/master/jsfiddles/example_app
|
||||||
|
|
79
docs/human-id-rules.rst
Normal file
79
docs/human-id-rules.rst
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
This document outlines the format for human-readable IDs within matrix.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
UTF-8 is quickly becoming the standard character encoding set on the web. As
|
||||||
|
such, Matrix requires that all strings MUST be encoded as UTF-8. However,
|
||||||
|
using Unicode as the character set for human-readable IDs is troublesome. There
|
||||||
|
are many different characters which appear identical to each other, but would
|
||||||
|
identify different users. In addition, there are non-printable characters which
|
||||||
|
cannot be rendered by the end-user. This opens up a security vulnerability with
|
||||||
|
phishing/spoofing of IDs, commonly known as a homograph attack.
|
||||||
|
|
||||||
|
Web browers encountered this problem when International Domain Names were
|
||||||
|
introduced. A variety of checks were put in place in order to protect users. If
|
||||||
|
an address failed the check, the raw punycode would be displayed to disambiguate
|
||||||
|
the address. Similar checks are performed by home servers in Matrix. However,
|
||||||
|
Matrix does not use punycode representations, and so does not show raw punycode
|
||||||
|
on a failed check. Instead, home servers must outright reject these misleading
|
||||||
|
IDs.
|
||||||
|
|
||||||
|
Types of human-readable IDs
|
||||||
|
---------------------------
|
||||||
|
There are two main human-readable IDs in question:
|
||||||
|
|
||||||
|
- Room aliases
|
||||||
|
- User IDs
|
||||||
|
|
||||||
|
Room aliases look like ``#localpart:domain``. These aliases point to opaque
|
||||||
|
non human-readable room IDs. These pointers can change, so there is already an
|
||||||
|
issue present with the same ID pointing to a different destination at a later
|
||||||
|
date.
|
||||||
|
|
||||||
|
User IDs look like ``@localpart:domain``. These represent actual end-users, and
|
||||||
|
unlike room aliases, there is no layer of indirection. This presents a much
|
||||||
|
greater concern with homograph attacks.
|
||||||
|
|
||||||
|
Checks
|
||||||
|
------
|
||||||
|
- Similar to web browsers.
|
||||||
|
- blacklisted chars (e.g. non-printable characters)
|
||||||
|
- mix of language sets from 'preferred' language not allowed.
|
||||||
|
- Language sets from CLDR dataset.
|
||||||
|
- Treated in segments (localpart, domain)
|
||||||
|
- Additional restrictions for ease of processing IDs.
|
||||||
|
- Room alias localparts MUST NOT have ``#`` or ``:``.
|
||||||
|
- User ID localparts MUST NOT have ``@`` or ``:``.
|
||||||
|
|
||||||
|
Rejecting
|
||||||
|
---------
|
||||||
|
- Home servers MUST reject room aliases which do not pass the check, both on
|
||||||
|
GETs and PUTs.
|
||||||
|
- Home servers MUST reject user ID localparts which do not pass the check, both
|
||||||
|
on creation and on events.
|
||||||
|
- Any home server whose domain does not pass this check, MUST use their punycode
|
||||||
|
domain name instead of the IDN, to prevent other home servers rejecting you.
|
||||||
|
- Error code is ``M_FAILED_HUMAN_ID_CHECK``. (generic enough for both failing
|
||||||
|
due to homograph attacks, and failing due to including ``:`` s, etc)
|
||||||
|
- Error message MAY go into further information about which characters were
|
||||||
|
rejected and why.
|
||||||
|
- Error message SHOULD contain a ``failed_keys`` key which contains an array
|
||||||
|
of strings which represent the keys which failed the check e.g::
|
||||||
|
|
||||||
|
failed_keys: [ user_id, room_alias ]
|
||||||
|
|
||||||
|
Other considerations
|
||||||
|
--------------------
|
||||||
|
- Basic security: Informational key on the event attached by HS to say "unsafe
|
||||||
|
ID". Problem: clients can just ignore it, and since it will appear only very
|
||||||
|
rarely, easy to forget when implementing clients.
|
||||||
|
- Moderate security: Requires client handshake. Forces clients to implement
|
||||||
|
a check, else they cannot communicate with the misleading ID. However, this is
|
||||||
|
extra overhead in both client implementations and round-trips.
|
||||||
|
- High security: Outright rejection of the ID at the point of creation /
|
||||||
|
receiving event. Point of creation rejection is preferable to avoid the ID
|
||||||
|
entering the system in the first place. However, malicious HSes can just allow
|
||||||
|
the ID. Hence, other home servers must reject them if they see them in events.
|
||||||
|
Client never sees the problem ID, provided the HS is correctly implemented.
|
||||||
|
- High security decided; client doesn't need to worry about it, no additional
|
||||||
|
protocol complexity aside from rejection of an event.
|
|
@ -1251,6 +1251,32 @@ Or a rejected call:
|
||||||
Calls are negotiated according to the WebRTC specification.
|
Calls are negotiated according to the WebRTC specification.
|
||||||
|
|
||||||
|
|
||||||
|
Glare
|
||||||
|
-----
|
||||||
|
This specification aims to address the problem of two users calling each other
|
||||||
|
at roughly the same time and their invites crossing on the wire. It is a far
|
||||||
|
better experience for the users if their calls are connected if it is clear
|
||||||
|
that their intention is to set up a call with one another.
|
||||||
|
|
||||||
|
In Matrix, calls are to rooms rather than users (even if those rooms may only
|
||||||
|
contain one other user) so we consider calls which are to the same room.
|
||||||
|
|
||||||
|
The rules for dealing with such a situation are as follows:
|
||||||
|
|
||||||
|
- If an invite to a room is received whilst the client is preparing to send an
|
||||||
|
invite to the same room, the client should cancel its outgoing call and
|
||||||
|
instead automatically accept the incoming call on behalf of the user.
|
||||||
|
- If an invite to a room is received after the client has sent an invite to the
|
||||||
|
same room and is waiting for a response, the client should perform a
|
||||||
|
lexicographical comparison of the call IDs of the two calls and use the
|
||||||
|
lesser of the two calls, aborting the greater. If the incoming call is the
|
||||||
|
lesser, the client should accept this call on behalf of the user.
|
||||||
|
|
||||||
|
The call setup should appear seamless to the user as if they had simply placed
|
||||||
|
a call and the other party had accepted. Thusly, any media stream that had been
|
||||||
|
setup for use on a call should be transferred and used for the call that
|
||||||
|
replaces it.
|
||||||
|
|
||||||
Profiles
|
Profiles
|
||||||
========
|
========
|
||||||
.. NOTE::
|
.. NOTE::
|
||||||
|
|
|
@ -19,7 +19,12 @@ $('.login').live('click', function() {
|
||||||
showLoggedIn(data);
|
showLoggedIn(data);
|
||||||
},
|
},
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
var errMsg = "To try this, you need a home server running!";
|
||||||
|
var errJson = $.parseJSON(err.responseText);
|
||||||
|
if (errJson) {
|
||||||
|
errMsg = JSON.stringify(errJson);
|
||||||
|
}
|
||||||
|
alert(errMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,7 +58,12 @@ $('.login').live('click', function() {
|
||||||
showLoggedIn(data);
|
showLoggedIn(data);
|
||||||
},
|
},
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
var errMsg = "To try this, you need a home server running!";
|
||||||
|
var errJson = $.parseJSON(err.responseText);
|
||||||
|
if (errJson) {
|
||||||
|
errMsg = JSON.stringify(errJson);
|
||||||
|
}
|
||||||
|
alert(errMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
7
jsfiddles/example_app/demo.details
Normal file
7
jsfiddles/example_app/demo.details
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
name: Example Matrix Client
|
||||||
|
description: Includes login, live event streaming, creating rooms, sending messages and viewing member lists.
|
||||||
|
authors:
|
||||||
|
- matrix.org
|
||||||
|
resources:
|
||||||
|
- http://matrix.org
|
||||||
|
normalize_css: no
|
|
@ -20,7 +20,12 @@ $('.register').live('click', function() {
|
||||||
showLoggedIn(data);
|
showLoggedIn(data);
|
||||||
},
|
},
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
var errMsg = "To try this, you need a home server running!";
|
||||||
|
var errJson = $.parseJSON(err.responseText);
|
||||||
|
if (errJson) {
|
||||||
|
errMsg = JSON.stringify(errJson);
|
||||||
|
}
|
||||||
|
alert(errMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -36,7 +41,12 @@ var login = function(user, password) {
|
||||||
showLoggedIn(data);
|
showLoggedIn(data);
|
||||||
},
|
},
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
var errMsg = "To try this, you need a home server running!";
|
||||||
|
var errJson = $.parseJSON(err.responseText);
|
||||||
|
if (errJson) {
|
||||||
|
errMsg = JSON.stringify(errJson);
|
||||||
|
}
|
||||||
|
alert(errMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,12 @@ $('.login').live('click', function() {
|
||||||
showLoggedIn(data);
|
showLoggedIn(data);
|
||||||
},
|
},
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
alert(JSON.stringify($.parseJSON(err.responseText)));
|
var errMsg = "To try this, you need a home server running!";
|
||||||
|
var errJson = $.parseJSON(err.responseText);
|
||||||
|
if (errJson) {
|
||||||
|
errMsg = JSON.stringify(errJson);
|
||||||
|
}
|
||||||
|
alert(errMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,4 +16,4 @@
|
||||||
""" This is a reference implementation of a synapse home server.
|
""" This is a reference implementation of a synapse home server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.2.2"
|
__version__ = "0.2.3"
|
||||||
|
|
|
@ -69,6 +69,7 @@ class Pdu(JsonEncodedObject):
|
||||||
"prev_state_id",
|
"prev_state_id",
|
||||||
"prev_state_origin",
|
"prev_state_origin",
|
||||||
"required_power_level",
|
"required_power_level",
|
||||||
|
"user_id",
|
||||||
]
|
]
|
||||||
|
|
||||||
internal_keys = [
|
internal_keys = [
|
||||||
|
|
|
@ -593,6 +593,12 @@ class RoomListHandler(BaseHandler):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_public_room_list(self):
|
def get_public_room_list(self):
|
||||||
chunk = yield self.store.get_rooms(is_public=True)
|
chunk = yield self.store.get_rooms(is_public=True)
|
||||||
|
for room in chunk:
|
||||||
|
joined_members = yield self.store.get_room_members(
|
||||||
|
room_id=room["room_id"],
|
||||||
|
membership=Membership.JOIN
|
||||||
|
)
|
||||||
|
room["num_joined_members"] = len(joined_members)
|
||||||
# FIXME (erikj): START is no longer a valid value
|
# FIXME (erikj): START is no longer a valid value
|
||||||
defer.returnValue({"start": "START", "end": "END", "chunk": chunk})
|
defer.returnValue({"start": "START", "end": "END", "chunk": chunk})
|
||||||
|
|
||||||
|
|
157
synapse/state.py
157
synapse/state.py
|
@ -115,6 +115,8 @@ class StateHandler(object):
|
||||||
|
|
||||||
is_new = yield self._handle_new_state(new_pdu)
|
is_new = yield self._handle_new_state(new_pdu)
|
||||||
|
|
||||||
|
logger.debug("is_new: %s %s %s", is_new, new_pdu.pdu_id, new_pdu.origin)
|
||||||
|
|
||||||
if is_new:
|
if is_new:
|
||||||
yield self.store.update_current_state(
|
yield self.store.update_current_state(
|
||||||
pdu_id=new_pdu.pdu_id,
|
pdu_id=new_pdu.pdu_id,
|
||||||
|
@ -134,7 +136,9 @@ class StateHandler(object):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@log_function
|
@log_function
|
||||||
def _handle_new_state(self, new_pdu):
|
def _handle_new_state(self, new_pdu):
|
||||||
tree = yield self.store.get_unresolved_state_tree(new_pdu)
|
tree, missing_branch = yield self.store.get_unresolved_state_tree(
|
||||||
|
new_pdu
|
||||||
|
)
|
||||||
new_branch, current_branch = tree
|
new_branch, current_branch = tree
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -142,64 +146,17 @@ class StateHandler(object):
|
||||||
new_branch, current_branch
|
new_branch, current_branch
|
||||||
)
|
)
|
||||||
|
|
||||||
if not current_branch:
|
if missing_branch is not None:
|
||||||
# There is no current state
|
# We're missing some PDUs. Fetch them.
|
||||||
defer.returnValue(True)
|
# TODO (erikj): Limit this.
|
||||||
return
|
missing_prev = tree[missing_branch][-1]
|
||||||
|
|
||||||
n = new_branch[-1]
|
|
||||||
c = current_branch[-1]
|
|
||||||
|
|
||||||
if n.pdu_id == c.pdu_id and n.origin == c.origin:
|
|
||||||
# We have all the PDUs we need, so we can just do the conflict
|
|
||||||
# resolution.
|
|
||||||
|
|
||||||
if len(current_branch) == 1:
|
|
||||||
# This is a direct clobber so we can just...
|
|
||||||
defer.returnValue(True)
|
|
||||||
|
|
||||||
conflict_res = [
|
|
||||||
self._do_power_level_conflict_res,
|
|
||||||
self._do_chain_length_conflict_res,
|
|
||||||
self._do_hash_conflict_res,
|
|
||||||
]
|
|
||||||
|
|
||||||
for algo in conflict_res:
|
|
||||||
new_res, curr_res = algo(new_branch, current_branch)
|
|
||||||
|
|
||||||
if new_res < curr_res:
|
|
||||||
defer.returnValue(False)
|
|
||||||
elif new_res > curr_res:
|
|
||||||
defer.returnValue(True)
|
|
||||||
|
|
||||||
raise Exception("Conflict resolution failed.")
|
|
||||||
|
|
||||||
else:
|
|
||||||
# We need to ask for PDUs.
|
|
||||||
missing_prev = max(
|
|
||||||
new_branch[-1], current_branch[-1],
|
|
||||||
key=lambda x: x.depth
|
|
||||||
)
|
|
||||||
|
|
||||||
if not hasattr(missing_prev, "prev_state_id"):
|
|
||||||
# FIXME Hmm
|
|
||||||
# temporary fallback
|
|
||||||
for algo in conflict_res:
|
|
||||||
new_res, curr_res = algo(new_branch, current_branch)
|
|
||||||
|
|
||||||
if new_res < curr_res:
|
|
||||||
defer.returnValue(False)
|
|
||||||
elif new_res > curr_res:
|
|
||||||
defer.returnValue(True)
|
|
||||||
return
|
|
||||||
|
|
||||||
pdu_id = missing_prev.prev_state_id
|
pdu_id = missing_prev.prev_state_id
|
||||||
origin = missing_prev.prev_state_origin
|
origin = missing_prev.prev_state_origin
|
||||||
|
|
||||||
is_missing = yield self.store.get_pdu(pdu_id, origin) is None
|
is_missing = yield self.store.get_pdu(pdu_id, origin) is None
|
||||||
|
|
||||||
if not is_missing:
|
if not is_missing:
|
||||||
raise Exception("Conflict resolution failed.")
|
raise Exception("Conflict resolution failed")
|
||||||
|
|
||||||
yield self._replication.get_pdu(
|
yield self._replication.get_pdu(
|
||||||
destination=missing_prev.origin,
|
destination=missing_prev.origin,
|
||||||
|
@ -211,23 +168,93 @@ class StateHandler(object):
|
||||||
updated_current = yield self._handle_new_state(new_pdu)
|
updated_current = yield self._handle_new_state(new_pdu)
|
||||||
defer.returnValue(updated_current)
|
defer.returnValue(updated_current)
|
||||||
|
|
||||||
def _do_power_level_conflict_res(self, new_branch, current_branch):
|
if not current_branch:
|
||||||
max_power_new = max(
|
# There is no current state
|
||||||
new_branch[:-1],
|
defer.returnValue(True)
|
||||||
key=lambda t: t.power_level
|
return
|
||||||
).power_level
|
|
||||||
|
|
||||||
max_power_current = max(
|
n = new_branch[-1]
|
||||||
current_branch[:-1],
|
c = current_branch[-1]
|
||||||
key=lambda t: t.power_level
|
|
||||||
).power_level
|
|
||||||
|
|
||||||
return (max_power_new, max_power_current)
|
common_ancestor = n.pdu_id == c.pdu_id and n.origin == c.origin
|
||||||
|
|
||||||
def _do_chain_length_conflict_res(self, new_branch, current_branch):
|
if common_ancestor:
|
||||||
|
# We found a common ancestor!
|
||||||
|
|
||||||
|
if len(current_branch) == 1:
|
||||||
|
# This is a direct clobber so we can just...
|
||||||
|
defer.returnValue(True)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# We didn't find a common ancestor. This is probably fine.
|
||||||
|
pass
|
||||||
|
|
||||||
|
result = yield self._do_conflict_res(
|
||||||
|
new_branch, current_branch, common_ancestor
|
||||||
|
)
|
||||||
|
defer.returnValue(result)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _do_conflict_res(self, new_branch, current_branch, common_ancestor):
|
||||||
|
conflict_res = [
|
||||||
|
self._do_power_level_conflict_res,
|
||||||
|
self._do_chain_length_conflict_res,
|
||||||
|
self._do_hash_conflict_res,
|
||||||
|
]
|
||||||
|
|
||||||
|
for algo in conflict_res:
|
||||||
|
new_res, curr_res = yield defer.maybeDeferred(
|
||||||
|
algo,
|
||||||
|
new_branch, current_branch, common_ancestor
|
||||||
|
)
|
||||||
|
|
||||||
|
if new_res < curr_res:
|
||||||
|
defer.returnValue(False)
|
||||||
|
elif new_res > curr_res:
|
||||||
|
defer.returnValue(True)
|
||||||
|
|
||||||
|
raise Exception("Conflict resolution failed.")
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _do_power_level_conflict_res(self, new_branch, current_branch,
|
||||||
|
common_ancestor):
|
||||||
|
new_powers_deferreds = []
|
||||||
|
for e in new_branch[:-1] if common_ancestor else new_branch:
|
||||||
|
if hasattr(e, "user_id"):
|
||||||
|
new_powers_deferreds.append(
|
||||||
|
self.store.get_power_level(e.context, e.user_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
current_powers_deferreds = []
|
||||||
|
for e in current_branch[:-1] if common_ancestor else current_branch:
|
||||||
|
if hasattr(e, "user_id"):
|
||||||
|
current_powers_deferreds.append(
|
||||||
|
self.store.get_power_level(e.context, e.user_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
new_powers = yield defer.gatherResults(
|
||||||
|
new_powers_deferreds,
|
||||||
|
consumeErrors=True
|
||||||
|
)
|
||||||
|
|
||||||
|
current_powers = yield defer.gatherResults(
|
||||||
|
current_powers_deferreds,
|
||||||
|
consumeErrors=True
|
||||||
|
)
|
||||||
|
|
||||||
|
max_power_new = max(new_powers)
|
||||||
|
max_power_current = max(current_powers)
|
||||||
|
|
||||||
|
defer.returnValue(
|
||||||
|
(max_power_new, max_power_current)
|
||||||
|
)
|
||||||
|
|
||||||
|
def _do_chain_length_conflict_res(self, new_branch, current_branch,
|
||||||
|
common_ancestor):
|
||||||
return (len(new_branch), len(current_branch))
|
return (len(new_branch), len(current_branch))
|
||||||
|
|
||||||
def _do_hash_conflict_res(self, new_branch, current_branch):
|
def _do_hash_conflict_res(self, new_branch, current_branch,
|
||||||
|
common_ancestor):
|
||||||
new_str = "".join([p.pdu_id + p.origin for p in new_branch])
|
new_str = "".join([p.pdu_id + p.origin for p in new_branch])
|
||||||
c_str = "".join([p.pdu_id + p.origin for p in current_branch])
|
c_str = "".join([p.pdu_id + p.origin for p in current_branch])
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ from .registration import RegistrationStore
|
||||||
from .room import RoomStore
|
from .room import RoomStore
|
||||||
from .roommember import RoomMemberStore
|
from .roommember import RoomMemberStore
|
||||||
from .stream import StreamStore
|
from .stream import StreamStore
|
||||||
from .pdu import StatePduStore, PduStore
|
from .pdu import StatePduStore, PduStore, PdusTable
|
||||||
from .transactions import TransactionStore
|
from .transactions import TransactionStore
|
||||||
from .keys import KeyStore
|
from .keys import KeyStore
|
||||||
|
|
||||||
|
@ -47,6 +47,11 @@ import os
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class _RollbackButIsFineException(Exception):
|
||||||
|
""" This exception is used to rollback a transaction without implying
|
||||||
|
something went wrong.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
class DataStore(RoomMemberStore, RoomStore,
|
class DataStore(RoomMemberStore, RoomStore,
|
||||||
RegistrationStore, StreamStore, ProfileStore, FeedbackStore,
|
RegistrationStore, StreamStore, ProfileStore, FeedbackStore,
|
||||||
|
@ -71,14 +76,16 @@ class DataStore(RoomMemberStore, RoomStore,
|
||||||
self.min_token -= 1
|
self.min_token -= 1
|
||||||
stream_ordering = self.min_token
|
stream_ordering = self.min_token
|
||||||
|
|
||||||
latest = yield self._db_pool.runInteraction(
|
try:
|
||||||
self._persist_pdu_event_txn,
|
yield self._db_pool.runInteraction(
|
||||||
pdu=pdu,
|
self._persist_pdu_event_txn,
|
||||||
event=event,
|
pdu=pdu,
|
||||||
backfilled=backfilled,
|
event=event,
|
||||||
stream_ordering=stream_ordering,
|
backfilled=backfilled,
|
||||||
)
|
stream_ordering=stream_ordering,
|
||||||
defer.returnValue(latest)
|
)
|
||||||
|
except _RollbackButIsFineException as e:
|
||||||
|
pass
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_event(self, event_id, allow_none=False):
|
def get_event(self, event_id, allow_none=False):
|
||||||
|
@ -116,6 +123,12 @@ class DataStore(RoomMemberStore, RoomStore,
|
||||||
del cols["content"]
|
del cols["content"]
|
||||||
del cols["prev_pdus"]
|
del cols["prev_pdus"]
|
||||||
cols["content_json"] = json.dumps(pdu.content)
|
cols["content_json"] = json.dumps(pdu.content)
|
||||||
|
|
||||||
|
unrec_keys.update({
|
||||||
|
k: v for k, v in cols.items()
|
||||||
|
if k not in PdusTable.fields
|
||||||
|
})
|
||||||
|
|
||||||
cols["unrecognized_keys"] = json.dumps(unrec_keys)
|
cols["unrecognized_keys"] = json.dumps(unrec_keys)
|
||||||
|
|
||||||
logger.debug("Persisting: %s", repr(cols))
|
logger.debug("Persisting: %s", repr(cols))
|
||||||
|
@ -175,11 +188,12 @@ class DataStore(RoomMemberStore, RoomStore,
|
||||||
try:
|
try:
|
||||||
self._simple_insert_txn(txn, "events", vals)
|
self._simple_insert_txn(txn, "events", vals)
|
||||||
except:
|
except:
|
||||||
logger.exception(
|
logger.warn(
|
||||||
"Failed to persist, probably duplicate: %s",
|
"Failed to persist, probably duplicate: %s",
|
||||||
event.event_id
|
event.event_id,
|
||||||
|
exc_info=True,
|
||||||
)
|
)
|
||||||
return
|
raise _RollbackButIsFineException("_persist_event")
|
||||||
|
|
||||||
if not backfilled and hasattr(event, "state_key"):
|
if not backfilled and hasattr(event, "state_key"):
|
||||||
vals = {
|
vals = {
|
||||||
|
@ -205,8 +219,6 @@ class DataStore(RoomMemberStore, RoomStore,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return self._get_room_events_max_id_txn(txn)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_current_state(self, room_id, event_type=None, state_key=""):
|
def get_current_state(self, room_id, event_type=None, state_key=""):
|
||||||
sql = (
|
sql = (
|
||||||
|
|
|
@ -17,6 +17,7 @@ import logging
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.errors import StoreError
|
from synapse.api.errors import StoreError
|
||||||
|
from synapse.util.logutils import log_function
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import copy
|
import copy
|
||||||
|
@ -91,6 +92,7 @@ class SQLBaseStore(object):
|
||||||
self._simple_insert_txn, table, values, or_replace=or_replace
|
self._simple_insert_txn, table, values, or_replace=or_replace
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@log_function
|
||||||
def _simple_insert_txn(self, txn, table, values, or_replace=False):
|
def _simple_insert_txn(self, txn, table, values, or_replace=False):
|
||||||
sql = "%s INTO %s (%s) VALUES(%s)" % (
|
sql = "%s INTO %s (%s) VALUES(%s)" % (
|
||||||
("INSERT OR REPLACE" if or_replace else "INSERT"),
|
("INSERT OR REPLACE" if or_replace else "INSERT"),
|
||||||
|
@ -98,6 +100,12 @@ class SQLBaseStore(object):
|
||||||
", ".join(k for k in values),
|
", ".join(k for k in values),
|
||||||
", ".join("?" for k in values)
|
", ".join("?" for k in values)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"[SQL] %s Args=%s Func=%s",
|
||||||
|
sql, values.values(),
|
||||||
|
)
|
||||||
|
|
||||||
txn.execute(sql, values.values())
|
txn.execute(sql, values.values())
|
||||||
return txn.lastrowid
|
return txn.lastrowid
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from twisted.internet import defer
|
||||||
|
|
||||||
from ._base import SQLBaseStore, Table, JoinHelper
|
from ._base import SQLBaseStore, Table, JoinHelper
|
||||||
|
|
||||||
|
from synapse.federation.units import Pdu
|
||||||
from synapse.util.logutils import log_function
|
from synapse.util.logutils import log_function
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
@ -308,7 +309,7 @@ class PduStore(SQLBaseStore):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_oldest_pdus_in_context(self, context):
|
def get_oldest_pdus_in_context(self, context):
|
||||||
"""Get a list of Pdus that we haven't backfilled beyond yet (and haven't
|
"""Get a list of Pdus that we haven't backfilled beyond yet (and havent
|
||||||
seen). This list is used when we want to backfill backwards and is the
|
seen). This list is used when we want to backfill backwards and is the
|
||||||
list we send to the remote server.
|
list we send to the remote server.
|
||||||
|
|
||||||
|
@ -516,7 +517,7 @@ class StatePduStore(SQLBaseStore):
|
||||||
|
|
||||||
if not current:
|
if not current:
|
||||||
logger.debug("get_unresolved_state_tree No current state.")
|
logger.debug("get_unresolved_state_tree No current state.")
|
||||||
return return_value
|
return (return_value, None)
|
||||||
|
|
||||||
return_value.current_branch.append(current)
|
return_value.current_branch.append(current)
|
||||||
|
|
||||||
|
@ -524,13 +525,16 @@ class StatePduStore(SQLBaseStore):
|
||||||
txn, new_pdu, current
|
txn, new_pdu, current
|
||||||
)
|
)
|
||||||
|
|
||||||
|
missing_branch = None
|
||||||
for branch, prev_state, state in enum_branches:
|
for branch, prev_state, state in enum_branches:
|
||||||
if state:
|
if state:
|
||||||
return_value[branch].append(state)
|
return_value[branch].append(state)
|
||||||
else:
|
else:
|
||||||
|
# We don't have prev_state :(
|
||||||
|
missing_branch = branch
|
||||||
break
|
break
|
||||||
|
|
||||||
return return_value
|
return (return_value, missing_branch)
|
||||||
|
|
||||||
def update_current_state(self, pdu_id, origin, context, pdu_type,
|
def update_current_state(self, pdu_id, origin, context, pdu_type,
|
||||||
state_key):
|
state_key):
|
||||||
|
@ -622,53 +626,6 @@ class StatePduStore(SQLBaseStore):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_next_missing_pdu(self, new_pdu):
|
|
||||||
"""When we get a new state pdu we need to check whether we need to do
|
|
||||||
any conflict resolution, if we do then we need to check if we need
|
|
||||||
to go back and request some more state pdus that we haven't seen yet.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
txn
|
|
||||||
new_pdu
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
PduIdTuple: A pdu that we are missing, or None if we have all the
|
|
||||||
pdus required to do the conflict resolution.
|
|
||||||
"""
|
|
||||||
return self._db_pool.runInteraction(
|
|
||||||
self._get_next_missing_pdu, new_pdu
|
|
||||||
)
|
|
||||||
|
|
||||||
def _get_next_missing_pdu(self, txn, new_pdu):
|
|
||||||
logger.debug(
|
|
||||||
"get_next_missing_pdu %s %s",
|
|
||||||
new_pdu.pdu_id, new_pdu.origin
|
|
||||||
)
|
|
||||||
|
|
||||||
current = self._get_current_interaction(
|
|
||||||
txn,
|
|
||||||
new_pdu.context, new_pdu.pdu_type, new_pdu.state_key
|
|
||||||
)
|
|
||||||
|
|
||||||
if (not current or not current.prev_state_id
|
|
||||||
or not current.prev_state_origin):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Oh look, it's a straight clobber, so wooooo almost no-op.
|
|
||||||
if (new_pdu.prev_state_id == current.pdu_id
|
|
||||||
and new_pdu.prev_state_origin == current.origin):
|
|
||||||
return None
|
|
||||||
|
|
||||||
enum_branches = self._enumerate_state_branches(txn, new_pdu, current)
|
|
||||||
for branch, prev_state, state in enum_branches:
|
|
||||||
if not state:
|
|
||||||
return PduIdTuple(
|
|
||||||
prev_state.prev_state_id,
|
|
||||||
prev_state.prev_state_origin
|
|
||||||
)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def handle_new_state(self, new_pdu):
|
def handle_new_state(self, new_pdu):
|
||||||
"""Actually perform conflict resolution on the new_pdu on the
|
"""Actually perform conflict resolution on the new_pdu on the
|
||||||
assumption we have all the pdus required to perform it.
|
assumption we have all the pdus required to perform it.
|
||||||
|
@ -752,24 +709,11 @@ class StatePduStore(SQLBaseStore):
|
||||||
|
|
||||||
return is_current
|
return is_current
|
||||||
|
|
||||||
@classmethod
|
|
||||||
@log_function
|
@log_function
|
||||||
def _enumerate_state_branches(cls, txn, pdu_a, pdu_b):
|
def _enumerate_state_branches(self, txn, pdu_a, pdu_b):
|
||||||
branch_a = pdu_a
|
branch_a = pdu_a
|
||||||
branch_b = pdu_b
|
branch_b = pdu_b
|
||||||
|
|
||||||
get_query = (
|
|
||||||
"SELECT %(fields)s FROM %(pdus)s as p "
|
|
||||||
"LEFT JOIN %(state)s as s "
|
|
||||||
"ON p.pdu_id = s.pdu_id AND p.origin = s.origin "
|
|
||||||
"WHERE p.pdu_id = ? AND p.origin = ? "
|
|
||||||
) % {
|
|
||||||
"fields": _pdu_state_joiner.get_fields(
|
|
||||||
PdusTable="p", StatePdusTable="s"),
|
|
||||||
"pdus": PdusTable.table_name,
|
|
||||||
"state": StatePdusTable.table_name,
|
|
||||||
}
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if (branch_a.pdu_id == branch_b.pdu_id
|
if (branch_a.pdu_id == branch_b.pdu_id
|
||||||
and branch_a.origin == branch_b.origin):
|
and branch_a.origin == branch_b.origin):
|
||||||
|
@ -801,13 +745,12 @@ class StatePduStore(SQLBaseStore):
|
||||||
branch_a.prev_state_origin
|
branch_a.prev_state_origin
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug("getting branch_a prev %s", pdu_tuple)
|
|
||||||
txn.execute(get_query, pdu_tuple)
|
|
||||||
|
|
||||||
prev_branch = branch_a
|
prev_branch = branch_a
|
||||||
|
|
||||||
res = txn.fetchone()
|
logger.debug("getting branch_a prev %s", pdu_tuple)
|
||||||
branch_a = PduEntry(*res) if res else None
|
branch_a = self._get_pdu_tuple(txn, *pdu_tuple)
|
||||||
|
if branch_a:
|
||||||
|
branch_a = Pdu.from_pdu_tuple(branch_a)
|
||||||
|
|
||||||
logger.debug("branch_a=%s", branch_a)
|
logger.debug("branch_a=%s", branch_a)
|
||||||
|
|
||||||
|
@ -820,14 +763,13 @@ class StatePduStore(SQLBaseStore):
|
||||||
branch_b.prev_state_id,
|
branch_b.prev_state_id,
|
||||||
branch_b.prev_state_origin
|
branch_b.prev_state_origin
|
||||||
)
|
)
|
||||||
txn.execute(get_query, pdu_tuple)
|
|
||||||
|
|
||||||
logger.debug("getting branch_b prev %s", pdu_tuple)
|
|
||||||
|
|
||||||
prev_branch = branch_b
|
prev_branch = branch_b
|
||||||
|
|
||||||
res = txn.fetchone()
|
logger.debug("getting branch_b prev %s", pdu_tuple)
|
||||||
branch_b = PduEntry(*res) if res else None
|
branch_b = self._get_pdu_tuple(txn, *pdu_tuple)
|
||||||
|
if branch_b:
|
||||||
|
branch_b = Pdu.from_pdu_tuple(branch_b)
|
||||||
|
|
||||||
logger.debug("branch_b=%s", branch_b)
|
logger.debug("branch_b=%s", branch_b)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ from twisted.internet import defer
|
||||||
from ._base import SQLBaseStore
|
from ._base import SQLBaseStore
|
||||||
|
|
||||||
from synapse.api.constants import Membership
|
from synapse.api.constants import Membership
|
||||||
|
from synapse.util.logutils import log_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -29,8 +30,18 @@ class RoomMemberStore(SQLBaseStore):
|
||||||
def _store_room_member_txn(self, txn, event):
|
def _store_room_member_txn(self, txn, event):
|
||||||
"""Store a room member in the database.
|
"""Store a room member in the database.
|
||||||
"""
|
"""
|
||||||
target_user_id = event.state_key
|
try:
|
||||||
domain = self.hs.parse_userid(target_user_id).domain
|
target_user_id = event.state_key
|
||||||
|
domain = self.hs.parse_userid(target_user_id).domain
|
||||||
|
except:
|
||||||
|
logger.exception("Failed to parse target_user_id=%s", target_user_id)
|
||||||
|
raise
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"_store_room_member_txn: target_user_id=%s, membership=%s",
|
||||||
|
target_user_id,
|
||||||
|
event.membership,
|
||||||
|
)
|
||||||
|
|
||||||
self._simple_insert_txn(
|
self._simple_insert_txn(
|
||||||
txn,
|
txn,
|
||||||
|
@ -51,12 +62,30 @@ class RoomMemberStore(SQLBaseStore):
|
||||||
"VALUES (?, ?)"
|
"VALUES (?, ?)"
|
||||||
)
|
)
|
||||||
txn.execute(sql, (event.room_id, domain))
|
txn.execute(sql, (event.room_id, domain))
|
||||||
else:
|
elif event.membership != Membership.INVITE:
|
||||||
sql = (
|
# Check if this was the last person to have left.
|
||||||
"DELETE FROM room_hosts WHERE room_id = ? AND host = ?"
|
member_events = self._get_members_query_txn(
|
||||||
|
txn,
|
||||||
|
where_clause="c.room_id = ? AND m.membership = ? AND m.user_id != ?",
|
||||||
|
where_values=(event.room_id, Membership.JOIN, target_user_id,)
|
||||||
)
|
)
|
||||||
|
|
||||||
txn.execute(sql, (event.room_id, domain))
|
joined_domains = set()
|
||||||
|
for e in member_events:
|
||||||
|
try:
|
||||||
|
joined_domains.add(
|
||||||
|
self.hs.parse_userid(e.state_key).domain
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
# FIXME: How do we deal with invalid user ids in the db?
|
||||||
|
logger.exception("Invalid user_id: %s", event.state_key)
|
||||||
|
|
||||||
|
if domain not in joined_domains:
|
||||||
|
sql = (
|
||||||
|
"DELETE FROM room_hosts WHERE room_id = ? AND host = ?"
|
||||||
|
)
|
||||||
|
|
||||||
|
txn.execute(sql, (event.room_id, domain))
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_room_member(self, user_id, room_id):
|
def get_room_member(self, user_id, room_id):
|
||||||
|
@ -146,8 +175,13 @@ class RoomMemberStore(SQLBaseStore):
|
||||||
vals = where_dict.values()
|
vals = where_dict.values()
|
||||||
return self._get_members_query(clause, vals)
|
return self._get_members_query(clause, vals)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
|
||||||
def _get_members_query(self, where_clause, where_values):
|
def _get_members_query(self, where_clause, where_values):
|
||||||
|
return self._db_pool.runInteraction(
|
||||||
|
self._get_members_query_txn,
|
||||||
|
where_clause, where_values
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_members_query_txn(self, txn, where_clause, where_values):
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT e.* FROM events as e "
|
"SELECT e.* FROM events as e "
|
||||||
"INNER JOIN room_memberships as m "
|
"INNER JOIN room_memberships as m "
|
||||||
|
@ -157,12 +191,11 @@ class RoomMemberStore(SQLBaseStore):
|
||||||
"WHERE %s "
|
"WHERE %s "
|
||||||
) % (where_clause,)
|
) % (where_clause,)
|
||||||
|
|
||||||
rows = yield self._execute_and_decode(sql, *where_values)
|
txn.execute(sql, where_values)
|
||||||
|
rows = self.cursor_to_dict(txn)
|
||||||
|
|
||||||
# logger.debug("_get_members_query Got rows %s", rows)
|
results = self._parse_events_txn(txn, rows)
|
||||||
|
return results
|
||||||
results = yield self._parse_events(rows)
|
|
||||||
defer.returnValue(results)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def user_rooms_intersect(self, user_list):
|
def user_rooms_intersect(self, user_list):
|
||||||
|
|
9
synctl
9
synctl
|
@ -4,7 +4,6 @@ SYNAPSE="synapse/app/homeserver.py"
|
||||||
|
|
||||||
CONFIGFILE="homeserver.yaml"
|
CONFIGFILE="homeserver.yaml"
|
||||||
PIDFILE="homeserver.pid"
|
PIDFILE="homeserver.pid"
|
||||||
LOGFILE="homeserver.log"
|
|
||||||
|
|
||||||
GREEN=$'\e[1;32m'
|
GREEN=$'\e[1;32m'
|
||||||
NORMAL=$'\e[m'
|
NORMAL=$'\e[m'
|
||||||
|
@ -14,15 +13,13 @@ set -e
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
if [ ! -f "$CONFIGFILE" ]; then
|
if [ ! -f "$CONFIGFILE" ]; then
|
||||||
echo "No config file found - generating a default one..."
|
echo "No config file found"
|
||||||
$SYNAPSE -c "$CONFIGFILE" --generate-config
|
echo "To generate a config file, run 'python --generate-config'"
|
||||||
echo "Wrote $CONFIGFILE"
|
|
||||||
echo "You must now edit this file before continuing"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -n "Starting ..."
|
echo -n "Starting ..."
|
||||||
$SYNAPSE --daemonize -c "$CONFIGFILE" --pid-file "$PIDFILE" --log-file "$LOGFILE"
|
$SYNAPSE --daemonize -c "$CONFIGFILE" --pid-file "$PIDFILE"
|
||||||
echo "${GREEN}started${NORMAL}"
|
echo "${GREEN}started${NORMAL}"
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
|
|
|
@ -15,21 +15,31 @@
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
|
from twisted.python.log import PythonLoggingObserver
|
||||||
|
|
||||||
from synapse.state import StateHandler
|
from synapse.state import StateHandler
|
||||||
from synapse.storage.pdu import PduEntry
|
from synapse.storage.pdu import PduEntry
|
||||||
from synapse.federation.pdu_codec import encode_event_id
|
from synapse.federation.pdu_codec import encode_event_id
|
||||||
|
from synapse.federation.units import Pdu
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import mock
|
||||||
|
|
||||||
|
|
||||||
ReturnType = namedtuple(
|
ReturnType = namedtuple(
|
||||||
"StateReturnType", ["new_branch", "current_branch"]
|
"StateReturnType", ["new_branch", "current_branch"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _gen_get_power_level(power_level_list):
|
||||||
|
def get_power_level(room_id, user_id):
|
||||||
|
return defer.succeed(power_level_list.get(user_id, None))
|
||||||
|
return get_power_level
|
||||||
|
|
||||||
class StateTestCase(unittest.TestCase):
|
class StateTestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.persistence = Mock(spec=[
|
self.persistence = Mock(spec=[
|
||||||
|
@ -38,6 +48,7 @@ class StateTestCase(unittest.TestCase):
|
||||||
"get_latest_pdus_in_context",
|
"get_latest_pdus_in_context",
|
||||||
"get_current_state_pdu",
|
"get_current_state_pdu",
|
||||||
"get_pdu",
|
"get_pdu",
|
||||||
|
"get_power_level",
|
||||||
])
|
])
|
||||||
self.replication = Mock(spec=["get_pdu"])
|
self.replication = Mock(spec=["get_pdu"])
|
||||||
|
|
||||||
|
@ -51,10 +62,12 @@ class StateTestCase(unittest.TestCase):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def test_new_state_key(self):
|
def test_new_state_key(self):
|
||||||
# We've never seen anything for this state before
|
# We've never seen anything for this state before
|
||||||
new_pdu = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
new_pdu = new_fake_pdu("A", "test", "mem", "x", None, "u")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu], [])
|
(ReturnType([new_pdu], []), None)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -74,11 +87,44 @@ class StateTestCase(unittest.TestCase):
|
||||||
# We do a direct overwriting of the old state, i.e., the new state
|
# We do a direct overwriting of the old state, i.e., the new state
|
||||||
# points to the old state.
|
# points to the old state.
|
||||||
|
|
||||||
old_pdu = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
new_pdu = new_fake_pdu_entry("B", "test", "mem", "x", "A", 5)
|
new_pdu = new_fake_pdu("B", "test", "mem", "x", "A", "u2")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 5,
|
||||||
|
})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu, old_pdu], [old_pdu])
|
(ReturnType([new_pdu, old_pdu], [old_pdu]), None)
|
||||||
|
)
|
||||||
|
|
||||||
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
|
||||||
|
self.assertTrue(is_new)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.assert_called_once_with(
|
||||||
|
new_pdu
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
||||||
|
|
||||||
|
self.assertFalse(self.replication.get_pdu.called)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def test_overwrite(self):
|
||||||
|
old_pdu_1 = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
|
old_pdu_2 = new_fake_pdu("B", "test", "mem", "x", "A", "u2")
|
||||||
|
new_pdu = new_fake_pdu("C", "test", "mem", "x", "B", "u3")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 5,
|
||||||
|
"u3": 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
|
(ReturnType([new_pdu, old_pdu_2, old_pdu_1], [old_pdu_1]), None)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -98,12 +144,18 @@ class StateTestCase(unittest.TestCase):
|
||||||
# We try to update the state based on an outdated state, and have a
|
# We try to update the state based on an outdated state, and have a
|
||||||
# too low power level.
|
# too low power level.
|
||||||
|
|
||||||
old_pdu_1 = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu_1 = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
old_pdu_2 = new_fake_pdu_entry("B", "test", "mem", "x", None, 10)
|
old_pdu_2 = new_fake_pdu("B", "test", "mem", "x", None, "u2")
|
||||||
new_pdu = new_fake_pdu_entry("C", "test", "mem", "x", "A", 5)
|
new_pdu = new_fake_pdu("C", "test", "mem", "x", "A", "u3")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 5,
|
||||||
|
})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1])
|
(ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1]), None)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -123,12 +175,18 @@ class StateTestCase(unittest.TestCase):
|
||||||
# We try to update the state based on an outdated state, but have
|
# We try to update the state based on an outdated state, but have
|
||||||
# sufficient power level to force the update.
|
# sufficient power level to force the update.
|
||||||
|
|
||||||
old_pdu_1 = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu_1 = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
old_pdu_2 = new_fake_pdu_entry("B", "test", "mem", "x", None, 10)
|
old_pdu_2 = new_fake_pdu("B", "test", "mem", "x", None, "u2")
|
||||||
new_pdu = new_fake_pdu_entry("C", "test", "mem", "x", "A", 15)
|
new_pdu = new_fake_pdu("C", "test", "mem", "x", "A", "u3")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 15,
|
||||||
|
})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1])
|
(ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1]), None)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -148,12 +206,18 @@ class StateTestCase(unittest.TestCase):
|
||||||
# We try to update the state based on an outdated state, the power
|
# We try to update the state based on an outdated state, the power
|
||||||
# levels are the same and so are the branch lengths
|
# levels are the same and so are the branch lengths
|
||||||
|
|
||||||
old_pdu_1 = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu_1 = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
old_pdu_2 = new_fake_pdu_entry("B", "test", "mem", "x", None, 10)
|
old_pdu_2 = new_fake_pdu("B", "test", "mem", "x", None, "u2")
|
||||||
new_pdu = new_fake_pdu_entry("C", "test", "mem", "x", "A", 10)
|
new_pdu = new_fake_pdu("C", "test", "mem", "x", "A", "u3")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 10,
|
||||||
|
})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1])
|
(ReturnType([new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1]), None)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -173,13 +237,26 @@ class StateTestCase(unittest.TestCase):
|
||||||
# We try to update the state based on an outdated state, the power
|
# We try to update the state based on an outdated state, the power
|
||||||
# levels are the same but the branch length of the new one is longer.
|
# levels are the same but the branch length of the new one is longer.
|
||||||
|
|
||||||
old_pdu_1 = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu_1 = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
old_pdu_2 = new_fake_pdu_entry("B", "test", "mem", "x", None, 10)
|
old_pdu_2 = new_fake_pdu("B", "test", "mem", "x", None, "u2")
|
||||||
old_pdu_3 = new_fake_pdu_entry("C", "test", "mem", "x", "A", 10)
|
old_pdu_3 = new_fake_pdu("C", "test", "mem", "x", "A", "u3")
|
||||||
new_pdu = new_fake_pdu_entry("D", "test", "mem", "x", "C", 10)
|
new_pdu = new_fake_pdu("D", "test", "mem", "x", "C", "u4")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 10,
|
||||||
|
"u4": 10,
|
||||||
|
})
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.return_value = (
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
ReturnType([new_pdu, old_pdu_3, old_pdu_1], [old_pdu_2, old_pdu_1])
|
(
|
||||||
|
ReturnType(
|
||||||
|
[new_pdu, old_pdu_3, old_pdu_1],
|
||||||
|
[old_pdu_2, old_pdu_1]
|
||||||
|
),
|
||||||
|
None
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
is_new = yield self.state.handle_new_state(new_pdu)
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
@ -200,22 +277,38 @@ class StateTestCase(unittest.TestCase):
|
||||||
# triggering a get_pdu request
|
# triggering a get_pdu request
|
||||||
|
|
||||||
# The pdu we haven't seen
|
# The pdu we haven't seen
|
||||||
old_pdu_1 = new_fake_pdu_entry("A", "test", "mem", "x", None, 10)
|
old_pdu_1 = new_fake_pdu(
|
||||||
|
"A", "test", "mem", "x", None, "u1", depth=0
|
||||||
|
)
|
||||||
|
|
||||||
old_pdu_2 = new_fake_pdu_entry("B", "test", "mem", "x", None, 10)
|
old_pdu_2 = new_fake_pdu(
|
||||||
new_pdu = new_fake_pdu_entry("C", "test", "mem", "x", "A", 20)
|
"B", "test", "mem", "x", "A", "u2", depth=1
|
||||||
|
)
|
||||||
|
new_pdu = new_fake_pdu(
|
||||||
|
"C", "test", "mem", "x", "A", "u3", depth=2
|
||||||
|
)
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 20,
|
||||||
|
})
|
||||||
|
|
||||||
# The return_value of `get_unresolved_state_tree`, which changes after
|
# The return_value of `get_unresolved_state_tree`, which changes after
|
||||||
# the call to get_pdu
|
# the call to get_pdu
|
||||||
tree_to_return = [ReturnType([new_pdu], [old_pdu_2])]
|
tree_to_return = [(ReturnType([new_pdu], [old_pdu_2]), 0)]
|
||||||
|
|
||||||
def return_tree(p):
|
def return_tree(p):
|
||||||
return tree_to_return[0]
|
return tree_to_return[0]
|
||||||
|
|
||||||
def set_return_tree(*args, **kwargs):
|
def set_return_tree(destination, pdu_origin, pdu_id, outlier=False):
|
||||||
tree_to_return[0] = ReturnType(
|
tree_to_return[0] = (
|
||||||
[new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1]
|
ReturnType(
|
||||||
|
[new_pdu, old_pdu_1], [old_pdu_2, old_pdu_1]
|
||||||
|
),
|
||||||
|
None
|
||||||
)
|
)
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.side_effect = return_tree
|
self.persistence.get_unresolved_state_tree.side_effect = return_tree
|
||||||
|
|
||||||
|
@ -227,6 +320,13 @@ class StateTestCase(unittest.TestCase):
|
||||||
|
|
||||||
self.assertTrue(is_new)
|
self.assertTrue(is_new)
|
||||||
|
|
||||||
|
self.replication.get_pdu.assert_called_with(
|
||||||
|
destination=new_pdu.origin,
|
||||||
|
pdu_origin=old_pdu_1.origin,
|
||||||
|
pdu_id=old_pdu_1.pdu_id,
|
||||||
|
outlier=True
|
||||||
|
)
|
||||||
|
|
||||||
self.persistence.get_unresolved_state_tree.assert_called_with(
|
self.persistence.get_unresolved_state_tree.assert_called_with(
|
||||||
new_pdu
|
new_pdu
|
||||||
)
|
)
|
||||||
|
@ -237,12 +337,233 @@ class StateTestCase(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def test_missing_pdu_depth_1(self):
|
||||||
|
# We try to update state against a PDU we haven't yet seen,
|
||||||
|
# triggering a get_pdu request
|
||||||
|
|
||||||
|
# The pdu we haven't seen
|
||||||
|
old_pdu_1 = new_fake_pdu(
|
||||||
|
"A", "test", "mem", "x", None, "u1", depth=0
|
||||||
|
)
|
||||||
|
|
||||||
|
old_pdu_2 = new_fake_pdu(
|
||||||
|
"B", "test", "mem", "x", "A", "u2", depth=2
|
||||||
|
)
|
||||||
|
old_pdu_3 = new_fake_pdu(
|
||||||
|
"C", "test", "mem", "x", "B", "u3", depth=3
|
||||||
|
)
|
||||||
|
new_pdu = new_fake_pdu(
|
||||||
|
"D", "test", "mem", "x", "A", "u4", depth=4
|
||||||
|
)
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 10,
|
||||||
|
"u4": 20,
|
||||||
|
})
|
||||||
|
|
||||||
|
# The return_value of `get_unresolved_state_tree`, which changes after
|
||||||
|
# the call to get_pdu
|
||||||
|
tree_to_return = [
|
||||||
|
(
|
||||||
|
ReturnType([new_pdu], [old_pdu_3]),
|
||||||
|
0
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ReturnType(
|
||||||
|
[new_pdu, old_pdu_1], [old_pdu_3]
|
||||||
|
),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ReturnType(
|
||||||
|
[new_pdu, old_pdu_1], [old_pdu_3, old_pdu_2, old_pdu_1]
|
||||||
|
),
|
||||||
|
None
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
to_return = [0]
|
||||||
|
|
||||||
|
def return_tree(p):
|
||||||
|
return tree_to_return[to_return[0]]
|
||||||
|
|
||||||
|
def set_return_tree(destination, pdu_origin, pdu_id, outlier=False):
|
||||||
|
to_return[0] += 1
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.side_effect = return_tree
|
||||||
|
|
||||||
|
self.replication.get_pdu.side_effect = set_return_tree
|
||||||
|
|
||||||
|
self.persistence.get_pdu.return_value = None
|
||||||
|
|
||||||
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
|
||||||
|
self.assertTrue(is_new)
|
||||||
|
|
||||||
|
self.assertEqual(2, self.replication.get_pdu.call_count)
|
||||||
|
|
||||||
|
self.replication.get_pdu.assert_has_calls(
|
||||||
|
[
|
||||||
|
mock.call(
|
||||||
|
destination=new_pdu.origin,
|
||||||
|
pdu_origin=old_pdu_1.origin,
|
||||||
|
pdu_id=old_pdu_1.pdu_id,
|
||||||
|
outlier=True
|
||||||
|
),
|
||||||
|
mock.call(
|
||||||
|
destination=old_pdu_3.origin,
|
||||||
|
pdu_origin=old_pdu_2.origin,
|
||||||
|
pdu_id=old_pdu_2.pdu_id,
|
||||||
|
outlier=True
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.assert_called_with(
|
||||||
|
new_pdu
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
3, self.persistence.get_unresolved_state_tree.call_count
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def test_missing_pdu_depth_2(self):
|
||||||
|
# We try to update state against a PDU we haven't yet seen,
|
||||||
|
# triggering a get_pdu request
|
||||||
|
|
||||||
|
# The pdu we haven't seen
|
||||||
|
old_pdu_1 = new_fake_pdu(
|
||||||
|
"A", "test", "mem", "x", None, "u1", depth=0
|
||||||
|
)
|
||||||
|
|
||||||
|
old_pdu_2 = new_fake_pdu(
|
||||||
|
"B", "test", "mem", "x", "A", "u2", depth=2
|
||||||
|
)
|
||||||
|
old_pdu_3 = new_fake_pdu(
|
||||||
|
"C", "test", "mem", "x", "B", "u3", depth=3
|
||||||
|
)
|
||||||
|
new_pdu = new_fake_pdu(
|
||||||
|
"D", "test", "mem", "x", "A", "u4", depth=1
|
||||||
|
)
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 10,
|
||||||
|
"u2": 10,
|
||||||
|
"u3": 10,
|
||||||
|
"u4": 20,
|
||||||
|
})
|
||||||
|
|
||||||
|
# The return_value of `get_unresolved_state_tree`, which changes after
|
||||||
|
# the call to get_pdu
|
||||||
|
tree_to_return = [
|
||||||
|
(
|
||||||
|
ReturnType([new_pdu], [old_pdu_3]),
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ReturnType(
|
||||||
|
[new_pdu], [old_pdu_3, old_pdu_2]
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ReturnType(
|
||||||
|
[new_pdu, old_pdu_1], [old_pdu_3, old_pdu_2, old_pdu_1]
|
||||||
|
),
|
||||||
|
None
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
to_return = [0]
|
||||||
|
|
||||||
|
def return_tree(p):
|
||||||
|
return tree_to_return[to_return[0]]
|
||||||
|
|
||||||
|
def set_return_tree(destination, pdu_origin, pdu_id, outlier=False):
|
||||||
|
to_return[0] += 1
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.side_effect = return_tree
|
||||||
|
|
||||||
|
self.replication.get_pdu.side_effect = set_return_tree
|
||||||
|
|
||||||
|
self.persistence.get_pdu.return_value = None
|
||||||
|
|
||||||
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
|
||||||
|
self.assertTrue(is_new)
|
||||||
|
|
||||||
|
self.assertEqual(2, self.replication.get_pdu.call_count)
|
||||||
|
|
||||||
|
self.replication.get_pdu.assert_has_calls(
|
||||||
|
[
|
||||||
|
mock.call(
|
||||||
|
destination=old_pdu_3.origin,
|
||||||
|
pdu_origin=old_pdu_2.origin,
|
||||||
|
pdu_id=old_pdu_2.pdu_id,
|
||||||
|
outlier=True
|
||||||
|
),
|
||||||
|
mock.call(
|
||||||
|
destination=new_pdu.origin,
|
||||||
|
pdu_origin=old_pdu_1.origin,
|
||||||
|
pdu_id=old_pdu_1.pdu_id,
|
||||||
|
outlier=True
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.assert_called_with(
|
||||||
|
new_pdu
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
3, self.persistence.get_unresolved_state_tree.call_count
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def test_no_common_ancestor(self):
|
||||||
|
# We do a direct overwriting of the old state, i.e., the new state
|
||||||
|
# points to the old state.
|
||||||
|
|
||||||
|
old_pdu = new_fake_pdu("A", "test", "mem", "x", None, "u1")
|
||||||
|
new_pdu = new_fake_pdu("B", "test", "mem", "x", None, "u2")
|
||||||
|
|
||||||
|
self.persistence.get_power_level.side_effect = _gen_get_power_level({
|
||||||
|
"u1": 5,
|
||||||
|
"u2": 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.return_value = (
|
||||||
|
(ReturnType([new_pdu], [old_pdu]), None)
|
||||||
|
)
|
||||||
|
|
||||||
|
is_new = yield self.state.handle_new_state(new_pdu)
|
||||||
|
|
||||||
|
self.assertTrue(is_new)
|
||||||
|
|
||||||
|
self.persistence.get_unresolved_state_tree.assert_called_once_with(
|
||||||
|
new_pdu
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(1, self.persistence.update_current_state.call_count)
|
||||||
|
|
||||||
|
self.assertFalse(self.replication.get_pdu.called)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def test_new_event(self):
|
def test_new_event(self):
|
||||||
event = Mock()
|
event = Mock()
|
||||||
event.event_id = "12123123@test"
|
event.event_id = "12123123@test"
|
||||||
|
|
||||||
state_pdu = new_fake_pdu_entry("C", "test", "mem", "x", "A", 20)
|
state_pdu = new_fake_pdu("C", "test", "mem", "x", "A", 20)
|
||||||
|
|
||||||
snapshot = Mock()
|
snapshot = Mock()
|
||||||
snapshot.prev_state_pdu = state_pdu
|
snapshot.prev_state_pdu = state_pdu
|
||||||
|
@ -269,24 +590,25 @@ class StateTestCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def new_fake_pdu_entry(pdu_id, context, pdu_type, state_key, prev_state_id,
|
def new_fake_pdu(pdu_id, context, pdu_type, state_key, prev_state_id,
|
||||||
power_level):
|
user_id, depth=0):
|
||||||
new_pdu = PduEntry(
|
new_pdu = Pdu(
|
||||||
pdu_id=pdu_id,
|
pdu_id=pdu_id,
|
||||||
pdu_type=pdu_type,
|
pdu_type=pdu_type,
|
||||||
state_key=state_key,
|
state_key=state_key,
|
||||||
power_level=power_level,
|
user_id=user_id,
|
||||||
prev_state_id=prev_state_id,
|
prev_state_id=prev_state_id,
|
||||||
origin="example.com",
|
origin="example.com",
|
||||||
context="context",
|
context="context",
|
||||||
ts=1405353060021,
|
ts=1405353060021,
|
||||||
depth=0,
|
depth=depth,
|
||||||
content_json="{}",
|
content_json="{}",
|
||||||
unrecognized_keys="{}",
|
unrecognized_keys="{}",
|
||||||
outlier=True,
|
outlier=True,
|
||||||
is_state=True,
|
is_state=True,
|
||||||
prev_state_origin="example.com",
|
prev_state_origin="example.com",
|
||||||
have_processed=True,
|
have_processed=True,
|
||||||
|
content={},
|
||||||
)
|
)
|
||||||
|
|
||||||
return new_pdu
|
return new_pdu
|
||||||
|
|
|
@ -21,8 +21,8 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'eventStreamService'])
|
angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'eventStreamService'])
|
||||||
.controller('MatrixWebClientController', ['$scope', '$location', '$rootScope', '$timeout', '$animate', 'matrixService', 'mPresence', 'eventStreamService', 'matrixPhoneService',
|
.controller('MatrixWebClientController', ['$scope', '$location', '$rootScope', '$timeout', '$animate', 'matrixService', 'mPresence', 'eventStreamService', 'eventHandlerService', 'matrixPhoneService',
|
||||||
function($scope, $location, $rootScope, $timeout, $animate, matrixService, mPresence, eventStreamService, matrixPhoneService) {
|
function($scope, $location, $rootScope, $timeout, $animate, matrixService, mPresence, eventStreamService, eventHandlerService, matrixPhoneService) {
|
||||||
|
|
||||||
// Check current URL to avoid to display the logout button on the login page
|
// Check current URL to avoid to display the logout button on the login page
|
||||||
$scope.location = $location.path();
|
$scope.location = $location.path();
|
||||||
|
@ -74,6 +74,9 @@ angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'even
|
||||||
matrixService.setConfig({});
|
matrixService.setConfig({});
|
||||||
matrixService.saveConfig();
|
matrixService.saveConfig();
|
||||||
|
|
||||||
|
// Reset cached data
|
||||||
|
eventHandlerService.reset();
|
||||||
|
|
||||||
// And go to the login page
|
// And go to the login page
|
||||||
$location.url("login");
|
$location.url("login");
|
||||||
};
|
};
|
||||||
|
@ -96,50 +99,80 @@ angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'even
|
||||||
delete roomMembers[matrixService.config().user_id];
|
delete roomMembers[matrixService.config().user_id];
|
||||||
|
|
||||||
$rootScope.currentCall.user_id = Object.keys(roomMembers)[0];
|
$rootScope.currentCall.user_id = Object.keys(roomMembers)[0];
|
||||||
|
|
||||||
|
// set it to the user ID until we fetch the display name
|
||||||
|
$rootScope.currentCall.userProfile = { displayname: $rootScope.currentCall.user_id };
|
||||||
|
|
||||||
matrixService.getProfile($rootScope.currentCall.user_id).then(
|
matrixService.getProfile($rootScope.currentCall.user_id).then(
|
||||||
function(response) {
|
function(response) {
|
||||||
$rootScope.currentCall.userProfile = response.data;
|
if (response.data.displayname) $rootScope.currentCall.userProfile.displayname = response.data.displayname;
|
||||||
|
if (response.data.avatar_url) $rootScope.currentCall.userProfile.avatar_url = response.data.avatar_url;
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
$scope.feedback = "Can't load user profile";
|
$scope.feedback = "Can't load user profile";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
$rootScope.$watch('currentCall.state', function(newVal, oldVal) {
|
||||||
|
if (newVal == 'ringing') {
|
||||||
|
angular.element('#ringbackAudio')[0].pause();
|
||||||
|
angular.element('#ringAudio')[0].load();
|
||||||
|
angular.element('#ringAudio')[0].play();
|
||||||
|
} else if (newVal == 'invite_sent') {
|
||||||
|
angular.element('#ringAudio')[0].pause();
|
||||||
|
angular.element('#ringbackAudio')[0].load();
|
||||||
|
angular.element('#ringbackAudio')[0].play();
|
||||||
|
} else if (newVal == 'ended' && oldVal == 'connected') {
|
||||||
|
angular.element('#ringAudio')[0].pause();
|
||||||
|
angular.element('#ringbackAudio')[0].pause();
|
||||||
|
angular.element('#callendAudio')[0].play();
|
||||||
|
} else if (newVal == 'ended' && oldVal == 'invite_sent' && $rootScope.currentCall.hangupParty == 'remote') {
|
||||||
|
angular.element('#ringAudio')[0].pause();
|
||||||
|
angular.element('#ringbackAudio')[0].pause();
|
||||||
|
angular.element('#busyAudio')[0].play();
|
||||||
|
} else if (oldVal == 'invite_sent') {
|
||||||
|
angular.element('#ringbackAudio')[0].pause();
|
||||||
|
} else if (oldVal == 'ringing') {
|
||||||
|
angular.element('#ringAudio')[0].pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$rootScope.$on(matrixPhoneService.INCOMING_CALL_EVENT, function(ngEvent, call) {
|
$rootScope.$on(matrixPhoneService.INCOMING_CALL_EVENT, function(ngEvent, call) {
|
||||||
console.trace("incoming call");
|
console.log("incoming call");
|
||||||
|
if ($rootScope.currentCall && $rootScope.currentCall.state != 'ended') {
|
||||||
|
console.log("rejecting call because we're already in a call");
|
||||||
|
call.hangup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
call.onError = $scope.onCallError;
|
call.onError = $scope.onCallError;
|
||||||
call.onHangup = $scope.onCallHangup;
|
call.onHangup = $scope.onCallHangup;
|
||||||
$rootScope.currentCall = call;
|
$rootScope.currentCall = call;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$rootScope.$on(matrixPhoneService.REPLACED_CALL_EVENT, function(ngEvent, oldCall, newCall) {
|
||||||
|
console.log("call ID "+oldCall.call_id+" has been replaced by call ID "+newCall.call_id+"!");
|
||||||
|
newCall.onError = $scope.onCallError;
|
||||||
|
newCall.onHangup = $scope.onCallHangup;
|
||||||
|
$rootScope.currentCall = newCall;
|
||||||
|
});
|
||||||
|
|
||||||
$scope.answerCall = function() {
|
$scope.answerCall = function() {
|
||||||
$rootScope.currentCall.answer();
|
$rootScope.currentCall.answer();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.hangupCall = function() {
|
$scope.hangupCall = function() {
|
||||||
$rootScope.currentCall.hangup();
|
$rootScope.currentCall.hangup();
|
||||||
|
|
||||||
$timeout(function() {
|
|
||||||
var icon = angular.element('#callEndedIcon');
|
|
||||||
$animate.addClass(icon, 'callIconRotate');
|
|
||||||
$timeout(function(){
|
|
||||||
$rootScope.currentCall = undefined;
|
|
||||||
}, 2000);
|
|
||||||
}, 100);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$rootScope.onCallError = function(errStr) {
|
$rootScope.onCallError = function(errStr) {
|
||||||
$scope.feedback = errStr;
|
$scope.feedback = errStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.onCallHangup = function() {
|
$rootScope.onCallHangup = function(call) {
|
||||||
$timeout(function() {
|
if (call == $rootScope.currentCall) {
|
||||||
var icon = angular.element('#callEndedIcon');
|
|
||||||
$animate.addClass(icon, 'callIconRotate');
|
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$rootScope.currentCall = undefined;
|
if (call == $rootScope.currentCall) $rootScope.currentCall = undefined;
|
||||||
}, 2000);
|
}, 4070);
|
||||||
}, 100);
|
}
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -55,20 +55,20 @@ a:active { color: #000; }
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
||||||
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
||||||
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
||||||
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.callIconRotate {
|
#callEndedIcon {
|
||||||
-webkit-transform: rotateZ(45deg);
|
transition:all linear 0.5s;
|
||||||
-moz-transform: rotateZ(45deg);
|
}
|
||||||
-ms-transform: rotateZ(45deg);
|
|
||||||
-o-transform: rotateZ(45deg);
|
#callEndedIcon {
|
||||||
transform: rotateZ(45deg);
|
transform: rotateZ(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#callEndedIcon.ng-hide {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
#callPeerImage {
|
#callPeerImage {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -220,12 +220,6 @@ a:active { color: #000; }
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#roomName {
|
|
||||||
float: right;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#roomHeader {
|
#roomHeader {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
@ -263,12 +257,80 @@ a:active { color: #000; }
|
||||||
|
|
||||||
#mainInput {
|
#mainInput {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blink {
|
.blink {
|
||||||
background-color: #faa;
|
background-color: #faa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.roomHighlight {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publicTable {
|
||||||
|
max-width: 480px;
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.publicTable tr {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.publicTable td {
|
||||||
|
vertical-align: text-top;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publicRoomEntry {
|
||||||
|
max-width: 430px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publicRoomJoinedUsers {
|
||||||
|
width: 5em;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publicRoomTopic {
|
||||||
|
color: #888;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
border-bottom: 1px #ddd solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#roomName {
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#roomTopic {
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomNameInput, .roomTopicInput {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomNameSection, .roomTopicSection {
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomNameSetNew, .roomTopicSetNew {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomHeaderInfo {
|
||||||
|
float: right;
|
||||||
|
margin-top: 15px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
/*** Participant list ***/
|
/*** Participant list ***/
|
||||||
|
|
||||||
#usersTableWrapper {
|
#usersTableWrapper {
|
||||||
|
@ -465,6 +527,10 @@ a:active { color: #000; }
|
||||||
text-align: left ! important;
|
text-align: left ! important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bubble .message {
|
||||||
|
/* Break lines when encountering CR+LF */
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
.bubble .messagePending {
|
.bubble .messagePending {
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
var matrixWebClient = angular.module('matrixWebClient', [
|
var matrixWebClient = angular.module('matrixWebClient', [
|
||||||
'ngRoute',
|
'ngRoute',
|
||||||
|
'ngAnimate',
|
||||||
'MatrixWebClientController',
|
'MatrixWebClientController',
|
||||||
'LoginController',
|
'LoginController',
|
||||||
'RegisterController',
|
'RegisterController',
|
||||||
|
|
|
@ -35,12 +35,19 @@ angular.module('eventHandlerService', [])
|
||||||
var POWERLEVEL_EVENT = "POWERLEVEL_EVENT";
|
var POWERLEVEL_EVENT = "POWERLEVEL_EVENT";
|
||||||
var CALL_EVENT = "CALL_EVENT";
|
var CALL_EVENT = "CALL_EVENT";
|
||||||
var NAME_EVENT = "NAME_EVENT";
|
var NAME_EVENT = "NAME_EVENT";
|
||||||
|
var TOPIC_EVENT = "TOPIC_EVENT";
|
||||||
|
var RESET_EVENT = "RESET_EVENT"; // eventHandlerService has been resetted
|
||||||
|
|
||||||
var InitialSyncDeferred = $q.defer();
|
var initialSyncDeferred;
|
||||||
|
|
||||||
$rootScope.events = {
|
var reset = function() {
|
||||||
rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
|
initialSyncDeferred = $q.defer();
|
||||||
};
|
|
||||||
|
$rootScope.events = {
|
||||||
|
rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
reset();
|
||||||
|
|
||||||
// used for dedupping events - could be expanded in future...
|
// used for dedupping events - could be expanded in future...
|
||||||
// FIXME: means that we leak memory over time (along with lots of the rest
|
// FIXME: means that we leak memory over time (along with lots of the rest
|
||||||
|
@ -55,6 +62,11 @@ angular.module('eventHandlerService', [])
|
||||||
$rootScope.events.rooms[room_id] = {};
|
$rootScope.events.rooms[room_id] = {};
|
||||||
$rootScope.events.rooms[room_id].messages = [];
|
$rootScope.events.rooms[room_id].messages = [];
|
||||||
$rootScope.events.rooms[room_id].members = {};
|
$rootScope.events.rooms[room_id].members = {};
|
||||||
|
|
||||||
|
// Pagination information
|
||||||
|
$rootScope.events.rooms[room_id].pagination = {
|
||||||
|
earliest_token: "END" // how far back we've paginated
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,9 +76,37 @@ angular.module('eventHandlerService', [])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleRoomCreate = function(event, isLiveEvent) {
|
// Generic method to handle events data
|
||||||
initRoom(event.room_id);
|
var handleRoomDateEvent = function(event, isLiveEvent, addToRoomMessages) {
|
||||||
|
// Add topic changes as if they were a room message
|
||||||
|
if (addToRoomMessages) {
|
||||||
|
if (isLiveEvent) {
|
||||||
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$rootScope.events.rooms[event.room_id].messages.unshift(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// live events always update, but non-live events only update if the
|
||||||
|
// ts is later.
|
||||||
|
var latestData = true;
|
||||||
|
if (!isLiveEvent) {
|
||||||
|
var eventTs = event.ts;
|
||||||
|
var storedEvent = $rootScope.events.rooms[event.room_id][event.type];
|
||||||
|
if (storedEvent) {
|
||||||
|
if (storedEvent.ts > eventTs) {
|
||||||
|
// ignore it, we have a newer one already.
|
||||||
|
latestData = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latestData) {
|
||||||
|
$rootScope.events.rooms[event.room_id][event.type] = event;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleRoomCreate = function(event, isLiveEvent) {
|
||||||
// For now, we do not use the event data. Simply signal it to the app controllers
|
// For now, we do not use the event data. Simply signal it to the app controllers
|
||||||
$rootScope.$broadcast(ROOM_CREATE_EVENT, event, isLiveEvent);
|
$rootScope.$broadcast(ROOM_CREATE_EVENT, event, isLiveEvent);
|
||||||
};
|
};
|
||||||
|
@ -76,13 +116,18 @@ angular.module('eventHandlerService', [])
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleMessage = function(event, isLiveEvent) {
|
var handleMessage = function(event, isLiveEvent) {
|
||||||
initRoom(event.room_id);
|
|
||||||
|
|
||||||
if (isLiveEvent) {
|
if (isLiveEvent) {
|
||||||
if (event.user_id === matrixService.config().user_id &&
|
if (event.user_id === matrixService.config().user_id &&
|
||||||
(event.content.msgtype === "m.text" || event.content.msgtype === "m.emote") ) {
|
(event.content.msgtype === "m.text" || event.content.msgtype === "m.emote") ) {
|
||||||
// assume we've already echoed it
|
// Assume we've already echoed it. So, there is a fake event in the messages list of the room
|
||||||
// FIXME: track events by ID and ungrey the right message to show it's been delivered
|
// Replace this fake event by the true one
|
||||||
|
var index = getRoomEventIndex(event.room_id, event.event_id);
|
||||||
|
if (index) {
|
||||||
|
$rootScope.events.rooms[event.room_id].messages[index] = event;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rootScope.events.rooms[event.room_id].messages.push(event);
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
|
@ -100,9 +145,7 @@ angular.module('eventHandlerService', [])
|
||||||
$rootScope.$broadcast(MSG_EVENT, event, isLiveEvent);
|
$rootScope.$broadcast(MSG_EVENT, event, isLiveEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleRoomMember = function(event, isLiveEvent) {
|
var handleRoomMember = function(event, isLiveEvent, isStateEvent) {
|
||||||
initRoom(event.room_id);
|
|
||||||
|
|
||||||
// if the server is stupidly re-relaying a no-op join, discard it.
|
// if the server is stupidly re-relaying a no-op join, discard it.
|
||||||
if (event.prev_content &&
|
if (event.prev_content &&
|
||||||
event.content.membership === "join" &&
|
event.content.membership === "join" &&
|
||||||
|
@ -112,7 +155,10 @@ angular.module('eventHandlerService', [])
|
||||||
}
|
}
|
||||||
|
|
||||||
// add membership changes as if they were a room message if something interesting changed
|
// add membership changes as if they were a room message if something interesting changed
|
||||||
if (event.content.prev !== event.content.membership) {
|
// Exception: Do not do this if the event is a room state event because such events already come
|
||||||
|
// as room messages events. Moreover, when they come as room messages events, they are relatively ordered
|
||||||
|
// with other other room messages
|
||||||
|
if (event.content.prev !== event.content.membership && !isStateEvent) {
|
||||||
if (isLiveEvent) {
|
if (isLiveEvent) {
|
||||||
$rootScope.events.rooms[event.room_id].messages.push(event);
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
}
|
}
|
||||||
|
@ -121,8 +167,13 @@ angular.module('eventHandlerService', [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.events.rooms[event.room_id].members[event.state_key] = event;
|
// Use data from state event or the latest data from the stream.
|
||||||
$rootScope.$broadcast(MEMBER_EVENT, event, isLiveEvent);
|
// Do not care of events that come when paginating back
|
||||||
|
if (isStateEvent || isLiveEvent) {
|
||||||
|
$rootScope.events.rooms[event.room_id].members[event.state_key] = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootScope.$broadcast(MEMBER_EVENT, event, isLiveEvent, isStateEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
var handlePresence = function(event, isLiveEvent) {
|
var handlePresence = function(event, isLiveEvent) {
|
||||||
|
@ -131,8 +182,6 @@ angular.module('eventHandlerService', [])
|
||||||
};
|
};
|
||||||
|
|
||||||
var handlePowerLevels = function(event, isLiveEvent) {
|
var handlePowerLevels = function(event, isLiveEvent) {
|
||||||
initRoom(event.room_id);
|
|
||||||
|
|
||||||
// Keep the latest data. Do not care of events that come when paginating back
|
// Keep the latest data. Do not care of events that come when paginating back
|
||||||
if (!$rootScope.events.rooms[event.room_id][event.type] || isLiveEvent) {
|
if (!$rootScope.events.rooms[event.room_id][event.type] || isLiveEvent) {
|
||||||
$rootScope.events.rooms[event.room_id][event.type] = event;
|
$rootScope.events.rooms[event.room_id][event.type] = event;
|
||||||
|
@ -140,19 +189,50 @@ angular.module('eventHandlerService', [])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleRoomName = function(event, isLiveEvent) {
|
var handleRoomName = function(event, isLiveEvent, isStateEvent) {
|
||||||
console.log("handleRoomName " + isLiveEvent);
|
console.log("handleRoomName room_id: " + event.room_id + " - isLiveEvent: " + isLiveEvent + " - name: " + event.content.name);
|
||||||
|
handleRoomDateEvent(event, isLiveEvent, !isStateEvent);
|
||||||
initRoom(event.room_id);
|
|
||||||
|
|
||||||
$rootScope.events.rooms[event.room_id][event.type] = event;
|
|
||||||
$rootScope.$broadcast(NAME_EVENT, event, isLiveEvent);
|
$rootScope.$broadcast(NAME_EVENT, event, isLiveEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var handleRoomTopic = function(event, isLiveEvent, isStateEvent) {
|
||||||
|
console.log("handleRoomTopic room_id: " + event.room_id + " - isLiveEvent: " + isLiveEvent + " - topic: " + event.content.topic);
|
||||||
|
handleRoomDateEvent(event, isLiveEvent, !isStateEvent);
|
||||||
|
$rootScope.$broadcast(TOPIC_EVENT, event, isLiveEvent);
|
||||||
|
};
|
||||||
|
|
||||||
var handleCallEvent = function(event, isLiveEvent) {
|
var handleCallEvent = function(event, isLiveEvent) {
|
||||||
$rootScope.$broadcast(CALL_EVENT, event, isLiveEvent);
|
$rootScope.$broadcast(CALL_EVENT, event, isLiveEvent);
|
||||||
|
if (event.type == 'm.call.invite') {
|
||||||
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the event in $rootScope.events.rooms[room_id].messages
|
||||||
|
* @param {type} room_id the room id
|
||||||
|
* @param {type} event_id the event id to look for
|
||||||
|
* @returns {Number | undefined} the index. undefined if not found.
|
||||||
|
*/
|
||||||
|
var getRoomEventIndex = function(room_id, event_id) {
|
||||||
|
var index;
|
||||||
|
|
||||||
|
var room = $rootScope.events.rooms[room_id];
|
||||||
|
if (room) {
|
||||||
|
// Start looking from the tail since the first goal of this function
|
||||||
|
// is to find a messaged among the latest ones
|
||||||
|
for (var i = room.messages.length - 1; i > 0; i--) {
|
||||||
|
var message = room.messages[i];
|
||||||
|
if (event_id === message.event_id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
|
ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
|
||||||
MSG_EVENT: MSG_EVENT,
|
MSG_EVENT: MSG_EVENT,
|
||||||
|
@ -161,19 +241,37 @@ angular.module('eventHandlerService', [])
|
||||||
POWERLEVEL_EVENT: POWERLEVEL_EVENT,
|
POWERLEVEL_EVENT: POWERLEVEL_EVENT,
|
||||||
CALL_EVENT: CALL_EVENT,
|
CALL_EVENT: CALL_EVENT,
|
||||||
NAME_EVENT: NAME_EVENT,
|
NAME_EVENT: NAME_EVENT,
|
||||||
|
TOPIC_EVENT: TOPIC_EVENT,
|
||||||
|
RESET_EVENT: RESET_EVENT,
|
||||||
|
|
||||||
handleEvent: function(event, isLiveEvent) {
|
reset: function() {
|
||||||
// FIXME: event duplication suppression is all broken as the code currently expect to handles
|
reset();
|
||||||
// events multiple times to get their side-effects...
|
$rootScope.$broadcast(RESET_EVENT);
|
||||||
/*
|
},
|
||||||
if (eventMap[event.event_id]) {
|
|
||||||
console.log("discarding duplicate event: " + JSON.stringify(event));
|
handleEvent: function(event, isLiveEvent, isStateEvent) {
|
||||||
return;
|
|
||||||
|
// FIXME: /initialSync on a particular room is not yet available
|
||||||
|
// So initRoom on a new room is not called. Make sure the room data is initialised here
|
||||||
|
initRoom(event.room_id);
|
||||||
|
|
||||||
|
// Avoid duplicated events
|
||||||
|
// Needed for rooms where initialSync has not been done.
|
||||||
|
// In this case, we do not know where to start pagination. So, it starts from the END
|
||||||
|
// and we can have the same event (ex: joined, invitation) coming from the pagination
|
||||||
|
// AND from the event stream.
|
||||||
|
// FIXME: This workaround should be no more required when /initialSync on a particular room
|
||||||
|
// will be available (as opposite to the global /initialSync done at startup)
|
||||||
|
if (!isStateEvent) { // Do not consider state events
|
||||||
|
if (event.event_id && eventMap[event.event_id]) {
|
||||||
|
console.log("discarding duplicate event: " + JSON.stringify(event, undefined, 4));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eventMap[event.event_id] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
eventMap[event.event_id] = 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (event.type.indexOf('m.call.') === 0) {
|
if (event.type.indexOf('m.call.') === 0) {
|
||||||
handleCallEvent(event, isLiveEvent);
|
handleCallEvent(event, isLiveEvent);
|
||||||
}
|
}
|
||||||
|
@ -189,7 +287,7 @@ angular.module('eventHandlerService', [])
|
||||||
handleMessage(event, isLiveEvent);
|
handleMessage(event, isLiveEvent);
|
||||||
break;
|
break;
|
||||||
case "m.room.member":
|
case "m.room.member":
|
||||||
handleRoomMember(event, isLiveEvent);
|
handleRoomMember(event, isLiveEvent, isStateEvent);
|
||||||
break;
|
break;
|
||||||
case "m.presence":
|
case "m.presence":
|
||||||
handlePresence(event, isLiveEvent);
|
handlePresence(event, isLiveEvent);
|
||||||
|
@ -202,7 +300,10 @@ angular.module('eventHandlerService', [])
|
||||||
handlePowerLevels(event, isLiveEvent);
|
handlePowerLevels(event, isLiveEvent);
|
||||||
break;
|
break;
|
||||||
case 'm.room.name':
|
case 'm.room.name':
|
||||||
handleRoomName(event, isLiveEvent);
|
handleRoomName(event, isLiveEvent, isStateEvent);
|
||||||
|
break;
|
||||||
|
case 'm.room.topic':
|
||||||
|
handleRoomTopic(event, isLiveEvent, isStateEvent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Unable to handle event type " + event.type);
|
console.log("Unable to handle event type " + event.type);
|
||||||
|
@ -214,20 +315,30 @@ angular.module('eventHandlerService', [])
|
||||||
|
|
||||||
// isLiveEvents determines whether notifications should be shown, whether
|
// isLiveEvents determines whether notifications should be shown, whether
|
||||||
// messages get appended to the start/end of lists, etc.
|
// messages get appended to the start/end of lists, etc.
|
||||||
handleEvents: function(events, isLiveEvents) {
|
handleEvents: function(events, isLiveEvents, isStateEvents) {
|
||||||
for (var i=0; i<events.length; i++) {
|
for (var i=0; i<events.length; i++) {
|
||||||
this.handleEvent(events[i], isLiveEvents);
|
this.handleEvent(events[i], isLiveEvents, isStateEvents);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleInitialSyncDone: function() {
|
// Handle messages from /initialSync or /messages
|
||||||
|
handleRoomMessages: function(room_id, messages, isLiveEvents) {
|
||||||
|
initRoom(room_id);
|
||||||
|
this.handleEvents(messages.chunk, isLiveEvents);
|
||||||
|
|
||||||
|
// Store how far back we've paginated
|
||||||
|
// This assumes the paginations requests are contiguous and in reverse chronological order
|
||||||
|
$rootScope.events.rooms[room_id].pagination.earliest_token = messages.end;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleInitialSyncDone: function(initialSyncData) {
|
||||||
console.log("# handleInitialSyncDone");
|
console.log("# handleInitialSyncDone");
|
||||||
InitialSyncDeferred.resolve($rootScope.events, $rootScope.presence);
|
initialSyncDeferred.resolve(initialSyncData);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns a promise that resolves when the initialSync request has been processed
|
// Returns a promise that resolves when the initialSync request has been processed
|
||||||
waitForInitialSyncCompletion: function() {
|
waitForInitialSyncCompletion: function() {
|
||||||
return InitialSyncDeferred.promise;
|
return initialSyncDeferred.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
resetRoomMessages: function(room_id) {
|
resetRoomMessages: function(room_id) {
|
||||||
|
|
|
@ -104,15 +104,19 @@ angular.module('eventStreamService', [])
|
||||||
settings.isActive = true;
|
settings.isActive = true;
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
|
||||||
// FIXME: We are discarding all the messages.
|
// Initial sync: get all information and the last message of all rooms of the user
|
||||||
matrixService.rooms().then(
|
matrixService.initialSync(1, false).then(
|
||||||
function(response) {
|
function(response) {
|
||||||
var rooms = response.data.rooms;
|
var rooms = response.data.rooms;
|
||||||
for (var i = 0; i < rooms.length; ++i) {
|
for (var i = 0; i < rooms.length; ++i) {
|
||||||
var room = rooms[i];
|
var room = rooms[i];
|
||||||
// console.log("got room: " + room.room_id);
|
|
||||||
|
if ("messages" in room) {
|
||||||
|
eventHandlerService.handleRoomMessages(room.room_id, room.messages, false);
|
||||||
|
}
|
||||||
|
|
||||||
if ("state" in room) {
|
if ("state" in room) {
|
||||||
eventHandlerService.handleEvents(room.state, false);
|
eventHandlerService.handleEvents(room.state, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +124,9 @@ angular.module('eventStreamService', [])
|
||||||
eventHandlerService.handleEvents(presence, false);
|
eventHandlerService.handleEvents(presence, false);
|
||||||
|
|
||||||
// Initial sync is done
|
// Initial sync is done
|
||||||
eventHandlerService.handleInitialSyncDone();
|
eventHandlerService.handleInitialSyncDone(response);
|
||||||
|
|
||||||
|
// Start event streaming from that point
|
||||||
settings.from = response.data.end;
|
settings.from = response.data.end;
|
||||||
doEventStream(deferred);
|
doEventStream(deferred);
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,8 +35,13 @@ var forAllTracksOnStream = function(s, f) {
|
||||||
forAllAudioTracksOnStream(s, f);
|
forAllAudioTracksOnStream(s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||||
|
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection; // but not mozRTCPeerConnection because its interface is not compatible
|
||||||
|
window.RTCSessionDescription = window.RTCSessionDescription || window.webkitRTCSessionDescription || window.mozRTCSessionDescription;
|
||||||
|
window.RTCIceCandidate = window.RTCIceCandidate || window.webkitRTCIceCandidate || window.mozRTCIceCandidate;
|
||||||
|
|
||||||
angular.module('MatrixCall', [])
|
angular.module('MatrixCall', [])
|
||||||
.factory('MatrixCall', ['matrixService', 'matrixPhoneService', '$rootScope', function MatrixCallFactory(matrixService, matrixPhoneService, $rootScope) {
|
.factory('MatrixCall', ['matrixService', 'matrixPhoneService', '$rootScope', '$timeout', function MatrixCallFactory(matrixService, matrixPhoneService, $rootScope, $timeout) {
|
||||||
var MatrixCall = function(room_id) {
|
var MatrixCall = function(room_id) {
|
||||||
this.room_id = room_id;
|
this.room_id = room_id;
|
||||||
this.call_id = "c" + new Date().getTime();
|
this.call_id = "c" + new Date().getTime();
|
||||||
|
@ -44,93 +49,117 @@ angular.module('MatrixCall', [])
|
||||||
this.didConnect = false;
|
this.didConnect = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
MatrixCall.prototype.createPeerConnection = function() {
|
||||||
|
var stunServer = 'stun:stun.l.google.com:19302';
|
||||||
|
var pc;
|
||||||
|
if (window.mozRTCPeerConnection) {
|
||||||
|
pc = window.mozRTCPeerConnection({'url': stunServer});
|
||||||
|
} else {
|
||||||
|
pc = new window.RTCPeerConnection({"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]});
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
|
pc.oniceconnectionstatechange = function() { self.onIceConnectionStateChanged(); };
|
||||||
|
pc.onsignalingstatechange = function() { self.onSignallingStateChanged(); };
|
||||||
|
pc.onicecandidate = function(c) { self.gotLocalIceCandidate(c); };
|
||||||
|
pc.onaddstream = function(s) { self.onAddStream(s); };
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
|
MatrixCall.prototype.placeCall = function(config) {
|
||||||
|
var self = this;
|
||||||
MatrixCall.prototype.placeCall = function() {
|
|
||||||
self = this;
|
|
||||||
matrixPhoneService.callPlaced(this);
|
matrixPhoneService.callPlaced(this);
|
||||||
navigator.getUserMedia({audio: true, video: false}, function(s) { self.gotUserMediaForInvite(s); }, function(e) { self.getUserMediaFailed(e); });
|
navigator.getUserMedia({audio: config.audio, video: config.video}, function(s) { self.gotUserMediaForInvite(s); }, function(e) { self.getUserMediaFailed(e); });
|
||||||
self.state = 'wait_local_media';
|
this.state = 'wait_local_media';
|
||||||
this.direction = 'outbound';
|
this.direction = 'outbound';
|
||||||
|
this.config = config;
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.initWithInvite = function(msg) {
|
MatrixCall.prototype.initWithInvite = function(msg) {
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
this.peerConn = new window.RTCPeerConnection({"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]})
|
this.peerConn = this.createPeerConnection();
|
||||||
self= this;
|
this.peerConn.setRemoteDescription(new RTCSessionDescription(this.msg.offer), this.onSetRemoteDescriptionSuccess, this.onSetRemoteDescriptionError);
|
||||||
this.peerConn.oniceconnectionstatechange = function() { self.onIceConnectionStateChanged(); };
|
|
||||||
this.peerConn.onicecandidate = function(c) { self.gotLocalIceCandidate(c); };
|
|
||||||
this.peerConn.onsignalingstatechange = function() { self.onSignallingStateChanged(); };
|
|
||||||
this.peerConn.onaddstream = function(s) { self.onAddStream(s); };
|
|
||||||
this.peerConn.setRemoteDescription(new RTCSessionDescription(this.msg.offer), self.onSetRemoteDescriptionSuccess, self.onSetRemoteDescriptionError);
|
|
||||||
this.state = 'ringing';
|
this.state = 'ringing';
|
||||||
this.direction = 'inbound';
|
this.direction = 'inbound';
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.answer = function() {
|
MatrixCall.prototype.answer = function() {
|
||||||
console.trace("Answering call "+this.call_id);
|
console.log("Answering call "+this.call_id);
|
||||||
self = this;
|
var self = this;
|
||||||
navigator.getUserMedia({audio: true, video: false}, function(s) { self.gotUserMediaForAnswer(s); }, function(e) { self.getUserMediaFailed(e); });
|
if (!this.localAVStream && !this.waitForLocalAVStream) {
|
||||||
this.state = 'wait_local_media';
|
navigator.getUserMedia({audio: true, video: false}, function(s) { self.gotUserMediaForAnswer(s); }, function(e) { self.getUserMediaFailed(e); });
|
||||||
|
this.state = 'wait_local_media';
|
||||||
|
} else if (this.localAVStream) {
|
||||||
|
this.gotUserMediaForAnswer(this.localAVStream);
|
||||||
|
} else if (this.waitForLocalAVStream) {
|
||||||
|
this.state = 'wait_local_media';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.stopAllMedia = function() {
|
MatrixCall.prototype.stopAllMedia = function() {
|
||||||
if (this.localAVStream) {
|
if (this.localAVStream) {
|
||||||
forAllTracksOnStream(this.localAVStream, function(t) {
|
forAllTracksOnStream(this.localAVStream, function(t) {
|
||||||
t.stop();
|
if (t.stop) t.stop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.remoteAVStream) {
|
if (this.remoteAVStream) {
|
||||||
forAllTracksOnStream(this.remoteAVStream, function(t) {
|
forAllTracksOnStream(this.remoteAVStream, function(t) {
|
||||||
t.stop();
|
if (t.stop) t.stop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.hangup = function() {
|
MatrixCall.prototype.hangup = function(suppressEvent) {
|
||||||
console.trace("Ending call "+this.call_id);
|
console.log("Ending call "+this.call_id);
|
||||||
|
|
||||||
this.stopAllMedia();
|
this.stopAllMedia();
|
||||||
|
if (this.peerConn) this.peerConn.close();
|
||||||
|
|
||||||
|
this.hangupParty = 'local';
|
||||||
|
|
||||||
var content = {
|
var content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: this.call_id,
|
call_id: this.call_id,
|
||||||
};
|
};
|
||||||
matrixService.sendEvent(this.room_id, 'm.call.hangup', undefined, content).then(this.messageSent, this.messageSendFailed);
|
this.sendEventWithRetry('m.call.hangup', content);
|
||||||
this.state = 'ended';
|
this.state = 'ended';
|
||||||
|
if (this.onHangup && !suppressEvent) this.onHangup(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.gotUserMediaForInvite = function(stream) {
|
MatrixCall.prototype.gotUserMediaForInvite = function(stream) {
|
||||||
|
if (this.successor) {
|
||||||
|
this.successor.gotUserMediaForAnswer(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.state == 'ended') return;
|
||||||
|
|
||||||
this.localAVStream = stream;
|
this.localAVStream = stream;
|
||||||
var audioTracks = stream.getAudioTracks();
|
var audioTracks = stream.getAudioTracks();
|
||||||
for (var i = 0; i < audioTracks.length; i++) {
|
for (var i = 0; i < audioTracks.length; i++) {
|
||||||
audioTracks[i].enabled = true;
|
audioTracks[i].enabled = true;
|
||||||
}
|
}
|
||||||
this.peerConn = new window.RTCPeerConnection({"iceServers":[{"urls":"stun:stun.l.google.com:19302"}]})
|
this.peerConn = this.createPeerConnection();
|
||||||
self = this;
|
|
||||||
this.peerConn.oniceconnectionstatechange = function() { self.onIceConnectionStateChanged(); };
|
|
||||||
this.peerConn.onsignalingstatechange = function() { self.onSignallingStateChanged(); };
|
|
||||||
this.peerConn.onicecandidate = function(c) { self.gotLocalIceCandidate(c); };
|
|
||||||
this.peerConn.onaddstream = function(s) { self.onAddStream(s); };
|
|
||||||
this.peerConn.addStream(stream);
|
this.peerConn.addStream(stream);
|
||||||
|
var self = this;
|
||||||
this.peerConn.createOffer(function(d) {
|
this.peerConn.createOffer(function(d) {
|
||||||
self.gotLocalOffer(d);
|
self.gotLocalOffer(d);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
self.getLocalOfferFailed(e);
|
self.getLocalOfferFailed(e);
|
||||||
});
|
});
|
||||||
this.state = 'create_offer';
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'create_offer';
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.gotUserMediaForAnswer = function(stream) {
|
MatrixCall.prototype.gotUserMediaForAnswer = function(stream) {
|
||||||
|
if (this.state == 'ended') return;
|
||||||
|
|
||||||
this.localAVStream = stream;
|
this.localAVStream = stream;
|
||||||
var audioTracks = stream.getAudioTracks();
|
var audioTracks = stream.getAudioTracks();
|
||||||
for (var i = 0; i < audioTracks.length; i++) {
|
for (var i = 0; i < audioTracks.length; i++) {
|
||||||
audioTracks[i].enabled = true;
|
audioTracks[i].enabled = true;
|
||||||
}
|
}
|
||||||
this.peerConn.addStream(stream);
|
this.peerConn.addStream(stream);
|
||||||
self = this;
|
var self = this;
|
||||||
var constraints = {
|
var constraints = {
|
||||||
'mandatory': {
|
'mandatory': {
|
||||||
'OfferToReceiveAudio': true,
|
'OfferToReceiveAudio': true,
|
||||||
|
@ -138,23 +167,28 @@ angular.module('MatrixCall', [])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this.peerConn.createAnswer(function(d) { self.createdAnswer(d); }, function(e) {}, constraints);
|
this.peerConn.createAnswer(function(d) { self.createdAnswer(d); }, function(e) {}, constraints);
|
||||||
this.state = 'create_answer';
|
// This can't be in an apply() because it's called by a predecessor call under glare conditions :(
|
||||||
|
self.state = 'create_answer';
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.gotLocalIceCandidate = function(event) {
|
MatrixCall.prototype.gotLocalIceCandidate = function(event) {
|
||||||
console.trace(event);
|
console.log(event);
|
||||||
if (event.candidate) {
|
if (event.candidate) {
|
||||||
var content = {
|
var content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: this.call_id,
|
call_id: this.call_id,
|
||||||
candidate: event.candidate
|
candidate: event.candidate
|
||||||
};
|
};
|
||||||
matrixService.sendEvent(this.room_id, 'm.call.candidate', undefined, content).then(this.messageSent, this.messageSendFailed);
|
this.sendEventWithRetry('m.call.candidate', content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixCall.prototype.gotRemoteIceCandidate = function(cand) {
|
MatrixCall.prototype.gotRemoteIceCandidate = function(cand) {
|
||||||
console.trace("Got ICE candidate from remote: "+cand);
|
console.log("Got ICE candidate from remote: "+cand);
|
||||||
|
if (this.state == 'ended') {
|
||||||
|
console.log("Ignoring remote ICE candidate because call has ended");
|
||||||
|
return;
|
||||||
|
}
|
||||||
var candidateObject = new RTCIceCandidate({
|
var candidateObject = new RTCIceCandidate({
|
||||||
sdpMLineIndex: cand.label,
|
sdpMLineIndex: cand.label,
|
||||||
candidate: cand.candidate
|
candidate: cand.candidate
|
||||||
|
@ -163,12 +197,18 @@ angular.module('MatrixCall', [])
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.receivedAnswer = function(msg) {
|
MatrixCall.prototype.receivedAnswer = function(msg) {
|
||||||
this.peerConn.setRemoteDescription(new RTCSessionDescription(msg.answer), self.onSetRemoteDescriptionSuccess, self.onSetRemoteDescriptionError);
|
this.peerConn.setRemoteDescription(new RTCSessionDescription(msg.answer), this.onSetRemoteDescriptionSuccess, this.onSetRemoteDescriptionError);
|
||||||
this.state = 'connecting';
|
this.state = 'connecting';
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.gotLocalOffer = function(description) {
|
MatrixCall.prototype.gotLocalOffer = function(description) {
|
||||||
console.trace("Created offer: "+description);
|
console.log("Created offer: "+description);
|
||||||
|
|
||||||
|
if (this.state == 'ended') {
|
||||||
|
console.log("Ignoring newly created offer on call ID "+this.call_id+" because the call has ended");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.peerConn.setLocalDescription(description);
|
this.peerConn.setLocalDescription(description);
|
||||||
|
|
||||||
var content = {
|
var content = {
|
||||||
|
@ -176,26 +216,27 @@ angular.module('MatrixCall', [])
|
||||||
call_id: this.call_id,
|
call_id: this.call_id,
|
||||||
offer: description
|
offer: description
|
||||||
};
|
};
|
||||||
matrixService.sendEvent(this.room_id, 'm.call.invite', undefined, content).then(this.messageSent, this.messageSendFailed);
|
this.sendEventWithRetry('m.call.invite', content);
|
||||||
this.state = 'invite_sent';
|
|
||||||
|
var self = this;
|
||||||
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'invite_sent';
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.createdAnswer = function(description) {
|
MatrixCall.prototype.createdAnswer = function(description) {
|
||||||
console.trace("Created answer: "+description);
|
console.log("Created answer: "+description);
|
||||||
this.peerConn.setLocalDescription(description);
|
this.peerConn.setLocalDescription(description);
|
||||||
var content = {
|
var content = {
|
||||||
version: 0,
|
version: 0,
|
||||||
call_id: this.call_id,
|
call_id: this.call_id,
|
||||||
answer: description
|
answer: description
|
||||||
};
|
};
|
||||||
matrixService.sendEvent(this.room_id, 'm.call.answer', undefined, content).then(this.messageSent, this.messageSendFailed);
|
this.sendEventWithRetry('m.call.answer', content);
|
||||||
this.state = 'connecting';
|
var self = this;
|
||||||
};
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'connecting';
|
||||||
MatrixCall.prototype.messageSent = function() {
|
});
|
||||||
};
|
|
||||||
|
|
||||||
MatrixCall.prototype.messageSendFailed = function(error) {
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.getLocalOfferFailed = function(error) {
|
MatrixCall.prototype.getLocalOfferFailed = function(error) {
|
||||||
|
@ -204,33 +245,36 @@ angular.module('MatrixCall', [])
|
||||||
|
|
||||||
MatrixCall.prototype.getUserMediaFailed = function() {
|
MatrixCall.prototype.getUserMediaFailed = function() {
|
||||||
this.onError("Couldn't start capturing audio! Is your microphone set up?");
|
this.onError("Couldn't start capturing audio! Is your microphone set up?");
|
||||||
|
this.hangup();
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onIceConnectionStateChanged = function() {
|
MatrixCall.prototype.onIceConnectionStateChanged = function() {
|
||||||
if (this.state == 'ended') return; // because ICE can still complete as we're ending the call
|
if (this.state == 'ended') return; // because ICE can still complete as we're ending the call
|
||||||
console.trace("Ice connection state changed to: "+this.peerConn.iceConnectionState);
|
console.log("Ice connection state changed to: "+this.peerConn.iceConnectionState);
|
||||||
// ideally we'd consider the call to be connected when we get media but chrome doesn't implement nay of the 'onstarted' events yet
|
// ideally we'd consider the call to be connected when we get media but chrome doesn't implement nay of the 'onstarted' events yet
|
||||||
if (this.peerConn.iceConnectionState == 'completed' || this.peerConn.iceConnectionState == 'connected') {
|
if (this.peerConn.iceConnectionState == 'completed' || this.peerConn.iceConnectionState == 'connected') {
|
||||||
this.state = 'connected';
|
var self = this;
|
||||||
this.didConnect = true;
|
$rootScope.$apply(function() {
|
||||||
$rootScope.$apply();
|
self.state = 'connected';
|
||||||
|
self.didConnect = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onSignallingStateChanged = function() {
|
MatrixCall.prototype.onSignallingStateChanged = function() {
|
||||||
console.trace("Signalling state changed to: "+this.peerConn.signalingState);
|
console.log("call "+this.call_id+": Signalling state changed to: "+this.peerConn.signalingState);
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onSetRemoteDescriptionSuccess = function() {
|
MatrixCall.prototype.onSetRemoteDescriptionSuccess = function() {
|
||||||
console.trace("Set remote description");
|
console.log("Set remote description");
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onSetRemoteDescriptionError = function(e) {
|
MatrixCall.prototype.onSetRemoteDescriptionError = function(e) {
|
||||||
console.trace("Failed to set remote description"+e);
|
console.log("Failed to set remote description"+e);
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onAddStream = function(event) {
|
MatrixCall.prototype.onAddStream = function(event) {
|
||||||
console.trace("Stream added"+event);
|
console.log("Stream added"+event);
|
||||||
|
|
||||||
var s = event.stream;
|
var s = event.stream;
|
||||||
|
|
||||||
|
@ -251,23 +295,79 @@ angular.module('MatrixCall', [])
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onRemoteStreamStarted = function(event) {
|
MatrixCall.prototype.onRemoteStreamStarted = function(event) {
|
||||||
this.state = 'connected';
|
var self = this;
|
||||||
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'connected';
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onRemoteStreamEnded = function(event) {
|
MatrixCall.prototype.onRemoteStreamEnded = function(event) {
|
||||||
this.state = 'ended';
|
console.log("Remote stream ended");
|
||||||
this.stopAllMedia();
|
var self = this;
|
||||||
this.onHangup();
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'ended';
|
||||||
|
self.hangupParty = 'remote';
|
||||||
|
self.stopAllMedia();
|
||||||
|
if (self.peerConn.signalingState != 'closed') self.peerConn.close();
|
||||||
|
if (self.onHangup) self.onHangup(self);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onRemoteStreamTrackStarted = function(event) {
|
MatrixCall.prototype.onRemoteStreamTrackStarted = function(event) {
|
||||||
this.state = 'connected';
|
var self = this;
|
||||||
|
$rootScope.$apply(function() {
|
||||||
|
self.state = 'connected';
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MatrixCall.prototype.onHangupReceived = function() {
|
MatrixCall.prototype.onHangupReceived = function() {
|
||||||
|
console.log("Hangup received");
|
||||||
this.state = 'ended';
|
this.state = 'ended';
|
||||||
|
this.hangupParty = 'remote';
|
||||||
this.stopAllMedia();
|
this.stopAllMedia();
|
||||||
this.onHangup();
|
if (this.peerConn.signalingState != 'closed') this.peerConn.close();
|
||||||
|
if (this.onHangup) this.onHangup(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.replacedBy = function(newCall) {
|
||||||
|
console.log(this.call_id+" being replaced by "+newCall.call_id);
|
||||||
|
if (this.state == 'wait_local_media') {
|
||||||
|
console.log("Telling new call to wait for local media");
|
||||||
|
newCall.waitForLocalAVStream = true;
|
||||||
|
} else if (this.state == 'create_offer') {
|
||||||
|
console.log("Handing local stream to new call");
|
||||||
|
newCall.localAVStream = this.localAVStream;
|
||||||
|
delete(this.localAVStream);
|
||||||
|
} else if (this.state == 'invite_sent') {
|
||||||
|
console.log("Handing local stream to new call");
|
||||||
|
newCall.localAVStream = this.localAVStream;
|
||||||
|
delete(this.localAVStream);
|
||||||
|
}
|
||||||
|
this.successor = newCall;
|
||||||
|
this.hangup(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.sendEventWithRetry = function(evType, content) {
|
||||||
|
var ev = { type:evType, content:content, tries:1 };
|
||||||
|
var self = this;
|
||||||
|
matrixService.sendEvent(this.room_id, evType, undefined, content).then(this.eventSent, function(error) { self.eventSendFailed(ev, error); } );
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.eventSent = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.eventSendFailed = function(ev, error) {
|
||||||
|
if (ev.tries > 5) {
|
||||||
|
console.log("Failed to send event of type "+ev.type+" on attempt "+ev.tries+". Giving up.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var delayMs = 500 * Math.pow(2, ev.tries);
|
||||||
|
console.log("Failed to send event of type "+ev.type+". Retrying in "+delayMs+"ms");
|
||||||
|
++ev.tries;
|
||||||
|
var self = this;
|
||||||
|
$timeout(function() {
|
||||||
|
matrixService.sendEvent(self.room_id, ev.type, undefined, ev.content).then(self.eventSent, function(error) { self.eventSendFailed(ev, error); } );
|
||||||
|
}, delayMs);
|
||||||
};
|
};
|
||||||
|
|
||||||
return MatrixCall;
|
return MatrixCall;
|
||||||
|
|
|
@ -31,15 +31,17 @@ angular.module('matrixFilter', [])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (undefined === roomName) {
|
if (undefined === roomName) {
|
||||||
// Else, build the name from its users
|
|
||||||
var room = $rootScope.events.rooms[room_id];
|
var room = $rootScope.events.rooms[room_id];
|
||||||
if (room) {
|
if (room) {
|
||||||
|
// Get name from room state date
|
||||||
var room_name_event = room["m.room.name"];
|
var room_name_event = room["m.room.name"];
|
||||||
|
|
||||||
if (room_name_event) {
|
if (room_name_event) {
|
||||||
roomName = room_name_event.content.name;
|
roomName = room_name_event.content.name;
|
||||||
}
|
}
|
||||||
else if (room.members) {
|
else if (room.members) {
|
||||||
|
// Else, build the name from its users
|
||||||
|
// FIXME: Is it still required?
|
||||||
// Limit the room renaming to 1:1 room
|
// Limit the room renaming to 1:1 room
|
||||||
if (2 === Object.keys(room.members).length) {
|
if (2 === Object.keys(room.members).length) {
|
||||||
for (var i in room.members) {
|
for (var i in room.members) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ angular.module('matrixPhoneService', [])
|
||||||
};
|
};
|
||||||
|
|
||||||
matrixPhoneService.INCOMING_CALL_EVENT = "INCOMING_CALL_EVENT";
|
matrixPhoneService.INCOMING_CALL_EVENT = "INCOMING_CALL_EVENT";
|
||||||
|
matrixPhoneService.REPLACED_CALL_EVENT = "REPLACED_CALL_EVENT";
|
||||||
matrixPhoneService.allCalls = {};
|
matrixPhoneService.allCalls = {};
|
||||||
|
|
||||||
matrixPhoneService.callPlaced = function(call) {
|
matrixPhoneService.callPlaced = function(call) {
|
||||||
|
@ -38,29 +39,59 @@ angular.module('matrixPhoneService', [])
|
||||||
call.call_id = msg.call_id;
|
call.call_id = msg.call_id;
|
||||||
call.initWithInvite(msg);
|
call.initWithInvite(msg);
|
||||||
matrixPhoneService.allCalls[call.call_id] = call;
|
matrixPhoneService.allCalls[call.call_id] = call;
|
||||||
$rootScope.$broadcast(matrixPhoneService.INCOMING_CALL_EVENT, call);
|
|
||||||
|
// Were we trying to call that user (room)?
|
||||||
|
var existingCall;
|
||||||
|
var callIds = Object.keys(matrixPhoneService.allCalls);
|
||||||
|
for (var i = 0; i < callIds.length; ++i) {
|
||||||
|
var thisCallId = callIds[i];
|
||||||
|
var thisCall = matrixPhoneService.allCalls[thisCallId];
|
||||||
|
|
||||||
|
if (call.room_id == thisCall.room_id && thisCall.direction == 'outbound'
|
||||||
|
&& (thisCall.state == 'wait_local_media' || thisCall.state == 'create_offer' || thisCall.state == 'invite_sent')) {
|
||||||
|
existingCall = thisCall;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingCall) {
|
||||||
|
// If we've only got to wait_local_media or create_offer and we've got an invite,
|
||||||
|
// pick the incoming call because we know we haven't sent our invite yet
|
||||||
|
// otherwise, pick whichever call has the lowest call ID (by string comparison)
|
||||||
|
if (existingCall.state == 'wait_local_media' || existingCall.state == 'create_offer' || existingCall.call_id > call.call_id) {
|
||||||
|
console.log("Glare detected: answering incoming call "+call.call_id+" and canceling outgoing call "+existingCall.call_id);
|
||||||
|
existingCall.replacedBy(call);
|
||||||
|
call.answer();
|
||||||
|
$rootScope.$broadcast(matrixPhoneService.REPLACED_CALL_EVENT, existingCall, call);
|
||||||
|
} else {
|
||||||
|
console.log("Glare detected: rejecting incoming call "+call.call_id+" and keeping outgoing call "+existingCall.call_id);
|
||||||
|
call.hangup();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$rootScope.$broadcast(matrixPhoneService.INCOMING_CALL_EVENT, call);
|
||||||
|
}
|
||||||
} else if (event.type == 'm.call.answer') {
|
} else if (event.type == 'm.call.answer') {
|
||||||
var call = matrixPhoneService.allCalls[msg.call_id];
|
var call = matrixPhoneService.allCalls[msg.call_id];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
console.trace("Got answer for unknown call ID "+msg.call_id);
|
console.log("Got answer for unknown call ID "+msg.call_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.receivedAnswer(msg);
|
call.receivedAnswer(msg);
|
||||||
} else if (event.type == 'm.call.candidate') {
|
} else if (event.type == 'm.call.candidate') {
|
||||||
var call = matrixPhoneService.allCalls[msg.call_id];
|
var call = matrixPhoneService.allCalls[msg.call_id];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
console.trace("Got candidate for unknown call ID "+msg.call_id);
|
console.log("Got candidate for unknown call ID "+msg.call_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.gotRemoteIceCandidate(msg.candidate);
|
call.gotRemoteIceCandidate(msg.candidate);
|
||||||
} else if (event.type == 'm.call.hangup') {
|
} else if (event.type == 'm.call.hangup') {
|
||||||
var call = matrixPhoneService.allCalls[msg.call_id];
|
var call = matrixPhoneService.allCalls[msg.call_id];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
console.trace("Got hangup for unknown call ID "+msg.call_id);
|
console.log("Got hangup for unknown call ID "+msg.call_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.onHangupReceived();
|
call.onHangupReceived();
|
||||||
matrixPhoneService.allCalls[msg.call_id] = undefined;
|
delete(matrixPhoneService.allCalls[msg.call_id]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -130,8 +130,9 @@ angular.module('matrixService', [])
|
||||||
return doRequest("POST", path, undefined, req);
|
return doRequest("POST", path, undefined, req);
|
||||||
},
|
},
|
||||||
|
|
||||||
// List all rooms joined or been invited to
|
// Get the user's current state: his presence, the list of his rooms with
|
||||||
rooms: function(limit, feedback) {
|
// the last {limit} events
|
||||||
|
initialSync: function(limit, feedback) {
|
||||||
// The REST path spec
|
// The REST path spec
|
||||||
|
|
||||||
var path = "/initialSync";
|
var path = "/initialSync";
|
||||||
|
@ -235,6 +236,32 @@ angular.module('matrixService', [])
|
||||||
return doRequest("GET", path, undefined, {});
|
return doRequest("GET", path, undefined, {});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setName: function(room_id, name) {
|
||||||
|
var data = {
|
||||||
|
name: name
|
||||||
|
};
|
||||||
|
return this.sendStateEvent(room_id, "m.room.name", data);
|
||||||
|
},
|
||||||
|
|
||||||
|
setTopic: function(room_id, topic) {
|
||||||
|
var data = {
|
||||||
|
topic: topic
|
||||||
|
};
|
||||||
|
return this.sendStateEvent(room_id, "m.room.topic", data);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
sendStateEvent: function(room_id, eventType, content, state_key) {
|
||||||
|
var path = "/rooms/$room_id/state/"+eventType;
|
||||||
|
if (state_key !== undefined) {
|
||||||
|
path += "/" + state_key;
|
||||||
|
}
|
||||||
|
room_id = encodeURIComponent(room_id);
|
||||||
|
path = path.replace("$room_id", room_id);
|
||||||
|
|
||||||
|
return doRequest("PUT", path, undefined, content);
|
||||||
|
},
|
||||||
|
|
||||||
sendEvent: function(room_id, eventType, txn_id, content) {
|
sendEvent: function(room_id, eventType, txn_id, content) {
|
||||||
// The REST path spec
|
// The REST path spec
|
||||||
var path = "/rooms/$room_id/send/"+eventType+"/$txn_id";
|
var path = "/rooms/$room_id/send/"+eventType+"/$txn_id";
|
||||||
|
|
|
@ -142,4 +142,9 @@ angular.module('HomeController', ['matrixService', 'eventHandlerService', 'Recen
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clean data when user logs out
|
||||||
|
$scope.$on(eventHandlerService.RESET_EVENT, function() {
|
||||||
|
$scope.public_rooms = [];
|
||||||
|
});
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -24,11 +24,30 @@
|
||||||
|
|
||||||
<h3>Public rooms</h3>
|
<h3>Public rooms</h3>
|
||||||
|
|
||||||
<div class="public_rooms" ng-repeat="room in public_rooms">
|
<table class="publicTable">
|
||||||
<div>
|
<tbody ng-repeat="room in public_rooms | orderBy:'room_display_name'"
|
||||||
<a href="#/room/{{ room.room_alias ? room.room_alias : room.room_id }}" >{{ room.room_display_name }}</a>
|
class="publicRoomEntry"
|
||||||
</div>
|
ng-class="room.room_display_name.toLowerCase().indexOf('#matrix:') === 0 ? 'roomHighlight' : ''">
|
||||||
</div>
|
<tr>
|
||||||
|
<td class="publicRoomEntry">
|
||||||
|
<a href="#/room/{{ room.room_alias ? room.room_alias : room.room_id }}" >
|
||||||
|
{{ room.room_display_name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="publicRoomJoinedUsers"
|
||||||
|
ng-show="room.num_joined_members">
|
||||||
|
{{ room.num_joined_members }} {{ room.num_joined_members == 1 ? 'user' : 'users' }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="publicRoomTopic">
|
||||||
|
{{ room.topic }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
<script src="js/angular.min.js"></script>
|
<script src="js/angular.min.js"></script>
|
||||||
<script src="js/angular-route.min.js"></script>
|
<script src="js/angular-route.min.js"></script>
|
||||||
<script src="js/angular-sanitize.min.js"></script>
|
<script src="js/angular-sanitize.min.js"></script>
|
||||||
|
<script src="js/angular-animate.min.js"></script>
|
||||||
<script type='text/javascript' src='js/ng-infinite-scroll-matrix.js'></script>
|
<script type='text/javascript' src='js/ng-infinite-scroll-matrix.js'></script>
|
||||||
|
<script type='text/javascript' src='js/autofill-event.js'></script>
|
||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
<script src="config.js"></script>
|
<script src="config.js"></script>
|
||||||
<script src="app-controller.js"></script>
|
<script src="app-controller.js"></script>
|
||||||
|
@ -56,9 +58,11 @@
|
||||||
<br />
|
<br />
|
||||||
<span id="callState">
|
<span id="callState">
|
||||||
<span ng-show="currentCall.state == 'invite_sent'">Calling...</span>
|
<span ng-show="currentCall.state == 'invite_sent'">Calling...</span>
|
||||||
|
<span ng-show="currentCall.state == 'ringing'">Incoming Call</span>
|
||||||
<span ng-show="currentCall.state == 'connecting'">Call Connecting...</span>
|
<span ng-show="currentCall.state == 'connecting'">Call Connecting...</span>
|
||||||
<span ng-show="currentCall.state == 'connected'">Call Connected</span>
|
<span ng-show="currentCall.state == 'connected'">Call Connected</span>
|
||||||
<span ng-show="currentCall.state == 'ended' && !currentCall.didConnect && currentCall.direction == 'outbound'">Call Rejected</span>
|
<span ng-show="currentCall.state == 'ended' && !currentCall.didConnect && currentCall.direction == 'outbound' && currentCall.hangupParty == 'remote'">Call Rejected</span>
|
||||||
|
<span ng-show="currentCall.state == 'ended' && !currentCall.didConnect && currentCall.direction == 'outbound' && currentCall.hangupParty == 'local'">Call Canceled</span>
|
||||||
<span ng-show="currentCall.state == 'ended' && currentCall.didConnect && currentCall.direction == 'outbound'">Call Ended</span>
|
<span ng-show="currentCall.state == 'ended' && currentCall.didConnect && currentCall.direction == 'outbound'">Call Ended</span>
|
||||||
<span ng-show="currentCall.state == 'ended' && !currentCall.didConnect && currentCall.direction == 'inbound'">Call Canceled</span>
|
<span ng-show="currentCall.state == 'ended' && !currentCall.didConnect && currentCall.direction == 'inbound'">Call Canceled</span>
|
||||||
<span ng-show="currentCall.state == 'ended' && currentCall.didConnect && currentCall.direction == 'inbound'">Call Ended</span>
|
<span ng-show="currentCall.state == 'ended' && currentCall.didConnect && currentCall.direction == 'inbound'">Call Ended</span>
|
||||||
|
@ -70,6 +74,22 @@
|
||||||
<button ng-click="hangupCall()">Reject</button>
|
<button ng-click="hangupCall()">Reject</button>
|
||||||
</span>
|
</span>
|
||||||
<button ng-click="hangupCall()" ng-show="currentCall && currentCall.state != 'ringing' && currentCall.state != 'ended' && currentCall.state != 'fledgling'">Hang up</button>
|
<button ng-click="hangupCall()" ng-show="currentCall && currentCall.state != 'ringing' && currentCall.state != 'ended' && currentCall.state != 'fledgling'">Hang up</button>
|
||||||
|
<audio id="ringAudio" loop>
|
||||||
|
<source src="media/ring.ogg" type="audio/ogg" />
|
||||||
|
<source src="media/ring.mp3" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<audio id="ringbackAudio" loop>
|
||||||
|
<source src="media/ringback.ogg" type="audio/ogg" />
|
||||||
|
<source src="media/ringback.mp3" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<audio id="callendAudio">
|
||||||
|
<source src="media/callend.ogg" type="audio/ogg" />
|
||||||
|
<source src="media/callend.mp3" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<audio id="busyAudio">
|
||||||
|
<source src="media/busy.ogg" type="audio/ogg" />
|
||||||
|
<source src="media/busy.mp3" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
</div>
|
</div>
|
||||||
<a href id="headerUserId" ng-click='goToUserPage(user_id)'>{{ user_id }}</a>
|
<a href id="headerUserId" ng-click='goToUserPage(user_id)'>{{ user_id }}</a>
|
||||||
|
|
||||||
|
|
1051
webclient/js/angular-animate.js
vendored
1051
webclient/js/angular-animate.js
vendored
File diff suppressed because it is too large
Load diff
43
webclient/js/angular-animate.min.js
vendored
43
webclient/js/angular-animate.min.js
vendored
|
@ -1,21 +1,30 @@
|
||||||
/*
|
/*
|
||||||
AngularJS v1.2.0
|
AngularJS v1.3.0-rc.1
|
||||||
(c) 2010-2012 Google, Inc. http://angularjs.org
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
License: MIT
|
License: MIT
|
||||||
*/
|
*/
|
||||||
(function(A,s,B){'use strict';s.module("ngAnimate",["ng"]).config(["$provide","$animateProvider",function(N,D){var z=s.noop,k=s.forEach,X=D.$$selectors,T=1,f="$$ngAnimateState",E="ng-animate",g={running:!0};N.decorator("$animate",["$delegate","$injector","$sniffer","$rootElement","$timeout","$rootScope","$document",function(t,A,F,m,G,p,H){function B(a){if(a){var d=[],b={};a=a.substr(1).split(".");(F.transitions||F.animations)&&a.push("");for(var c=0;c<a.length;c++){var h=a[c],f=X[h];f&&!b[h]&&(d.push(A.get(f)),
|
(function(D,f,E){'use strict';f.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(P,w,g){g=g.ngAnimateChildren;f.isString(g)&&0===g.length?w.data("$$ngAnimateChildren",!0):P.$watch(g,function(f){w.data("$$ngAnimateChildren",!!f)})}}).factory("$$animateReflow",["$$rAF","$document",function(f,w){return function(g){return f(function(){g()})}}]).config(["$provide","$animateProvider",function(P,w){function g(f){for(var g=0;g<f.length;g++){var h=f[g];if(1==h.nodeType)return h}}
|
||||||
b[h]=!0)}return d}}function n(a,d,b,c,h,g,m){function p(a){g();if(!0===a)u();else{if(a=b.data(f))a.done=u,b.data(f,a);s(v,"after",u)}}function s(c,h,g){var f=h+"End";k(c,function(k,t){var e=function(){a:{var e=h+"Complete",a=c[t];a[e]=!0;(a[f]||z)();for(a=0;a<c.length;a++)if(!c[a][e])break a;g()}};"before"!=h||"enter"!=a&&"move"!=a?k[h]?k[f]=n?k[h](b,d,e):k[h](b,e):e():e()})}function t(){m&&G(m,0,!1)}function u(){if(!u.hasBeenRun){u.hasBeenRun=!0;var a=b.data(f);a&&(n?q(b):(a.closeAnimationTimeout=
|
function Z(f,h){return g(f)==g(h)}var q=f.noop,h=f.forEach,$=w.$$selectors,W=f.isArray,u={running:!0};P.decorator("$animate",["$delegate","$$q","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$document","$templateRequest",function(Q,D,I,E,v,X,x,Y,J){function K(a,c){var d=a.data("$$ngAnimateState")||{};c&&(d.running=!0,d.structural=!0,a.data("$$ngAnimateState",d));return d.disabled||d.running&&d.structural}function L(a){var c,d=D.defer();d.promise.$$cancelFn=function(){c&&c()};
|
||||||
G(function(){q(b)},0,!1),b.data(f,a)));t()}}var r=(" "+((b.attr("class")||"")+" "+d)).replace(/\s+/g,".");c||(c=h?h.parent():b.parent());h=B(r);var n="addClass"==a||"removeClass"==a,r=b.data(f)||{};if(J(b,c)||0===h.length)g(),u();else{var v=[];r.running&&n&&r.structural||k(h,function(c){if(!c.allowCancel||c.allowCancel(b,a,d)){var h=c[a];"leave"==a?(c=h,h=null):c=c["before"+a.charAt(0).toUpperCase()+a.substr(1)];v.push({before:c,after:h})}});0===v.length?(g(),t()):(r.running&&(G.cancel(r.closeAnimationTimeout),
|
x.$$postDigest(function(){c=a(function(){d.resolve()})});return d.promise}function M(a,c,d){d=d||{};var e={};h(c.add,function(b){b&&b.length&&(e[b]=e[b]||0,e[b]++)});h(c.remove,function(b){b&&b.length&&(e[b]=e[b]||0,e[b]--)});var R=[];h(d,function(b,a){h(a.split(" "),function(a){R[a]=b})});var g=[],l=[];h(e,function(b,c){var d=f.$$hasClass(a[0],c),e=R[c]||{};0>b?(d||"addClass"==e.event)&&l.push(c):0<b&&(d&&"removeClass"!=e.event||g.push(c))});return 0<g.length+l.length&&[g.join(" "),l.join(" ")]}
|
||||||
q(b),K(r.animations),(r.done||z)(!0)),"addClass"==a&&b.hasClass(d)||"removeClass"==a&&!b.hasClass(d)?(g(),t()):(b.addClass(E),b.data(f,{running:!0,structural:!n,animations:v,done:p}),s(v,"before",p)))}}function L(a){a=a[0];a.nodeType==T&&k(a.querySelectorAll("."+E),function(a){a=s.element(a);var b=a.data(f);b&&(K(b.animations),q(a))})}function K(a){k(a,function(d){a.beforeComplete||(d.beforeEnd||z)(!0);a.afterComplete||(d.afterEnd||z)(!0)})}function q(a){a[0]==m[0]?g.disabled||(g.running=!1,g.structural=
|
function N(a){if(a){var c=[],d={};a=a.substr(1).split(".");(E.transitions||E.animations)&&c.push(I.get($[""]));for(var e=0;e<a.length;e++){var f=a[e],g=$[f];g&&!d[f]&&(c.push(I.get(g)),d[f]=!0)}return c}}function T(a,c,d){function e(b,a){var c=b[a],d=b["before"+a.charAt(0).toUpperCase()+a.substr(1)];if(c||d)return"leave"==a&&(d=c,c=null),U.push({event:a,fn:c}),m.push({event:a,fn:d}),!0}function f(c,r,e){var A=[];h(c,function(b){b.fn&&A.push(b)});var k=0;h(A,function(c,f){var g=function(){a:{if(r){(r[f]||
|
||||||
!1):(a.removeClass(E),a.removeData(f))}function J(a,d){if(g.disabled)return!0;if(a[0]==m[0])return g.disabled||g.running;do{if(0===d.length)break;var b=d[0]==m[0],c=b?g:d.data(f),c=c&&(!!c.disabled||!!c.running);if(b||c)return c;if(b)break}while(d=d.parent());return!0}m.data(f,g);p.$$postDigest(function(){g.running=!1});return{enter:function(a,d,b,c){this.enabled(!1,a);t.enter(a,d,b);p.$$postDigest(function(){n("enter","ng-enter",a,d,b,z,c)})},leave:function(a,d){L(a);this.enabled(!1,a);p.$$postDigest(function(){n("leave",
|
q)();if(++k<A.length)break a;r=null}e()}};switch(c.event){case "setClass":r.push(c.fn(a,l,b,g));break;case "addClass":r.push(c.fn(a,l||d,g));break;case "removeClass":r.push(c.fn(a,b||d,g));break;default:r.push(c.fn(a,g))}});r&&0===r.length&&e()}var g=a[0];if(g){var l,b;W(d)&&(l=d[0],b=d[1],l?b?d=l+" "+b:(d=l,c="addClass"):(d=b,c="removeClass"));var r="setClass"==c,A=r||"addClass"==c||"removeClass"==c,y=a.attr("class")+" "+d;if(B(y)){var C=q,k=[],m=[],n=q,s=[],U=[],y=(" "+y).replace(/\s+/g,".");h(N(y),
|
||||||
"ng-leave",a,null,null,function(){t.leave(a)},d)})},move:function(a,d,b,c){L(a);this.enabled(!1,a);t.move(a,d,b);p.$$postDigest(function(){n("move","ng-move",a,d,b,z,c)})},addClass:function(a,d,b){n("addClass",d,a,null,null,function(){t.addClass(a,d)},b)},removeClass:function(a,d,b){n("removeClass",d,a,null,null,function(){t.removeClass(a,d)},b)},enabled:function(a,d){switch(arguments.length){case 2:if(a)q(d);else{var b=d.data(f)||{};b.disabled=!0;d.data(f,b)}break;case 1:g.disabled=!a;break;default:a=
|
function(b){!e(b,c)&&r&&(e(b,"addClass"),e(b,"removeClass"))});return{node:g,event:c,className:d,isClassBased:A,isSetClassOperation:r,before:function(b){C=b;f(m,k,function(){C=q;b()})},after:function(b){n=b;f(U,s,function(){n=q;b()})},cancel:function(){k&&(h(k,function(b){(b||q)(!0)}),C(!0));s&&(h(s,function(b){(b||q)(!0)}),n(!0))}}}}}function F(a,c,d,e,g,S,l){function b(b){var l="$animate:"+b;m&&m[l]&&0<m[l].length&&X(function(){d.triggerHandler(l,{event:a,className:c})})}function r(){b("before")}
|
||||||
!g.disabled}return!!a}}}]);D.register("",["$window","$sniffer","$timeout",function(f,g,F){function m(e){Q.push(e);F.cancel(R);R=F(function(){k(Q,function(e){e()});Q=[];R=null;C={}},10,!1)}function G(e,a){var w=e.getAttribute("style")||"";e.setAttribute("style",(0<w.length?"; ":"")+a);return w}function p(e,a){var w=a?C[a]:null;if(!w){var b=0,d=0,c=0,l=0,g,n,m,p;k(e,function(e){if(e.nodeType==T){e=f.getComputedStyle(e)||{};m=e[h+D];b=Math.max(H(m),b);p=e[h+S];g=e[h+u];d=Math.max(H(g),d);n=e[I+u];l=
|
function A(){b("after")}function y(){y.hasBeenRun||(y.hasBeenRun=!0,S())}function C(){if(!C.hasBeenRun){C.hasBeenRun=!0;var r=d.data("$$ngAnimateState");r&&(k&&k.isClassBased?z(d,c):(X(function(){var b=d.data("$$ngAnimateState")||{};p==b.index&&z(d,c,a)}),d.data("$$ngAnimateState",r)));b("close");l()}}var k=T(d,a,c);if(!k)return y(),r(),A(),C(),q;a=k.event;c=k.className;var m=f.element._data(k.node),m=m&&m.events;e||(e=g?g.parent():d.parent());if(H(d,e))return y(),r(),A(),C(),q;e=d.data("$$ngAnimateState")||
|
||||||
Math.max(H(n),l);var a=H(e[I+D]);0<a&&(a*=parseInt(e[I+r],10)||1);c=Math.max(a,c)}});w={total:0,transitionPropertyStyle:p,transitionDurationStyle:m,transitionDelayStyle:g,transitionDelay:d,transitionDuration:b,animationDelayStyle:n,animationDelay:l,animationDuration:c};a&&(C[a]=w)}return w}function H(e){var a=0;e=s.isString(e)?e.split(/\s*,\s*/):[];k(e,function(e){a=Math.max(parseFloat(e)||0,a)});return a}function E(e){var a=e.parent(),b=a.data(W);b||(a.data(W,++V),b=V);return b+"-"+e[0].className}
|
{};var n=e.active||{},s=e.totalActive||0,U=e.last;g=!1;if(0<s){s=[];if(k.isClassBased)"setClass"==U.event?(s.push(U),z(d,c)):n[c]&&(t=n[c],t.event==a?g=!0:(s.push(t),z(d,c)));else if("leave"==a&&n["ng-leave"])g=!0;else{for(var t in n)s.push(n[t]);e={};z(d,!0)}0<s.length&&h(s,function(b){b.cancel()})}!k.isClassBased||k.isSetClassOperation||g||(g="addClass"==a==d.hasClass(c));if(g)return y(),r(),A(),b("close"),l(),q;n=e.active||{};s=e.totalActive||0;if("leave"==a)d.one("$destroy",function(b){b=f.element(this);
|
||||||
function n(e,a){var b=E(e),d=b+" "+a,c={},g=C[d]?++C[d].total:0;if(0<g){var l=a+"-stagger",c=b+" "+l;(b=!C[c])&&e.addClass(l);c=p(e,c);b&&e.removeClass(l)}e.addClass(a);d=p(e,d);l=Math.max(d.transitionDuration,d.animationDuration);if(0===l)return e.removeClass(a),!1;var b=e[0],f="";0<d.transitionDuration&&(e.addClass(U),f+=N+" ",b.style[h+S]="none");k(a.split(" "),function(a,e){f+=(0<e?" ":"")+a+"-active"});e.data(v,{className:a,activeClassName:f,maxDuration:l,classes:a+" "+f,timings:d,stagger:c,
|
var a=b.data("$$ngAnimateState");a&&(a=a.active["ng-leave"])&&(a.cancel(),z(b,"ng-leave"))});d.addClass("ng-animate");var p=G++;s++;n[c]=k;d.data("$$ngAnimateState",{last:k,active:n,index:p,totalActive:s});r();k.before(function(b){var l=d.data("$$ngAnimateState");b=b||!l||!l.active[c]||k.isClassBased&&l.active[c].event!=a;y();!0===b?C():(A(),k.after(C))});return k.cancel}function p(a){if(a=g(a))a=f.isFunction(a.getElementsByClassName)?a.getElementsByClassName("ng-animate"):a.querySelectorAll(".ng-animate"),
|
||||||
ii:g});return!0}function L(a,b,w){function f(a){a.stopPropagation();a=a.originalEvent||a;var e=a.$manualTimeStamp||a.timeStamp||Date.now();Math.max(e-t,0)>=p&&a.elapsedTime>=n&&w()}var x=a.data(v);if(a.hasClass(b)&&x){var M=a[0],l=x.timings,k=x.stagger,n=x.maxDuration,m=x.activeClassName,p=1E3*Math.max(l.transitionDelay,l.animationDelay),t=Date.now(),s=P+" "+O,r,x=x.ii,u,y="";if(0<l.transitionDuration){M.style[h+S]="";var q=l.transitionPropertyStyle;-1==q.indexOf("all")&&(u=!0,y+=c+"transition-property: "+
|
h(a,function(a){a=f.element(a);(a=a.data("$$ngAnimateState"))&&a.active&&h(a.active,function(a){a.cancel()})})}function z(a,c){if(Z(a,v))u.disabled||(u.running=!1,u.structural=!1);else if(c){var d=a.data("$$ngAnimateState")||{},e=!0===c;!e&&d.active&&d.active[c]&&(d.totalActive--,delete d.active[c]);if(e||!d.totalActive)a.removeClass("ng-animate"),a.removeData("$$ngAnimateState")}}function H(a,c){if(u.disabled)return!0;if(Z(a,v))return u.running;var d,e,g;do{if(0===c.length)break;var h=Z(c,v),l=h?
|
||||||
q+", "+(g.msie?"-ms-zoom":"clip")+"; ",y+=c+"transition-duration: "+l.transitionDurationStyle+", "+l.transitionDuration+"s; ")}0<x&&(0<k.transitionDelay&&0===k.transitionDuration&&(q=l.transitionDelayStyle,u&&(q+=", "+l.transitionDelay+"s"),y+=c+"transition-delay: "+K(q,k.transitionDelay,x)+"; "),0<k.animationDelay&&0===k.animationDuration&&(y+=c+"animation-delay: "+K(l.animationDelayStyle,k.animationDelay,x)+"; "));0<y.length&&(r=G(M,y));a.on(s,f);a.addClass(m);return function(c){a.off(s,f);a.removeClass(m);
|
u:c.data("$$ngAnimateState")||{};if(l.disabled)return!0;h&&(g=!0);!1!==d&&(h=c.data("$$ngAnimateChildren"),f.isDefined(h)&&(d=h));e=e||l.running||l.last&&!l.last.isClassBased}while(c=c.parent());return!g||!d&&e}v.data("$$ngAnimateState",u);var V=x.$watch(function(){return J.totalPendingRequests},function(a,c){0===a&&(V(),x.$$postDigest(function(){x.$$postDigest(function(){u.running=!1})}))}),G=0,O=w.classNameFilter(),B=O?function(a){return O.test(a)}:function(){return!0};return{enter:function(a,c,
|
||||||
d(a,b);null!=r&&(0<r.length?M.setAttribute("style",r):M.removeAttribute("style"))}}w()}function K(a,b,d){var c="";k(a.split(","),function(a,e){c+=(0<e?",":"")+(d*b+parseInt(a,10))+"s"});return c}function q(a,b){if(n(a,b))return function(c){c&&d(a,b)}}function J(a,b,c){if(a.data(v))return L(a,b,c);d(a,b);c()}function a(a,b,c){var d=q(a,b);if(d){var f=d;m(function(){f=J(a,b,c)});return function(a){(f||z)(a)}}c()}function d(a,b){a.removeClass(b);a.removeClass(U);a.removeData(v)}function b(a,b){var c=
|
d){a=f.element(a);c=c&&f.element(c);d=d&&f.element(d);K(a,!0);Q.enter(a,c,d);return L(function(e){return F("enter","ng-enter",f.element(g(a)),c,d,q,e)})},leave:function(a){a=f.element(a);p(a);K(a,!0);this.enabled(!1,a);return L(function(c){return F("leave","ng-leave",f.element(g(a)),null,null,function(){Q.leave(a)},c)})},move:function(a,c,d){a=f.element(a);c=c&&f.element(c);d=d&&f.element(d);p(a);K(a,!0);Q.move(a,c,d);return L(function(e){return F("move","ng-move",f.element(g(a)),c,d,q,e)})},addClass:function(a,
|
||||||
"";a=s.isArray(a)?a:a.split(/\s+/);k(a,function(a,e){a&&0<a.length&&(c+=(0<e?" ":"")+a+b)});return c}var c="",h,O,I,P;A.ontransitionend===B&&A.onwebkittransitionend!==B?(c="-webkit-",h="WebkitTransition",O="webkitTransitionEnd transitionend"):(h="transition",O="transitionend");A.onanimationend===B&&A.onwebkitanimationend!==B?(c="-webkit-",I="WebkitAnimation",P="webkitAnimationEnd animationend"):(I="animation",P="animationend");var D="Duration",S="Property",u="Delay",r="IterationCount",W="$$ngAnimateKey",
|
c){return this.setClass(a,c,[])},removeClass:function(a,c){return this.setClass(a,[],c)},setClass:function(a,c,d){a=f.element(a);a=f.element(g(a));if(K(a))return Q.setClass(a,c,d);c=W(c)?c:c.split(" ");d=W(d)?d:d.split(" ");var e=a.data("$$animateClasses");if(e)return e.add=e.add.concat(c),e.remove=e.remove.concat(d),e.promise;a.data("$$animateClasses",e={add:c,remove:d});return e.promise=L(function(c){var d=a.data("$$animateClasses");a.removeData("$$animateClasses");var l=a.data("$$ngAnimateState")||
|
||||||
v="$$ngAnimateCSS3Data",U="ng-animate-start",N="ng-animate-active",C={},V=0,Q=[],R;return{allowCancel:function(a,c,d){var f=(a.data(v)||{}).classes;if(!f||0<=["enter","leave","move"].indexOf(c))return!0;var h=a.parent(),g=s.element(a[0].cloneNode());g.attr("style","position:absolute; top:-9999px; left:-9999px");g.removeAttr("id");g.html("");k(f.split(" "),function(a){g.removeClass(a)});g.addClass(b(d,"addClass"==c?"-add":"-remove"));h.append(g);a=p(g);g.remove();return 0<Math.max(a.transitionDuration,
|
{},b=M(a,d,l.active);return b?F("setClass",b,a,null,null,function(){Q.setClass(a,b[0],b[1])},c):c()})},cancel:function(a){a.$$cancelFn()},enabled:function(a,c){switch(arguments.length){case 2:if(a)z(c);else{var d=c.data("$$ngAnimateState")||{};d.disabled=!0;c.data("$$ngAnimateState",d)}break;case 1:u.disabled=!a;break;default:a=!u.disabled}return!!a}}}]);w.register("",["$window","$sniffer","$timeout","$$animateReflow",function(u,w,I,P){function v(a,b){d&&d();c.push(b);d=P(function(){h(c,function(b){b()});
|
||||||
a.animationDuration)},enter:function(b,c){return a(b,"ng-enter",c)},leave:function(b,c){return a(b,"ng-leave",c)},move:function(b,c){return a(b,"ng-move",c)},beforeAddClass:function(a,c,d){if(a=q(a,b(c,"-add")))return m(d),a;d()},addClass:function(a,c,d){return J(a,b(c,"-add"),d)},beforeRemoveClass:function(a,c,d){if(a=q(a,b(c,"-remove")))return m(d),a;d()},removeClass:function(a,c,d){return J(a,b(c,"-remove"),d)}}}])}])})(window,window.angular);
|
c=[];d=null;B={}})}function X(a,b){var c=g(a);a=f.element(c);S.push(a);c=Date.now()+b;c<=R||(I.cancel(e),R=c,e=I(function(){x(S);S=[]},b,!1))}function x(a){h(a,function(b){(b=b.data("$$ngAnimateCSS3Data"))&&h(b.closeAnimationFns,function(b){b()})})}function Y(a,b){var c=b?B[b]:null;if(!c){var d=0,e=0,g=0,f=0;h(a,function(b){if(1==b.nodeType){b=u.getComputedStyle(b)||{};d=Math.max(J(b[H+"Duration"]),d);e=Math.max(J(b[H+"Delay"]),e);f=Math.max(J(b[G+"Delay"]),f);var a=J(b[G+"Duration"]);0<a&&(a*=parseInt(b[G+
|
||||||
|
"IterationCount"],10)||1);g=Math.max(a,g)}});c={total:0,transitionDelay:e,transitionDuration:d,animationDelay:f,animationDuration:g};b&&(B[b]=c)}return c}function J(a){var b=0;a=f.isString(a)?a.split(/\s*,\s*/):[];h(a,function(a){b=Math.max(parseFloat(a)||0,b)});return b}function K(c,b,d){c=0<=["ng-enter","ng-leave","ng-move"].indexOf(d);var e,f=b.parent(),h=f.data("$$ngAnimateKey");h||(f.data("$$ngAnimateKey",++a),h=a);e=h+"-"+g(b).getAttribute("class");var f=e+" "+d,h=B[f]?++B[f].total:0,k={};if(0<
|
||||||
|
h){var m=d+"-stagger",k=e+" "+m;(e=!B[k])&&b.addClass(m);k=Y(b,k);e&&b.removeClass(m)}b.addClass(d);var m=b.data("$$ngAnimateCSS3Data")||{},n=Y(b,f);e=n.transitionDuration;n=n.animationDuration;if(c&&0===e&&0===n)return b.removeClass(d),!1;d=c&&0<e;c=0<n&&0<k.animationDelay&&0===k.animationDuration;b.data("$$ngAnimateCSS3Data",{stagger:k,cacheKey:f,running:m.running||0,itemIndex:h,blockTransition:d,closeAnimationFns:m.closeAnimationFns||[]});b=g(b);d&&(b.style[H+"Property"]="none");c&&(b.style[G+
|
||||||
|
"PlayState"]="paused");return!0}function L(a,b,c,d){function e(a){b.off(D,f);b.removeClass(m);b.removeClass(n);x&&I.cancel(x);F(b,c);a=g(b);for(var d in s)a.style.removeProperty(s[d])}function f(b){b.stopPropagation();var a=b.originalEvent||b;b=a.$manualTimeStamp||a.timeStamp||Date.now();a=parseFloat(a.elapsedTime.toFixed(3));Math.max(b-E,0)>=B&&a>=w&&d()}var k=g(b);a=b.data("$$ngAnimateCSS3Data");if(-1!=k.getAttribute("class").indexOf(c)&&a){a.blockTransition&&(k.style[H+"Property"]="");var m="",
|
||||||
|
n="";h(c.split(" "),function(b,a){var c=(0<a?" ":"")+b;m+=c+"-active";n+=c+"-pending"});var s=[],p=a.itemIndex,t=a.stagger,q=0;if(0<p){q=0;0<t.transitionDelay&&0===t.transitionDuration&&(q=t.transitionDelay*p);var u=0;0<t.animationDelay&&0===t.animationDuration&&(u=t.animationDelay*p,s.push(z+"animation-play-state"));q=Math.round(100*Math.max(q,u))/100}q||b.addClass(m);var v=Y(b,a.cacheKey+" "+m),w=Math.max(v.transitionDuration,v.animationDuration);if(0===w)b.removeClass(m),F(b,c),d();else{var p=
|
||||||
|
Math.max(v.transitionDelay,v.animationDelay),B=1E3*p;0<s.length&&(t=k.getAttribute("style")||"",";"!==t.charAt(t.length-1)&&(t+=";"),k.setAttribute("style",t+" "));var E=Date.now(),D=O+" "+V,p=1E3*(q+1.5*(p+w)),x;0<q&&(b.addClass(n),x=I(function(){x=null;b.addClass(m);b.removeClass(n);0<v.animationDuration&&(k.style[G+"PlayState"]="")},1E3*q,!1));b.on(D,f);a.closeAnimationFns.push(function(){e();d()});a.running++;X(b,p);return e}}else d()}function M(a,b,c,d){if(K(a,b,c,d))return function(a){a&&F(b,
|
||||||
|
c)}}function N(a,b,c,d){if(b.data("$$ngAnimateCSS3Data"))return L(a,b,c,d);F(b,c);d()}function T(a,b,c,d){var e=M(a,b,c);if(e){var f=e;v(b,function(){f=N(a,b,c,d)});return function(b){(f||q)(b)}}d()}function F(a,b){a.removeClass(b);var c=a.data("$$ngAnimateCSS3Data");c&&(c.running&&c.running--,c.running&&0!==c.running||a.removeData("$$ngAnimateCSS3Data"))}function p(a,b){var c="";a=W(a)?a:a.split(/\s+/);h(a,function(a,d){a&&0<a.length&&(c+=(0<d?" ":"")+a+b)});return c}var z="",H,V,G,O;D.ontransitionend===
|
||||||
|
E&&D.onwebkittransitionend!==E?(z="-webkit-",H="WebkitTransition",V="webkitTransitionEnd transitionend"):(H="transition",V="transitionend");D.onanimationend===E&&D.onwebkitanimationend!==E?(z="-webkit-",G="WebkitAnimation",O="webkitAnimationEnd animationend"):(G="animation",O="animationend");var B={},a=0,c=[],d,e=null,R=0,S=[];return{enter:function(a,b){return T("enter",a,"ng-enter",b)},leave:function(a,b){return T("leave",a,"ng-leave",b)},move:function(a,b){return T("move",a,"ng-move",b)},beforeSetClass:function(a,
|
||||||
|
b,c,d){b=p(c,"-remove")+" "+p(b,"-add");if(b=M("setClass",a,b))return v(a,d),b;d()},beforeAddClass:function(a,b,c){if(b=M("addClass",a,p(b,"-add")))return v(a,c),b;c()},beforeRemoveClass:function(a,b,c){if(b=M("removeClass",a,p(b,"-remove")))return v(a,c),b;c()},setClass:function(a,b,c,d){c=p(c,"-remove");b=p(b,"-add");return N("setClass",a,c+" "+b,d)},addClass:function(a,b,c){return N("addClass",a,p(b,"-add"),c)},removeClass:function(a,b,c){return N("removeClass",a,p(b,"-remove"),c)}}}])}])})(window,
|
||||||
|
window.angular);
|
||||||
//# sourceMappingURL=angular-animate.min.js.map
|
//# sourceMappingURL=angular-animate.min.js.map
|
||||||
|
|
61
webclient/js/angular-route.js
vendored
61
webclient/js/angular-route.js
vendored
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @license AngularJS v1.2.20
|
* @license AngularJS v1.3.0-rc.1
|
||||||
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
* License: MIT
|
* License: MIT
|
||||||
*/
|
*/
|
||||||
|
@ -22,12 +22,12 @@
|
||||||
*/
|
*/
|
||||||
/* global -ngRouteModule */
|
/* global -ngRouteModule */
|
||||||
var ngRouteModule = angular.module('ngRoute', ['ng']).
|
var ngRouteModule = angular.module('ngRoute', ['ng']).
|
||||||
provider('$route', $RouteProvider);
|
provider('$route', $RouteProvider),
|
||||||
|
$routeMinErr = angular.$$minErr('ngRoute');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc provider
|
* @ngdoc provider
|
||||||
* @name $routeProvider
|
* @name $routeProvider
|
||||||
* @kind function
|
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
*
|
*
|
||||||
|
@ -216,10 +216,14 @@ function $RouteProvider(){
|
||||||
* Sets route definition that will be used on route change when no other route definition
|
* Sets route definition that will be used on route change when no other route definition
|
||||||
* is matched.
|
* is matched.
|
||||||
*
|
*
|
||||||
* @param {Object} params Mapping information to be assigned to `$route.current`.
|
* @param {Object|string} params Mapping information to be assigned to `$route.current`.
|
||||||
|
* If called with a string, the value maps to `redirectTo`.
|
||||||
* @returns {Object} self
|
* @returns {Object} self
|
||||||
*/
|
*/
|
||||||
this.otherwise = function(params) {
|
this.otherwise = function(params) {
|
||||||
|
if (typeof params === 'string') {
|
||||||
|
params = {redirectTo: params};
|
||||||
|
}
|
||||||
this.when(null, params);
|
this.when(null, params);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
@ -230,10 +234,9 @@ function $RouteProvider(){
|
||||||
'$routeParams',
|
'$routeParams',
|
||||||
'$q',
|
'$q',
|
||||||
'$injector',
|
'$injector',
|
||||||
'$http',
|
'$templateRequest',
|
||||||
'$templateCache',
|
|
||||||
'$sce',
|
'$sce',
|
||||||
function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
|
function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc service
|
* @ngdoc service
|
||||||
|
@ -441,6 +444,36 @@ function $RouteProvider(){
|
||||||
reload: function() {
|
reload: function() {
|
||||||
forceReload = true;
|
forceReload = true;
|
||||||
$rootScope.$evalAsync(updateRoute);
|
$rootScope.$evalAsync(updateRoute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name $route#updateParams
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Causes `$route` service to update the current URL, replacing
|
||||||
|
* current route parameters with those specified in `newParams`.
|
||||||
|
* Provided property names that match the route's path segment
|
||||||
|
* definitions will be interpolated into the location's path, while
|
||||||
|
* remaining properties will be treated as query params.
|
||||||
|
*
|
||||||
|
* @param {Object} newParams mapping of URL parameter names to values
|
||||||
|
*/
|
||||||
|
updateParams: function(newParams) {
|
||||||
|
if (this.current && this.current.$$route) {
|
||||||
|
var searchParams = {}, self=this;
|
||||||
|
|
||||||
|
angular.forEach(Object.keys(newParams), function(key) {
|
||||||
|
if (!self.current.pathParams[key]) searchParams[key] = newParams[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
newParams = angular.extend({}, this.current.params, newParams);
|
||||||
|
$location.path(interpolate(this.current.$$route.originalPath, newParams));
|
||||||
|
$location.search(angular.extend({}, $location.search(), searchParams));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw $routeMinErr('norout', 'Tried updating route when with no current route');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -473,9 +506,7 @@ function $RouteProvider(){
|
||||||
for (var i = 1, len = m.length; i < len; ++i) {
|
for (var i = 1, len = m.length; i < len; ++i) {
|
||||||
var key = keys[i - 1];
|
var key = keys[i - 1];
|
||||||
|
|
||||||
var val = 'string' == typeof m[i]
|
var val = m[i];
|
||||||
? decodeURIComponent(m[i])
|
|
||||||
: m[i];
|
|
||||||
|
|
||||||
if (key && val) {
|
if (key && val) {
|
||||||
params[key.name] = val;
|
params[key.name] = val;
|
||||||
|
@ -518,7 +549,7 @@ function $RouteProvider(){
|
||||||
|
|
||||||
angular.forEach(locals, function(value, key) {
|
angular.forEach(locals, function(value, key) {
|
||||||
locals[key] = angular.isString(value) ?
|
locals[key] = angular.isString(value) ?
|
||||||
$injector.get(value) : $injector.invoke(value);
|
$injector.get(value) : $injector.invoke(value, null, null, key);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (angular.isDefined(template = next.template)) {
|
if (angular.isDefined(template = next.template)) {
|
||||||
|
@ -532,8 +563,7 @@ function $RouteProvider(){
|
||||||
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
|
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
|
||||||
if (angular.isDefined(templateUrl)) {
|
if (angular.isDefined(templateUrl)) {
|
||||||
next.loadedTemplateUrl = templateUrl;
|
next.loadedTemplateUrl = templateUrl;
|
||||||
template = $http.get(templateUrl, {cache: $templateCache}).
|
template = $templateRequest(templateUrl);
|
||||||
then(function(response) { return response.data; });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (angular.isDefined(template)) {
|
if (angular.isDefined(template)) {
|
||||||
|
@ -695,7 +725,6 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
||||||
<pre>$location.path() = {{main.$location.path()}}</pre>
|
<pre>$location.path() = {{main.$location.path()}}</pre>
|
||||||
<pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
|
<pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
|
||||||
<pre>$route.current.params = {{main.$route.current.params}}</pre>
|
<pre>$route.current.params = {{main.$route.current.params}}</pre>
|
||||||
<pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
|
|
||||||
<pre>$routeParams = {{main.$routeParams}}</pre>
|
<pre>$routeParams = {{main.$routeParams}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</file>
|
</file>
|
||||||
|
@ -846,7 +875,7 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
|
||||||
currentScope = null;
|
currentScope = null;
|
||||||
}
|
}
|
||||||
if(currentElement) {
|
if(currentElement) {
|
||||||
$animate.leave(currentElement, function() {
|
$animate.leave(currentElement).then(function() {
|
||||||
previousElement = null;
|
previousElement = null;
|
||||||
});
|
});
|
||||||
previousElement = currentElement;
|
previousElement = currentElement;
|
||||||
|
@ -869,7 +898,7 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
|
||||||
// function is called before linking the content, which would apply child
|
// function is called before linking the content, which would apply child
|
||||||
// directives to non existing elements.
|
// directives to non existing elements.
|
||||||
var clone = $transclude(newScope, function(clone) {
|
var clone = $transclude(newScope, function(clone) {
|
||||||
$animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
|
$animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter () {
|
||||||
if (angular.isDefined(autoScrollExp)
|
if (angular.isDefined(autoScrollExp)
|
||||||
&& (!autoScrollExp || scope.$eval(autoScrollExp))) {
|
&& (!autoScrollExp || scope.$eval(autoScrollExp))) {
|
||||||
$anchorScroll();
|
$anchorScroll();
|
||||||
|
|
20
webclient/js/angular-route.min.js
vendored
20
webclient/js/angular-route.min.js
vendored
|
@ -1,14 +1,14 @@
|
||||||
/*
|
/*
|
||||||
AngularJS v1.2.0
|
AngularJS v1.3.0-rc.1
|
||||||
(c) 2010-2012 Google, Inc. http://angularjs.org
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
License: MIT
|
License: MIT
|
||||||
*/
|
*/
|
||||||
(function(t,c,B){'use strict';function w(s,r,g,a,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(k,d,A){return function(u,k,d){function v(){l&&(l.$destroy(),l=null);m&&(h.leave(m),m=null)}function x(){var f=s.current&&s.current.locals,y=f&&f.$template;if(y){var z=u.$new();A(z,function(e){e.html(y);h.enter(e,null,m||k,function(){!c.isDefined(n)||n&&!u.$eval(n)||r()});v();var p=g(e.contents()),q=s.current;l=q.scope=z;m=e;if(q.controller){f.$scope=l;var d=a(q.controller,
|
(function(r,d,z){'use strict';function v(s,h,f){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,e,b,g,u){function w(){k&&(k.remove(),k=null);l&&(l.$destroy(),l=null);n&&(f.leave(n).then(function(){k=null}),k=n,n=null)}function t(){var c=s.current&&s.current.locals;if(d.isDefined(c&&c.$template)){var c=a.$new(),m=s.current;n=u(c,function(c){f.enter(c,null,n||e).then(function(){!d.isDefined(p)||p&&!a.$eval(p)||h()});w()});l=m.scope=c;l.$emit("$viewContentLoaded");
|
||||||
f);q.controllerAs&&(l[q.controllerAs]=d);e.data("$ngControllerController",d);e.children().data("$ngControllerController",d)}p(l);l.$emit("$viewContentLoaded");l.$eval(b)})}else v()}var l,m,n=d.autoscroll,b=d.onload||"";u.$on("$routeChangeSuccess",x);x()}}}}t=c.module("ngRoute",["ng"]).provider("$route",function(){function s(a,h){return c.extend(new (c.extend(function(){},{prototype:a})),h)}function r(a,c){var k=c.caseInsensitiveMatch,d={originalPath:a,regexp:a},g=d.keys=[];a=a.replace(/([().])/g,
|
l.$eval(q)}else w()}var l,n,k,p=b.autoscroll,q=b.onload||"";a.$on("$routeChangeSuccess",t);t()}}}function x(d,h,f){return{restrict:"ECA",priority:-400,link:function(a,e){var b=f.current,g=b.locals;e.html(g.$template);var u=d(e.contents());b.controller&&(g.$scope=a,g=h(b.controller,g),b.controllerAs&&(a[b.controllerAs]=g),e.data("$ngControllerController",g),e.children().data("$ngControllerController",g));u(a)}}}r=d.module("ngRoute",["ng"]).provider("$route",function(){function s(a,e){return d.extend(new (d.extend(function(){},
|
||||||
"\\$1").replace(/(\/)?:(\w+)([\?|\*])?/g,function(a,c,h,d){a="?"===d?d:null;d="*"===d?d:null;g.push({name:h,optional:!!a});c=c||"";return""+(a?"":c)+"(?:"+(a?c:"")+(d&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=RegExp("^"+a+"$",k?"i":"");return d}var g={};this.when=function(a,h){g[a]=c.extend({reloadOnSearch:!0},h,a&&r(a,h));if(a){var k="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[k]=c.extend({redirectTo:a},r(k,h))}return this};this.otherwise=function(a){this.when(null,
|
{prototype:a})),e)}function h(a,d){var b=d.caseInsensitiveMatch,g={originalPath:a,regexp:a},f=g.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,e,b){a="?"===b?b:null;b="*"===b?b:null;f.push({name:e,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(b&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");g.regexp=new RegExp("^"+a+"$",b?"i":"");return g}var f={};this.when=function(a,e){f[a]=d.extend({reloadOnSearch:!0},e,a&&h(a,e));if(a){var b=
|
||||||
a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,h,k,d,r,u,t,w){function v(){var b=x(),f=n.current;if(b&&f&&b.$$route===f.$$route&&c.equals(b.pathParams,f.pathParams)&&!b.reloadOnSearch&&!m)f.params=b.params,c.copy(f.params,k),a.$broadcast("$routeUpdate",f);else if(b||f)m=!1,a.$broadcast("$routeChangeStart",b,f),(n.current=b)&&b.redirectTo&&(c.isString(b.redirectTo)?h.path(l(b.redirectTo,b.params)).search(b.params).replace():
|
"/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";f[b]=d.extend({redirectTo:a},h(b,e))}return this};this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,e,b,g,h,r,t){function l(){var c=n(),m=q.current;if(c&&m&&c.$$route===m.$$route&&d.equals(c.pathParams,m.pathParams)&&!c.reloadOnSearch&&!p)m.params=c.params,d.copy(m.params,b),a.$broadcast("$routeUpdate",
|
||||||
h.url(b.redirectTo(b.pathParams,h.path(),h.search())).replace()),d.when(b).then(function(){if(b){var a=c.extend({},b.resolve),f,e;c.forEach(a,function(b,f){a[f]=c.isString(b)?r.get(b):r.invoke(b)});c.isDefined(f=b.template)?c.isFunction(f)&&(f=f(b.params)):c.isDefined(e=b.templateUrl)&&(c.isFunction(e)&&(e=e(b.params)),e=w.getTrustedResourceUrl(e),c.isDefined(e)&&(b.loadedTemplateUrl=e,f=u.get(e,{cache:t}).then(function(b){return b.data})));c.isDefined(f)&&(a.$template=f);return d.all(a)}}).then(function(d){b==
|
m);else if(c||m)p=!1,a.$broadcast("$routeChangeStart",c,m),(q.current=c)&&c.redirectTo&&(d.isString(c.redirectTo)?e.path(k(c.redirectTo,c.params)).search(c.params).replace():e.url(c.redirectTo(c.pathParams,e.path(),e.search())).replace()),g.when(c).then(function(){if(c){var a=d.extend({},c.resolve),e,b;d.forEach(a,function(c,b){a[b]=d.isString(c)?h.get(c):h.invoke(c,null,null,b)});d.isDefined(e=c.template)?d.isFunction(e)&&(e=e(c.params)):d.isDefined(b=c.templateUrl)&&(d.isFunction(b)&&(b=b(c.params)),
|
||||||
n.current&&(b&&(b.locals=d,c.copy(b.params,k)),a.$broadcast("$routeChangeSuccess",b,f))},function(c){b==n.current&&a.$broadcast("$routeChangeError",b,f,c)})}function x(){var b,a;c.forEach(g,function(d,l){var e;if(e=!a){var p=h.path();e=d.keys;var q={};if(d.regexp)if(p=d.regexp.exec(p)){for(var g=1,k=p.length;g<k;++g){var m=e[g-1],n="string"==typeof p[g]?decodeURIComponent(p[g]):p[g];m&&n&&(q[m.name]=n)}e=q}else e=null;else e=null;e=b=e}e&&(a=s(d,{params:c.extend({},h.search(),b),pathParams:b}),a.$$route=
|
b=t.getTrustedResourceUrl(b),d.isDefined(b)&&(c.loadedTemplateUrl=b,e=r(b)));d.isDefined(e)&&(a.$template=e);return g.all(a)}}).then(function(e){c==q.current&&(c&&(c.locals=e,d.copy(c.params,b)),a.$broadcast("$routeChangeSuccess",c,m))},function(d){c==q.current&&a.$broadcast("$routeChangeError",c,m,d)})}function n(){var c,a;d.forEach(f,function(b,g){var f;if(f=!a){var h=e.path();f=b.keys;var l={};if(b.regexp)if(h=b.regexp.exec(h)){for(var k=1,n=h.length;k<n;++k){var p=f[k-1],q=h[k];p&&q&&(l[p.name]=
|
||||||
d)});return a||g[null]&&s(g[null],{params:{},pathParams:{}})}function l(a,d){var g=[];c.forEach((a||"").split(":"),function(a,b){if(0===b)g.push(a);else{var c=a.match(/(\w+)(.*)/),h=c[1];g.push(d[h]);g.push(c[2]||"");delete d[h]}});return g.join("")}var m=!1,n={routes:g,reload:function(){m=!0;a.$evalAsync(v)}};a.$on("$locationChangeSuccess",v);return n}]});t.provider("$routeParams",function(){this.$get=function(){return{}}});t.directive("ngView",w);w.$inject=["$route","$anchorScroll","$compile","$controller",
|
q)}f=l}else f=null;else f=null;f=c=f}f&&(a=s(b,{params:d.extend({},e.search(),c),pathParams:c}),a.$$route=b)});return a||f[null]&&s(f[null],{params:{},pathParams:{}})}function k(a,b){var e=[];d.forEach((a||"").split(":"),function(a,c){if(0===c)e.push(a);else{var d=a.match(/(\w+)(.*)/),f=d[1];e.push(b[f]);e.push(d[2]||"");delete b[f]}});return e.join("")}var p=!1,q={routes:f,reload:function(){p=!0;a.$evalAsync(l)},updateParams:function(a){if(this.current&&this.current.$$route){var b={},f=this;d.forEach(Object.keys(a),
|
||||||
"$animate"]})(window,window.angular);
|
function(d){f.current.pathParams[d]||(b[d]=a[d])});a=d.extend({},this.current.params,a);e.path(k(this.current.$$route.originalPath,a));e.search(d.extend({},e.search(),b))}else throw y("norout");}};a.$on("$locationChangeSuccess",l);return q}]});var y=d.$$minErr("ngRoute");r.provider("$routeParams",function(){this.$get=function(){return{}}});r.directive("ngView",v);r.directive("ngView",x);v.$inject=["$route","$anchorScroll","$animate"];x.$inject=["$compile","$controller","$route"]})(window,window.angular);
|
||||||
//# sourceMappingURL=angular-route.min.js.map
|
//# sourceMappingURL=angular-route.min.js.map
|
||||||
|
|
278
webclient/js/angular-sanitize.js
vendored
278
webclient/js/angular-sanitize.js
vendored
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @license AngularJS v1.2.0
|
* @license AngularJS v1.3.0-rc.1
|
||||||
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
* License: MIT
|
* License: MIT
|
||||||
*/
|
*/
|
||||||
(function(window, angular, undefined) {'use strict';
|
(function(window, angular, undefined) {'use strict';
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc overview
|
* @ngdoc module
|
||||||
* @name ngSanitize
|
* @name ngSanitize
|
||||||
* @description
|
* @description
|
||||||
*
|
*
|
||||||
|
@ -16,7 +16,6 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
||||||
*
|
*
|
||||||
* The `ngSanitize` module provides functionality to sanitize HTML.
|
* The `ngSanitize` module provides functionality to sanitize HTML.
|
||||||
*
|
*
|
||||||
* {@installModule sanitize}
|
|
||||||
*
|
*
|
||||||
* <div doc-module-components="ngSanitize"></div>
|
* <div doc-module-components="ngSanitize"></div>
|
||||||
*
|
*
|
||||||
|
@ -42,8 +41,8 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc service
|
* @ngdoc service
|
||||||
* @name ngSanitize.$sanitize
|
* @name $sanitize
|
||||||
* @function
|
* @kind function
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
|
* The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
|
||||||
|
@ -51,25 +50,28 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
||||||
* it into the returned string, however, since our parser is more strict than a typical browser
|
* it into the returned string, however, since our parser is more strict than a typical browser
|
||||||
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
|
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
|
||||||
* browser, won't make it through the sanitizer.
|
* browser, won't make it through the sanitizer.
|
||||||
|
* The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
|
||||||
|
* `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
|
||||||
*
|
*
|
||||||
* @param {string} html Html input.
|
* @param {string} html Html input.
|
||||||
* @returns {string} Sanitized html.
|
* @returns {string} Sanitized html.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
<doc:example module="ngSanitize">
|
<example module="sanitizeExample" deps="angular-sanitize.js">
|
||||||
<doc:source>
|
<file name="index.html">
|
||||||
<script>
|
<script>
|
||||||
function Ctrl($scope, $sce) {
|
angular.module('sanitizeExample', ['ngSanitize'])
|
||||||
$scope.snippet =
|
.controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
|
||||||
'<p style="color:blue">an html\n' +
|
$scope.snippet =
|
||||||
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
|
'<p style="color:blue">an html\n' +
|
||||||
'snippet</p>';
|
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
|
||||||
$scope.deliberatelyTrustDangerousSnippet = function() {
|
'snippet</p>';
|
||||||
return $sce.trustAsHtml($scope.snippet);
|
$scope.deliberatelyTrustDangerousSnippet = function() {
|
||||||
};
|
return $sce.trustAsHtml($scope.snippet);
|
||||||
}
|
};
|
||||||
|
}]);
|
||||||
</script>
|
</script>
|
||||||
<div ng-controller="Ctrl">
|
<div ng-controller="ExampleController">
|
||||||
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -101,56 +103,71 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</doc:source>
|
</file>
|
||||||
<doc:scenario>
|
<file name="protractor.js" type="protractor">
|
||||||
it('should sanitize the html snippet by default', function() {
|
it('should sanitize the html snippet by default', function() {
|
||||||
expect(using('#bind-html-with-sanitize').element('div').html()).
|
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
|
||||||
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
|
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inline raw snippet if bound to a trusted value', function() {
|
it('should inline raw snippet if bound to a trusted value', function() {
|
||||||
expect(using('#bind-html-with-trust').element("div").html()).
|
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
|
||||||
toBe("<p style=\"color:blue\">an html\n" +
|
toBe("<p style=\"color:blue\">an html\n" +
|
||||||
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
||||||
"snippet</p>");
|
"snippet</p>");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape snippet without any filter', function() {
|
it('should escape snippet without any filter', function() {
|
||||||
expect(using('#bind-default').element('div').html()).
|
expect(element(by.css('#bind-default div')).getInnerHtml()).
|
||||||
toBe("<p style=\"color:blue\">an html\n" +
|
toBe("<p style=\"color:blue\">an html\n" +
|
||||||
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
|
||||||
"snippet</p>");
|
"snippet</p>");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update', function() {
|
it('should update', function() {
|
||||||
input('snippet').enter('new <b onclick="alert(1)">text</b>');
|
element(by.model('snippet')).clear();
|
||||||
expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new <b>text</b>');
|
element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
|
||||||
expect(using('#bind-html-with-trust').element('div').html()).toBe(
|
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
|
||||||
|
toBe('new <b>text</b>');
|
||||||
|
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
|
||||||
'new <b onclick="alert(1)">text</b>');
|
'new <b onclick="alert(1)">text</b>');
|
||||||
expect(using('#bind-default').element('div').html()).toBe(
|
expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
|
||||||
"new <b onclick=\"alert(1)\">text</b>");
|
"new <b onclick=\"alert(1)\">text</b>");
|
||||||
});
|
});
|
||||||
</doc:scenario>
|
</file>
|
||||||
</doc:example>
|
</example>
|
||||||
*/
|
*/
|
||||||
var $sanitize = function(html) {
|
function $SanitizeProvider() {
|
||||||
|
this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
|
||||||
|
return function(html) {
|
||||||
|
var buf = [];
|
||||||
|
htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
|
||||||
|
return !/^unsafe/.test($$sanitizeUri(uri, isImage));
|
||||||
|
}));
|
||||||
|
return buf.join('');
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeText(chars) {
|
||||||
var buf = [];
|
var buf = [];
|
||||||
htmlParser(html, htmlSanitizeWriter(buf));
|
var writer = htmlSanitizeWriter(buf, angular.noop);
|
||||||
return buf.join('');
|
writer.chars(chars);
|
||||||
};
|
return buf.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Regular Expressions for parsing tags and attributes
|
// Regular Expressions for parsing tags and attributes
|
||||||
var START_TAG_REGEXP =
|
var START_TAG_REGEXP =
|
||||||
/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
|
/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,
|
||||||
END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
|
END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/,
|
||||||
ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
|
ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
|
||||||
BEGIN_TAG_REGEXP = /^</,
|
BEGIN_TAG_REGEXP = /^</,
|
||||||
BEGING_END_TAGE_REGEXP = /^<\s*\//,
|
BEGING_END_TAGE_REGEXP = /^<\//,
|
||||||
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
||||||
DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
|
DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
|
||||||
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
||||||
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/i,
|
SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
||||||
// Match everything outside of normal chars and " (quote character)
|
// Match everything outside of normal chars and " (quote character)
|
||||||
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
|
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
|
||||||
|
|
||||||
|
@ -197,7 +214,7 @@ var validAttrs = angular.extend({}, uriAttrs, makeMap(
|
||||||
'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
|
'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
|
||||||
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
|
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
|
||||||
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
|
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
|
||||||
'scope,scrolling,shape,span,start,summary,target,title,type,'+
|
'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
|
||||||
'valign,value,vspace,width'));
|
'valign,value,vspace,width'));
|
||||||
|
|
||||||
function makeMap(str) {
|
function makeMap(str) {
|
||||||
|
@ -220,10 +237,18 @@ function makeMap(str) {
|
||||||
* @param {object} handler
|
* @param {object} handler
|
||||||
*/
|
*/
|
||||||
function htmlParser( html, handler ) {
|
function htmlParser( html, handler ) {
|
||||||
var index, chars, match, stack = [], last = html;
|
if (typeof html !== 'string') {
|
||||||
|
if (html === null || typeof html === 'undefined') {
|
||||||
|
html = '';
|
||||||
|
} else {
|
||||||
|
html = '' + html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var index, chars, match, stack = [], last = html, text;
|
||||||
stack.last = function() { return stack[ stack.length - 1 ]; };
|
stack.last = function() { return stack[ stack.length - 1 ]; };
|
||||||
|
|
||||||
while ( html ) {
|
while ( html ) {
|
||||||
|
text = '';
|
||||||
chars = true;
|
chars = true;
|
||||||
|
|
||||||
// Make sure we're not in a script or style element
|
// Make sure we're not in a script or style element
|
||||||
|
@ -244,7 +269,7 @@ function htmlParser( html, handler ) {
|
||||||
match = html.match( DOCTYPE_REGEXP );
|
match = html.match( DOCTYPE_REGEXP );
|
||||||
|
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
html = html.replace( match[0] , '');
|
html = html.replace( match[0], '');
|
||||||
chars = false;
|
chars = false;
|
||||||
}
|
}
|
||||||
// end tag
|
// end tag
|
||||||
|
@ -262,16 +287,23 @@ function htmlParser( html, handler ) {
|
||||||
match = html.match( START_TAG_REGEXP );
|
match = html.match( START_TAG_REGEXP );
|
||||||
|
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
html = html.substring( match[0].length );
|
// We only have a valid start-tag if there is a '>'.
|
||||||
match[0].replace( START_TAG_REGEXP, parseStartTag );
|
if ( match[4] ) {
|
||||||
|
html = html.substring( match[0].length );
|
||||||
|
match[0].replace( START_TAG_REGEXP, parseStartTag );
|
||||||
|
}
|
||||||
chars = false;
|
chars = false;
|
||||||
|
} else {
|
||||||
|
// no ending tag found --- this piece should be encoded as an entity.
|
||||||
|
text += '<';
|
||||||
|
html = html.substring(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( chars ) {
|
if ( chars ) {
|
||||||
index = html.indexOf("<");
|
index = html.indexOf("<");
|
||||||
|
|
||||||
var text = index < 0 ? html : html.substring( 0, index );
|
text += index < 0 ? html : html.substring( 0, index );
|
||||||
html = index < 0 ? "" : html.substring( index );
|
html = index < 0 ? "" : html.substring( index );
|
||||||
|
|
||||||
if (handler.chars) handler.chars( decodeEntities(text) );
|
if (handler.chars) handler.chars( decodeEntities(text) );
|
||||||
|
@ -351,15 +383,32 @@ function htmlParser( html, handler ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hiddenPre=document.createElement("pre");
|
||||||
|
var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
|
||||||
/**
|
/**
|
||||||
* decodes all entities into regular string
|
* decodes all entities into regular string
|
||||||
* @param value
|
* @param value
|
||||||
* @returns {string} A string with decoded entities.
|
* @returns {string} A string with decoded entities.
|
||||||
*/
|
*/
|
||||||
var hiddenPre=document.createElement("pre");
|
|
||||||
function decodeEntities(value) {
|
function decodeEntities(value) {
|
||||||
hiddenPre.innerHTML=value.replace(/</g,"<");
|
if (!value) { return ''; }
|
||||||
return hiddenPre.innerText || hiddenPre.textContent || '';
|
|
||||||
|
// Note: IE8 does not preserve spaces at the start/end of innerHTML
|
||||||
|
// so we must capture them and reattach them afterward
|
||||||
|
var parts = spaceRe.exec(value);
|
||||||
|
var spaceBefore = parts[1];
|
||||||
|
var spaceAfter = parts[3];
|
||||||
|
var content = parts[2];
|
||||||
|
if (content) {
|
||||||
|
hiddenPre.innerHTML=content.replace(/</g,"<");
|
||||||
|
// innerText depends on styling as it doesn't display hidden elements.
|
||||||
|
// Therefore, it's better to use textContent not to cause unnecessary
|
||||||
|
// reflows. However, IE<9 don't support textContent so the innerText
|
||||||
|
// fallback is necessary.
|
||||||
|
content = 'textContent' in hiddenPre ?
|
||||||
|
hiddenPre.textContent : hiddenPre.innerText;
|
||||||
|
}
|
||||||
|
return spaceBefore + content + spaceAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -367,11 +416,16 @@ function decodeEntities(value) {
|
||||||
* resulting string can be safely inserted into attribute or
|
* resulting string can be safely inserted into attribute or
|
||||||
* element text.
|
* element text.
|
||||||
* @param value
|
* @param value
|
||||||
* @returns escaped text
|
* @returns {string} escaped text
|
||||||
*/
|
*/
|
||||||
function encodeEntities(value) {
|
function encodeEntities(value) {
|
||||||
return value.
|
return value.
|
||||||
replace(/&/g, '&').
|
replace(/&/g, '&').
|
||||||
|
replace(SURROGATE_PAIR_REGEXP, function (value) {
|
||||||
|
var hi = value.charCodeAt(0);
|
||||||
|
var low = value.charCodeAt(1);
|
||||||
|
return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
|
||||||
|
}).
|
||||||
replace(NON_ALPHANUMERIC_REGEXP, function(value){
|
replace(NON_ALPHANUMERIC_REGEXP, function(value){
|
||||||
return '&#' + value.charCodeAt(0) + ';';
|
return '&#' + value.charCodeAt(0) + ';';
|
||||||
}).
|
}).
|
||||||
|
@ -389,7 +443,7 @@ function encodeEntities(value) {
|
||||||
* comment: function(text) {}
|
* comment: function(text) {}
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
function htmlSanitizeWriter(buf){
|
function htmlSanitizeWriter(buf, uriValidator){
|
||||||
var ignore = false;
|
var ignore = false;
|
||||||
var out = angular.bind(buf, buf.push);
|
var out = angular.bind(buf, buf.push);
|
||||||
return {
|
return {
|
||||||
|
@ -403,7 +457,9 @@ function htmlSanitizeWriter(buf){
|
||||||
out(tag);
|
out(tag);
|
||||||
angular.forEach(attrs, function(value, key){
|
angular.forEach(attrs, function(value, key){
|
||||||
var lkey=angular.lowercase(key);
|
var lkey=angular.lowercase(key);
|
||||||
if (validAttrs[lkey]===true && (uriAttrs[lkey]!==true || value.match(URI_REGEXP))) {
|
var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
|
||||||
|
if (validAttrs[lkey] === true &&
|
||||||
|
(uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
|
||||||
out(' ');
|
out(' ');
|
||||||
out(key);
|
out(key);
|
||||||
out('="');
|
out('="');
|
||||||
|
@ -435,14 +491,14 @@ function htmlSanitizeWriter(buf){
|
||||||
|
|
||||||
|
|
||||||
// define ngSanitize module and register $sanitize service
|
// define ngSanitize module and register $sanitize service
|
||||||
angular.module('ngSanitize', []).value('$sanitize', $sanitize);
|
angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
|
||||||
|
|
||||||
/* global htmlSanitizeWriter: false */
|
/* global sanitizeText: false */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc filter
|
* @ngdoc filter
|
||||||
* @name ngSanitize.filter:linky
|
* @name linky
|
||||||
* @function
|
* @kind function
|
||||||
*
|
*
|
||||||
* @description
|
* @description
|
||||||
* Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
|
* Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
|
||||||
|
@ -458,20 +514,21 @@ angular.module('ngSanitize', []).value('$sanitize', $sanitize);
|
||||||
<span ng-bind-html="linky_expression | linky"></span>
|
<span ng-bind-html="linky_expression | linky"></span>
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
<doc:example module="ngSanitize">
|
<example module="linkyExample" deps="angular-sanitize.js">
|
||||||
<doc:source>
|
<file name="index.html">
|
||||||
<script>
|
<script>
|
||||||
function Ctrl($scope) {
|
angular.module('linkyExample', ['ngSanitize'])
|
||||||
$scope.snippet =
|
.controller('ExampleController', ['$scope', function($scope) {
|
||||||
'Pretty text with some links:\n'+
|
$scope.snippet =
|
||||||
'http://angularjs.org/,\n'+
|
'Pretty text with some links:\n'+
|
||||||
'mailto:us@somewhere.org,\n'+
|
'http://angularjs.org/,\n'+
|
||||||
'another@somewhere.org,\n'+
|
'mailto:us@somewhere.org,\n'+
|
||||||
'and one more: ftp://127.0.0.1/.';
|
'another@somewhere.org,\n'+
|
||||||
$scope.snippetWithTarget = 'http://angularjs.org/';
|
'and one more: ftp://127.0.0.1/.';
|
||||||
}
|
$scope.snippetWithTarget = 'http://angularjs.org/';
|
||||||
|
}]);
|
||||||
</script>
|
</script>
|
||||||
<div ng-controller="Ctrl">
|
<div ng-controller="ExampleController">
|
||||||
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -503,43 +560,44 @@ angular.module('ngSanitize', []).value('$sanitize', $sanitize);
|
||||||
<td><div ng-bind="snippet"></div></td>
|
<td><div ng-bind="snippet"></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</doc:source>
|
</file>
|
||||||
<doc:scenario>
|
<file name="protractor.js" type="protractor">
|
||||||
it('should linkify the snippet with urls', function() {
|
it('should linkify the snippet with urls', function() {
|
||||||
expect(using('#linky-filter').binding('snippet | linky')).
|
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
|
||||||
toBe('Pretty text with some links: ' +
|
toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
|
||||||
'<a href="http://angularjs.org/">http://angularjs.org/</a>, ' +
|
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
|
||||||
'<a href="mailto:us@somewhere.org">us@somewhere.org</a>, ' +
|
expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
|
||||||
'<a href="mailto:another@somewhere.org">another@somewhere.org</a>, ' +
|
|
||||||
'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it ('should not linkify snippet without the linky filter', function() {
|
it('should not linkify snippet without the linky filter', function() {
|
||||||
expect(using('#escaped-html').binding('snippet')).
|
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
|
||||||
toBe("Pretty text with some links:\n" +
|
toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
|
||||||
"http://angularjs.org/,\n" +
|
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
|
||||||
"mailto:us@somewhere.org,\n" +
|
expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
|
||||||
"another@somewhere.org,\n" +
|
|
||||||
"and one more: ftp://127.0.0.1/.");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update', function() {
|
it('should update', function() {
|
||||||
input('snippet').enter('new http://link.');
|
element(by.model('snippet')).clear();
|
||||||
expect(using('#linky-filter').binding('snippet | linky')).
|
element(by.model('snippet')).sendKeys('new http://link.');
|
||||||
toBe('new <a href="http://link">http://link</a>.');
|
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
|
||||||
expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
|
toBe('new http://link.');
|
||||||
|
expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
|
||||||
|
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
|
||||||
|
.toBe('new http://link.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with the target property', function() {
|
it('should work with the target property', function() {
|
||||||
expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
|
expect(element(by.id('linky-target')).
|
||||||
toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>');
|
element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
|
||||||
|
toBe('http://angularjs.org/');
|
||||||
|
expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
|
||||||
});
|
});
|
||||||
</doc:scenario>
|
</file>
|
||||||
</doc:example>
|
</example>
|
||||||
*/
|
*/
|
||||||
angular.module('ngSanitize').filter('linky', function() {
|
angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
|
||||||
var LINKY_URL_REGEXP =
|
var LINKY_URL_REGEXP =
|
||||||
/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
|
/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"]/,
|
||||||
MAILTO_REGEXP = /^mailto:/;
|
MAILTO_REGEXP = /^mailto:/;
|
||||||
|
|
||||||
return function(text, target) {
|
return function(text, target) {
|
||||||
|
@ -547,31 +605,43 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||||
var match;
|
var match;
|
||||||
var raw = text;
|
var raw = text;
|
||||||
var html = [];
|
var html = [];
|
||||||
// TODO(vojta): use $sanitize instead
|
|
||||||
var writer = htmlSanitizeWriter(html);
|
|
||||||
var url;
|
var url;
|
||||||
var i;
|
var i;
|
||||||
var properties = {};
|
|
||||||
if (angular.isDefined(target)) {
|
|
||||||
properties.target = target;
|
|
||||||
}
|
|
||||||
while ((match = raw.match(LINKY_URL_REGEXP))) {
|
while ((match = raw.match(LINKY_URL_REGEXP))) {
|
||||||
// We can not end in these as they are sometimes found at the end of the sentence
|
// We can not end in these as they are sometimes found at the end of the sentence
|
||||||
url = match[0];
|
url = match[0];
|
||||||
// if we did not match ftp/http/mailto then assume mailto
|
// if we did not match ftp/http/mailto then assume mailto
|
||||||
if (match[2] == match[3]) url = 'mailto:' + url;
|
if (match[2] == match[3]) url = 'mailto:' + url;
|
||||||
i = match.index;
|
i = match.index;
|
||||||
writer.chars(raw.substr(0, i));
|
addText(raw.substr(0, i));
|
||||||
properties.href = url;
|
addLink(url, match[0].replace(MAILTO_REGEXP, ''));
|
||||||
writer.start('a', properties);
|
|
||||||
writer.chars(match[0].replace(MAILTO_REGEXP, ''));
|
|
||||||
writer.end('a');
|
|
||||||
raw = raw.substring(i + match[0].length);
|
raw = raw.substring(i + match[0].length);
|
||||||
}
|
}
|
||||||
writer.chars(raw);
|
addText(raw);
|
||||||
return html.join('');
|
return $sanitize(html.join(''));
|
||||||
|
|
||||||
|
function addText(text) {
|
||||||
|
if (!text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
html.push(sanitizeText(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLink(url, text) {
|
||||||
|
html.push('<a ');
|
||||||
|
if (angular.isDefined(target)) {
|
||||||
|
html.push('target="');
|
||||||
|
html.push(target);
|
||||||
|
html.push('" ');
|
||||||
|
}
|
||||||
|
html.push('href="');
|
||||||
|
html.push(url);
|
||||||
|
html.push('">');
|
||||||
|
addText(text);
|
||||||
|
html.push('</a>');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
}]);
|
||||||
|
|
||||||
|
|
||||||
})(window, window.angular);
|
})(window, window.angular);
|
||||||
|
|
21
webclient/js/angular-sanitize.min.js
vendored
21
webclient/js/angular-sanitize.min.js
vendored
|
@ -1,14 +1,15 @@
|
||||||
/*
|
/*
|
||||||
AngularJS v1.2.0
|
AngularJS v1.3.0-rc.1
|
||||||
(c) 2010-2012 Google, Inc. http://angularjs.org
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
License: MIT
|
License: MIT
|
||||||
*/
|
*/
|
||||||
(function(m,g,n){'use strict';function h(a){var d={};a=a.split(",");var c;for(c=0;c<a.length;c++)d[a[c]]=!0;return d}function D(a,d){function c(a,b,c,f){b=g.lowercase(b);if(r[b])for(;e.last()&&s[e.last()];)k("",e.last());t[b]&&e.last()==b&&k("",b);(f=u[b]||!!f)||e.push(b);var l={};c.replace(E,function(a,b,d,c,e){l[b]=p(d||c||e||"")});d.start&&d.start(b,l,f)}function k(a,b){var c=0,k;if(b=g.lowercase(b))for(c=e.length-1;0<=c&&e[c]!=b;c--);if(0<=c){for(k=e.length-1;k>=c;k--)d.end&&d.end(e[k]);e.length=
|
(function(q,g,r){'use strict';function F(a){var d=[];t(d,g.noop).chars(a);return d.join("")}function m(a){var d={};a=a.split(",");var c;for(c=0;c<a.length;c++)d[a[c]]=!0;return d}function G(a,d){function c(a,b,c,h){b=g.lowercase(b);if(u[b])for(;f.last()&&v[f.last()];)e("",f.last());w[b]&&f.last()==b&&e("",b);(h=x[b]||!!h)||f.push(b);var n={};c.replace(H,function(a,b,d,c,e){n[b]=s(d||c||e||"")});d.start&&d.start(b,n,h)}function e(a,b){var c=0,e;if(b=g.lowercase(b))for(c=f.length-1;0<=c&&f[c]!=b;c--);
|
||||||
c}}var b,f,e=[],l=a;for(e.last=function(){return e[e.length-1]};a;){f=!0;if(e.last()&&v[e.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+e.last()+"[^>]*>","i"),function(a,b){b=b.replace(F,"$1").replace(G,"$1");d.chars&&d.chars(p(b));return""}),k("",e.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(d.comment&&d.comment(a.substring(4,b)),a=a.substring(b+3),f=!1);else if(w.test(a)){if(b=a.match(w))a=a.replace(b[0],""),f=!1}else if(H.test(a)){if(b=a.match(x))a=
|
if(0<=c){for(e=f.length-1;e>=c;e--)d.end&&d.end(f[e]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,l,f=[],n=a,h;for(f.last=function(){return f[f.length-1]};a;){h="";l=!0;if(f.last()&&y[f.last()])a=a.replace(new RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(I,"$1").replace(J,"$1");d.chars&&d.chars(s(b));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(d.comment&&d.comment(a.substring(4,
|
||||||
a.substring(b[0].length),b[0].replace(x,k),f=!1}else I.test(a)&&(b=a.match(y))&&(a=a.substring(b[0].length),b[0].replace(y,c),f=!1);f&&(b=a.indexOf("<"),f=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),d.chars&&d.chars(p(f)))}if(a==l)throw J("badparse",a);l=a}k()}function p(a){q.innerHTML=a.replace(/</g,"<");return q.innerText||q.textContent||""}function z(a){return a.replace(/&/g,"&").replace(K,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"<").replace(/>/g,">")}function A(a){var d=
|
b)),a=a.substring(b+3),l=!1);else if(z.test(a)){if(b=a.match(z))a=a.replace(b[0],""),l=!1}else if(K.test(a)){if(b=a.match(A))a=a.substring(b[0].length),b[0].replace(A,e),l=!1}else L.test(a)&&((b=a.match(B))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(B,c)),l=!1):(h+="<",a=a.substring(1)));l&&(b=a.indexOf("<"),h+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),d.chars&&d.chars(s(h)))}if(a==n)throw M("badparse",a);n=a}e()}function s(a){if(!a)return"";var d=N.exec(a);a=d[1];var c=d[3];if(d=d[2])p.innerHTML=
|
||||||
!1,c=g.bind(a,a.push);return{start:function(a,b,f){a=g.lowercase(a);!d&&v[a]&&(d=a);d||!0!==B[a]||(c("<"),c(a),g.forEach(b,function(a,b){var d=g.lowercase(b);!0!==L[d]||!0===C[d]&&!a.match(M)||(c(" "),c(b),c('="'),c(z(a)),c('"'))}),c(f?"/>":">"))},end:function(a){a=g.lowercase(a);d||!0!==B[a]||(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(z(a))}}}var J=g.$$minErr("$sanitize"),y=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,x=/^<\s*\/\s*([\w:-]+)[^>]*>/,
|
d.replace(/</g,"<"),d="textContent"in p?p.textContent:p.innerText;return a+d+c}function C(a){return a.replace(/&/g,"&").replace(O,function(a){var c=a.charCodeAt(0);a=a.charCodeAt(1);return"&#"+(1024*(c-55296)+(a-56320)+65536)+";"}).replace(P,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"<").replace(/>/g,">")}function t(a,d){var c=!1,e=g.bind(a,a.push);return{start:function(a,l,f){a=g.lowercase(a);!c&&y[a]&&(c=a);c||!0!==D[a]||(e("<"),e(a),g.forEach(l,function(c,f){var k=
|
||||||
E=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,I=/^</,H=/^<\s*\//,F=/\x3c!--(.*?)--\x3e/g,w=/<!DOCTYPE([^>]*?)>/i,G=/<!\[CDATA\[(.*?)]]\x3e/g,M=/^((ftp|https?):\/\/|mailto:|tel:|#)/i,K=/([^\#-~| |!])/g,u=h("area,br,col,hr,img,wbr");m=h("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");n=h("rp,rt");var t=g.extend({},n,m),r=g.extend({},m,h("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),
|
g.lowercase(f),l="img"===a&&"src"===k||"background"===k;!0!==Q[k]||!0===E[k]&&!d(c,l)||(e(" "),e(f),e('="'),e(C(c)),e('"'))}),e(f?"/>":">"))},end:function(a){a=g.lowercase(a);c||!0!==D[a]||(e("</"),e(a),e(">"));a==c&&(c=!1)},chars:function(a){c||e(C(a))}}}var M=g.$$minErr("$sanitize"),B=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,A=/^<\/\s*([\w:-]+)[^>]*>/,H=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,L=/^</,
|
||||||
s=g.extend({},n,h("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),v=h("script,style"),B=g.extend({},u,r,s,t),C=h("background,cite,href,longdesc,src,usemap"),L=g.extend({},C,h("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),
|
K=/^<\//,I=/\x3c!--(.*?)--\x3e/g,z=/<!DOCTYPE([^>]*?)>/i,J=/<!\[CDATA\[(.*?)]]\x3e/g,O=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,P=/([^\#-~| |!])/g,x=m("area,br,col,hr,img,wbr");q=m("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");r=m("rp,rt");var w=g.extend({},r,q),u=g.extend({},q,m("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),v=g.extend({},r,m("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),
|
||||||
q=document.createElement("pre");g.module("ngSanitize",[]).value("$sanitize",function(a){var d=[];D(a,A(d));return d.join("")});g.module("ngSanitize").filter("linky",function(){var a=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,d=/^mailto:/;return function(c,k){if(!c)return c;var b,f=c,e=[],l=A(e),h,m,n={};g.isDefined(k)&&(n.target=k);for(;b=f.match(a);)h=b[0],b[2]==b[3]&&(h="mailto:"+h),m=b.index,l.chars(f.substr(0,m)),n.href=h,l.start("a",n),l.chars(b[0].replace(d,"")),l.end("a"),
|
y=m("script,style"),D=g.extend({},x,u,v,w),E=m("background,cite,href,longdesc,src,usemap"),Q=g.extend({},E,m("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,target,title,type,valign,value,vspace,width")),p=document.createElement("pre"),N=/^(\s*)([\s\S]*?)(\s*)$/;g.module("ngSanitize",[]).provider("$sanitize",
|
||||||
f=f.substring(m+b[0].length);l.chars(f);return e.join("")}})})(window,window.angular);
|
function(){this.$get=["$$sanitizeUri",function(a){return function(d){var c=[];G(d,t(c,function(c,b){return!/^unsafe/.test(a(c,b))}));return c.join("")}}]});g.module("ngSanitize").filter("linky",["$sanitize",function(a){var d=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"]/,c=/^mailto:/;return function(e,b){function l(a){a&&k.push(F(a))}function f(a,c){k.push("<a ");g.isDefined(b)&&(k.push('target="'),k.push(b),k.push('" '));k.push('href="');k.push(a);k.push('">');l(c);k.push("</a>")}
|
||||||
|
if(!e)return e;for(var n,h=e,k=[],m,p;n=h.match(d);)m=n[0],n[2]==n[3]&&(m="mailto:"+m),p=n.index,l(h.substr(0,p)),f(m,n[0].replace(c,"")),h=h.substring(p+n[0].length);l(h);return a(k.join(""))}}])})(window,window.angular);
|
||||||
//# sourceMappingURL=angular-sanitize.min.js.map
|
//# sourceMappingURL=angular-sanitize.min.js.map
|
||||||
|
|
7909
webclient/js/angular.js
vendored
7909
webclient/js/angular.js
vendored
File diff suppressed because it is too large
Load diff
429
webclient/js/angular.min.js
vendored
429
webclient/js/angular.min.js
vendored
|
@ -1,200 +1,237 @@
|
||||||
/*
|
/*
|
||||||
AngularJS v1.2.0
|
AngularJS v1.3.0-rc.1
|
||||||
(c) 2010-2012 Google, Inc. http://angularjs.org
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||||
License: MIT
|
License: MIT
|
||||||
*/
|
*/
|
||||||
(function(W,O,s){'use strict';function L(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/undefined/"+(b?b+"/":"")+a;for(c=1;c<arguments.length;c++)a=a+(1==c?"?":"&")+"p"+(c-1)+"="+encodeURIComponent("function"==typeof arguments[c]?arguments[c].toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof arguments[c]?"undefined":"string"!=typeof arguments[c]?JSON.stringify(arguments[c]):arguments[c]);return Error(a)}}function pb(b){if(null==b||ya(b))return!1;
|
(function(t,Y,s){'use strict';function K(b){return function(){var a=arguments[0],c;c="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.3.0-rc.1/"+(b?b+"/":"")+a;for(a=1;a<arguments.length;a++){c=c+(1==a?"?":"&")+"p"+(a-1)+"=";var d=encodeURIComponent,e;e=arguments[a];e="function"==typeof e?e.toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof e?"undefined":"string"!=typeof e?JSON.stringify(e):e;c+=d(e)}return Error(c)}}function Na(b){if(null==b||Oa(b))return!1;var a=b.length;return 1===b.nodeType&&
|
||||||
var a=b.length;return 1===b.nodeType&&a?!0:D(b)||J(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function q(b,a,c){var d;if(b)if(B(b))for(d in b)"prototype"!=d&&("length"!=d&&"name"!=d&&b.hasOwnProperty(d))&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==q)b.forEach(a,c);else if(pb(b))for(d=0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function Nb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function Jc(b,a,c){for(var d=
|
a?!0:C(b)||L(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function r(b,a,c){var d,e;if(b)if(D(b))for(d in b)"prototype"==d||"length"==d||"name"==d||b.hasOwnProperty&&!b.hasOwnProperty(d)||a.call(c,b[d],d,b);else if(L(b)||Na(b)){var f="object"!==typeof b;d=0;for(e=b.length;d<e;d++)(f||d in b)&&a.call(c,b[d],d,b)}else if(b.forEach&&b.forEach!==r)b.forEach(a,c,b);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d,b);return b}function Zb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}
|
||||||
Nb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function Ob(b){return function(a,c){b(c,a)}}function Za(){for(var b=ia.length,a;b;){b--;a=ia[b].charCodeAt(0);if(57==a)return ia[b]="A",ia.join("");if(90==a)ia[b]="0";else return ia[b]=String.fromCharCode(a+1),ia.join("")}ia.unshift("0");return ia.join("")}function Pb(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function u(b){var a=b.$$hashKey;q(arguments,function(a){a!==b&&q(a,function(a,c){b[c]=a})});Pb(b,a);return b}function U(b){return parseInt(b,
|
function od(b,a,c){for(var d=Zb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function $b(b){return function(a,c){b(c,a)}}function pd(){return++bb}function ac(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function E(b){for(var a=b.$$hashKey,c=1,d=arguments.length;c<d;c++){var e=arguments[c];if(e)for(var f=Object.keys(e),g=0,h=f.length;g<h;g++){var m=f[g];b[m]=e[m]}}ac(b,a);return b}function U(b){return parseInt(b,10)}function bc(b,a){return E(new (E(function(){},{prototype:b})),a)}function w(){}
|
||||||
10)}function Qb(b,a){return u(new (u(function(){},{prototype:b})),a)}function t(){}function za(b){return b}function aa(b){return function(){return b}}function x(b){return"undefined"==typeof b}function z(b){return"undefined"!=typeof b}function T(b){return null!=b&&"object"==typeof b}function D(b){return"string"==typeof b}function qb(b){return"number"==typeof b}function Ja(b){return"[object Date]"==Ka.apply(b)}function J(b){return"[object Array]"==Ka.apply(b)}function B(b){return"function"==typeof b}
|
function Pa(b){return b}function da(b){return function(){return b}}function F(b){return"undefined"===typeof b}function B(b){return"undefined"!==typeof b}function S(b){return null!==b&&"object"===typeof b}function C(b){return"string"===typeof b}function ea(b){return"number"===typeof b}function fa(b){return"[object Date]"===Ga.call(b)}function D(b){return"function"===typeof b}function cb(b){return"[object RegExp]"===Ga.call(b)}function Oa(b){return b&&b.window===b}function Qa(b){return b&&b.$evalAsync&&
|
||||||
function $a(b){return"[object RegExp]"==Ka.apply(b)}function ya(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function Kc(b){return b&&(b.nodeName||b.on&&b.find)}function Lc(b,a,c){var d=[];q(b,function(b,f,g){d.push(a.call(c,b,f,g))});return d}function ab(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function La(b,a){var c=ab(b,a);0<=c&&b.splice(c,1);return a}function da(b,a){if(ya(b)||b&&b.$evalAsync&&b.$watch)throw Ma("cpws");if(a){if(b===
|
b.$watch}function qd(b){return!(!b||!(b.nodeName||b.prop&&b.attr&&b.find))}function rd(b){var a={};b=b.split(",");var c;for(c=0;c<b.length;c++)a[b[c]]=!0;return a}function pa(b){return P(b.nodeName||b[0].nodeName)}function sd(b,a,c){var d=[];r(b,function(b,f,g){d.push(a.call(c,b,f,g))});return d}function Ra(b,a){var c=b.indexOf(a);0<=c&&b.splice(c,1);return a}function Ha(b,a,c,d){if(Oa(b)||Qa(b))throw Sa("cpws");if(a){if(b===a)throw Sa("cpi");c=c||[];d=d||[];if(S(b)){var e=c.indexOf(b);if(-1!==e)return d[e];
|
||||||
a)throw Ma("cpi");if(J(b))for(var c=a.length=0;c<b.length;c++)a.push(da(b[c]));else{c=a.$$hashKey;q(a,function(b,c){delete a[c]});for(var d in b)a[d]=da(b[d]);Pb(a,c)}}else(a=b)&&(J(b)?a=da(b,[]):Ja(b)?a=new Date(b.getTime()):$a(b)?a=RegExp(b.source):T(b)&&(a=da(b,{})));return a}function Mc(b,a){a=a||{};for(var c in b)b.hasOwnProperty(c)&&"$$"!==c.substr(0,2)&&(a[c]=b[c]);return a}function Aa(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&
|
c.push(b);d.push(a)}if(L(b))for(var f=a.length=0;f<b.length;f++)e=Ha(b[f],null,c,d),S(b[f])&&(c.push(b[f]),d.push(e)),a.push(e);else{var g=a.$$hashKey;L(a)?a.length=0:r(a,function(c,b){delete a[b]});for(f in b)b.hasOwnProperty(f)&&(e=Ha(b[f],null,c,d),S(b[f])&&(c.push(b[f]),d.push(e)),a[f]=e);ac(a,g)}}else if(a=b)L(b)?a=Ha(b,[],c,d):fa(b)?a=new Date(b.getTime()):cb(b)?(a=new RegExp(b.source,b.toString().match(/[^\/]*$/)[0]),a.lastIndex=b.lastIndex):S(b)&&(e=Object.create(Object.getPrototypeOf(b)),
|
||||||
"object"==c)if(J(b)){if(!J(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!Aa(b[d],a[d]))return!1;return!0}}else{if(Ja(b))return Ja(a)&&b.getTime()==a.getTime();if($a(b)&&$a(a))return b.toString()==a.toString();if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||ya(b)||ya(a)||J(a))return!1;c={};for(d in b)if("$"!==d.charAt(0)&&!B(b[d])){if(!Aa(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==s&&!B(a[d]))return!1;return!0}return!1}function Rb(){return O.securityPolicy&&
|
a=Ha(b,e,c,d));return a}function qa(b,a){if(L(b)){a=a||[];for(var c=0,d=b.length;c<d;c++)a[c]=b[c]}else if(S(b))for(c in a=a||{},b)if("$"!==c.charAt(0)||"$"!==c.charAt(1))a[c]=b[c];return a||b}function ra(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&"object"==c)if(L(b)){if(!L(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ra(b[d],a[d]))return!1;return!0}}else{if(fa(b))return fa(a)?ra(b.getTime(),a.getTime()):!1;if(cb(b)&&
|
||||||
O.securityPolicy.isActive||O.querySelector&&!(!O.querySelector("[ng-csp]")&&!O.querySelector("[data-ng-csp]"))}function rb(b,a){var c=2<arguments.length?ta.call(arguments,2):[];return!B(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,c.concat(ta.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function Nc(b,a){var c=a;"string"===typeof b&&"$"===b.charAt(0)?c=s:ya(a)?c="$WINDOW":a&&O===a?c="$DOCUMENT":a&&(a.$evalAsync&&
|
cb(a))return b.toString()==a.toString();if(Qa(b)||Qa(a)||Oa(b)||Oa(a)||L(a))return!1;c={};for(d in b)if("$"!==d.charAt(0)&&!D(b[d])){if(!ra(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==s&&!D(a[d]))return!1;return!0}return!1}function db(b,a,c){return b.concat(Ta.call(a,c))}function cc(b,a){var c=2<arguments.length?Ta.call(arguments,2):[];return!D(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,c.concat(Ta.call(arguments,0))):
|
||||||
a.$watch)&&(c="$SCOPE");return c}function ma(b,a){return"undefined"===typeof b?s:JSON.stringify(b,Nc,a?" ":null)}function Sb(b){return D(b)?JSON.parse(b):b}function Na(b){b&&0!==b.length?(b=w(""+b),b=!("f"==b||"0"==b||"false"==b||"no"==b||"n"==b||"[]"==b)):b=!1;return b}function ea(b){b=y(b).clone();try{b.html("")}catch(a){}var c=y("<div>").append(b).html();try{return 3===b[0].nodeType?w(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+w(b)})}catch(d){return w(c)}}function Tb(b){try{return decodeURIComponent(b)}catch(a){}}
|
a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function td(b,a){var c=a;"string"===typeof b&&"$"===b.charAt(0)&&"$"===b.charAt(1)?c=s:Oa(a)?c="$WINDOW":a&&Y===a?c="$DOCUMENT":Qa(a)&&(c="$SCOPE");return c}function sa(b,a){return"undefined"===typeof b?s:JSON.stringify(b,td,a?" ":null)}function dc(b){return C(b)?JSON.parse(b):b}function ta(b){b=G(b).clone();try{b.empty()}catch(a){}var c=G("<div>").append(b).html();try{return 3===b[0].nodeType?P(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,
|
||||||
function Ub(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.split("="),d=Tb(c[0]),z(d)&&(b=z(c[1])?Tb(c[1]):!0,a[d]?J(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Vb(b){var a=[];q(b,function(b,d){J(b)?q(b,function(b){a.push(ua(d,!0)+(!0===b?"":"="+ua(b,!0)))}):a.push(ua(d,!0)+(!0===b?"":"="+ua(b,!0)))});return a.length?a.join("&"):""}function sb(b){return ua(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function ua(b,a){return encodeURIComponent(b).replace(/%40/gi,
|
function(a,c){return"<"+P(c)})}catch(d){return P(c)}}function ec(b){try{return decodeURIComponent(b)}catch(a){}}function fc(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=ec(c[0]),B(d)&&(b=B(c[1])?ec(c[1]):!0,Ab.call(a,d)?L(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Bb(b){var a=[];r(b,function(b,d){L(b)?r(b,function(b){a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))}):a.push(Da(d,!0)+(!0===b?"":"="+Da(b,!0)))});return a.length?a.join("&"):""}
|
||||||
"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Oc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;q(g,function(a){g[a]=!0;c(O.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,f=
|
function eb(b){return Da(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Da(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,a?"%20":"+")}function ud(b,a){var c,d,e=fb.length;b=G(b);for(d=0;d<e;++d)if(c=fb[d]+a,C(c=b.attr(c)))return c;return null}function vd(b,a){var c,d,e={};r(fb,function(a){a+="app";!c&&b.hasAttribute&&b.hasAttribute(a)&&(c=b,d=b.getAttribute(a))});
|
||||||
(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function Wb(b,a){var c=function(){b=y(b);if(b.injector()){var c=b[0]===O?"document":ea(b);throw Ma("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=Xb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;
|
r(fb,function(a){a+="app";var e;!c&&(e=b.querySelector("["+a.replace(":","\\:")+"]"))&&(c=e,d=e.getAttribute(a))});c&&(e.strictDi=null!==ud(c,"strict-di"),a(c,d?[d]:[],e))}function gc(b,a,c){S(c)||(c={});c=E({strictDi:!1},c);var d=function(){b=G(b);if(b.injector()){var d=b[0]===Y?"document":ta(b);throw Sa("btstrpd",d.replace(/</,"<").replace(/>/,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);c.debugInfoEnabled&&a.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);
|
||||||
if(W&&!d.test(W.name))return c();W.name=W.name.replace(d,"");bb.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function cb(b,a){a=a||"_";return b.replace(Pc,function(b,d){return(d?a:"")+b.toLowerCase()})}function tb(b,a,c){if(!b)throw Ma("areq",a||"?",c||"required");return b}function Oa(b,a,c){c&&J(b)&&(b=b[b.length-1]);tb(B(b),a,"not a function, got "+(b&&"object"==typeof b?b.constructor.name||"Object":typeof b));return b}function na(b,a){if("hasOwnProperty"===b)throw Ma("badname",
|
a.unshift("ng");d=Cb(a,c.strictDi);d.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return d},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;t&&e.test(t.name)&&(c.debugInfoEnabled=!0,t.name=t.name.replace(e,""));if(t&&!f.test(t.name))return d();t.name=t.name.replace(f,"");Ea.resumeBootstrap=function(b){r(b,function(b){a.push(b)});d()}}function wd(){t.name="NG_ENABLE_DEBUG_INFO!"+t.name;t.location.reload()}function xd(b){return Ea.element(b).injector().get("$$testability")}
|
||||||
a);}function ub(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&B(b)?rb(e,b):b}function vb(b){if(b.startNode===b.endNode)return y(b.startNode);var a=b.startNode,c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b.endNode);return y(c)}function Qc(b){function a(a,b,c){return a[b]||(a[b]=c())}var c=L("$injector");return a(a(b,"angular",Object),"module",function(){var b={};return function(e,f,g){na(e,"module");f&&b.hasOwnProperty(e)&&(b[e]=
|
function Db(b,a){a=a||"_";return b.replace(yd,function(b,d){return(d?a:"")+b.toLowerCase()})}function zd(){var b;hc||((la=t.jQuery)&&la.fn.on?(G=la,E(la.fn,{scope:Ia.scope,isolateScope:Ia.isolateScope,controller:Ia.controller,injector:Ia.injector,inheritedData:Ia.inheritedData}),b=la.cleanData,la.cleanData=function(a){var c;if(Eb)Eb=!1;else for(var d=0,e;null!=(e=a[d]);d++)(c=la._data(e,"events"))&&c.$destroy&&la(e).triggerHandler("$destroy");b(a)}):G=V,Ea.element=G,hc=!0)}function Fb(b,a,c){if(!b)throw Sa("areq",
|
||||||
null);return a(b,e,function(){function a(c,d,e){return function(){b[e||"push"]([c,d,arguments]);return n}}if(!f)throw c("nomod",e);var b=[],d=[],l=a("$injector","invoke"),n={_invokeQueue:b,_runBlocks:d,requires:f,name:e,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animateProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider",
|
a||"?",c||"required");return b}function gb(b,a,c){c&&L(b)&&(b=b[b.length-1]);Fb(D(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Ja(b,a){if("hasOwnProperty"===b)throw Sa("badname",a);}function ic(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&D(b)?cc(e,b):b}function hb(b){var a=b[0];b=b[b.length-1];var c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b);return G(c)}function Ad(b){function a(a,
|
||||||
"register"),directive:a("$compileProvider","directive"),config:l,run:function(a){d.push(a);return this}};g&&l(g);return n})}})}function Pa(b){return b.replace(Rc,function(a,b,d,e){return e?d.toUpperCase():d}).replace(Sc,"Moz$1")}function wb(b,a,c,d){function e(b){var e=c&&b?[this.filter(b)]:[this],m=a,k,l,n,r,p,C;if(!d||null!=b)for(;e.length;)for(k=e.shift(),l=0,n=k.length;l<n;l++)for(r=y(k[l]),m?r.triggerHandler("$destroy"):m=!m,p=0,r=(C=r.children()).length;p<r;p++)e.push(Ba(C[p]));return f.apply(this,
|
b,c){return a[b]||(a[b]=c())}var c=K("$injector"),d=K("ng");b=a(b,"angular",Object);b.$$minErr=b.$$minErr||K;return a(b,"module",function(){var b={};return function(f,g,h){if("hasOwnProperty"===f)throw d("badname","module");g&&b.hasOwnProperty(f)&&(b[f]=null);return a(b,f,function(){function a(c,d,e,f){f||(f=b);return function(){f[e||"push"]([c,d,arguments]);return q}}if(!g)throw c("nomod",f);var b=[],d=[],e=[],l=a("$injector","invoke","push",d),q={_invokeQueue:b,_configBlocks:d,_runBlocks:e,requires:g,
|
||||||
arguments)}var f=Ba.fn[b],f=f.$original||f;e.$original=f;Ba.fn[b]=e}function Q(b){if(b instanceof Q)return b;if(!(this instanceof Q)){if(D(b)&&"<"!=b.charAt(0))throw xb("nosel");return new Q(b)}if(D(b)){var a=O.createElement("div");a.innerHTML="<div> </div>"+b;a.removeChild(a.firstChild);yb(this,a.childNodes);y(O.createDocumentFragment()).append(this)}else yb(this,b)}function zb(b){return b.cloneNode(!0)}function Qa(b){Yb(b);var a=0;for(b=b.childNodes||[];a<b.length;a++)Qa(b[a])}function Zb(b,
|
name:f,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animateProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:l,run:function(a){e.push(a);return this}};h&&l(h);return q})}})}function Bd(b){E(b,{bootstrap:gc,copy:Ha,extend:E,equals:ra,element:G,forEach:r,
|
||||||
a,c,d){if(z(d))throw xb("offargs");var e=ja(b,"events");ja(b,"handle")&&(x(a)?q(e,function(a,c){Ab(b,c,a);delete e[c]}):q(a.split(" "),function(a){x(c)?(Ab(b,a,e[a]),delete e[a]):La(e[a]||[],c)}))}function Yb(b,a){var c=b[db],d=Ra[c];d&&(a?delete Ra[c].data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),Zb(b)),delete Ra[c],b[db]=s))}function ja(b,a,c){var d=b[db],d=Ra[d||-1];if(z(c))d||(b[db]=d=++Tc,d=Ra[d]={}),d[a]=c;else return d&&d[a]}function $b(b,a,c){var d=ja(b,"data"),e=z(c),f=!e&&
|
injector:Cb,noop:w,bind:cc,toJson:sa,fromJson:dc,identity:Pa,isUndefined:F,isDefined:B,isString:C,isFunction:D,isObject:S,isNumber:ea,isElement:qd,isArray:L,version:Cd,isDate:fa,lowercase:P,uppercase:ib,callbacks:{counter:0},getTestability:xd,$$minErr:K,$$csp:Ua,reloadWithDebugInfo:wd,$$hasClass:jb});Va=Ad(t);try{Va("ngLocale")}catch(a){Va("ngLocale",[]).provider("$locale",Dd)}Va("ng",["ngLocale"],["$provide",function(a){a.provider({$$sanitizeUri:Ed});a.provider("$compile",jc).directive({a:Fd,input:kc,
|
||||||
z(a),g=f&&!T(a);d||g||ja(b,"data",d={});if(e)d[a]=c;else if(f){if(g)return d&&d[a];u(d,a)}else return d}function Bb(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function Cb(b,a){a&&b.setAttribute&&q(a.split(" "),function(a){b.setAttribute("class",Y((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").replace(" "+Y(a)+" "," ")))})}function Db(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g,
|
textarea:kc,form:Gd,script:Hd,select:Id,style:Jd,option:Kd,ngBind:Ld,ngBindHtml:Md,ngBindTemplate:Nd,ngClass:Od,ngClassEven:Pd,ngClassOdd:Qd,ngCloak:Rd,ngController:Sd,ngForm:Td,ngHide:Ud,ngIf:Vd,ngInclude:Wd,ngInit:Xd,ngNonBindable:Yd,ngPluralize:Zd,ngRepeat:$d,ngShow:ae,ngStyle:be,ngSwitch:ce,ngSwitchWhen:de,ngSwitchDefault:ee,ngOptions:fe,ngTransclude:ge,ngModel:he,ngList:ie,ngChange:je,pattern:lc,ngPattern:lc,required:mc,ngRequired:mc,minlength:nc,ngMinlength:nc,maxlength:oc,ngMaxlength:oc,ngValue:ke,
|
||||||
" ");q(a.split(" "),function(a){a=Y(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",Y(c))}}function yb(b,a){if(a){a=a.nodeName||!z(a.length)||ya(a)?[a]:a;for(var c=0;c<a.length;c++)b.push(a[c])}}function ac(b,a){return eb(b,"$"+(a||"ngController")+"Controller")}function eb(b,a,c){b=y(b);9==b[0].nodeType&&(b=b.find("html"));for(a=J(a)?a:[a];b.length;){for(var d=0,e=a.length;d<e;d++)if((c=b.data(a[d]))!==s)return c;b=b.parent()}}function bc(b,a){var c=fb[a.toLowerCase()];return c&&
|
ngModelOptions:le}).directive({ngInclude:me}).directive(kb).directive(pc);a.provider({$anchorScroll:ne,$animate:oe,$browser:pe,$cacheFactory:qe,$controller:re,$document:se,$exceptionHandler:te,$filter:qc,$interpolate:ue,$interval:ve,$http:we,$httpBackend:xe,$location:ye,$log:ze,$parse:Ae,$rootScope:Be,$q:Ce,$$q:De,$sce:Ee,$sceDelegate:Fe,$sniffer:Ge,$templateCache:He,$templateRequest:Ie,$$testability:Je,$timeout:Ke,$window:Le,$$rAF:Me,$$asyncCallback:Ne})}])}function Wa(b){return b.replace(Oe,function(a,
|
||||||
cc[b.nodeName]&&c}function Uc(b,a){var c=function(c,e){c.preventDefault||(c.preventDefault=function(){c.returnValue=!1});c.stopPropagation||(c.stopPropagation=function(){c.cancelBubble=!0});c.target||(c.target=c.srcElement||O);if(x(c.defaultPrevented)){var f=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;f.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented||!1===c.returnValue};q(a[e||c.type],function(a){a.call(b,c)});8>=P?(c.preventDefault=
|
b,d,e){return e?d.toUpperCase():d}).replace(Pe,"Moz$1")}function rc(b){b=b.nodeType;return 1===b||!b||9===b}function sc(b,a){var c,d,e=a.createDocumentFragment(),f=[];if(Gb.test(b)){c=c||e.appendChild(a.createElement("div"));d=(Qe.exec(b)||["",""])[1].toLowerCase();d=ia[d]||ia._default;c.innerHTML=d[1]+b.replace(Re,"<$1></$2>")+d[2];for(d=d[0];d--;)c=c.lastChild;f=db(f,c.childNodes);c=e.firstChild;c.textContent=""}else f.push(a.createTextNode(b));e.textContent="";e.innerHTML="";r(f,function(a){e.appendChild(a)});
|
||||||
null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ca(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=Za()):c=b;return a+":"+c}function Sa(b){q(b,this.put,this)}function dc(b){var a,c;"function"==typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(Vc,""),c=c.match(Wc),q(c[1].split(Xc),function(b){b.replace(Yc,function(b,
|
return e}function V(b){if(b instanceof V)return b;var a;C(b)&&(b=ba(b),a=!0);if(!(this instanceof V)){if(a&&"<"!=b.charAt(0))throw Hb("nosel");return new V(b)}if(a){a=Y;var c;b=(c=Se.exec(b))?[a.createElement(c[1])]:(c=sc(b,a))?c.childNodes:[]}tc(this,b)}function Ib(b){return b.cloneNode(!0)}function lb(b,a){a||mb(b);if(b.querySelectorAll)for(var c=b.querySelectorAll("*"),d=0,e=c.length;d<e;d++)mb(c[d])}function uc(b,a,c,d){if(B(d))throw Hb("offargs");var e=(d=nb(b))&&d.events;if(d&&d.handle)if(a)r(a.split(" "),
|
||||||
c,d){a.push(d)})})),b.$inject=a):J(b)?(c=b.length-1,Oa(b[c],"fn"),a=b.slice(0,c)):Oa(b,"fn",!0);return a}function Xb(b){function a(a){return function(b,c){if(T(b))q(b,Ob(a));else return a(b,c)}}function c(a,b){na(a,"service");if(B(b)||J(b))b=n.instantiate(b);if(!b.$get)throw Ta("pget",a);return l[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,h;q(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(D(a))for(c=Ua(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,
|
function(a){F(c)?(b.removeEventListener(a,e[a],!1),delete e[a]):Ra(e[a]||[],c)});else for(a in e)"$destroy"!==a&&b.removeEventListener(a,e[a],!1),delete e[a]}function mb(b,a){var c=b.ng339,d=c&&ob[c];d&&(a?delete d.data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),uc(b)),delete ob[c],b.ng339=s))}function nb(b,a){var c=b.ng339,c=c&&ob[c];a&&!c&&(b.ng339=c=++Te,c=ob[c]={events:{},data:{},handle:s});return c}function Jb(b,a,c){if(rc(b)){var d=B(c),e=!d&&a&&!S(a),f=!a;b=(b=nb(b,!e))&&b.data;
|
||||||
f=0,h=d.length;f<h;f++){var g=d[f],m=n.get(g[0]);m[g[1]].apply(m,g[2])}else B(a)?b.push(n.invoke(a)):J(a)?b.push(n.invoke(a)):Oa(a,"module")}catch(l){throw J(a)&&(a=a[a.length-1]),l.message&&(l.stack&&-1==l.stack.indexOf(l.message))&&(l=l.message+"\n"+l.stack),Ta("modulerr",a,l.stack||l.message||l);}}});return b}function f(a,b){function c(d){if(a.hasOwnProperty(d)){if(a[d]===g)throw Ta("cdep",m.join(" <- "));return a[d]}try{return m.unshift(d),a[d]=g,a[d]=b(d)}finally{m.shift()}}function d(a,b,e){var f=
|
if(d)b[a]=c;else{if(f)return b;if(e)return b&&b[a];E(b,a)}}}function jb(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function Kb(b,a){a&&b.setAttribute&&r(a.split(" "),function(a){b.setAttribute("class",ba((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").replace(" "+ba(a)+" "," ")))})}function Lb(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ");r(a.split(" "),function(a){a=
|
||||||
[],h=dc(a),g,k,m;k=0;for(g=h.length;k<g;k++){m=h[k];if("string"!==typeof m)throw Ta("itkn",m);f.push(e&&e.hasOwnProperty(m)?e[m]:c(m))}a.$inject||(a=a[g]);switch(b?-1:f.length){case 0:return a();case 1:return a(f[0]);case 2:return a(f[0],f[1]);case 3:return a(f[0],f[1],f[2]);case 4:return a(f[0],f[1],f[2],f[3]);case 5:return a(f[0],f[1],f[2],f[3],f[4]);case 6:return a(f[0],f[1],f[2],f[3],f[4],f[5]);case 7:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6]);case 8:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],
|
ba(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",ba(c))}}function tc(b,a){if(a)if(a.nodeType)b[b.length++]=a;else{var c=a.length;if("number"===typeof c&&a.window!==a){if(c)for(var d=0;d<c;d++)b[b.length++]=a[d]}else b[b.length++]=a}}function vc(b,a){return pb(b,"$"+(a||"ngController")+"Controller")}function pb(b,a,c){9==b.nodeType&&(b=b.documentElement);for(a=L(a)?a:[a];b;){for(var d=0,e=a.length;d<e;d++)if((c=G.data(b,a[d]))!==s)return c;b=b.parentNode||11===b.nodeType&&b.host}}
|
||||||
f[7]);case 9:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);case 10:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]);default:return a.apply(b,f)}}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(J(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return T(e)||B(e)?e:c},get:c,annotate:dc,has:function(b){return l.hasOwnProperty(b+h)||a.hasOwnProperty(b)}}}var g={},h="Provider",m=[],k=new Sa,l={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,
|
function wc(b){for(lb(b,!0);b.firstChild;)b.removeChild(b.firstChild)}function xc(b,a){a||lb(b);var c=b.parentNode;c&&c.removeChild(b)}function yc(b,a){var c=qb[a.toLowerCase()];return c&&zc[pa(b)]&&c}function Ue(b,a){var c=b.nodeName;return("INPUT"===c||"TEXTAREA"===c)&&Ac[a]}function Ve(b,a){var c=function(c,e){c.isDefaultPrevented=function(){return c.defaultPrevented};var f=a[e||c.type],g=f?f.length:0;if(g){1<g&&(f=qa(f));for(var h=0;h<g;h++)f[h].call(b,c)}};c.elem=b;return c}function Ka(b,a){var c=
|
||||||
["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,aa(b))}),constant:a(function(a,b){na(a,"constant");l[a]=b;r[a]=b}),decorator:function(a,b){var c=n.get(a+h),d=c.$get;c.$get=function(){var a=p.invoke(d,c);return p.invoke(b,null,{$delegate:a})}}}},n=l.$injector=f(l,function(){throw Ta("unpr",m.join(" <- "));}),r={},p=r.$injector=f(r,function(a){a=n.get(a+h);return p.invoke(a.$get,a)});q(e(b),function(a){p.invoke(a||t)});return p}function Zc(){var b=!0;this.disableAutoScrolling=
|
b&&b.$$hashKey;if(c)return"function"===typeof c&&(c=b.$$hashKey()),c;c=typeof b;return c="function"==c||"object"==c&&null!==b?b.$$hashKey=c+":"+(a||pd)():c+":"+b}function Xa(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function We(b){return(b=b.toString().replace(Bc,"").match(Cc))?"function("+(b[1]||"").replace(/[\s\r\n]+/," ")+")":"fn"}function Mb(b,a,c){var d;if("function"===typeof b){if(!(d=b.$inject)){d=[];if(b.length){if(a)throw C(c)&&c||(c=b.name||We(b)),La("strictdi",
|
||||||
function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;q(a,function(a){b||"a"!==w(a.nodeName)||(b=a)});return b}function f(){var b=c.hash(),d;b?(d=g.getElementById(b))?d.scrollIntoView():(d=e(g.getElementsByName(b)))?d.scrollIntoView():"top"===b&&a.scrollTo(0,0):a.scrollTo(0,0)}var g=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(f)});return f}]}function $c(b,a,c,d){function e(a){try{a.apply(null,ta.call(arguments,1))}finally{if(C--,
|
c);a=b.toString().replace(Bc,"");a=a.match(Cc);r(a[1].split(Xe),function(a){a.replace(Ye,function(a,b,c){d.push(c)})})}b.$inject=d}}else L(b)?(a=b.length-1,gb(b[a],"fn"),d=b.slice(0,a)):gb(b,"fn",!0);return d}function Cb(b,a){function c(a){return function(b,c){if(S(b))r(b,$b(a));else return a(b,c)}}function d(a,b){Ja(a,"service");if(D(b)||L(b))b=p.instantiate(b);if(!b.$get)throw La("pget",a);return n[a+"Provider"]=b}function e(a,b){return d(a,{$get:b})}function f(a){var b=[],c;r(a,function(a){function d(a){var b,
|
||||||
0===C)for(;H.length;)try{H.pop()()}catch(b){c.error(b)}}}function f(a,b){(function gb(){q(I,function(a){a()});A=b(gb,a)})()}function g(){v=null;S!=h.url()&&(S=h.url(),q(Z,function(a){a(h.url())}))}var h=this,m=a[0],k=b.location,l=b.history,n=b.setTimeout,r=b.clearTimeout,p={};h.isMock=!1;var C=0,H=[];h.$$completeOutstandingRequest=e;h.$$incOutstandingRequestCount=function(){C++};h.notifyWhenNoOutstandingRequests=function(a){q(I,function(a){a()});0===C?a():H.push(a)};var I=[],A;h.addPollFn=function(a){x(A)&&
|
c;b=0;for(c=a.length;b<c;b++){var e=a[b],f=p.get(e[0]);f[e[1]].apply(f,e[2])}}if(!k.get(a)){k.put(a,!0);try{C(a)?(c=Va(a),b=b.concat(f(c.requires)).concat(c._runBlocks),d(c._invokeQueue),d(c._configBlocks)):D(a)?b.push(p.invoke(a)):L(a)?b.push(p.invoke(a)):gb(a,"module")}catch(e){throw L(a)&&(a=a[a.length-1]),e.message&&e.stack&&-1==e.stack.indexOf(e.message)&&(e=e.message+"\n"+e.stack),La("modulerr",a,e.stack||e.message||e);}}});return b}function g(b,c){function d(a){if(b.hasOwnProperty(a)){if(b[a]===
|
||||||
f(100,n);I.push(a);return a};var S=k.href,G=a.find("base"),v=null;h.url=function(a,c){k!==b.location&&(k=b.location);if(a){if(S!=a)return S=a,d.history?c?l.replaceState(null,"",a):(l.pushState(null,"",a),G.attr("href",G.attr("href"))):(v=a,c?k.replace(a):k.href=a),h}else return v||k.href.replace(/%27/g,"'")};var Z=[],E=!1;h.onUrlChange=function(a){if(!E){if(d.history)y(b).on("popstate",g);if(d.hashchange)y(b).on("hashchange",g);else h.addPollFn(g);E=!0}Z.push(a);return a};h.baseHref=function(){var a=
|
h)throw La("cdep",a+" <- "+m.join(" <- "));return b[a]}try{return m.unshift(a),b[a]=h,b[a]=c(a)}catch(e){throw b[a]===h&&delete b[a],e;}finally{m.shift()}}function e(b,c,f,h){"string"===typeof f&&(h=f,f=null);var g=[];h=Mb(b,a,h);var k,m,l;m=0;for(k=h.length;m<k;m++){l=h[m];if("string"!==typeof l)throw La("itkn",l);g.push(f&&f.hasOwnProperty(l)?f[l]:d(l))}L(b)&&(b=b[k]);return b.apply(c,g)}return{invoke:e,instantiate:function(a,b,c){var d=function(){};d.prototype=(L(a)?a[a.length-1]:a).prototype;
|
||||||
G.attr("href");return a?a.replace(/^https?\:\/\/[^\/]*/,""):""};var oa={},$="",va=h.baseHref();h.cookies=function(a,b){var d,e,f,h;if(a)b===s?m.cookie=escape(a)+"=;path="+va+";expires=Thu, 01 Jan 1970 00:00:00 GMT":D(b)&&(d=(m.cookie=escape(a)+"="+escape(b)+";path="+va).length+1,4096<d&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"));else{if(m.cookie!==$)for($=m.cookie,d=$.split("; "),oa={},f=0;f<d.length;f++)e=d[f],h=e.indexOf("="),0<h&&(a=
|
d=new d;a=e(a,d,b,c);return S(a)||D(a)?a:d},get:d,annotate:Mb,has:function(a){return n.hasOwnProperty(a+"Provider")||b.hasOwnProperty(a)}}}a=!0===a;var h={},m=[],k=new Xa([],!0),n={$provide:{provider:c(d),factory:c(e),service:c(function(a,b){return e(a,["$injector",function(a){return a.instantiate(b)}])}),value:c(function(a,b){return e(a,da(b))}),constant:c(function(a,b){Ja(a,"constant");n[a]=b;l[a]=b}),decorator:function(a,b){var c=p.get(a+"Provider"),d=c.$get;c.$get=function(){var a=q.invoke(d,
|
||||||
unescape(e.substring(0,h)),oa[a]===s&&(oa[a]=unescape(e.substring(h+1))));return oa}};h.defer=function(a,b){var c;C++;c=n(function(){delete p[c];e(a)},b||0);p[c]=!0;return c};h.defer.cancel=function(a){return p[a]?(delete p[a],r(a),e(t),!0):!1}}function bd(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new $c(b,d,a,c)}]}function cd(){this.$get=function(){function b(b,d){function e(a){a!=n&&(r?r==a&&(r=a.n):r=a,f(a.n,a.p),f(a,n),n=a,n.n=null)}function f(a,b){a!=b&&(a&&
|
c);return q.invoke(b,null,{$delegate:a})}}}},p=n.$injector=g(n,function(){throw La("unpr",m.join(" <- "));}),l={},q=l.$injector=g(l,function(a){var b=p.get(a+"Provider");return q.invoke(b.$get,b,s,a)});r(f(b),function(a){q.invoke(a||w)});return q}function ne(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;r(a,function(a){b||"a"!==pa(a)||(b=a)});return b}function f(){var b=c.hash(),d;b?(d=g.getElementById(b))?
|
||||||
(a.p=b),b&&(b.n=a))}if(b in a)throw L("$cacheFactory")("iid",b);var g=0,h=u({},d,{id:b}),m={},k=d&&d.capacity||Number.MAX_VALUE,l={},n=null,r=null;return a[b]={put:function(a,b){var c=l[a]||(l[a]={key:a});e(c);if(!x(b))return a in m||g++,m[a]=b,g>k&&this.remove(r.key),b},get:function(a){var b=l[a];if(b)return e(b),m[a]},remove:function(a){var b=l[a];b&&(b==n&&(n=b.p),b==r&&(r=b.n),f(b.n,b.p),delete l[a],delete m[a],g--)},removeAll:function(){m={};g=0;l={};n=r=null},destroy:function(){l=h=m=null;delete a[b]},
|
d.scrollIntoView():(d=e(g.getElementsByName(b)))?d.scrollIntoView():"top"===b&&a.scrollTo(0,0):a.scrollTo(0,0)}var g=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(f)});return f}]}function Ne(){this.$get=["$$rAF","$timeout",function(b,a){return b.supported?function(a){return b(a)}:function(b){return a(b,0,!1)}}]}function Ze(b,a,c,d){function e(a){try{a.apply(null,Ta.call(arguments,1))}finally{if(A--,0===A)for(;u.length;)try{u.pop()()}catch(b){c.error(b)}}}function f(a,
|
||||||
info:function(){return u({},h,{size:g})}}}var a={};b.info=function(){var b={};q(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function dd(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function ec(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,f=/^\s*(https?|ftp|mailto|tel|file):/,g=/^\s*(https?|ftp|file):|data:image\//,h=/^(on[a-z]+|formaction)$/;this.directive=function k(d,e){na(d,"directive");
|
b){(function R(){r(x,function(a){a()});z=b(R,a)})()}function g(){y=null;T!=h.url()&&(T=h.url(),r(Q,function(a){a(h.url())}))}var h=this,m=a[0],k=b.location,n=b.history,p=b.setTimeout,l=b.clearTimeout,q={};h.isMock=!1;var A=0,u=[];h.$$completeOutstandingRequest=e;h.$$incOutstandingRequestCount=function(){A++};h.notifyWhenNoOutstandingRequests=function(a){r(x,function(a){a()});0===A?a():u.push(a)};var x=[],z;h.addPollFn=function(a){F(z)&&f(100,p);x.push(a);return a};var T=k.href,v=a.find("base"),y=
|
||||||
D(d)?(tb(e,"directiveFactory"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];q(a[d],function(a,f){try{var h=b.invoke(a);B(h)?h={compile:aa(h)}:!h.compile&&h.link&&(h.compile=aa(h.link));h.priority=h.priority||0;h.index=f;h.name=h.name||d;h.require=h.require||h.controller&&h.name;h.restrict=h.restrict||"A";e.push(h)}catch(g){c(g)}});return e}])),a[d].push(e)):q(d,Ob(k));return this};this.aHrefSanitizationWhitelist=function(a){return z(a)?(f=a,this):
|
null;h.url=function(a,c){k!==b.location&&(k=b.location);n!==b.history&&(n=b.history);if(a){if(T!=a)return T=a,d.history?c?n.replaceState(null,"",a):(n.pushState(null,"",a),v.attr("href",v.attr("href"))):(y=a,c?k.replace(a):k.href=a),h}else return y||k.href.replace(/%27/g,"'")};var Q=[],ca=!1;h.onUrlChange=function(a){if(!ca){if(d.history)G(b).on("popstate",g);if(d.hashchange)G(b).on("hashchange",g);else h.addPollFn(g);ca=!0}Q.push(a);return a};h.$$checkUrlChange=g;h.baseHref=function(){var a=v.attr("href");
|
||||||
f};this.imgSrcSanitizationWhitelist=function(a){return z(a)?(g=a,this):g};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document","$sce","$animate",function(b,l,n,r,p,C,H,I,A,S,G){function v(a,b,c,d,e){a instanceof y||(a=y(a));q(a,function(b,c){3==b.nodeType&&b.nodeValue.match(/\S+/)&&(a[c]=y(b).wrap("<span></span>").parent()[0])});var f=E(a,b,a,c,d,e);return function(b,c){tb(b,"scope");for(var d=c?Da.clone.call(a):a,e=0,h=
|
return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};var J={},N="",M=h.baseHref();h.cookies=function(a,b){var d,e,f,h;if(a)b===s?m.cookie=encodeURIComponent(a)+"=;path="+M+";expires=Thu, 01 Jan 1970 00:00:00 GMT":C(b)&&(d=(m.cookie=encodeURIComponent(a)+"="+encodeURIComponent(b)+";path="+M).length+1,4096<d&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"));else{if(m.cookie!==N)for(N=m.cookie,d=N.split("; "),J={},f=0;f<d.length;f++)e=d[f],h=e.indexOf("="),
|
||||||
d.length;e<h;e++){var g=d[e];1!=g.nodeType&&9!=g.nodeType||d.eq(e).data("$scope",b)}Z(d,"ng-scope");c&&c(d,b);f&&f(b,d,d);return d}}function Z(a,b){try{a.addClass(b)}catch(c){}}function E(a,b,c,d,e,f){function h(a,c,d,e){var f,k,l,n,p,r,C,X=[];p=0;for(r=c.length;p<r;p++)X.push(c[p]);C=p=0;for(r=g.length;p<r;C++)k=X[C],c=g[p++],f=g[p++],l=y(k),c?(c.scope?(n=a.$new(),l.data("$scope",n),Z(l,"ng-scope")):n=a,(l=c.transclude)||!e&&b?c(f,n,k,d,function(b){return function(c){var d=a.$new();d.$$transcluded=
|
0<h&&(a=decodeURIComponent(e.substring(0,h)),J[a]===s&&(J[a]=decodeURIComponent(e.substring(h+1))));return J}};h.defer=function(a,b){var c;A++;c=p(function(){delete q[c];e(a)},b||0);q[c]=!0;return c};h.defer.cancel=function(a){return q[a]?(delete q[a],l(a),e(w),!0):!1}}function pe(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new Ze(b,d,a,c)}]}function qe(){this.$get=function(){function b(b,d){function e(a){a!=p&&(l?l==a&&(l=a.n):l=a,f(a.n,a.p),f(a,p),p=a,p.n=null)}
|
||||||
!0;return b(d,c).on("$destroy",rb(d,d.$destroy))}}(l||b)):c(f,n,k,s,e)):f&&f(a,k.childNodes,s,e)}for(var g=[],k,l,n,p=0;p<a.length;p++)l=new R,k=oa(a[p],[],l,0===p?d:s,e),k=(f=k.length?M(k,a[p],l,b,c,null,[],[],f):null)&&f.terminal||!a[p].childNodes||!a[p].childNodes.length?null:E(a[p].childNodes,f?f.transclude:b),g.push(f),g.push(k),n=n||f||k,f=null;return n?h:null}function oa(a,b,c,f,h){var g=c.$attr,k;switch(a.nodeType){case 1:N(b,ka(Ea(a).toLowerCase()),"E",f,h);var l,n,p;k=a.attributes;for(var r=
|
function f(a,b){a!=b&&(a&&(a.p=b),b&&(b.n=a))}if(b in a)throw K("$cacheFactory")("iid",b);var g=0,h=E({},d,{id:b}),m={},k=d&&d.capacity||Number.MAX_VALUE,n={},p=null,l=null;return a[b]={put:function(a,b){if(k<Number.MAX_VALUE){var c=n[a]||(n[a]={key:a});e(c)}if(!F(b))return a in m||g++,m[a]=b,g>k&&this.remove(l.key),b},get:function(a){if(k<Number.MAX_VALUE){var b=n[a];if(!b)return;e(b)}return m[a]},remove:function(a){if(k<Number.MAX_VALUE){var b=n[a];if(!b)return;b==p&&(p=b.p);b==l&&(l=b.n);f(b.n,
|
||||||
0,C=k&&k.length;r<C;r++){var H=!1,v=!1;l=k[r];if(!P||8<=P||l.specified){n=l.name;p=ka(n);Fa.test(p)&&(n=cb(p.substr(6),"-"));var q=p.replace(/(Start|End)$/,"");p===q+"Start"&&(H=n,v=n.substr(0,n.length-5)+"end",n=n.substr(0,n.length-6));p=ka(n.toLowerCase());g[p]=n;c[p]=l=Y(P&&"href"==n?decodeURIComponent(a.getAttribute(n,2)):l.value);bc(a,p)&&(c[p]=!0);w(a,b,l,p);N(b,p,"A",f,h,H,v)}}a=a.className;if(D(a)&&""!==a)for(;k=e.exec(a);)p=ka(k[2]),N(b,p,"C",f,h)&&(c[p]=Y(k[3])),a=a.substr(k.index+k[0].length);
|
b.p);delete n[a]}delete m[a];g--},removeAll:function(){m={};g=0;n={};p=l=null},destroy:function(){n=h=m=null;delete a[b]},info:function(){return E({},h,{size:g})}}}var a={};b.info=function(){var b={};r(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function He(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function jc(b,a){var c={},d=/^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,e=/(([\d\w_\-]+)(?:\:([^;]+))?;?)/,f=rd("ngSrc,ngSrcset,src,srcset"),g=
|
||||||
break;case 3:t(b,a.nodeValue);break;case 8:try{if(k=d.exec(a.nodeValue))p=ka(k[1]),N(b,p,"M",f,h)&&(c[p]=Y(k[2]))}catch(S){}}b.sort(wa);return b}function $(a,b,c){var d=[],e=0;if(b&&a.hasAttribute&&a.hasAttribute(b)){do{if(!a)throw fa("uterdir",b,c);1==a.nodeType&&(a.hasAttribute(b)&&e++,a.hasAttribute(c)&&e--);d.push(a);a=a.nextSibling}while(0<e)}else d.push(a);return y(d)}function va(a,b,c){return function(d,e,f,h){e=$(e[0],b,c);return a(d,e,f,h)}}function M(a,b,c,d,e,f,h,k,g){function p(a,b,c,
|
/^(on[a-z]+|formaction)$/;this.directive=function k(a,d){Ja(a,"directive");C(a)?(Fb(d,"directiveFactory"),c.hasOwnProperty(a)||(c[a]=[],b.factory(a+"Directive",["$injector","$exceptionHandler",function(b,d){var e=[];r(c[a],function(c,f){try{var h=b.invoke(c);D(h)?h={compile:da(h)}:!h.compile&&h.link&&(h.compile=da(h.link));h.priority=h.priority||0;h.index=f;h.name=h.name||a;h.require=h.require||h.controller&&h.name;h.restrict=h.restrict||"EA";e.push(h)}catch(g){d(g)}});return e}])),c[a].push(d)):
|
||||||
d){if(a){c&&(a=va(a,c,d));a.require=F.require;if(G===F||F.$$isolateScope)a=Q(a,{isolateScope:!0});h.push(a)}if(b){c&&(b=va(b,c,d));b.require=F.require;if(G===F||F.$$isolateScope)b=Q(b,{isolateScope:!0});k.push(b)}}function r(a,b){var c,d="data",e=!1;if(D(a)){for(;"^"==(c=a.charAt(0))||"?"==c;)a=a.substr(1),"^"==c&&(d="inheritedData"),e=e||"?"==c;c=b[d]("$"+a+"Controller");8==b[0].nodeType&&b[0].$$controller&&(c=c||b[0].$$controller,b[0].$$controller=null);if(!c&&!e)throw fa("ctreq",a,ba);}else J(a)&&
|
r(a,$b(k));return this};this.aHrefSanitizationWhitelist=function(b){return B(b)?(a.aHrefSanitizationWhitelist(b),this):a.aHrefSanitizationWhitelist()};this.imgSrcSanitizationWhitelist=function(b){return B(b)?(a.imgSrcSanitizationWhitelist(b),this):a.imgSrcSanitizationWhitelist()};var h=!0;this.debugInfoEnabled=function(a){return B(a)?(h=a,this):h};this.$get=["$injector","$interpolate","$exceptionHandler","$templateRequest","$parse","$controller","$rootScope","$document","$sce","$animate","$$sanitizeUri",
|
||||||
(c=[],q(a,function(a){c.push(r(a,b))}));return c}function S(a,d,e,f,g){var p,X,v,E,I,K;p=b===e?c:Mc(c,new R(y(e),c.$attr));X=p.$$element;if(G){var va=/^\s*([@=&])(\??)\s*(\w*)\s*$/;f=y(e);K=d.$new(!0);N&&N===G.$$originalDirective?f.data("$isolateScope",K):f.data("$isolateScopeNoTemplate",K);Z(f,"ng-isolate-scope");q(G.scope,function(a,b){var c=a.match(va)||[],e=c[3]||b,f="?"==c[2],c=c[1],h,g,k;K.$$isolateBindings[b]=c+e;switch(c){case "@":p.$observe(e,function(a){K[b]=a});p.$$observers[e].$$scope=
|
function(a,b,p,l,q,A,u,x,z,T,v){function y(a,b){try{a.addClass(b)}catch(c){}}function Q(a,b,c,d,e){a instanceof G||(a=G(a));r(a,function(b,c){3==b.nodeType&&b.nodeValue.match(/\S+/)&&(a[c]=G(b).wrap("<span></span>").parent()[0])});var f=ca(a,b,a,c,d,e);Q.$$addScopeClass(a);var h=null,g=a,k;return function(b,c,d,e,l){Fb(b,"scope");h||(h=(l=l&&l[0])?"foreignobject"!==pa(l)&&l.toString().match(/SVG/)?"svg":"html":"html");"html"!==h&&a[0]!==k&&(g=G(Nb(h,G("<div>").append(a).html())));k=a[0];l=c?Ia.clone.call(g):
|
||||||
d;p[e]&&(K[b]=l(p[e])(d));break;case "=":if(f&&!p[e])break;g=C(p[e]);k=g.assign||function(){h=K[b]=g(d);throw fa("nonassign",p[e],G.name);};h=K[b]=g(d);K.$watch(function(){var a=g(d);a!==K[b]&&(a!==h?h=K[b]=a:k(d,a=h=K[b]));return a});break;case "&":g=C(p[e]);K[b]=function(a){return g(d,a)};break;default:throw fa("iscp",G.name,b,a);}})}A&&q(A,function(a){var b={$scope:a===G||a.$$isolateScope?K:d,$element:X,$attrs:p,$transclude:g},c;I=a.controller;"@"==I&&(I=p[a.name]);c=H(I,b);8==X[0].nodeType?X[0].$$controller=
|
g;if(d)for(var n in d)l.data("$"+n+"Controller",d[n].instance);Q.$$addScopeInfo(l,b);c&&c(l,b);f&&f(b,l,l,e);return l}}function ca(a,b,c,d,e,f){function h(a,c,d,e){var f,k,l,n,u,q,ua;if(p)for(ua=Array(c.length),n=0;n<g.length;n+=3)f=g[n],ua[f]=c[f];else ua=c;n=0;for(u=g.length;n<u;)k=ua[g[n++]],c=g[n++],f=g[n++],c?(c.scope?(l=a.$new(),Q.$$addScopeInfo(G(k),l)):l=a,q=c.transcludeOnThisElement?J(a,c.transclude,e,c.elementTranscludeOnThisElement):!c.templateOnThisElement&&e?e:!e&&b?J(a,b):null,c(f,l,
|
||||||
c:X.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});f=0;for(v=h.length;f<v;f++)try{E=h[f],E(E.isolateScope?K:d,X,p,E.require&&r(E.require,X))}catch(M){n(M,ea(X))}f=d;G&&(G.template||null===G.templateUrl)&&(f=K);a&&a(f,e.childNodes,s,g);for(f=k.length-1;0<=f;f--)try{E=k[f],E(E.isolateScope?K:d,X,p,E.require&&r(E.require,X))}catch($){n($,ea(X))}}g=g||{};var E=-Number.MAX_VALUE,I,A=g.controllerDirectives,G=g.newIsolateScopeDirective,N=g.templateDirective;g=g.transcludeDirective;
|
k,d,q)):f&&f(a,k.childNodes,s,e)}for(var g=[],k,l,n,u,p,q=0;q<a.length;q++){k=new Ob;l=N(a[q],[],k,0===q?d:s,e);(f=l.length?H(l,a[q],k,b,c,null,[],[],f):null)&&f.scope&&Q.$$addScopeClass(k.$$element);k=f&&f.terminal||!(n=a[q].childNodes)||!n.length?null:ca(n,f?(f.transcludeOnThisElement||!f.templateOnThisElement)&&f.transclude:b);if(f||k)g.push(q,f,k),u=!0,p=p||f;f=null}return u?h:null}function J(a,b,c,d){return function(e,f,h,g){var k=!1;e||(e=a.$new(),k=e.$$transcluded=!0);f=b(e,f,h,c,g);if(k&&
|
||||||
for(var M=c.$$element=y(b),F,ba,t,wa=d,x,ga=0,w=a.length;ga<w;ga++){F=a[ga];var u=F.$$start,Fa=F.$$end;u&&(M=$(b,u,Fa));t=s;if(E>F.priority)break;if(t=F.scope)I=I||F,F.templateUrl||(Va("new/isolated scope",G,F,M),T(t)&&(G=F));ba=F.name;!F.templateUrl&&F.controller&&(t=F.controller,A=A||{},Va("'"+ba+"' controller",A[ba],F,M),A[ba]=F);if(t=F.transclude)F.$$tlb||(Va("transclusion",g,F,M),g=F),"element"==t?(E=F.priority,t=$(b,u,Fa),M=c.$$element=y(O.createComment(" "+ba+": "+c[ba]+" ")),b=M[0],L(e,y(ta.call(t,
|
!d)f.on("$destroy",function(){e.$destroy()});return f}}function N(b,f,h,g,l){var n=h.$attr,u;switch(b.nodeType){case 1:R(f,va(pa(b)),"E",g,l);for(var p,q,T,A=b.attributes,z=0,v=A&&A.length;z<v;z++){var x=!1,J=!1;p=A[z];if(!X||8<=X||p.specified){u=p.name;p=ba(p.value);q=va(u);if(T=U.test(q))u=Db(q.substr(6),"-");var W=q.replace(/(Start|End)$/,""),r;a:{var H=W;if(c.hasOwnProperty(H)){r=void 0;for(var H=a.get(H+"Directive"),O=0,Q=H.length;O<Q;O++)if(r=H[O],r.multiElement){r=!0;break a}}r=!1}r&&q===W+
|
||||||
0)),b),wa=v(t,d,E,f&&f.name,{transcludeDirective:g})):(t=y(zb(b)).contents(),M.html(""),wa=v(t,d));if(F.template)if(Va("template",N,F,M),N=F,t=B(F.template)?F.template(M,c):F.template,t=fc(t),F.replace){f=F;t=y("<div>"+Y(t)+"</div>").contents();b=t[0];if(1!=t.length||1!==b.nodeType)throw fa("tplrt",ba,"");L(e,M,b);w={$attr:{}};t=oa(b,[],w);var P=a.splice(ga+1,a.length-(ga+1));G&&z(t);a=a.concat(t).concat(P);gb(c,w);w=a.length}else M.html(t);if(F.templateUrl)Va("template",N,F,M),N=F,F.replace&&(f=
|
"Start"&&(x=u,J=u.substr(0,u.length-5)+"end",u=u.substr(0,u.length-6));q=va(u.toLowerCase());n[q]=u;if(T||!h.hasOwnProperty(q))h[q]=p,yc(b,q)&&(h[q]=!0);ya(b,f,p,q,T);R(f,q,"A",g,l,x,J)}}b=b.className;if(C(b)&&""!==b)for(;u=e.exec(b);)q=va(u[2]),R(f,q,"C",g,l)&&(h[q]=ba(u[3])),b=b.substr(u.index+u[0].length);break;case 3:t(f,b.nodeValue);break;case 8:try{if(u=d.exec(b.nodeValue))q=va(u[1]),R(f,q,"M",g,l)&&(h[q]=ba(u[2]))}catch(M){}}f.sort(F);return f}function M(a,b,c){var d=[],e=0;if(b&&a.hasAttribute&&
|
||||||
F),S=ad(a.splice(ga,a.length-ga),M,c,e,wa,h,k,{controllerDirectives:A,newIsolateScopeDirective:G,templateDirective:N,transcludeDirective:g}),w=a.length;else if(F.compile)try{x=F.compile(M,c,wa),B(x)?p(null,x,u,Fa):x&&p(x.pre,x.post,u,Fa)}catch(ed){n(ed,ea(M))}F.terminal&&(S.terminal=!0,E=Math.max(E,F.priority))}S.scope=I&&!0===I.scope;S.transclude=g&&wa;return S}function z(a){for(var b=0,c=a.length;b<c;b++)a[b]=Qb(a[b],{$$isolateScope:!0})}function N(d,e,f,h,g,l,p){if(e===g)return null;g=null;if(a.hasOwnProperty(e)){var r;
|
a.hasAttribute(b)){do{if(!a)throw ja("uterdir",b,c);1==a.nodeType&&(a.hasAttribute(b)&&e++,a.hasAttribute(c)&&e--);d.push(a);a=a.nextSibling}while(0<e)}else d.push(a);return G(d)}function O(a,b,c){return function(d,e,f,h,g){e=M(e[0],b,c);return a(d,e,f,h,g)}}function H(a,c,d,e,f,h,g,k,l){function u(a,b,c,d){if(a){c&&(a=O(a,c,d));a.require=I.require;a.directiveName=ha;if(y===I||I.$$isolateScope)a=ga(a,{isolateScope:!0});g.push(a)}if(b){c&&(b=O(b,c,d));b.require=I.require;b.directiveName=ha;if(y===
|
||||||
e=b.get(e+c);for(var C=0,H=e.length;C<H;C++)try{r=e[C],(h===s||h>r.priority)&&-1!=r.restrict.indexOf(f)&&(l&&(r=Qb(r,{$$start:l,$$end:p})),d.push(r),g=r)}catch(E){n(E)}}return g}function gb(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,f){"class"==f?(Z(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?e.attr("style",e.attr("style")+";"+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||
|
I||I.$$isolateScope)b=ga(b,{isolateScope:!0});k.push(b)}}function T(a,b,c,d){var e,f="data",h=!1;if(C(b)){for(;"^"==(e=b.charAt(0))||"?"==e;)b=b.substr(1),"^"==e&&(f="inheritedData"),h=h||"?"==e;e=null;d&&"data"===f&&(e=d[b])&&(e=e.instance);e=e||c[f]("$"+b+"Controller");if(!e&&!h)throw ja("ctreq",b,a);}else L(b)&&(e=[],r(b,function(b){e.push(T(a,b,c,d))}));return e}function z(a,e,f,h,l){function u(a,b,c){var d;Qa(a)||(c=b,b=a,a=s);E&&(d=W);c||(c=E?M.parent():M);return l(a,b,d,c)}var p,v,ua,x,W,O,
|
||||||
(a[f]=b,d[f]=c[f])})}function ad(a,b,c,d,e,f,h,g){var k=[],n,l,C=b[0],H=a.shift(),v=u({},H,{templateUrl:null,transclude:null,replace:null,$$originalDirective:H}),I=B(H.templateUrl)?H.templateUrl(b,c):H.templateUrl;b.html("");r.get(S.getTrustedResourceUrl(I),{cache:p}).success(function(p){var r;p=fc(p);if(H.replace){p=y("<div>"+Y(p)+"</div>").contents();r=p[0];if(1!=p.length||1!==r.nodeType)throw fa("tplrt",H.name,I);p={$attr:{}};L(d,b,r);var S=oa(r,[],p);T(H.scope)&&z(S);a=S.concat(a);gb(c,p)}else r=
|
M,R;c===f?(R=d,M=d.$$element):(M=G(f),R=new Ob(M,d));y&&(x=e.$new(!0));O=l&&u;J&&(H={},W={},r(J,function(a){var b={$scope:a===y||a.$$isolateScope?x:e,$element:M,$attrs:R,$transclude:O};ua=a.controller;"@"==ua&&(ua=R[a.name]);b=A(ua,b,!0,a.controllerAs);W[a.name]=b;E||M.data("$"+a.name+"Controller",b.instance);H[a.name]=b}));if(y){var N=/^\s*([@=&])(\??)\s*(\w*)\s*$/;Q.$$addScopeInfo(M,x,!0,!(ca&&(ca===y||ca===y.$$originalDirective)));Q.$$addScopeClass(M,!0);h=H&&H[y.name];var xa=x;h&&h.identifier&&
|
||||||
C,b.html(p);a.unshift(v);n=M(a,r,c,e,b,H,f,h,g);q(d,function(a,c){a==r&&(d[c]=b[0])});for(l=E(b[0].childNodes,e);k.length;){p=k.shift();var S=k.shift(),Z=k.shift(),G=k.shift(),A=b[0];S!==C&&(A=zb(r),L(Z,y(S),A));n(l,p,A,d,G)}k=null}).error(function(a,b,c,d){throw fa("tpload",d.url);});return function(a,b,c,d,e){k?(k.push(b),k.push(c),k.push(d),k.push(e)):n(l,b,c,d,e)}}function wa(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name<b.name?-1:1:a.index-b.index}function Va(a,b,c,d){if(b)throw fa("multidir",
|
!0===y.bindToController&&(xa=h.instance);r(y.scope,function(a,c){var d=a.match(N)||[],f=d[3]||c,h="?"==d[2],d=d[1],g,k,l,u;x.$$isolateBindings[c]=d+f;switch(d){case "@":R.$observe(f,function(a){x[c]=a});R.$$observers[f].$$scope=e;R[f]&&(xa[c]=b(R[f])(e));break;case "=":if(h&&!R[f])break;k=q(R[f]);u=k.literal?ra:function(a,b){return a===b||a!==a&&b!==b};l=k.assign||function(){g=xa[c]=k(e);throw ja("nonassign",R[f],y.name);};g=xa[c]=k(e);h=e.$watch(q(R[f],function(a){u(a,xa[c])||(u(a,g)?l(e,a=xa[c]):
|
||||||
b.name,c.name,a,ea(d));}function t(a,b){var c=l(b,!0);c&&a.push({priority:0,compile:aa(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);Z(d.data("$binding",e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function x(a,b){if("xlinkHref"==b||"IMG"!=Ea(a)&&("src"==b||"ngSrc"==b))return S.RESOURCE_URL}function w(a,b,c,d){var e=l(c,!0);if(e){if("multiple"===d&&"SELECT"===Ea(a))throw fa("selmulti",ea(a));b.push({priority:100,compile:function(){return{pre:function(b,c,f){c=
|
xa[c]=a);return g=a}),null,k.literal);x.$on("$destroy",h);break;case "&":k=q(R[f]);xa[c]=function(a){return k(e,a)};break;default:throw ja("iscp",y.name,c,a);}})}H&&(r(H,function(a){a()}),H=null);h=0;for(p=g.length;h<p;h++)v=g[h],Dc(v,v.isolateScope?x:e,M,R,v.require&&T(v.directiveName,v.require,M,W),O);h=e;y&&(y.template||null===y.templateUrl)&&(h=x);a&&a(h,f.childNodes,s,l);for(h=k.length-1;0<=h;h--)v=k[h],Dc(v,v.isolateScope?x:e,M,R,v.require&&T(v.directiveName,v.require,M,W),O)}l=l||{};for(var v=
|
||||||
f.$$observers||(f.$$observers={});if(h.test(d))throw fa("nodomevents");if(e=l(f[d],!0,x(a,d)))f[d]=e(b),(c[d]||(c[d]=[])).$$inter=!0,(f.$$observers&&f.$$observers[d].$$scope||b).$watch(e,function(a){f.$set(d,a)})}}}})}}function L(a,b,c){var d=b[0],e=b.length,f=d.parentNode,h,g;if(a)for(h=0,g=a.length;h<g;h++)if(a[h]==d){a[h++]=c;g=h+e-1;for(var k=a.length;h<k;h++,g++)g<k?a[h]=a[g]:delete a[h];a.length-=e-1;break}f&&f.replaceChild(c,d);a=O.createDocumentFragment();a.appendChild(d);c[y.expando]=d[y.expando];
|
-Number.MAX_VALUE,x,J=l.controllerDirectives,H,y=l.newIsolateScopeDirective,ca=l.templateDirective,R=l.nonTlbTranscludeDirective,w=!1,F=!1,E=l.hasElementTranscludeDirective,aa=d.$$element=G(c),I,ha,t,P=e,za,ma=0,ya=a.length;ma<ya;ma++){I=a[ma];var U=I.$$start,X=I.$$end;U&&(aa=M(c,U,X));t=s;if(v>I.priority)break;if(t=I.scope)I.templateUrl||(S(t)?(K("new/isolated scope",y||x,I,aa),y=I):K("new/isolated scope",y,I,aa)),x=x||I;ha=I.name;!I.templateUrl&&I.controller&&(t=I.controller,J=J||{},K("'"+ha+"' controller",
|
||||||
d=1;for(e=b.length;d<e;d++)f=b[d],y(f).remove(),a.appendChild(f),delete b[d];b[0]=c;b.length=1}function Q(a,b){return u(function(){return a.apply(null,arguments)},a,b)}var R=function(a,b){this.$$element=a;this.$attr=b||{}};R.prototype={$normalize:ka,$addClass:function(a){a&&0<a.length&&G.addClass(this.$$element,a)},$removeClass:function(a){a&&0<a.length&&G.removeClass(this.$$element,a)},$set:function(a,b,c,d){function e(a,b){var c=[],d=a.split(/\s+/),f=b.split(/\s+/),h=0;a:for(;h<d.length;h++){for(var g=
|
J[ha],I,aa),J[ha]=I);if(t=I.transclude)w=!0,I.$$tlb||(K("transclusion",R,I,aa),R=I),"element"==t?(E=!0,v=I.priority,t=aa,aa=d.$$element=G(Y.createComment(" "+ha+": "+d[ha]+" ")),c=aa[0],rb(f,Ta.call(t,0),c),P=Q(t,e,v,h&&h.name,{nonTlbTranscludeDirective:R})):(t=G(Ib(c)).contents(),aa.empty(),P=Q(t,e));if(I.template)if(F=!0,K("template",ca,I,aa),ca=I,t=D(I.template)?I.template(aa,d):I.template,t=V(t),I.replace){h=I;t=Gb.test(t)?G(Nb(I.templateNamespace,ba(t))):[];c=t[0];if(1!=t.length||1!==c.nodeType)throw ja("tplrt",
|
||||||
d[h],k=0;k<f.length;k++)if(g==f[k])continue a;c.push(g)}return c}if("class"==a)b=b||"",c=this.$$element.attr("class")||"",this.$removeClass(e(c,b).join(" ")),this.$addClass(e(b,c).join(" "));else{var h=bc(this.$$element[0],a);h&&(this.$$element.prop(a,b),d=h);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=cb(a,"-"));h=Ea(this.$$element);if("A"===h&&"href"===a||"IMG"===h&&"src"===a)if(!P||8<=P)h=xa(b).href,""!==h&&("href"===a&&!h.match(f)||"src"===a&&!h.match(g))&&(this[a]=b="unsafe:"+
|
ha,"");rb(f,aa,c);ya={$attr:{}};t=N(c,[],ya);var Z=a.splice(ma+1,a.length-(ma+1));y&&W(t);a=a.concat(t).concat(Z);B(d,ya);ya=a.length}else aa.html(t);if(I.templateUrl)F=!0,K("template",ca,I,aa),ca=I,I.replace&&(h=I),z=$e(a.splice(ma,a.length-ma),aa,d,f,w&&P,g,k,{controllerDirectives:J,newIsolateScopeDirective:y,templateDirective:ca,nonTlbTranscludeDirective:R}),ya=a.length;else if(I.compile)try{za=I.compile(aa,d,P),D(za)?u(null,za,U,X):za&&u(za.pre,za.post,U,X)}catch($){p($,ta(aa))}I.terminal&&(z.terminal=
|
||||||
h);!1!==c&&(null===b||b===s?this.$$element.removeAttr(d):this.$$element.attr(d,b))}(c=this.$$observers)&&q(c[a],function(a){try{a(b)}catch(c){n(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);I.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var ba=l.startSymbol(),ga=l.endSymbol(),fc="{{"==ba||"}}"==ga?za:function(a){return a.replace(/\{\{/g,ba).replace(/}}/g,ga)},Fa=/^ngAttr[A-Z]/;return v}]}function ka(b){return Pa(b.replace(fd,""))}
|
!0,v=Math.max(v,I.priority))}z.scope=x&&!0===x.scope;z.transcludeOnThisElement=w;z.elementTranscludeOnThisElement=E;z.templateOnThisElement=F;z.transclude=P;l.hasElementTranscludeDirective=E;return z}function W(a){for(var b=0,c=a.length;b<c;b++)a[b]=bc(a[b],{$$isolateScope:!0})}function R(b,d,e,f,h,g,l){if(d===h)return null;h=null;if(c.hasOwnProperty(d)){var n;d=a.get(d+"Directive");for(var u=0,q=d.length;u<q;u++)try{n=d[u],(f===s||f>n.priority)&&-1!=n.restrict.indexOf(e)&&(g&&(n=bc(n,{$$start:g,
|
||||||
function gd(){var b={},a=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,d){na(a,"controller");T(a)?u(b,a):b[a]=d};this.$get=["$injector","$window",function(c,d){return function(e,f){var g,h,m;D(e)&&(g=e.match(a),h=g[1],m=g[3],e=b.hasOwnProperty(h)?b[h]:ub(f.$scope,h,!0)||ub(d,h,!0),Oa(e,h,!0));g=c.instantiate(e,f);if(m){if(!f||"object"!=typeof f.$scope)throw L("$controller")("noscp",h||e.name,m);f.$scope[m]=g}return g}}]}function hd(){this.$get=["$window",function(b){return y(b.document)}]}function id(){this.$get=
|
$$end:l})),b.push(n),h=n)}catch(T){p(T)}}return h}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(y(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function $e(a,b,c,d,e,f,h,g){var k=[],n,u,p=b[0],q=a.shift(),
|
||||||
["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function gc(b){var a={},c,d,e;if(!b)return a;q(b.split("\n"),function(b){e=b.indexOf(":");c=w(Y(b.substr(0,e)));d=Y(b.substr(e+1));c&&(a[c]=a[c]?a[c]+(", "+d):d)});return a}function hc(b){var a=T(b)?b:s;return function(c){a||(a=gc(b));return c?a[w(c)]||null:a}}function ic(b,a,c){if(B(c))return c(b,a);q(c,function(c){b=c(b,a)});return b}function jd(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d={"Content-Type":"application/json;charset=utf-8"},
|
T=E({},q,{templateUrl:null,transclude:null,replace:null,$$originalDirective:q}),v=D(q.templateUrl)?q.templateUrl(b,c):q.templateUrl,A=q.templateNamespace;b.empty();l(z.getTrustedResourceUrl(v)).then(function(l){var z,x;l=V(l);if(q.replace){l=Gb.test(l)?G(Nb(A,ba(l))):[];z=l[0];if(1!=l.length||1!==z.nodeType)throw ja("tplrt",q.name,v);l={$attr:{}};rb(d,b,z);var O=N(z,[],l);S(q.scope)&&W(O);a=O.concat(a);B(c,l)}else z=p,b.html(l);a.unshift(T);n=H(a,z,c,e,b,q,f,h,g);r(d,function(a,c){a==z&&(d[c]=b[0])});
|
||||||
e=this.defaults={transformResponse:[function(d){D(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=Sb(d)));return d}],transformRequest:[function(a){return T(a)&&"[object File]"!==Ka.apply(a)?ma(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:d,put:d,patch:d},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},f=this.interceptors=[],g=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,d,n,r){function p(a){function c(a){var b=
|
for(u=ca(b[0].childNodes,e);k.length;){l=k.shift();x=k.shift();var M=k.shift(),Q=k.shift(),O=b[0];if(x!==p){var R=x.className;g.hasElementTranscludeDirective&&q.replace||(O=Ib(z));rb(M,G(x),O);y(G(O),R)}x=n.transcludeOnThisElement?J(l,n.transclude,Q):Q;n(u,l,O,d,x)}k=null});return function(a,b,c,d,e){a=e;k?(k.push(b),k.push(c),k.push(d),k.push(a)):(n.transcludeOnThisElement&&(a=J(b,n.transclude,e)),n(u,b,c,d,a))}}function F(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name<b.name?
|
||||||
u({},a,{data:ic(a.data,a.headers,d.transformResponse)});return 200<=a.status&&300>a.status?b:n.reject(b)}var d={transformRequest:e.transformRequest,transformResponse:e.transformResponse},f=function(a){function b(a){var c;q(a,function(b,d){B(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=u({},a.headers),f,h,c=u({},c.common,c[w(a.method)]);b(c);b(d);a:for(f in c){a=w(f);for(h in d)if(w(h)===a)continue a;d[f]=c[f]}return d}(a);u(d,a);d.headers=f;d.method=Ga(d.method);(a=Eb(d.url)?b.cookies()[d.xsrfCookieName||
|
-1:1:a.index-b.index}function K(a,b,c,d){if(b)throw ja("multidir",b.name,c.name,a,ta(d));}function t(a,c){var d=b(c,!0);d&&a.push({priority:0,compile:function(a){a=a.parent();var b=!!a.length;b&&Q.$$addBindingClass(a);return function(a,c){var e=c.parent();b||Q.$$addBindingClass(e);Q.$$addBindingInfo(e,d.expressions);a.$watch(d,function(a){c[0].nodeValue=a})}}})}function Nb(a,b){a=P(a||"html");switch(a){case "svg":case "math":var c=Y.createElement("div");c.innerHTML="<"+a+">"+b+"</"+a+">";return c.childNodes[0].childNodes;
|
||||||
e.xsrfCookieName]:s)&&(f[d.xsrfHeaderName||e.xsrfHeaderName]=a);var h=[function(a){f=a.headers;var b=ic(a.data,hc(f),a.transformRequest);x(a.data)&&q(f,function(a,b){"content-type"===w(b)&&delete f[b]});x(a.withCredentials)&&!x(e.withCredentials)&&(a.withCredentials=e.withCredentials);return C(a,b,f).then(c,c)},s],g=n.when(d);for(q(A,function(a){(a.request||a.requestError)&&h.unshift(a.request,a.requestError);(a.response||a.responseError)&&h.push(a.response,a.responseError)});h.length;){a=h.shift();
|
default:return b}}function za(a,b){if("srcdoc"==b)return z.HTML;var c=pa(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return z.RESOURCE_URL}function ya(a,c,d,e,h){var k=b(d,!0);if(k){if("multiple"===e&&"select"===pa(a))throw ja("selmulti",ta(a));c.push({priority:100,compile:function(){return{pre:function(c,d,l){d=l.$$observers||(l.$$observers={});if(g.test(e))throw ja("nodomevents");if(k=b(l[e],!0,za(a,e),f[e]||h))l[e]=k(c),(d[e]||(d[e]=[])).$$inter=!0,(l.$$observers&&
|
||||||
var k=h.shift(),g=g.then(a,k)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,d)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,d)});return g};return g}function C(b,c,f){function g(a,b,c){q&&(200<=a&&300>a?q.put(s,[a,b,gc(c)]):q.remove(s));k(b,a,c);d.$$phase||d.$apply()}function k(a,c,d){c=Math.max(c,0);(200<=c&&300>c?r.resolve:r.reject)({data:a,status:c,headers:hc(d),config:b})}function m(){var a=ab(p.pendingRequests,b);-1!==a&&p.pendingRequests.splice(a,
|
l.$$observers[e].$$scope||c).$watch(k,function(a,b){"class"===e&&a!=b?l.$updateClass(a,b):l.$set(e,a)})}}}})}}function rb(a,b,c){var d=b[0],e=b.length,f=d.parentNode,h,g;if(a)for(h=0,g=a.length;h<g;h++)if(a[h]==d){a[h++]=c;g=h+e-1;for(var k=a.length;h<k;h++,g++)g<k?a[h]=a[g]:delete a[h];a.length-=e-1;a.context===d&&(a.context=c);break}f&&f.replaceChild(c,d);a=Y.createDocumentFragment();a.appendChild(d);G(c).data(G(d).data());la?(Eb=!0,la.cleanData([d])):delete G.cache[d[G.expando]];d=1;for(e=b.length;d<
|
||||||
1)}var r=n.defer(),C=r.promise,q,A,s=H(b.url,b.params);p.pendingRequests.push(b);C.then(m,m);(b.cache||e.cache)&&(!1!==b.cache&&"GET"==b.method)&&(q=T(b.cache)?b.cache:T(e.cache)?e.cache:I);if(q)if(A=q.get(s),z(A)){if(A.then)return A.then(m,m),A;J(A)?k(A[1],A[0],da(A[2])):k(A,200,{})}else q.put(s,C);x(A)&&a(b.method,s,c,g,f,b.timeout,b.withCredentials,b.responseType);return C}function H(a,b){if(!b)return a;var c=[];Jc(b,function(a,b){null===a||x(a)||(J(a)||(a=[a]),q(a,function(a){T(a)&&(a=ma(a));
|
e;d++)f=b[d],G(f).remove(),a.appendChild(f),delete b[d];b[0]=c;b.length=1}function ga(a,b){return E(function(){return a.apply(null,arguments)},a,b)}function Dc(a,b,c,d,e,f){try{a(b,c,d,e,f)}catch(h){p(h,ta(c))}}var Ob=function(a,b){if(b){var c=Object.keys(b),d,e,f;d=0;for(e=c.length;d<e;d++)f=c[d],this[f]=b[f]}else this.$attr={};this.$$element=a};Ob.prototype={$normalize:va,$addClass:function(a){a&&0<a.length&&T.addClass(this.$$element,a)},$removeClass:function(a){a&&0<a.length&&T.removeClass(this.$$element,
|
||||||
c.push(ua(b)+"="+ua(a))}))});return a+(-1==a.indexOf("?")?"?":"&")+c.join("&")}var I=c("$http"),A=[];q(f,function(a){A.unshift(D(a)?r.get(a):r.invoke(a))});q(g,function(a,b){var c=D(a)?r.get(a):r.invoke(a);A.splice(b,0,{response:function(a){return c(n.when(a))},responseError:function(a){return c(n.reject(a))}})});p.pendingRequests=[];(function(a){q(arguments,function(a){p[a]=function(b,c){return p(u(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){q(arguments,function(a){p[a]=
|
a)},$updateClass:function(a,b){var c=Ec(a,b);c&&c.length&&T.addClass(this.$$element,c);(c=Ec(b,a))&&c.length&&T.removeClass(this.$$element,c)},$set:function(a,b,c,d){var e=this.$$element[0],f=yc(e,a),h=Ue(e,a),e=a;f?(this.$$element.prop(a,b),d=f):h&&(this[h]=b,e=h);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=Db(a,"-"));f=pa(this.$$element);if("a"===f&&"href"===a||"img"===f&&"src"===a)this[a]=b=v(b,"src"===a);!1!==c&&(null===b||b===s?this.$$element.removeAttr(d):this.$$element.attr(d,
|
||||||
function(b,c,d){return p(u(d||{},{method:a,url:b,data:c}))}})})("post","put");p.defaults=e;return p}]}function kd(){this.$get=["$browser","$window","$document",function(b,a,c){return ld(b,md,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}function ld(b,a,c,d,e,f){function g(a,b){var c=e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;P?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=
|
b));(a=this.$$observers)&&r(a[e],function(a){try{a(b)}catch(c){p(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);u.$evalAsync(function(){e.$$inter||b(c[a])});return function(){Ra(e,b)}}};var ma=b.startSymbol(),ha=b.endSymbol(),V="{{"==ma||"}}"==ha?Pa:function(a){return a.replace(/\{\{/g,ma).replace(/}}/g,ha)},U=/^ngAttr[A-Z]/;Q.$$addBindingInfo=h?function(a,b){var c=a.data("$binding")||[];L(b)?c=c.concat(b):c.push(b);a.data("$binding",c)}:w;
|
||||||
d;e.body.appendChild(c);return d}return function(e,m,k,l,n,r,p,C){function H(){A=-1;G&&G();v&&v.abort()}function I(a,d,e,h){var g=f||xa(m).protocol;Z&&c.cancel(Z);G=v=null;d="file"==g?e?200:404:d;a(1223==d?204:d,e,h);b.$$completeOutstandingRequest(t)}var A;b.$$incOutstandingRequestCount();m=m||b.url();if("jsonp"==w(e)){var s="_"+(d.counter++).toString(36);d[s]=function(a){d[s].data=a};var G=g(m.replace("JSON_CALLBACK","angular.callbacks."+s),function(){d[s].data?I(l,200,d[s].data):I(l,A||-2);delete d[s]})}else{var v=
|
Q.$$addBindingClass=h?function(a){y(a,"ng-binding")}:w;Q.$$addScopeInfo=h?function(a,b,c,d){a.data(c?d?"$isolateScopeNoTemplate":"$isolateScope":"$scope",b)}:w;Q.$$addScopeClass=h?function(a,b){y(a,b?"ng-isolate-scope":"ng-scope")}:w;return Q}]}function va(b){return Wa(b.replace(af,""))}function Ec(b,a){var c="",d=b.split(/\s+/),e=a.split(/\s+/),f=0;a:for(;f<d.length;f++){for(var g=d[f],h=0;h<e.length;h++)if(g==e[h])continue a;c+=(0<c.length?" ":"")+g}return c}function re(){var b={},a=!1,c=/^(\S+)(\s+as\s+(\w+))?$/;
|
||||||
new a;v.open(e,m,!0);q(n,function(a,b){z(a)&&v.setRequestHeader(b,a)});v.onreadystatechange=function(){if(4==v.readyState){var a=v.getAllResponseHeaders();I(l,A||v.status,v.responseType?v.response:v.responseText,a)}};p&&(v.withCredentials=!0);C&&(v.responseType=C);v.send(k||null)}if(0<r)var Z=c(H,r);else r&&r.then&&r.then(H)}}function nd(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler",
|
this.register=function(a,c){Ja(a,"controller");S(a)?E(b,a):b[a]=c};this.allowGlobals=function(){a=!0};this.$get=["$injector","$window",function(d,e){function f(a,b,c,d){if(!a||!S(a.$scope))throw K("$controller")("noscp",d,b);a.$scope[b]=c}return function(g,h,m,k){var n,p,l;m=!0===m;k&&C(k)&&(l=k);C(g)&&(k=g.match(c),p=k[1],l=l||k[3],g=b.hasOwnProperty(p)?b[p]:ic(h.$scope,p,!0)||(a?ic(e,p,!0):s),gb(g,p,!0));if(m)return m=function(){},m.prototype=(L(g)?g[g.length-1]:g).prototype,n=new m,l&&f(h,l,n,
|
||||||
"$sce",function(c,d,e){function f(f,k,l){for(var n,r,p=0,C=[],H=f.length,q=!1,A=[];p<H;)-1!=(n=f.indexOf(b,p))&&-1!=(r=f.indexOf(a,n+g))?(p!=n&&C.push(f.substring(p,n)),C.push(p=c(q=f.substring(n+g,r))),p.exp=q,p=r+h,q=!0):(p!=H&&C.push(f.substring(p)),p=H);(H=C.length)||(C.push(""),H=1);if(l&&1<C.length)throw jc("noconcat",f);if(!k||q)return A.length=H,p=function(a){try{for(var b=0,c=H,h;b<c;b++)"function"==typeof(h=C[b])&&(h=h(a),h=l?e.getTrusted(l,h):e.valueOf(h),null===h||x(h)?h="":"string"!=
|
p||g.name),E(function(){d.invoke(g,n,h,p);return n},{instance:n,identifier:l});n=d.instantiate(g,h,p);l&&f(h,l,n,p||g.name);return n}}]}function se(){this.$get=["$window",function(b){return G(b.document)}]}function te(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Fc(b){var a={},c,d,e;if(!b)return a;r(b.split("\n"),function(b){e=b.indexOf(":");c=P(ba(b.substr(0,e)));d=ba(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function Gc(b){var a=S(b)?b:
|
||||||
typeof h&&(h=ma(h))),A[b]=h;return A.join("")}catch(g){a=jc("interr",f,g.toString()),d(a)}},p.exp=f,p.parts=C,p}var g=b.length,h=a.length;f.startSymbol=function(){return b};f.endSymbol=function(){return a};return f}]}function od(){this.$get=["$rootScope","$window","$q",function(b,a,c){function d(d,g,h,m){var k=a.setInterval,l=a.clearInterval,n=c.defer(),r=n.promise,p=0,C=z(m)&&!m;h=z(h)?h:0;r.then(null,null,d);r.$$intervalId=k(function(){n.notify(p++);0<h&&p>=h&&(n.resolve(p),l(r.$$intervalId),delete e[r.$$intervalId]);
|
s;return function(c){a||(a=Fc(b));return c?a[P(c)]||null:a}}function Hc(b,a,c){if(D(c))return c(b,a);r(c,function(c){b=c(b,a)});return b}function we(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d={"Content-Type":"application/json;charset=utf-8"},e=this.defaults={transformResponse:[function(d){C(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=dc(d)));return d}],transformRequest:[function(a){return S(a)&&"[object File]"!==Ga.call(a)&&"[object Blob]"!==Ga.call(a)?sa(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},
|
||||||
C||b.$apply()},g);e[r.$$intervalId]=n;return r}var e={};d.cancel=function(a){return a&&a.$$intervalId in e?(e[a.$$intervalId].reject("canceled"),clearInterval(a.$$intervalId),delete e[a.$$intervalId],!0):!1};return d}]}function pd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",
|
post:qa(d),put:qa(d),patch:qa(d)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},f=!1;this.useApplyAsync=function(a){return B(a)?(f=!!a,this):f};var g=this.interceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,d,p,l){function q(a){function b(a){var d=E({},a,{data:Hc(a.data,a.headers,c.transformResponse)});a=a.status;return 200<=a&&300>a?d:p.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},
|
||||||
gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",
|
d=function(a){var b=e.headers,c=E({},a.headers),d,f,b=E({},b.common,b[P(a.method)]);a:for(d in b){a=P(d);for(f in c)if(P(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){D(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a);E(c,a);c.headers=d;c.method=ib(c.method);var f=[function(a){d=a.headers;var c=Hc(a.data,Gc(d),a.transformRequest);F(c)&&r(d,function(a,b){"content-type"===P(b)&&delete d[b]});F(a.withCredentials)&&!F(e.withCredentials)&&(a.withCredentials=e.withCredentials);
|
||||||
mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function kc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=sb(b[a]);return b.join("/")}function lc(b,a){var c=xa(b);a.$$protocol=c.protocol;a.$$host=c.hostname;a.$$port=U(c.port)||qd[c.protocol]||null}function mc(b,a){var c="/"!==b.charAt(0);c&&(b="/"+b);var d=xa(b);a.$$path=decodeURIComponent(c&&"/"===d.pathname.charAt(0)?d.pathname.substring(1):d.pathname);a.$$search=Ub(d.search);a.$$hash=decodeURIComponent(d.hash);
|
return A(a,c,d).then(b,b)},s],h=p.when(c);for(r(z,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var g=f.shift(),h=h.then(a,g)}h.success=function(a){h.then(function(b){a(b.data,b.status,b.headers,c)});return h};h.error=function(a){h.then(null,function(b){a(b.data,b.status,b.headers,c)});return h};return h}function A(c,g,k){function l(a,b,c,e){function h(){z(b,a,c,e)}O&&(200<=a&&
|
||||||
a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function la(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Wa(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Fb(b){return b.substr(0,Wa(b).lastIndexOf("/")+1)}function nc(b,a){this.$$html5=!0;a=a||"";var c=Fb(b);lc(b,this);this.$$parse=function(a){var b=la(c,a);if(!D(b))throw Gb("ipthprfx",a,c);mc(b,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Vb(this.$$search),b=this.$$hash?
|
300>a?O.put(W,[a,b,Fc(c),e]):O.remove(W));f?d.$applyAsync(h):(h(),d.$$phase||d.$apply())}function z(a,b,d,e){b=Math.max(b,0);(200<=b&&300>b?r.resolve:r.reject)({data:a,status:b,headers:Gc(d),config:c,statusText:e})}function A(){var a=q.pendingRequests.indexOf(c);-1!==a&&q.pendingRequests.splice(a,1)}var r=p.defer(),M=r.promise,O,H,W=u(c.url,c.params);q.pendingRequests.push(c);M.then(A,A);!c.cache&&!e.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(O=S(c.cache)?c.cache:S(e.cache)?e.cache:
|
||||||
"#"+sb(this.$$hash):"";this.$$url=kc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=la(b,d))!==s)return d=e,(e=la(a,e))!==s?c+(la("/",e)||e):b+d;if((e=la(c,d))!==s)return c+e;if(c==d+"/")return c}}function Hb(b,a){var c=Fb(b);lc(b,this);this.$$parse=function(d){var e=la(b,d)||la(c,d),e="#"==e.charAt(0)?la(a,e):this.$$html5?e:"";if(!D(e))throw Gb("ihshprfx",d,a);mc(e,this);this.$$compose()};this.$$compose=function(){var c=Vb(this.$$search),
|
x);if(O)if(H=O.get(W),B(H)){if(H&&D(H.then))return H.then(A,A),H;L(H)?z(H[1],H[0],qa(H[2]),H[3]):z(H,200,{},"OK")}else O.put(W,M);F(H)&&((H=Ic(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:s)&&(k[c.xsrfHeaderName||e.xsrfHeaderName]=H),a(c.method,W,g,l,k,c.timeout,c.withCredentials,c.responseType));return M}function u(a,b){if(!b)return a;var c=[];od(b,function(a,b){null===a||F(a)||(L(a)||(a=[a]),r(a,function(a){S(a)&&(a=fa(a)?a.toISOString():sa(a));c.push(Da(b)+"="+Da(a))}))});0<c.length&&
|
||||||
e=this.$$hash?"#"+sb(this.$$hash):"";this.$$url=kc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Wa(b)==Wa(a))return a}}function oc(b,a){this.$$html5=!0;Hb.apply(this,arguments);var c=Fb(b);this.$$rewrite=function(d){var e;if(b==Wa(d))return d;if(e=la(c,d))return b+a+e;if(c===d+"/")return c}}function hb(b){return function(){return this[b]}}function pc(b,a){return function(c){if(x(c))return this[b];this[b]=a(c);this.$$compose();return this}}
|
(a+=(-1==a.indexOf("?")?"?":"&")+c.join("&"));return a}var x=c("$http"),z=[];r(g,function(a){z.unshift(C(a)?l.get(a):l.invoke(a))});q.pendingRequests=[];(function(a){r(arguments,function(a){q[a]=function(b,c){return q(E(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){r(arguments,function(a){q[a]=function(b,c,d){return q(E(d||{},{method:a,url:b,data:c}))}})})("post","put","patch");q.defaults=e;return q}]}function bf(b){if(8>=X&&(!b.match(/^(get|post|head|put|delete|options)$/i)||
|
||||||
function rd(){var b="",a=!1;this.hashPrefix=function(a){return z(a)?(b=a,this):b};this.html5Mode=function(b){return z(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,m=d.baseHref(),k=d.url();a?(m=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(m||"/"),e=e.history?nc:oc):(m=Wa(k),e=Hb);h=new e(m,"#"+b);h.$$parse(h.$$rewrite(k));f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&
|
!t.XMLHttpRequest))return new t.ActiveXObject("Microsoft.XMLHTTP");if(t.XMLHttpRequest)return new t.XMLHttpRequest;throw K("$httpBackend")("noxhr");}function xe(){this.$get=["$browser","$window","$document",function(b,a,c){return cf(b,bf,b.defer,a.angular.callbacks,c[0])}]}function cf(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),n=null;f.type="text/javascript";f.src=a;f.async=!0;n=function(a){f.removeEventListener("load",n,!1);f.removeEventListener("error",n,!1);e.body.removeChild(f);
|
||||||
2!=a.which){for(var b=y(a.target);"a"!==w(b[0].nodeName);)if(b[0]===f[0]||!(b=b.parent())[0])return;var e=b.prop("href"),g=h.$$rewrite(e);e&&(!b.attr("target")&&g&&!a.isDefaultPrevented())&&(a.preventDefault(),g!=d.url()&&(h.$$parse(g),c.$apply(),W.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$broadcast("$locationChangeStart",a,h.absUrl()).defaultPrevented?d.url(h.absUrl()):(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);
|
f=null;var g=-1,q="unknown";a&&("load"!==a.type||d[b].called||(a={type:"error"}),q=a.type,g="error"===a.type?404:200);c&&c(g,q)};f.addEventListener("load",n,!1);f.addEventListener("error",n,!1);e.body.appendChild(f);return n}return function(e,h,m,k,n,p,l,q){function A(){x=-1;T&&T();v&&v.abort()}function u(a,d,e,f,g){Q&&c.cancel(Q);T=v=null;0===d&&(d=e?200:"file"==Aa(h).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(w)}var x;b.$$incOutstandingRequestCount();h=h||b.url();
|
||||||
g(b)}),c.$$phase||c.$digest()))});var l=0;c.$watch(function(){var a=d.url(),b=h.$$replace;l&&a==h.absUrl()||(l++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),g(a))}));h.$$replace=!1;return l});return h}]}function sd(){var b=!0,a=this;this.debugEnabled=function(a){return z(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+
|
if("jsonp"==P(e)){var z="_"+(d.counter++).toString(36);d[z]=function(a){d[z].data=a;d[z].called=!0};var T=f(h.replace("JSON_CALLBACK","angular.callbacks."+z),z,function(a,b){u(k,a,d[z].data,"",b);d[z]=w})}else{var v=a(e);v.open(e,h,!0);r(n,function(a,b){B(a)&&v.setRequestHeader(b,a)});v.onreadystatechange=function(){if(v&&4==v.readyState){var a=null,b=null,c="";-1!==x&&(a=v.getAllResponseHeaders(),b="response"in v?v.response:v.responseText);-1===x&&10>X||(c=v.statusText);u(k,x||v.status,b,a,c)}};
|
||||||
a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||t;return e.apply?function(){var a=[];q(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function ha(b,a,c){if("string"!==typeof b&&"[object String]"!==Ka.apply(b))return b;
|
l&&(v.withCredentials=!0);if(q)try{v.responseType=q}catch(y){if("json"!==q)throw y;}v.send(m||null)}if(0<p)var Q=c(A,p);else p&&D(p.then)&&p.then(A)}}function ue(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler","$sce",function(c,d,e){function f(a){return"\\\\\\"+a}function g(f,g,q,A){function u(c){return c.replace(k,b).replace(n,a)}function x(a){try{var b;var c=q?e.getTrusted(q,a):e.valueOf(a);
|
||||||
if("constructor"===b&&!c)throw pa("isecfld",a);if("_"===b.charAt(0)||"_"===b.charAt(b.length-1))throw pa("isecprv",a);return b}function Xa(b,a){if(b&&b.constructor===b)throw pa("isecfn",a);if(b&&b.document&&b.location&&b.alert&&b.setInterval)throw pa("isecwindow",a);if(b&&(b.nodeName||b.on&&b.find))throw pa("isecdom",a);return b}function ib(b,a,c,d,e){e=e||{};a=a.split(".");for(var f,g=0;1<a.length;g++){f=ha(a.shift(),d);var h=b[f];h||(h={},b[f]=h);b=h;b.then&&e.unwrapPromises&&(qa(d),"$$v"in b||
|
if(null==c)b="";else{switch(typeof c){case "string":break;case "number":c=""+c;break;default:c=sa(c)}b=c}return b}catch(h){a=Pb("interr",f,h.toString()),d(a)}}A=!!A;for(var z,T,v=0,r=[],Q=[],s=f.length,J=[],N=[];v<s;)if(-1!=(z=f.indexOf(b,v))&&-1!=(T=f.indexOf(a,z+h)))v!==z&&J.push(u(f.substring(v,z))),v=f.substring(z+h,T),r.push(v),Q.push(c(v,x)),v=T+m,N.push(J.length),J.push("");else{v!==s&&J.push(u(f.substring(v)));break}if(q&&1<J.length)throw Pb("noconcat",f);if(!g||r.length){var M=function(a){for(var b=
|
||||||
function(a){a.then(function(b){a.$$v=b})}(b),b.$$v===s&&(b.$$v={}),b=b.$$v)}f=ha(a.shift(),d);return b[f]=c}function qc(b,a,c,d,e,f,g){ha(b,f);ha(a,f);ha(c,f);ha(d,f);ha(e,f);return g.unwrapPromises?function(h,g){var k=g&&g.hasOwnProperty(b)?g:h,l;if(null===k||k===s)return k;(k=k[b])&&k.then&&(qa(f),"$$v"in k||(l=k,l.$$v=s,l.then(function(a){l.$$v=a})),k=k.$$v);if(!a||null===k||k===s)return k;(k=k[a])&&k.then&&(qa(f),"$$v"in k||(l=k,l.$$v=s,l.then(function(a){l.$$v=a})),k=k.$$v);if(!c||null===k||
|
0,c=r.length;b<c;b++){if(A&&F(a[b]))return;J[N[b]]=a[b]}return J.join("")};return E(function(a){var b=0,c=r.length,e=Array(c);try{for(;b<c;b++)e[b]=Q[b](a);return M(e)}catch(h){a=Pb("interr",f,h.toString()),d(a)}},{exp:f,expressions:r,$$watchDelegate:function(a,b,c){var d;return a.$watchGroup(Q,function(c,e){var f=M(c);D(b)&&b.call(this,f,c!==e?d:f,a);d=f},c)}})}}var h=b.length,m=a.length,k=new RegExp(b.replace(/./g,f),"g"),n=new RegExp(a.replace(/./g,f),"g");g.startSymbol=function(){return b};g.endSymbol=
|
||||||
k===s)return k;(k=k[c])&&k.then&&(qa(f),"$$v"in k||(l=k,l.$$v=s,l.then(function(a){l.$$v=a})),k=k.$$v);if(!d||null===k||k===s)return k;(k=k[d])&&k.then&&(qa(f),"$$v"in k||(l=k,l.$$v=s,l.then(function(a){l.$$v=a})),k=k.$$v);if(!e||null===k||k===s)return k;(k=k[e])&&k.then&&(qa(f),"$$v"in k||(l=k,l.$$v=s,l.then(function(a){l.$$v=a})),k=k.$$v);return k}:function(f,g){var k=g&&g.hasOwnProperty(b)?g:f;if(null===k||k===s)return k;k=k[b];if(!a||null===k||k===s)return k;k=k[a];if(!c||null===k||k===s)return k;
|
function(){return a};return g}]}function ve(){this.$get=["$rootScope","$window","$q","$$q",function(b,a,c,d){function e(e,h,m,k){var n=a.setInterval,p=a.clearInterval,l=0,q=B(k)&&!k,A=(q?d:c).defer(),u=A.promise;m=B(m)?m:0;u.then(null,null,e);u.$$intervalId=n(function(){A.notify(l++);0<m&&l>=m&&(A.resolve(l),p(u.$$intervalId),delete f[u.$$intervalId]);q||b.$apply()},h);f[u.$$intervalId]=A;return u}var f={};e.cancel=function(b){return b&&b.$$intervalId in f?(f[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),
|
||||||
k=k[c];if(!d||null===k||k===s)return k;k=k[d];return e&&null!==k&&k!==s?k=k[e]:k}}function rc(b,a,c){if(Ib.hasOwnProperty(b))return Ib[b];var d=b.split("."),e=d.length,f;if(a.csp)f=6>e?qc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,f){var h=0,g;do g=qc(d[h++],d[h++],d[h++],d[h++],d[h++],c,a)(b,f),f=s,b=g;while(h<e);return g};else{var g="var l, fn, p;\n";q(d,function(b,d){ha(b,c);g+="if(s === null || s === undefined) return s;\nl=s;\ns="+(d?"s":'((k&&k.hasOwnProperty("'+b+'"))?k:s)')+'["'+b+'"];\n'+(a.unwrapPromises?
|
delete f[b.$$intervalId],!0):!1};return e}]}function Dd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),
|
||||||
'if (s && s.then) {\n pw("'+c.replace(/\"/g,'\\"')+'");\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n':"")});var g=g+"return s;",h=new Function("s","k","pw",g);h.toString=function(){return g};f=function(a,b){return h(a,b,qa)}}"hasOwnProperty"!==b&&(Ib[b]=f);return f}function td(){var b={},a={csp:!1,unwrapPromises:!1,logPromiseWarnings:!0};this.unwrapPromises=function(b){return z(b)?(a.unwrapPromises=!!b,this):a.unwrapPromises};this.logPromiseWarnings=
|
DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a",short:"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]=eb(b[a]);return b.join("/")}function Jc(b,a,c){b=Aa(b,c);a.$$protocol=
|
||||||
function(b){return z(b)?(a.logPromiseWarnings=b,this):a.logPromiseWarnings};this.$get=["$filter","$sniffer","$log",function(c,d,e){a.csp=d.csp;qa=function(b){a.logPromiseWarnings&&!sc.hasOwnProperty(b)&&(sc[b]=!0,e.warn("[$parse] Promise found in the expression `"+b+"`. Automatic unwrapping of promises in Angular expressions is deprecated."))};return function(d){var e;switch(typeof d){case "string":if(b.hasOwnProperty(d))return b[d];e=new Jb(a);e=(new Ya(e,c,a)).parse(d,!1);"hasOwnProperty"!==d&&
|
b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||df[b.protocol]||null}function Kc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=Aa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=fc(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function wa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ya(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0,
|
||||||
(b[d]=e);return e;case "function":return d;default:return t}}}]}function ud(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return vd(function(a){b.$evalAsync(a)},a)}]}function vd(b,a){function c(a){return a}function d(a){return g(a)}var e=function(){var h=[],m,k;return k={resolve:function(a){if(h){var c=h;h=s;m=f(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],m.then(a[0],a[1],a[2])})}},reject:function(a){k.resolve(g(a))},notify:function(a){if(h){var c=h;h.length&&b(function(){for(var b,
|
Ya(b).lastIndexOf("/")+1)}function Lc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);Jc(b,this,b);this.$$parse=function(a){var e=wa(c,a);if(!C(e))throw sb("ipthprfx",a,c);Kc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Bb(this.$$search),b=this.$$hash?"#"+eb(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;(f=wa(b,d))!==s?
|
||||||
d=0,e=c.length;d<e;d++)b=c[d],b[2](a)})}},promise:{then:function(b,f,g){var k=e(),C=function(d){try{k.resolve((B(b)?b:c)(d))}catch(e){k.reject(e),a(e)}},H=function(b){try{k.resolve((B(f)?f:d)(b))}catch(c){k.reject(c),a(c)}},q=function(b){try{k.notify((B(g)?g:c)(b))}catch(d){a(d)}};h?h.push([C,H,q]):m.then(C,H,q);return k.promise},"catch":function(a){return this.then(null,a)},"finally":function(a){function b(a,c){var d=e();c?d.resolve(a):d.reject(a);return d.promise}function d(e,f){var h=null;try{h=
|
(g=f,g=(f=wa(a,f))!==s?c+(wa("/",f)||f):b+g):(f=wa(c,d))!==s?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function Sb(b,a){var c=Rb(b);Jc(b,this,b);this.$$parse=function(d){var e=wa(b,d)||wa(c,d),e="#"==e.charAt(0)?wa(a,e):this.$$html5?e:"";if(!C(e))throw sb("ihshprfx",d,a);Kc(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Bb(this.$$search),e=this.$$hash?
|
||||||
(a||c)()}catch(g){return b(g,!1)}return h&&B(h.then)?h.then(function(){return b(e,f)},function(a){return b(a,!1)}):b(e,f)}return this.then(function(a){return d(a,!0)},function(a){return d(a,!1)})}}}},f=function(a){return a&&B(a.then)?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},g=function(c){return{then:function(f,g){var l=e();b(function(){try{l.resolve((B(g)?g:d)(c))}catch(b){l.reject(b),a(b)}});return l.promise}}};return{defer:e,reject:g,when:function(h,m,k,l){var n=
|
"#"+eb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Ya(b)==Ya(a)?(this.$$parse(a),!0):!1}}function Mc(b,a){this.$$html5=!0;Sb.apply(this,arguments);var c=Rb(b);this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;b==Ya(d)?f=d:(g=wa(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=function(){var c=Bb(this.$$search),e=this.$$hash?"#"+eb(this.$$hash):
|
||||||
e(),r,p=function(b){try{return(B(m)?m:c)(b)}catch(d){return a(d),g(d)}},C=function(b){try{return(B(k)?k:d)(b)}catch(c){return a(c),g(c)}},q=function(b){try{return(B(l)?l:c)(b)}catch(d){a(d)}};b(function(){f(h).then(function(a){r||(r=!0,n.resolve(f(a).then(p,C,q)))},function(a){r||(r=!0,n.resolve(C(a)))},function(a){r||n.notify(q(a))})});return n.promise},all:function(a){var b=e(),c=0,d=J(a)?[]:{};q(a,function(a,e){c++;f(a).then(function(a){d.hasOwnProperty(e)||(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||
|
"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function tb(b){return function(){return this[b]}}function Nc(b,a){return function(c){if(F(c))return this[b];this[b]=a(c);this.$$compose();return this}}function ye(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode=function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),
|
||||||
b.reject(a)})});0===c&&b.resolve(d);return b.promise}}}function wd(){var b=10,a=L("$rootScope");this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse","$browser",function(c,d,e,f){function g(){this.$id=Za();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$postDigestQueue=[];this.$$listeners={};this.$$isolateBindings=
|
a)}var h,m=d.baseHref(),k=d.url();if(a){if(!m)throw sb("nobase");m=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(m||"/");e=e.history?Lc:Mc}else m=Ya(k),e=Sb;h=new e(m,"#"+b);h.$$parseLinkUrl(k,k);var n=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=G(a.target);"a"!==pa(b[0]);)if(b[0]===f[0]||!(b=b.parent())[0])return;var e=b.prop("href"),g=b.attr("href")||b.attr("xlink:href");S(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=Aa(e.animVal).href);
|
||||||
{}}function h(b){if(l.$$phase)throw a("inprog",l.$$phase);l.$$phase=b}function m(a,b){var c=e(a);Oa(c,b);return c}function k(){}g.prototype={constructor:g,$new:function(a){a?(a=new g,a.$root=this.$root,a.$$asyncQueue=this.$$asyncQueue,a.$$postDigestQueue=this.$$postDigestQueue):(a=function(){},a.prototype=this,a=new a,a.$id=Za());a["this"]=a;a.$$listeners={};a.$parent=this;a.$$watchers=a.$$nextSibling=a.$$childHead=a.$$childTail=null;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=
|
n.test(e)||!e||b.attr("target")||a.isDefaultPrevented()||!h.$$parseLinkUrl(e,g)||(a.preventDefault(),h.absUrl()!=d.url()&&(c.$apply(),t.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):g(b)}),c.$$phase||c.$digest())});var p=0;c.$watch(function(){var a=d.url(),b=h.$$replace;p&&a==h.absUrl()||
|
||||||
this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,c){var d=m(a,"watch"),e=this.$$watchers,f={fn:b,last:k,get:d,exp:a,eq:!!c};if(!B(b)){var h=m(b||t,"listener");f.fn=function(a,b,c){h(c)}}if("string"==typeof a&&d.constant){var g=f.fn;f.fn=function(a,b,c){g.call(this,a,b,c);La(e,f)}}e||(e=this.$$watchers=[]);e.unshift(f);return function(){La(e,f)}},$watchCollection:function(a,b){var c=this,d,f,h=0,g=e(a),k=[],l={},m=0;return this.$watch(function(){f=
|
(p++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),g(a))}));h.$$replace=!1;return p});return h}]}function ze(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=
|
||||||
g(c);var a,b;if(T(f))if(pb(f))for(d!==k&&(d=k,m=d.length=0,h++),a=f.length,m!==a&&(h++,d.length=m=a),b=0;b<a;b++)d[b]!==f[b]&&(h++,d[b]=f[b]);else{d!==l&&(d=l={},m=0,h++);a=0;for(b in f)f.hasOwnProperty(b)&&(a++,d.hasOwnProperty(b)?d[b]!==f[b]&&(h++,d[b]=f[b]):(m++,d[b]=f[b],h++));if(m>a)for(b in h++,d)d.hasOwnProperty(b)&&!f.hasOwnProperty(b)&&(m--,delete d[b])}else d!==f&&(d=f,h++);return h},function(){b(f,d,c)})},$digest:function(){var c,e,f,g,m=this.$$asyncQueue,q=this.$$postDigestQueue,s,t,G=
|
c.console||{},e=b[a]||b.log||w;a=!1;try{a=!!e.apply}catch(m){}return a?function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function na(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw oa("isecfld",a);return b}function Ba(b,
|
||||||
b,v,y=[],E,z,$;h("$digest");do{t=!1;for(v=this;m.length;)try{$=m.shift(),$.scope.$eval($.expression)}catch(x){d(x)}do{if(g=v.$$watchers)for(s=g.length;s--;)try{(c=g[s])&&((e=c.get(v))!==(f=c.last)&&!(c.eq?Aa(e,f):"number"==typeof e&&"number"==typeof f&&isNaN(e)&&isNaN(f)))&&(t=!0,c.last=c.eq?da(e):e,c.fn(e,f===k?e:f,v),5>G&&(E=4-G,y[E]||(y[E]=[]),z=B(c.exp)?"fn: "+(c.exp.name||c.exp.toString()):c.exp,z+="; newVal: "+ma(e)+"; oldVal: "+ma(f),y[E].push(z)))}catch(M){d(M)}if(!(g=v.$$childHead||v!==this&&
|
a){if(b){if(b.constructor===b)throw oa("isecfn",a);if(b.window===b)throw oa("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw oa("isecdom",a);if(b===Object)throw oa("isecobj",a);}return b}function ub(b,a,c,d){Ba(b,d);a=a.split(".");for(var e,f=0;1<a.length;f++){e=na(a.shift(),d);var g=Ba(b[e],d);g||(g={},b[e]=g);b=g}e=na(a.shift(),d);Ba(b[e],d);return b[e]=c}function Oc(b,a,c,d,e,f){na(b,f);na(a,f);na(c,f);na(d,f);na(e,f);return function(f,h){var m=h&&h.hasOwnProperty(b)?h:
|
||||||
v.$$nextSibling))for(;v!==this&&!(g=v.$$nextSibling);)v=v.$parent}while(v=g);if(t&&!G--)throw l.$$phase=null,a("infdig",b,ma(y));}while(t||m.length);for(l.$$phase=null;q.length;)try{q.shift()()}catch(w){d(w)}},$destroy:function(){if(l!=this&&!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;a.$$childHead==this&&(a.$$childHead=this.$$nextSibling);a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling);
|
f;if(null==m)return m;m=m[b];if(!a)return m;if(null==m)return s;m=m[a];if(!c)return m;if(null==m)return s;m=m[c];if(!d)return m;if(null==m)return s;m=m[d];return e?null==m?s:m=m[e]:m}}function Pc(b,a,c){var d=Qc[b];if(d)return d;var e=b.split("."),f=e.length;if(a.csp)d=6>f?Oc(e[0],e[1],e[2],e[3],e[4],c):function(a,b){var d=0,g;do g=Oc(e[d++],e[d++],e[d++],e[d++],e[d++],c)(a,b),b=s,a=g;while(d<f);return g};else{var g="";r(e,function(a,b){na(a,c);g+="if(s == null) return undefined;\ns="+(b?"s":'((l&&l.hasOwnProperty("'+
|
||||||
this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null}},$eval:function(a,b){return e(a)(this,b)},$evalAsync:function(a){l.$$phase||l.$$asyncQueue.length||f.defer(function(){l.$$asyncQueue.length&&l.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return h("$apply"),this.$eval(a)}catch(b){d(b)}finally{l.$$phase=
|
a+'"))?l:s)')+"."+a+";\n"});g+="return s;";a=new Function("s","l",g);a.toString=da(g);a.assign=function(a,c){return ub(a,b,c,b)};d=a}d.sharedGetter=!0;return Qc[b]=d}function Ae(){var b=Object.create(null),a={csp:!1};this.$get=["$filter","$sniffer",function(c,d){function e(a){var b=a;a.sharedGetter&&(b=function(b,c){return a(b,c)},b.literal=a.literal,b.constant=a.constant,b.assign=a.assign);return b}function f(a,b,c,d){var e,f;return e=a.$watch(function(a){return d(a)},function(a,c,d){f=a;D(b)&&b.apply(this,
|
||||||
null;try{l.$digest()}catch(c){throw d(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);return function(){c[ab(c,b)]=null}},$emit:function(a,b){var c=[],e,f=this,h=!1,g={name:a,targetScope:f,stopPropagation:function(){h=!0},preventDefault:function(){g.defaultPrevented=!0},defaultPrevented:!1},k=[g].concat(ta.call(arguments,1)),l,m;do{e=f.$$listeners[a]||c;g.currentScope=f;l=0;for(m=e.length;l<m;l++)if(e[l])try{e[l].apply(null,k)}catch(q){d(q)}else e.splice(l,
|
arguments);B(a)&&d.$$postDigest(function(){B(f)&&e()})},c)}function g(a,b,c,d){function e(a){var b=!0;r(a,function(a){B(a)||(b=!1)});return b}var f;return f=a.$watch(function(a){return d(a)},function(a,c,d){D(b)&&b.call(this,a,c,d);e(a)&&d.$$postDigest(function(){e(a)&&f()})},c)}function h(a,b,c,d){var e;return e=a.$watch(function(a){return d(a)},function(a,c,d){D(b)&&b.apply(this,arguments);e()},c)}function m(a,b){if(!b)return a;var c=function(c,d){var e=a(c,d),f=b(e,c,d);return B(e)?f:e};c.$$watchDelegate=
|
||||||
1),l--,m--;if(h)break;f=f.$parent}while(f);return g},$broadcast:function(a,b){var c=this,e=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},h=[f].concat(ta.call(arguments,1)),g,k;do{c=e;f.currentScope=c;e=c.$$listeners[a]||[];g=0;for(k=e.length;g<k;g++)if(e[g])try{e[g].apply(null,h)}catch(l){d(l)}else e.splice(g,1),g--,k--;if(!(e=c.$$childHead||c!==this&&c.$$nextSibling))for(;c!==this&&!(e=c.$$nextSibling);)c=c.$parent}while(c=e);return f}};var l=
|
a.$$watchDelegate;return c}a.csp=d.csp;return function(d,n){var p,l,q;switch(typeof d){case "string":return q=d=d.trim(),p=b[q],p||(":"===d.charAt(0)&&":"===d.charAt(1)&&(l=!0,d=d.substring(2)),p=new Tb(a),p=(new Za(p,c,a)).parse(d),p.constant?p.$$watchDelegate=h:l&&(p=e(p),p.$$watchDelegate=p.literal?g:f),b[q]=p),m(p,n);case "function":return m(d,n);default:return m(w,n)}}}]}function Ce(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Rc(function(a){b.$evalAsync(a)},a)}]}function De(){this.$get=
|
||||||
new g;return l}]}function xd(b){if("self"===b)return b;if(D(b)){if(-1<b.indexOf("***"))throw ra("iwcard",b);b=b.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08").replace("\\*\\*",".*").replace("\\*","[^:/.?&;]*");return RegExp("^"+b+"$")}if($a(b))return RegExp("^"+b.source+"$");throw ra("imatcher");}function tc(b){var a=[];z(b)&&q(b,function(b){a.push(xd(b))});return a}function yd(){this.SCE_CONTEXTS=ca;var b=["self"],a=[];this.resourceUrlWhitelist=function(a){arguments.length&&
|
["$browser","$exceptionHandler",function(b,a){return Rc(function(a){b.defer(a)},a)}]}function Rc(b,a){function c(a,b,c){function d(b){return function(c){e||(e=!0,b.call(a,c))}}var e=!1;return[d(b),d(c)]}function d(){this.$$state={status:0}}function e(a,b){return function(c){b.call(a,c)}}function f(c){!c.processScheduled&&c.pending&&(c.processScheduled=!0,b(function(){var b,d,e;e=c.pending;c.processScheduled=!1;c.pending=s;for(var f=0,h=e.length;f<h;++f){d=e[f][0];b=e[f][c.status];try{D(b)?d.resolve(b(c.value)):
|
||||||
(b=tc(a));return b};this.resourceUrlBlacklist=function(b){arguments.length&&(a=tc(b));return a};this.$get=["$log","$document","$injector",function(c,d,e){function f(a){var b=function(a){this.$$unwrapTrustedValue=function(){return a}};a&&(b.prototype=new a);b.prototype.valueOf=function(){return this.$$unwrapTrustedValue()};b.prototype.toString=function(){return this.$$unwrapTrustedValue().toString()};return b}var g=function(a){throw ra("unsafe");};e.has("$sanitize")&&(g=e.get("$sanitize"));var h=f(),
|
1===c.status?d.resolve(c.value):d.reject(c.value)}catch(g){d.reject(g),a(g)}}}))}function g(){this.promise=new d;this.resolve=e(this,this.resolve);this.reject=e(this,this.reject);this.notify=e(this,this.notify)}var h=K("$q",TypeError);d.prototype={then:function(a,b,c){var d=new g;this.$$state.pending=this.$$state.pending||[];this.$$state.pending.push([d,a,b,c]);0<this.$$state.status&&f(this.$$state);return d.promise},"catch":function(a){return this.then(null,a)},"finally":function(a,b){return this.then(function(b){return k(b,
|
||||||
m={};m[ca.HTML]=f(h);m[ca.CSS]=f(h);m[ca.URL]=f(h);m[ca.JS]=f(h);m[ca.RESOURCE_URL]=f(m[ca.URL]);return{trustAs:function(a,b){var c=m.hasOwnProperty(a)?m[a]:null;if(!c)throw ra("icontext",a,b);if(null===b||b===s||""===b)return b;if("string"!==typeof b)throw ra("itype",a);return new c(b)},getTrusted:function(c,d){if(null===d||d===s||""===d)return d;var e=m.hasOwnProperty(c)?m[c]:null;if(e&&d instanceof e)return d.$$unwrapTrustedValue();if(c===ca.RESOURCE_URL){var e=xa(d.toString()),f,h,q=!1;f=0;for(h=
|
!0,a)},function(b){return k(b,!1,a)},b)}};g.prototype={resolve:function(a){this.promise.$$state.status||(a===this.promise?this.$$reject(h("qcycle",a)):this.$$resolve(a))},$$resolve:function(b){var d,e;e=c(this,this.$$resolve,this.$$reject);try{if(S(b)||D(b))d=b&&b.then;D(d)?(this.promise.$$state.status=-1,d.call(b,e[0],e[1],this.notify)):(this.promise.$$state.value=b,this.promise.$$state.status=1,f(this.promise.$$state))}catch(h){e[1](h),a(h)}},reject:function(a){this.promise.$$state.status||this.$$reject(a)},
|
||||||
b.length;f<h;f++)if("self"===b[f]?Eb(e):b[f].exec(e.href)){q=!0;break}if(q)for(f=0,h=a.length;f<h;f++)if("self"===a[f]?Eb(e):a[f].exec(e.href)){q=!1;break}if(q)return d;throw ra("insecurl",d.toString());}if(c===ca.HTML)return g(d);throw ra("unsafe");},valueOf:function(a){return a instanceof h?a.$$unwrapTrustedValue():a}}}]}function zd(){var b=!0;this.enabled=function(a){arguments.length&&(b=!!a);return b};this.$get=["$parse","$document","$sceDelegate",function(a,c,d){if(b&&P&&(c=c[0].documentMode,
|
$$reject:function(a){this.promise.$$state.value=a;this.promise.$$state.status=2;f(this.promise.$$state)},notify:function(c){var d=this.promise.$$state.pending;0>=this.promise.$$state.status&&d&&d.length&&b(function(){for(var b,e,f=0,h=d.length;f<h;f++){e=d[f][0];b=d[f][3];try{e.notify(D(b)?b(c):c)}catch(g){a(g)}}})}};var m=function(a,b){var c=new g;b?c.resolve(a):c.reject(a);return c.promise},k=function(a,b,c){var d=null;try{D(c)&&(d=c())}catch(e){return m(e,!1)}return d&&D(d.then)?d.then(function(){return m(a,
|
||||||
c!==s&&8>c))throw ra("iequirks");var e=da(ca);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=za);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,h=e.trustAs;q(ca,function(a,b){var c=w(b);e[Pa("parse_as_"+c)]=function(b){return f(a,b)};e[Pa("get_trusted_"+c)]=function(b){return g(a,b)};e[Pa("trust_as_"+
|
b)},function(a){return m(a,!1)}):m(a,b)},n=function(a,b,c,d){var e=new g;e.resolve(a);return e.promise.then(b,c,d)},p=function q(a){if(!D(a))throw h("norslvr",a);if(!(this instanceof q))return new q(a);var b=new g;a(function(a){b.resolve(a)},function(a){b.reject(a)});return b.promise};p.defer=function(){return new g};p.reject=function(a){var b=new g;b.reject(a);return b.promise};p.when=n;p.all=function(a){var b=new g,c=0,d=L(a)?[]:{};r(a,function(a,e){c++;n(a).then(function(a){d.hasOwnProperty(e)||
|
||||||
c)]=function(b){return h(a,b)}});return e}]}function Ad(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(w((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g,h=/^(Moz|webkit|O|ms)(?=[A-Z])/,m=f.body&&f.body.style,k=!1,l=!1;if(m){for(var n in m)if(k=h.exec(n)){g=k[0];g=g.substr(0,1).toUpperCase()+g.substr(1);break}g||(g="WebkitOpacity"in m&&"webkit");k=!!("transition"in m||g+"Transition"in m);l=!!("animation"in m||g+"Animation"in
|
(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||b.reject(a)})});0===c&&b.resolve(d);return b.promise};return p}function Me(){this.$get=["$window","$timeout",function(b,a){var c=b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame,d=b.cancelAnimationFrame||b.webkitCancelAnimationFrame||b.mozCancelAnimationFrame||b.webkitCancelRequestAnimationFrame,e=!!c,f=e?function(a){var b=c(a);return function(){d(b)}}:function(b){var c=a(b,16.66,!1);return function(){a.cancel(c)}};
|
||||||
m);!d||k&&l||(k=D(f.body.style.webkitTransition),l=D(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!f.documentMode||7<f.documentMode),hasEvent:function(a){if("input"==a&&9==P)return!1;if(x(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Rb(),vendorPrefix:g,transitions:k,animations:l,msie:P}}]}function Bd(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,h,m){var k=
|
f.supported=e;return f}]}function Be(){var b=10,a=K("$rootScope"),c=null,d=null;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse","$browser",function(e,f,g,h){function m(){this.$id=++bb;this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$postDigestQueue=[];this.$$listeners={};this.$$listenerCount=
|
||||||
c.defer(),l=k.promise,n=z(m)&&!m;h=a.defer(function(){try{k.resolve(e())}catch(a){k.reject(a),d(a)}finally{delete f[l.$$timeoutId]}n||b.$apply()},h);l.$$timeoutId=h;f[h]=k;return l}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),delete f[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return e}]}function xa(b){P&&(R.setAttribute("href",b),b=R.href);R.setAttribute("href",b);return{href:R.href,protocol:R.protocol?R.protocol.replace(/:$/,""):"",host:R.host,
|
{};this.$$isolateBindings={};this.$$applyAsyncQueue=[]}function k(b){if(A.$$phase)throw a("inprog",A.$$phase);A.$$phase=b}function n(a,b,c){do a.$$listenerCount[c]-=b,0===a.$$listenerCount[c]&&delete a.$$listenerCount[c];while(a=a.$parent)}function p(){}function l(){for(var a=A.$$applyAsyncQueue;a.length;)try{a.shift()()}catch(b){f(b)}d=null}function q(){null===d&&(d=h.defer(function(){A.$apply(l)}))}m.prototype={constructor:m,$new:function(a){a?(a=new m,a.$root=this.$root,a.$$asyncQueue=this.$$asyncQueue,
|
||||||
search:R.search?R.search.replace(/^\?/,""):"",hash:R.hash?R.hash.replace(/^#/,""):"",hostname:R.hostname,port:R.port,pathname:R.pathname&&"/"===R.pathname.charAt(0)?R.pathname:"/"+R.pathname}}function Eb(b){b=D(b)?xa(b):b;return b.protocol===uc.protocol&&b.host===uc.host}function Cd(){this.$get=aa(W)}function vc(b){function a(d,e){if(T(d)){var f={};q(d,function(b,c){f[c]=a(c,b)});return f}return b.factory(d+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+
|
a.$$postDigestQueue=this.$$postDigestQueue):(this.$$ChildScope||(this.$$ChildScope=function(){this.$$watchers=this.$$nextSibling=this.$$childHead=this.$$childTail=null;this.$$listeners={};this.$$listenerCount={};this.$id=++bb;this.$$ChildScope=null},this.$$ChildScope.prototype=this),a=new this.$$ChildScope);a["this"]=a;a.$parent=this;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,
|
||||||
c)}}];a("currency",wc);a("date",xc);a("filter",Dd);a("json",Ed);a("limitTo",Fd);a("lowercase",Gd);a("number",yc);a("orderBy",zc);a("uppercase",Hd)}function Dd(){return function(b,a,c){if(!J(b))return b;var d=typeof c,e=[];e.check=function(a){for(var b=0;b<e.length;b++)if(!e[b](a))return!1;return!0};"function"!==d&&(c="boolean"===d&&c?function(a,b){return bb.equals(a,b)}:function(a,b){b=(""+b).toLowerCase();return-1<(""+a).toLowerCase().indexOf(b)});var f=function(a,b){if("string"==typeof b&&"!"===
|
d){var e=g(a);if(e.$$watchDelegate)return e.$$watchDelegate(this,b,d,e);var f=this.$$watchers,h={fn:b,last:p,get:e,exp:a,eq:!!d};c=null;D(b)||(h.fn=w);f||(f=this.$$watchers=[]);f.unshift(h);return function(){Ra(f,h);c=null}},$watchGroup:function(a,b){function c(){g=!1;k?(k=!1,b(e,e,h)):b(e,d,h)}var d=Array(a.length),e=Array(a.length),f=[],h=this,g=!1,k=!0;if(!a.length){var m=!0;h.$evalAsync(function(){m&&b(e,e,h)});return function(){m=!1}}if(1===a.length)return this.$watch(a[0],function(a,c,f){e[0]=
|
||||||
b.charAt(0))return!f(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return c(a,b);case "object":switch(typeof b){case "object":return c(a,b);default:for(var d in a)if("$"!==d.charAt(0)&&f(a[d],b))return!0}return!1;case "array":for(d=0;d<a.length;d++)if(f(a[d],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a={$:a};case "object":for(var g in a)"$"==g?function(){if(a[g]){var b=g;e.push(function(c){return f(c,a[b])})}}():
|
a;d[0]=c;b(e,a===c?e:d,f)});r(a,function(a,b){var k=h.$watch(a,function(a,f){e[b]=a;d[b]=f;g||(g=!0,h.$evalAsync(c))});f.push(k)});return function(){for(;f.length;)f.shift()()}},$watchCollection:function(a,b){var c=this,d,e,f,h=1<b.length,k=0,m=g(a,function(a){d=a;var b,c,f,h;if(S(d))if(Na(d))for(e!==l&&(e=l,q=e.length=0,k++),a=d.length,q!==a&&(k++,e.length=q=a),b=0;b<a;b++)h=e[b],f=d[b],c=h!==h&&f!==f,c||h===f||(k++,e[b]=f);else{e!==n&&(e=n={},q=0,k++);a=0;for(b in d)d.hasOwnProperty(b)&&(a++,f=
|
||||||
function(){if("undefined"!=typeof a[g]){var b=g;e.push(function(c){return f(ub(c,b),a[b])})}}();break;case "function":e.push(a);break;default:return b}for(var d=[],h=0;h<b.length;h++){var m=b[h];e.check(m)&&d.push(m)}return d}}function wc(b){var a=b.NUMBER_FORMATS;return function(b,d){x(d)&&(d=a.CURRENCY_SYM);return Ac(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function yc(b){var a=b.NUMBER_FORMATS;return function(b,d){return Ac(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}
|
d[b],h=e[b],b in e?(c=h!==h&&f!==f,c||h===f||(k++,e[b]=f)):(q++,e[b]=f,k++));if(q>a)for(b in k++,e)d.hasOwnProperty(b)||(q--,delete e[b])}else e!==d&&(e=d,k++);return k}),l=[],n={},p=!0,q=0;return this.$watch(m,function(){p?(p=!1,b(d,d,c)):b(d,f,c);if(h)if(S(d))if(Na(d)){f=Array(d.length);for(var a=0;a<d.length;a++)f[a]=d[a]}else for(a in f={},d)Ab.call(d,a)&&(f[a]=d[a]);else f=d})},$digest:function(){var e,g,m,n,q=this.$$asyncQueue,r=this.$$postDigestQueue,s,B,J=b,N,M=[],O,H,W;k("$digest");h.$$checkUrlChange();
|
||||||
function Ac(b,a,c,d,e){if(isNaN(b)||!isFinite(b))return"";var f=0>b;b=Math.abs(b);var g=b+"",h="",m=[],k=!1;if(-1!==g.indexOf("e")){var l=g.match(/([\d\.]+)e(-?)(\d+)/);l&&"-"==l[2]&&l[3]>e+1?g="0":(h=g,k=!0)}if(k)0<e&&(-1<b&&1>b)&&(h=b.toFixed(e));else{g=(g.split(Bc)[1]||"").length;x(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));g=Math.pow(10,e);b=Math.round(b*g)/g;b=(""+b).split(Bc);g=b[0];b=b[1]||"";var l=0,n=a.lgSize,r=a.gSize;if(g.length>=n+r)for(l=g.length-n,k=0;k<l;k++)0===(l-k)%r&&0!==
|
this===A&&null!==d&&(h.defer.cancel(d),l());c=null;do{B=!1;for(N=this;q.length;){try{W=q.shift(),W.scope.$eval(W.expression)}catch(R){f(R)}c=null}a:do{if(n=N.$$watchers)for(s=n.length;s--;)try{if(e=n[s])if((g=e.get(N))!==(m=e.last)&&!(e.eq?ra(g,m):"number"===typeof g&&"number"===typeof m&&isNaN(g)&&isNaN(m)))B=!0,c=e,e.last=e.eq?Ha(g,null):g,e.fn(g,m===p?g:m,N),5>J&&(O=4-J,M[O]||(M[O]=[]),H=D(e.exp)?"fn: "+(e.exp.name||e.exp.toString()):e.exp,H+="; newVal: "+sa(g)+"; oldVal: "+sa(m),M[O].push(H));
|
||||||
k&&(h+=c),h+=g.charAt(k);for(k=l;k<g.length;k++)0===(g.length-k)%n&&0!==k&&(h+=c),h+=g.charAt(k);for(;b.length<e;)b+="0";e&&"0"!==e&&(h+=d+b.substr(0,e))}m.push(f?a.negPre:a.posPre);m.push(h);m.push(f?a.negSuf:a.posSuf);return m.join("")}function Kb(b,a,c){var d="";0>b&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function V(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(0<c||e>-c)e+=c;0===e&&-12==c&&(e=12);return Kb(e,a,d)}}function jb(b,a){return function(c,
|
else if(e===c){B=!1;break a}}catch(t){f(t)}if(!(n=N.$$childHead||N!==this&&N.$$nextSibling))for(;N!==this&&!(n=N.$$nextSibling);)N=N.$parent}while(N=n);if((B||q.length)&&!J--)throw A.$$phase=null,a("infdig",b,sa(M));}while(B||q.length);for(A.$$phase=null;r.length;)try{r.shift()()}catch(G){f(G)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(this!==A){for(var b in this.$$listenerCount)n(this,this.$$listenerCount[b],b);a.$$childHead==
|
||||||
d){var e=c["get"+b](),f=Ga(a?"SHORT"+b:b);return d[f][e]}}function xc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));h.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;h=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
|
this&&(a.$$childHead=this.$$nextSibling);a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null;this.$$listeners={};this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[];this.$destroy=this.$digest=this.$apply=w;this.$on=this.$watch=this.$watchGroup=
|
||||||
return function(c,e){var f="",g=[],h,m;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;D(c)&&(c=Id.test(c)?U(c):a(c));qb(c)&&(c=new Date(c));if(!Ja(c))return c;for(;e;)(m=Jd.exec(e))?(g=g.concat(ta.call(m,1)),e=g.pop()):(g.push(e),e=null);q(g,function(a){h=Kd[a];f+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function Ed(){return function(b){return ma(b,!0)}}function Fd(){return function(b,a){if(!J(b)&&!D(b))return b;a=U(a);if(D(b))return a?0<=a?b.slice(0,a):b.slice(a,
|
function(){return w}}}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){A.$$phase||A.$$asyncQueue.length||h.defer(function(){A.$$asyncQueue.length&&A.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return k("$apply"),this.$eval(a)}catch(b){f(b)}finally{A.$$phase=null;try{A.$digest()}catch(c){throw f(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&A.$$applyAsyncQueue.push(b);
|
||||||
b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0<a?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function zc(b){return function(a,c,d){function e(a,b){return Na(b)?function(b,c){return a(c,b)}:a}if(!J(a)||!c)return a;c=J(c)?c:[c];c=Lc(c,function(a){var c=!1,d=a||za;if(D(a)){if("+"==a.charAt(0)||"-"==a.charAt(0))c="-"==a.charAt(0),a=a.substring(1);d=b(a)}return e(function(a,b){var c;c=d(a);var e=d(b),f=typeof c,g=typeof e;f==g?("string"==f&&(c=
|
q()},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){c[c.indexOf(b)]=null;n(e,1,a)}},$emit:function(a,b){var c=[],d,e=this,h=!1,g={name:a,targetScope:e,stopPropagation:function(){h=!0},preventDefault:function(){g.defaultPrevented=!0},defaultPrevented:!1},k=db([g],arguments,1),m,l;do{d=e.$$listeners[a]||c;g.currentScope=e;m=0;for(l=
|
||||||
c.toLowerCase(),e=e.toLowerCase()),c=c===e?0:c<e?-1:1):c=f<g?-1:1;return c},c)});for(var f=[],g=0;g<a.length;g++)f.push(a[g]);return f.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function sa(b){B(b)&&(b={link:b});b.restrict=b.restrict||"AC";return aa(b)}function Cc(b,a){function c(a,c){c=c?"-"+cb(c,"-"):"";b.removeClass((a?kb:lb)+c).addClass((a?lb:kb)+c)}var d=this,e=b.parent().controller("form")||mb,f=0,g=d.$error={},h=[];d.$name=a.name||a.ngForm;
|
d.length;m<l;m++)if(d[m])try{d[m].apply(null,k)}catch(n){f(n)}else d.splice(m,1),m--,l--;if(h)return g.currentScope=null,g;e=e.$parent}while(e);g.currentScope=null;return g},$broadcast:function(a,b){var c=this,d=this,e={name:a,targetScope:this,preventDefault:function(){e.defaultPrevented=!0},defaultPrevented:!1};if(!this.$$listenerCount[a])return e;for(var h=db([e],arguments,1),g,k;c=d;){e.currentScope=c;d=c.$$listeners[a]||[];g=0;for(k=d.length;g<k;g++)if(d[g])try{d[g].apply(null,h)}catch(m){f(m)}else d.splice(g,
|
||||||
d.$dirty=!1;d.$pristine=!0;d.$valid=!0;d.$invalid=!1;e.$addControl(d);b.addClass(Ha);c(!0);d.$addControl=function(a){na(a.$name,"input");h.push(a);a.$name&&(d[a.$name]=a)};d.$removeControl=function(a){a.$name&&d[a.$name]===a&&delete d[a.$name];q(g,function(b,c){d.$setValidity(c,!0,a)});La(h,a)};d.$setValidity=function(a,b,h){var n=g[a];if(b)n&&(La(n,h),n.length||(f--,f||(c(b),d.$valid=!0,d.$invalid=!1),g[a]=!1,c(!0,a),e.$setValidity(a,!0,d)));else{f||c(b);if(n){if(-1!=ab(n,h))return}else g[a]=n=[],
|
1),g--,k--;if(!(d=c.$$listenerCount[a]&&c.$$childHead||c!==this&&c.$$nextSibling))for(;c!==this&&!(d=c.$$nextSibling);)c=c.$parent}e.currentScope=null;return e}};var A=new m;return A}]}function Ed(){var b=/^\s*(https?|ftp|mailto|tel|file):/,a=/^\s*((https?|ftp|file|blob):|data:image\/)/;this.aHrefSanitizationWhitelist=function(a){return B(a)?(b=a,this):b};this.imgSrcSanitizationWhitelist=function(b){return B(b)?(a=b,this):a};this.$get=function(){return function(c,d){var e=d?a:b,f;if(!X||8<=X)if(f=
|
||||||
f++,c(!1,a),e.$setValidity(a,!1,d);n.push(h);d.$valid=!1;d.$invalid=!0}};d.$setDirty=function(){b.removeClass(Ha).addClass(nb);d.$dirty=!0;d.$pristine=!1;e.$setDirty()};d.$setPristine=function(){b.removeClass(nb).addClass(Ha);d.$dirty=!1;d.$pristine=!0;q(h,function(a){a.$setPristine()})}}function ob(b,a,c,d,e,f){var g=function(){var e=a.val();Na(c.ngTrim||"T")&&(e=Y(e));d.$viewValue!==e&&b.$apply(function(){d.$setViewValue(e)})};if(e.hasEvent("input"))a.on("input",g);else{var h,m=function(){h||(h=
|
Aa(c).href,""!==f&&!f.match(e))return"unsafe:"+f;return c}}}function ef(b){if("self"===b)return b;if(C(b)){if(-1<b.indexOf("***"))throw Ca("iwcard",b);b=b.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08").replace("\\*\\*",".*").replace("\\*","[^:/.?&;]*");return new RegExp("^"+b+"$")}if(cb(b))return new RegExp("^"+b.source+"$");throw Ca("imatcher");}function Sc(b){var a=[];B(b)&&r(b,function(b){a.push(ef(b))});return a}function Fe(){this.SCE_CONTEXTS=ka;var b=["self"],a=[];
|
||||||
f.defer(function(){g();h=null}))};a.on("keydown",function(a){a=a.keyCode;91===a||(15<a&&19>a||37<=a&&40>=a)||m()});a.on("change",g);if(e.hasEvent("paste"))a.on("paste cut",m)}d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var k=c.ngPattern,l=function(a,b){if(d.$isEmpty(b)||a.test(b))return d.$setValidity("pattern",!0),b;d.$setValidity("pattern",!1);return s};k&&((e=k.match(/^\/(.*)\/([gim]*)$/))?(k=RegExp(e[1],e[2]),e=function(a){return l(k,a)}):e=function(c){var d=b.$eval(k);
|
this.resourceUrlWhitelist=function(a){arguments.length&&(b=Sc(a));return b};this.resourceUrlBlacklist=function(b){arguments.length&&(a=Sc(b));return a};this.$get=["$injector",function(c){function d(a,b){return"self"===a?Ic(b):!!a.exec(b.href)}function e(a){var b=function(a){this.$$unwrapTrustedValue=function(){return a}};a&&(b.prototype=new a);b.prototype.valueOf=function(){return this.$$unwrapTrustedValue()};b.prototype.toString=function(){return this.$$unwrapTrustedValue().toString()};return b}
|
||||||
if(!d||!d.test)throw L("ngPattern")("noregexp",k,d,ea(a));return l(d,c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var n=U(c.ngMinlength);e=function(a){if(!d.$isEmpty(a)&&a.length<n)return d.$setValidity("minlength",!1),s;d.$setValidity("minlength",!0);return a};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var r=U(c.ngMaxlength);e=function(a){if(!d.$isEmpty(a)&&a.length>r)return d.$setValidity("maxlength",!1),s;d.$setValidity("maxlength",!0);return a};d.$parsers.push(e);
|
var f=function(a){throw Ca("unsafe");};c.has("$sanitize")&&(f=c.get("$sanitize"));var g=e(),h={};h[ka.HTML]=e(g);h[ka.CSS]=e(g);h[ka.URL]=e(g);h[ka.JS]=e(g);h[ka.RESOURCE_URL]=e(h[ka.URL]);return{trustAs:function(a,b){var c=h.hasOwnProperty(a)?h[a]:null;if(!c)throw Ca("icontext",a,b);if(null===b||b===s||""===b)return b;if("string"!==typeof b)throw Ca("itype",a);return new c(b)},getTrusted:function(c,e){if(null===e||e===s||""===e)return e;var g=h.hasOwnProperty(c)?h[c]:null;if(g&&e instanceof g)return e.$$unwrapTrustedValue();
|
||||||
d.$formatters.push(e)}}function Lb(b,a){b="ngClass"+b;return function(){return{restrict:"AC",link:function(c,d,e){function f(b){if(!0===a||c.$index%2===a)h&&!Aa(b,h)&&e.$removeClass(g(h)),e.$addClass(g(b));h=da(b)}function g(a){if(J(a))return a.join(" ");if(T(a)){var b=[];q(a,function(a,c){a&&b.push(c)});return b.join(" ")}return a}var h;c.$watch(e[b],f,!0);e.$observe("class",function(a){f(c.$eval(e[b]))});"ngClass"!==b&&c.$watch("$index",function(d,f){var h=d&1;h!==f&1&&(h===a?(h=c.$eval(e[b]),e.$addClass(g(h))):
|
if(c===ka.RESOURCE_URL){var g=Aa(e.toString()),p,l,q=!1;p=0;for(l=b.length;p<l;p++)if(d(b[p],g)){q=!0;break}if(q)for(p=0,l=a.length;p<l;p++)if(d(a[p],g)){q=!1;break}if(q)return e;throw Ca("insecurl",e.toString());}if(c===ka.HTML)return f(e);throw Ca("unsafe");},valueOf:function(a){return a instanceof g?a.$$unwrapTrustedValue():a}}}]}function Ee(){var b=!0;this.enabled=function(a){arguments.length&&(b=!!a);return b};this.$get=["$parse","$sniffer","$sceDelegate",function(a,c,d){if(b&&c.msie&&8>c.msieDocumentMode)throw Ca("iequirks");
|
||||||
(h=c.$eval(e[b]),e.$removeClass(g(h))))})}}}}var w=function(b){return D(b)?b.toLowerCase():b},Ga=function(b){return D(b)?b.toUpperCase():b},P,y,Ba,ta=[].slice,Ld=[].push,Ka=Object.prototype.toString,Ma=L("ng"),bb=W.angular||(W.angular={}),Ua,Ea,ia=["0","0","0"];P=U((/msie (\d+)/.exec(w(navigator.userAgent))||[])[1]);isNaN(P)&&(P=U((/trident\/.*; rv:(\d+)/.exec(w(navigator.userAgent))||[])[1]));t.$inject=[];za.$inject=[];var Y=function(){return String.prototype.trim?function(b){return D(b)?b.trim():
|
var e=qa(ka);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Pa);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:a(c,function(a){return e.getTrusted(b,a)})};var f=e.parseAs,g=e.getTrusted,h=e.trustAs;r(ka,function(a,b){var c=P(b);e[Wa("parse_as_"+c)]=function(b){return f(a,b)};e[Wa("get_trusted_"+c)]=function(b){return g(a,b)};e[Wa("trust_as_"+c)]=function(b){return h(a,
|
||||||
b}:function(b){return D(b)?b.replace(/^\s*/,"").replace(/\s*$/,""):b}}();Ea=9>P?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ga(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Pc=/[A-Z]/g,Md={full:"1.2.0",major:1,minor:"NG_VERSION_MINOR",dot:0,codeName:"timely-delivery"},Ra=Q.cache={},db=Q.expando="ng-"+(new Date).getTime(),Tc=1,Dc=W.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+
|
b)}});return e}]}function Ge(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(P((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g=f.documentMode,h,m=/^(Moz|webkit|O|ms)(?=[A-Z])/,k=f.body&&f.body.style,n=!1,p=!1;if(k){for(var l in k)if(n=m.exec(l)){h=n[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in k&&"webkit");n=!!("transition"in k||h+"Transition"in k);p=!!("animation"in k||h+"Animation"in
|
||||||
a,c)},Ab=W.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},Rc=/([\:\-\_]+(.))/g,Sc=/^moz([A-Z])/,xb=L("jqLite"),Da=Q.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===O.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),Q(W).on("load",a))},toString:function(){var b=[];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?y(this[b]):y(this[this.length+b])},length:0,
|
k);!d||n&&p||(n=C(f.body.style.webkitTransition),p=C(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7<g),hasEvent:function(a){if("input"==a&&9==X)return!1;if(F(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Ua(),vendorPrefix:h,transitions:n,animations:p,android:d,msie:X,msieDocumentMode:g}}]}function Ie(){this.$get=["$templateCache","$http","$q",function(b,a,c){function d(e,f){function g(){h.totalPendingRequests--;
|
||||||
push:Ld,sort:[].sort,splice:[].splice},fb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){fb[w(b)]=b});var cc={};q("input select option textarea button form details".split(" "),function(b){cc[Ga(b)]=!0});q({data:$b,inheritedData:eb,scope:function(b){return y(b).data("$scope")||eb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return y(b).data("$isolateScope")||y(b).data("$isolateScopeNoTemplate")},controller:ac,injector:function(b){return eb(b,
|
if(!f)throw ja("tpload",e);return c.reject()}var h=d;h.totalPendingRequests++;return a.get(e,{cache:b}).then(function(a){a=a.data;if(!a||0===a.length)return g();h.totalPendingRequests--;b.put(e,a);return a},g)}d.totalPendingRequests=0;return d}]}function Je(){this.$get=["$rootScope","$browser","$location",function(b,a,c){return{findBindings:function(a,b,c){a=a.getElementsByClassName("ng-binding");var g=[];r(a,function(a){var d=Ea.element(a).data("$binding");d&&r(d,function(d){c?(new RegExp("(^|\\s)"+
|
||||||
"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Bb,css:function(b,a,c){a=Pa(a);if(z(c))b.style[a]=c;else{var d;8>=P&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=P&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=w(a);if(fb[d])if(z(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||t).specified?d:s;else if(z(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,
|
b+"(\\s|\\||$)")).test(d)&&g.push(a):-1!=d.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b,c){for(var g=["ng-","data-ng-","ng\\:"],h=0;h<g.length;++h){var m=a.querySelectorAll("["+g[h]+"model"+(c?"=":"*=")+'"'+b+'"]');if(m.length)return m}},getLocation:function(){return c.url()},setLocation:function(a){a!==c.url()&&(c.url(a),b.$digest())},whenStable:function(b){a.notifyWhenNoOutstandingRequests(b)}}}]}function Ke(){this.$get=["$rootScope","$browser","$q","$$q","$exceptionHandler",function(b,
|
||||||
2),null===b?s:b},prop:function(b,a,c){if(z(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(x(d))return e?b[e]:"";b[e]=d}var a=[];9>P?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(x(a)){if("SELECT"===Ea(b)&&b.multiple){var c=[];q(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(x(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<
|
a,c,d,e){function f(f,m,k){var n=B(k)&&!k,p=(n?d:c).defer(),l=p.promise;m=a.defer(function(){try{p.resolve(f())}catch(a){p.reject(a),e(a)}finally{delete g[l.$$timeoutId]}n||b.$apply()},m);l.$$timeoutId=m;g[m]=p;return l}var g={};f.cancel=function(b){return b&&b.$$timeoutId in g?(g[b.$$timeoutId].reject("canceled"),delete g[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return f}]}function Aa(b,a){var c=b;X&&(Z.setAttribute("href",c),c=Z.href);Z.setAttribute("href",c);return{href:Z.href,protocol:Z.protocol?
|
||||||
d.length;c++)Qa(d[c]);b.innerHTML=a}},function(b,a){Q.prototype[a]=function(a,d){var e,f;if((2==b.length&&b!==Bb&&b!==ac?a:d)===s){if(T(a)){for(e=0;e<this.length;e++)if(b===$b)b(this[e],a);else for(f in a)b(this[e],f,a[f]);return this}e=b.$dv;f=e===s?Math.min(this.length,1):this.length;for(var g=0;g<f;g++){var h=b(this[g],a,d);e=e?e+h:h}return e}for(e=0;e<this.length;e++)b(this[e],a,d);return this}});q({removeData:Yb,dealoc:Qa,on:function a(c,d,e,f){if(z(f))throw xb("onargs");var g=ja(c,"events"),
|
Z.protocol.replace(/:$/,""):"",host:Z.host,search:Z.search?Z.search.replace(/^\?/,""):"",hash:Z.hash?Z.hash.replace(/^#/,""):"",hostname:Z.hostname,port:Z.port,pathname:"/"===Z.pathname.charAt(0)?Z.pathname:"/"+Z.pathname}}function Ic(b){b=C(b)?Aa(b):b;return b.protocol===Tc.protocol&&b.host===Tc.host}function Le(){this.$get=da(t)}function qc(b){function a(c,d){if(S(c)){var e={};r(c,function(b,c){e[c]=a(c,b)});return e}return b.factory(c+"Filter",d)}this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+
|
||||||
h=ja(c,"handle");g||ja(c,"events",g={});h||ja(c,"handle",h=Uc(c,g));q(d.split(" "),function(d){var f=g[d];if(!f){if("mouseenter"==d||"mouseleave"==d){var l=O.body.contains||O.body.compareDocumentPosition?function(a,c){var d=9===a.nodeType?a.documentElement:a,e=c&&c.parentNode;return a===e||!!(e&&1===e.nodeType&&(d.contains?d.contains(e):a.compareDocumentPosition&&a.compareDocumentPosition(e)&16))}:function(a,c){if(c)for(;c=c.parentNode;)if(c===a)return!0;return!1};g[d]=[];a(c,{mouseleave:"mouseout",
|
"Filter")}}];a("currency",Uc);a("date",Vc);a("filter",ff);a("json",gf);a("limitTo",hf);a("lowercase",jf);a("number",Wc);a("orderBy",Xc);a("uppercase",kf)}function ff(){return function(b,a,c){if(!L(b))return b;var d=typeof c,e=[];e.check=function(a,b){for(var c=0;c<e.length;c++)if(!e[c](a,b))return!1;return!0};"function"!==d&&(c="boolean"===d&&c?function(a,b){return Ea.equals(a,b)}:function(a,b){if(a&&b&&"object"===typeof a&&"object"===typeof b){for(var d in a)if("$"!==d.charAt(0)&&Ab.call(a,d)&&c(a[d],
|
||||||
mouseenter:"mouseover"}[d],function(a){var c=a.relatedTarget;c&&(c===this||l(this,c))||h(a,d)})}else Dc(c,d,h),g[d]=[];f=g[d]}f.push(e)})},off:Zb,replaceWith:function(a,c){var d,e=a.parentNode;Qa(a);q(new Q(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];q(a.childNodes,function(a){1===a.nodeType&&c.push(a)});return c},contents:function(a){return a.childNodes||[]},append:function(a,c){q(new Q(c),function(c){1!==a.nodeType&&11!==a.nodeType||
|
b[d]))return!0;return!1}b=(""+b).toLowerCase();return-1<(""+a).toLowerCase().indexOf(b)});var f=function(a,b){if("string"==typeof b&&"!"===b.charAt(0))return!f(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return c(a,b);case "object":switch(typeof b){case "object":return c(a,b);default:for(var d in a)if("$"!==d.charAt(0)&&f(a[d],b))return!0}return!1;case "array":for(d=0;d<a.length;d++)if(f(a[d],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a=
|
||||||
a.appendChild(c)})},prepend:function(a,c){if(1===a.nodeType){var d=a.firstChild;q(new Q(c),function(c){a.insertBefore(c,d)})}},wrap:function(a,c){c=y(c)[0];var d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){Qa(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;q(new Q(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:Db,removeClass:Cb,toggleClass:function(a,c,d){x(d)&&(d=!Bb(a,c));(d?Db:Cb)(a,c)},parent:function(a){return(a=
|
{$:a};case "object":for(var g in a)(function(b){"undefined"!==typeof a[b]&&e.push(function(c){return f("$"==b?c:c&&c[b],a[b])})})(g);break;case "function":e.push(a);break;default:return b}d=[];for(g=0;g<b.length;g++){var h=b[g];e.check(h,g)&&d.push(h)}return d}}function Uc(b){var a=b.NUMBER_FORMATS;return function(b,d){F(d)&&(d=a.CURRENCY_SYM);return null==b?b:Yc(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function Wc(b){var a=b.NUMBER_FORMATS;return function(b,d){return null==
|
||||||
a.parentNode)&&11!==a.nodeType?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;for(a=a.nextSibling;null!=a&&1!==a.nodeType;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName(c)},clone:zb,triggerHandler:function(a,c,d){c=(ja(a,"events")||{})[c];d=d||[];var e=[{preventDefault:t,stopPropagation:t}];q(c,function(c){c.apply(a,e.concat(d))})}},function(a,c){Q.prototype[c]=function(c,e,f){for(var g,h=0;h<this.length;h++)x(g)?(g=a(this[h],c,e,f),z(g)&&
|
b?b:Yc(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Yc(b,a,c,d,e){if(!isFinite(b)||S(b))return"";var f=0>b;b=Math.abs(b);var g=b+"",h="",m=[],k=!1;if(-1!==g.indexOf("e")){var n=g.match(/([\d\.]+)e(-?)(\d+)/);n&&"-"==n[2]&&n[3]>e+1?(g="0",b=0):(h=g,k=!0)}if(k)0<e&&-1<b&&1>b&&(h=b.toFixed(e));else{g=(g.split(Zc)[1]||"").length;F(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(Zc);g=b[0];b=b[1]||"";var n=
|
||||||
(g=y(g))):yb(g,a(this[h],c,e,f));return z(g)?g:this};Q.prototype.bind=Q.prototype.on;Q.prototype.unbind=Q.prototype.off});Sa.prototype={put:function(a,c){this[Ca(a)]=c},get:function(a){return this[Ca(a)]},remove:function(a){var c=this[a=Ca(a)];delete this[a];return c}};var Wc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,Xc=/,/,Yc=/^\s*(_?)(\S+?)\1\s*$/,Vc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,Ta=L("$injector"),Nd=L("$animate"),Od=["$provide",function(a){this.$$selectors={};this.register=function(c,d){var e=
|
0,p=a.lgSize,l=a.gSize;if(g.length>=p+l)for(n=g.length-p,k=0;k<n;k++)0===(n-k)%l&&0!==k&&(h+=c),h+=g.charAt(k);for(k=n;k<g.length;k++)0===(g.length-k)%p&&0!==k&&(h+=c),h+=g.charAt(k);for(;b.length<e;)b+="0";e&&"0"!==e&&(h+=d+b.substr(0,e))}m.push(f?a.negPre:a.posPre);m.push(h);m.push(f?a.negSuf:a.posSuf);return m.join("")}function vb(b,a,c){var d="";0>b&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function $(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();
|
||||||
c+"-animation";if(c&&"."!=c.charAt(0))throw Nd("notcsel",c);this.$$selectors[c.substr(1)]=e;a.factory(e,d)};this.$get=["$timeout",function(a){return{enter:function(d,e,f,g){f=f&&f[f.length-1];var h=e&&e[0]||f&&f.parentNode,m=f&&f.nextSibling||null;q(d,function(a){h.insertBefore(a,m)});g&&a(g,0,!1)},leave:function(d,e){d.remove();e&&a(e,0,!1)},move:function(a,c,f,g){this.enter(a,c,f,g)},addClass:function(d,e,f){e=D(e)?e:J(e)?e.join(" "):"";q(d,function(a){Db(a,e)});f&&a(f,0,!1)},removeClass:function(d,
|
if(0<c||e>-c)e+=c;0===e&&-12==c&&(e=12);return vb(e,a,d)}}function wb(b,a){return function(c,d){var e=c["get"+b](),f=ib(a?"SHORT"+b:b);return d[f][e]}}function $c(b){var a=(new Date(b,0,1)).getDay();return new Date(b,0,(4>=a?5:12)-a)}function ad(b){return function(a){var c=$c(a.getFullYear());a=+new Date(a.getFullYear(),a.getMonth(),a.getDate()+(4-a.getDay()))-+c;a=1+Math.round(a/6048E5);return vb(a,b)}}function Vc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:
|
||||||
e,f){e=D(e)?e:J(e)?e.join(" "):"";q(d,function(a){Cb(a,e)});f&&a(f,0,!1)},enabled:t}}]}],fa=L("$compile");ec.$inject=["$provide"];var fd=/^(x[\:\-_]|data[\:\-_])/i,md=W.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw L("$httpBackend")("noxhr");},jc=L("$interpolate"),Pd=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,qd={http:80,https:443,ftp:21},Gb=
|
a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));h.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;h=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e,f){var g="",h=[],m,k;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;C(c)&&(c=lf.test(c)?U(c):a(c));ea(c)&&(c=new Date(c));if(!fa(c))return c;
|
||||||
L("$location");oc.prototype=Hb.prototype=nc.prototype={$$html5:!1,$$replace:!1,absUrl:hb("$$absUrl"),url:function(a,c){if(x(a))return this.$$url;var d=Pd.exec(a);d[1]&&this.path(decodeURIComponent(d[1]));(d[2]||d[1])&&this.search(d[3]||"");this.hash(d[5]||"",c);return this},protocol:hb("$$protocol"),host:hb("$$host"),port:hb("$$port"),path:pc("$$path",function(a){return"/"==a.charAt(0)?a:"/"+a}),search:function(a,c){switch(arguments.length){case 0:return this.$$search;case 1:if(D(a))this.$$search=
|
for(;e;)(k=mf.exec(e))?(h=db(h,k,1),e=h.pop()):(h.push(e),e=null);f&&"UTC"===f&&(c=new Date(c.getTime()),c.setMinutes(c.getMinutes()+c.getTimezoneOffset()));r(h,function(a){m=nf[a];g+=m?m(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function gf(){return function(b){return sa(b,!0)}}function hf(){return function(b,a){if(!L(b)&&!C(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):U(a);if(C(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?
|
||||||
Ub(a);else if(T(a))this.$$search=a;else throw Gb("isrcharg");break;default:x(c)||null===c?delete this.$$search[a]:this.$$search[a]=c}this.$$compose();return this},hash:pc("$$hash",za),replace:function(){this.$$replace=!0;return this}};var pa=L("$parse"),sc={},qa,Ia={"null":function(){return null},"true":function(){return!0},"false":function(){return!1},undefined:t,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return z(d)?z(e)?d+e:d:z(e)?e:s},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(z(d)?d:0)-(z(e)?
|
a=b.length:a<-b.length&&(a=-b.length);0<a?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Xc(b){return function(a,c,d){function e(a,b){return b?function(b,c){return a(c,b)}:a}function f(a,b){var c=typeof a,d=typeof b;return c==d?(fa(a)&&fa(b)&&(a=a.valueOf(),b=b.valueOf()),"string"==c&&(a=a.toLowerCase(),b=b.toLowerCase()),a===b?0:a<b?-1:1):c<d?-1:1}if(!Na(a)||!c)return a;c=L(c)?c:[c];c=sd(c,function(a){var c=!1,d=a||Pa;if(C(a)){if("+"==a.charAt(0)||"-"==a.charAt(0))c=
|
||||||
e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":t,"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=
|
"-"==a.charAt(0),a=a.substring(1);d=b(a);if(d.constant){var h=d();return e(function(a,b){return f(a[h],b[h])},c)}}return e(function(a,b){return f(d(a),d(b))},c)});for(var g=[],h=0;h<a.length;h++)g.push(a[h]);return g.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function Fa(b){D(b)&&(b={link:b});b.restrict=b.restrict||"AC";return da(b)}function bd(b,a,c,d){var e=this,f=b.parent().controller("form")||xb,g=[];e.$error={};e.$$success={};e.$pending=
|
||||||
e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Qd={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},Jb=function(a){this.options=a};Jb.prototype={constructor:Jb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";this.tokens=[];var c;for(a=[];this.index<this.text.length;){this.ch=
|
s;e.$name=a.name||a.ngForm;e.$dirty=!1;e.$pristine=!0;e.$valid=!0;e.$invalid=!1;e.$submitted=!1;f.$addControl(e);b.addClass(Ma);e.$rollbackViewValue=function(){r(g,function(a){a.$rollbackViewValue()})};e.$commitViewValue=function(){r(g,function(a){a.$commitViewValue()})};e.$addControl=function(a){Ja(a.$name,"input");g.push(a);a.$name&&(e[a.$name]=a)};e.$removeControl=function(a){a.$name&&e[a.$name]===a&&delete e[a.$name];r(e.$pending,function(b,c){e.$setValidity(c,null,a)});r(e.$error,function(b,
|
||||||
this.text.charAt(this.index);if(this.is("\"'"))this.readString(this.ch);else if(this.isNumber(this.ch)||this.is(".")&&this.isNumber(this.peek()))this.readNumber();else if(this.isIdent(this.ch))this.readIdent(),this.was("{,")&&("{"===a[0]&&(c=this.tokens[this.tokens.length-1]))&&(c.json=-1===c.text.indexOf("."));else if(this.is("(){}[].,;:?"))this.tokens.push({index:this.index,text:this.ch,json:this.was(":[,")&&this.is("{[")||this.is("}]:,")}),this.is("{[")&&a.unshift(this.ch),this.is("}]")&&a.shift(),
|
c){e.$setValidity(c,null,a)});Ra(g,a)};cd({ctrl:this,$element:b,set:function(a,b,c){var d=a[b];d?-1===d.indexOf(c)&&d.push(c):a[b]=[c]},unset:function(a,b,c){var d=a[b];d&&(Ra(d,c),0===d.length&&delete a[b])},parentForm:f,$animate:d});e.$setDirty=function(){d.removeClass(b,Ma);d.addClass(b,yb);e.$dirty=!0;e.$pristine=!1;f.$setDirty()};e.$setPristine=function(){d.setClass(b,Ma,yb+" ng-submitted");e.$dirty=!1;e.$pristine=!0;e.$submitted=!1;r(g,function(a){a.$setPristine()})};e.$setSubmitted=function(){d.addClass(b,
|
||||||
this.index++;else if(this.isWhitespace(this.ch)){this.index++;continue}else{var d=this.ch+this.peek(),e=d+this.peek(2),f=Ia[this.ch],g=Ia[d],h=Ia[e];h?(this.tokens.push({index:this.index,text:e,fn:h}),this.index+=3):g?(this.tokens.push({index:this.index,text:d,fn:g}),this.index+=2):f?(this.tokens.push({index:this.index,text:this.ch,fn:f,json:this.was("[,:")&&this.is("+-")}),this.index+=1):this.throwError("Unexpected next character ",this.index,this.index+1)}this.lastCh=this.ch}return this.tokens},
|
"ng-submitted");e.$submitted=!0;f.$setSubmitted()}}function Ub(b){b.$formatters.push(function(a){return b.$isEmpty(a)?a:a.toString()})}function $a(b,a,c,d,e,f){a.prop("validity");var g=a[0].placeholder,h={},m=P(a[0].type);if(!e.android){var k=!1;a.on("compositionstart",function(a){k=!0});a.on("compositionend",function(){k=!1;n()})}var n=function(b){if(!k){var e=a.val(),f=b&&b.type;X&&"input"===(b||h).type&&a[0].placeholder!==g?g=a[0].placeholder:("password"===m||c.ngTrim&&"false"===c.ngTrim||(e=ba(e)),
|
||||||
is:function(a){return-1!==a.indexOf(this.ch)},was:function(a){return-1!==a.indexOf(this.lastCh)},peek:function(a){a=a||1;return this.index+a<this.text.length?this.text.charAt(this.index+a):!1},isNumber:function(a){return"0"<=a&&"9">=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=
|
(d.$viewValue!==e||""===e&&d.$$hasNativeValidators)&&d.$setViewValue(e,f))}};if(e.hasEvent("input"))a.on("input",n);else{var p,l=function(a){p||(p=f.defer(function(){n(a);p=null}))};a.on("keydown",function(a){var b=a.keyCode;91===b||15<b&&19>b||37<=b&&40>=b||l(a)});if(e.hasEvent("paste"))a.on("paste cut",l)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)}}function zb(b,a){return function(c){var d;if(fa(c))return c;if(C(c)){'"'==c.charAt(0)&&'"'==c.charAt(c.length-
|
||||||
d||this.index;c=z(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw pa("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index<this.text.length;){var d=w(this.text.charAt(this.index));if("."==d||this.isNumber(d))a+=d;else{var e=this.peek();if("e"==d&&this.isExpOperator(e))a+=d;else if(this.isExpOperator(d)&&e&&this.isNumber(e)&&"e"==a.charAt(a.length-1))a+=d;else if(!this.isExpOperator(d)||e&&this.isNumber(e)||"e"!=a.charAt(a.length-1))break;else this.throwError("Invalid exponent")}this.index++}a*=
|
1)&&(c=c.substring(1,c.length-1));if(of.test(c))return new Date(c);b.lastIndex=0;if(c=b.exec(c))return c.shift(),d={yyyy:1970,MM:1,dd:1,HH:0,mm:0,ss:0},r(c,function(b,c){c<a.length&&(d[a[c]]=+b)}),new Date(d.yyyy,d.MM-1,d.dd,d.HH,d.mm,d.ss||0)}return NaN}}function ab(b,a,c,d){return function(e,f,g,h,m,k,n){function p(a){return B(a)?fa(a)?a:c(a):s}dd(e,f,g,h);$a(e,f,g,h,m,k);var l=h&&h.$options&&h.$options.timezone;h.$$parserName=b;h.$parsers.push(function(b){return h.$isEmpty(b)?null:a.test(b)?(b=
|
||||||
1;this.tokens.push({index:c,text:a,json:!0,fn:function(){return a}})},readIdent:function(){for(var a=this,c="",d=this.index,e,f,g,h;this.index<this.text.length;){h=this.text.charAt(this.index);if("."===h||this.isIdent(h)||this.isNumber(h))"."===h&&(e=this.index),c+=h;else break;this.index++}if(e)for(f=this.index;f<this.text.length;){h=this.text.charAt(f);if("("===h){g=c.substr(e-d+1);c=c.substr(0,e-d);this.index=f;break}if(this.isWhitespace(h))f++;else break}d={index:d,text:c};if(Ia.hasOwnProperty(c))d.fn=
|
c(b),"UTC"===l&&b.setMinutes(b.getMinutes()-b.getTimezoneOffset()),b):s});h.$formatters.push(function(a){return fa(a)?n("date")(a,d,l):""});if(B(g.min)||g.ngMin){var q;h.$validators.min=function(a){return h.$isEmpty(a)||F(q)||c(a)>=q};g.$observe("min",function(a){q=p(a);h.$validate()})}if(B(g.max)||g.ngMax){var r;h.$validators.max=function(a){return h.$isEmpty(a)||F(r)||c(a)<=r};g.$observe("max",function(a){r=p(a);h.$validate()})}}}function dd(b,a,c,d){(d.$$hasNativeValidators=S(a[0].validity))&&
|
||||||
Ia[c],d.json=Ia[c];else{var m=rc(c,this.options,this.text);d.fn=u(function(a,c){return m(a,c)},{assign:function(d,e){return ib(d,c,e,a.text,a.options)}})}this.tokens.push(d);g&&(this.tokens.push({index:e,text:".",json:!1}),this.tokens.push({index:e+1,text:g,json:!1}))},readString:function(a){var c=this.index;this.index++;for(var d="",e=a,f=!1;this.index<this.text.length;){var g=this.text.charAt(this.index),e=e+g;if(f)"u"===g?(g=this.text.substring(this.index+1,this.index+5),g.match(/[\da-f]{4}/i)||
|
d.$parsers.push(function(b){var c=a.prop("validity")||{};return c.badInput&&!c.typeMismatch?s:b})}function ed(b,a,c,d,e){if(B(d)){b=b(d);if(!b.constant)throw K("ngModel")("constexpr",c,d);return b(a)}return e}function cd(b){function a(a,b){b&&!f[a]?(k.addClass(e,a),f[a]=!0):!b&&f[a]&&(k.removeClass(e,a),f[a]=!1)}function c(b,c){b=b?"-"+Db(b,"-"):"";a(pf+b,!0===c);a(qf+b,!1===c)}var d=b.ctrl,e=b.$element,f={},g=b.set,h=b.unset,m=b.parentForm,k=b.$animate;d.$setValidity=function(b,e,f){e===s?(d.$pending||
|
||||||
this.throwError("Invalid unicode escape [\\u"+g+"]"),this.index+=4,d+=String.fromCharCode(parseInt(g,16))):d=(f=Qd[g])?d+f:d+g,f=!1;else if("\\"===g)f=!0;else{if(g===a){this.index++;this.tokens.push({index:c,text:e,string:d,json:!0,fn:function(){return d}});return}d+=g}this.index++}this.throwError("Unterminated quote",c)}};var Ya=function(a,c,d){this.lexer=a;this.$filter=c;this.options=d};Ya.ZERO=function(){return 0};Ya.prototype={constructor:Ya,parse:function(a,c){this.text=a;this.json=c;this.tokens=
|
(d.$pending={}),g(d.$pending,b,f)):(d.$pending&&h(d.$pending,b,f),fd(d.$pending)&&(d.$pending=s));"boolean"!==typeof e?(h(d.$error,b,f),h(d.$$success,b,f)):e?(h(d.$error,b,f),g(d.$$success,b,f)):(g(d.$error,b,f),h(d.$$success,b,f));d.$pending?(a(gd,!0),d.$valid=d.$invalid=s,c("",null)):(a(gd,!1),d.$valid=fd(d.$error),d.$invalid=!d.$valid,c("",d.$valid));e=d.$pending&&d.$pending[b]?s:d.$error[b]?!1:d.$$success[b]?!0:null;c(b,e);m.$setValidity(b,e,d)};c("",!0)}function fd(b){if(b)for(var a in b)return!1;
|
||||||
this.lexer.lex(a);c&&(this.assignment=this.logicalOR,this.functionCall=this.fieldAccess=this.objectIndex=this.filterChain=function(){this.throwError("is not valid json",{text:a,index:0})});var d=c?this.primary():this.statements();0!==this.tokens.length&&this.throwError("is an unexpected token",this.tokens[0]);d.literal=!!d.literal;d.constant=!!d.constant;return d},primary:function(){var a;if(this.expect("("))a=this.filterChain(),this.consume(")");else if(this.expect("["))a=this.arrayDeclaration();
|
return!0}function Vb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;d<a.length;d++){for(var e=a[d],n=0;n<b.length;n++)if(e==b[n])continue a;c.push(e)}return c}function e(a){if(!L(a)){if(C(a))return a.split(" ");if(S(a)){var b=[];r(a,function(a,c){a&&(b=b.concat(c.split(" ")))});return b}}return a}return{restrict:"AC",link:function(f,g,h){function m(a,b){var c=g.data("$classCounts")||{},d=[];r(a,function(a){if(0<b||c[a])c[a]=(c[a]||0)+b,c[a]===+(0<b)&&d.push(a)});
|
||||||
else if(this.expect("{"))a=this.object();else{var c=this.expect();(a=c.fn)||this.throwError("not a primary expression",c);c.json&&(a.constant=!0,a.literal=!0)}for(var d;c=this.expect("(","[",".");)"("===c.text?(a=this.functionCall(a,d),d=null):"["===c.text?(d=a,a=this.objectIndex(a)):"."===c.text?(d=a,a=this.fieldAccess(a)):this.throwError("IMPOSSIBLE");return a},throwError:function(a,c){throw pa("syntax",c.text,a,c.index+1,this.text,this.text.substring(c.index));},peekToken:function(){if(0===this.tokens.length)throw pa("ueoe",
|
g.data("$classCounts",c);return d.join(" ")}function k(b){if(!0===a||f.$index%2===a){var k=e(b||[]);if(!n){var q=m(k,1);h.$addClass(q)}else if(!ra(b,n)){var r=e(n),q=d(k,r),k=d(r,k),q=m(q,1),k=m(k,-1);q&&q.length&&c.addClass(g,q);k&&k.length&&c.removeClass(g,k)}}n=qa(b)}var n;f.$watch(h[b],k,!0);h.$observe("class",function(a){k(f.$eval(h[b]))});"ngClass"!==b&&f.$watch("$index",function(c,d){var g=c&1;if(g!==(d&1)){var k=e(f.$eval(h[b]));g===a?(g=m(k,1),h.$addClass(g)):(g=m(k,-1),h.$removeClass(g))}})}}}]}
|
||||||
this.text);return this.tokens[0]},peek:function(a,c,d,e){if(0<this.tokens.length){var f=this.tokens[0],g=f.text;if(g===a||g===c||g===d||g===e||!(a||c||d||e))return f}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.json&&!a.json&&this.throwError("is not valid json",a),this.tokens.shift(),a):!1},consume:function(a){this.expect(a)||this.throwError("is unexpected, expecting ["+a+"]",this.peek())},unaryFn:function(a,c){return u(function(d,e){return a(d,e,c)},{constant:c.constant})},
|
var rf=/^\/(.+)\/([a-z]*)$/,P=function(b){return C(b)?b.toLowerCase():b},Ab=Object.prototype.hasOwnProperty,ib=function(b){return C(b)?b.toUpperCase():b},X,G,la,Ta=[].slice,sf=[].push,Ga=Object.prototype.toString,Sa=K("ng"),Ea=t.angular||(t.angular={}),Va,bb=0;X=U((/msie (\d+)/.exec(P(navigator.userAgent))||[])[1]);isNaN(X)&&(X=U((/trident\/.*; rv:(\d+)/.exec(P(navigator.userAgent))||[])[1]));w.$inject=[];Pa.$inject=[];var L=Array.isArray,ba=function(b){return C(b)?b.trim():b},Ua=function(){if(B(Ua.isActive_))return Ua.isActive_;
|
||||||
ternaryFn:function(a,c,d){return u(function(e,f){return a(e,f)?c(e,f):d(e,f)},{constant:a.constant&&c.constant&&d.constant})},binaryFn:function(a,c,d){return u(function(e,f){return c(e,f,a,d)},{constant:a.constant&&d.constant})},statements:function(){for(var a=[];;)if(0<this.tokens.length&&!this.peek("}",")",";","]")&&a.push(this.filterChain()),!this.expect(";"))return 1===a.length?a[0]:function(c,d){for(var e,f=0;f<a.length;f++){var g=a[f];g&&(e=g(c,d))}return e}},filterChain:function(){for(var a=
|
var b=!(!Y.querySelector("[ng-csp]")&&!Y.querySelector("[data-ng-csp]"));if(!b)try{new Function("")}catch(a){b=!0}return Ua.isActive_=b},fb=["ng-","data-ng-","ng:","x-ng-"],yd=/[A-Z]/g,hc=!1,Eb,Cd={full:"1.3.0-rc.1",major:1,minor:3,dot:0,codeName:"backyard-atomicity"};V.expando="ng339";var ob=V.cache={},Te=1;V._data=function(b){return this.cache[b[this.expando]]||{}};var Oe=/([\:\-\_]+(.))/g,Pe=/^moz([A-Z])/,tf={mouseleave:"mouseout",mouseenter:"mouseover"},Hb=K("jqLite"),Se=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,
|
||||||
this.expression(),c;;)if(c=this.expect("|"))a=this.binaryFn(a,c.fn,this.filter());else return a},filter:function(){for(var a=this.expect(),c=this.$filter(a.text),d=[];;)if(a=this.expect(":"))d.push(this.expression());else{var e=function(a,e,h){h=[h];for(var m=0;m<d.length;m++)h.push(d[m](a,e));return c.apply(a,h)};return function(){return e}}},expression:function(){return this.assignment()},assignment:function(){var a=this.ternary(),c,d;return(d=this.expect("="))?(a.assign||this.throwError("implies assignment but ["+
|
Gb=/<|&#?\w+;/,Qe=/<([\w:]+)/,Re=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ia={option:[1,'<select multiple="multiple">',"</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option;ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead;ia.th=ia.td;var Ia=V.prototype={ready:function(b){function a(){c||(c=
|
||||||
this.text.substring(0,d.index)+"] can not be assigned to",d),c=this.ternary(),function(d,f){return a.assign(d,c(d,f),f)}):a},ternary:function(){var a=this.logicalOR(),c,d;if(this.expect("?")){c=this.ternary();if(d=this.expect(":"))return this.ternaryFn(a,c,this.ternary());this.throwError("expected :",d)}else return a},logicalOR:function(){for(var a=this.logicalAND(),c;;)if(c=this.expect("||"))a=this.binaryFn(a,c.fn,this.logicalAND());else return a},logicalAND:function(){var a=this.equality(),c;if(c=
|
!0,b())}var c=!1;"complete"===Y.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),V(t).on("load",a),this.on("DOMContentLoaded",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?G(this[b]):G(this[this.length+b])},length:0,push:sf,sort:[].sort,splice:[].splice},qb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){qb[P(b)]=b});var zc={};r("input select option textarea button form details".split(" "),
|
||||||
this.expect("&&"))a=this.binaryFn(a,c.fn,this.logicalAND());return a},equality:function(){var a=this.relational(),c;if(c=this.expect("==","!=","===","!=="))a=this.binaryFn(a,c.fn,this.equality());return a},relational:function(){var a=this.additive(),c;if(c=this.expect("<",">","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=
|
function(b){zc[b]=!0});var Ac={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};r({data:Jb,removeData:mb},function(b,a){V[a]=b});r({data:Jb,inheritedData:pb,scope:function(b){return G.data(b,"$scope")||pb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return G.data(b,"$isolateScope")||G.data(b,"$isolateScopeNoTemplate")},controller:vc,injector:function(b){return pb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:jb,
|
||||||
this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(Ya.ZERO,a.fn,this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=rc(d,this.options,this.text);return u(function(c,d,h){return e(h||a(c,d),d)},{assign:function(e,g,h){return ib(a(e,h),d,g,c.text,c.options)}})},objectIndex:function(a){var c=
|
css:function(b,a,c){a=Wa(a);if(B(c))b.style[a]=c;else return b.style[a]},attr:function(b,a,c){var d=P(a);if(qb[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||w).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(a,b){if(F(b)){var d=a.nodeType;return 1===d||3===d?a.textContent:""}a.textContent=
|
||||||
this,d=this.expression();this.consume("]");return u(function(e,f){var g=a(e,f),h=ha(d(e,f),c.text,!0),m;if(!g)return s;(g=Xa(g[h],c.text))&&(g.then&&c.options.unwrapPromises)&&(m=g,"$$v"in g||(m.$$v=s,m.then(function(a){m.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var h=ha(d(e,g),c.text);return Xa(a(e,g),c.text)[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var h=
|
b}b.$dv="";return b}(),val:function(b,a){if(F(a)){if(b.multiple&&"select"===pa(b)){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(F(a))return b.innerHTML;lb(b,!0);b.innerHTML=a},empty:wc},function(b,a){V.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==wc&&(2==b.length&&b!==jb&&b!==vc?a:d)===s){if(S(a)){for(e=0;e<g;e++)if(b===Jb)b(this[e],a);else for(f in a)b(this[e],f,a[f]);return this}e=b.$dv;
|
||||||
[],m=c?c(f,g):f,k=0;k<d.length;k++)h.push(d[k](f,g));k=a(f,g,m)||t;Xa(m,e.text);Xa(k,e.text);h=k.apply?k.apply(m,h):k(h[0],h[1],h[2],h[3],h[4]);return Xa(h,e.text)}},arrayDeclaration:function(){var a=[],c=!0;if("]"!==this.peekToken().text){do{var d=this.expression();a.push(d);d.constant||(c=!1)}while(this.expect(","))}this.consume("]");return u(function(c,d){for(var g=[],h=0;h<a.length;h++)g.push(a[h](c,d));return g},{literal:!0,constant:c})},object:function(){var a=[],c=!0;if("}"!==this.peekToken().text){do{var d=
|
g=e===s?Math.min(g,1):g;for(f=0;f<g;f++){var h=b(this[f],a,d);e=e?e+h:h}return e}for(e=0;e<g;e++)b(this[e],a,d);return this}});r({removeData:mb,on:function a(c,d,e,f){if(B(f))throw Hb("onargs");if(rc(c)){var g=nb(c,!0);f=g.events;var h=g.handle;h||(h=g.handle=Ve(c,f));for(var g=0<=d.indexOf(" ")?d.split(" "):[d],m=g.length;m--;){d=g[m];var k=f[d];k||(f[d]=[],"mouseenter"===d||"mouseleave"===d?a(c,tf[d],function(a){var c=a.relatedTarget;c&&(c===this||this.contains(c))||h(a,d)}):"$destroy"!==d&&c.addEventListener(d,
|
||||||
this.expect(),d=d.string||d.text;this.consume(":");var e=this.expression();a.push({key:d,value:e});e.constant||(c=!1)}while(this.expect(","))}this.consume("}");return u(function(c,d){for(var e={},m=0;m<a.length;m++){var k=a[m];e[k.key]=k.value(c,d)}return e},{literal:!0,constant:c})}};var Ib={},ra=L("$sce"),ca={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},R=O.createElement("a"),uc=xa(W.location.href,!0);vc.$inject=["$provide"];wc.$inject=["$locale"];yc.$inject=["$locale"];var Bc=
|
h,!1),k=f[d]);k.push(e)}}},off:uc,one:function(a,c,d){a=G(a);a.on(c,function f(){a.off(c,d);a.off(c,f)});a.on(c,d)},replaceWith:function(a,c){var d,e=a.parentNode;lb(a);r(new V(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];r(a.childNodes,function(a){1===a.nodeType&&c.push(a)});return c},contents:function(a){return a.contentDocument||a.childNodes||[]},append:function(a,c){var d=a.nodeType;if(1===d||11===d){c=new V(c);for(var d=0,e=c.length;d<
|
||||||
".",Kd={yyyy:V("FullYear",4),yy:V("FullYear",2,0,!0),y:V("FullYear",1),MMMM:jb("Month"),MMM:jb("Month",!0),MM:V("Month",2,1),M:V("Month",1,1),dd:V("Date",2),d:V("Date",1),HH:V("Hours",2),H:V("Hours",1),hh:V("Hours",2,-12),h:V("Hours",1,-12),mm:V("Minutes",2),m:V("Minutes",1),ss:V("Seconds",2),s:V("Seconds",1),sss:V("Milliseconds",3),EEEE:jb("Day"),EEE:jb("Day",!0),a:function(a,c){return 12>a.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Kb(Math[0<
|
e;d++)a.appendChild(c[d])}},prepend:function(a,c){if(1===a.nodeType){var d=a.firstChild;r(new V(c),function(c){a.insertBefore(c,d)})}},wrap:function(a,c){c=G(c).eq(0).clone()[0];var d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:xc,detach:function(a){xc(a,!0)},after:function(a,c){var d=a,e=a.parentNode;c=new V(c);for(var f=0,g=c.length;f<g;f++){var h=c[f];e.insertBefore(h,d.nextSibling);d=h}},addClass:Lb,removeClass:Kb,toggleClass:function(a,c,d){c&&r(c.split(" "),function(c){var f=
|
||||||
a?"floor":"ceil"](a/60),2)+Kb(Math.abs(a%60),2))}},Jd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,Id=/^\-?\d+$/;xc.$inject=["$locale"];var Gd=aa(w),Hd=aa(Ga);zc.$inject=["$parse"];var Rd=aa({restrict:"E",compile:function(a,c){8>=P&&(c.href||c.name||c.$set("href",""),a.append(O.createComment("IE fix")));return function(a,c){c.on("click",function(a){c.attr("href")||a.preventDefault()})}}}),Mb={};q(fb,function(a,c){if("multiple"!=a){var d=ka("ng-"+c);Mb[d]=function(){return{priority:100,
|
d;F(f)&&(f=!jb(a,c));(f?Lb:Kb)(a,c)})},parent:function(a){return(a=a.parentNode)&&11!==a.nodeType?a:null},next:function(a){return a.nextElementSibling},find:function(a,c){return a.getElementsByTagName?a.getElementsByTagName(c):[]},clone:Ib,triggerHandler:function(a,c,d){var e,f;e=c.type||c;var g=nb(a);if(g=(g=g&&g.events)&&g[e])e={preventDefault:function(){this.defaultPrevented=!0},isDefaultPrevented:function(){return!0===this.defaultPrevented},stopPropagation:w,type:e,target:a},c.type&&(e=E(e,c)),
|
||||||
compile:function(){return function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}}});q(["src","srcset","href"],function(a){var c=ka("ng-"+a);Mb[c]=function(){return{priority:99,link:function(d,e,f){f.$observe(c,function(c){c&&(f.$set(a,c),P&&e.prop(a,f[a]))})}}}});var mb={$addControl:t,$removeControl:t,$setValidity:t,$setDirty:t,$setPristine:t};Cc.$inject=["$element","$attrs","$scope"];var Ec=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Cc,compile:function(){return{pre:function(a,
|
c=qa(g),f=d?[e].concat(d):[e],r(c,function(c){c.apply(a,f)})}},function(a,c){V.prototype[c]=function(c,e,f){for(var g,h=0,m=this.length;h<m;h++)F(g)?(g=a(this[h],c,e,f),B(g)&&(g=G(g))):tc(g,a(this[h],c,e,f));return B(g)?g:this};V.prototype.bind=V.prototype.on;V.prototype.unbind=V.prototype.off});Xa.prototype={put:function(a,c){this[Ka(a,this.nextUid)]=c},get:function(a){return this[Ka(a,this.nextUid)]},remove:function(a){var c=this[a=Ka(a,this.nextUid)];delete this[a];return c}};var Cc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,
|
||||||
e,f,g){if(!f.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};Dc(e[0],"submit",h);e.on("$destroy",function(){c(function(){Ab(e[0],"submit",h)},0,!1)})}var m=e.parent().controller("form"),k=f.name||f.ngForm;k&&ib(a,k,g,k);if(m)e.on("$destroy",function(){m.$removeControl(g);k&&ib(a,k,s,k);u(g,mb)})}}}}}]},Sd=Ec(),Td=Ec(!0),Ud=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Vd=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/,Wd=
|
Xe=/,/,Ye=/^\s*(_?)(\S+?)\1\s*$/,Bc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,La=K("$injector");Cb.$$annotate=Mb;var uf=K("$animate"),oe=["$provide",function(a){this.$$selectors={};this.register=function(c,d){var e=c+"-animation";if(c&&"."!=c.charAt(0))throw uf("notcsel",c);this.$$selectors[c.substr(1)]=e;a.factory(e,d)};this.classNameFilter=function(a){1===arguments.length&&(this.$$classNameFilter=a instanceof RegExp?a:null);return this.$$classNameFilter};this.$get=["$$q","$$asyncCallback",function(a,d){function e(){f||
|
||||||
/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Fc={text:ob,number:function(a,c,d,e,f,g){ob(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Wd.test(a))return e.$setValidity("number",!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);if(!e.$isEmpty(a)&&a<c)return e.$setValidity("min",!1),s;e.$setValidity("min",!0);return a},e.$parsers.push(a),e.$formatters.push(a));
|
(f=a.defer(),d(function(){f.resolve();f=null}));return f.promise}var f;return{enter:function(a,c,d){d?d.after(a):c.prepend(a);return e()},leave:function(a){a.remove();return e()},move:function(a,c,d){return this.enter(a,c,d)},addClass:function(a,c){c=C(c)?c:L(c)?c.join(" "):"";r(a,function(a){Lb(a,c)});return e()},removeClass:function(a,c){c=C(c)?c:L(c)?c.join(" "):"";r(a,function(a){Kb(a,c)});return e()},setClass:function(a,c,d){this.addClass(a,c);this.removeClass(a,d);return e()},enabled:w,cancel:w}}]}],
|
||||||
d.max&&(a=function(a){var c=parseFloat(d.max);if(!e.$isEmpty(a)&&a>c)return e.$setValidity("max",!1),s;e.$setValidity("max",!0);return a},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){if(e.$isEmpty(a)||qb(a))return e.$setValidity("number",!0),a;e.$setValidity("number",!1);return s})},url:function(a,c,d,e,f,g){ob(a,c,d,e,f,g);a=function(a){if(e.$isEmpty(a)||Ud.test(a))return e.$setValidity("url",!0),a;e.$setValidity("url",!1);return s};e.$formatters.push(a);e.$parsers.push(a)},
|
ja=K("$compile");jc.$inject=["$provide","$$sanitizeUriProvider"];var af=/^(x[\:\-_]|data[\:\-_])/i,Pb=K("$interpolate"),vf=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,df={http:80,https:443,ftp:21},sb=K("$location");Mc.prototype=Sb.prototype=Lc.prototype={$$html5:!1,$$replace:!1,absUrl:tb("$$absUrl"),url:function(a){if(F(a))return this.$$url;a=vf.exec(a);a[1]&&this.path(decodeURIComponent(a[1]));(a[2]||a[1])&&this.search(a[3]||"");this.hash(a[5]||"");return this},protocol:tb("$$protocol"),host:tb("$$host"),
|
||||||
email:function(a,c,d,e,f,g){ob(a,c,d,e,f,g);a=function(a){if(e.$isEmpty(a)||Vd.test(a))return e.$setValidity("email",!0),a;e.$setValidity("email",!1);return s};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){x(d.name)&&c.attr("name",Za());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;D(f)||
|
port:tb("$$port"),path:Nc("$$path",function(a){a=a?a.toString():"";return"/"==a.charAt(0)?a:"/"+a}),search:function(a,c){switch(arguments.length){case 0:return this.$$search;case 1:if(C(a)||ea(a))a=a.toString(),this.$$search=fc(a);else if(S(a))r(a,function(c,e){null==c&&delete a[e]}),this.$$search=a;else throw sb("isrcharg");break;default:F(c)||null===c?delete this.$$search[a]:this.$$search[a]=c}this.$$compose();return this},hash:Nc("$$hash",function(a){return a?a.toString():""}),replace:function(){this.$$replace=
|
||||||
(f=!0);D(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:t,button:t,submit:t,reset:t},Gc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,f,g){g&&(Fc[w(f.type)]||Fc.text)(d,e,f,g,c,a)}}}],lb="ng-valid",kb="ng-invalid",Ha="ng-pristine",
|
!0;return this}};var oa=K("$parse"),wf=Function.prototype.call,xf=Function.prototype.apply,yf=Function.prototype.bind,hd=Object.create(null);r({"null":function(){return null},"true":function(){return!0},"false":function(){return!1},undefined:function(){}},function(a,c){a.constant=a.literal=a.sharedGetter=!0;hd[c]=a});var Wb=E(Object.create(null),{"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return B(d)?B(e)?d+e:d:B(e)?e:s},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(B(d)?d:0)-(B(e)?e:0)},"*":function(a,
|
||||||
nb="ng-dirty",Xd=["$scope","$exceptionHandler","$attrs","$element","$parse",function(a,c,d,e,f){function g(a,c){c=c?"-"+cb(c,"-"):"";e.removeClass((a?kb:lb)+c).addClass((a?lb:kb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var h=f(d.ngModel),m=h.assign;if(!m)throw L("ngModel")("nonassign",d.ngModel,ea(e));this.$render=t;this.$isEmpty=function(a){return x(a)||
|
c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":w,"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,
|
||||||
""===a||null===a||a!==a};var k=e.inheritedData("$formController")||mb,l=0,n=this.$error={};e.addClass(Ha);g(!0);this.$setValidity=function(a,c){n[a]!==!c&&(c?(n[a]&&l--,l||(g(!0),this.$valid=!0,this.$invalid=!1)):(g(!1),this.$invalid=!0,this.$valid=!1,l++),n[a]=!c,g(c,a),k.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;e.removeClass(nb).addClass(Ha)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,e.removeClass(Ha).addClass(nb),
|
c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}}),zf={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},Tb=function(a){this.options=a};Tb.prototype={constructor:Tb,lex:function(a){this.text=a;this.index=0;this.ch=s;for(this.tokens=[];this.index<this.text.length;)if(this.ch=this.text.charAt(this.index),
|
||||||
k.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,m(a,d),q(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=h(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue=c,r.$render())}})}],Yd=function(){return{require:["ngModel","^?form"],controller:Xd,link:function(a,c,d,e){var f=e[0],g=e[1]||mb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},
|
this.is("\"'"))this.readString(this.ch);else if(this.isNumber(this.ch)||this.is(".")&&this.isNumber(this.peek()))this.readNumber();else if(this.isIdent(this.ch))this.readIdent();else if(this.is("(){}[].,;:?"))this.tokens.push({index:this.index,text:this.ch}),this.index++;else if(this.isWhitespace(this.ch))this.index++;else{a=this.ch+this.peek();var c=a+this.peek(2),d=Wb[this.ch],e=Wb[a],f=Wb[c];f?(this.tokens.push({index:this.index,text:c,fn:f}),this.index+=3):e?(this.tokens.push({index:this.index,
|
||||||
Zd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),Hc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},$d=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&
|
text:a,fn:e}),this.index+=2):d?(this.tokens.push({index:this.index,text:this.ch,fn:d}),this.index+=1):this.throwError("Unexpected next character ",this.index,this.index+1)}return this.tokens},is:function(a){return-1!==a.indexOf(this.ch)},peek:function(a){a=a||1;return this.index+a<this.text.length?this.text.charAt(this.index+a):!1},isNumber:function(a){return"0"<=a&&"9">=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=
|
||||||
RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!x(a)){var c=[];a&&q(a.split(f),function(a){a&&c.push(Y(a))});return c}});e.$formatters.push(function(a){return J(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},ae=/^(true|false|\d+)$/,be=function(){return{priority:100,compile:function(a,c){return ae.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},ce=sa(function(a,c,d){c.addClass("ng-binding").data("$binding",
|
a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw oa("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index<this.text.length;){var d=P(this.text.charAt(this.index));if("."==d||this.isNumber(d))a+=d;else{var e=this.peek();if("e"==d&&this.isExpOperator(e))a+=d;else if(this.isExpOperator(d)&&
|
||||||
d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),de=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],ee=["$sce","$parse",function(a,c){return function(d,e,f){e.addClass("ng-binding").data("$binding",f.ngBindHtml);var g=c(f.ngBindHtml);d.$watch(function(){return(g(d)||"").toString()},function(c){e.html(a.getTrustedHtml(g(d))||"")})}}],fe=Lb("",!0),ge=
|
e&&this.isNumber(e)&&"e"==a.charAt(a.length-1))a+=d;else if(!this.isExpOperator(d)||e&&this.isNumber(e)||"e"!=a.charAt(a.length-1))break;else this.throwError("Invalid exponent")}this.index++}a*=1;this.tokens.push({index:c,text:a,constant:!0,fn:function(){return a}})},readIdent:function(){for(var a=this.text,c="",d=this.index,e,f,g,h;this.index<this.text.length;){h=this.text.charAt(this.index);if("."===h||this.isIdent(h)||this.isNumber(h))"."===h&&(e=this.index),c+=h;else break;this.index++}e&&"."===
|
||||||
Lb("Odd",0),he=Lb("Even",1),ie=sa({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}),je=[function(){return{scope:!0,controller:"@"}}],Ic={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=ka("ng-"+a);Ic[c]=["$parse",function(d){return{compile:function(e,f){var g=d(f[c]);return function(c,d,e){d.on(w(a),function(a){c.$apply(function(){g(c,{$event:a})})})}}}}]});
|
c[c.length-1]&&(this.index--,c=c.slice(0,-1),e=c.lastIndexOf("."),-1===e&&(e=s));if(e)for(f=this.index;f<this.text.length;){h=this.text.charAt(f);if("("===h){g=c.substr(e-d+1);c=c.substr(0,e-d);this.index=f;break}if(this.isWhitespace(h))f++;else break}this.tokens.push({index:d,text:c,fn:hd[c]||Pc(c,this.options,a)});g&&(this.tokens.push({index:e,text:"."}),this.tokens.push({index:e+1,text:g}))},readString:function(a){var c=this.index;this.index++;for(var d="",e=a,f=!1;this.index<this.text.length;){var g=
|
||||||
var ke=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,compile:function(c,d,e){return function(c,d,h){var m,k;c.$watch(h.ngIf,function(l){Na(l)?(k=c.$new(),e(k,function(c){m={startNode:c[0],endNode:c[c.length++]=O.createComment(" end ngIf: "+h.ngIf+" ")};a.enter(c,d.parent(),d)})):(k&&(k.$destroy(),k=null),m&&(a.leave(vb(m)),m=null))})}}}}],le=["$http","$templateCache","$anchorScroll","$compile","$animate","$sce",function(a,c,d,e,f,g){return{restrict:"ECA",
|
this.text.charAt(this.index),e=e+g;if(f)"u"===g?(f=this.text.substring(this.index+1,this.index+5),f.match(/[\da-f]{4}/i)||this.throwError("Invalid unicode escape [\\u"+f+"]"),this.index+=4,d+=String.fromCharCode(parseInt(f,16))):d+=zf[g]||g,f=!1;else if("\\"===g)f=!0;else{if(g===a){this.index++;this.tokens.push({index:c,text:e,string:d,constant:!0,fn:function(){return d}});return}d+=g}this.index++}this.throwError("Unterminated quote",c)}};var Za=function(a,c,d){this.lexer=a;this.$filter=c;this.options=
|
||||||
priority:400,terminal:!0,transclude:"element",compile:function(h,m,k){var l=m.ngInclude||m.src,n=m.onload||"",r=m.autoscroll;return function(h,m){var q=0,s,t,y=function(){s&&(s.$destroy(),s=null);t&&(f.leave(t),t=null)};h.$watch(g.parseAsResourceUrl(l),function(g){var l=function(){!z(r)||r&&!h.$eval(r)||d()},x=++q;g?(a.get(g,{cache:c}).success(function(a){if(x===q){var c=h.$new();k(c,function(d){y();s=c;t=d;t.html(a);f.enter(t,null,m,l);e(t.contents())(s);s.$emit("$includeContentLoaded");h.$eval(n)})}}).error(function(){x===
|
d};Za.ZERO=E(function(){return 0},{sharedGetter:!0,constant:!0});Za.prototype={constructor:Za,parse:function(a){this.text=a;this.tokens=this.lexer.lex(a);a=this.statements();0!==this.tokens.length&&this.throwError("is an unexpected token",this.tokens[0]);a.literal=!!a.literal;a.constant=!!a.constant;return a},primary:function(){var a;if(this.expect("("))a=this.filterChain(),this.consume(")");else if(this.expect("["))a=this.arrayDeclaration();else if(this.expect("{"))a=this.object();else{var c=this.expect();
|
||||||
q&&y()}),h.$emit("$includeContentRequested")):y()})}}}}],me=sa({compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),ne=sa({terminal:!0,priority:1E3}),oe=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var h=g.count,m=g.$attr.when&&f.attr(g.$attr.when),k=g.offset||0,l=e.$eval(m)||{},n={},r=c.startSymbol(),p=c.endSymbol(),s=/^when(Minus)?(.+)$/;q(g,function(a,c){s.test(c)&&(l[w(c.replace("when","").replace("Minus","-"))]=f.attr(g.$attr[c]))});
|
(a=c.fn)||this.throwError("not a primary expression",c);c.constant&&(a.constant=!0,a.literal=!0)}for(var d;c=this.expect("(","[",".");)"("===c.text?(a=this.functionCall(a,d),d=null):"["===c.text?(d=a,a=this.objectIndex(a)):"."===c.text?(d=a,a=this.fieldAccess(a)):this.throwError("IMPOSSIBLE");return a},throwError:function(a,c){throw oa("syntax",c.text,a,c.index+1,this.text,this.text.substring(c.index));},peekToken:function(){if(0===this.tokens.length)throw oa("ueoe",this.text);return this.tokens[0]},
|
||||||
q(l,function(a,e){n[e]=c(a.replace(d,r+h+"-"+k+p))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-k));return n[c](e,f,!0)},function(a){f.text(a)})}}}],pe=["$parse","$animate",function(a,c){var d=L("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,compile:function(e,f,g){return function(e,f,k){var l=k.ngRepeat,n=l.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),r,p,s,t,z,A,x,G={$id:Ca};if(!n)throw d("iexp",l);k=
|
peek:function(a,c,d,e){if(0<this.tokens.length){var f=this.tokens[0],g=f.text;if(g===a||g===c||g===d||g===e||!(a||c||d||e))return f}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){this.expect(a)||this.throwError("is unexpected, expecting ["+a+"]",this.peek())},unaryFn:function(a,c){return E(function(d,e){return a(d,e,c)},{constant:c.constant})},ternaryFn:function(a,c,d){return E(function(e,f){return a(e,f)?c(e,f):d(e,f)},{constant:a.constant&&
|
||||||
n[1];z=n[2];(n=n[4])?(r=a(n),p=function(a,c,d){x&&(G[x]=a);G[A]=c;G.$index=d;return r(e,G)}):(s=function(a,c){return Ca(c)},t=function(a){return a});n=k.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!n)throw d("iidexp",k);A=n[3]||n[1];x=n[2];var v={};e.$watchCollection(z,function(a){var k,n,r=f[0],z,M={},G,N,w,I,D,u,J=[];if(pb(a))D=a,z=p||s;else{z=p||t;D=[];for(w in a)a.hasOwnProperty(w)&&"$"!=w.charAt(0)&&D.push(w);D.sort()}G=D.length;n=J.length=D.length;for(k=0;k<n;k++)if(w=a===D?k:
|
c.constant&&d.constant})},binaryFn:function(a,c,d){return E(function(e,f){return c(e,f,a,d)},{constant:a.constant&&d.constant})},statements:function(){for(var a=[];;)if(0<this.tokens.length&&!this.peek("}",")",";","]")&&a.push(this.filterChain()),!this.expect(";"))return 1===a.length?a[0]:function(c,d){for(var e,f=0,g=a.length;f<g;f++)e=a[f](c,d);return e}},filterChain:function(){for(var a=this.expression(),c;c=this.expect("|");)a=this.binaryFn(a,c.fn,this.filter());return a},filter:function(){var a=
|
||||||
D[k],I=a[w],I=z(w,I,k),na(I,"`track by` id"),v.hasOwnProperty(I))u=v[I],delete v[I],M[I]=u,J[k]=u;else{if(M.hasOwnProperty(I))throw q(J,function(a){a&&a.startNode&&(v[a.id]=a)}),d("dupes",l,I);J[k]={id:I};M[I]=!1}for(w in v)v.hasOwnProperty(w)&&(u=v[w],k=vb(u),c.leave(k),q(k,function(a){a.$$NG_REMOVED=!0}),u.scope.$destroy());k=0;for(n=D.length;k<n;k++){w=a===D?k:D[k];I=a[w];u=J[k];J[k-1]&&(r=J[k-1].endNode);if(u.startNode){N=u.scope;z=r;do z=z.nextSibling;while(z&&z.$$NG_REMOVED);u.startNode!=z&&
|
this.expect(),c=this.$filter(a.text),d,e;if(this.peek(":"))for(d=[],e=[];this.expect(":");)d.push(this.expression());return da(function(a,g,h){if(e){e[0]=h;for(h=d.length;h--;)e[h+1]=d[h](a,g);return c.apply(s,e)}return c(h)})},expression:function(){return this.assignment()},assignment:function(){var a=this.ternary(),c,d;return(d=this.expect("="))?(a.assign||this.throwError("implies assignment but ["+this.text.substring(0,d.index)+"] can not be assigned to",d),c=this.ternary(),function(d,f){return a.assign(d,
|
||||||
c.move(vb(u),null,y(r));r=u.endNode}else N=e.$new();N[A]=I;x&&(N[x]=w);N.$index=k;N.$first=0===k;N.$last=k===G-1;N.$middle=!(N.$first||N.$last);N.$odd=!(N.$even=0===(k&1));u.startNode||g(N,function(a){a[a.length++]=O.createComment(" end ngRepeat: "+l+" ");c.enter(a,null,y(r));r=a;u.scope=N;u.startNode=r&&r.endNode?r.endNode:a[0];u.endNode=a[a.length-1];M[u.id]=u})}v=M})}}}}],qe=["$animate",function(a){return function(c,d,e){c.$watch(e.ngShow,function(c){a[Na(c)?"removeClass":"addClass"](d,"ng-hide")})}}],
|
c(d,f),f)}):a},ternary:function(){var a=this.logicalOR(),c,d;if(this.expect("?")){c=this.assignment();if(d=this.expect(":"))return this.ternaryFn(a,c,this.assignment());this.throwError("expected :",d)}else return a},logicalOR:function(){for(var a=this.logicalAND(),c;c=this.expect("||");)a=this.binaryFn(a,c.fn,this.logicalAND());return a},logicalAND:function(){var a=this.equality(),c;if(c=this.expect("&&"))a=this.binaryFn(a,c.fn,this.logicalAND());return a},equality:function(){var a=this.relational(),
|
||||||
re=["$animate",function(a){return function(c,d,e){c.$watch(e.ngHide,function(c){a[Na(c)?"addClass":"removeClass"](d,"ng-hide")})}}],se=sa(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&q(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),te=["$animate",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,f){var g,h,m=[];c.$watch(e.ngSwitch||e.on,function(d){for(var l=0,n=m.length;l<n;l++)m[l].$destroy(),a.leave(h[l]);h=[];
|
c;if(c=this.expect("==","!=","===","!=="))a=this.binaryFn(a,c.fn,this.equality());return a},relational:function(){var a=this.additive(),c;if(c=this.expect("<",">","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;
|
||||||
m=[];if(g=f.cases["!"+d]||f.cases["?"])c.$eval(e.change),q(g,function(d){var e=c.$new();m.push(e);d.transclude(e,function(c){var e=d.element;h.push(c);a.enter(c,e.parent(),e)})})})}}}],ue=sa({transclude:"element",priority:800,require:"^ngSwitch",compile:function(a,c,d){return function(a,f,g,h){h.cases["!"+c.ngSwitchWhen]=h.cases["!"+c.ngSwitchWhen]||[];h.cases["!"+c.ngSwitchWhen].push({transclude:d,element:f})}}}),ve=sa({transclude:"element",priority:800,require:"^ngSwitch",compile:function(a,c,d){return function(a,
|
return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(Za.ZERO,a.fn,this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this.text,d=this.expect().text,e=Pc(d,this.options,c);return E(function(c,d,h){return e(h||a(c,d))},{assign:function(e,g,h){(h=a(e,h))||a.assign(e,h={});return ub(h,d,g,c)}})},objectIndex:function(a){var c=this.text,d=this.expression();this.consume("]");return E(function(e,f){var g=a(e,f),h=d(e,f);na(h,
|
||||||
c,g,h){h.cases["?"]=h.cases["?"]||[];h.cases["?"].push({transclude:d,element:c})}}}),we=sa({controller:["$element","$transclude",function(a,c){if(!c)throw L("ngTransclude")("orphan",ea(a));this.$transclude=c}],link:function(a,c,d,e){e.$transclude(function(a){c.html("");c.append(a)})}}),xe=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){"text/ng-template"==d.type&&a.put(d.id,c[0].text)}}}],ye=L("ngOptions"),ze=aa({terminal:!0}),Ae=["$compile","$parse",function(a,
|
c);return g?Ba(g[h],c):s},{assign:function(e,f,g){var h=na(d(e,g),c);(g=Ba(a(e,g),c))||a.assign(e,g={});return g[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this.text,f=d.length?[]:null;return function(g,h){var m=c?c(g,h):g,k=a(g,h,m)||w;if(f)for(var n=d.length;n--;)f[n]=Ba(d[n](g,h),e);Ba(m,e);if(k){if(k.constructor===k)throw oa("isecfn",e);if(k===wf||k===xf||k===yf)throw oa("isecff",e);
|
||||||
c){var d=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/,e={$setViewValue:t};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var m=this,k={},l=e,n;m.databound=d.ngModel;m.init=function(a,c,d){l=a;n=d};m.addOption=function(c){na(c,'"option value"');k[c]=!0;l.$viewValue==c&&(a.val(c),n.parent()&&n.remove())};m.removeOption=
|
}m=k.apply?k.apply(m,f):k(f[0],f[1],f[2],f[3],f[4]);return Ba(m,e)}},arrayDeclaration:function(){var a=[],c=!0;if("]"!==this.peekToken().text){do{if(this.peek("]"))break;var d=this.expression();a.push(d);d.constant||(c=!1)}while(this.expect(","))}this.consume("]");return E(function(c,d){for(var g=[],h=0,m=a.length;h<m;h++)g.push(a[h](c,d));return g},{literal:!0,constant:c})},object:function(){var a=[],c=!0;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;var d=this.expect(),d=d.string||
|
||||||
function(a){this.hasOption(a)&&(delete k[a],l.$viewValue==a&&this.renderUnknownOption(a))};m.renderUnknownOption=function(c){c="? "+Ca(c)+" ?";n.val(c);a.prepend(n);a.val(c);n.prop("selected",!0)};m.hasOption=function(a){return k.hasOwnProperty(a)};c.$on("$destroy",function(){m.renderUnknownOption=t})}],link:function(e,g,h,m){function k(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(v.parent()&&v.remove(),c.val(a),""===a&&A.prop("selected",!0)):x(a)&&A?c.val(""):e.renderUnknownOption(a)};
|
d.text;this.consume(":");var e=this.expression();a.push({key:d,value:e});e.constant||(c=!1)}while(this.expect(","))}this.consume("}");return E(function(c,d){for(var e={},m=0,k=a.length;m<k;m++){var n=a[m];e[n.key]=n.value(c,d)}return e},{literal:!0,constant:c})}};var Qc=Object.create(null),Ca=K("$sce"),ka={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},ja=K("$compile"),Z=Y.createElement("a"),Tc=Aa(t.location.href,!0);qc.$inject=["$provide"];Uc.$inject=["$locale"];Wc.$inject=["$locale"];
|
||||||
c.on("change",function(){a.$apply(function(){v.parent()&&v.remove();d.$setViewValue(c.val())})})}function l(a,c,d){var e;d.$render=function(){var a=new Sa(d.$viewValue);q(c.find("option"),function(c){c.selected=z(a.get(c.value))})};a.$watch(function(){Aa(e,d.$viewValue)||(e=da(d.$viewValue),d.$render())});c.on("change",function(){a.$apply(function(){var a=[];q(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function n(e,f,g){function h(){var a={"":[]},c=[""],d,k,
|
var Zc=".",nf={yyyy:$("FullYear",4),yy:$("FullYear",2,0,!0),y:$("FullYear",1),MMMM:wb("Month"),MMM:wb("Month",!0),MM:$("Month",2,1),M:$("Month",1,1),dd:$("Date",2),d:$("Date",1),HH:$("Hours",2),H:$("Hours",1),hh:$("Hours",2,-12),h:$("Hours",1,-12),mm:$("Minutes",2),m:$("Minutes",1),ss:$("Seconds",2),s:$("Seconds",1),sss:$("Milliseconds",3),EEEE:wb("Day"),EEE:wb("Day",!0),a:function(a,c){return 12>a.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(vb(Math[0<
|
||||||
s,u,x;u=g.$modelValue;x=r(e)||[];var A=n?Nb(x):x,H,K,B;K={};s=!1;var E,L;if(t)if(v&&J(u))for(s=new Sa([]),B=0;B<u.length;B++)K[m]=u[B],s.put(v(e,K),u[B]);else s=new Sa(u);for(B=0;H=A.length,B<H;B++){k=B;if(n){k=A[B];if("$"===k.charAt(0))continue;K[n]=k}K[m]=x[k];d=p(e,K)||"";(k=a[d])||(k=a[d]=[],c.push(d));t?d=z(s.remove(v?v(e,K):q(e,K))):(v?(d={},d[m]=u,d=v(e,d)===v(e,K)):d=u===q(e,K),s=s||d);E=l(e,K);E=z(E)?E:"";k.push({id:v?v(e,K):n?A[B]:B,label:E,selected:d})}t||(w||null===u?a[""].unshift({id:"",
|
a?"floor":"ceil"](a/60),2)+vb(Math.abs(a%60),2))},ww:ad(2),w:ad(1)},mf=/((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|w+))(.*)/,lf=/^\-?\d+$/;Vc.$inject=["$locale"];var jf=da(P),kf=da(ib);Xc.$inject=["$parse"];var Fd=da({restrict:"E",compile:function(a,c){8>=X&&(c.href||c.name||c.$set("href",""),a.append(Y.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===Ga.call(c.prop("href"))?"xlink:href":"href";c.on("click",
|
||||||
label:"",selected:!s}):s||a[""].unshift({id:"?",label:"",selected:!0}));K=0;for(A=c.length;K<A;K++){d=c[K];k=a[d];y.length<=K?(u={element:G.clone().attr("label",d),label:k.label},x=[u],y.push(x),f.append(u.element)):(x=y[K],u=x[0],u.label!=d&&u.element.attr("label",u.label=d));E=null;B=0;for(H=k.length;B<H;B++)s=k[B],(d=x[B+1])?(E=d.element,d.label!==s.label&&E.text(d.label=s.label),d.id!==s.id&&E.val(d.id=s.id),E[0].selected!==s.selected&&E.prop("selected",d.selected=s.selected)):(""===s.id&&w?L=
|
function(a){c.attr(f)||a.preventDefault()})}}}),kb={};r(qb,function(a,c){if("multiple"!=a){var d=va("ng-"+c);kb[d]=function(){return{restrict:"A",priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(Ac,function(a,c){kb[c]=function(){return{priority:100,link:function(a,e,f){if("ngPattern"===c&&"/"==f.ngPattern.charAt(0)&&(e=f.ngPattern.match(rf))){f.$set("ngPattern",new RegExp(e[1],e[2]));return}a.$watch(f[c],function(a){f.$set(c,a)})}}}});r(["src","srcset","href"],function(a){var c=
|
||||||
w:(L=D.clone()).val(s.id).attr("selected",s.selected).text(s.label),x.push({element:L,label:s.label,id:s.id,selected:s.selected}),E?E.after(L):u.element.append(L),E=L);for(B++;x.length>B;)x.pop().element.remove()}for(;y.length>K;)y.pop()[0].element.remove()}var k;if(!(k=u.match(d)))throw ye("iexp",u,ea(f));var l=c(k[2]||k[1]),m=k[4]||k[6],n=k[5],p=c(k[3]||""),q=c(k[2]?k[1]:m),r=c(k[7]),v=k[8]?c(k[8]):null,y=[[{element:f,label:""}]];w&&(a(w)(e),w.removeClass("ng-scope"),w.remove());f.html("");f.on("change",
|
va("ng-"+a);kb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,h=a;"href"===a&&"[object SVGAnimatedString]"===Ga.call(e.prop("href"))&&(h="xlinkHref",f.$attr[h]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(h,c),X&&g&&e.prop(g,f[h])):"href"===a&&f.$set(h,null)})}}}});var xb={$addControl:w,$removeControl:w,$setValidity:w,$$setPending:w,$setDirty:w,$setPristine:w,$setSubmitted:w,$$clearControlValidity:w};bd.$inject=["$element","$attrs","$scope","$animate"];var id=function(a){return["$timeout",
|
||||||
function(){e.$apply(function(){var a,c=r(e)||[],d={},h,k,l,p,u,x,w;if(t)for(k=[],p=0,x=y.length;p<x;p++)for(a=y[p],l=1,u=a.length;l<u;l++){if((h=a[l].element)[0].selected){h=h.val();n&&(d[n]=h);if(v)for(w=0;w<c.length&&(d[m]=c[w],v(e,d)!=h);w++);else d[m]=c[h];k.push(q(e,d))}}else if(h=f.val(),"?"==h)k=s;else if(""===h)k=null;else if(v)for(w=0;w<c.length;w++){if(d[m]=c[w],v(e,d)==h){k=q(e,d);break}}else d[m]=c[h],n&&(d[n]=h),k=q(e,d);g.$setViewValue(k)})});g.$render=h;e.$watch(h)}if(m[1]){var r=m[0],
|
function(c){return{name:"form",restrict:a?"EAC":"E",controller:bd,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var h=function(c){a.$apply(function(){g.$commitViewValue();g.$setSubmitted()});c.preventDefault?c.preventDefault():c.returnValue=!1};e[0].addEventListener("submit",h,!1);e.on("$destroy",function(){c(function(){e[0].removeEventListener("submit",h,!1)},0,!1)})}var m=e.parent().controller("form"),k=f.name||f.ngForm;k&&ub(a,k,g,k);if(m)e.on("$destroy",function(){m.$removeControl(g);
|
||||||
p=m[1],t=h.multiple,u=h.ngOptions,w=!1,A,D=y(O.createElement("option")),G=y(O.createElement("optgroup")),v=D.clone();m=0;for(var B=g.children(),E=B.length;m<E;m++)if(""===B[m].value){A=w=B.eq(m);break}r.init(p,w,v);if(t&&(h.required||h.ngRequired)){var L=function(a){p.$setValidity("required",!h.required||a&&a.length);return a};p.$parsers.push(L);p.$formatters.unshift(L);h.$observe("required",function(){L(p.$viewValue)})}u?n(e,g,p):t?l(e,g,p):k(e,g,p,r)}}}}],Be=["$interpolate",function(a){var c={addOption:t,
|
k&&ub(a,k,s,k);E(g,xb)})}}}}}]},Gd=id(),Td=id(!0),of=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,Af=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Bf=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Cf=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,jd=/^(\d{4})-(\d{2})-(\d{2})$/,kd=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d))?$/,Xb=/^(\d{4})-W(\d\d)$/,ld=/^(\d{4})-(\d\d)$/,md=/^(\d\d):(\d\d)(?::(\d\d))?$/,
|
||||||
removeOption:t};return{restrict:"E",priority:100,compile:function(d,e){if(x(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,d,e){var k=d.parent(),l=k.data("$selectController")||k.parent().data("$selectController");l&&l.databound?d.prop("selected",!1):l=c;f?a.$watch(f,function(a,c){e.$set("value",a);a!==c&&l.removeOption(c);l.addOption(a)}):l.addOption(e.value);d.on("$destroy",function(){l.removeOption(e.value)})}}}}],Ce=aa({restrict:"E",terminal:!0});(Ba=W.jQuery)?(y=
|
Df=/(\s+|^)default(\s+|$)/,Yb=new K("ngModel"),nd={text:function(a,c,d,e,f,g){$a(a,c,d,e,f,g);Ub(e)},date:ab("date",jd,zb(jd,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":ab("datetimelocal",kd,zb(kd,"yyyy MM dd HH mm ss".split(" ")),"yyyy-MM-ddTHH:mm:ss"),time:ab("time",md,zb(md,["HH","mm","ss"]),"HH:mm:ss"),week:ab("week",Xb,function(a){if(fa(a))return a;if(C(a)){Xb.lastIndex=0;var c=Xb.exec(a);if(c){a=+c[1];var d=+c[2],c=$c(a),d=7*(d-1);return new Date(a,0,c.getDate()+d)}}return NaN},"yyyy-Www"),
|
||||||
Ba,u(Ba.fn,{scope:Da.scope,isolateScope:Da.isolateScope,controller:Da.controller,injector:Da.injector,inheritedData:Da.inheritedData}),wb("remove",!0,!0,!1),wb("empty",!1,!1,!1),wb("html",!1,!1,!0)):y=Q;bb.element=y;(function(a){u(a,{bootstrap:Wb,copy:da,extend:u,equals:Aa,element:y,forEach:q,injector:Xb,noop:t,bind:rb,toJson:ma,fromJson:Sb,identity:za,isUndefined:x,isDefined:z,isString:D,isFunction:B,isObject:T,isNumber:qb,isElement:Kc,isArray:J,version:Md,isDate:Ja,lowercase:w,uppercase:Ga,callbacks:{counter:0},
|
month:ab("month",ld,zb(ld,["yyyy","MM"]),"yyyy-MM"),number:function(a,c,d,e,f,g){dd(a,c,d,e);$a(a,c,d,e,f,g);e.$$parserName="number";e.$parsers.push(function(a){return e.$isEmpty(a)?null:Cf.test(a)?parseFloat(a):s});e.$formatters.push(function(a){if(!e.$isEmpty(a)){if(!ea(a))throw Yb("numfmt",a);a=a.toString()}return a});if(d.min||d.ngMin){var h;e.$validators.min=function(a){return e.$isEmpty(a)||F(h)||a>=h};d.$observe("min",function(a){B(a)&&!ea(a)&&(a=parseFloat(a,10));h=ea(a)&&!isNaN(a)?a:s;e.$validate()})}if(d.max||
|
||||||
$$minErr:L,$$csp:Rb});Ua=Qc(W);try{Ua("ngLocale")}catch(c){Ua("ngLocale",[]).provider("$locale",pd)}Ua("ng",["ngLocale"],["$provide",function(a){a.provider("$compile",ec).directive({a:Rd,input:Gc,textarea:Gc,form:Sd,script:xe,select:Ae,style:Ce,option:Be,ngBind:ce,ngBindHtml:ee,ngBindTemplate:de,ngClass:fe,ngClassEven:he,ngClassOdd:ge,ngCloak:ie,ngController:je,ngForm:Td,ngHide:re,ngIf:ke,ngInclude:le,ngInit:me,ngNonBindable:ne,ngPluralize:oe,ngRepeat:pe,ngShow:qe,ngStyle:se,ngSwitch:te,ngSwitchWhen:ue,
|
d.ngMax){var m;e.$validators.max=function(a){return e.$isEmpty(a)||F(m)||a<=m};d.$observe("max",function(a){B(a)&&!ea(a)&&(a=parseFloat(a,10));m=ea(a)&&!isNaN(a)?a:s;e.$validate()})}},url:function(a,c,d,e,f,g){$a(a,c,d,e,f,g);Ub(e);e.$$parserName="url";e.$validators.url=function(a,c){var d=a||c;return e.$isEmpty(d)||Af.test(d)}},email:function(a,c,d,e,f,g){$a(a,c,d,e,f,g);Ub(e);e.$$parserName="email";e.$validators.email=function(a,c){var d=a||c;return e.$isEmpty(d)||Bf.test(d)}},radio:function(a,
|
||||||
ngSwitchDefault:ve,ngOptions:ze,ngTransclude:we,ngModel:Yd,ngList:$d,ngChange:Zd,required:Hc,ngRequired:Hc,ngValue:be}).directive(Mb).directive(Ic);a.provider({$anchorScroll:Zc,$animate:Od,$browser:bd,$cacheFactory:cd,$controller:gd,$document:hd,$exceptionHandler:id,$filter:vc,$interpolate:nd,$interval:od,$http:jd,$httpBackend:kd,$location:rd,$log:sd,$parse:td,$rootScope:wd,$q:ud,$sce:zd,$sceDelegate:yd,$sniffer:Ad,$templateCache:dd,$timeout:Bd,$window:Cd})}])})(bb);y(O).ready(function(){Oc(O,Wb)})})(window,
|
c,d,e){F(d.name)&&c.attr("name",++bb);c.on("click",function(a){c[0].checked&&e.$setViewValue(d.value,a&&a.type)});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e,f,g,h,m){var k=ed(m,a,"ngTrueValue",d.ngTrueValue,!0),n=ed(m,a,"ngFalseValue",d.ngFalseValue,!1);c.on("click",function(a){e.$setViewValue(c[0].checked,a&&a.type)});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==k};e.$formatters.push(function(a){return ra(a,
|
||||||
document);!angular.$$csp()&&angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-start{clip:rect(0,auto,auto,0);-ms-zoom:1.0001;}.ng-animate-active{clip:rect(-1px,auto,auto,0);-ms-zoom:1;}</style>');
|
k)});e.$parsers.push(function(a){return a?k:n})},hidden:w,button:w,submit:w,reset:w,file:w},kc=["$browser","$sniffer","$filter","$parse",function(a,c,d,e){return{restrict:"E",require:["?ngModel"],link:function(f,g,h,m){m[0]&&(nd[P(h.type)]||nd.text)(f,g,h,m[0],c,a,d,e)}}}],pf="ng-valid",qf="ng-invalid",Ma="ng-pristine",yb="ng-dirty",gd="ng-pending",Ef=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q",function(a,c,d,e,f,g,h,m,k){this.$modelValue=this.$viewValue=
|
||||||
|
Number.NaN;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=s;this.$name=d.name;var n=f(d.ngModel),p=null,l=this,q=function(){var c=n(a);l.$options&&l.$options.getterSetter&&D(c)&&(c=c());return c},A=function(c){var d;l.$options&&l.$options.getterSetter&&D(d=n(a))?d(l.$modelValue):n.assign(a,
|
||||||
|
l.$modelValue)};this.$$setOptions=function(a){l.$options=a;if(!(n.assign||a&&a.getterSetter))throw Yb("nonassign",d.ngModel,ta(e));};this.$render=w;this.$isEmpty=function(a){return F(a)||""===a||null===a||a!==a};var u=e.inheritedData("$formController")||xb,x=0;e.addClass(Ma).addClass("ng-untouched");cd({ctrl:this,$element:e,set:function(a,c){a[c]=!0},unset:function(a,c){delete a[c]},parentForm:u,$animate:g});this.$setPristine=function(){l.$dirty=!1;l.$pristine=!0;g.removeClass(e,yb);g.addClass(e,
|
||||||
|
Ma)};this.$setUntouched=function(){l.$touched=!1;l.$untouched=!0;g.setClass(e,"ng-untouched","ng-touched")};this.$setTouched=function(){l.$touched=!0;l.$untouched=!1;g.setClass(e,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){h.cancel(p);l.$viewValue=l.$$lastCommittedViewValue;l.$render()};this.$validate=function(){ea(l.$modelValue)&&isNaN(l.$modelValue)||this.$$parseAndValidate()};this.$$runValidators=function(a,c,d,e){function f(){var a=!0;r(l.$validators,function(e,f){var h=e(c,
|
||||||
|
d);a=a&&h;g(f,h)});return a?!0:(r(l.$asyncValidators,function(a,c){g(c,null)}),m(),!1)}function h(){var a=[];r(l.$asyncValidators,function(e,f){var h=e(c,d);if(!h||!D(h.then))throw Yb("$asyncValidators",h);g(f,s);a.push(h.then(function(){g(f,!0)},function(a){g(f,!1)}))});a.length?k.all(a).then(m):m()}function g(a,c){n===x&&l.$setValidity(a,c)}function m(){n===x&&e()}x++;var n=x;(function(a){var c=l.$$parserName||"parse";if(a===s)g(c,null);else if(g(c,a),!a)return r(l.$validators,function(a,c){g(c,
|
||||||
|
null)}),r(l.$asyncValidators,function(a,c){g(c,null)}),m(),!1;return!0})(a)&&f()&&h()};this.$commitViewValue=function(){var a=l.$viewValue;h.cancel(p);if(l.$$lastCommittedViewValue!==a||""===a&&l.$$hasNativeValidators)l.$$lastCommittedViewValue=a,l.$pristine&&(l.$dirty=!0,l.$pristine=!1,g.removeClass(e,Ma),g.addClass(e,yb),u.$setDirty()),this.$$parseAndValidate()};this.$$parseAndValidate=function(){for(var a=!0,c=l.$$lastCommittedViewValue,d=c,e=0;e<l.$parsers.length;e++)if(d=l.$parsers[e](d),F(d)){a=
|
||||||
|
!1;break}ea(l.$modelValue)&&isNaN(l.$modelValue)&&(l.$modelValue=q());var f=l.$modelValue,h=l.$options&&l.$options.allowInvalid;h&&(l.$modelValue=d,l.$modelValue!==f&&l.$$writeModelToScope());l.$$runValidators(a,d,c,function(){h||(l.$modelValue=l.$valid?d:s,l.$modelValue!==f&&l.$$writeModelToScope())})};this.$$writeModelToScope=function(){A(l.$modelValue);r(l.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};this.$setViewValue=function(a,c){l.$viewValue=a;l.$options&&!l.$options.updateOnDefault||
|
||||||
|
l.$$debounceViewValueCommit(c)};this.$$debounceViewValueCommit=function(c){var d=0,e=l.$options;e&&B(e.debounce)&&(e=e.debounce,ea(e)?d=e:ea(e[c])?d=e[c]:ea(e["default"])&&(d=e["default"]));h.cancel(p);d?p=h(function(){l.$commitViewValue()},d):m.$$phase?l.$commitViewValue():a.$apply(function(){l.$commitViewValue()})};a.$watch(function(){var a=q();if(a!==l.$modelValue){l.$modelValue=a;for(var c=l.$formatters,d=c.length,e=a;d--;)e=c[d](e);l.$viewValue!==e&&(l.$viewValue=l.$$lastCommittedViewValue=e,
|
||||||
|
l.$render(),l.$$runValidators(s,a,e,w))}return a})}],he=function(){return{restrict:"A",require:["ngModel","^?form","^?ngModelOptions"],controller:Ef,link:{pre:function(a,c,d,e){var f=e[0],g=e[1]||xb;f.$$setOptions(e[2]&&e[2].$options);g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})},post:function(a,c,d,e){var f=e[0];if(f.$options&&f.$options.updateOn)c.on(f.$options.updateOn,function(a){f.$$debounceViewValueCommit(a&&a.type)});c.on("blur",function(c){f.$touched||a.$apply(function(){f.$setTouched()})})}}}},
|
||||||
|
je=da({restrict:"A",require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),mc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){e&&(d.required=!0,e.$validators.required=function(a,c){return!d.required||!e.$isEmpty(c)},d.$observe("required",function(){e.$validate()}))}}},lc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f,g=d.ngPattern||d.pattern;d.$observe("pattern",function(a){C(a)&&0<a.length&&
|
||||||
|
(a=new RegExp(a));if(a&&!a.test)throw K("ngPattern")("noregexp",g,a,ta(c));f=a||s;e.$validate()});e.$validators.pattern=function(a){return e.$isEmpty(a)||F(f)||f.test(a)}}}}},oc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=0;d.$observe("maxlength",function(a){f=U(a)||0;e.$validate()});e.$validators.maxlength=function(a,c){return e.$isEmpty(c)||c.length<=f}}}}},nc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=0;d.$observe("minlength",
|
||||||
|
function(a){f=U(a)||0;e.$validate()});e.$validators.minlength=function(a,c){return e.$isEmpty(c)||c.length>=f}}}}},ie=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,c,d,e){var f=c.attr(d.$attr.ngList)||", ",g="false"!==d.ngTrim,h=g?ba(f):f;e.$parsers.push(function(a){if(!F(a)){var c=[];a&&r(a.split(h),function(a){a&&c.push(g?ba(a):a)});return c}});e.$formatters.push(function(a){return L(a)?a.join(f):s});e.$isEmpty=function(a){return!a||!a.length}}}},Ff=/^(true|false|\d+)$/,
|
||||||
|
ke=function(){return{restrict:"A",priority:100,compile:function(a,c){return Ff.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},le=function(){return{restrict:"A",controller:["$scope","$attrs",function(a,c){var d=this;this.$options=a.$eval(c.ngModelOptions);this.$options.updateOn!==s?(this.$options.updateOnDefault=!1,this.$options.updateOn=ba(this.$options.updateOn.replace(Df,function(){d.$options.updateOnDefault=
|
||||||
|
!0;return" "}))):this.$options.updateOnDefault=!0}]}},Ld=["$compile",function(a){return{restrict:"AC",compile:function(c){a.$$addBindingClass(c);return function(c,e,f){a.$$addBindingInfo(e,f.ngBind);c.$watch(f.ngBind,function(a){e.text(a==s?"":a)})}}}}],Nd=["$interpolate","$compile",function(a,c){return{compile:function(d){c.$$addBindingClass(d);return function(d,f,g){d=a(f.attr(g.$attr.ngBindTemplate));c.$$addBindingInfo(f,d.expressions);g.$observe("ngBindTemplate",function(a){f.text(a)})}}}}],Md=
|
||||||
|
["$sce","$parse","$compile",function(a,c,d){return{restrict:"A",compile:function(e,f){var g=c(f.ngBindHtml),h=c(f.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(e);return function(c,e,f){d.$$addBindingInfo(e,f.ngBindHtml);c.$watch(h,function(){e.html(a.getTrustedHtml(g(c))||"")})}}}}],Od=Vb("",!0),Qd=Vb("Odd",0),Pd=Vb("Even",1),Rd=Fa({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}),Sd=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],
|
||||||
|
pc={},Gf={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=va("ng-"+a);pc[c]=["$parse","$rootScope",function(d,e){return{restrict:"A",compile:function(f,g){var h=d(g[c]);return function(c,d){var f=P(a);d.on(f,function(a){var d=function(){h(c,{$event:a})};Gf[f]&&e.$$phase?c.$evalAsync(d):c.$apply(d)})}}}}]});var Vd=["$animate",function(a){return{multiElement:!0,
|
||||||
|
transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,m,k;c.$watch(e.ngIf,function(c){c?m||g(function(c,f){m=f;c[c.length++]=Y.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)}):(k&&(k.remove(),k=null),m&&(m.$destroy(),m=null),h&&(k=hb(h.clone),a.leave(k).then(function(){k=null}),h=null))})}}}],Wd=["$templateRequest","$anchorScroll","$animate","$sce",function(a,c,d,e){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",
|
||||||
|
controller:Ea.noop,compile:function(f,g){var h=g.ngInclude||g.src,m=g.onload||"",k=g.autoscroll;return function(f,g,l,q,r){var u=0,s,z,t,v=function(){z&&(z.remove(),z=null);s&&(s.$destroy(),s=null);t&&(d.leave(t).then(function(){z=null}),z=t,t=null)};f.$watch(e.parseAsResourceUrl(h),function(e){var h=function(){!B(k)||k&&!f.$eval(k)||c()},l=++u;e?(a(e,!0).then(function(a){if(l===u){var c=f.$new();q.template=a;a=r(c,function(a){v();d.enter(a,null,g).then(h)});s=c;t=a;s.$emit("$includeContentLoaded");
|
||||||
|
f.$eval(m)}},function(){l===u&&(v(),f.$emit("$includeContentError"))}),f.$emit("$includeContentRequested")):(v(),q.template=null)})}}}}],me=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,f){/SVG/.test(d[0].toString())?(d.empty(),a(sc(f.template,Y).childNodes)(c,function(a){d.append(a)},s,s,d)):(d.html(f.template),a(d.contents())(c))}}}],Xd=Fa({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),Yd=Fa({terminal:!0,priority:1E3}),
|
||||||
|
Zd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var h=g.count,m=g.$attr.when&&f.attr(g.$attr.when),k=g.offset||0,n=e.$eval(m)||{},p={},l=c.startSymbol(),q=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(n[P(c.replace("when","").replace("Minus","-"))]=f.attr(g.$attr[c]))});r(n,function(a,e){p[e]=c(a.replace(d,l+h+"-"+k+q))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in n||(c=a.pluralCat(c-k));return p[c](e)},
|
||||||
|
function(a){f.text(a)})}}}],$d=["$parse","$animate",function(a,c){var d=K("ngRepeat"),e=function(a,c,d,e,k,n,p){a[d]=e;k&&(a[k]=n);a.$index=c;a.$first=0===c;a.$last=c===p-1;a.$middle=!(a.$first||a.$last);a.$odd=!(a.$even=0===(c&1))};return{restrict:"A",multiElement:!0,transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,compile:function(f,g){var h=g.ngRepeat,m=Y.createComment(" end ngRepeat: "+h+" "),k=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
|
||||||
|
if(!k)throw d("iexp",h);var n=k[1],p=k[2],l=k[3],q=k[4],k=n.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!k)throw d("iidexp",n);var A=k[3]||k[1],u=k[2];if(l&&(!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(l)||/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent)$/.test(l)))throw d("badident",l);var t,z,B,v,w={$id:Ka};q?t=a(q):(B=function(a,c){return Ka(c)},v=function(a){return a});return function(a,f,g,k,n){t&&(z=function(c,d,e){u&&(w[u]=c);w[A]=d;w.$index=e;return t(a,w)});
|
||||||
|
var q=Object.create(null);a.$watchCollection(p,function(g){var k,p,t=f[0],J,x=Object.create(null),w,N,E,F,y,C,ga;l&&(a[l]=g);if(Na(g))y=g,p=z||B;else{p=z||v;y=[];for(ga in g)g.hasOwnProperty(ga)&&"$"!=ga.charAt(0)&&y.push(ga);y.sort()}w=y.length;ga=Array(w);for(k=0;k<w;k++)if(N=g===y?k:y[k],E=g[N],F=p(N,E,k),q[F])C=q[F],delete q[F],x[F]=C,ga[k]=C;else{if(x[F])throw r(ga,function(a){a&&a.scope&&(q[a.id]=a)}),d("dupes",h,F,sa(E));ga[k]={id:F,scope:s,clone:s};x[F]=!0}for(J in q){C=q[J];F=hb(C.clone);
|
||||||
|
c.leave(F);if(F[0].parentNode)for(k=0,p=F.length;k<p;k++)F[k].$$NG_REMOVED=!0;C.scope.$destroy()}for(k=0;k<w;k++)if(N=g===y?k:y[k],E=g[N],C=ga[k],C.scope){J=t;do J=J.nextSibling;while(J&&J.$$NG_REMOVED);C.clone[0]!=J&&c.move(hb(C.clone),null,G(t));t=C.clone[C.clone.length-1];e(C.scope,k,A,E,u,N,w)}else n(function(a,d){C.scope=d;var f=m.cloneNode(!1);a[a.length++]=f;c.enter(a,null,G(t));t=f;C.clone=a;x[C.id]=C;e(C.scope,k,A,E,u,N,w)});q=x})}}}}],ae=["$animate",function(a){return{restrict:"A",multiElement:!0,
|
||||||
|
link:function(c,d,e){c.$watch(e.ngShow,function(c){a[c?"removeClass":"addClass"](d,"ng-hide")})}}}],Ud=["$animate",function(a){return{restrict:"A",multiElement:!0,link:function(c,d,e){c.$watch(e.ngHide,function(c){a[c?"addClass":"removeClass"](d,"ng-hide")})}}}],be=Fa(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&r(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),ce=["$animate",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,
|
||||||
|
d,e,f){var g=[],h=[],m=[],k=[],n=function(a,c){return function(){a.splice(c,1)}};c.$watch(e.ngSwitch||e.on,function(c){var d,e;d=0;for(e=m.length;d<e;++d)a.cancel(m[d]);d=m.length=0;for(e=k.length;d<e;++d){var s=hb(h[d].clone);k[d].$destroy();(m[d]=a.leave(s)).then(n(m,d))}h.length=0;k.length=0;(g=f.cases["!"+c]||f.cases["?"])&&r(g,function(c){c.transclude(function(d,e){k.push(e);var f=c.element;d[d.length++]=Y.createComment(" end ngSwitchWhen: ");h.push({clone:d});a.enter(d,f.parent(),f)})})})}}}],
|
||||||
|
de=Fa({transclude:"element",priority:1200,require:"^ngSwitch",multiElement:!0,link:function(a,c,d,e,f){e.cases["!"+d.ngSwitchWhen]=e.cases["!"+d.ngSwitchWhen]||[];e.cases["!"+d.ngSwitchWhen].push({transclude:f,element:c})}}),ee=Fa({transclude:"element",priority:1200,require:"^ngSwitch",multiElement:!0,link:function(a,c,d,e,f){e.cases["?"]=e.cases["?"]||[];e.cases["?"].push({transclude:f,element:c})}}),ge=Fa({restrict:"EAC",link:function(a,c,d,e,f){if(!f)throw K("ngTransclude")("orphan",ta(c));f(function(a){c.empty();
|
||||||
|
c.append(a)})}}),Hd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){"text/ng-template"==d.type&&a.put(d.id,c[0].text)}}}],Hf=K("ngOptions"),fe=da({restrict:"A",terminal:!0}),Id=["$compile","$parse",function(a,c){var d=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,e={$setViewValue:w};return{restrict:"E",require:["select",
|
||||||
|
"?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var m=this,k={},n=e,p;m.databound=d.ngModel;m.init=function(a,c,d){n=a;p=d};m.addOption=function(c,d){Ja(c,'"option value"');k[c]=!0;n.$viewValue==c&&(a.val(c),p.parent()&&p.remove());d[0].hasAttribute("selected")&&(d[0].selected=!0)};m.removeOption=function(a){this.hasOption(a)&&(delete k[a],n.$viewValue==a&&this.renderUnknownOption(a))};m.renderUnknownOption=function(c){c="? "+Ka(c)+" ?";p.val(c);a.prepend(p);a.val(c);p.prop("selected",
|
||||||
|
!0)};m.hasOption=function(a){return k.hasOwnProperty(a)};c.$on("$destroy",function(){m.renderUnknownOption=w})}],link:function(e,g,h,m){function k(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(y.parent()&&y.remove(),c.val(a),""===a&&w.prop("selected",!0)):F(a)&&w?c.val(""):e.renderUnknownOption(a)};c.on("change",function(){a.$apply(function(){y.parent()&&y.remove();d.$setViewValue(c.val())})})}function n(a,c,d){var e;d.$render=function(){var a=new Xa(d.$viewValue);r(c.find("option"),
|
||||||
|
function(c){c.selected=B(a.get(c.value))})};a.$watch(function(){ra(e,d.$viewValue)||(e=qa(d.$viewValue),d.$render())});c.on("change",function(){a.$apply(function(){var a=[];r(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function p(e,f,h){function g(){z||(e.$$postDigest(k),z=!0)}function k(){z=!1;var a={"":[]},c=[""],d,g,l,s,t;l=h.$modelValue;s=F(e)||[];var A=p?Zb(s):s,G,y,D;y={};D=!1;if(q)if(g=h.$modelValue,x&&L(g))for(D=new Xa([]),d={},t=0;t<g.length;t++)d[n]=
|
||||||
|
g[t],D.put(x(e,d),g[t]);else D=new Xa(g);t=D;var H,K;for(D=0;G=A.length,D<G;D++){g=D;if(p){g=A[D];if("$"===g.charAt(0))continue;y[p]=g}y[n]=s[g];d=r(e,y)||"";(g=a[d])||(g=a[d]=[],c.push(d));q?d=B(t.remove(x?x(e,y):w(e,y))):(x?(d={},d[n]=l,d=x(e,d)===x(e,y)):d=l===w(e,y),t=t||d);H=m(e,y);H=B(H)?H:"";g.push({id:x?x(e,y):p?A[D]:D,label:H,selected:d})}q||(u||null===l?a[""].unshift({id:"",label:"",selected:!t}):t||a[""].unshift({id:"?",label:"",selected:!0}));y=0;for(A=c.length;y<A;y++){d=c[y];g=a[d];
|
||||||
|
E.length<=y?(l={element:v.clone().attr("label",d),label:g.label},s=[l],E.push(s),f.append(l.element)):(s=E[y],l=s[0],l.label!=d&&l.element.attr("label",l.label=d));H=null;D=0;for(G=g.length;D<G;D++)d=g[D],(t=s[D+1])?(H=t.element,t.label!==d.label&&H.text(t.label=d.label),t.id!==d.id&&H.val(t.id=d.id),H[0].selected!==d.selected&&(H.prop("selected",t.selected=d.selected),X&&H.prop("selected",t.selected))):(""===d.id&&u?K=u:(K=C.clone()).val(d.id).prop("selected",d.selected).attr("selected",d.selected).text(d.label),
|
||||||
|
s.push({element:K,label:d.label,id:d.id,selected:d.selected}),H?H.after(K):l.element.append(K),H=K);for(D++;s.length>D;)s.pop().element.remove()}for(;E.length>y;)E.pop()[0].element.remove()}var l;if(!(l=t.match(d)))throw Hf("iexp",t,ta(f));var m=c(l[2]||l[1]),n=l[4]||l[6],p=l[5],r=c(l[3]||""),w=c(l[2]?l[1]:n),F=c(l[7]),x=l[8]?c(l[8]):null,E=[[{element:f,label:""}]];u&&(a(u)(e),u.removeClass("ng-scope"),u.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=F(e)||[],d={},g,l,m,
|
||||||
|
r,t,u,v;if(q)for(l=[],r=0,u=E.length;r<u;r++)for(a=E[r],m=1,t=a.length;m<t;m++){if((g=a[m].element)[0].selected){g=g.val();p&&(d[p]=g);if(x)for(v=0;v<c.length&&(d[n]=c[v],x(e,d)!=g);v++);else d[n]=c[g];l.push(w(e,d))}}else if(g=f.val(),"?"==g)l=s;else if(""===g)l=null;else if(x)for(v=0;v<c.length;v++){if(d[n]=c[v],x(e,d)==g){l=w(e,d);break}}else d[n]=c[g],p&&(d[p]=g),l=w(e,d);h.$setViewValue(l);k()})});h.$render=k;e.$watchCollection(F,g);q&&e.$watchCollection(function(){return h.$modelValue},g)}if(m[1]){var l=
|
||||||
|
m[0];m=m[1];var q=h.multiple,t=h.ngOptions,u=!1,w,z=!1,C=G(Y.createElement("option")),v=G(Y.createElement("optgroup")),y=C.clone();h=0;for(var E=g.children(),D=E.length;h<D;h++)if(""===E[h].value){w=u=E.eq(h);break}l.init(m,u,y);q&&(m.$isEmpty=function(a){return!a||0===a.length});t?p(e,g,m):q?n(e,g,m):k(e,g,m,l)}}}}],Kd=["$interpolate",function(a){var c={addOption:w,removeOption:w};return{restrict:"E",priority:100,compile:function(d,e){if(F(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,
|
||||||
|
d,e){var k=d.parent(),n=k.data("$selectController")||k.parent().data("$selectController");n&&n.databound?d.prop("selected",!1):n=c;f?a.$watch(f,function(a,c){e.$set("value",a);c!==a&&n.removeOption(c);n.addOption(a,d)}):n.addOption(e.value,d);d.on("$destroy",function(){n.removeOption(e.value)})}}}}],Jd=da({restrict:"E",terminal:!1});t.angular.bootstrap?console.log("WARNING: Tried to load angular more than once."):(zd(),Bd(Ea),G(Y).ready(function(){vd(Y,gc)}))})(window,document);
|
||||||
|
!window.angular.$$csp()&&window.angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-animate){display:none !important;}ng\\:form{display:block;}</style>');
|
||||||
//# sourceMappingURL=angular.min.js.map
|
//# sourceMappingURL=angular.min.js.map
|
||||||
|
|
117
webclient/js/autofill-event.js
Executable file
117
webclient/js/autofill-event.js
Executable file
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* Autofill event polyfill ##version:1.0.0##
|
||||||
|
* (c) 2014 Google, Inc.
|
||||||
|
* License: MIT
|
||||||
|
*/
|
||||||
|
(function(window) {
|
||||||
|
var $ = window.jQuery || window.angular.element;
|
||||||
|
var rootElement = window.document.documentElement,
|
||||||
|
$rootElement = $(rootElement);
|
||||||
|
|
||||||
|
addGlobalEventListener('change', markValue);
|
||||||
|
addValueChangeByJsListener(markValue);
|
||||||
|
|
||||||
|
$.prototype.checkAndTriggerAutoFillEvent = jqCheckAndTriggerAutoFillEvent;
|
||||||
|
|
||||||
|
// Need to use blur and not change event
|
||||||
|
// as Chrome does not fire change events in all cases an input is changed
|
||||||
|
// (e.g. when starting to type and then finish the input by auto filling a username)
|
||||||
|
addGlobalEventListener('blur', function(target) {
|
||||||
|
// setTimeout needed for Chrome as it fills other
|
||||||
|
// form fields a little later...
|
||||||
|
window.setTimeout(function() {
|
||||||
|
findParentForm(target).find('input').checkAndTriggerAutoFillEvent();
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// The timeout is needed for Chrome as it auto fills
|
||||||
|
// login forms some time after DOMContentLoaded!
|
||||||
|
window.setTimeout(function() {
|
||||||
|
$rootElement.find('input').checkAndTriggerAutoFillEvent();
|
||||||
|
}, 200);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
function jqCheckAndTriggerAutoFillEvent() {
|
||||||
|
var i, el;
|
||||||
|
for (i=0; i<this.length; i++) {
|
||||||
|
el = this[i];
|
||||||
|
if (!valueMarked(el)) {
|
||||||
|
markValue(el);
|
||||||
|
triggerChangeEvent(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function valueMarked(el) {
|
||||||
|
var val = el.value,
|
||||||
|
$$currentValue = el.$$currentValue;
|
||||||
|
if (!val && !$$currentValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return val === $$currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function markValue(el) {
|
||||||
|
el.$$currentValue = el.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addValueChangeByJsListener(listener) {
|
||||||
|
var jq = window.jQuery || window.angular.element,
|
||||||
|
jqProto = jq.prototype;
|
||||||
|
var _val = jqProto.val;
|
||||||
|
jqProto.val = function(newValue) {
|
||||||
|
var res = _val.apply(this, arguments);
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
forEach(this, function(el) {
|
||||||
|
listener(el, newValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addGlobalEventListener(eventName, listener) {
|
||||||
|
// Use a capturing event listener so that
|
||||||
|
// we also get the event when it's stopped!
|
||||||
|
// Also, the blur event does not bubble.
|
||||||
|
rootElement.addEventListener(eventName, onEvent, true);
|
||||||
|
|
||||||
|
function onEvent(event) {
|
||||||
|
var target = event.target;
|
||||||
|
listener(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findParentForm(el) {
|
||||||
|
while (el) {
|
||||||
|
if (el.nodeName === 'FORM') {
|
||||||
|
return $(el);
|
||||||
|
}
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
return $();
|
||||||
|
}
|
||||||
|
|
||||||
|
function forEach(arr, listener) {
|
||||||
|
if (arr.forEach) {
|
||||||
|
return arr.forEach(listener);
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
for (i=0; i<arr.length; i++) {
|
||||||
|
listener(arr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerChangeEvent(element) {
|
||||||
|
var doc = window.document;
|
||||||
|
var event = doc.createEvent("HTMLEvents");
|
||||||
|
event.initEvent("change", true, true);
|
||||||
|
element.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window);
|
BIN
webclient/media/busy.mp3
Normal file
BIN
webclient/media/busy.mp3
Normal file
Binary file not shown.
BIN
webclient/media/busy.ogg
Normal file
BIN
webclient/media/busy.ogg
Normal file
Binary file not shown.
BIN
webclient/media/callend.mp3
Normal file
BIN
webclient/media/callend.mp3
Normal file
Binary file not shown.
BIN
webclient/media/callend.ogg
Normal file
BIN
webclient/media/callend.ogg
Normal file
Binary file not shown.
BIN
webclient/media/ring.mp3
Normal file
BIN
webclient/media/ring.mp3
Normal file
Binary file not shown.
BIN
webclient/media/ring.ogg
Normal file
BIN
webclient/media/ring.ogg
Normal file
Binary file not shown.
BIN
webclient/media/ringback.mp3
Normal file
BIN
webclient/media/ringback.mp3
Normal file
Binary file not shown.
BIN
webclient/media/ringback.ogg
Normal file
BIN
webclient/media/ringback.ogg
Normal file
Binary file not shown.
|
@ -17,80 +17,133 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('RecentsController', ['matrixService', 'matrixFilter', 'eventHandlerService'])
|
angular.module('RecentsController', ['matrixService', 'matrixFilter', 'eventHandlerService'])
|
||||||
.controller('RecentsController', ['$scope', 'matrixService', 'eventHandlerService',
|
.controller('RecentsController', ['$rootScope', '$scope', 'matrixService', 'eventHandlerService',
|
||||||
function($scope, matrixService, eventHandlerService) {
|
function($rootScope, $scope, matrixService, eventHandlerService) {
|
||||||
$scope.rooms = {};
|
|
||||||
|
|
||||||
// $scope of the parent where the recents component is included can override this value
|
// FIXME: Angularjs reloads the controller (and resets its $scope) each time
|
||||||
|
// the page URL changes, use $rootScope to avoid to have to reload data
|
||||||
|
$rootScope.rooms;
|
||||||
|
|
||||||
|
// $rootScope of the parent where the recents component is included can override this value
|
||||||
// in order to highlight a specific room in the list
|
// in order to highlight a specific room in the list
|
||||||
$scope.recentsSelectedRoomID;
|
$rootScope.recentsSelectedRoomID;
|
||||||
|
|
||||||
var listenToEventStream = function() {
|
var listenToEventStream = function() {
|
||||||
// Refresh the list on matrix invitation and message event
|
// Refresh the list on matrix invitation and message event
|
||||||
$scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
|
$rootScope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
$scope.rooms[event.room_id].lastMsg = event;
|
if (!$rootScope.rooms[event.room_id]) {
|
||||||
|
// The user has joined a new room, which we do not have data yet. The reason is that
|
||||||
|
// the room has appeared in the scope of the user rooms after the global initialSync
|
||||||
|
// FIXME: an initialSync on this specific room should be done
|
||||||
|
$rootScope.rooms[event.room_id] = {
|
||||||
|
room_id:event.room_id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (event.state_key === matrixService.config().user_id && "invite" !== event.membership && "join" !== event.membership) {
|
||||||
|
// The user has been kicked or banned from the room, remove this room from the recents
|
||||||
|
delete $rootScope.rooms[event.room_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rootScope.rooms[event.room_id]) {
|
||||||
|
$rootScope.rooms[event.room_id].lastMsg = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update room users count
|
||||||
|
$rootScope.rooms[event.room_id].numUsersInRoom = getUsersCountInRoom(event.room_id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
|
$rootScope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
$scope.rooms[event.room_id].lastMsg = event;
|
$rootScope.rooms[event.room_id].lastMsg = event;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scope.$on(eventHandlerService.CALL_EVENT, function(ngEvent, event, isLive) {
|
$rootScope.$on(eventHandlerService.CALL_EVENT, function(ngEvent, event, isLive) {
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
$scope.rooms[event.room_id].lastMsg = event;
|
$rootScope.rooms[event.room_id].lastMsg = event;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scope.$on(eventHandlerService.ROOM_CREATE_EVENT, function(ngEvent, event, isLive) {
|
$rootScope.$on(eventHandlerService.ROOM_CREATE_EVENT, function(ngEvent, event, isLive) {
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
$scope.rooms[event.room_id] = event;
|
$rootScope.rooms[event.room_id] = event;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$rootScope.$on(eventHandlerService.NAME_EVENT, function(ngEvent, event, isLive) {
|
||||||
|
if (isLive) {
|
||||||
|
$rootScope.rooms[event.room_id].lastMsg = event;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$rootScope.$on(eventHandlerService.TOPIC_EVENT, function(ngEvent, event, isLive) {
|
||||||
|
if (isLive) {
|
||||||
|
$rootScope.rooms[event.room_id].lastMsg = event;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the room users number, ie the number of members who has joined the room.
|
||||||
|
* @param {String} room_id the room id
|
||||||
|
* @returns {undefined | Number} the room users number if available
|
||||||
|
*/
|
||||||
|
var getUsersCountInRoom = function(room_id) {
|
||||||
|
var memberCount;
|
||||||
|
|
||||||
var refresh = function() {
|
var room = $rootScope.events.rooms[room_id];
|
||||||
// List all rooms joined or been invited to
|
if (room) {
|
||||||
// TODO: This is a pity that event-stream-service.js makes the same call
|
memberCount = 0;
|
||||||
// We should be able to reuse event-stream-service.js fetched data
|
|
||||||
matrixService.rooms(1, false).then(
|
|
||||||
function(response) {
|
|
||||||
// Reset data
|
|
||||||
$scope.rooms = {};
|
|
||||||
|
|
||||||
var rooms = response.data.rooms;
|
for (var i in room.members) {
|
||||||
|
var member = room.members[i];
|
||||||
|
|
||||||
|
if ("join" === member.membership) {
|
||||||
|
memberCount = memberCount + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return memberCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.onInit = function() {
|
||||||
|
// Init recents list only once
|
||||||
|
if ($rootScope.rooms) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootScope.rooms = {};
|
||||||
|
|
||||||
|
// Use initialSync data to init the recents list
|
||||||
|
eventHandlerService.waitForInitialSyncCompletion().then(
|
||||||
|
function(initialSyncData) {
|
||||||
|
|
||||||
|
var rooms = initialSyncData.data.rooms;
|
||||||
for (var i=0; i<rooms.length; i++) {
|
for (var i=0; i<rooms.length; i++) {
|
||||||
var room = rooms[i];
|
var room = rooms[i];
|
||||||
|
|
||||||
// Add room_alias & room_display_name members
|
// Add room_alias & room_display_name members
|
||||||
$scope.rooms[room.room_id] = angular.extend(room, matrixService.getRoomAliasAndDisplayName(room));
|
$rootScope.rooms[room.room_id] = angular.extend(room, matrixService.getRoomAliasAndDisplayName(room));
|
||||||
|
|
||||||
// Create a shortcut for the last message of this room
|
// Create a shortcut for the last message of this room
|
||||||
if (room.messages && room.messages.chunk && room.messages.chunk[0]) {
|
if (room.messages && room.messages.chunk && room.messages.chunk[0]) {
|
||||||
$scope.rooms[room.room_id].lastMsg = room.messages.chunk[0];
|
$rootScope.rooms[room.room_id].lastMsg = room.messages.chunk[0];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var presence = response.data.presence;
|
$rootScope.rooms[room.room_id].numUsersInRoom = getUsersCountInRoom(room.room_id);
|
||||||
for (var i = 0; i < presence.length; ++i) {
|
|
||||||
eventHandlerService.handleEvent(presence[i], false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// From now, update recents from the stream
|
// From now, update recents from the stream
|
||||||
listenToEventStream();
|
listenToEventStream();
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
$scope.feedback = "Failure: " + error.data;
|
$rootScope.feedback = "Failure: " + error.data;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.onInit = function() {
|
// Clean data when user logs out
|
||||||
eventHandlerService.waitForInitialSyncCompletion().then(function() {
|
$scope.$on(eventHandlerService.RESET_EVENT, function() {
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
delete $rootScope.rooms;
|
||||||
|
});
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,18 @@
|
||||||
<td class="recentsRoomName">
|
<td class="recentsRoomName">
|
||||||
{{ room.room_id | mRoomName }}
|
{{ room.room_id | mRoomName }}
|
||||||
</td>
|
</td>
|
||||||
|
<td class="recentsRoomSummaryTS">
|
||||||
|
<span ng-show="undefined !== room.numUsersInRoom">
|
||||||
|
{{ room.numUsersInRoom || '1' }} {{ room.numUsersInRoom == 1 ? 'user' : 'users' }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
<td class="recentsRoomSummaryTS">
|
<td class="recentsRoomSummaryTS">
|
||||||
{{ (room.lastMsg.ts) | date:'MMM d HH:mm' }}
|
{{ (room.lastMsg.ts) | date:'MMM d HH:mm' }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="recentsRoomSummary">
|
<td colspan="3" class="recentsRoomSummary">
|
||||||
|
|
||||||
<div ng-show="room.membership === 'invite'">
|
<div ng-show="room.membership === 'invite'">
|
||||||
{{ room.lastMsg.inviter | mUserDisplayName: room.room_id }} invited you
|
{{ room.lastMsg.inviter | mUserDisplayName: room.room_id }} invited you
|
||||||
|
@ -61,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-switch-when="m.emote">
|
<div ng-switch-when="m.emote">
|
||||||
<span ng-bind-html="'* ' + (room.lastMsg.user_id) + ' ' + room.lastMsg.content.body | linky:'_blank'">
|
<span ng-bind-html="'* ' + (room.lastMsg.user_id | mUserDisplayName: room.room_id) + ' ' + room.lastMsg.content.body | linky:'_blank'">
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -71,6 +76,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ng-switch-when="m.room.topic">
|
||||||
|
{{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} changed the topic to: {{ room.lastMsg.content.topic }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-switch-when="m.room.name">
|
||||||
|
{{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} changed the room name to: {{ room.lastMsg.content.name }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div ng-switch-default>
|
<div ng-switch-default>
|
||||||
<div ng-if="room.lastMsg.type.indexOf('m.call.') === 0">
|
<div ng-if="room.lastMsg.type.indexOf('m.call.') === 0">
|
||||||
Call
|
Call
|
||||||
|
|
|
@ -15,8 +15,8 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
.controller('RoomController', ['$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'eventHandlerService', 'mFileUpload', 'mPresence', 'matrixPhoneService', 'MatrixCall',
|
.controller('RoomController', ['$filter', '$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'eventHandlerService', 'mFileUpload', 'mPresence', 'matrixPhoneService', 'MatrixCall',
|
||||||
function($scope, $timeout, $routeParams, $location, $rootScope, matrixService, eventHandlerService, mFileUpload, mPresence, matrixPhoneService, MatrixCall) {
|
function($filter, $scope, $timeout, $routeParams, $location, $rootScope, matrixService, eventHandlerService, mFileUpload, mPresence, matrixPhoneService, MatrixCall) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var MESSAGES_PER_PAGINATION = 30;
|
var MESSAGES_PER_PAGINATION = 30;
|
||||||
var THUMBNAIL_SIZE = 320;
|
var THUMBNAIL_SIZE = 320;
|
||||||
|
@ -27,12 +27,12 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
|
|
||||||
$scope.state = {
|
$scope.state = {
|
||||||
user_id: matrixService.config().user_id,
|
user_id: matrixService.config().user_id,
|
||||||
events_from: "END", // when to start the event stream from.
|
permission_denied: undefined, // If defined, this string contains the reason why the user cannot join the room
|
||||||
earliest_token: "END", // stores how far back we've paginated.
|
|
||||||
first_pagination: true, // this is toggled off when the first pagination is done
|
first_pagination: true, // this is toggled off when the first pagination is done
|
||||||
can_paginate: true, // this is toggled off when we run out of items
|
can_paginate: false, // this is toggled off when we are not ready yet to paginate or when we run out of items
|
||||||
paginating: false, // used to avoid concurrent pagination requests pulling in dup contents
|
paginating: false, // used to avoid concurrent pagination requests pulling in dup contents
|
||||||
stream_failure: undefined // the response when the stream fails
|
stream_failure: undefined, // the response when the stream fails
|
||||||
|
waiting_for_joined_event: false // true when the join request is pending. Back to false once the corresponding m.room.member event is received
|
||||||
};
|
};
|
||||||
$scope.members = {};
|
$scope.members = {};
|
||||||
$scope.autoCompleting = false;
|
$scope.autoCompleting = false;
|
||||||
|
@ -42,6 +42,85 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
$scope.imageURLToSend = "";
|
$scope.imageURLToSend = "";
|
||||||
$scope.userIDToInvite = "";
|
$scope.userIDToInvite = "";
|
||||||
|
|
||||||
|
|
||||||
|
// vars and functions for updating the name
|
||||||
|
$scope.name = {
|
||||||
|
isEditing: false,
|
||||||
|
newNameText: "",
|
||||||
|
editName: function() {
|
||||||
|
if ($scope.name.isEditing) {
|
||||||
|
console.log("Warning: Already editing name.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use the filter applied in html to set the input value
|
||||||
|
$scope.name.newNameText = $filter('mRoomName')($scope.room_id);
|
||||||
|
|
||||||
|
// Force focus to the input
|
||||||
|
$timeout(function() {
|
||||||
|
angular.element('.roomNameInput').focus();
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
$scope.name.isEditing = true;
|
||||||
|
},
|
||||||
|
updateName: function() {
|
||||||
|
console.log("Updating name to "+$scope.name.newNameText);
|
||||||
|
matrixService.setName($scope.room_id, $scope.name.newNameText).then(
|
||||||
|
function() {
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
$scope.feedback = "Request failed: " + error.data.error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$scope.name.isEditing = false;
|
||||||
|
},
|
||||||
|
cancelEdit: function() {
|
||||||
|
$scope.name.isEditing = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// vars and functions for updating the topic
|
||||||
|
$scope.topic = {
|
||||||
|
isEditing: false,
|
||||||
|
newTopicText: "",
|
||||||
|
editTopic: function() {
|
||||||
|
if ($scope.topic.isEditing) {
|
||||||
|
console.log("Warning: Already editing topic.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var topicEvent = $rootScope.events.rooms[$scope.room_id]['m.room.topic'];
|
||||||
|
if (topicEvent) {
|
||||||
|
$scope.topic.newTopicText = topicEvent.content.topic;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.topic.newTopicText = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force focus to the input
|
||||||
|
$timeout(function() {
|
||||||
|
angular.element('.roomTopicInput').focus();
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
$scope.topic.isEditing = true;
|
||||||
|
},
|
||||||
|
updateTopic: function() {
|
||||||
|
console.log("Updating topic to "+$scope.topic.newTopicText);
|
||||||
|
matrixService.setTopic($scope.room_id, $scope.topic.newTopicText).then(
|
||||||
|
function() {
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
$scope.feedback = "Request failed: " + error.data.error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$scope.topic.isEditing = false;
|
||||||
|
},
|
||||||
|
cancelEdit: function() {
|
||||||
|
$scope.topic.isEditing = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var scrollToBottom = function(force) {
|
var scrollToBottom = function(force) {
|
||||||
console.log("Scrolling to bottom");
|
console.log("Scrolling to bottom");
|
||||||
|
|
||||||
|
@ -81,8 +160,37 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
|
|
||||||
$scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
|
$scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
scrollToBottom();
|
if ($scope.state.waiting_for_joined_event) {
|
||||||
updateMemberList(event);
|
// The user has successfully joined the room, we can getting data for this room
|
||||||
|
$scope.state.waiting_for_joined_event = false;
|
||||||
|
onInit3();
|
||||||
|
}
|
||||||
|
else if (event.state_key === $scope.state.user_id && "invite" !== event.membership && "join" !== event.membership) {
|
||||||
|
var user;
|
||||||
|
|
||||||
|
if ($scope.members[event.user_id]) {
|
||||||
|
user = $scope.members[event.user_id].displayname;
|
||||||
|
}
|
||||||
|
if (user) {
|
||||||
|
user = user + " (" + event.user_id + ")";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
user = event.user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ("ban" === event.membership) {
|
||||||
|
$scope.state.permission_denied = "You have been banned by " + user;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.state.permission_denied = "You have been kicked by " + user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scrollToBottom();
|
||||||
|
updateMemberList(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,12 +227,15 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
else {
|
else {
|
||||||
$scope.state.paginating = true;
|
$scope.state.paginating = true;
|
||||||
}
|
}
|
||||||
// console.log("paginateBackMessages from " + $scope.state.earliest_token + " for " + numItems);
|
|
||||||
|
console.log("paginateBackMessages from " + $rootScope.events.rooms[$scope.room_id].pagination.earliest_token + " for " + numItems);
|
||||||
var originalTopRow = $("#messageTable>tbody>tr:first")[0];
|
var originalTopRow = $("#messageTable>tbody>tr:first")[0];
|
||||||
matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then(
|
|
||||||
|
// Paginate events from the point in cache
|
||||||
|
matrixService.paginateBackMessages($scope.room_id, $rootScope.events.rooms[$scope.room_id].pagination.earliest_token, numItems).then(
|
||||||
function(response) {
|
function(response) {
|
||||||
eventHandlerService.handleEvents(response.data.chunk, false);
|
|
||||||
$scope.state.earliest_token = response.data.end;
|
eventHandlerService.handleRoomMessages($scope.room_id, response.data, false);
|
||||||
if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
|
if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
|
||||||
// no more messages to paginate. this currently never gets turned true again, as we never
|
// no more messages to paginate. this currently never gets turned true again, as we never
|
||||||
// expire paginated contents in the current implementation.
|
// expire paginated contents in the current implementation.
|
||||||
|
@ -419,7 +530,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
var powerLevel = 50; // default power level for op
|
var powerLevel = 50; // default power level for op
|
||||||
if (matches) {
|
if (matches) {
|
||||||
var user_id = matches[1];
|
var user_id = matches[1];
|
||||||
if (matches.length === 4) {
|
if (matches.length === 4 && undefined !== matches[3]) {
|
||||||
powerLevel = parseInt(matches[3]);
|
powerLevel = parseInt(matches[3]);
|
||||||
}
|
}
|
||||||
if (powerLevel !== NaN) {
|
if (powerLevel !== NaN) {
|
||||||
|
@ -472,8 +583,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
room_id: $scope.room_id,
|
room_id: $scope.room_id,
|
||||||
type: "m.room.message",
|
type: "m.room.message",
|
||||||
user_id: $scope.state.user_id,
|
user_id: $scope.state.user_id,
|
||||||
// FIXME: re-enable echo_msg_state when we have a nice way to turn the field off again
|
echo_msg_state: "messagePending" // Add custom field to indicate the state of this fake message to HTML
|
||||||
// echo_msg_state: "messagePending" // Add custom field to indicate the state of this fake message to HTML
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.textInput = "";
|
$scope.textInput = "";
|
||||||
|
@ -482,26 +592,22 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promise) {
|
if (promise) {
|
||||||
|
// Reset previous feedback
|
||||||
|
$scope.feedback = "";
|
||||||
|
|
||||||
promise.then(
|
promise.then(
|
||||||
function() {
|
function(response) {
|
||||||
console.log("Request successfully sent");
|
console.log("Request successfully sent");
|
||||||
if (!echo) {
|
|
||||||
$scope.textInput = "";
|
if (echo) {
|
||||||
}
|
// Mark this fake message event with its allocated event_id
|
||||||
/*
|
// When the true message event will come from the events stream (in handleMessage),
|
||||||
if (echoMessage) {
|
// we will be able to replace the fake one by the true one
|
||||||
// Remove the fake echo message from the room messages
|
echoMessage.event_id = response.data.event_id;
|
||||||
// It will be replaced by the one acknowledged by the server
|
|
||||||
// ...except this causes a nasty flicker. So don't swap messages for now. --matthew
|
|
||||||
// var index = $rootScope.events.rooms[$scope.room_id].messages.indexOf(echoMessage);
|
|
||||||
// if (index > -1) {
|
|
||||||
// $rootScope.events.rooms[$scope.room_id].messages.splice(index, 1);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$scope.textInput = "";
|
$scope.textInput = "";
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
$scope.feedback = "Request failed: " + error.data.error;
|
$scope.feedback = "Request failed: " + error.data.error;
|
||||||
|
@ -596,14 +702,18 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
|
|
||||||
// Do we to join the room before starting?
|
// Do we to join the room before starting?
|
||||||
if (needsToJoin) {
|
if (needsToJoin) {
|
||||||
|
$scope.state.waiting_for_joined_event = true;
|
||||||
matrixService.join($scope.room_id).then(
|
matrixService.join($scope.room_id).then(
|
||||||
function() {
|
function() {
|
||||||
|
// onInit3 will be called once the joined m.room.member event is received from the events stream
|
||||||
|
// This avoids to get the joined information twice in parallel:
|
||||||
|
// - one from the events stream
|
||||||
|
// - one from the pagination because the pagination window covers this event ts
|
||||||
console.log("Joined room "+$scope.room_id);
|
console.log("Joined room "+$scope.room_id);
|
||||||
onInit3();
|
|
||||||
},
|
},
|
||||||
function(reason) {
|
function(reason) {
|
||||||
console.log("Can't join room: " + JSON.stringify(reason));
|
console.log("Can't join room: " + JSON.stringify(reason));
|
||||||
$scope.feedback = "You do not have permission to join this room";
|
$scope.state.permission_denied = "You do not have permission to join this room";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -616,9 +726,6 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
var onInit3 = function() {
|
var onInit3 = function() {
|
||||||
console.log("onInit3");
|
console.log("onInit3");
|
||||||
|
|
||||||
// TODO: We should be able to keep them
|
|
||||||
eventHandlerService.resetRoomMessages($scope.room_id);
|
|
||||||
|
|
||||||
// Make recents highlight the current room
|
// Make recents highlight the current room
|
||||||
$scope.recentsSelectedRoomID = $scope.room_id;
|
$scope.recentsSelectedRoomID = $scope.room_id;
|
||||||
|
|
||||||
|
@ -635,21 +742,24 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
|
|
||||||
// Arm list timing update timer
|
// Arm list timing update timer
|
||||||
updateMemberListPresenceAge();
|
updateMemberListPresenceAge();
|
||||||
|
|
||||||
|
// Start pagination
|
||||||
|
$scope.state.can_paginate = true;
|
||||||
|
paginate(MESSAGES_PER_PAGINATION);
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
$scope.feedback = "Failed get member list: " + error.data.error;
|
$scope.feedback = "Failed get member list: " + error.data.error;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
paginate(MESSAGES_PER_PAGINATION);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.inviteUser = function(user_id) {
|
$scope.inviteUser = function() {
|
||||||
|
|
||||||
matrixService.invite($scope.room_id, user_id).then(
|
matrixService.invite($scope.room_id, $scope.userIDToInvite).then(
|
||||||
function() {
|
function() {
|
||||||
console.log("Invited.");
|
console.log("Invited.");
|
||||||
$scope.feedback = "Invite sent successfully";
|
$scope.feedback = "Invite successfully sent to " + $scope.userIDToInvite;
|
||||||
|
$scope.userIDToInvite = "";
|
||||||
},
|
},
|
||||||
function(reason) {
|
function(reason) {
|
||||||
$scope.feedback = "Failure: " + reason;
|
$scope.feedback = "Failure: " + reason;
|
||||||
|
@ -710,7 +820,15 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||||
var call = new MatrixCall($scope.room_id);
|
var call = new MatrixCall($scope.room_id);
|
||||||
call.onError = $rootScope.onCallError;
|
call.onError = $rootScope.onCallError;
|
||||||
call.onHangup = $rootScope.onCallHangup;
|
call.onHangup = $rootScope.onCallHangup;
|
||||||
call.placeCall();
|
call.placeCall({audio: true, video: false});
|
||||||
|
$rootScope.currentCall = call;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.startVideoCall = function() {
|
||||||
|
var call = new MatrixCall($scope.room_id);
|
||||||
|
call.onError = $rootScope.onCallError;
|
||||||
|
call.onHangup = $rootScope.onCallHangup;
|
||||||
|
call.placeCall({audio: true, video: true});
|
||||||
$rootScope.currentCall = call;
|
$rootScope.currentCall = call;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,31 @@
|
||||||
|
|
||||||
<div id="roomHeader">
|
<div id="roomHeader">
|
||||||
<a href ng-click="goToPage('/')"><img src="img/logo-small.png" width="100" height="43" alt="[matrix]"/></a>
|
<a href ng-click="goToPage('/')"><img src="img/logo-small.png" width="100" height="43" alt="[matrix]"/></a>
|
||||||
<div id="roomName">
|
<div class="roomHeaderInfo">
|
||||||
{{ room_id | mRoomName }}
|
|
||||||
|
<div class="roomNameSection">
|
||||||
|
<div ng-hide="name.isEditing" ng-dblclick="name.editName()" id="roomName">
|
||||||
|
{{ room_id | mRoomName }}
|
||||||
|
</div>
|
||||||
|
<form ng-submit="name.updateName()" ng-show="name.isEditing" class="roomNameForm">
|
||||||
|
<input ng-model="name.newNameText" ng-blur="name.cancelEdit()" class="roomNameInput" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="roomTopicSection">
|
||||||
|
<button ng-hide="events.rooms[room_id]['m.room.topic'].content.topic || topic.isEditing"
|
||||||
|
ng-click="topic.editTopic()" class="roomTopicSetNew">
|
||||||
|
Set Topic
|
||||||
|
</button>
|
||||||
|
<div ng-show="events.rooms[room_id]['m.room.topic'].content.topic || topic.isEditing">
|
||||||
|
<div ng-hide="topic.isEditing" ng-dblclick="topic.editTopic()" id="roomTopic">
|
||||||
|
{{ events.rooms[room_id]['m.room.topic'].content.topic | limitTo: 200}}
|
||||||
|
</div>
|
||||||
|
<form ng-submit="topic.updateTopic()" ng-show="topic.isEditing" class="roomTopicForm">
|
||||||
|
<input ng-model="topic.newTopicText" ng-blur="topic.cancelEdit()" class="roomTopicInput" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -14,14 +37,14 @@
|
||||||
<div ng-include="'recents/recents.html'"></div>
|
<div ng-include="'recents/recents.html'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="usersTableWrapper">
|
<div id="usersTableWrapper" ng-hide="state.permission_denied">
|
||||||
<table id="usersTable">
|
<table id="usersTable">
|
||||||
<tr ng-repeat="member in members | orderMembersList">
|
<tr ng-repeat="member in members | orderMembersList">
|
||||||
<td class="userAvatar mouse-pointer" ng-click="$parent.goToUserPage(member.id)" ng-class="member.membership == 'invite' ? 'invited' : ''">
|
<td class="userAvatar mouse-pointer" ng-click="$parent.goToUserPage(member.id)" ng-class="member.membership == 'invite' ? 'invited' : ''">
|
||||||
<img class="userAvatarImage"
|
<img class="userAvatarImage"
|
||||||
ng-src="{{member.avatar_url || 'img/default-profile.png'}}"
|
ng-src="{{member.avatar_url || 'img/default-profile.png'}}"
|
||||||
alt="{{ member.displayname || member.id.substr(0, member.id.indexOf(':')) }}"
|
alt="{{ member.displayname || member.id.substr(0, member.id.indexOf(':')) }}"
|
||||||
title="{{ member.id }}"
|
title="{{ member.id }} - power: {{ member.powerLevel }}"
|
||||||
width="80" height="80"/>
|
width="80" height="80"/>
|
||||||
<img class="userAvatarGradient" src="img/gradient.png" title="{{ member.id }}" width="80" height="24"/>
|
<img class="userAvatarGradient" src="img/gradient.png" title="{{ member.id }}" width="80" height="24"/>
|
||||||
<div class="userPowerLevel" ng-style="{'width': member.powerLevelNorm +'%'}"></div>
|
<div class="userPowerLevel" ng-style="{'width': member.powerLevelNorm +'%'}"></div>
|
||||||
|
@ -33,7 +56,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="messageTableWrapper" keep-scroll>
|
<div id="messageTableWrapper" ng-hide="state.permission_denied" keep-scroll>
|
||||||
<!-- FIXME: need to have better timestamp semantics than the (msg.content.hsob_ts || msg.ts) hack below -->
|
<!-- FIXME: need to have better timestamp semantics than the (msg.content.hsob_ts || msg.ts) hack below -->
|
||||||
<table id="messageTable" infinite-scroll="paginateMore()">
|
<table id="messageTable" infinite-scroll="paginateMore()">
|
||||||
<tr ng-repeat="msg in events.rooms[room_id].messages"
|
<tr ng-repeat="msg in events.rooms[room_id].messages"
|
||||||
|
@ -49,7 +72,7 @@
|
||||||
<img class="avatarImage" ng-src="{{ members[msg.user_id].avatar_url || 'img/default-profile.png' }}" width="32" height="32"
|
<img class="avatarImage" ng-src="{{ members[msg.user_id].avatar_url || 'img/default-profile.png' }}" width="32" height="32"
|
||||||
ng-hide="events.rooms[room_id].messages[$index - 1].user_id === msg.user_id || msg.user_id === state.user_id"/>
|
ng-hide="events.rooms[room_id].messages[$index - 1].user_id === msg.user_id || msg.user_id === state.user_id"/>
|
||||||
</td>
|
</td>
|
||||||
<td ng-class="!msg.content.membership ? (msg.content.msgtype === 'm.emote' ? 'emote text' : 'text') : 'membership text'">
|
<td ng-class="(!msg.content.membership && ('m.room.topic' !== msg.type && 'm.room.name' !== msg.type))? (msg.content.msgtype === 'm.emote' ? 'emote text' : 'text') : 'membership text'">
|
||||||
<div class="bubble">
|
<div class="bubble">
|
||||||
<span ng-if="'join' === msg.content.membership">
|
<span ng-if="'join' === msg.content.membership">
|
||||||
{{ members[msg.state_key].displayname || msg.state_key }} joined
|
{{ members[msg.state_key].displayname || msg.state_key }} joined
|
||||||
|
@ -76,10 +99,18 @@
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span ng-show='msg.content.msgtype === "m.emote"' ng-bind-html="'* ' + (members[msg.user_id].displayname || msg.user_id) + ' ' + msg.content.body | linky:'_blank'"/>
|
<span ng-show='msg.content.msgtype === "m.emote"'
|
||||||
|
ng-class="msg.echo_msg_state"
|
||||||
|
ng-bind-html="'* ' + (members[msg.user_id].displayname || msg.user_id) + ' ' + msg.content.body | linky:'_blank'"/>
|
||||||
|
|
||||||
<span ng-show='msg.content.msgtype === "m.text"'
|
<span ng-show='msg.content.msgtype === "m.text"'
|
||||||
|
class="message"
|
||||||
ng-class="msg.echo_msg_state"
|
ng-class="msg.echo_msg_state"
|
||||||
ng-bind-html="((msg.content.msgtype === 'm.text') ? msg.content.body : '') | linky:'_blank'"/>
|
ng-bind-html="((msg.content.msgtype === 'm.text') ? msg.content.body : '') | linky:'_blank'"/>
|
||||||
|
|
||||||
|
<span ng-show='msg.type === "m.call.invite" && msg.user_id == state.user_id'>Outgoing Call</span>
|
||||||
|
<span ng-show='msg.type === "m.call.invite" && msg.user_id != state.user_id'>Incoming Call</span>
|
||||||
|
|
||||||
<div ng-show='msg.content.msgtype === "m.image"'>
|
<div ng-show='msg.content.msgtype === "m.image"'>
|
||||||
<div ng-hide='msg.content.thumbnail_url' ng-style="msg.content.body.h && { 'height' : (msg.content.body.h < 320) ? msg.content.body.h : 320}">
|
<div ng-hide='msg.content.thumbnail_url' ng-style="msg.content.body.h && { 'height' : (msg.content.body.h < 320) ? msg.content.body.h : 320}">
|
||||||
<img class="image" ng-src="{{ msg.content.url }}"/>
|
<img class="image" ng-src="{{ msg.content.url }}"/>
|
||||||
|
@ -89,6 +120,15 @@
|
||||||
ng-click="$parent.fullScreenImageURL = msg.content.url"/>
|
ng-click="$parent.fullScreenImageURL = msg.content.url"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span ng-if="'m.room.topic' === msg.type">
|
||||||
|
{{ members[msg.user_id].displayname || msg.user_id }} changed the topic to: {{ msg.content.topic }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span ng-if="'m.room.name' === msg.type">
|
||||||
|
{{ members[msg.user_id].displayname || msg.user_id }} changed the room name to: {{ msg.content.name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="rightBlock">
|
<td class="rightBlock">
|
||||||
|
@ -99,6 +139,10 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ng-show="state.permission_denied">
|
||||||
|
{{ state.permission_denied }}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -110,11 +154,13 @@
|
||||||
{{ state.user_id }}
|
{{ state.user_id }}
|
||||||
</td>
|
</td>
|
||||||
<td width="*">
|
<td width="*">
|
||||||
<input id="mainInput" ng-model="textInput" ng-enter="send()" ng-focus="true" autocomplete="off" tab-complete/>
|
<textarea id="mainInput" rows="1" ng-model="textInput" ng-enter="send()"
|
||||||
|
ng-disabled="state.permission_denied"
|
||||||
|
ng-focus="true" autocomplete="off" tab-complete/>
|
||||||
</td>
|
</td>
|
||||||
<td id="buttonsCell">
|
<td id="buttonsCell">
|
||||||
<button ng-click="send()">Send</button>
|
<button ng-click="send()" ng-disabled="state.permission_denied">Send</button>
|
||||||
<button m-file-input="imageFileToSend" class="extraControls">Image</button>
|
<button m-file-input="imageFileToSend" class="extraControls" ng-disabled="state.permission_denied">Image</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -122,11 +168,11 @@
|
||||||
<div class="extraControls">
|
<div class="extraControls">
|
||||||
<span>
|
<span>
|
||||||
Invite a user:
|
Invite a user:
|
||||||
<input ng-model="userIDToInvite" size="32" type="text" placeholder="User ID (ex:@user:homeserver)"/>
|
<input ng-model="userIDToInvite" size="32" type="text" ng-enter="inviteUser()" ng-disabled="state.permission_denied" placeholder="User ID (ex:@user:homeserver)"/>
|
||||||
<button ng-click="inviteUser(userIDToInvite)">Invite</button>
|
<button ng-click="inviteUser()" ng-disabled="state.permission_denied">Invite</button>
|
||||||
</span>
|
</span>
|
||||||
<button ng-click="leaveRoom()">Leave</button>
|
<button ng-click="leaveRoom()" ng-disabled="state.permission_denied">Leave</button>
|
||||||
<button ng-click="startVoiceCall()" ng-show="(currentCall == undefined || currentCall.state == 'ended') && memberCount() == 2">Voice Call</button>
|
<button ng-click="startVoiceCall()" ng-show="(currentCall == undefined || currentCall.state == 'ended') && memberCount() == 2" ng-disabled="state.permission_denied">Voice Call</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ feedback }}
|
{{ feedback }}
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>/nick <display_name>: change your display name</li>
|
<li>/nick <display_name>: change your display name</li>
|
||||||
<li>/me <action>: send the action you are doing. /me will be replaced by your display name</li>
|
<li>/me <action>: send the action you are doing. /me will be replaced by your display name</li>
|
||||||
|
<li>/join <room_alias>: join a room</li>
|
||||||
<li>/kick <user_id> [<reason>]: kick the user</li>
|
<li>/kick <user_id> [<reason>]: kick the user</li>
|
||||||
<li>/ban <user_id> [<reason>]: ban the user</li>
|
<li>/ban <user_id> [<reason>]: ban the user</li>
|
||||||
<li>/unban <user_id>: unban the user</li>
|
<li>/unban <user_id>: unban the user</li>
|
||||||
|
|
Loading…
Reference in a new issue