aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2015-04-08 00:20:37 +0200
committerMaximilian Hils <git@maximilianhils.com>2015-04-08 00:20:37 +0200
commite7b154c823af60c1aaf008858c637621ca562895 (patch)
tree9380432f9022389a814fe76a363d0d6dd6838329
parent2242c671fd53a5a5a864bcdc085a2207018fd5f0 (diff)
parentb961f9e599453a6116b9b2dffb73dc5b45917f80 (diff)
downloadmitmproxy-e7b154c823af60c1aaf008858c637621ca562895.tar.gz
mitmproxy-e7b154c823af60c1aaf008858c637621ca562895.tar.bz2
mitmproxy-e7b154c823af60c1aaf008858c637621ca562895.zip
Merge branch 'master' of github.com:mitmproxy/mitmproxy
-rw-r--r--libmproxy/cmdline.py7
-rw-r--r--libmproxy/console/__init__.py118
-rw-r--r--libmproxy/console/common.py10
-rw-r--r--libmproxy/console/flowdetailview.py74
-rw-r--r--libmproxy/console/flowlist.py29
-rw-r--r--libmproxy/console/flowview.py19
-rw-r--r--libmproxy/console/help.py86
-rw-r--r--libmproxy/console/options.py270
-rw-r--r--libmproxy/console/palettepicker.py81
-rw-r--r--libmproxy/console/palettes.py111
-rw-r--r--libmproxy/console/searchable.py18
-rw-r--r--libmproxy/console/select.py107
-rw-r--r--libmproxy/console/signals.py2
-rw-r--r--libmproxy/console/statusbar.py1
-rw-r--r--libmproxy/console/tabs.py9
-rw-r--r--libmproxy/console/window.py100
-rw-r--r--libmproxy/flow.py6
-rw-r--r--libmproxy/main.py1
-rw-r--r--libmproxy/web/static/app.js2
-rw-r--r--libmproxy/web/static/vendor.js2694
-rw-r--r--test/test_console_palettes.py4
-rwxr-xr-xtest/tools/testpatt12
-rw-r--r--web/src/js/actions.js2
23 files changed, 2009 insertions, 1754 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index 28aa3ea6..7ea9be8c 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -575,12 +575,17 @@ def mitmproxy():
)
common_options(parser)
parser.add_argument(
- "--palette", type=str, default="dark",
+ "--palette", type=str, default=palettes.DEFAULT,
action="store", dest="palette",
choices=sorted(palettes.palettes.keys()),
help="Select color palette: " + ", ".join(palettes.palettes.keys())
)
parser.add_argument(
+ "--palette-transparent",
+ action="store_true", dest="palette_transparent", default=False,
+ help="Set transparent background for palette."
+ )
+ parser.add_argument(
"-e", "--eventlog",
action="store_true", dest="eventlog",
help="Show event log."
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 660024cc..5c2402f6 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -15,8 +15,8 @@ import urwid
import weakref
from .. import controller, flow, script
-from . import flowlist, flowview, help, common, window, signals
-from . import grideditor, palettes, contentview, flowdetailview, statusbar
+from . import flowlist, flowview, help, window, signals, options
+from . import grideditor, palettes, contentview, statusbar, palettepicker
EVENTLOG_SIZE = 500
@@ -73,6 +73,8 @@ class ConsoleState(flow.State):
elif idx < 0:
idx = 0
self.focus = idx
+ else:
+ self.focus = None
def set_focus_flow(self, f):
self.set_focus(self.view.index(f))
@@ -130,6 +132,7 @@ class Options(object):
"wfile",
"nopop",
"palette",
+ "palette_transparent"
]
def __init__(self, **kwargs):
@@ -154,9 +157,6 @@ class ConsoleMaster(flow.FlowMaster):
for i in options.setheaders:
self.setheaders.add(*i)
- self.flow_list_walker = None
- self.set_palette(options.palette)
-
r = self.set_intercept(options.intercept)
if r:
print >> sys.stderr, "Intercept error:", r
@@ -181,6 +181,8 @@ class ConsoleMaster(flow.FlowMaster):
self.rheaders = options.rheaders
self.nopop = options.nopop
self.showhost = options.showhost
+ self.palette = options.palette
+ self.palette_transparent = options.palette_transparent
self.eventlog = options.eventlog
self.eventlist = urwid.SimpleListWalker([])
@@ -227,6 +229,16 @@ class ConsoleMaster(flow.FlowMaster):
def sig_pop_view_state(self, sender):
if self.view_stack:
self.loop.widget = self.view_stack.pop()
+ else:
+ signals.status_prompt_onekey.send(
+ self,
+ prompt = "Quit",
+ keys = (
+ ("yes", "y"),
+ ("no", "n"),
+ ),
+ callback = self.quit,
+ )
def sig_push_view_state(self, sender):
self.view_stack.append(self.loop.widget)
@@ -379,7 +391,11 @@ class ConsoleMaster(flow.FlowMaster):
os.unlink(name)
def set_palette(self, name):
- self.palette = palettes.palettes[name]
+ self.palette = name
+ self.ui.register_palette(
+ palettes.palettes[name].palette(self.palette_transparent)
+ )
+ self.ui.clear()
def ticker(self, *userdata):
changed = self.tick(self.masterq, timeout=0)
@@ -391,9 +407,7 @@ class ConsoleMaster(flow.FlowMaster):
def run(self):
self.ui = urwid.raw_display.Screen()
self.ui.set_terminal_properties(256)
- self.ui.register_palette(self.palette.palette())
- self.flow_list_walker = flowlist.FlowListWalker(self, self.state)
- self.help_context = None
+ self.set_palette(self.palette)
self.loop = urwid.MainLoop(
urwid.SolidFill("x"),
screen = self.ui,
@@ -444,23 +458,47 @@ class ConsoleMaster(flow.FlowMaster):
sys.stderr.flush()
self.shutdown()
- def view_help(self):
+ def view_help(self, helpctx):
+ signals.push_view_state.send(self)
+ self.loop.widget = window.Window(
+ self,
+ help.HelpView(helpctx),
+ None,
+ statusbar.StatusBar(self, help.footer),
+ None
+ )
+
+ def view_options(self):
+ for i in self.view_stack:
+ if isinstance(i["body"], options.Options):
+ return
signals.push_view_state.send(self)
self.loop.widget = window.Window(
self,
- help.HelpView(self.help_context),
+ options.Options(self),
None,
- statusbar.StatusBar(self, help.footer)
+ statusbar.StatusBar(self, options.footer),
+ options.help_context,
+ )
+
+ def view_palette_picker(self):
+ signals.push_view_state.send(self)
+ self.loop.widget = window.Window(
+ self,
+ palettepicker.PalettePicker(self),
+ None,
+ statusbar.StatusBar(self, palettepicker.footer),
+ palettepicker.help_context,
)
def view_grideditor(self, ge):
signals.push_view_state.send(self)
- self.help_context = ge.make_help()
self.loop.widget = window.Window(
self,
ge,
None,
- statusbar.StatusBar(self, grideditor.FOOTER)
+ statusbar.StatusBar(self, grideditor.FOOTER),
+ ge.make_help()
)
def view_flowlist(self):
@@ -474,24 +512,24 @@ class ConsoleMaster(flow.FlowMaster):
else:
body = flowlist.FlowListBox(self)
- self.help_context = flowlist.help_context
self.loop.widget = window.Window(
self,
body,
None,
- statusbar.StatusBar(self, flowlist.footer)
+ statusbar.StatusBar(self, flowlist.footer),
+ flowlist.help_context
)
self.loop.draw_screen()
def view_flow(self, flow, tab_offset=0):
signals.push_view_state.send(self)
self.state.set_focus_flow(flow)
- self.help_context = flowview.help_context
self.loop.widget = window.Window(
self,
flowview.FlowView(self, self.state, flow, tab_offset),
flowview.FlowViewHeader(self, flow),
- statusbar.StatusBar(self, flowview.footer)
+ statusbar.StatusBar(self, flowview.footer),
+ flowview.help_context
)
def _write_flows(self, path, flows):
@@ -525,8 +563,7 @@ class ConsoleMaster(flow.FlowMaster):
flow.FlowMaster.load_flows_file(self, path)
except flow.FlowReadError, v:
reterr = str(v)
- if self.flow_list_walker:
- self.sync_list_view()
+ signals.flowlist_change.send(self)
return reterr
def accept_all(self):
@@ -534,7 +571,7 @@ class ConsoleMaster(flow.FlowMaster):
def set_limit(self, txt):
v = self.state.set_limit(txt)
- self.sync_list_view()
+ signals.flowlist_change.send(self)
return v
def set_intercept(self, txt):
@@ -553,14 +590,7 @@ class ConsoleMaster(flow.FlowMaster):
self.unload_scripts()
for command in commands:
self.load_script(command)
-
- def edit_ignore_filter(self, ignore):
- patterns = (x[0] for x in ignore)
- self.set_ignore_filter(patterns)
-
- def edit_tcp_filter(self, tcp):
- patterns = (x[0] for x in tcp)
- self.set_tcp_filter(patterns)
+ signals.update_settings.send(self)
def stop_client_playback_prompt(self, a):
if a != "n":
@@ -574,35 +604,13 @@ class ConsoleMaster(flow.FlowMaster):
if a != "n":
raise urwid.ExitMainLoop
- def _change_options(self, a):
- if a == "a":
- self.anticache = not self.anticache
- if a == "c":
- self.anticomp = not self.anticomp
- if a == "h":
- self.showhost = not self.showhost
- self.sync_list_view()
- self.refresh_focus()
- elif a == "k":
- self.killextra = not self.killextra
- elif a == "n":
- self.refresh_server_playback = not self.refresh_server_playback
- elif a == "u":
- self.server.config.no_upstream_cert =\
- not self.server.config.no_upstream_cert
- signals.update_settings.send(self)
-
def shutdown(self):
self.state.killall(self)
flow.FlowMaster.shutdown(self)
- def sync_list_view(self):
- self.flow_list_walker._modified()
- signals.update_settings.send(self)
-
def clear_flows(self):
self.state.clear()
- self.sync_list_view()
+ signals.flowlist_change.send(self)
def toggle_follow_flows(self):
# toggle flow follow
@@ -610,11 +618,11 @@ class ConsoleMaster(flow.FlowMaster):
# jump to most recent flow if follow is now on
if self.state.follow_focus:
self.state.set_focus(self.state.flow_count())
- self.sync_list_view()
+ signals.flowlist_change.send(self)
def delete_flow(self, f):
self.state.delete_flow(f)
- self.sync_list_view()
+ signals.flowlist_change.send(self)
def refresh_focus(self):
if self.state.view:
@@ -628,7 +636,7 @@ class ConsoleMaster(flow.FlowMaster):
f.intercept(self)
else:
f.reply()
- self.sync_list_view()
+ signals.flowlist_change.send(self)
signals.flow_change.send(self, flow = f)
def clear_events(self):
diff --git a/libmproxy/console/common.py b/libmproxy/console/common.py
index bc8a2aad..23d3a4a4 100644
--- a/libmproxy/console/common.py
+++ b/libmproxy/console/common.py
@@ -37,14 +37,14 @@ def is_keypress(k):
return True
-def highlight_key(s, k):
+def highlight_key(str, key, textattr="text", keyattr="key"):
l = []
- parts = s.split(k, 1)
+ parts = str.split(key, 1)
if parts[0]:
- l.append(("text", parts[0]))
- l.append(("key", k))
+ l.append((textattr, parts[0]))
+ l.append((keyattr, key))
if parts[1]:
- l.append(("text", parts[1]))
+ l.append((textattr, parts[1]))
return l
diff --git a/libmproxy/console/flowdetailview.py b/libmproxy/console/flowdetailview.py
index 99f2a262..48845a62 100644
--- a/libmproxy/console/flowdetailview.py
+++ b/libmproxy/console/flowdetailview.py
@@ -1,8 +1,17 @@
from __future__ import absolute_import
import urwid
-from . import common, signals, searchable
+from . import common, searchable
from .. import utils
+
+def maybe_timestamp(base, attr):
+ if base and getattr(base, attr):
+ return utils.format_timestamp_with_milli(getattr(base, attr))
+ else:
+ return "active"
+ pass
+
+
def flowdetails(state, flow):
text = []
@@ -81,16 +90,61 @@ def flowdetails(state, flow):
parts = []
- parts.append(["Client conn. established", utils.format_timestamp_with_milli(cc.timestamp_start) if (cc and cc.timestamp_start) else "active"])
- parts.append(["Server conn. initiated", utils.format_timestamp_with_milli(sc.timestamp_start) if sc else "active" ])
- parts.append(["Server conn. TCP handshake", utils.format_timestamp_with_milli(sc.timestamp_tcp_setup) if (sc and sc.timestamp_tcp_setup) else "active"])
+ parts.append(
+ [
+ "Client conn. established",
+ maybe_timestamp(cc, "timestamp_start")
+ ]
+ )
+ parts.append(
+ [
+ "Server conn. initiated",
+ maybe_timestamp(sc, "timestamp_start")
+ ]
+ )
+ parts.append(
+ [
+ "Server conn. TCP handshake",
+ maybe_timestamp(sc, "timestamp_tcp_setup")
+ ]
+ )
if sc.ssl_established:
- parts.append(["Server conn. SSL handshake", utils.format_timestamp_with_milli(sc.timestamp_ssl_setup) if sc.timestamp_ssl_setup else "active"])
- parts.append(["Client conn. SSL handshake", utils.format_timestamp_with_milli(cc.timestamp_ssl_setup) if (cc and cc.timestamp_ssl_setup) else "active"])
- parts.append(["First request byte", utils.format_timestamp_with_milli(req.timestamp_start)])
- parts.append(["Request complete", utils.format_timestamp_with_milli(req.timestamp_end) if req.timestamp_end else "active"])
- parts.append(["First response byte", utils.format_timestamp_with_milli(resp.timestamp_start) if resp else "active"])
- parts.append(["Response complete", utils.format_timestamp_with_milli(resp.timestamp_end) if (resp and resp.timestamp_end) else "active"])
+ parts.append(
+ [
+ "Server conn. SSL handshake",
+ maybe_timestamp(sc, "timestamp_ssl_setup")
+ ]
+ )
+ parts.append(
+ [
+ "Client conn. SSL handshake",
+ maybe_timestamp(cc, "timestamp_ssl_setup")
+ ]
+ )
+ parts.append(
+ [
+ "First request byte",
+ maybe_timestamp(req, "timestamp_start")
+ ]
+ )
+ parts.append(
+ [
+ "Request complete",
+ maybe_timestamp(req, "timestamp_end")
+ ]
+ )
+ parts.append(
+ [
+ "First response byte",
+ maybe_timestamp(resp, "timestamp_start")
+ ]
+ )
+ parts.append(
+ [
+ "Response complete",
+ maybe_timestamp(resp, "timestamp_end")
+ ]
+ )
# sort operations by timestamp
parts = sorted(parts, key=lambda p: p[1])
diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py
index 946bd97b..aa3fd718 100644
--- a/libmproxy/console/flowlist.py
+++ b/libmproxy/console/flowlist.py
@@ -15,10 +15,10 @@ def _mkhelp():
("D", "duplicate flow"),
("e", "toggle eventlog"),
("F", "toggle follow flow list"),
- ("g", "copy flow to clipboard"),
("l", "set limit filter pattern"),
("L", "load saved flows"),
("n", "create a new request"),
+ ("P", "copy flow to clipboard"),
("r", "replay request"),
("V", "revert changes to request"),
("w", "save flows "),
@@ -157,11 +157,11 @@ class ConnectionItem(urwid.WidgetWrap):
key = common.shortcuts(key)
if key == "a":
self.flow.accept_intercept(self.master)
- self.master.sync_list_view()
+ signals.flowlist_change.send(self)
elif key == "d":
self.flow.kill(self.master)
self.state.delete_flow(self.flow)
- self.master.sync_list_view()
+ signals.flowlist_change.send(self)
elif key == "D":
f = self.master.duplicate_flow(self.flow)
self.master.view_flow(f)
@@ -169,7 +169,7 @@ class ConnectionItem(urwid.WidgetWrap):
r = self.master.replay_request(self.flow)
if r:
signals.status_message.send(message=r)
- self.master.sync_list_view()
+ signals.flowlist_change.send(self)
elif key == "S":
if not self.master.server_playback:
signals.status_prompt_onekey.send(
@@ -195,7 +195,7 @@ class ConnectionItem(urwid.WidgetWrap):
signals.status_message.send(message="Flow not modified.")
return
self.state.revert(self.flow)
- self.master.sync_list_view()
+ signals.flowlist_change.send(self)
signals.status_message.send(message="Reverted.")
elif key == "w":
signals.status_prompt_onekey.send(
@@ -218,7 +218,7 @@ class ConnectionItem(urwid.WidgetWrap):
callback = self.master.run_script_once,
args = (self.flow,)
)
- elif key == "g":
+ elif key == "P":
common.ask_copy_part("a", self.flow, self.master, self.state)
elif key == "b":
common.ask_save_body(None, self.master, self.state, self.flow)
@@ -231,6 +231,10 @@ class FlowListWalker(urwid.ListWalker):
self.master, self.state = master, state
if self.state.flow_count():
self.set_focus(0)
+ signals.flowlist_change.connect(self.sig_flowlist_change)
+
+ def sig_flowlist_change(self, sender):
+ self._modified()
def get_focus(self):
f, i = self.state.get_focus()
@@ -255,7 +259,10 @@ class FlowListWalker(urwid.ListWalker):
class FlowListBox(urwid.ListBox):
def __init__(self, master):
self.master = master
- urwid.ListBox.__init__(self, master.flow_list_walker)
+ urwid.ListBox.__init__(
+ self,
+ FlowListWalker(master, master.state)
+ )
def get_method_raw(self, k):
if k:
@@ -297,11 +304,17 @@ class FlowListBox(urwid.ListBox):
key = common.shortcuts(key)
if key == "A":
self.master.accept_all()
- self.master.sync_list_view()
+ signals.flowlist_change.send(self)
elif key == "C":
self.master.clear_flows()
elif key == "e":
self.master.toggle_eventlog()
+ elif key == "G":
+ self.master.state.set_focus(0)
+ signals.flowlist_change.send(self)
+ elif key == "g":
+ self.master.state.set_focus(self.master.state.flow_count())
+ signals.flowlist_change.send(self)
elif key == "l":
signals.status_prompt.send(
prompt = "Limit",
diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py
index 538f42f0..9776f2b1 100644
--- a/libmproxy/console/flowview.py
+++ b/libmproxy/console/flowview.py
@@ -20,7 +20,6 @@ def _mkhelp():
("D", "duplicate flow"),
("e", "edit request/response"),
("f", "load full body data"),
- ("g", "copy response(content/headers) to clipboard"),
("m", "change body display mode for this entity"),
(None,
common.highlight_key("automatic", "a") +
@@ -60,6 +59,7 @@ def _mkhelp():
),
("M", "change default body display mode"),
("p", "previous flow"),
+ ("P", "copy response(content/headers) to clipboard"),
("r", "replay request"),
("V", "revert changes to request"),
("v", "view body in external viewer"),
@@ -68,6 +68,7 @@ def _mkhelp():
("x", "delete body"),
("z", "encode/decode a request/response"),
("tab", "next tab"),
+ ("h, l", "previous tab, next tab"),
("space", "next flow"),
("|", "run script on this flow"),
("/", "search (case sensitive)"),
@@ -434,6 +435,8 @@ class FlowView(tabs.Tabs):
signals.flow_change.send(self, flow = self.flow)
def keypress(self, size, key):
+ key = super(self.__class__, self).keypress(size, key)
+
if key == " ":
self.view_next_flow(self.flow)
return
@@ -446,10 +449,7 @@ class FlowView(tabs.Tabs):
else:
conn = None
- if key == "q":
- signals.pop_view_state.send(self)
- return None
- elif key in ("up", "down", "page up", "page down"):
+ if key in ("up", "down", "page up", "page down"):
# Why doesn't this just work??
self._w.keypress(size, key)
elif key == "a":
@@ -499,7 +499,7 @@ class FlowView(tabs.Tabs):
args = (self.flow,)
)
- if not conn and key in "befgmxvz":
+ if not conn and key in set(list("befgmxvz")):
signals.status_message.send(
message = "Tab to the request or response",
expire = 1
@@ -546,7 +546,7 @@ class FlowView(tabs.Tabs):
)
signals.flow_change.send(self, flow = self.flow)
signals.status_message.send(message="")
- elif key == "g":
+ elif key == "P":
if self.tab_offset == TAB_REQ:
scope = "q"
else:
@@ -601,10 +601,7 @@ class FlowView(tabs.Tabs):
args = (conn,)
)
signals.flow_change.send(self, flow = self.flow)
- else:
- return super(self.__class__, self).keypress(size, key)
- else:
- return super(self.__class__, self).keypress(size, key)
+ return key
def encode_callback(self, key, conn):
encoding_map = {
diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py
index 73cd8a50..6d36ee71 100644
--- a/libmproxy/console/help.py
+++ b/libmproxy/console/help.py
@@ -28,6 +28,7 @@ class HelpView(urwid.ListBox):
keys = [
("j, k", "down, up"),
("h, l", "left, right (in some contexts)"),
+ ("g, G", "go to end, beginning"),
("space", "page down"),
("pg up/down", "page up/down"),
("arrows", "up, down, left, right"),
@@ -37,92 +38,11 @@ class HelpView(urwid.ListBox):
text.append(urwid.Text([("head", "\n\nGlobal keys:\n")]))
keys = [
("c", "client replay"),
- ("H", "edit global header set patterns"),
- ("I", "set ignore pattern"),
("i", "set interception pattern"),
- ("M", "change global default display mode"),
- (None,
- common.highlight_key("automatic", "a") +
- [("text", ": automatic detection")]
- ),
- (None,
- common.highlight_key("hex", "e") +
- [("text", ": Hex")]
- ),
- (None,
- common.highlight_key("html", "h") +
- [("text", ": HTML")]
- ),
- (None,
- common.highlight_key("image", "i") +
- [("text", ": Image")]
- ),
- (None,
- common.highlight_key("javascript", "j") +
- [("text", ": JavaScript")]
- ),
- (None,
- common.highlight_key("json", "s") +
- [("text", ": JSON")]
- ),
- (None,
- common.highlight_key("css", "c") +
- [("text", ": CSS")]
- ),
- (None,
- common.highlight_key("urlencoded", "u") +
- [("text", ": URL-encoded data")]
- ),
- (None,
- common.highlight_key("raw", "r") +
- [("text", ": raw data")]
- ),
- (None,
- common.highlight_key("xml", "x") +
- [("text", ": XML")]
- ),
- (None,
- common.highlight_key("wbxml", "w") +
- [("text", ": WBXML")]
- ),
- (None,
- common.highlight_key("amf", "f") +
- [("text", ": AMF (requires PyAMF)")]
- ),
- ("o", "toggle options:"),
- (None,
- common.highlight_key("anticache", "a") +
- [("text", ": prevent cached responses")]
- ),
- (None,
- common.highlight_key("anticomp", "c") +
- [("text", ": prevent compressed responses")]
- ),
- (None,
- common.highlight_key("showhost", "h") +
- [("text", ": use Host header for URL display")]
- ),
- (None,
- common.highlight_key("killextra", "k") +
- [("text", ": kill requests not part of server replay")]
- ),
- (None,
- common.highlight_key("norefresh", "n") +
- [("text", ": disable server replay response refresh")]
- ),
- (None,
- common.highlight_key("upstream certs", "u") +
- [("text", ": sniff cert info from upstream server")]
- ),
-
- ("q", "quit / return to flow list"),
+ ("o", "options"),
+ ("q", "quit / return to previous page"),
("Q", "quit without confirm prompt"),
- ("R", "edit replacement patterns"),
- ("s", "add/remove scripts"),
("S", "server replay"),
- ("t", "set sticky cookie expression"),
- ("T", "set tcp proxying pattern"),
- ("u", "set sticky auth expression"),
]
text.extend(
common.format_keyvals(keys, key="key", val="text", indent=4)
diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py
new file mode 100644
index 00000000..dc7e00d5
--- /dev/null
+++ b/libmproxy/console/options.py
@@ -0,0 +1,270 @@
+import urwid
+
+from . import common, signals, grideditor, contentview
+from . import select, palettes
+
+footer = [
+ ('heading_key', "enter/space"), ":toggle ",
+ ('heading_key', "C"), ":clear all ",
+]
+
+def _mkhelp():
+ text = []
+ keys = [
+ ("enter/space", "activate option"),
+ ("C", "clear all options"),
+ ]
+ text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
+ return text
+help_context = _mkhelp()
+
+
+class Options(urwid.WidgetWrap):
+ def __init__(self, master):
+ self.master = master
+ self.lb = select.Select(
+ [
+ select.Heading("Traffic Manipulation"),
+ select.Option(
+ "Header Set Patterns",
+ "H",
+ lambda: master.setheaders.count(),
+ self.setheaders
+ ),
+ select.Option(
+ "Ignore Patterns",
+ "I",
+ lambda: master.server.config.check_ignore,
+ self.ignorepatterns
+ ),
+ select.Option(
+ "Replacement Patterns",
+ "R",
+ lambda: master.replacehooks.count(),
+ self.replacepatterns
+ ),
+ select.Option(
+ "Scripts",
+ "S",
+ lambda: master.scripts,
+ self.scripts
+ ),
+
+ select.Heading("Interface"),
+ select.Option(
+ "Default Display Mode",
+ "M",
+ self.has_default_displaymode,
+ self.default_displaymode
+ ),
+ select.Option(
+ "Palette",
+ "P",
+ lambda: self.master.palette != palettes.DEFAULT,
+ self.palette
+ ),
+ select.Option(
+ "Show Host",
+ "w",
+ lambda: master.showhost,
+ self.toggle_showhost
+ ),
+
+ select.Heading("Network"),
+ select.Option(
+ "No Upstream Certs",
+ "U",
+ lambda: master.server.config.no_upstream_cert,
+ self.toggle_upstream_cert
+ ),
+ select.Option(
+ "TCP Proxying",
+ "T",
+ lambda: master.server.config.check_tcp,
+ self.tcp_proxy
+ ),
+
+ select.Heading("Utility"),
+ select.Option(
+ "Anti-Cache",
+ "a",
+ lambda: master.anticache,
+ self.toggle_anticache
+ ),
+ select.Option(
+ "Anti-Compression",
+ "o",
+ lambda: master.anticomp,
+ self.toggle_anticomp
+ ),
+ select.Option(
+ "Kill Extra",
+ "x",
+ lambda: master.killextra,
+ self.toggle_killextra
+ ),
+ select.Option(
+ "No Refresh",
+ "f",
+ lambda: not master.refresh_server_playback,
+ self.toggle_refresh_server_playback
+ ),
+ select.Option(
+ "Sticky Auth",
+ "A",
+ lambda: master.stickyauth_txt,
+ self.sticky_auth
+ ),
+ select.Option(
+ "Sticky Cookies",
+ "t",
+ lambda: master.stickycookie_txt,
+ self.sticky_cookie
+ ),
+ ]
+ )
+ title = urwid.Text("Options")
+ title = urwid.Padding(title, align="left", width=("relative", 100))
+ title = urwid.AttrWrap(title, "heading")
+ self._w = urwid.Frame(
+ self.lb,
+ header = title
+ )
+ self.master.loop.widget.footer.update("")
+ signals.update_settings.connect(self.sig_update_settings)
+
+ def sig_update_settings(self, sender):
+ self.lb.walker._modified()
+
+ def keypress(self, size, key):
+ if key == "C":
+ self.clearall()
+ return None
+ return super(self.__class__, self).keypress(size, key)
+
+ def clearall(self):
+ self.master.anticache = False
+ self.master.anticomp = False
+ self.master.killextra = False
+ self.master.showhost = False
+ self.master.refresh_server_playback = True
+ self.master.server.config.no_upstream_cert = False
+ self.master.setheaders.clear()
+ self.master.replacehooks.clear()
+ self.master.set_ignore_filter([])
+ self.master.set_tcp_filter([])
+ self.master.scripts = []
+ self.master.set_stickyauth(None)
+ self.master.set_stickycookie(None)
+ self.master.state.default_body_view = contentview.get("Auto")
+
+ signals.update_settings.send(self)
+ signals.status_message.send(
+ message = "All select.Options cleared",
+ expire = 1
+ )
+
+ def toggle_anticache(self):
+ self.master.anticache = not self.master.anticache
+
+ def toggle_anticomp(self):
+ self.master.anticomp = not self.master.anticomp
+
+ def toggle_killextra(self):
+ self.master.killextra = not self.master.killextra
+
+ def toggle_showhost(self):
+ self.master.showhost = not self.master.showhost
+
+ def toggle_refresh_server_playback(self):
+ self.master.refresh_server_playback = not self.master.refresh_server_playback
+
+ def toggle_upstream_cert(self):
+ self.master.server.config.no_upstream_cert = not self.master.server.config.no_upstream_cert
+ signals.update_settings.send(self)
+
+ def setheaders(self):
+ def _set(*args, **kwargs):
+ self.master.setheaders.set(*args, **kwargs)
+ signals.update_settings.send(self)
+ self.master.view_grideditor(
+ grideditor.SetHeadersEditor(
+ self.master,
+ self.master.setheaders.get_specs(),
+ _set
+ )
+ )
+
+ def ignorepatterns(self):
+ def _set(ignore):
+ patterns = (x[0] for x in ignore)
+ self.master.set_ignore_filter(patterns)
+ signals.update_settings.send(self)
+ self.master.view_grideditor(
+ grideditor.HostPatternEditor(
+ self.master,
+ [[x] for x in self.master.get_ignore_filter()],
+ _set
+ )
+ )
+
+ def replacepatterns(self):
+ def _set(*args, **kwargs):
+ self.master.replacehooks.set(*args, **kwargs)
+ signals.update_settings.send(self)
+ self.master.view_grideditor(
+ grideditor.ReplaceEditor(
+ self.master,
+ self.master.replacehooks.get_specs(),
+ _set
+ )
+ )
+
+ def scripts(self):
+ self.master.view_grideditor(
+ grideditor.ScriptEditor(
+ self.master,
+ [[i.command] for i in self.master.scripts],
+ self.master.edit_scripts
+ )
+ )
+
+ def default_displaymode(self):
+ signals.status_prompt_onekey.send(
+ prompt = "Global default display mode",
+ keys = contentview.view_prompts,
+ callback = self.master.change_default_display_mode
+ )
+
+ def has_default_displaymode(self):
+ return self.master.state.default_body_view.name != "Auto"
+
+ def tcp_proxy(self):
+ def _set(tcp):
+ patterns = (x[0] for x in tcp)
+ self.master.set_tcp_filter(patterns)
+ signals.update_settings.send(self)
+ self.master.view_grideditor(
+ grideditor.HostPatternEditor(
+ self.master,
+ [[x] for x in self.master.get_tcp_filter()],
+ _set
+ )
+ )
+
+ def sticky_auth(self):
+ signals.status_prompt.send(
+ prompt = "Sticky auth filter",
+ text = self.master.stickyauth_txt,
+ callback = self.master.set_stickyauth
+ )
+
+ def sticky_cookie(self):
+ signals.status_prompt.send(
+ prompt = "Sticky cookie filter",
+ text = self.master.stickycookie_txt,
+ callback = self.master.set_stickycookie
+ )
+
+ def palette(self):
+ self.master.view_palette_picker()
diff --git a/libmproxy/console/palettepicker.py b/libmproxy/console/palettepicker.py
new file mode 100644
index 00000000..7e2c10cd
--- /dev/null
+++ b/libmproxy/console/palettepicker.py
@@ -0,0 +1,81 @@
+import urwid
+
+from . import select, common, palettes, signals
+
+footer = [
+ ('heading_key', "enter/space"), ":select",
+]
+
+
+def _mkhelp():
+ text = []
+ keys = [
+ ("enter/space", "select"),
+ ]
+ text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
+ return text
+help_context = _mkhelp()
+
+
+class PalettePicker(urwid.WidgetWrap):
+ def __init__(self, master):
+ self.master = master
+ low, high = [], []
+ for k, v in palettes.palettes.items():
+ if v.high:
+ high.append(k)
+ else:
+ low.append(k)
+ high.sort()
+ low.sort()
+
+ options = [
+ select.Heading("High Colour")
+ ]
+
+ def mkopt(name):
+ return select.Option(
+ i,
+ None,
+ lambda: self.master.palette == name,
+ lambda: self.select(name)
+ )
+
+ for i in high:
+ options.append(mkopt(i))
+ options.append(select.Heading("Low Colour"))
+ for i in low:
+ options.append(mkopt(i))
+
+ options.extend(
+ [
+ select.Heading("Options"),
+ select.Option(
+ "Transparent",
+ "T",
+ lambda: master.palette_transparent,
+ self.toggle_palette_transparent
+ )
+ ]
+ )
+
+ self.lb = select.Select(options)
+ title = urwid.Text("Palettes")
+ title = urwid.Padding(title, align="left", width=("relative", 100))
+ title = urwid.AttrWrap(title, "heading")
+ self._w = urwid.Frame(
+ self.lb,
+ header = title
+ )
+ signals.update_settings.connect(self.sig_update_settings)
+
+ def sig_update_settings(self, sender):
+ self.lb.walker._modified()
+
+ def select(self, name):
+ self.master.set_palette(name)
+
+ def toggle_palette_transparent(self):
+ self.master.palette_transparent = not self.master.palette_transparent
+ self.master.set_palette(self.master.palette)
+ signals.update_settings.send(self)
diff --git a/libmproxy/console/palettes.py b/libmproxy/console/palettes.py
index cfb2702c..e34233a6 100644
--- a/libmproxy/console/palettes.py
+++ b/libmproxy/console/palettes.py
@@ -1,4 +1,3 @@
-
# Low-color themes should ONLY use the standard foreground and background
# colours listed here:
#
@@ -6,9 +5,9 @@
#
-
class Palette:
_fields = [
+ 'background',
'title',
# Status bar & heading
@@ -17,6 +16,10 @@ class Palette:
# Help
'key', 'head', 'text',
+ # Options
+ 'option_selected', 'option_active', 'option_active_selected',
+ 'option_selected_key',
+
# List and Connections
'method', 'focus',
'code_200', 'code_300', 'code_400', 'code_500', 'code_other',
@@ -31,15 +34,33 @@ class Palette:
]
high = None
- def palette(self):
+ def palette(self, transparent):
l = []
+ highback, lowback = None, None
+ if not transparent:
+ if self.high and self.high.get("background"):
+ highback = self.high["background"][1]
+ lowback = self.low["background"][1]
+
for i in self._fields:
- v = [i]
- v.extend(self.low[i])
- if self.high and i in self.high:
- v.append(None)
- v.extend(self.high[i])
- l.append(tuple(v))
+ if transparent and i == "background":
+ l.append(["background", "default", "default"])
+ else:
+ v = [i]
+ low = list(self.low[i])
+ if lowback and low[1] == "default":
+ low[1] = lowback
+ v.extend(low)
+ if self.high and i in self.high:
+ v.append(None)
+ high = list(self.high[i])
+ if highback and high[1] == "default":
+ high[1] = highback
+ v.extend(high)
+ elif highback and self.low[i][1] == "default":
+ high = [None, low[0], highback]
+ v.extend(high)
+ l.append(tuple(v))
return l
@@ -48,18 +69,25 @@ class LowDark(Palette):
Low-color dark background
"""
low = dict(
+ background = ('white', 'black'),
title = ('white,bold', 'default'),
# Status bar & heading
- heading = ('light gray', 'dark blue'),
+ heading = ('white', 'dark blue'),
heading_key = ('light cyan', 'dark blue'),
- heading_inactive = ('white', 'dark gray'),
+ heading_inactive = ('dark gray', 'light gray'),
# Help
key = ('light cyan', 'default'),
head = ('white,bold', 'default'),
text = ('light gray', 'default'),
+ # Options
+ option_selected = ('black', 'light gray'),
+ option_selected_key = ('light cyan', 'light gray'),
+ option_active = ('light red', 'default'),
+ option_active_selected = ('light red', 'light gray'),
+
# List and Connections
method = ('dark cyan', 'default'),
focus = ('yellow', 'default'),
@@ -92,6 +120,10 @@ class Dark(LowDark):
high = dict(
heading_inactive = ('g58', 'g11'),
intercept = ('#f60', 'default'),
+
+ option_selected = ('g85', 'g45'),
+ option_selected_key = ('light cyan', 'g50'),
+ option_active_selected = ('light red', 'g50'),
)
@@ -100,18 +132,25 @@ class LowLight(Palette):
Low-color light background
"""
low = dict(
- title = ('dark magenta,bold', 'light blue'),
+ background = ('black', 'white'),
+ title = ('dark magenta', 'default'),
# Status bar & heading
- heading = ('light gray', 'dark blue'),
- heading_key = ('light cyan', 'dark blue'),
+ heading = ('white', 'black'),
+ heading_key = ('dark blue', 'black'),
heading_inactive = ('black', 'light gray'),
# Help
- key = ('dark blue,bold', 'default'),
- head = ('black,bold', 'default'),
+ key = ('dark blue', 'default'),
+ head = ('black', 'default'),
text = ('dark gray', 'default'),
+ # Options
+ option_selected = ('black', 'light gray'),
+ option_selected_key = ('dark blue', 'light gray'),
+ option_active = ('light red', 'default'),
+ option_active_selected = ('light red', 'light gray'),
+
# List and Connections
method = ('dark cyan', 'default'),
focus = ('black', 'default'),
@@ -142,10 +181,15 @@ class LowLight(Palette):
class Light(LowLight):
high = dict(
+ background = ('black', 'g100'),
heading = ('g99', '#08f'),
heading_key = ('#0ff,bold', '#08f'),
heading_inactive = ('g35', 'g85'),
replay = ('#0a0,bold', 'default'),
+
+ option_selected = ('black', 'g85'),
+ option_selected_key = ('dark blue', 'g85'),
+ option_active_selected = ('light red', 'g85'),
)
@@ -155,10 +199,10 @@ sol_base03 = "h234"
sol_base02 = "h235"
sol_base01 = "h240"
sol_base00 = "h241"
-sol_base0 = "h244"
-sol_base1 = "h245"
-sol_base2 = "h254"
-sol_base3 = "h230"
+sol_base0 = "h244"
+sol_base1 = "h245"
+sol_base2 = "h254"
+sol_base3 = "h230"
sol_yellow = "h136"
sol_orange = "h166"
sol_red = "h160"
@@ -167,9 +211,12 @@ sol_violet = "h61"
sol_blue = "h33"
sol_cyan = "h37"
sol_green = "h64"
+
+
class SolarizedLight(LowLight):
high = dict(
- title = (sol_blue, 'default'),
+ background = (sol_base00, sol_base3),
+ title = (sol_cyan, 'default'),
text = (sol_base00, 'default'),
# Status bar & heading
@@ -181,6 +228,12 @@ class SolarizedLight(LowLight):
key = (sol_blue, 'default',),
head = (sol_base00, 'default'),
+ # Options
+ option_selected = (sol_base03, sol_base2),
+ option_selected_key = (sol_blue, sol_base2),
+ option_active = (sol_orange, 'default'),
+ option_active_selected = (sol_orange, sol_base2),
+
# List and Connections
method = (sol_cyan, 'default'),
focus = (sol_base01, 'default'),
@@ -211,17 +264,24 @@ class SolarizedLight(LowLight):
class SolarizedDark(LowDark):
high = dict(
+ background = (sol_base2, sol_base03),
title = (sol_blue, 'default'),
- text = (sol_base0, 'default'),
+ text = (sol_base1, 'default'),
# Status bar & heading
- heading = (sol_base03, sol_base1),
- heading_key = (sol_blue+",bold", sol_base1),
+ heading = (sol_base2, sol_base01),
+ heading_key = (sol_blue+",bold", sol_base01),
heading_inactive = (sol_base1, sol_base02),
# Help
key = (sol_blue, 'default',),
- head = (sol_base00, 'default'),
+ head = (sol_base2, 'default'),
+
+ # Options
+ option_selected = (sol_base03, sol_base00),
+ option_selected_key = (sol_blue, sol_base00),
+ option_active = (sol_orange, 'default'),
+ option_active_selected = (sol_orange, sol_base00),
# List and Connections
method = (sol_cyan, 'default'),
@@ -251,6 +311,7 @@ class SolarizedDark(LowDark):
)
+DEFAULT = "dark"
palettes = {
"lowlight": LowLight(),
"lowdark": LowDark(),
diff --git a/libmproxy/console/searchable.py b/libmproxy/console/searchable.py
index 9d66c718..a9572ae3 100644
--- a/libmproxy/console/searchable.py
+++ b/libmproxy/console/searchable.py
@@ -15,10 +15,8 @@ class Highlight(urwid.AttrMap):
class Searchable(urwid.ListBox):
def __init__(self, state, contents):
- urwid.ListBox.__init__(
- self,
- urwid.SimpleFocusListWalker(contents)
- )
+ self.walker = urwid.SimpleFocusListWalker(contents)
+ urwid.ListBox.__init__(self, self.walker)
self.state = state
self.search_offset = 0
self.current_highlight = None
@@ -31,12 +29,18 @@ class Searchable(urwid.ListBox):
text = "",
callback = self.set_search
)
- if key == "n":
+ elif key == "n":
self.find_next(False)
- if key == "N":
+ elif key == "N":
self.find_next(True)
+ elif key == "G":
+ self.set_focus(0)
+ self.walker._modified()
+ elif key == "g":
+ self.set_focus(len(self.walker)-1)
+ self.walker._modified()
else:
- return key
+ return super(self.__class__, self).keypress(size, key)
def set_search(self, text):
self.state.last_search = text
diff --git a/libmproxy/console/select.py b/libmproxy/console/select.py
new file mode 100644
index 00000000..61ee50e4
--- /dev/null
+++ b/libmproxy/console/select.py
@@ -0,0 +1,107 @@
+import urwid
+
+from . import common
+
+class _OptionWidget(urwid.WidgetWrap):
+ def __init__(self, option, text, shortcut, active, focus):
+ self.option = option
+ textattr = "text"
+ keyattr = "key"
+ if focus and active:
+ textattr = "option_active_selected"
+ keyattr = "option_selected_key"
+ elif focus:
+ textattr = "option_selected"
+ keyattr = "option_selected_key"
+ elif active:
+ textattr = "option_active"
+ if shortcut:
+ text = common.highlight_key(
+ text,
+ shortcut,
+ textattr = textattr,
+ keyattr = keyattr
+ )
+ opt = urwid.Text(text, align="left")
+ opt = urwid.AttrWrap(opt, textattr)
+ opt = urwid.Padding(opt, align = "center", width = 40)
+ urwid.WidgetWrap.__init__(self, opt)
+
+ def keypress(self, size, key):
+ return key
+
+ def selectable(self):
+ return True
+
+
+class OptionWalker(urwid.ListWalker):
+ def __init__(self, options):
+ urwid.ListWalker.__init__(self)
+ self.options = options
+ self.focus = 0
+
+ def set_focus(self, pos):
+ self.focus = pos
+
+ def get_focus(self):
+ return self.options[self.focus].render(True), self.focus
+
+ def get_next(self, pos):
+ if pos >= len(self.options)-1:
+ return None, None
+ return self.options[pos+1].render(False), pos+1
+
+ def get_prev(self, pos):
+ if pos <= 0:
+ return None, None
+ return self.options[pos-1].render(False), pos-1
+
+
+class Heading:
+ def __init__(self, text):
+ self.text = text
+
+ def render(self, focus):
+ opt = urwid.Text("\n" + self.text, align="left")
+ opt = urwid.AttrWrap(opt, "title")
+ opt = urwid.Padding(opt, align = "center", width = 40)
+ return opt
+
+
+_neg = lambda: False
+class Option:
+ def __init__(self, text, shortcut, getstate=None, activate=None):
+ self.text = text
+ self.shortcut = shortcut
+ self.getstate = getstate or _neg
+ self.activate = activate or _neg
+
+ def render(self, focus):
+ return _OptionWidget(self, self.text, self.shortcut, self.getstate(), focus)
+
+
+class Select(urwid.ListBox):
+ def __init__(self, options):
+ self.walker = OptionWalker(options)
+ urwid.ListBox.__init__(
+ self,
+ self.walker
+ )
+ self.options = options
+ self.keymap = {}
+ for i in options:
+ if hasattr(i, "shortcut") and i.shortcut:
+ if i.shortcut in self.keymap:
+ raise ValueError("Duplicate shortcut key: %s"%i.shortcut)
+ self.keymap[i.shortcut] = i
+
+ def keypress(self, size, key):
+ if key == "enter" or key == " ":
+ self.get_focus()[0].option.activate()
+ return None
+ key = common.shortcuts(key)
+ if key in self.keymap:
+ self.keymap[key].activate()
+ self.set_focus(self.options.index(self.keymap[key]))
+ return None
+ return super(self.__class__, self).keypress(size, key)
diff --git a/libmproxy/console/signals.py b/libmproxy/console/signals.py
index e4c11f5a..c1bcf201 100644
--- a/libmproxy/console/signals.py
+++ b/libmproxy/console/signals.py
@@ -24,6 +24,8 @@ update_settings = blinker.Signal()
# Fired when a flow changes
flow_change = blinker.Signal()
+# Fired when the flow list or focus changes
+flowlist_change = blinker.Signal()
# Pop and push view state onto a stack
pop_view_state = blinker.Signal()
diff --git a/libmproxy/console/statusbar.py b/libmproxy/console/statusbar.py
index 7fb15aa6..5455ad6e 100644
--- a/libmproxy/console/statusbar.py
+++ b/libmproxy/console/statusbar.py
@@ -114,6 +114,7 @@ class StatusBar(urwid.WidgetWrap):
self.ib = urwid.WidgetWrap(urwid.Text(""))
self._w = urwid.Pile([self.ib, self.ab])
signals.update_settings.connect(self.sig_update_settings)
+ signals.flowlist_change.connect(self.sig_update_settings)
self.redraw()
def sig_update_settings(self, sender):
diff --git a/libmproxy/console/tabs.py b/libmproxy/console/tabs.py
index b8943ad4..2c46e59e 100644
--- a/libmproxy/console/tabs.py
+++ b/libmproxy/console/tabs.py
@@ -14,11 +14,13 @@ class Tabs(urwid.WidgetWrap):
return p
def keypress(self, size, key):
- if key == "tab":
+ if key in ["tab", "l"]:
self.tab_offset = (self.tab_offset + 1)%(len(self.tabs))
self.show()
- else:
- return self._w.keypress(size, key)
+ elif key == "h":
+ self.tab_offset = (self.tab_offset - 1)%(len(self.tabs))
+ self.show()
+ return self._w.keypress(size, key)
def show(self):
headers = []
@@ -33,3 +35,4 @@ class Tabs(urwid.WidgetWrap):
body = self.tabs[self.tab_offset][1](),
header = headers
)
+ self._w.set_focus("body")
diff --git a/libmproxy/console/window.py b/libmproxy/console/window.py
index d686f61d..d64e83df 100644
--- a/libmproxy/console/window.py
+++ b/libmproxy/console/window.py
@@ -1,19 +1,26 @@
import urwid
-from . import common, grideditor, signals, contentview
+from . import signals
+
class Window(urwid.Frame):
- def __init__(self, master, body, header, footer):
- urwid.Frame.__init__(self, body, header=header, footer=footer)
+ def __init__(self, master, body, header, footer, helpctx):
+ urwid.Frame.__init__(
+ self,
+ urwid.AttrWrap(body, "background"),
+ header = urwid.AttrWrap(header, "background") if header else None,
+ footer = urwid.AttrWrap(footer, "background") if footer else None
+ )
self.master = master
+ self.helpctx = helpctx
signals.focus.connect(self.sig_focus)
def sig_focus(self, sender, section):
self.focus_position = section
def keypress(self, size, k):
- k = urwid.Frame.keypress(self, self.master.loop.screen_size, k)
+ k = super(self.__class__, self).keypress(size, k)
if k == "?":
- self.master.view_help()
+ self.master.view_help(self.helpctx)
elif k == "c":
if not self.master.client_playback:
signals.status_prompt_path.send(
@@ -31,30 +38,6 @@ class Window(urwid.Frame):
),
callback = self.master.stop_client_playback_prompt,
)
- elif k == "H":
- self.master.view_grideditor(
- grideditor.SetHeadersEditor(
- self.master,
- self.master.setheaders.get_specs(),
- self.master.setheaders.set
- )
- )
- elif k == "I":
- self.master.view_grideditor(
- grideditor.HostPatternEditor(
- self.master,
- [[x] for x in self.master.get_ignore_filter()],
- self.master.edit_ignore_filter
- )
- )
- elif k == "T":
- self.master.view_grideditor(
- grideditor.HostPatternEditor(
- self.master,
- [[x] for x in self.master.get_tcp_filter()],
- self.master.edit_tcp_filter
- )
- )
elif k == "i":
signals.status_prompt.send(
self,
@@ -62,40 +45,12 @@ class Window(urwid.Frame):
text = self.master.state.intercept_txt,
callback = self.master.set_intercept
)
+ elif k == "o":
+ self.master.view_options()
elif k == "Q":
raise urwid.ExitMainLoop
elif k == "q":
- signals.status_prompt_onekey.send(
- self,
- prompt = "Quit",
- keys = (
- ("yes", "y"),
- ("no", "n"),
- ),
- callback = self.master.quit,
- )
- elif k == "M":
- signals.status_prompt_onekey.send(
- prompt = "Global default display mode",
- keys = contentview.view_prompts,
- callback = self.master.change_default_display_mode
- )
- elif k == "R":
- self.master.view_grideditor(
- grideditor.ReplaceEditor(
- self.master,
- self.master.replacehooks.get_specs(),
- self.master.replacehooks.set
- )
- )
- elif k == "s":
- self.master.view_grideditor(
- grideditor.ScriptEditor(
- self.master,
- [[i.command] for i in self.master.scripts],
- self.master.edit_scripts
- )
- )
+ signals.pop_view_state.send(self)
elif k == "S":
if not self.master.server_playback:
signals.status_prompt_path.send(
@@ -113,30 +68,5 @@ class Window(urwid.Frame):
),
callback = self.master.stop_server_playback_prompt,
)
- elif k == "o":
- signals.status_prompt_onekey.send(
- prompt = "Options",
- keys = (
- ("anticache", "a"),
- ("anticomp", "c"),
- ("showhost", "h"),
- ("killextra", "k"),
- ("norefresh", "n"),
- ("no-upstream-certs", "u"),
- ),
- callback = self.master._change_options
- )
- elif k == "t":
- signals.status_prompt.send(
- prompt = "Sticky cookie filter",
- text = self.master.stickycookie_txt,
- callback = self.master.set_stickycookie
- )
- elif k == "u":
- signals.status_prompt.send(
- prompt = "Sticky auth filter",
- text = self.master.stickyauth_txt,
- callback = self.master.set_stickyauth
- )
else:
return k
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index eb8ee16a..680b6a20 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -736,7 +736,7 @@ class FlowMaster(controller.Master):
ignore_payload_params: list of content params to ignore in server replay
ignore_host: true if request host should be ignored in server replay
"""
- self.server_playback = ServerPlaybackState(headers, flows, exit, nopop,
+ self.server_playback = ServerPlaybackState(headers, flows, exit, nopop,
ignore_params, ignore_content,
ignore_payload_params, ignore_host)
self.kill_nonreplay = kill
@@ -786,7 +786,7 @@ class FlowMaster(controller.Master):
def create_request(self, method, scheme, host, port, path):
"""
this method creates a new artificial and minimalist request also adds it to flowlist
- """
+ """
c = ClientConnection.from_state(dict(
address=dict(address=(host, port), use_ipv6=False),
clientcert=None
@@ -802,7 +802,7 @@ class FlowMaster(controller.Master):
))
f = http.HTTPFlow(c,s);
headers = ODictCaseless()
-
+
req = http.HTTPRequest("absolute", method, scheme, host, port, path, (1, 1), headers, None,
None, None, None)
f.request = req
diff --git a/libmproxy/main.py b/libmproxy/main.py
index a29fdb9d..7d56a505 100644
--- a/libmproxy/main.py
+++ b/libmproxy/main.py
@@ -89,6 +89,7 @@ def mitmproxy(args=None): # pragma: nocover
proxy_config = process_proxy_options(parser, options)
console_options = console.Options(**cmdline.get_common_options(options))
console_options.palette = options.palette
+ console_options.palette_transparent = options.palette_transparent
console_options.eventlog = options.eventlog
console_options.intercept = options.intercept
diff --git a/libmproxy/web/static/app.js b/libmproxy/web/static/app.js
index 24082b40..62cd8357 100644
--- a/libmproxy/web/static/app.js
+++ b/libmproxy/web/static/app.js
@@ -420,7 +420,7 @@ var FlowActions = {
});
},
clear: function(){
- $.post("/flows/" + flow.id);
+ $.post("/clear");
}
};
diff --git a/libmproxy/web/static/vendor.js b/libmproxy/web/static/vendor.js
index 1e83ac50..fbd6b1a4 100644
--- a/libmproxy/web/static/vendor.js
+++ b/libmproxy/web/static/vendor.js
@@ -394,422 +394,6 @@ var invariant = function(condition, format, a, b, c, d, e, f) {
module.exports = invariant;
},{}],4:[function(require,module,exports){
-module.exports = require('./lib/');
-
-},{"./lib/":5}],5:[function(require,module,exports){
-// Load modules
-
-var Stringify = require('./stringify');
-var Parse = require('./parse');
-
-
-// Declare internals
-
-var internals = {};
-
-
-module.exports = {
- stringify: Stringify,
- parse: Parse
-};
-
-},{"./parse":6,"./stringify":7}],6:[function(require,module,exports){
-// Load modules
-
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {
- delimiter: '&',
- depth: 5,
- arrayLimit: 20,
- parameterLimit: 1000
-};
-
-
-internals.parseValues = function (str, options) {
-
- var obj = {};
- var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
-
- for (var i = 0, il = parts.length; i < il; ++i) {
- var part = parts[i];
- var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
-
- if (pos === -1) {
- obj[Utils.decode(part)] = '';
- }
- else {
- var key = Utils.decode(part.slice(0, pos));
- var val = Utils.decode(part.slice(pos + 1));
-
- if (Object.prototype.hasOwnProperty(key)) {
- continue;
- }
-
- if (!obj.hasOwnProperty(key)) {
- obj[key] = val;
- }
- else {
- obj[key] = [].concat(obj[key]).concat(val);
- }
- }
- }
-
- return obj;
-};
-
-
-internals.parseObject = function (chain, val, options) {
-
- if (!chain.length) {
- return val;
- }
-
- var root = chain.shift();
-
- var obj = {};
- if (root === '[]') {
- obj = [];
- obj = obj.concat(internals.parseObject(chain, val, options));
- }
- else {
- var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
- var index = parseInt(cleanRoot, 10);
- var indexString = '' + index;
- if (!isNaN(index) &&
- root !== cleanRoot &&
- indexString === cleanRoot &&
- index >= 0 &&
- index <= options.arrayLimit) {
-
- obj = [];
- obj[index] = internals.parseObject(chain, val, options);
- }
- else {
- obj[cleanRoot] = internals.parseObject(chain, val, options);
- }
- }
-
- return obj;
-};
-
-
-internals.parseKeys = function (key, val, options) {
-
- if (!key) {
- return;
- }
-
- // The regex chunks
-
- var parent = /^([^\[\]]*)/;
- var child = /(\[[^\[\]]*\])/g;
-
- // Get the parent
-
- var segment = parent.exec(key);
-
- // Don't allow them to overwrite object prototype properties
-
- if (Object.prototype.hasOwnProperty(segment[1])) {
- return;
- }
-
- // Stash the parent if it exists
-
- var keys = [];
- if (segment[1]) {
- keys.push(segment[1]);
- }
-
- // Loop through children appending to the array until we hit depth
-
- var i = 0;
- while ((segment = child.exec(key)) !== null && i < options.depth) {
-
- ++i;
- if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
- keys.push(segment[1]);
- }
- }
-
- // If there's a remainder, just add whatever is left
-
- if (segment) {
- keys.push('[' + key.slice(segment.index) + ']');
- }
-
- return internals.parseObject(keys, val, options);
-};
-
-
-module.exports = function (str, options) {
-
- if (str === '' ||
- str === null ||
- typeof str === 'undefined') {
-
- return {};
- }
-
- options = options || {};
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
- options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
- options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
- options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
-
- var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
- var obj = {};
-
- // Iterate over the keys and setup the new object
-
- var keys = Object.keys(tempObj);
- for (var i = 0, il = keys.length; i < il; ++i) {
- var key = keys[i];
- var newObj = internals.parseKeys(key, tempObj[key], options);
- obj = Utils.merge(obj, newObj);
- }
-
- return Utils.compact(obj);
-};
-
-},{"./utils":8}],7:[function(require,module,exports){
-// Load modules
-
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {
- delimiter: '&',
- arrayPrefixGenerators: {
- brackets: function (prefix, key) {
- return prefix + '[]';
- },
- indices: function (prefix, key) {
- return prefix + '[' + key + ']';
- },
- repeat: function (prefix, key) {
- return prefix;
- }
- }
-};
-
-
-internals.stringify = function (obj, prefix, generateArrayPrefix) {
-
- if (Utils.isBuffer(obj)) {
- obj = obj.toString();
- }
- else if (obj instanceof Date) {
- obj = obj.toISOString();
- }
- else if (obj === null) {
- obj = '';
- }
-
- if (typeof obj === 'string' ||
- typeof obj === 'number' ||
- typeof obj === 'boolean') {
-
- return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)];
- }
-
- var values = [];
-
- if (typeof obj === 'undefined') {
- return values;
- }
-
- var objKeys = Object.keys(obj);
- for (var i = 0, il = objKeys.length; i < il; ++i) {
- var key = objKeys[i];
- if (Array.isArray(obj)) {
- values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
- }
- else {
- values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
- }
- }
-
- return values;
-};
-
-
-module.exports = function (obj, options) {
-
- options = options || {};
- var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
-
- var keys = [];
-
- if (typeof obj !== 'object' ||
- obj === null) {
-
- return '';
- }
-
- var arrayFormat;
- if (options.arrayFormat in internals.arrayPrefixGenerators) {
- arrayFormat = options.arrayFormat;
- }
- else if ('indices' in options) {
- arrayFormat = options.indices ? 'indices' : 'repeat';
- }
- else {
- arrayFormat = 'indices';
- }
-
- var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
-
- var objKeys = Object.keys(obj);
- for (var i = 0, il = objKeys.length; i < il; ++i) {
- var key = objKeys[i];
- keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
- }
-
- return keys.join(delimiter);
-};
-
-},{"./utils":8}],8:[function(require,module,exports){
-// Load modules
-
-
-// Declare internals
-
-var internals = {};
-
-
-exports.arrayToObject = function (source) {
-
- var obj = {};
- for (var i = 0, il = source.length; i < il; ++i) {
- if (typeof source[i] !== 'undefined') {
-
- obj[i] = source[i];
- }
- }
-
- return obj;
-};
-
-
-exports.merge = function (target, source) {
-
- if (!source) {
- return target;
- }
-
- if (typeof source !== 'object') {
- if (Array.isArray(target)) {
- target.push(source);
- }
- else {
- target[source] = true;
- }
-
- return target;
- }
-
- if (typeof target !== 'object') {
- target = [target].concat(source);
- return target;
- }
-
- if (Array.isArray(target) &&
- !Array.isArray(source)) {
-
- target = exports.arrayToObject(target);
- }
-
- var keys = Object.keys(source);
- for (var k = 0, kl = keys.length; k < kl; ++k) {
- var key = keys[k];
- var value = source[key];
-
- if (!target[key]) {
- target[key] = value;
- }
- else {
- target[key] = exports.merge(target[key], value);
- }
- }
-
- return target;
-};
-
-
-exports.decode = function (str) {
-
- try {
- return decodeURIComponent(str.replace(/\+/g, ' '));
- } catch (e) {
- return str;
- }
-};
-
-
-exports.compact = function (obj, refs) {
-
- if (typeof obj !== 'object' ||
- obj === null) {
-
- return obj;
- }
-
- refs = refs || [];
- var lookup = refs.indexOf(obj);
- if (lookup !== -1) {
- return refs[lookup];
- }
-
- refs.push(obj);
-
- if (Array.isArray(obj)) {
- var compacted = [];
-
- for (var i = 0, il = obj.length; i < il; ++i) {
- if (typeof obj[i] !== 'undefined') {
- compacted.push(obj[i]);
- }
- }
-
- return compacted;
- }
-
- var keys = Object.keys(obj);
- for (i = 0, il = keys.length; i < il; ++i) {
- var key = keys[i];
- obj[key] = exports.compact(obj[key], refs);
- }
-
- return obj;
-};
-
-
-exports.isRegExp = function (obj) {
- return Object.prototype.toString.call(obj) === '[object RegExp]';
-};
-
-
-exports.isBuffer = function (obj) {
-
- if (obj === null ||
- typeof obj === 'undefined') {
-
- return false;
- }
-
- return !!(obj.constructor &&
- obj.constructor.isBuffer &&
- obj.constructor.isBuffer(obj));
-};
-
-},{}],9:[function(require,module,exports){
"use strict";
/**
@@ -819,7 +403,7 @@ exports.isBuffer = function (obj) {
function Cancellation() {}
module.exports = Cancellation;
-},{}],10:[function(require,module,exports){
+},{}],5:[function(require,module,exports){
"use strict";
var invariant = require("react/lib/invariant");
@@ -850,7 +434,7 @@ var History = {
};
module.exports = History;
-},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],11:[function(require,module,exports){
+},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],6:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -928,7 +512,7 @@ var Match = (function () {
})();
module.exports = Match;
-},{"./PathUtils":13}],12:[function(require,module,exports){
+},{"./PathUtils":8}],7:[function(require,module,exports){
"use strict";
var warning = require("react/lib/warning");
@@ -1008,7 +592,7 @@ var Navigation = {
};
module.exports = Navigation;
-},{"./PropTypes":14,"react/lib/warning":212}],13:[function(require,module,exports){
+},{"./PropTypes":9,"react/lib/warning":212}],8:[function(require,module,exports){
"use strict";
var invariant = require("react/lib/invariant");
@@ -1162,7 +746,7 @@ var PathUtils = {
};
module.exports = PathUtils;
-},{"object-assign":41,"qs":4,"react/lib/invariant":191}],14:[function(require,module,exports){
+},{"object-assign":36,"qs":37,"react/lib/invariant":191}],9:[function(require,module,exports){
"use strict";
var assign = require("react/lib/Object.assign");
@@ -1194,7 +778,7 @@ var PropTypes = assign({}, ReactPropTypes, {
});
module.exports = PropTypes;
-},{"./Route":16,"react":"react","react/lib/Object.assign":69}],15:[function(require,module,exports){
+},{"./Route":11,"react":"react","react/lib/Object.assign":69}],10:[function(require,module,exports){
"use strict";
/**
@@ -1207,7 +791,7 @@ function Redirect(to, params, query) {
}
module.exports = Redirect;
-},{}],16:[function(require,module,exports){
+},{}],11:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -1415,7 +999,7 @@ var Route = (function () {
})();
module.exports = Route;
-},{"./PathUtils":13,"react/lib/Object.assign":69,"react/lib/invariant":191,"react/lib/warning":212}],17:[function(require,module,exports){
+},{"./PathUtils":8,"react/lib/Object.assign":69,"react/lib/invariant":191,"react/lib/warning":212}],12:[function(require,module,exports){
"use strict";
var invariant = require("react/lib/invariant");
@@ -1491,7 +1075,7 @@ var ScrollHistory = {
};
module.exports = ScrollHistory;
-},{"./getWindowScrollPosition":32,"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],18:[function(require,module,exports){
+},{"./getWindowScrollPosition":27,"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],13:[function(require,module,exports){
"use strict";
var warning = require("react/lib/warning");
@@ -1575,7 +1159,7 @@ var State = {
};
module.exports = State;
-},{"./PropTypes":14,"react/lib/warning":212}],19:[function(require,module,exports){
+},{"./PropTypes":9,"react/lib/warning":212}],14:[function(require,module,exports){
"use strict";
/* jshint -W058 */
@@ -1651,7 +1235,7 @@ Transition.to = function (transition, routes, params, query, callback) {
};
module.exports = Transition;
-},{"./Cancellation":9,"./Redirect":15}],20:[function(require,module,exports){
+},{"./Cancellation":4,"./Redirect":10}],15:[function(require,module,exports){
"use strict";
/**
@@ -1677,7 +1261,7 @@ var LocationActions = {
};
module.exports = LocationActions;
-},{}],21:[function(require,module,exports){
+},{}],16:[function(require,module,exports){
"use strict";
var LocationActions = require("../actions/LocationActions");
@@ -1707,7 +1291,7 @@ var ImitateBrowserBehavior = {
};
module.exports = ImitateBrowserBehavior;
-},{"../actions/LocationActions":20}],22:[function(require,module,exports){
+},{"../actions/LocationActions":15}],17:[function(require,module,exports){
"use strict";
/**
@@ -1723,7 +1307,7 @@ var ScrollToTopBehavior = {
};
module.exports = ScrollToTopBehavior;
-},{}],23:[function(require,module,exports){
+},{}],18:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -1763,7 +1347,7 @@ var ContextWrapper = (function (_React$Component) {
})(React.Component);
module.exports = ContextWrapper;
-},{"react":"react"}],24:[function(require,module,exports){
+},{"react":"react"}],19:[function(require,module,exports){
"use strict";
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
@@ -1811,7 +1395,7 @@ DefaultRoute.defaultProps = {
};
module.exports = DefaultRoute;
-},{"../PropTypes":14,"./Route":28,"./RouteHandler":29}],25:[function(require,module,exports){
+},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],20:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -1950,7 +1534,7 @@ Link.defaultProps = {
};
module.exports = Link;
-},{"../PropTypes":14,"react":"react","react/lib/Object.assign":69}],26:[function(require,module,exports){
+},{"../PropTypes":9,"react":"react","react/lib/Object.assign":69}],21:[function(require,module,exports){
"use strict";
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
@@ -1999,7 +1583,7 @@ NotFoundRoute.defaultProps = {
};
module.exports = NotFoundRoute;
-},{"../PropTypes":14,"./Route":28,"./RouteHandler":29}],27:[function(require,module,exports){
+},{"../PropTypes":9,"./Route":23,"./RouteHandler":24}],22:[function(require,module,exports){
"use strict";
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
@@ -2043,7 +1627,7 @@ Redirect.propTypes = {
Redirect.defaultProps = {};
module.exports = Redirect;
-},{"../PropTypes":14,"./Route":28}],28:[function(require,module,exports){
+},{"../PropTypes":9,"./Route":23}],23:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -2136,7 +1720,7 @@ Route.defaultProps = {
};
module.exports = Route;
-},{"../PropTypes":14,"./RouteHandler":29,"react":"react","react/lib/invariant":191}],29:[function(require,module,exports){
+},{"../PropTypes":9,"./RouteHandler":24,"react":"react","react/lib/invariant":191}],24:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -2237,7 +1821,7 @@ RouteHandler.childContextTypes = {
};
module.exports = RouteHandler;
-},{"../PropTypes":14,"./ContextWrapper":23,"react":"react","react/lib/Object.assign":69}],30:[function(require,module,exports){
+},{"../PropTypes":9,"./ContextWrapper":18,"react":"react","react/lib/Object.assign":69}],25:[function(require,module,exports){
(function (process){
"use strict";
@@ -2754,7 +2338,7 @@ function createRouter(options) {
module.exports = createRouter;
}).call(this,require('_process'))
-},{"./Cancellation":9,"./History":10,"./Match":11,"./PathUtils":13,"./PropTypes":14,"./Redirect":15,"./Route":16,"./ScrollHistory":17,"./Transition":19,"./actions/LocationActions":20,"./behaviors/ImitateBrowserBehavior":21,"./createRoutesFromReactChildren":31,"./isReactChildren":33,"./locations/HashLocation":34,"./locations/HistoryLocation":35,"./locations/RefreshLocation":36,"./locations/StaticLocation":37,"./supportsHistory":40,"_process":1,"react":"react","react/lib/ExecutionEnvironment":62,"react/lib/invariant":191,"react/lib/warning":212}],31:[function(require,module,exports){
+},{"./Cancellation":4,"./History":5,"./Match":6,"./PathUtils":8,"./PropTypes":9,"./Redirect":10,"./Route":11,"./ScrollHistory":12,"./Transition":14,"./actions/LocationActions":15,"./behaviors/ImitateBrowserBehavior":16,"./createRoutesFromReactChildren":26,"./isReactChildren":28,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./supportsHistory":35,"_process":1,"react":"react","react/lib/ExecutionEnvironment":62,"react/lib/invariant":191,"react/lib/warning":212}],26:[function(require,module,exports){
"use strict";
/* jshint -W084 */
@@ -2836,7 +2420,7 @@ function createRoutesFromReactChildren(children) {
}
module.exports = createRoutesFromReactChildren;
-},{"./Route":16,"./components/DefaultRoute":24,"./components/NotFoundRoute":26,"./components/Redirect":27,"react":"react","react/lib/Object.assign":69,"react/lib/warning":212}],32:[function(require,module,exports){
+},{"./Route":11,"./components/DefaultRoute":19,"./components/NotFoundRoute":21,"./components/Redirect":22,"react":"react","react/lib/Object.assign":69,"react/lib/warning":212}],27:[function(require,module,exports){
"use strict";
var invariant = require("react/lib/invariant");
@@ -2855,7 +2439,7 @@ function getWindowScrollPosition() {
}
module.exports = getWindowScrollPosition;
-},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],33:[function(require,module,exports){
+},{"react/lib/ExecutionEnvironment":62,"react/lib/invariant":191}],28:[function(require,module,exports){
"use strict";
var React = require("react");
@@ -2869,7 +2453,7 @@ function isReactChildren(object) {
}
module.exports = isReactChildren;
-},{"react":"react"}],34:[function(require,module,exports){
+},{"react":"react"}],29:[function(require,module,exports){
"use strict";
var LocationActions = require("../actions/LocationActions");
@@ -2981,7 +2565,7 @@ var HashLocation = {
};
module.exports = HashLocation;
-},{"../History":10,"../actions/LocationActions":20}],35:[function(require,module,exports){
+},{"../History":5,"../actions/LocationActions":15}],30:[function(require,module,exports){
"use strict";
var LocationActions = require("../actions/LocationActions");
@@ -3068,7 +2652,7 @@ var HistoryLocation = {
};
module.exports = HistoryLocation;
-},{"../History":10,"../actions/LocationActions":20}],36:[function(require,module,exports){
+},{"../History":5,"../actions/LocationActions":15}],31:[function(require,module,exports){
"use strict";
var HistoryLocation = require("./HistoryLocation");
@@ -3100,7 +2684,7 @@ var RefreshLocation = {
};
module.exports = RefreshLocation;
-},{"../History":10,"./HistoryLocation":35}],37:[function(require,module,exports){
+},{"../History":5,"./HistoryLocation":30}],32:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -3151,7 +2735,7 @@ StaticLocation.prototype.replace = throwCannotModify;
StaticLocation.prototype.pop = throwCannotModify;
module.exports = StaticLocation;
-},{"react/lib/invariant":191}],38:[function(require,module,exports){
+},{"react/lib/invariant":191}],33:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@@ -3247,7 +2831,7 @@ var TestLocation = (function () {
})();
module.exports = TestLocation;
-},{"../History":10,"../actions/LocationActions":20,"react/lib/invariant":191}],39:[function(require,module,exports){
+},{"../History":5,"../actions/LocationActions":15,"react/lib/invariant":191}],34:[function(require,module,exports){
"use strict";
var createRouter = require("./createRouter");
@@ -3298,7 +2882,7 @@ function runRouter(routes, location, callback) {
}
module.exports = runRouter;
-},{"./createRouter":30}],40:[function(require,module,exports){
+},{"./createRouter":25}],35:[function(require,module,exports){
"use strict";
function supportsHistory() {
@@ -3315,7 +2899,7 @@ function supportsHistory() {
}
module.exports = supportsHistory;
-},{}],41:[function(require,module,exports){
+},{}],36:[function(require,module,exports){
'use strict';
function ToObject(val) {
@@ -3343,6 +2927,422 @@ module.exports = Object.assign || function (target, source) {
return to;
};
+},{}],37:[function(require,module,exports){
+module.exports = require('./lib/');
+
+},{"./lib/":38}],38:[function(require,module,exports){
+// Load modules
+
+var Stringify = require('./stringify');
+var Parse = require('./parse');
+
+
+// Declare internals
+
+var internals = {};
+
+
+module.exports = {
+ stringify: Stringify,
+ parse: Parse
+};
+
+},{"./parse":39,"./stringify":40}],39:[function(require,module,exports){
+// Load modules
+
+var Utils = require('./utils');
+
+
+// Declare internals
+
+var internals = {
+ delimiter: '&',
+ depth: 5,
+ arrayLimit: 20,
+ parameterLimit: 1000
+};
+
+
+internals.parseValues = function (str, options) {
+
+ var obj = {};
+ var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
+
+ for (var i = 0, il = parts.length; i < il; ++i) {
+ var part = parts[i];
+ var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
+
+ if (pos === -1) {
+ obj[Utils.decode(part)] = '';
+ }
+ else {
+ var key = Utils.decode(part.slice(0, pos));
+ var val = Utils.decode(part.slice(pos + 1));
+
+ if (Object.prototype.hasOwnProperty(key)) {
+ continue;
+ }
+
+ if (!obj.hasOwnProperty(key)) {
+ obj[key] = val;
+ }
+ else {
+ obj[key] = [].concat(obj[key]).concat(val);
+ }
+ }
+ }
+
+ return obj;
+};
+
+
+internals.parseObject = function (chain, val, options) {
+
+ if (!chain.length) {
+ return val;
+ }
+
+ var root = chain.shift();
+
+ var obj = {};
+ if (root === '[]') {
+ obj = [];
+ obj = obj.concat(internals.parseObject(chain, val, options));
+ }
+ else {
+ var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
+ var index = parseInt(cleanRoot, 10);
+ var indexString = '' + index;
+ if (!isNaN(index) &&
+ root !== cleanRoot &&
+ indexString === cleanRoot &&
+ index >= 0 &&
+ index <= options.arrayLimit) {
+
+ obj = [];
+ obj[index] = internals.parseObject(chain, val, options);
+ }
+ else {
+ obj[cleanRoot] = internals.parseObject(chain, val, options);
+ }
+ }
+
+ return obj;
+};
+
+
+internals.parseKeys = function (key, val, options) {
+
+ if (!key) {
+ return;
+ }
+
+ // The regex chunks
+
+ var parent = /^([^\[\]]*)/;
+ var child = /(\[[^\[\]]*\])/g;
+
+ // Get the parent
+
+ var segment = parent.exec(key);
+
+ // Don't allow them to overwrite object prototype properties
+
+ if (Object.prototype.hasOwnProperty(segment[1])) {
+ return;
+ }
+
+ // Stash the parent if it exists
+
+ var keys = [];
+ if (segment[1]) {
+ keys.push(segment[1]);
+ }
+
+ // Loop through children appending to the array until we hit depth
+
+ var i = 0;
+ while ((segment = child.exec(key)) !== null && i < options.depth) {
+
+ ++i;
+ if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
+ keys.push(segment[1]);
+ }
+ }
+
+ // If there's a remainder, just add whatever is left
+
+ if (segment) {
+ keys.push('[' + key.slice(segment.index) + ']');
+ }
+
+ return internals.parseObject(keys, val, options);
+};
+
+
+module.exports = function (str, options) {
+
+ if (str === '' ||
+ str === null ||
+ typeof str === 'undefined') {
+
+ return {};
+ }
+
+ options = options || {};
+ options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
+ options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
+ options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
+ options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
+
+ var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
+ var obj = {};
+
+ // Iterate over the keys and setup the new object
+
+ var keys = Object.keys(tempObj);
+ for (var i = 0, il = keys.length; i < il; ++i) {
+ var key = keys[i];
+ var newObj = internals.parseKeys(key, tempObj[key], options);
+ obj = Utils.merge(obj, newObj);
+ }
+
+ return Utils.compact(obj);
+};
+
+},{"./utils":41}],40:[function(require,module,exports){
+// Load modules
+
+var Utils = require('./utils');
+
+
+// Declare internals
+
+var internals = {
+ delimiter: '&',
+ arrayPrefixGenerators: {
+ brackets: function (prefix, key) {
+ return prefix + '[]';
+ },
+ indices: function (prefix, key) {
+ return prefix + '[' + key + ']';
+ },
+ repeat: function (prefix, key) {
+ return prefix;
+ }
+ }
+};
+
+
+internals.stringify = function (obj, prefix, generateArrayPrefix) {
+
+ if (Utils.isBuffer(obj)) {
+ obj = obj.toString();
+ }
+ else if (obj instanceof Date) {
+ obj = obj.toISOString();
+ }
+ else if (obj === null) {
+ obj = '';
+ }
+
+ if (typeof obj === 'string' ||
+ typeof obj === 'number' ||
+ typeof obj === 'boolean') {
+
+ return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)];
+ }
+
+ var values = [];
+
+ if (typeof obj === 'undefined') {
+ return values;
+ }
+
+ var objKeys = Object.keys(obj);
+ for (var i = 0, il = objKeys.length; i < il; ++i) {
+ var key = objKeys[i];
+ if (Array.isArray(obj)) {
+ values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
+ }
+ else {
+ values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
+ }
+ }
+
+ return values;
+};
+
+
+module.exports = function (obj, options) {
+
+ options = options || {};
+ var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
+
+ var keys = [];
+
+ if (typeof obj !== 'object' ||
+ obj === null) {
+
+ return '';
+ }
+
+ var arrayFormat;
+ if (options.arrayFormat in internals.arrayPrefixGenerators) {
+ arrayFormat = options.arrayFormat;
+ }
+ else if ('indices' in options) {
+ arrayFormat = options.indices ? 'indices' : 'repeat';
+ }
+ else {
+ arrayFormat = 'indices';
+ }
+
+ var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
+
+ var objKeys = Object.keys(obj);
+ for (var i = 0, il = objKeys.length; i < il; ++i) {
+ var key = objKeys[i];
+ keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
+ }
+
+ return keys.join(delimiter);
+};
+
+},{"./utils":41}],41:[function(require,module,exports){
+// Load modules
+
+
+// Declare internals
+
+var internals = {};
+
+
+exports.arrayToObject = function (source) {
+
+ var obj = {};
+ for (var i = 0, il = source.length; i < il; ++i) {
+ if (typeof source[i] !== 'undefined') {
+
+ obj[i] = source[i];
+ }
+ }
+
+ return obj;
+};
+
+
+exports.merge = function (target, source) {
+
+ if (!source) {
+ return target;
+ }
+
+ if (typeof source !== 'object') {
+ if (Array.isArray(target)) {
+ target.push(source);
+ }
+ else {
+ target[source] = true;
+ }
+
+ return target;
+ }
+
+ if (typeof target !== 'object') {
+ target = [target].concat(source);
+ return target;
+ }
+
+ if (Array.isArray(target) &&
+ !Array.isArray(source)) {
+
+ target = exports.arrayToObject(target);
+ }
+
+ var keys = Object.keys(source);
+ for (var k = 0, kl = keys.length; k < kl; ++k) {
+ var key = keys[k];
+ var value = source[key];
+
+ if (!target[key]) {
+ target[key] = value;
+ }
+ else {
+ target[key] = exports.merge(target[key], value);
+ }
+ }
+
+ return target;
+};
+
+
+exports.decode = function (str) {
+
+ try {
+ return decodeURIComponent(str.replace(/\+/g, ' '));
+ } catch (e) {
+ return str;
+ }
+};
+
+
+exports.compact = function (obj, refs) {
+
+ if (typeof obj !== 'object' ||
+ obj === null) {
+
+ return obj;
+ }
+
+ refs = refs || [];
+ var lookup = refs.indexOf(obj);
+ if (lookup !== -1) {
+ return refs[lookup];
+ }
+
+ refs.push(obj);
+
+ if (Array.isArray(obj)) {
+ var compacted = [];
+
+ for (var i = 0, il = obj.length; i < il; ++i) {
+ if (typeof obj[i] !== 'undefined') {
+ compacted.push(obj[i]);
+ }
+ }
+
+ return compacted;
+ }
+
+ var keys = Object.keys(obj);
+ for (i = 0, il = keys.length; i < il; ++i) {
+ var key = keys[i];
+ obj[key] = exports.compact(obj[key], refs);
+ }
+
+ return obj;
+};
+
+
+exports.isRegExp = function (obj) {
+ return Object.prototype.toString.call(obj) === '[object RegExp]';
+};
+
+
+exports.isBuffer = function (obj) {
+
+ if (obj === null ||
+ typeof obj === 'undefined') {
+
+ return false;
+ }
+
+ return !!(obj.constructor &&
+ obj.constructor.isBuffer &&
+ obj.constructor.isBuffer(obj));
+};
+
},{}],42:[function(require,module,exports){
/**
* Copyright 2013-2015, Facebook, Inc.
@@ -34265,7 +34265,7 @@ return jQuery;
(function (global){
/**
* @license
- * lodash 3.6.0 (Custom Build) <https://lodash.com/>
+ * lodash 3.5.0 (Custom Build) <https://lodash.com/>
* Build: `lodash modern -d -o ./index.js`
* Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.2 <http://underscorejs.org/LICENSE>
@@ -34278,7 +34278,7 @@ return jQuery;
var undefined;
/** Used as the semantic version number. */
- var VERSION = '3.6.0';
+ var VERSION = '3.5.0';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -34288,8 +34288,8 @@ return jQuery;
CURRY_RIGHT_FLAG = 16,
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64,
- ARY_FLAG = 128,
- REARG_FLAG = 256;
+ REARG_FLAG = 128,
+ ARY_FLAG = 256;
/** Used as default options for `_.trunc`. */
var DEFAULT_TRUNC_LENGTH = 30,
@@ -34353,18 +34353,18 @@ return jQuery;
reInterpolate = /<%=([\s\S]+?)%>/g;
/**
- * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
- */
- var reComboMarks = /[\u0300-\u036f\ufe20-\ufe23]/g;
-
- /**
- * Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components).
+ * Used to match ES template delimiters.
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components)
+ * for more details.
*/
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;
+ /** Used to detect named functions. */
+ var reFuncName = /^\s*function[ \n\r\t]+\w/;
+
/** Used to detect hexadecimal string values. */
var reHexPrefix = /^0[xX]/;
@@ -34378,13 +34378,16 @@ return jQuery;
var reNoMatch = /($^)/;
/**
- * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special).
- * In addition to special characters the forward slash is escaped to allow for
- * easier `eval` use and `Function` compilation.
+ * Used to match `RegExp` special characters.
+ * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special)
+ * for more details.
*/
var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
reHasRegExpChars = RegExp(reRegExpChars.source);
+ /** Used to detect functions containing a `this` reference. */
+ var reThis = /\bthis\b/;
+
/** Used to match unescaped characters in compiled string literals. */
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
@@ -34415,7 +34418,7 @@ return jQuery;
'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document',
'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
- 'window'
+ 'window', 'WinRTError'
];
/** Used to make template sourceURLs easier to identify. */
@@ -34524,11 +34527,8 @@ return jQuery;
/** Detect free variable `global` from Node.js. */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
- /** Detect free variable `self`. */
- var freeSelf = objectTypes[typeof self] && self && self.Object && self;
-
/** Detect free variable `window`. */
- var freeWindow = objectTypes[typeof window] && window && window.Object && window;
+ var freeWindow = objectTypes[typeof window] && window;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
@@ -34539,7 +34539,7 @@ return jQuery;
* The `this` value is used if it is the global object to avoid Greasemonkey's
* restricted `window` object, otherwise the `window` object is used.
*/
- var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
+ var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || this;
/*--------------------------------------------------------------------------*/
@@ -34568,28 +34568,6 @@ return jQuery;
}
/**
- * The base implementation of `_.findIndex` and `_.findLastIndex` without
- * support for callback shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {Function} predicate The function invoked per iteration.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseFindIndex(array, predicate, fromRight) {
- var length = array.length,
- index = fromRight ? length : -1;
-
- while ((fromRight ? index-- : ++index < length)) {
- if (predicate(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
* The base implementation of `_.indexOf` without support for binary searches.
*
* @private
@@ -34775,6 +34753,7 @@ return jQuery;
/**
* Gets the index at which the first occurrence of `NaN` is found in `array`.
+ * If `fromRight` is provided elements of `array` are iterated from right to left.
*
* @private
* @param {Array} array The array to search.
@@ -34803,7 +34782,7 @@ return jQuery;
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
*/
function isObjectLike(value) {
- return !!value && typeof value == 'object';
+ return (value && typeof value == 'object') || false;
}
/**
@@ -34925,19 +34904,19 @@ return jQuery;
* @returns {Function} Returns a new `lodash` function.
* @example
*
- * _.mixin({ 'foo': _.constant('foo') });
+ * _.mixin({ 'add': function(a, b) { return a + b; } });
*
* var lodash = _.runInContext();
- * lodash.mixin({ 'bar': lodash.constant('bar') });
+ * lodash.mixin({ 'sub': function(a, b) { return a - b; } });
*
- * _.isFunction(_.foo);
+ * _.isFunction(_.add);
* // => true
- * _.isFunction(_.bar);
+ * _.isFunction(_.sub);
* // => false
*
- * lodash.isFunction(lodash.foo);
+ * lodash.isFunction(lodash.add);
* // => false
- * lodash.isFunction(lodash.bar);
+ * lodash.isFunction(lodash.sub);
* // => true
*
* // using `context` to mock `Date#getTime` use in `_.now`
@@ -34990,8 +34969,9 @@ return jQuery;
var idCounter = 0;
/**
- * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
- * of values.
+ * Used to resolve the `toStringTag` of values.
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
+ * for more details.
*/
var objToString = objectProto.toString;
@@ -35056,17 +35036,15 @@ return jQuery;
var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
/**
- * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
- * of an array-like value.
+ * Used as the maximum length of an array-like value.
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
+ * for more details.
*/
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;
- /** Used to lookup unminified function names. */
- var realNames = {};
-
/*------------------------------------------------------------------------*/
/**
@@ -35216,7 +35194,7 @@ return jQuery;
* @memberOf _.support
* @type boolean
*/
- support.funcDecomp = /\bthis\b/.test(function() { return this; });
+ support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
/**
* Detect if `Function#name` is supported (all but IE).
@@ -35592,7 +35570,7 @@ return jQuery;
/**
* A specialized version of `_.forEach` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35613,7 +35591,7 @@ return jQuery;
/**
* A specialized version of `_.forEachRight` for arrays without support for
- * callback shorthands and `this` binding.
+ * callback shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35633,7 +35611,7 @@ return jQuery;
/**
* A specialized version of `_.every` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35655,7 +35633,7 @@ return jQuery;
/**
* A specialized version of `_.filter` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35679,7 +35657,7 @@ return jQuery;
/**
* A specialized version of `_.map` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35741,7 +35719,7 @@ return jQuery;
/**
* A specialized version of `_.reduce` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35766,7 +35744,7 @@ return jQuery;
/**
* A specialized version of `_.reduceRight` for arrays without support for
- * callback shorthands and `this` binding.
+ * callback shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35789,7 +35767,7 @@ return jQuery;
/**
* A specialized version of `_.some` for arrays without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array} array The array to iterate over.
@@ -35810,23 +35788,6 @@ return jQuery;
}
/**
- * A specialized version of `_.sum` for arrays without support for iteratees.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @returns {number} Returns the sum.
- */
- function arraySum(array) {
- var length = array.length,
- result = 0;
-
- while (length--) {
- result += +array[length] || 0;
- }
- return result;
- }
-
- /**
* Used by `_.defaults` to customize its `_.assign` use.
*
* @private
@@ -35941,6 +35902,26 @@ return jQuery;
}
/**
+ * The base implementation of `_.bindAll` without support for individual
+ * method name arguments.
+ *
+ * @private
+ * @param {Object} object The object to bind and assign the bound methods to.
+ * @param {string[]} methodNames The object method names to bind.
+ * @returns {Object} Returns `object`.
+ */
+ function baseBindAll(object, methodNames) {
+ var index = -1,
+ length = methodNames.length;
+
+ while (++index < length) {
+ var key = methodNames[index];
+ object[key] = createWrapper(object[key], BIND_FLAG, object);
+ }
+ return object;
+ }
+
+ /**
* The base implementation of `_.callback` which supports specifying the
* number of arguments to provide to `func`.
*
@@ -35953,9 +35934,9 @@ return jQuery;
function baseCallback(func, thisArg, argCount) {
var type = typeof func;
if (type == 'function') {
- return typeof thisArg == 'undefined'
- ? func
- : bindCallback(func, thisArg, argCount);
+ return (typeof thisArg != 'undefined' && isBindable(func))
+ ? bindCallback(func, thisArg, argCount)
+ : func;
}
if (func == null) {
return identity;
@@ -36062,14 +36043,14 @@ return jQuery;
* @private
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
- * @param {Object} args The arguments provide to `func`.
+ * @param {Object} args The `arguments` object to slice and provide to `func`.
* @returns {number} Returns the timer id.
*/
- function baseDelay(func, wait, args) {
+ function baseDelay(func, wait, args, fromIndex) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
- return setTimeout(function() { func.apply(undefined, args); }, wait);
+ return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait);
}
/**
@@ -36128,7 +36109,21 @@ return jQuery;
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object|string} Returns `collection`.
*/
- var baseEach = createBaseEach(baseForOwn);
+ function baseEach(collection, iteratee) {
+ var length = collection ? collection.length : 0;
+ if (!isLength(length)) {
+ return baseForOwn(collection, iteratee);
+ }
+ var index = -1,
+ iterable = toObject(collection);
+
+ while (++index < length) {
+ if (iteratee(iterable[index], index, iterable) === false) {
+ break;
+ }
+ }
+ return collection;
+ }
/**
* The base implementation of `_.forEachRight` without support for callback
@@ -36139,11 +36134,23 @@ return jQuery;
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object|string} Returns `collection`.
*/
- var baseEachRight = createBaseEach(baseForOwnRight, true);
+ function baseEachRight(collection, iteratee) {
+ var length = collection ? collection.length : 0;
+ if (!isLength(length)) {
+ return baseForOwnRight(collection, iteratee);
+ }
+ var iterable = toObject(collection);
+ while (length--) {
+ if (iteratee(iterable[length], length, iterable) === false) {
+ break;
+ }
+ }
+ return collection;
+ }
/**
* The base implementation of `_.every` without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
@@ -36192,7 +36199,7 @@ return jQuery;
/**
* The base implementation of `_.filter` without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
@@ -36241,10 +36248,11 @@ return jQuery;
* @param {Array} array The array to flatten.
* @param {boolean} isDeep Specify a deep flatten.
* @param {boolean} isStrict Restrict flattening to arrays and `arguments` objects.
+ * @param {number} fromIndex The index to start from.
* @returns {Array} Returns the new flattened array.
*/
- function baseFlatten(array, isDeep, isStrict) {
- var index = -1,
+ function baseFlatten(array, isDeep, isStrict, fromIndex) {
+ var index = fromIndex - 1,
length = array.length,
resIndex = -1,
result = [];
@@ -36255,7 +36263,7 @@ return jQuery;
if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) {
if (isDeep) {
// Recursively flatten arrays (susceptible to call stack limits).
- value = baseFlatten(value, isDeep, isStrict);
+ value = baseFlatten(value, isDeep, isStrict, 0);
}
var valIndex = -1,
valLength = value.length;
@@ -36283,7 +36291,20 @@ return jQuery;
* @param {Function} keysFunc The function to get the keys of `object`.
* @returns {Object} Returns `object`.
*/
- var baseFor = createBaseFor();
+ function baseFor(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = toObject(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ }
/**
* This function is like `baseFor` except that it iterates over properties
@@ -36295,7 +36316,19 @@ return jQuery;
* @param {Function} keysFunc The function to get the keys of `object`.
* @returns {Object} Returns `object`.
*/
- var baseForRight = createBaseFor(true);
+ function baseForRight(object, iteratee, keysFunc) {
+ var iterable = toObject(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[length];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ }
/**
* The base implementation of `_.forIn` without support for callback
@@ -36361,6 +36394,30 @@ return jQuery;
}
/**
+ * The base implementation of `_.invoke` which requires additional arguments
+ * to be provided as an array of arguments rather than individually.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function|string} methodName The name of the method to invoke or
+ * the function invoked per iteration.
+ * @param {Array} [args] The arguments to invoke the method with.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseInvoke(collection, methodName, args) {
+ var index = -1,
+ isFunc = typeof methodName == 'function',
+ length = collection ? collection.length : 0,
+ result = isLength(length) ? Array(length) : [];
+
+ baseEach(collection, function(value) {
+ var func = isFunc ? methodName : (value != null && value[methodName]);
+ result[++index] = func ? func.apply(value, args) : undefined;
+ });
+ return result;
+ }
+
+ /**
* The base implementation of `_.isEqual` without support for `this` binding
* `customizer` functions.
*
@@ -36368,12 +36425,12 @@ return jQuery;
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {boolean} [isWhere] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
*/
- function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+ function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) {
// Exit early for identical values.
if (value === other) {
// Treat `+0` vs. `-0` as not equal.
@@ -36388,7 +36445,7 @@ return jQuery;
// Return `false` unless both values are `NaN`.
return value !== value && other !== other;
}
- return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+ return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB);
}
/**
@@ -36401,12 +36458,12 @@ return jQuery;
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing objects.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {boolean} [isWhere] Specify performing partial comparisons.
* @param {Array} [stackA=[]] Tracks traversed `value` objects.
* @param {Array} [stackB=[]] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
@@ -36428,27 +36485,21 @@ return jQuery;
othIsArr = isTypedArray(other);
}
}
- var objIsObj = (objTag == objectTag || (isLoose && objTag == funcTag)),
- othIsObj = (othTag == objectTag || (isLoose && othTag == funcTag)),
+ var objIsObj = objTag == objectTag,
+ othIsObj = othTag == objectTag,
isSameTag = objTag == othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
- if (isLoose) {
- if (!isSameTag && !(objIsObj && othIsObj)) {
- return false;
- }
- } else {
- var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
- othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+ var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+ othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
- if (valWrapped || othWrapped) {
- return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
- }
- if (!isSameTag) {
- return false;
- }
+ if (valWrapped || othWrapped) {
+ return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB);
+ }
+ if (!isSameTag) {
+ return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
@@ -36465,7 +36516,7 @@ return jQuery;
stackA.push(object);
stackB.push(other);
- var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
+ var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB);
stackA.pop();
stackB.pop();
@@ -36475,7 +36526,7 @@ return jQuery;
/**
* The base implementation of `_.isMatch` without support for callback
- * shorthands and `this` binding.
+ * shorthands or `this` binding.
*
* @private
* @param {Object} object The object to inspect.
@@ -36486,27 +36537,30 @@ return jQuery;
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
*/
function baseIsMatch(object, props, values, strictCompareFlags, customizer) {
+ var length = props.length;
+ if (object == null) {
+ return !length;
+ }
var index = -1,
- length = props.length,
noCustomizer = !customizer;
while (++index < length) {
if ((noCustomizer && strictCompareFlags[index])
? values[index] !== object[props[index]]
- : !(props[index] in object)
+ : !hasOwnProperty.call(object, props[index])
) {
return false;
}
}
index = -1;
while (++index < length) {
- var key = props[index],
- objValue = object[key],
- srcValue = values[index];
-
+ var key = props[index];
if (noCustomizer && strictCompareFlags[index]) {
- var result = typeof objValue != 'undefined' || (key in object);
+ var result = hasOwnProperty.call(object, key);
} else {
+ var objValue = object[key],
+ srcValue = values[index];
+
result = customizer ? customizer(objValue, srcValue, key) : undefined;
if (typeof result == 'undefined') {
result = baseIsEqual(srcValue, objValue, customizer, true);
@@ -36521,7 +36575,7 @@ return jQuery;
/**
* The base implementation of `_.map` without support for callback shorthands
- * and `this` binding.
+ * or `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
@@ -36547,17 +36601,13 @@ return jQuery;
var props = keys(source),
length = props.length;
- if (!length) {
- return constant(true);
- }
if (length == 1) {
var key = props[0],
value = source[key];
if (isStrictComparable(value)) {
return function(object) {
- return object != null && object[key] === value &&
- (typeof value != 'undefined' || (key in toObject(object)));
+ return object != null && object[key] === value && hasOwnProperty.call(object, key);
};
}
}
@@ -36570,7 +36620,7 @@ return jQuery;
strictCompareFlags[length] = isStrictComparable(value);
}
return function(object) {
- return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags);
+ return baseIsMatch(object, props, values, strictCompareFlags);
};
}
@@ -36586,8 +36636,7 @@ return jQuery;
function baseMatchesProperty(key, value) {
if (isStrictComparable(value)) {
return function(object) {
- return object != null && object[key] === value &&
- (typeof value != 'undefined' || (key in toObject(object)));
+ return object != null && object[key] === value;
};
}
return function(object) {
@@ -36667,7 +36716,7 @@ return jQuery;
if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) {
result = isArray(value)
? value
- : ((value && value.length) ? arrayCopy(value) : []);
+ : (value ? arrayCopy(value) : []);
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
result = isArguments(value)
@@ -36705,6 +36754,30 @@ return jQuery;
}
/**
+ * The base implementation of `_.pullAt` without support for individual
+ * index arguments.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {number[]} indexes The indexes of elements to remove.
+ * @returns {Array} Returns the new array of removed elements.
+ */
+ function basePullAt(array, indexes) {
+ var length = indexes.length,
+ result = baseAt(array, indexes);
+
+ indexes.sort(baseCompareAscending);
+ while (length--) {
+ var index = parseFloat(indexes[length]);
+ if (index != previous && isIndex(index)) {
+ var previous = index;
+ splice.call(array, index, 1);
+ }
+ }
+ return result;
+ }
+
+ /**
* The base implementation of `_.random` without support for argument juggling
* and returning floating-point numbers.
*
@@ -36719,7 +36792,7 @@ return jQuery;
/**
* The base implementation of `_.reduce` and `_.reduceRight` without support
- * for callback shorthands and `this` binding, which iterates over `collection`
+ * for callback shorthands or `this` binding, which iterates over `collection`
* using the provided `eachFunc`.
*
* @private
@@ -36786,7 +36859,7 @@ return jQuery;
/**
* The base implementation of `_.some` without support for callback shorthands
- * and `this` binding.
+ * or `this` binding.
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
@@ -36854,23 +36927,6 @@ return jQuery;
}
/**
- * The base implementation of `_.sum` without support for callback shorthands
- * and `this` binding.
- *
- * @private
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {number} Returns the sum.
- */
- function baseSum(collection, iteratee) {
- var result = 0;
- baseEach(collection, function(value, index, collection) {
- result += +iteratee(value, index, collection) || 0;
- });
- return result;
- }
-
- /**
* The base implementation of `_.uniq` without support for callback shorthands
* and `this` binding.
*
@@ -36944,27 +37000,6 @@ return jQuery;
}
/**
- * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,
- * and `_.takeWhile` without support for callback shorthands and `this` binding.
- *
- * @private
- * @param {Array} array The array to query.
- * @param {Function} predicate The function invoked per iteration.
- * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Array} Returns the slice of `array`.
- */
- function baseWhile(array, predicate, isDrop, fromRight) {
- var length = array.length,
- index = fromRight ? length : -1;
-
- while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
- return isDrop
- ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
- : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
- }
-
- /**
* The base implementation of `wrapperValue` which returns the result of
* performing a sequence of actions on the unwrapped `value`, where each
* successive action is supplied the return value of the previous.
@@ -36972,7 +37007,7 @@ return jQuery;
* @private
* @param {*} value The unwrapped value.
* @param {Array} actions Actions to peform to resolve the unwrapped value.
- * @returns {*} Returns the resolved value.
+ * @returns {*} Returns the resolved unwrapped value.
*/
function baseWrapperValue(value, actions) {
var result = value;
@@ -36999,7 +37034,8 @@ return jQuery;
* @private
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
- * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @param {boolean} [retHighest] Specify returning the highest, instead
+ * of the lowest, index at which a value should be inserted into `array`.
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
@@ -37032,7 +37068,8 @@ return jQuery;
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
* @param {Function} iteratee The function invoked per iteration.
- * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @param {boolean} [retHighest] Specify returning the highest, instead
+ * of the lowest, index at which a value should be inserted into `array`.
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
*/
@@ -37198,9 +37235,6 @@ return jQuery;
* object composed from the results of running each element in the collection
* through an iteratee.
*
- * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`,
- * and `_.partition`.
- *
* @private
* @param {Function} setter The function to set keys and values of the accumulator object.
* @param {Function} [initializer] The function to initialize the accumulator object.
@@ -37232,8 +37266,6 @@ return jQuery;
* Creates a function that assigns properties of source object(s) to a given
* destination object.
*
- * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
- *
* @private
* @param {Function} assigner The function to assign values.
* @returns {Function} Returns the new assigner function.
@@ -37274,56 +37306,6 @@ return jQuery;
}
/**
- * Creates a `baseEach` or `baseEachRight` function.
- *
- * @private
- * @param {Function} eachFunc The function to iterate over a collection.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
- function createBaseEach(eachFunc, fromRight) {
- return function(collection, iteratee) {
- var length = collection ? collection.length : 0;
- if (!isLength(length)) {
- return eachFunc(collection, iteratee);
- }
- var index = fromRight ? length : -1,
- iterable = toObject(collection);
-
- while ((fromRight ? index-- : ++index < length)) {
- if (iteratee(iterable[index], index, iterable) === false) {
- break;
- }
- }
- return collection;
- };
- }
-
- /**
- * Creates a base function for `_.forIn` or `_.forInRight`.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
- function createBaseFor(fromRight) {
- return function(object, iteratee, keysFunc) {
- var iterable = toObject(object),
- props = keysFunc(object),
- length = props.length,
- index = fromRight ? length : -1;
-
- while ((fromRight ? index-- : ++index < length)) {
- var key = props[index];
- if (iteratee(iterable[key], key, iterable) === false) {
- break;
- }
- }
- return object;
- };
- }
-
- /**
* Creates a function that wraps `func` and invokes it with the `this`
* binding of `thisArg`.
*
@@ -37354,6 +37336,41 @@ return jQuery;
};
/**
+ * Creates a function to compose other functions into a single function.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new composer function.
+ */
+ function createComposer(fromRight) {
+ return function() {
+ var length = arguments.length,
+ index = length,
+ fromIndex = fromRight ? (length - 1) : 0;
+
+ if (!length) {
+ return function() { return arguments[0]; };
+ }
+ var funcs = Array(length);
+ while (index--) {
+ funcs[index] = arguments[index];
+ if (typeof funcs[index] != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ }
+ return function() {
+ var index = fromIndex,
+ result = funcs[index].apply(this, arguments);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ result = funcs[index].call(this, result);
+ }
+ return result;
+ };
+ };
+ }
+
+ /**
* Creates a function that produces compound words out of the words in a
* given string.
*
@@ -37395,26 +37412,7 @@ return jQuery;
}
/**
- * Creates a `_.curry` or `_.curryRight` function.
- *
- * @private
- * @param {boolean} flag The curry bit flag.
- * @returns {Function} Returns the new curry function.
- */
- function createCurry(flag) {
- function curryFunc(func, arity, guard) {
- if (guard && isIterateeCall(func, arity, guard)) {
- arity = null;
- }
- var result = createWrapper(func, flag, null, null, null, null, null, arity);
- result.placeholder = curryFunc.placeholder;
- return result;
- }
- return curryFunc;
- }
-
- /**
- * Creates a `_.max` or `_.min` function.
+ * Creates a function that gets the extremum value of a collection.
*
* @private
* @param {Function} arrayFunc The function to get the extremum value from an array.
@@ -37447,204 +37445,6 @@ return jQuery;
}
/**
- * Creates a `_.find` or `_.findLast` function.
- *
- * @private
- * @param {Function} eachFunc The function to iterate over a collection.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFind(eachFunc, fromRight) {
- return function(collection, predicate, thisArg) {
- predicate = getCallback(predicate, thisArg, 3);
- if (isArray(collection)) {
- var index = baseFindIndex(collection, predicate, fromRight);
- return index > -1 ? collection[index] : undefined;
- }
- return baseFind(collection, predicate, eachFunc);
- }
- }
-
- /**
- * Creates a `_.findIndex` or `_.findLastIndex` function.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new find function.
- */
- function createFindIndex(fromRight) {
- return function(array, predicate, thisArg) {
- if (!(array && array.length)) {
- return -1;
- }
- predicate = getCallback(predicate, thisArg, 3);
- return baseFindIndex(array, predicate, fromRight);
- };
- }
-
- /**
- * Creates a `_.findKey` or `_.findLastKey` function.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new find function.
- */
- function createFindKey(objectFunc) {
- return function(object, predicate, thisArg) {
- predicate = getCallback(predicate, thisArg, 3);
- return baseFind(object, predicate, objectFunc, true);
- };
- }
-
- /**
- * Creates a `_.flow` or `_.flowRight` function.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new flow function.
- */
- function createFlow(fromRight) {
- return function() {
- var length = arguments.length;
- if (!length) {
- return function() { return arguments[0]; };
- }
- var wrapper,
- index = fromRight ? length : -1,
- leftIndex = 0,
- funcs = Array(length);
-
- while ((fromRight ? index-- : ++index < length)) {
- var func = funcs[leftIndex++] = arguments[index];
- if (typeof func != 'function') {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
- var funcName = wrapper ? '' : getFuncName(func);
- wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper;
- }
- index = wrapper ? -1 : length;
- while (++index < length) {
- func = funcs[index];
- funcName = getFuncName(func);
-
- var data = funcName == 'wrapper' ? getData(func) : null;
- if (data && isLaziable(data[0])) {
- wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
- } else {
- wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
- }
- }
- return function() {
- var args = arguments;
- if (wrapper && args.length == 1 && isArray(args[0])) {
- return wrapper.plant(args[0]).value();
- }
- var index = 0,
- result = funcs[index].apply(this, args);
-
- while (++index < length) {
- result = funcs[index].call(this, result);
- }
- return result;
- };
- };
- }
-
- /**
- * Creates a function for `_.forEach` or `_.forEachRight`.
- *
- * @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createForEach(arrayFunc, eachFunc) {
- return function(collection, iteratee, thisArg) {
- return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection))
- ? arrayFunc(collection, iteratee)
- : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
- };
- }
-
- /**
- * Creates a function for `_.forIn` or `_.forInRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForIn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || typeof thisArg != 'undefined') {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee, keysIn);
- };
- }
-
- /**
- * Creates a function for `_.forOwn` or `_.forOwnRight`.
- *
- * @private
- * @param {Function} objectFunc The function to iterate over an object.
- * @returns {Function} Returns the new each function.
- */
- function createForOwn(objectFunc) {
- return function(object, iteratee, thisArg) {
- if (typeof iteratee != 'function' || typeof thisArg != 'undefined') {
- iteratee = bindCallback(iteratee, thisArg, 3);
- }
- return objectFunc(object, iteratee);
- };
- }
-
- /**
- * Creates a function for `_.padLeft` or `_.padRight`.
- *
- * @private
- * @param {boolean} [fromRight] Specify padding from the right.
- * @returns {Function} Returns the new pad function.
- */
- function createPadDir(fromRight) {
- return function(string, length, chars) {
- string = baseToString(string);
- return string && ((fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string));
- };
- }
-
- /**
- * Creates a `_.partial` or `_.partialRight` function.
- *
- * @private
- * @param {boolean} flag The partial bit flag.
- * @returns {Function} Returns the new partial function.
- */
- function createPartial(flag) {
- var partialFunc = restParam(function(func, partials) {
- var holders = replaceHolders(partials, partialFunc.placeholder);
- return createWrapper(func, flag, null, partials, holders);
- });
- return partialFunc;
- }
-
- /**
- * Creates a function for `_.reduce` or `_.reduceRight`.
- *
- * @private
- * @param {Function} arrayFunc The function to iterate over an array.
- * @param {Function} eachFunc The function to iterate over a collection.
- * @returns {Function} Returns the new each function.
- */
- function createReduce(arrayFunc, eachFunc) {
- return function(collection, iteratee, accumulator, thisArg) {
- var initFromArray = arguments.length < 3;
- return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection))
- ? arrayFunc(collection, iteratee, accumulator, initFromArray)
- : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
- };
- }
-
- /**
* Creates a function that wraps `func` and invokes it with optional `this`
* binding of, partial application, and currying.
*
@@ -37707,12 +37507,7 @@ return jQuery;
if (!isCurryBound) {
bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
}
- var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
- result = createHybridWrapper.apply(undefined, newData);
-
- if (isLaziable(func)) {
- setData(result, newData);
- }
+ var result = createHybridWrapper(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity);
result.placeholder = placeholder;
return result;
}
@@ -37734,8 +37529,9 @@ return jQuery;
}
/**
- * Creates the padding required for `string` based on the given `length`.
- * The `chars` string is truncated if the number of characters exceeds `length`.
+ * Creates the pad required for `string` based on the given padding length.
+ * The `chars` string may be truncated if the number of padding characters
+ * exceeds the padding length.
*
* @private
* @param {string} string The string to create padding for.
@@ -37743,7 +37539,7 @@ return jQuery;
* @param {string} [chars=' '] The string used as padding.
* @returns {string} Returns the pad for `string`.
*/
- function createPadding(string, length, chars) {
+ function createPad(string, length, chars) {
var strLength = string.length;
length = +length;
@@ -37793,22 +37589,6 @@ return jQuery;
}
/**
- * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
- *
- * @private
- * @param {boolean} [retHighest] Specify returning the highest qualified index.
- * @returns {Function} Returns the new index function.
- */
- function createSortedIndex(retHighest) {
- return function(array, value, iteratee, thisArg) {
- var func = getCallback(iteratee);
- return (func === baseCallback && iteratee == null)
- ? binaryIndex(array, value, retHighest)
- : binaryIndexBy(array, value, func(iteratee, thisArg, 1), retHighest);
- };
- }
-
- /**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
@@ -37850,10 +37630,10 @@ return jQuery;
partials = holders = null;
}
- var data = isBindKey ? null : getData(func),
+ var data = !isBindKey && getData(func),
newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
- if (data) {
+ if (data && data !== true) {
mergeData(newData, data);
bitmask = newData[1];
arity = newData[9];
@@ -37882,18 +37662,18 @@ return jQuery;
* @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing arrays.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {boolean} [isWhere] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
- function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length,
result = true;
- if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+ if (arrLength != othLength && !(isWhere && othLength > arrLength)) {
return false;
}
// Deep compare the contents, ignoring non-numeric properties.
@@ -37903,23 +37683,23 @@ return jQuery;
result = undefined;
if (customizer) {
- result = isLoose
+ result = isWhere
? customizer(othValue, arrValue, index)
: customizer(arrValue, othValue, index);
}
if (typeof result == 'undefined') {
// Recursively compare arrays (susceptible to call stack limits).
- if (isLoose) {
+ if (isWhere) {
var othIndex = othLength;
while (othIndex--) {
othValue = other[othIndex];
- result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+ result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB);
if (result) {
break;
}
}
} else {
- result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+ result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB);
}
}
}
@@ -37975,26 +37755,26 @@ return jQuery;
* @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Function} [customizer] The function to customize comparing values.
- * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {boolean} [isWhere] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects.
* @param {Array} [stackB] Tracks traversed `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
- function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+ function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
- if (objLength != othLength && !isLoose) {
+ if (objLength != othLength && !isWhere) {
return false;
}
- var skipCtor = isLoose,
+ var hasCtor,
index = -1;
while (++index < objLength) {
var key = objProps[index],
- result = isLoose ? key in other : hasOwnProperty.call(other, key);
+ result = hasOwnProperty.call(other, key);
if (result) {
var objValue = object[key],
@@ -38002,21 +37782,21 @@ return jQuery;
result = undefined;
if (customizer) {
- result = isLoose
+ result = isWhere
? customizer(othValue, objValue, key)
: customizer(objValue, othValue, key);
}
if (typeof result == 'undefined') {
// Recursively compare objects (susceptible to call stack limits).
- result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB);
+ result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB);
}
}
if (!result) {
return false;
}
- skipCtor || (skipCtor = key == 'constructor');
+ hasCtor || (hasCtor = key == 'constructor');
}
- if (!skipCtor) {
+ if (!hasCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
@@ -38034,7 +37814,7 @@ return jQuery;
/**
* Gets the extremum value of `collection` invoking `iteratee` for each value
* in `collection` to generate the criterion by which the value is ranked.
- * The `iteratee` is invoked with three arguments: (value, index, collection).
+ * The `iteratee` is invoked with three arguments; (value, index, collection).
*
* @private
* @param {Array|Object|string} collection The collection to iterate over.
@@ -38086,37 +37866,6 @@ return jQuery;
};
/**
- * Gets the name of `func`.
- *
- * @private
- * @param {Function} func The function to query.
- * @returns {string} Returns the function name.
- */
- var getFuncName = (function() {
- if (!support.funcNames) {
- return constant('');
- }
- if (constant.name == 'constant') {
- return baseProperty('name');
- }
- return function(func) {
- var result = func.name,
- array = realNames[result],
- length = array ? array.length : 0;
-
- while (length--) {
- var data = array[length],
- otherFunc = data.func;
-
- if (otherFunc == null || otherFunc == func) {
- return data.name;
- }
- }
- return result;
- };
- }());
-
- /**
* Gets the appropriate "indexOf" function. If the `_.indexOf` method is
* customized this function returns the custom method, otherwise it returns
* the `baseIndexOf` function. If arguments are provided the chosen function
@@ -38234,6 +37983,31 @@ return jQuery;
}
/**
+ * Checks if `func` is eligible for `this` binding.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` is eligible, else `false`.
+ */
+ function isBindable(func) {
+ var support = lodash.support,
+ result = !(support.funcNames ? func.name : support.funcDecomp);
+
+ if (!result) {
+ var source = fnToString.call(func);
+ if (!support.funcNames) {
+ result = !reFuncName.test(source);
+ }
+ if (!result) {
+ // Check if `func` references the `this` keyword and store the result.
+ result = reThis.test(source) || isNative(func);
+ baseSetData(func, result);
+ }
+ }
+ return result;
+ }
+
+ /**
* Checks if `value` is a valid array-like index.
*
* @private
@@ -38275,21 +38049,11 @@ return jQuery;
}
/**
- * Checks if `func` has a lazy counterpart.
- *
- * @private
- * @param {Function} func The function to check.
- * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
- */
- function isLaziable(func) {
- var funcName = getFuncName(func);
- return !!funcName && func === lodash[funcName] && funcName in LazyWrapper.prototype;
- }
-
- /**
* Checks if `value` is a valid array-like length.
*
- * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
+ * **Note:** This function is based on ES `ToLength`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * for more details.
*
* @private
* @param {*} value The value to check.
@@ -38329,13 +38093,22 @@ return jQuery;
function mergeData(data, source) {
var bitmask = data[1],
srcBitmask = source[1],
- newBitmask = bitmask | srcBitmask,
- isCommon = newBitmask < ARY_FLAG;
+ newBitmask = bitmask | srcBitmask;
+
+ var arityFlags = ARY_FLAG | REARG_FLAG,
+ bindFlags = BIND_FLAG | BIND_KEY_FLAG,
+ comboFlags = arityFlags | bindFlags | CURRY_BOUND_FLAG | CURRY_RIGHT_FLAG;
- var isCombo =
- (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
- (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
- (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+ var isAry = bitmask & ARY_FLAG && !(srcBitmask & ARY_FLAG),
+ isRearg = bitmask & REARG_FLAG && !(srcBitmask & REARG_FLAG),
+ argPos = (isRearg ? data : source)[7],
+ ary = (isAry ? data : source)[8];
+
+ var isCommon = !(bitmask >= REARG_FLAG && srcBitmask > bindFlags) &&
+ !(bitmask > bindFlags && srcBitmask >= REARG_FLAG);
+
+ var isCombo = (newBitmask >= arityFlags && newBitmask <= comboFlags) &&
+ (bitmask < REARG_FLAG || ((isRearg || isAry) && argPos.length <= ary));
// Exit early if metadata can't be merged.
if (!(isCommon || isCombo)) {
@@ -38654,9 +38427,10 @@ return jQuery;
* Creates an array excluding all values of the provided arrays using
* `SameValueZero` for equality comparisons.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -38669,11 +38443,19 @@ return jQuery;
* _.difference([1, 2, 3], [4, 2]);
* // => [1, 3]
*/
- var difference = restParam(function(array, values) {
- return (isArray(array) || isArguments(array))
- ? baseDifference(array, baseFlatten(values, false, true))
- : [];
- });
+ function difference() {
+ var args = arguments,
+ index = -1,
+ length = args.length;
+
+ while (++index < length) {
+ var value = args[index];
+ if (isArray(value) || isArguments(value)) {
+ break;
+ }
+ }
+ return baseDifference(value, baseFlatten(args, false, true, ++index));
+ }
/**
* Creates a slice of `array` with `n` elements dropped from the beginning.
@@ -38749,7 +38531,7 @@ return jQuery;
/**
* Creates a slice of `array` excluding elements dropped from the end.
* Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
+ * bound to `thisArg` and invoked with three arguments; (value, index, array).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -38796,15 +38578,19 @@ return jQuery;
* // => ['barney', 'fred', 'pebbles']
*/
function dropRightWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)
- : [];
+ var length = array ? array.length : 0;
+ if (!length) {
+ return [];
+ }
+ predicate = getCallback(predicate, thisArg, 3);
+ while (length-- && predicate(array[length], length, array)) {}
+ return baseSlice(array, 0, length + 1);
}
/**
* Creates a slice of `array` excluding elements dropped from the beginning.
* Elements are dropped until `predicate` returns falsey. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, index, array).
+ * bound to `thisArg` and invoked with three arguments; (value, index, array).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -38851,9 +38637,14 @@ return jQuery;
* // => ['barney', 'fred', 'pebbles']
*/
function dropWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), true)
- : [];
+ var length = array ? array.length : 0;
+ if (!length) {
+ return [];
+ }
+ var index = -1;
+ predicate = getCallback(predicate, thisArg, 3);
+ while (++index < length && predicate(array[index], index, array)) {}
+ return baseSlice(array, index);
}
/**
@@ -38870,19 +38661,6 @@ return jQuery;
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3];
- *
- * _.fill(array, 'a');
- * console.log(array);
- * // => ['a', 'a', 'a']
- *
- * _.fill(Array(3), 2);
- * // => [2, 2, 2]
- *
- * _.fill([4, 6, 8], '*', 1, 2);
- * // => [4, '*', 8]
*/
function fill(array, value, start, end) {
var length = array ? array.length : 0;
@@ -38898,7 +38676,7 @@ return jQuery;
/**
* This method is like `_.find` except that it returns the index of the first
- * element `predicate` returns truthy for instead of the element itself.
+ * element `predicate` returns truthy for, instead of the element itself.
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -38944,7 +38722,18 @@ return jQuery;
* _.findIndex(users, 'active');
* // => 2
*/
- var findIndex = createFindIndex();
+ function findIndex(array, predicate, thisArg) {
+ var index = -1,
+ length = array ? array.length : 0;
+
+ predicate = getCallback(predicate, thisArg, 3);
+ while (++index < length) {
+ if (predicate(array[index], index, array)) {
+ return index;
+ }
+ }
+ return -1;
+ }
/**
* This method is like `_.findIndex` except that it iterates over elements
@@ -38994,7 +38783,16 @@ return jQuery;
* _.findLastIndex(users, 'active');
* // => 0
*/
- var findLastIndex = createFindIndex(true);
+ function findLastIndex(array, predicate, thisArg) {
+ var length = array ? array.length : 0;
+ predicate = getCallback(predicate, thisArg, 3);
+ while (length--) {
+ if (predicate(array[length], length, array)) {
+ return length;
+ }
+ }
+ return -1;
+ }
/**
* Gets the first element of `array`.
@@ -39031,18 +38829,18 @@ return jQuery;
* @example
*
* _.flatten([1, [2, 3, [4]]]);
- * // => [1, 2, 3, [4]]
+ * // => [1, 2, 3, [4]];
*
* // using `isDeep`
* _.flatten([1, [2, 3, [4]]], true);
- * // => [1, 2, 3, 4]
+ * // => [1, 2, 3, 4];
*/
function flatten(array, isDeep, guard) {
var length = array ? array.length : 0;
if (guard && isIterateeCall(array, isDeep, guard)) {
isDeep = false;
}
- return length ? baseFlatten(array, isDeep) : [];
+ return length ? baseFlatten(array, isDeep, false, 0) : [];
}
/**
@@ -39056,11 +38854,11 @@ return jQuery;
* @example
*
* _.flattenDeep([1, [2, 3, [4]]]);
- * // => [1, 2, 3, 4]
+ * // => [1, 2, 3, 4];
*/
function flattenDeep(array) {
var length = array ? array.length : 0;
- return length ? baseFlatten(array, true) : [];
+ return length ? baseFlatten(array, true, false, 0) : [];
}
/**
@@ -39069,9 +38867,10 @@ return jQuery;
* it is used as the offset from the end of `array`. If `array` is sorted
* providing `true` for `fromIndex` performs a faster binary search.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39134,9 +38933,10 @@ return jQuery;
* Creates an array of unique values in all provided arrays using `SameValueZero`
* for equality comparisons.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39264,10 +39064,10 @@ return jQuery;
* comparisons.
*
* **Notes:**
- * - Unlike `_.without`, this method mutates `array`
- * - [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except
- * that `NaN` matches `NaN`
+ * - Unlike `_.without`, this method mutates `array`.
+ * - `SameValueZero` comparisons are like strict equality comparisons, e.g. `===`,
+ * except that `NaN` matches `NaN`. See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39330,28 +39130,14 @@ return jQuery;
* console.log(evens);
* // => [10, 20]
*/
- var pullAt = restParam(function(array, indexes) {
- array || (array = []);
- indexes = baseFlatten(indexes);
-
- var length = indexes.length,
- result = baseAt(array, indexes);
-
- indexes.sort(baseCompareAscending);
- while (length--) {
- var index = parseFloat(indexes[length]);
- if (index != previous && isIndex(index)) {
- var previous = index;
- splice.call(array, index, 1);
- }
- }
- return result;
- });
+ function pullAt(array) {
+ return basePullAt(array || [], baseFlatten(arguments, false, false, 1));
+ }
/**
* Removes all elements from `array` that `predicate` returns truthy for
* and returns an array of the removed elements. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
+ * `thisArg` and invoked with three arguments; (value, index, array).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -39455,14 +39241,14 @@ return jQuery;
* to compute their sort ranking. The iteratee is bound to `thisArg` and
* invoked with one argument; (value).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -39496,7 +39282,12 @@ return jQuery;
* _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
* // => 1
*/
- var sortedIndex = createSortedIndex();
+ function sortedIndex(array, value, iteratee, thisArg) {
+ var func = getCallback(iteratee);
+ return (func === baseCallback && iteratee == null)
+ ? binaryIndex(array, value)
+ : binaryIndexBy(array, value, func(iteratee, thisArg, 1));
+ }
/**
* This method is like `_.sortedIndex` except that it returns the highest
@@ -39518,7 +39309,12 @@ return jQuery;
* _.sortedLastIndex([4, 4, 5, 5], 5);
* // => 4
*/
- var sortedLastIndex = createSortedIndex(true);
+ function sortedLastIndex(array, value, iteratee, thisArg) {
+ var func = getCallback(iteratee);
+ return (func === baseCallback && iteratee == null)
+ ? binaryIndex(array, value, true)
+ : binaryIndexBy(array, value, func(iteratee, thisArg, 1), true);
+ }
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
@@ -39594,7 +39390,7 @@ return jQuery;
/**
* Creates a slice of `array` with elements taken from the end. Elements are
* taken until `predicate` returns falsey. The predicate is bound to `thisArg`
- * and invoked with three arguments: (value, index, array).
+ * and invoked with three arguments; (value, index, array).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -39641,15 +39437,19 @@ return jQuery;
* // => []
*/
function takeRightWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)
- : [];
+ var length = array ? array.length : 0;
+ if (!length) {
+ return [];
+ }
+ predicate = getCallback(predicate, thisArg, 3);
+ while (length-- && predicate(array[length], length, array)) {}
+ return baseSlice(array, length + 1);
}
/**
* Creates a slice of `array` with elements taken from the beginning. Elements
* are taken until `predicate` returns falsey. The predicate is bound to
- * `thisArg` and invoked with three arguments: (value, index, array).
+ * `thisArg` and invoked with three arguments; (value, index, array).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -39696,18 +39496,24 @@ return jQuery;
* // => []
*/
function takeWhile(array, predicate, thisArg) {
- return (array && array.length)
- ? baseWhile(array, getCallback(predicate, thisArg, 3))
- : [];
+ var length = array ? array.length : 0;
+ if (!length) {
+ return [];
+ }
+ var index = -1;
+ predicate = getCallback(predicate, thisArg, 3);
+ while (++index < length && predicate(array[index], index, array)) {}
+ return baseSlice(array, 0, index);
}
/**
* Creates an array of unique values, in order, of the provided arrays using
* `SameValueZero` for equality comparisons.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39719,9 +39525,9 @@ return jQuery;
* _.union([1, 2], [4, 2], [2, 1]);
* // => [1, 2, 4]
*/
- var union = restParam(function(arrays) {
- return baseUniq(baseFlatten(arrays, false, true));
- });
+ function union() {
+ return baseUniq(baseFlatten(arguments, false, true, 0));
+ }
/**
* Creates a duplicate-value-free version of an array using `SameValueZero`
@@ -39729,22 +39535,23 @@ return jQuery;
* search algorithm for sorted arrays. If an iteratee function is provided it
* is invoked for each value in the array to generate the criterion by which
* uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked
- * with three arguments: (value, index, array).
+ * with three arguments; (value, index, array).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39826,9 +39633,10 @@ return jQuery;
* Creates an array excluding all provided values using `SameValueZero` for
* equality comparisons.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -39841,15 +39649,14 @@ return jQuery;
* _.without([1, 2, 1, 3], 1, 2);
* // => [3]
*/
- var without = restParam(function(array, values) {
- return (isArray(array) || isArguments(array))
- ? baseDifference(array, values)
- : [];
- });
+ function without(array) {
+ return baseDifference(array, baseSlice(arguments, 1));
+ }
/**
- * Creates an array that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
- * of the provided arrays.
+ * Creates an array that is the symmetric difference of the provided arrays.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Symmetric_difference) for
+ * more details.
*
* @static
* @memberOf _
@@ -39891,13 +39698,20 @@ return jQuery;
* _.zip(['fred', 'barney'], [30, 40], [true, false]);
* // => [['fred', 30, true], ['barney', 40, false]]
*/
- var zip = restParam(unzip);
+ function zip() {
+ var length = arguments.length,
+ array = Array(length);
+
+ while (length--) {
+ array[length] = arguments[length];
+ }
+ return unzip(array);
+ }
/**
- * The inverse of `_.pairs`; this method returns an object composed from arrays
- * of property names and values. Provide either a single two dimensional array,
- * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
- * and one of corresponding values.
+ * Creates an object composed from arrays of property names and values. Provide
+ * either a single two dimensional array, e.g. `[[key1, value1], [key2, value2]]`
+ * or two arrays, one of property names and one of corresponding values.
*
* @static
* @memberOf _
@@ -39908,9 +39722,6 @@ return jQuery;
* @returns {Object} Returns the new object.
* @example
*
- * _.zipObject([['fred', 30], ['barney', 40]]);
- * // => { 'fred': 30, 'barney': 40 }
- *
* _.zipObject(['fred', 'barney'], [30, 40]);
* // => { 'fred': 30, 'barney': 40 }
*/
@@ -40007,14 +39818,13 @@ return jQuery;
* @returns {*} Returns the result of `interceptor`.
* @example
*
- * _(' abc ')
- * .chain()
- * .trim()
+ * _([1, 2, 3])
+ * .last()
* .thru(function(value) {
* return [value];
* })
* .value();
- * // => ['abc']
+ * // => [3]
*/
function thru(value, interceptor, thisArg) {
return interceptor.call(thisArg, value);
@@ -40204,32 +40014,32 @@ return jQuery;
* _.at(['a', 'b', 'c'], [0, 2]);
* // => ['a', 'c']
*
- * _.at(['barney', 'fred', 'pebbles'], 0, 2);
- * // => ['barney', 'pebbles']
+ * _.at(['fred', 'barney', 'pebbles'], 0, 2);
+ * // => ['fred', 'pebbles']
*/
- var at = restParam(function(collection, props) {
+ function at(collection) {
var length = collection ? collection.length : 0;
if (isLength(length)) {
collection = toIterable(collection);
}
- return baseAt(collection, baseFlatten(props));
- });
+ return baseAt(collection, baseFlatten(arguments, false, false, 1));
+ }
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
* of each key is the number of times the key was returned by `iteratee`.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -40262,7 +40072,7 @@ return jQuery;
/**
* Checks if `predicate` returns truthy for **all** elements of `collection`.
- * The predicate is bound to `thisArg` and invoked with three arguments:
+ * The predicate is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
@@ -40310,9 +40120,6 @@ return jQuery;
*/
function every(collection, predicate, thisArg) {
var func = isArray(collection) ? arrayEvery : baseEvery;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
- }
if (typeof predicate != 'function' || typeof thisArg != 'undefined') {
predicate = getCallback(predicate, thisArg, 3);
}
@@ -40322,7 +40129,7 @@ return jQuery;
/**
* Iterates over elements of `collection`, returning an array of all elements
* `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
+ * invoked with three arguments; (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -40377,7 +40184,7 @@ return jQuery;
/**
* Iterates over elements of `collection`, returning the first element
* `predicate` returns truthy for. The predicate is bound to `thisArg` and
- * invoked with three arguments: (value, index|key, collection).
+ * invoked with three arguments; (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -40424,7 +40231,14 @@ return jQuery;
* _.result(_.find(users, 'active'), 'user');
* // => 'barney'
*/
- var find = createFind(baseEach);
+ function find(collection, predicate, thisArg) {
+ if (isArray(collection)) {
+ var index = findIndex(collection, predicate, thisArg);
+ return index > -1 ? collection[index] : undefined;
+ }
+ predicate = getCallback(predicate, thisArg, 3);
+ return baseFind(collection, predicate, baseEach);
+ }
/**
* This method is like `_.find` except that it iterates over elements of
@@ -40445,7 +40259,10 @@ return jQuery;
* });
* // => 3
*/
- var findLast = createFind(baseEachRight, true);
+ function findLast(collection, predicate, thisArg) {
+ predicate = getCallback(predicate, thisArg, 3);
+ return baseFind(collection, predicate, baseEachRight);
+ }
/**
* Performs a deep comparison between each element in `collection` and the
@@ -40482,7 +40299,7 @@ return jQuery;
/**
* Iterates over elements of `collection` invoking `iteratee` for each element.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection). Iterator functions may exit iteration early
* by explicitly returning `false`.
*
@@ -40510,7 +40327,11 @@ return jQuery;
* });
* // => logs each value-key pair and returns the object (iteration order is not guaranteed)
*/
- var forEach = createForEach(arrayEach, baseEach);
+ function forEach(collection, iteratee, thisArg) {
+ return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection))
+ ? arrayEach(collection, iteratee)
+ : baseEach(collection, bindCallback(iteratee, thisArg, 3));
+ }
/**
* This method is like `_.forEach` except that it iterates over elements of
@@ -40528,26 +40349,30 @@ return jQuery;
*
* _([1, 2]).forEachRight(function(n) {
* console.log(n);
- * }).value();
+ * }).join(',');
* // => logs each value from right to left and returns the array
*/
- var forEachRight = createForEach(arrayEachRight, baseEachRight);
+ function forEachRight(collection, iteratee, thisArg) {
+ return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection))
+ ? arrayEachRight(collection, iteratee)
+ : baseEachRight(collection, bindCallback(iteratee, thisArg, 3));
+ }
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
* of each key is an array of the elements responsible for generating the key.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -40588,9 +40413,10 @@ return jQuery;
* comparisons. If `fromIndex` is negative, it is used as the offset from
* the end of `collection`.
*
- * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
- * comparisons are like strict equality comparisons, e.g. `===`, except that
- * `NaN` matches `NaN`.
+ * **Note:** `SameValueZero` comparisons are like strict equality comparisons,
+ * e.g. `===`, except that `NaN` matches `NaN`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * for more details.
*
* @static
* @memberOf _
@@ -40599,7 +40425,6 @@ return jQuery;
* @param {Array|Object|string} collection The collection to search.
* @param {*} target The value to search for.
* @param {number} [fromIndex=0] The index to search from.
- * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
* @returns {boolean} Returns `true` if a matching element is found, else `false`.
* @example
*
@@ -40615,7 +40440,7 @@ return jQuery;
* _.includes('pebbles', 'eb');
* // => true
*/
- function includes(collection, target, fromIndex, guard) {
+ function includes(collection, target, fromIndex) {
var length = collection ? collection.length : 0;
if (!isLength(length)) {
collection = values(collection);
@@ -40624,10 +40449,10 @@ return jQuery;
if (!length) {
return false;
}
- if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
- fromIndex = 0;
- } else {
+ if (typeof fromIndex == 'number') {
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
+ } else {
+ fromIndex = 0;
}
return (typeof collection == 'string' || !isArray(collection) && isString(collection))
? (fromIndex < length && collection.indexOf(target, fromIndex) > -1)
@@ -40638,17 +40463,17 @@ return jQuery;
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
* of each key is the last element responsible for generating the key. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
+ * iteratee function is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -40706,32 +40531,23 @@ return jQuery;
* _.invoke([123, 456], String.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']]
*/
- var invoke = restParam(function(collection, methodName, args) {
- var index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = isLength(length) ? Array(length) : [];
-
- baseEach(collection, function(value) {
- var func = isFunc ? methodName : (value != null && value[methodName]);
- result[++index] = func ? func.apply(value, args) : undefined;
- });
- return result;
- });
+ function invoke(collection, methodName) {
+ return baseInvoke(collection, methodName, baseSlice(arguments, 2));
+ }
/**
* Creates an array of values by running each element in `collection` through
* `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index|key, collection).
+ * arguments; (value, index|key, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -40740,9 +40556,9 @@ return jQuery;
*
* The guarded methods are:
* `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`,
- * `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`,
- * `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`,
- * `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, `uniq`, and `words`
+ * `dropRight`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, `slice`,
+ * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`,
+ * `trunc`, `random`, `range`, `sample`, `uniq`, and `words`
*
* @static
* @memberOf _
@@ -40785,7 +40601,7 @@ return jQuery;
* Creates an array of elements split into two groups, the first of which
* contains elements `predicate` returns truthy for, while the second of which
* contains elements `predicate` returns falsey for. The predicate is bound
- * to `thisArg` and invoked with three arguments: (value, index|key, collection).
+ * to `thisArg` and invoked with three arguments; (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -40876,14 +40692,14 @@ return jQuery;
* each element in `collection` through `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
* is not provided the first element of `collection` is used as the initial
- * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:
+ * value. The `iteratee` is bound to `thisArg`and invoked with four arguments;
* (accumulator, value, index|key, collection).
*
* Many lodash methods are guarded to work as interatees for methods like
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
- * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder`
+ * `assign`, `defaults`, `merge`, and `sortAllBy`
*
* @static
* @memberOf _
@@ -40907,7 +40723,10 @@ return jQuery;
* }, {});
* // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
*/
- var reduce = createReduce(arrayReduce, baseEach);
+ function reduce(collection, iteratee, accumulator, thisArg) {
+ var func = isArray(collection) ? arrayReduce : baseReduce;
+ return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEach);
+ }
/**
* This method is like `_.reduce` except that it iterates over elements of
@@ -40931,7 +40750,10 @@ return jQuery;
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
- var reduceRight = createReduce(arrayReduceRight, baseEachRight);
+ function reduceRight(collection, iteratee, accumulator, thisArg) {
+ var func = isArray(collection) ? arrayReduceRight : baseReduce;
+ return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEachRight);
+ }
/**
* The opposite of `_.filter`; this method returns the elements of `collection`
@@ -41018,8 +40840,9 @@ return jQuery;
}
/**
- * Creates an array of shuffled values, using a version of the
- * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+ * Creates an array of shuffled values, using a version of the Fisher-Yates
+ * shuffle. See [Wikipedia](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle)
+ * for more details.
*
* @static
* @memberOf _
@@ -41077,7 +40900,7 @@ return jQuery;
* Checks if `predicate` returns truthy for **any** element of `collection`.
* The function returns as soon as it finds a passing value and does not iterate
* over the entire collection. The predicate is bound to `thisArg` and invoked
- * with three arguments: (value, index|key, collection).
+ * with three arguments; (value, index|key, collection).
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -41124,9 +40947,6 @@ return jQuery;
*/
function some(collection, predicate, thisArg) {
var func = isArray(collection) ? arraySome : baseSome;
- if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
- predicate = null;
- }
if (typeof predicate != 'function' || typeof thisArg != 'undefined') {
predicate = getCallback(predicate, thisArg, 3);
}
@@ -41137,17 +40957,17 @@ return jQuery;
* Creates an array of elements, sorted in ascending order by the results of
* running each element in a collection through `iteratee`. This method performs
* a stable sort, that is, it preserves the original sort order of equal elements.
- * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments;
* (value, index|key, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -41223,24 +41043,17 @@ return jQuery;
* _.map(_.sortByAll(users, ['user', 'age']), _.values);
* // => [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
*/
- function sortByAll() {
- var args = arguments,
- collection = args[0],
- guard = args[3],
- index = 0,
- length = args.length - 1;
-
+ function sortByAll(collection) {
if (collection == null) {
return [];
}
- var props = Array(length);
- while (index < length) {
- props[index] = args[++index];
- }
+ var args = arguments,
+ guard = args[3];
+
if (guard && isIterateeCall(args[1], args[2], guard)) {
- props = args[1];
+ args = [collection, args[1]];
}
- return baseSortByOrder(collection, baseFlatten(props), []);
+ return baseSortByOrder(collection, baseFlatten(args, false, false, 1), []);
}
/**
@@ -41459,7 +41272,7 @@ return jQuery;
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
- * @param {...*} [partials] The arguments to be partially applied.
+ * @param {...*} [args] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
@@ -41478,14 +41291,16 @@ return jQuery;
* bound('hi');
* // => 'hi fred!'
*/
- var bind = restParam(function(func, thisArg, partials) {
+ function bind(func, thisArg) {
var bitmask = BIND_FLAG;
- if (partials.length) {
- var holders = replaceHolders(partials, bind.placeholder);
+ if (arguments.length > 2) {
+ var partials = baseSlice(arguments, 2),
+ holders = replaceHolders(partials, bind.placeholder);
+
bitmask |= PARTIAL_FLAG;
}
return createWrapper(func, bitmask, thisArg, partials, holders);
- });
+ }
/**
* Binds methods of an object to the object itself, overwriting the existing
@@ -41515,18 +41330,13 @@ return jQuery;
* jQuery('#docs').on('click', view.onClick);
* // => logs 'clicked docs' when the element is clicked
*/
- var bindAll = restParam(function(object, methodNames) {
- methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);
-
- var index = -1,
- length = methodNames.length;
-
- while (++index < length) {
- var key = methodNames[index];
- object[key] = createWrapper(object[key], BIND_FLAG, object);
- }
- return object;
- });
+ function bindAll(object) {
+ return baseBindAll(object,
+ arguments.length > 1
+ ? baseFlatten(arguments, false, false, 1)
+ : functions(object)
+ );
+ }
/**
* Creates a function that invokes the method at `object[key]` and prepends
@@ -41545,7 +41355,7 @@ return jQuery;
* @category Function
* @param {Object} object The object the method belongs to.
* @param {string} key The key of the method.
- * @param {...*} [partials] The arguments to be partially applied.
+ * @param {...*} [args] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
@@ -41572,14 +41382,16 @@ return jQuery;
* bound('hi');
* // => 'hiya fred!'
*/
- var bindKey = restParam(function(object, key, partials) {
+ function bindKey(object, key) {
var bitmask = BIND_FLAG | BIND_KEY_FLAG;
- if (partials.length) {
- var holders = replaceHolders(partials, bindKey.placeholder);
+ if (arguments.length > 2) {
+ var partials = baseSlice(arguments, 2),
+ holders = replaceHolders(partials, bindKey.placeholder);
+
bitmask |= PARTIAL_FLAG;
}
return createWrapper(key, bitmask, object, partials, holders);
- });
+ }
/**
* Creates a function that accepts one or more arguments of `func` that when
@@ -41621,7 +41433,14 @@ return jQuery;
* curried(1)(_, 3)(2);
* // => [1, 2, 3]
*/
- var curry = createCurry(CURRY_FLAG);
+ function curry(func, arity, guard) {
+ if (guard && isIterateeCall(func, arity, guard)) {
+ arity = null;
+ }
+ var result = createWrapper(func, CURRY_FLAG, null, null, null, null, null, arity);
+ result.placeholder = curry.placeholder;
+ return result;
+ }
/**
* This method is like `_.curry` except that arguments are applied to `func`
@@ -41660,7 +41479,14 @@ return jQuery;
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
- var curryRight = createCurry(CURRY_RIGHT_FLAG);
+ function curryRight(func, arity, guard) {
+ if (guard && isIterateeCall(func, arity, guard)) {
+ arity = null;
+ }
+ var result = createWrapper(func, CURRY_RIGHT_FLAG, null, null, null, null, null, arity);
+ result.placeholder = curryRight.placeholder;
+ return result;
+ }
/**
* Creates a function that delays invoking `func` until after `wait` milliseconds
@@ -41855,9 +41681,9 @@ return jQuery;
* }, 'deferred');
* // logs 'deferred' after one or more milliseconds
*/
- var defer = restParam(function(func, args) {
- return baseDelay(func, 1, args);
- });
+ function defer(func) {
+ return baseDelay(func, 1, arguments, 1);
+ }
/**
* Invokes `func` after `wait` milliseconds. Any additional arguments are
@@ -41877,9 +41703,9 @@ return jQuery;
* }, 1000, 'later');
* // => logs 'later' after one second
*/
- var delay = restParam(function(func, wait, args) {
- return baseDelay(func, wait, args);
- });
+ function delay(func, wait) {
+ return baseDelay(func, wait, arguments, 2);
+ }
/**
* Creates a function that returns the result of invoking the provided
@@ -41901,7 +41727,7 @@ return jQuery;
* addSquare(1, 2);
* // => 9
*/
- var flow = createFlow();
+ var flow = createComposer();
/**
* This method is like `_.flow` except that it creates a function that
@@ -41923,7 +41749,7 @@ return jQuery;
* addSquare(1, 2);
* // => 9
*/
- var flowRight = createFlow(true);
+ var flowRight = createComposer(true);
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
@@ -41935,8 +41761,10 @@ return jQuery;
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the [`Map`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object)
- * method interface of `get`, `has`, and `set`.
+ * constructor with one whose instances implement the ES `Map` method interface
+ * of `get`, `has`, and `set`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object)
+ * for more details.
*
* @static
* @memberOf _
@@ -42027,7 +41855,7 @@ return jQuery;
/**
* Creates a function that is restricted to invoking `func` once. Repeat calls
* to the function return the value of the first call. The `func` is invoked
- * with the `this` binding and arguments of the created function.
+ * with the `this` binding of the created function.
*
* @static
* @memberOf _
@@ -42060,7 +41888,7 @@ return jQuery;
* @memberOf _
* @category Function
* @param {Function} func The function to partially apply arguments to.
- * @param {...*} [partials] The arguments to be partially applied.
+ * @param {...*} [args] The arguments to be partially applied.
* @returns {Function} Returns the new partially applied function.
* @example
*
@@ -42077,7 +41905,12 @@ return jQuery;
* greetFred('hi');
* // => 'hi fred'
*/
- var partial = createPartial(PARTIAL_FLAG);
+ function partial(func) {
+ var partials = baseSlice(arguments, 1),
+ holders = replaceHolders(partials, partial.placeholder);
+
+ return createWrapper(func, PARTIAL_FLAG, null, partials, holders);
+ }
/**
* This method is like `_.partial` except that partially applied arguments
@@ -42093,7 +41926,7 @@ return jQuery;
* @memberOf _
* @category Function
* @param {Function} func The function to partially apply arguments to.
- * @param {...*} [partials] The arguments to be partially applied.
+ * @param {...*} [args] The arguments to be partially applied.
* @returns {Function} Returns the new partially applied function.
* @example
*
@@ -42110,7 +41943,12 @@ return jQuery;
* sayHelloTo('fred');
* // => 'hello fred'
*/
- var partialRight = createPartial(PARTIAL_RIGHT_FLAG);
+ function partialRight(func) {
+ var partials = baseSlice(arguments, 1),
+ holders = replaceHolders(partials, partialRight.placeholder);
+
+ return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders);
+ }
/**
* Creates a function that invokes `func` with arguments arranged according
@@ -42140,80 +41978,29 @@ return jQuery;
* }, [1, 2, 3]);
* // => [3, 6, 9]
*/
- var rearg = restParam(function(func, indexes) {
- return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes));
- });
-
- /**
- * Creates a function that invokes `func` with the `this` binding of the
- * created function and arguments from `start` and beyond provided as an array.
- *
- * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
- *
- * @static
- * @memberOf _
- * @category Function
- * @param {Function} func The function to apply a rest parameter to.
- * @param {number} [start=func.length-1] The start position of the rest parameter.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var say = _.restParam(function(what, names) {
- * return what + ' ' + _.initial(names).join(', ') +
- * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
- * });
- *
- * say('hello', 'fred', 'barney', 'pebbles');
- * // => 'hello fred, barney, & pebbles'
- */
- function restParam(func, start) {
- if (typeof func != 'function') {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
- start = nativeMax(typeof start == 'undefined' ? (func.length - 1) : (+start || 0), 0);
- return function() {
- var args = arguments,
- index = -1,
- length = nativeMax(args.length - start, 0),
- rest = Array(length);
-
- while (++index < length) {
- rest[index] = args[start + index];
- }
- switch (start) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, args[0], rest);
- case 2: return func.call(this, args[0], args[1], rest);
- }
- var otherArgs = Array(start + 1);
- index = -1;
- while (++index < start) {
- otherArgs[index] = args[index];
- }
- otherArgs[start] = rest;
- return func.apply(this, otherArgs);
- };
+ function rearg(func) {
+ var indexes = baseFlatten(arguments, false, false, 1);
+ return createWrapper(func, REARG_FLAG, null, null, null, indexes);
}
/**
- * Creates a function that invokes `func` with the `this` binding of the created
- * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
- *
- * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator).
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and the array of arguments provided to the created
+ * function much like [Function#apply](http://es5.github.io/#x15.3.4.3).
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to spread arguments over.
- * @returns {Function} Returns the new function.
+ * @returns {*} Returns the new function.
* @example
*
- * var say = _.spread(function(who, what) {
+ * var spread = _.spread(function(who, what) {
* return who + ' says ' + what;
* });
*
- * say(['fred', 'hello']);
- * // => 'fred says hello'
+ * spread(['Fred', 'hello']);
+ * // => 'Fred says hello'
*
* // with a Promise
* var numbers = Promise.all([
@@ -42328,12 +42115,12 @@ return jQuery;
* cloning is handled by the method instead. The `customizer` is bound to
* `thisArg` and invoked with two argument; (value [, index|key, object]).
*
- * **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+ * **Note:** This method is loosely based on the structured clone algorithm.
* The enumerable properties of `arguments` objects and objects created by
* constructors other than `Object` are cloned to plain `Object` objects. An
* empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
+ * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
+ * for more details.
*
* @static
* @memberOf _
@@ -42391,12 +42178,12 @@ return jQuery;
* is handled by the method instead. The `customizer` is bound to `thisArg`
* and invoked with two argument; (value [, index|key, object]).
*
- * **Note:** This method is loosely based on the
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+ * **Note:** This method is loosely based on the structured clone algorithm.
* The enumerable properties of `arguments` objects and objects created by
* constructors other than `Object` are cloned to plain `Object` objects. An
* empty object is returned for uncloneable values such as functions, DOM nodes,
- * Maps, Sets, and WeakMaps.
+ * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
+ * for more details.
*
* @static
* @memberOf _
@@ -42453,7 +42240,7 @@ return jQuery;
*/
function isArguments(value) {
var length = isObjectLike(value) ? value.length : undefined;
- return isLength(length) && objToString.call(value) == argsTag;
+ return (isLength(length) && objToString.call(value) == argsTag) || false;
}
/**
@@ -42473,7 +42260,7 @@ return jQuery;
* // => false
*/
var isArray = nativeIsArray || function(value) {
- return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+ return (isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag) || false;
};
/**
@@ -42493,7 +42280,7 @@ return jQuery;
* // => false
*/
function isBoolean(value) {
- return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
+ return (value === true || value === false || isObjectLike(value) && objToString.call(value) == boolTag) || false;
}
/**
@@ -42513,7 +42300,7 @@ return jQuery;
* // => false
*/
function isDate(value) {
- return isObjectLike(value) && objToString.call(value) == dateTag;
+ return (isObjectLike(value) && objToString.call(value) == dateTag) || false;
}
/**
@@ -42533,13 +42320,13 @@ return jQuery;
* // => false
*/
function isElement(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) &&
- (objToString.call(value).indexOf('Element') > -1);
+ return (value && value.nodeType === 1 && isObjectLike(value) &&
+ (objToString.call(value).indexOf('Element') > -1)) || false;
}
// Fallback for environments without DOM support.
if (!support.dom) {
isElement = function(value) {
- return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
+ return (value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value)) || false;
};
}
@@ -42587,7 +42374,7 @@ return jQuery;
* equivalent. If `customizer` is provided it is invoked to compare values.
* If `customizer` returns `undefined` comparisons are handled by the method
* instead. The `customizer` is bound to `thisArg` and invoked with three
- * arguments: (value, other [, index|key]).
+ * arguments; (value, other [, index|key]).
*
* **Note:** This method supports comparing arrays, booleans, `Date` objects,
* numbers, `Object` objects, regexes, and strings. Objects are compared by
@@ -42652,13 +42439,15 @@ return jQuery;
* // => false
*/
function isError(value) {
- return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
+ return (isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag) || false;
}
/**
* Checks if `value` is a finite primitive number.
*
- * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite).
+ * **Note:** This method is based on ES `Number.isFinite`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite)
+ * for more details.
*
* @static
* @memberOf _
@@ -42710,9 +42499,11 @@ return jQuery;
};
/**
- * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * Checks if `value` is the language type of `Object`.
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
+ * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details.
+ *
* @static
* @memberOf _
* @category Lang
@@ -42733,7 +42524,7 @@ return jQuery;
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
- return type == 'function' || (!!value && type == 'object');
+ return type == 'function' || (value && type == 'object') || false;
}
/**
@@ -42741,7 +42532,7 @@ return jQuery;
* `object` contains equivalent property values. If `customizer` is provided
* it is invoked to compare values. If `customizer` returns `undefined`
* comparisons are handled by the method instead. The `customizer` is bound
- * to `thisArg` and invoked with three arguments: (value, other, index|key).
+ * to `thisArg` and invoked with three arguments; (value, other, index|key).
*
* **Note:** This method supports comparing properties of arrays, booleans,
* `Date` objects, numbers, `Object` objects, regexes, and strings. Functions
@@ -42779,19 +42570,13 @@ return jQuery;
var props = keys(source),
length = props.length;
- if (!length) {
- return true;
- }
- if (object == null) {
- return false;
- }
customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3);
if (!customizer && length == 1) {
var key = props[0],
value = source[key];
if (isStrictComparable(value)) {
- return value === object[key] && (typeof value != 'undefined' || (key in toObject(object)));
+ return object != null && value === object[key] && hasOwnProperty.call(object, key);
}
}
var values = Array(length),
@@ -42801,14 +42586,15 @@ return jQuery;
value = values[length] = source[props[length]];
strictCompareFlags[length] = isStrictComparable(value);
}
- return baseIsMatch(toObject(object), props, values, strictCompareFlags, customizer);
+ return baseIsMatch(object, props, values, strictCompareFlags, customizer);
}
/**
* Checks if `value` is `NaN`.
*
- * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
- * which returns `true` for `undefined` and other non-numeric values.
+ * **Note:** This method is not the same as native `isNaN` which returns `true`
+ * for `undefined` and other non-numeric values. See the [ES5 spec](https://es5.github.io/#x15.1.2.4)
+ * for more details.
*
* @static
* @memberOf _
@@ -42858,7 +42644,7 @@ return jQuery;
if (objToString.call(value) == funcTag) {
return reNative.test(fnToString.call(value));
}
- return isObjectLike(value) && reHostCtor.test(value);
+ return (isObjectLike(value) && reHostCtor.test(value)) || false;
}
/**
@@ -42904,7 +42690,7 @@ return jQuery;
* // => false
*/
function isNumber(value) {
- return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+ return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag) || false;
}
/**
@@ -42986,7 +42772,7 @@ return jQuery;
* // => false
*/
function isString(value) {
- return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+ return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag) || false;
}
/**
@@ -43006,7 +42792,7 @@ return jQuery;
* // => false
*/
function isTypedArray(value) {
- return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+ return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false;
}
/**
@@ -43088,7 +42874,7 @@ return jQuery;
* Assigns own enumerable properties of source object(s) to the destination
* object. Subsequent sources overwrite property assignments of previous sources.
* If `customizer` is provided it is invoked to produce the assigned values.
- * The `customizer` is bound to `thisArg` and invoked with five arguments:
+ * The `customizer` is bound to `thisArg` and invoked with five arguments;
* (objectValue, sourceValue, key, object, source).
*
* @static
@@ -43173,18 +42959,18 @@ return jQuery;
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
* // => { 'user': 'barney', 'age': 36 }
*/
- var defaults = restParam(function(args) {
- var object = args[0];
+ function defaults(object) {
if (object == null) {
return object;
}
+ var args = arrayCopy(arguments);
args.push(assignDefaults);
return assign.apply(undefined, args);
- });
+ }
/**
- * This method is like `_.find` except that it returns the key of the first
- * element `predicate` returns truthy for instead of the element itself.
+ * This method is like `_.findIndex` except that it returns the key of the
+ * first element `predicate` returns truthy for, instead of the element itself.
*
* If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
@@ -43230,7 +43016,10 @@ return jQuery;
* _.findKey(users, 'active');
* // => 'barney'
*/
- var findKey = createFindKey(baseForOwn);
+ function findKey(object, predicate, thisArg) {
+ predicate = getCallback(predicate, thisArg, 3);
+ return baseFind(object, predicate, baseForOwn, true);
+ }
/**
* This method is like `_.findKey` except that it iterates over elements of
@@ -43280,12 +43069,15 @@ return jQuery;
* _.findLastKey(users, 'active');
* // => 'pebbles'
*/
- var findLastKey = createFindKey(baseForOwnRight);
+ function findLastKey(object, predicate, thisArg) {
+ predicate = getCallback(predicate, thisArg, 3);
+ return baseFind(object, predicate, baseForOwnRight, true);
+ }
/**
* Iterates over own and inherited enumerable properties of an object invoking
* `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked
- * with three arguments: (value, key, object). Iterator functions may exit
+ * with three arguments; (value, key, object). Iterator functions may exit
* iteration early by explicitly returning `false`.
*
* @static
@@ -43309,7 +43101,12 @@ return jQuery;
* });
* // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)
*/
- var forIn = createForIn(baseFor);
+ function forIn(object, iteratee, thisArg) {
+ if (typeof iteratee != 'function' || typeof thisArg != 'undefined') {
+ iteratee = bindCallback(iteratee, thisArg, 3);
+ }
+ return baseFor(object, iteratee, keysIn);
+ }
/**
* This method is like `_.forIn` except that it iterates over properties of
@@ -43336,12 +43133,15 @@ return jQuery;
* });
* // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
*/
- var forInRight = createForIn(baseForRight);
+ function forInRight(object, iteratee, thisArg) {
+ iteratee = bindCallback(iteratee, thisArg, 3);
+ return baseForRight(object, iteratee, keysIn);
+ }
/**
* Iterates over own enumerable properties of an object invoking `iteratee`
* for each property. The `iteratee` is bound to `thisArg` and invoked with
- * three arguments: (value, key, object). Iterator functions may exit iteration
+ * three arguments; (value, key, object). Iterator functions may exit iteration
* early by explicitly returning `false`.
*
* @static
@@ -43365,7 +43165,12 @@ return jQuery;
* });
* // => logs 'a' and 'b' (iteration order is not guaranteed)
*/
- var forOwn = createForOwn(baseForOwn);
+ function forOwn(object, iteratee, thisArg) {
+ if (typeof iteratee != 'function' || typeof thisArg != 'undefined') {
+ iteratee = bindCallback(iteratee, thisArg, 3);
+ }
+ return baseForOwn(object, iteratee);
+ }
/**
* This method is like `_.forOwn` except that it iterates over properties of
@@ -43392,7 +43197,10 @@ return jQuery;
* });
* // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
*/
- var forOwnRight = createForOwn(baseForOwnRight);
+ function forOwnRight(object, iteratee, thisArg) {
+ iteratee = bindCallback(iteratee, thisArg, 3);
+ return baseForRight(object, iteratee, keys);
+ }
/**
* Creates an array of function property names from all enumerable properties,
@@ -43577,7 +43385,7 @@ return jQuery;
/**
* Creates an object with the same keys as `object` and values generated by
* running each own enumerable property of `object` through `iteratee`. The
- * iteratee function is bound to `thisArg` and invoked with three arguments:
+ * iteratee function is bound to `thisArg` and invoked with three arguments;
* (value, key, object).
*
* If a property name is provided for `iteratee` the created `_.property`
@@ -43632,7 +43440,7 @@ return jQuery;
* provided it is invoked to produce the merged values of the destination and
* source properties. If `customizer` returns `undefined` merging is handled
* by the method instead. The `customizer` is bound to `thisArg` and invoked
- * with five arguments: (objectValue, sourceValue, key, object, source).
+ * with five arguments; (objectValue, sourceValue, key, object, source).
*
* @static
* @memberOf _
@@ -43681,7 +43489,7 @@ return jQuery;
* Property names may be specified as individual arguments or as arrays of
* property names. If `predicate` is provided it is invoked for each property
* of `object` omitting the properties `predicate` returns truthy for. The
- * predicate is bound to `thisArg` and invoked with three arguments:
+ * predicate is bound to `thisArg` and invoked with three arguments;
* (value, key, object).
*
* @static
@@ -43703,19 +43511,19 @@ return jQuery;
* _.omit(object, _.isNumber);
* // => { 'user': 'fred' }
*/
- var omit = restParam(function(object, props) {
+ function omit(object, predicate, thisArg) {
if (object == null) {
return {};
}
- if (typeof props[0] != 'function') {
- var props = arrayMap(baseFlatten(props), String);
+ if (typeof predicate != 'function') {
+ var props = arrayMap(baseFlatten(arguments, false, false, 1), String);
return pickByArray(object, baseDifference(keysIn(object), props));
}
- var predicate = bindCallback(props[0], props[1], 3);
+ predicate = bindCallback(predicate, thisArg, 3);
return pickByCallback(object, function(value, key, object) {
return !predicate(value, key, object);
});
- });
+ }
/**
* Creates a two dimensional array of the key-value pairs for `object`,
@@ -43749,7 +43557,7 @@ return jQuery;
* names may be specified as individual arguments or as arrays of property
* names. If `predicate` is provided it is invoked for each property of `object`
* picking the properties `predicate` returns truthy for. The predicate is
- * bound to `thisArg` and invoked with three arguments: (value, key, object).
+ * bound to `thisArg` and invoked with three arguments; (value, key, object).
*
* @static
* @memberOf _
@@ -43770,14 +43578,14 @@ return jQuery;
* _.pick(object, _.isString);
* // => { 'user': 'fred' }
*/
- var pick = restParam(function(object, props) {
+ function pick(object, predicate, thisArg) {
if (object == null) {
return {};
}
- return typeof props[0] == 'function'
- ? pickByCallback(object, bindCallback(props[0], props[1], 3))
- : pickByArray(object, baseFlatten(props));
- });
+ return typeof predicate == 'function'
+ ? pickByCallback(object, bindCallback(predicate, thisArg, 3))
+ : pickByArray(object, baseFlatten(arguments, false, false, 1));
+ }
/**
* Resolves the value of property `key` on `object`. If the value of `key` is
@@ -43822,7 +43630,7 @@ return jQuery;
* `accumulator` object which is the result of running each of its own enumerable
* properties through `iteratee`, with each invocation potentially mutating
* the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked
- * with four arguments: (accumulator, value, key, object). Iterator functions
+ * with four arguments; (accumulator, value, key, object). Iterator functions
* may exit iteration early by explicitly returning `false`.
*
* @static
@@ -44033,7 +43841,8 @@ return jQuery;
/*------------------------------------------------------------------------*/
/**
- * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
+ * Converts `string` to camel case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/CamelCase) for more details.
*
* @static
* @memberOf _
@@ -44075,8 +43884,9 @@ return jQuery;
}
/**
- * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
- * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+ * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+ * for more details.
*
* @static
* @memberOf _
@@ -44090,7 +43900,7 @@ return jQuery;
*/
function deburr(string) {
string = baseToString(string);
- return string && string.replace(reLatin1, deburrLetter).replace(reComboMarks, '');
+ return string && string.replace(reLatin1, deburrLetter);
}
/**
@@ -44145,8 +43955,9 @@ return jQuery;
* [#108](https://html5sec.org/#108), and [#133](https://html5sec.org/#133) of
* the [HTML5 Security Cheatsheet](https://html5sec.org/) for more details.
*
- * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
- * to reduce XSS vectors.
+ * When working with HTML you should always quote attribute values to reduce
+ * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping)
+ * for more details.
*
* @static
* @memberOf _
@@ -44167,8 +43978,8 @@ return jQuery;
}
/**
- * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",
- * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
+ * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*",
+ * "+", "(", ")", "[", "]", "{" and "}" in `string`.
*
* @static
* @memberOf _
@@ -44178,7 +43989,7 @@ return jQuery;
* @example
*
* _.escapeRegExp('[lodash](https://lodash.com/)');
- * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'
+ * // => '\[lodash\]\(https://lodash\.com/\)'
*/
function escapeRegExp(string) {
string = baseToString(string);
@@ -44188,7 +43999,9 @@ return jQuery;
}
/**
- * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+ * Converts `string` to kebab case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for
+ * more details.
*
* @static
* @memberOf _
@@ -44211,8 +44024,9 @@ return jQuery;
});
/**
- * Pads `string` on the left and right sides if it is shorter than `length`.
- * Padding characters are truncated if they can't be evenly divided by `length`.
+ * Pads `string` on the left and right sides if it is shorter then the given
+ * padding length. The `chars` string may be truncated if the number of padding
+ * characters can't be evenly divided by the padding length.
*
* @static
* @memberOf _
@@ -44244,13 +44058,14 @@ return jQuery;
leftLength = floor(mid),
rightLength = ceil(mid);
- chars = createPadding('', rightLength, chars);
+ chars = createPad('', rightLength, chars);
return chars.slice(0, leftLength) + string + chars;
}
/**
- * Pads `string` on the left side if it is shorter than `length`. Padding
- * characters are truncated if they exceed `length`.
+ * Pads `string` on the left side if it is shorter then the given padding
+ * length. The `chars` string may be truncated if the number of padding
+ * characters exceeds the padding length.
*
* @static
* @memberOf _
@@ -44270,11 +44085,15 @@ return jQuery;
* _.padLeft('abc', 3);
* // => 'abc'
*/
- var padLeft = createPadDir();
+ function padLeft(string, length, chars) {
+ string = baseToString(string);
+ return string && (createPad(string, length, chars) + string);
+ }
/**
- * Pads `string` on the right side if it is shorter than `length`. Padding
- * characters are truncated if they exceed `length`.
+ * Pads `string` on the right side if it is shorter then the given padding
+ * length. The `chars` string may be truncated if the number of padding
+ * characters exceeds the padding length.
*
* @static
* @memberOf _
@@ -44294,15 +44113,18 @@ return jQuery;
* _.padRight('abc', 3);
* // => 'abc'
*/
- var padRight = createPadDir(true);
+ function padRight(string, length, chars) {
+ string = baseToString(string);
+ return string && (string + createPad(string, length, chars));
+ }
/**
* Converts `string` to an integer of the specified radix. If `radix` is
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
* in which case a `radix` of `16` is used.
*
- * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
- * of `parseInt`.
+ * **Note:** This method aligns with the ES5 implementation of `parseInt`.
+ * See the [ES5 spec](https://es5.github.io/#E) for more details.
*
* @static
* @memberOf _
@@ -44382,7 +44204,8 @@ return jQuery;
}
/**
- * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
+ * Converts `string` to snake case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details.
*
* @static
* @memberOf _
@@ -44405,7 +44228,9 @@ return jQuery;
});
/**
- * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+ * Converts `string` to start case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage)
+ * for more details.
*
* @static
* @memberOf _
@@ -44464,9 +44289,9 @@ return jQuery;
* properties may be accessed as free variables in the template. If a setting
* object is provided it takes precedence over `_.templateSettings` values.
*
- * **Note:** In the development build `_.template` utilizes
- * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
- * for easier debugging.
+ * **Note:** In the development build `_.template` utilizes sourceURLs for easier debugging.
+ * See the [HTML5 Rocks article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+ * for more details.
*
* For more information on precompiling templates see
* [lodash's custom builds documentation](https://lodash.com/custom-builds).
@@ -44678,7 +44503,7 @@ return jQuery;
* // => 'abc'
*
* _.map([' foo ', ' bar '], _.trim);
- * // => ['foo', 'bar']
+ * // => ['foo', 'bar]
*/
function trim(string, chars, guard) {
var value = string;
@@ -44786,7 +44611,7 @@ return jQuery;
* 'length': 24,
* 'separator': /,? +/
* });
- * // => 'hi-diddly-ho there...'
+ * //=> 'hi-diddly-ho there...'
*
* _.trunc('hi-diddly-ho there, neighborino', {
* 'omission': ' [...]'
@@ -44905,7 +44730,7 @@ return jQuery;
* @static
* @memberOf _
* @category Utility
- * @param {Function} func The function to attempt.
+ * @param {*} func The function to attempt.
* @returns {*} Returns the `func` result or error object.
* @example
*
@@ -44918,13 +44743,20 @@ return jQuery;
* elements = [];
* }
*/
- var attempt = restParam(function(func, args) {
+ function attempt() {
+ var func = arguments[0],
+ length = arguments.length,
+ args = Array(length ? (length - 1) : 0);
+
+ while (--length > 0) {
+ args[length - 1] = arguments[length];
+ }
try {
return func.apply(undefined, args);
} catch(e) {
return isError(e) ? e : new Error(e);
}
- });
+ }
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
@@ -45061,11 +44893,12 @@ return jQuery;
*
* var users = [
* { 'user': 'barney' },
- * { 'user': 'fred' }
+ * { 'user': 'fred' },
+ * { 'user': 'pebbles' }
* ];
*
* _.find(users, _.matchesProperty('user', 'fred'));
- * // => { 'user': 'fred' }
+ * // => { 'user': 'fred', 'age': 40 }
*/
function matchesProperty(key, value) {
return baseMatchesProperty(key + '', baseClone(value, true));
@@ -45076,9 +44909,6 @@ return jQuery;
* destination object. If `object` is a function then methods are added to
* its prototype as well.
*
- * **Note:** Use `_.runInContext` to create a pristine `lodash` function
- * for mixins to avoid conflicts caused by modifying the original.
- *
* @static
* @memberOf _
* @category Utility
@@ -45096,7 +44926,7 @@ return jQuery;
* });
* }
*
- * // use `_.runInContext` to avoid conflicts (esp. in Node.js)
+ * // use `_.runInContext` to avoid potential conflicts (esp. in Node.js)
* var _ = require('lodash').runInContext();
*
* _.mixin({ 'vowels': vowels });
@@ -45146,10 +44976,12 @@ return jQuery;
return function() {
var chainAll = this.__chain__;
if (chain || chainAll) {
- var result = object(this.__wrapped__),
- actions = result.__actions__ = arrayCopy(this.__actions__);
-
- actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
+ var result = object(this.__wrapped__);
+ (result.__actions__ = arrayCopy(this.__actions__)).push({
+ 'func': func,
+ 'args': arguments,
+ 'thisArg': object
+ });
result.__chain__ = chainAll;
return result;
}
@@ -45216,7 +45048,7 @@ return jQuery;
* var getName = _.property('user');
*
* _.map(users, getName);
- * // => ['fred', 'barney']
+ * // => ['fred', barney']
*
* _.pluck(_.sortBy(users, getName), 'user');
* // => ['barney', 'fred']
@@ -45226,7 +45058,7 @@ return jQuery;
}
/**
- * The opposite of `_.property`; this method creates a function which returns
+ * The inverse of `_.property`; this method creates a function which returns
* the property value of a given key on `object`.
*
* @static
@@ -45404,16 +45236,16 @@ return jQuery;
* `-Infinity` is returned. If an iteratee function is provided it is invoked
* for each value in `collection` to generate the criterion by which the value
* is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
+ * arguments; (value, index, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -45440,11 +45272,11 @@ return jQuery;
* _.max(users, function(chr) {
* return chr.age;
* });
- * // => { 'user': 'fred', 'age': 40 }
+ * // => { 'user': 'fred', 'age': 40 };
*
* // using the `_.property` callback shorthand
* _.max(users, 'age');
- * // => { 'user': 'fred', 'age': 40 }
+ * // => { 'user': 'fred', 'age': 40 };
*/
var max = createExtremum(arrayMax);
@@ -45453,16 +45285,16 @@ return jQuery;
* `Infinity` is returned. If an iteratee function is provided it is invoked
* for each value in `collection` to generate the criterion by which the value
* is ranked. The `iteratee` is bound to `thisArg` and invoked with three
- * arguments: (value, index, collection).
+ * arguments; (value, index, collection).
*
- * If a property name is provided for `iteratee` the created `_.property`
+ * If a property name is provided for `predicate` the created `_.property`
* style callback returns the property value of the given element.
*
* If a value is also provided for `thisArg` the created `_.matchesProperty`
* style callback returns `true` for elements that have a matching property
* value, else `false`.
*
- * If an object is provided for `iteratee` the created `_.matches` style
+ * If an object is provided for `predicate` the created `_.matches` style
* callback returns `true` for elements that have the properties of the given
* object, else `false`.
*
@@ -45489,11 +45321,11 @@ return jQuery;
* _.min(users, function(chr) {
* return chr.age;
* });
- * // => { 'user': 'barney', 'age': 36 }
+ * // => { 'user': 'barney', 'age': 36 };
*
* // using the `_.property` callback shorthand
* _.min(users, 'age');
- * // => { 'user': 'barney', 'age': 36 }
+ * // => { 'user': 'barney', 'age': 36 };
*/
var min = createExtremum(arrayMin, true);
@@ -45504,45 +45336,26 @@ return jQuery;
* @memberOf _
* @category Math
* @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee] The function invoked per iteration.
- * @param {*} [thisArg] The `this` binding of `iteratee`.
* @returns {number} Returns the sum.
* @example
*
- * _.sum([4, 6]);
- * // => 10
+ * _.sum([4, 6, 2]);
+ * // => 12
*
- * _.sum({ 'a': 4, 'b': 6 });
- * // => 10
- *
- * var objects = [
- * { 'n': 4 },
- * { 'n': 6 }
- * ];
- *
- * _.sum(objects, function(object) {
- * return object.n;
- * });
- * // => 10
- *
- * // using the `_.property` callback shorthand
- * _.sum(objects, 'n');
- * // => 10
+ * _.sum({ 'a': 4, 'b': 6, 'c': 2 });
+ * // => 12
*/
- function sum(collection, iteratee, thisArg) {
- if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
- iteratee = null;
+ function sum(collection) {
+ if (!isArray(collection)) {
+ collection = toIterable(collection);
}
- var func = getCallback(),
- noIteratee = iteratee == null;
+ var length = collection.length,
+ result = 0;
- if (!(func === baseCallback && noIteratee)) {
- noIteratee = false;
- iteratee = func(iteratee, thisArg, 3);
+ while (length--) {
+ result += +collection[length] || 0;
}
- return noIteratee
- ? arraySum(isArray(collection) ? collection : toIterable(collection))
- : baseSum(collection, iteratee);
+ return result;
}
/*------------------------------------------------------------------------*/
@@ -45641,7 +45454,6 @@ return jQuery;
lodash.reject = reject;
lodash.remove = remove;
lodash.rest = rest;
- lodash.restParam = restParam;
lodash.shuffle = shuffle;
lodash.slice = slice;
lodash.sortBy = sortBy;
@@ -45933,11 +45745,8 @@ return jQuery;
// Add `LazyWrapper` methods to `lodash.prototype`.
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
- var lodashFunc = lodash[methodName];
- if (!lodashFunc) {
- return;
- }
- var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
+ var lodashFunc = lodash[methodName],
+ checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
retUnwrapped = /^(?:first|last)$/.test(methodName);
lodash.prototype[methodName] = function() {
@@ -45996,19 +45805,6 @@ return jQuery;
};
});
- // Map minified function names to their real names.
- baseForOwn(LazyWrapper.prototype, function(func, methodName) {
- var lodashFunc = lodash[methodName];
- if (lodashFunc) {
- var key = lodashFunc.name,
- names = realNames[key] || (realNames[key] = []);
-
- names.push({ 'name': methodName, 'func': lodashFunc });
- }
- });
-
- realNames[createHybridWrapper(null, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': null }];
-
// Add functions to the lazy wrapper.
LazyWrapper.prototype.clone = lazyClone;
LazyWrapper.prototype.reverse = lazyReverse;
@@ -46098,7 +45894,7 @@ exports.createRedirect = require("./Route").createRedirect;
exports.createRoutesFromReactChildren = require("./createRoutesFromReactChildren");
exports.create = require("./createRouter");
exports.run = require("./runRouter");
-},{"./History":10,"./Navigation":12,"./Route":16,"./State":18,"./behaviors/ImitateBrowserBehavior":21,"./behaviors/ScrollToTopBehavior":22,"./components/DefaultRoute":24,"./components/Link":25,"./components/NotFoundRoute":26,"./components/Redirect":27,"./components/Route":28,"./components/RouteHandler":29,"./createRouter":30,"./createRoutesFromReactChildren":31,"./locations/HashLocation":34,"./locations/HistoryLocation":35,"./locations/RefreshLocation":36,"./locations/StaticLocation":37,"./locations/TestLocation":38,"./runRouter":39}],"react/addons":[function(require,module,exports){
+},{"./History":5,"./Navigation":7,"./Route":11,"./State":13,"./behaviors/ImitateBrowserBehavior":16,"./behaviors/ScrollToTopBehavior":17,"./components/DefaultRoute":19,"./components/Link":20,"./components/NotFoundRoute":21,"./components/Redirect":22,"./components/Route":23,"./components/RouteHandler":24,"./createRouter":25,"./createRoutesFromReactChildren":26,"./locations/HashLocation":29,"./locations/HistoryLocation":30,"./locations/RefreshLocation":31,"./locations/StaticLocation":32,"./locations/TestLocation":33,"./runRouter":34}],"react/addons":[function(require,module,exports){
module.exports = require('./lib/ReactWithAddons');
},{"./lib/ReactWithAddons":141}],"react":[function(require,module,exports){
diff --git a/test/test_console_palettes.py b/test/test_console_palettes.py
index 3f8e280a..a3b7fe4f 100644
--- a/test/test_console_palettes.py
+++ b/test/test_console_palettes.py
@@ -8,4 +8,6 @@ import libmproxy.console.palettes as palettes
class TestPalette:
def test_helptext(self):
for i in palettes.palettes.values():
- assert i.palette()
+ assert i.palette(False)
+ for i in palettes.palettes.values():
+ assert i.palette(True)
diff --git a/test/tools/testpatt b/test/tools/testpatt
index 5ee1ea02..b41011c0 100755
--- a/test/tools/testpatt
+++ b/test/tools/testpatt
@@ -1,9 +1,9 @@
#!/bin/bash
# Generate a test pattern with pathoc
-PATHOD=http://localhost:9999
-pathoc localhost:8080 "get:'$PATHOD/p/200:p0,1:b@2048b':b@2048b"
-pathoc localhost:8080 "get:'$PATHOD/p/300:p0,1:b@2048b':b@2048b"
-pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@2048b':b@2048b"
-pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@2048b':b@2048b"
-pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@2048b':b@2048b"
+PATHOD=localhost:9999
+pathoc -s -c $PATHOD localhost:8080 "get:'/p/200:p0,1:b@2048b':b@2048b"
+pathoc -s -c $PATHOD localhost:8080 "get:'/p/300:p0,1:b@2048b':b@2048b"
+pathoc -s -c $PATHOD localhost:8080 "get:'/p/400:p0,1:b@2048b':b@2048b"
+pathoc -s -c $PATHOD localhost:8080 "get:'/p/500:p0,1:b@2048b':b@2048b"
+pathoc -s -c $PATHOD localhost:8080 "get:'/p/600:p0,1:b@2048b':b@2048b"
diff --git a/web/src/js/actions.js b/web/src/js/actions.js
index 32c3c7c0..2455a52e 100644
--- a/web/src/js/actions.js
+++ b/web/src/js/actions.js
@@ -116,7 +116,7 @@ var FlowActions = {
});
},
clear: function(){
- $.post("/flows/" + flow.id);
+ $.post("/clear");
}
};