Sun, 23 Apr 2017 13:15:30 +0900 encoding: introduce tagging type for non-lossy non-ASCII string
Yuya Nishihara <yuya@tcha.org> [Sun, 23 Apr 2017 13:15:30 +0900] rev 37991
encoding: introduce tagging type for non-lossy non-ASCII string This fixes the weird behavior of toutf8b(), which would convert a local string back to UTF-8 *only if* it was lossy in the system encoding. Before b7b26e54e37a "encoding: avoid localstr when a string can be encoded losslessly (issue2763)", all local strings were wrapped by the localstr class. I think this would justify the round-trip behavior of toutf8b(). ASCII strings are special-cased, so the cost of wrapping with safelocalstr is negligible. (with mercurial repo) $ export HGRCPATH=/dev/null HGPLAIN= HGENCODING=latin-1 $ hg log --time --config experimental.evolution=all > /dev/null (original) time: real 11.340 secs (user 11.290+0.000 sys 0.060+0.000) time: real 11.390 secs (user 11.300+0.000 sys 0.080+0.000) time: real 11.430 secs (user 11.360+0.000 sys 0.070+0.000) (this patch) time: real 11.200 secs (user 11.100+0.000 sys 0.100+0.000) time: real 11.370 secs (user 11.300+0.000 sys 0.070+0.000) time: real 11.190 secs (user 11.130+0.000 sys 0.060+0.000)
Sun, 22 Apr 2018 11:38:53 +0900 encoding: fix toutf8b() to resurrect lossy characters even if "\xed" in it
Yuya Nishihara <yuya@tcha.org> [Sun, 22 Apr 2018 11:38:53 +0900] rev 37990
encoding: fix toutf8b() to resurrect lossy characters even if "\xed" in it If 's' is a localstr, 's._utf8' must be returned to get the original UTF-8 sequence back. Because of this, it was totally wrong to test if '"\xed" not in s', which should be either '"\xed" not in s._utf8' or just omitted. This patch moves the localstr handling to top as the validity of 's._utf8' should be pre-checked by encoding.tolocal().
Sun, 25 Mar 2018 16:47:33 +0900 sshserver: redirect stdin/stdout early and use duplicated streams
Yuya Nishihara <yuya@tcha.org> [Sun, 25 Mar 2018 16:47:33 +0900] rev 37989
sshserver: redirect stdin/stdout early and use duplicated streams This is what we achieved with hook.redirect(True) plus ui.fout = ui.ferr. The hook.redirect() function can't be completely removed yet since hgweb still depends on it. I'm not sure if it is necessary for WSGI servers. CGI needs it, but does WSGI communicate over stdin/stdout channels?
Sun, 25 Mar 2018 16:35:24 +0900 sshserver: do setbinary() by caller (API)
Yuya Nishihara <yuya@tcha.org> [Sun, 25 Mar 2018 16:35:24 +0900] rev 37988
sshserver: do setbinary() by caller (API) In most cases, stdio should be set to binary mode by the dispatcher, so the sshserver does not have to take care of that. The only exception was hg-ssh, which is fixed by this patch. .. api:: ``sshserver()`` no longer sets stdin and stdout to binary mode.
Sun, 25 Mar 2018 16:39:17 +0900 test-ssh: add some flush() to make output deterministic
Yuya Nishihara <yuya@tcha.org> [Sun, 25 Mar 2018 16:39:17 +0900] rev 37987
test-ssh: add some flush() to make output deterministic We shouldn't rely on buffering mode/state of file handles.
Thu, 10 May 2018 21:08:32 +0900 stringutil: flip the default of pprint() to bprefix=False
Yuya Nishihara <yuya@tcha.org> [Thu, 10 May 2018 21:08:32 +0900] rev 37986
stringutil: flip the default of pprint() to bprefix=False If we use pprint() as a drop-in replacement for repr(), bprefix=False is more appropriate. Let's make it the default to remove bprefix=False noise.
Thu, 10 May 2018 21:00:58 +0900 stringutil: make pprint() forward uninteresting object to b'%r'
Yuya Nishihara <yuya@tcha.org> [Thu, 10 May 2018 21:00:58 +0900] rev 37985
stringutil: make pprint() forward uninteresting object to b'%r' We appear to start using pprint() as a replacement for repr(), so it's probably safer to support any Python objects instead of complaining about that.
Fri, 27 Apr 2018 13:46:54 -0400 tests: use stringutil.pprint instead of custom dumper in test-hgweb-auth.py
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:46:54 -0400] rev 37984
tests: use stringutil.pprint instead of custom dumper in test-hgweb-auth.py Differential Revision: https://phab.mercurial-scm.org/D3529
Fri, 27 Apr 2018 13:43:59 -0400 tests: port test-simplekeyvaluefile.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:43:59 -0400] rev 37983
tests: port test-simplekeyvaluefile.py to Python 3 # skip-blame just b prefixes Differential Revision: https://phab.mercurial-scm.org/D3528
Fri, 27 Apr 2018 13:39:45 -0400 tests: port test-extensions-wrapfunction to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:39:45 -0400] rev 37982
tests: port test-extensions-wrapfunction to Python 3 Differential Revision: https://phab.mercurial-scm.org/D3527
Fri, 27 Apr 2018 13:15:51 -0400 tests: port test-ui-config to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:15:51 -0400] rev 37981
tests: port test-ui-config to Python 3 Slight test output changes to make life easier. Differential Revision: https://phab.mercurial-scm.org/D3526
Fri, 27 Apr 2018 13:37:10 -0400 config: fix py3 backslash escaping bug in parser caught by tests
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:37:10 -0400] rev 37980
config: fix py3 backslash escaping bug in parser caught by tests Differential Revision: https://phab.mercurial-scm.org/D3525
Fri, 27 Apr 2018 13:27:18 -0400 tests: port test-symlink-os-yes-fs-no.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:27:18 -0400] rev 37979
tests: port test-symlink-os-yes-fs-no.py to Python 3 # skip-blame just bytes/str changes Differential Revision: https://phab.mercurial-scm.org/D3524
Fri, 27 Apr 2018 13:26:43 -0400 posix: use inst.errno instead of inst[0] on OSError instances
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:26:43 -0400] rev 37978
posix: use inst.errno instead of inst[0] on OSError instances Differential Revision: https://phab.mercurial-scm.org/D3523
Fri, 27 Apr 2018 13:17:24 -0400 tests: port test-filelog.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:17:24 -0400] rev 37977
tests: port test-filelog.py to Python 3 # skip-blame just some bytes prefixes Differential Revision: https://phab.mercurial-scm.org/D3522
Fri, 27 Apr 2018 13:15:16 -0400 stringutil: teach pprint about tuples
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:15:16 -0400] rev 37976
stringutil: teach pprint about tuples Differential Revision: https://phab.mercurial-scm.org/D3521
Thu, 19 Apr 2018 21:00:12 +0900 templatefuncs: show hint if extdata source is evaluated to empty (issue5843)
Yuya Nishihara <yuya@tcha.org> [Thu, 19 Apr 2018 21:00:12 +0900] rev 37975
templatefuncs: show hint if extdata source is evaluated to empty (issue5843)
Fri, 04 May 2018 21:31:34 -0700 revlog: use literal -1 instead of variable that always has that value
Martin von Zweigbergk <martinvonz@google.com> [Fri, 04 May 2018 21:31:34 -0700] rev 37974
revlog: use literal -1 instead of variable that always has that value We were setting "ntrev" to "rev", but "rev" was always -1 at the end of the loop, so it's clearer to use a literal -1. Differential Revision: https://phab.mercurial-scm.org/D3498
Fri, 04 May 2018 22:17:28 -0700 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com> [Fri, 04 May 2018 22:17:28 -0700] rev 37973
revlog: extract function for fully populating the radix tree This code is currently used for partialmatch(), but I want to reuse it when I implement shortest() in native code. Differential Revision: https://phab.mercurial-scm.org/D3497
Fri, 27 Apr 2018 12:07:57 -0400 tests: port test-lfs-pointer.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 12:07:57 -0400] rev 37972
tests: port test-lfs-pointer.py to Python 3 The weird bit here is having to import /something/ from Mercurial before we touch hgext.* so that the module loader gets initialized. That's probably a bug we should explore at some point? Differential Revision: https://phab.mercurial-scm.org/D3514
Fri, 27 Apr 2018 13:09:19 -0400 tests: port test-ui-verbosity.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 13:09:19 -0400] rev 37971
tests: port test-ui-verbosity.py to Python 3 # skip-blame just some bytes/string wrangling Differential Revision: https://phab.mercurial-scm.org/D3515
Fri, 27 Apr 2018 12:07:32 -0400 lfs: stabilize error message values for Python 2 and 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 12:07:32 -0400] rev 37970
lfs: stabilize error message values for Python 2 and 3 Differential Revision: https://phab.mercurial-scm.org/D3513
Fri, 27 Apr 2018 11:59:21 -0400 tests: port test-ui-color.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:59:21 -0400] rev 37969
tests: port test-ui-color.py to Python 3 As in some other tests, I like confirming that we're dealing with bytes here, so the b prefix is now in the expected output on both 2 and 3. Differential Revision: https://phab.mercurial-scm.org/D3512
Fri, 27 Apr 2018 11:57:15 -0400 tests: port test-dispatch.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:57:15 -0400] rev 37968
tests: port test-dispatch.py to Python 3 Differential Revision: https://phab.mercurial-scm.org/D3511
Fri, 27 Apr 2018 11:55:04 -0400 tests: port test-wireproto.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:55:04 -0400] rev 37967
tests: port test-wireproto.py to Python 3 A little bit of output churn because we now get b'' prefixes on output in both 2 and 3, but for this test I'm more comfortable knowing that we're using bytestrs everywhere. Differential Revision: https://phab.mercurial-scm.org/D3510
Fri, 27 Apr 2018 11:50:24 -0400 tests: port test-context.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:50:24 -0400] rev 37966
tests: port test-context.py to Python 3 This is a weird "minimally invasive" port. I think there's room to do better here, but I'm also not sure how often we'll touch this code... Differential Revision: https://phab.mercurial-scm.org/D3509
Fri, 27 Apr 2018 11:49:49 -0400 scmutil: fix __repr__ of status tuple
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:49:49 -0400] rev 37965
scmutil: fix __repr__ of status tuple We should probably start giving some thought to migrating the status tuple to attrs, but not now. Differential Revision: https://phab.mercurial-scm.org/D3508
Mon, 07 May 2018 19:43:43 -0700 update: print warning about hidden changeset after update
Martin von Zweigbergk <martinvonz@google.com> [Mon, 07 May 2018 19:43:43 -0700] rev 37964
update: print warning about hidden changeset after update When an attempt to update to a hidden changeset fails because the working copy is dirty, you may get a message like this: updating to a hidden changeset 343f6de32686 (hidden revision '343f6de32686' was rewritten as: 4ab941244072) abort: conflicting changes (commit or update --clean to discard changes) It's easy to miss the real error here. This patch moves the warning about the hidden changeset to after the update has happened. It changes the verb tense accordingly (and drops the "a" that I think it sounds better without). Of course, this means that the commit isn't actually hidden anymore when the message is printed. I think that's fine. Differential Revision: https://phab.mercurial-scm.org/D3479
Fri, 27 Apr 2018 01:35:00 -0400 py3: whitelist three passing cvs convert tests
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 01:35:00 -0400] rev 37963
py3: whitelist three passing cvs convert tests Differential Revision: https://phab.mercurial-scm.org/D3490
Fri, 27 Apr 2018 01:32:21 -0400 cvsps: convert encoding name to sysstr
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 01:32:21 -0400] rev 37962
cvsps: convert encoding name to sysstr Differential Revision: https://phab.mercurial-scm.org/D3489
Wed, 09 May 2018 13:46:31 -0700 tweakdefaults: remove "bisect" from commands.status.skipstates
Martin von Zweigbergk <martinvonz@google.com> [Wed, 09 May 2018 13:46:31 -0700] rev 37961
tweakdefaults: remove "bisect" from commands.status.skipstates If you forget to clear bisect state after you're done bisecting (as I've done twice in the last week or so), the next time you run `hg bisect --good/--bad`, it's going to tell you "The first bad revision is:" etc. It's probably not obvious to new users what's going on, and having the verbose output about an ongoing bisection will probably help them, so let's turn it back on by default. Differential Revision: https://phab.mercurial-scm.org/D3516
Tue, 03 Apr 2018 22:58:33 +0900 hgweb: wrap {instabilities} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Tue, 03 Apr 2018 22:58:33 +0900] rev 37960
hgweb: wrap {instabilities} by hybridlist() This is a list of simple values, which can be a hybrid list.
Tue, 03 Apr 2018 22:55:33 +0900 hgweb: wrap {whyunstable} with mappinggenerator
Yuya Nishihara <yuya@tcha.org> [Tue, 03 Apr 2018 22:55:33 +0900] rev 37959
hgweb: wrap {whyunstable} with mappinggenerator This is also a generator of mappings, which needs a wrapper.
Tue, 03 Apr 2018 22:54:36 +0900 hgweb: wrap {succsandmarkers} with mappinggenerator
Yuya Nishihara <yuya@tcha.org> [Tue, 03 Apr 2018 22:54:36 +0900] rev 37958
hgweb: wrap {succsandmarkers} with mappinggenerator This is also a generator of mappings, which needs a wrapper.
Mon, 02 Apr 2018 00:46:33 +0900 hgweb: wrap {branches} and {entries} of branches with mappinggenerator
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:46:33 +0900] rev 37957
hgweb: wrap {branches} and {entries} of branches with mappinggenerator Bare generator of mappings shouldn't be put in a template mapping because its type can't be determined without consuming it.
Mon, 02 Apr 2018 00:41:19 +0900 hgweb: drop tmpl argument from webutil.showtag() and showbookmark()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:41:19 +0900] rev 37956
hgweb: drop tmpl argument from webutil.showtag() and showbookmark() It's replaced by a context argument passed to a mappinggenerator.
Mon, 02 Apr 2018 00:39:26 +0900 hgweb: wrap {changelogtag}, {changesettag}, and {changesetbookmark}
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:39:26 +0900] rev 37955
hgweb: wrap {changelogtag}, {changesettag}, and {changesetbookmark} These can't be hybrid lists as they've associated with named template, 't1'.
Mon, 02 Apr 2018 00:29:31 +0900 hgweb: drop useless **args from webutil.showtag() and showbookmark()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:29:31 +0900] rev 37954
hgweb: drop useless **args from webutil.showtag() and showbookmark() Callers never pass excessive arguments to these functions.
Tue, 08 May 2018 19:00:01 +0800 hgweb: reuse graph node-related functions from templates
Anton Shestakov <av6@dwimlabs.net> [Tue, 08 May 2018 19:00:01 +0800] rev 37953
hgweb: reuse graph node-related functions from templates The difference between templatekw.getgraphnode() and webutil.getgraphnode() is that the latter is not limited to 1 character.
Tue, 08 May 2018 17:54:57 +0800 templates: split getgraphnode() body into two functions
Anton Shestakov <av6@dwimlabs.net> [Tue, 08 May 2018 17:54:57 +0800] rev 37952
templates: split getgraphnode() body into two functions getgraphnodecurrent() is checking if the node is currently checked out and getgraphnodesymbol() is checking properties that have more to do with the stored data and the DAG.
Mon, 02 Apr 2018 00:06:39 +0900 hgweb: wrap {branch} and {changesetbranch} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:06:39 +0900] rev 37951
hgweb: wrap {branch} and {changesetbranch} by hybridlist() This is also a 0/1-length list of a simple value, can be a hybrid list. Appears that we have many {branch} variants.
Mon, 02 Apr 2018 00:05:38 +0900 hgweb: wrap {inbranch} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:05:38 +0900] rev 37950
hgweb: wrap {inbranch} by hybridlist() This is also a 0/1-length list of a simple value, can be a hybrid list.
Mon, 02 Apr 2018 00:04:53 +0900 hgweb: wrap {branches} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:04:53 +0900] rev 37949
hgweb: wrap {branches} by hybridlist() This is a 0/1-length list of a simple value, can be a hybrid list.
Mon, 02 Apr 2018 00:03:49 +0900 hgweb: wrap {bookmarks} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:03:49 +0900] rev 37948
hgweb: wrap {bookmarks} by hybridlist() This is also a list of simple values.
Mon, 02 Apr 2018 00:02:36 +0900 hgweb: wrap {tags} by hybridlist()
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:02:36 +0900] rev 37947
hgweb: wrap {tags} by hybridlist() This one is a list of simple values, which can be a hybrid list.
Mon, 02 Apr 2018 00:00:29 +0900 hgweb: wrap {rename} with mappinglist
Yuya Nishihara <yuya@tcha.org> [Mon, 02 Apr 2018 00:00:29 +0900] rev 37946
hgweb: wrap {rename} with mappinglist No bare list of mappings should be put in a template mapping.
Fri, 27 Apr 2018 11:23:41 -0400 tests: fix test-status-inprocess.py on Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:23:41 -0400] rev 37945
tests: fix test-status-inprocess.py on Python 3 The same print() hack as test-filecache.py. Differential Revision: https://phab.mercurial-scm.org/D3507
Fri, 27 Apr 2018 11:22:00 -0400 tests: port test-filecache.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:22:00 -0400] rev 37944
tests: port test-filecache.py to Python 3 Only remarkable bit is my wrapper around print(), which I regret a little, but not enough to go back and try to do something cleaner. Differential Revision: https://phab.mercurial-scm.org/D3506
Fri, 27 Apr 2018 11:07:24 -0400 tests: port test-cbor.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:07:24 -0400] rev 37943
tests: port test-cbor.py to Python 3 I suspect this b''.join() was a remnant of an earlier iteration of this code, as it was building a string from a string. Differential Revision: https://phab.mercurial-scm.org/D3505
Fri, 27 Apr 2018 11:06:49 -0400 cborutil: port to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 11:06:49 -0400] rev 37942
cborutil: port to Python 3 The only problem lurking in here was sorts of mismatched types. The sorts are only for output stability in our tests (sigh), so we just build a phony sort key using the __name__ of types so that we only compare like types against each other. By pure luck, my awful sort key matches the behavior we get "for free" in Python 2, so no test output changes. Differential Revision: https://phab.mercurial-scm.org/D3504
Fri, 27 Apr 2018 10:58:08 -0400 lock: pass sysstr to warnings module
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:58:08 -0400] rev 37941
lock: pass sysstr to warnings module This makes test-lock.py slightly less broken, but it's still pretty far from passing. Differential Revision: https://phab.mercurial-scm.org/D3503
Fri, 27 Apr 2018 10:46:33 -0400 tests: port test-revlog-raw.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:46:33 -0400] rev 37940
tests: port test-revlog-raw.py to Python 3 # skip-blame just b prefixes Differential Revision: https://phab.mercurial-scm.org/D3496
Fri, 27 Apr 2018 10:40:04 -0400 tests: migrate test-wsgirequest.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:40:04 -0400] rev 37939
tests: migrate test-wsgirequest.py to Python 3 # skip-blame adding and removing b prefixes Differential Revision: https://phab.mercurial-scm.org/D3495
Fri, 27 Apr 2018 10:31:49 -0400 tests: port test-parseindex2.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:31:49 -0400] rev 37938
tests: port test-parseindex2.py to Python 3 # skip-blame just b prefixes and int() instead of long() Differential Revision: https://phab.mercurial-scm.org/D3494
Fri, 27 Apr 2018 10:30:24 -0400 tests: prefer string concatenation with () instead of \ in parseindex2 tests
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:30:24 -0400] rev 37937
tests: prefer string concatenation with () instead of \ in parseindex2 tests Differential Revision: https://phab.mercurial-scm.org/D3493
Fri, 27 Apr 2018 10:17:48 -0400 tests: port test-simplemerge.py to Python 3
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:17:48 -0400] rev 37936
tests: port test-simplemerge.py to Python 3 # skip-blame just b prefixes Differential Revision: https://phab.mercurial-scm.org/D3492
Fri, 27 Apr 2018 10:21:24 -0400 tests: replace use of assertEquals with assertEqual in test-simplemerge.py
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 10:21:24 -0400] rev 37935
tests: replace use of assertEquals with assertEqual in test-simplemerge.py The former is deprecated. No functionality change. # skip-blame just removing an ess and some whitespace Differential Revision: https://phab.mercurial-scm.org/D3491
Fri, 27 Apr 2018 01:30:29 -0400 tests: b prefixes on some inline python in test-convert-cvs.t
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 01:30:29 -0400] rev 37934
tests: b prefixes on some inline python in test-convert-cvs.t # skip-blame just b prefixes Differential Revision: https://phab.mercurial-scm.org/D3488
Fri, 27 Apr 2018 01:28:56 -0400 cvsps: wrap bytes in bytestr before %r-ing it
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 01:28:56 -0400] rev 37933
cvsps: wrap bytes in bytestr before %r-ing it Differential Revision: https://phab.mercurial-scm.org/D3487
Fri, 27 Apr 2018 01:27:22 -0400 convcmd: make a copy of heads before mutating it
Augie Fackler <augie@google.com> [Fri, 27 Apr 2018 01:27:22 -0400] rev 37932
convcmd: make a copy of heads before mutating it Differential Revision: https://phab.mercurial-scm.org/D3486
(0) -30000 -10000 -3000 -1000 -300 -100 -60 +60 +100 +300 +1000 +3000 +10000 tip