Эх сурвалжийг харах

wallet: make a ChatView widget

darkfi 2 жил өмнө
parent
commit
1b88b31950

+ 332 - 0
bin/darkwallet/chat.txt

@@ -0,0 +1,332 @@
+2024-02-07 21:21:25	somiaj	Z-module: am I messing up the logic now...grr
+2024-02-07 21:22:10	somiaj	rex: If a is a free variable, then you need a universe, though I guess if you already know something about a you don't, thanks for pointing that out.
+2024-02-07 21:22:37	rex	no I mean things like -1 \not\in ℕ
+2024-02-07 21:22:41	rex	why do I need a universe here?
+2024-02-07 21:23:19	somiaj	yea, that is what I was stating, if you knew something about the object, it wasn't a free variable, then you are correct, a universal set isn't needed
+2024-02-07 21:23:33	rex	that's what you meant. I see
+2024-02-07 21:23:44	somiaj	I was (maybe incorrectly) assuming that x and y were free variables here (vs already in some other set or something is known about them, like yoru example)
+2024-02-07 21:24:15	somiaj	so yea, I guess there are contexts in which you can use not in A, but A^c may not be welldefined
+2024-02-07 21:28:21	rex	with free variables you mean, that it is implicit to what universe they belong?
+2024-02-07 21:43:04	mh_le	Z-module: can I get you to take a look at a solution?
+2024-02-07 21:57:48	mahboubine	I've got a function and I calculated it's derivative to determine whether the function is increasing or decreasing at different intervals.
+2024-02-07 21:59:16	mahboubine	but the exercise correction also found the points from which the curve stars descending or ascending, for instance f(x) decends from 0 to -1/4 and back up until 0 and so on
+2024-02-07 21:59:26	mahboubine	I am wondering how to find those points as well
+2024-02-07 22:01:14	blackfield	well you're looking for points c such that f'(c)=0, or undefined..
+2024-02-07 22:04:14	blackfield	then you can test f''(c)>0 (then the point is a local minimum), or if f''(c)<0 it's a local maximum
+2024-02-07 22:08:32	mahboubine	I came to that conclusion as well
+2024-02-07 22:08:39	mahboubine	pretty easy now that I see it.
+2024-02-07 22:08:45	mahboubine	thanks, blackfield
+2024-02-07 22:08:51	blackfield	:)
+2024-02-07 23:51:00	biberao	hi
+2024-02-08 00:53:39	bouma	would you call within a 75% CI weak evidence ? i would call it no evidence
+2024-02-08 01:00:28	somiaj	bouma: I would just call it a 75% CI, so 1 and 4 chance you are wrong.
+2024-02-08 01:00:49	somiaj	I don't think a p value of 0.25 is that common, most prefer 0.05 or smaller
+2024-02-08 01:34:20	PlanckWalk	Ci width has little to do with evidence strength.
+2024-02-08 02:19:35	KZ-Spectra	hello
+2024-02-08 02:34:19	KZ-Spectra	originally, the indices n+m and n-m do not coincide.
+2024-02-08 02:34:39	KZ-Spectra	so when impose periodicity, then I want that also to be the case
+2024-02-08 02:35:15	KZ-Spectra	anyway, here is a fun problem
+2024-02-08 02:35:43	KZ-Spectra	"Find the remainder when 9 x 99 x 999  x ... x 99....9 (999 9s) is divided by 1000"
+2024-02-08 02:35:49	KZ-Spectra	Z-module: ^
+2024-02-08 02:43:44	Z-module	so the last factor there is 10^999 - 1 ?
+2024-02-08 03:01:14	KZ-Spectra	yeah
+2024-02-08 03:02:30	KZ-Spectra	it's the flavor of mod arithmetic since that's what we have been doing :)
+2024-02-08 03:08:00	KZ-Spectra	Z-module:  I'll give you the end answer: 109
+2024-02-08 03:09:22	KZ-Spectra	Z-module: https://i.imgur.com/vTstSUO.png can we just do this?
+2024-02-08 03:13:43	PlanckWalk	yeah, 9*99*999^997 = 891*(-1) = 109 (mod 1000)
+2024-02-08 03:15:15	PlanckWalk	KZ-Spectra: Are you assuming that u_{n+m} = u_{n-m} in general?
+2024-02-08 03:15:30	KZ-Spectra	oh no
+2024-02-08 03:19:04	PlanckWalk	Oh, I had trouble seeing the subscripts.  After I zoomed in so I could see Z^+, yeah that's fine.
+2024-02-08 03:19:16	PlanckWalk	Err, superscripts
+2024-02-08 03:20:09	KZ-Spectra	PlanckWalk:  were you comparing with the mathbin link from earlier? https://mathb.in/77541 Equation 1
+2024-02-08 03:20:24	PlanckWalk	No
+2024-02-08 03:21:14	PlanckWalk	It looks like it stands alone
+2024-02-08 03:22:22	PlanckWalk	There are possible questions of conditional convergence, though.
+2024-02-08 03:23:48	KZ-Spectra	those u's are complex
+2024-02-08 03:23:49	PlanckWalk	Defining a sum over Z usually requires absolute convergence, but the LHS doesn't.
+2024-02-08 03:23:54	PlanckWalk	Doesn't matter
+2024-02-08 03:24:38	PlanckWalk	So *if* the RHS is defined, it is equal to the LHS.
+2024-02-08 03:25:34	KZ-Spectra	do I even need to go to Z to do my mod arithmetic argument?
+2024-02-08 03:25:52	PlanckWalk	No idea, I haven't read through the mathbin at all.
+2024-02-08 03:26:03	PlanckWalk	(and probably won't since I'm just in a tea break at work)
+2024-02-08 06:12:54	Hasdiel	Does anyone know of a good self-hosted open source alternative to wolfram alpha?
+2024-02-08 07:18:54	Pelleplutt	Hello everyone. Our boss have given us a math problem for fun. If we solve it we will get a cake apparently. None of us here are able to solve it since it seems pretty complex so i thought i just put it out here if someone wants to take a chance :)
+2024-02-08 07:18:56	Pelleplutt	In a fictive world. Tell me how one human male and ten human females would repopulate an deserted island in the fastest way. How many years would it take for the population to reach 1 million with unlimited food supply, pre-build shelters and enough space. Take in to calculation that a human female cannot reproduce until 13 years old on average and
+2024-02-08 07:18:57	Pelleplutt	will only have 1.1 child per year, The maternal mortality rate will be 0,3 %. Please show the calculation for the population reaching 1 million. Take also into calculation that 3,4 % of the the island population die before 40 due to accident and diseases.
+2024-02-08 07:36:27	greenbagels	Pelleplutt: interesting problem for a boss to give their employees lol
+2024-02-08 07:37:11	Pelleplutt	greenbagels indeed :) He has been playing around with AI but i do not know why this question came from that
+2024-02-08 07:43:22	isekaijin	Pelleplutt: Is your boss a weeb or what? What the hell is with that plot?
+2024-02-08 07:43:41	greenbagels	isekaijin: lol it is a very male-centric plot
+2024-02-08 07:43:50	greenbagels	Pelleplutt: how old are the original people?
+2024-02-08 07:44:08	Pelleplutt	I think he is about 43 or something
+2024-02-08 07:44:15	greenbagels	no i mean in the problem
+2024-02-08 07:44:55	Pelleplutt	oh, good question. We can assume they are above 13 and below 40
+2024-02-08 08:00:15	Pelleplutt	I guess we have to assume that its 50% males and 50% females that is born aswell
+2024-02-08 08:15:37	PlanckWalk	Looks like something you could just plug into a spreadsheet.
+2024-02-08 08:15:47	PlanckWalk	With lots of simplifying assumptions, of course.
+2024-02-08 08:16:33	PlanckWalk	Proabbly the most annoying relevant one would be reduced fertility with age.
+2024-02-08 08:18:02	PlanckWalk	Inbreeding would be definitely a concern, but make a lot less difference than pretty much any other assumptions.
+2024-02-08 08:19:11	PlanckWalk	But basically the boss will either give you a cake or not, on his whims.  There isn't a true "correct answer" to this.
+2024-02-08 08:19:26	PlanckWalk	(and it's not a math problem anyway)
+2024-02-08 08:25:12	PlanckWalk	(If only 3.4% die before 40 on this isolated island with no pre-existing civilization then it's a fucking miracle)
+2024-02-08 08:25:29	PlanckWalk	(Even with food and shelter)
+2024-02-08 08:29:51	PlanckWalk	Anyway, maybe try asking on worldbuilding.stackexchange.com or something :-p
+2024-02-08 08:30:15	PlanckWalk	Because it sounds like the premise for some crappy harem litrpg.
+2024-02-08 08:33:28	Pelleplutt	PlanckWalk haha yeah i guess :)
+2024-02-08 08:33:40	Pelleplutt	Assumtion is that there is no inbreeding problem aswell :P
+2024-02-08 09:30:44	PlanckWalk	Pelleplutt: Then eh, if you take off every sane limit like that then you could probably do it in just over a century.
+2024-02-08 09:32:12	PlanckWalk	(The stated mortality rates are irrelevant, and shouldn't even have been mentioned)
+2024-02-08 10:03:19	mh_le	morning all
+2024-02-08 10:03:46	mahboubine	mornin' mh_le
+2024-02-08 10:06:00	biberao	hi
+2024-02-08 10:29:29	sigma1	is T := { {}, {{}} } transitive?
+2024-02-08 10:30:09	Inline	vertically not, horizontally maybe
+2024-02-08 10:33:55	mh_le	sigma1: what is the definition of "transitive" in this sense?
+2024-02-08 10:34:25	sigma1	is each element of the set is a subset of the set
+2024-02-08 10:34:28	sigma1	*If
+2024-02-08 10:35:17	mh_le	if would help if you were a bit more precise
+2024-02-08 10:36:25	sigma1	A set H is transitive if every one of its elements is a subset.
+2024-02-08 10:37:21	mh_le	then yes
+2024-02-08 10:40:39	sigma1	and T := { {}, {{}}, {{{}}} } ?
+2024-02-08 10:41:27	lericson	we went through this, sigma1
+2024-02-08 10:41:38	lericson	can you check for yourself?
+2024-02-08 10:47:55	biberao	math time
+2024-02-08 10:48:11	mh_le	which kind?
+2024-02-08 10:50:13	biberao	mh_le: i did some trig and sequences yesterday night
+2024-02-08 10:50:25	mh_le	great
+2024-02-08 10:51:52	machinewhore	Is there a collection of urn problems/solutions somewhere that I can use for practice?
+2024-02-08 10:52:17	mh_le	urn?
+2024-02-08 10:52:36	mh_le	you mean counting/probability problems?
+2024-02-08 10:52:43	machinewhore	yeah
+2024-02-08 10:53:07	machinewhore	eg, 50 red balls and 50 black balls randomly distributed between 2 urns, yada yada
+2024-02-08 10:53:32	mh_le	https://www.google.com/search?q=counting+and+probability+problems&oq=counting+and+probability&gs_lcrp=EgZjaHJvbWUqCAgCEAAYFhgeMgYIABBFGDkyBwgBEAAYgAQyCAgCEAAYFhgeMggIAxAAGBYYHjIICAQQABgWGB4yCAgFEAAYFhgeMggIBhAAGBYYHjIICAcQABgWGB4yCAgIEAAYFhgeMggICRAAGBYYHtIBCDcwNTJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8
+2024-02-08 10:58:45	sigma1	I'm not sure whether these are transitive T: = {∅, {{∅}} and S:= {∅, {{∅}}, {∅}} I get confused with the ∅
+2024-02-08 10:59:49	machinewhore	S is transitive iff each element of S is a subset of S.
+2024-02-08 11:01:00	machinewhore	Is ∅ a subset of T? Is {{∅}} a subset of T?
+2024-02-08 11:01:08	sigma1	it'd be T: = {∅, {{∅}} btw
+2024-02-08 11:01:20	machinewhore	Still missing a bracket.
+2024-02-08 11:01:35	sigma1	T: = {∅, {{∅}}}
+2024-02-08 11:02:01	machinewhore	If you answer those two questions I asked, then you will know if T is transitive or not.
+2024-02-08 11:02:19	biberao	immibis: mh_le going to do it in latex
+2024-02-08 11:02:22	biberao	sorry
+2024-02-08 11:02:26	biberao	i meant mh_le
+2024-02-08 11:02:28	sigma1	since the elements of ∅(i.e. none) are contained in T
+2024-02-08 11:03:07	mh_le	biberao: ah cool
+2024-02-08 11:07:43	machinewhore	sigma1: Figure it out?
+2024-02-08 11:12:46	sigma1	machinewhore the set {{∅}} is a subset of T, because its element is part of T
+2024-02-08 11:13:05	PlanckWalk	Its element is {∅}
+2024-02-08 11:14:31	PlanckWalk	The elements of T are ∅ and {{∅}}
+2024-02-08 11:16:32	machinewhore	Yup, those are the elements of T.
+2024-02-08 11:16:41	biberao	mh_le: i might need help  structuring :D
+2024-02-08 11:23:36	mh_le	biberao: is a solution to an assignment you are typesetting?
+2024-02-08 11:24:42	biberao	yes
+2024-02-08 11:25:19	mh_le	ok, I don't know spanish so I'm not sure I will be able to help
+2024-02-08 11:25:52	biberao	mh_le: its not even spanish
+2024-02-08 11:25:54	biberao	:\
+2024-02-08 11:26:05	biberao	but the issue is structuring i wanted to make it similar
+2024-02-08 11:26:27	mh_le	biberao: I'm not sure what you mean by that
+2024-02-08 11:27:15	biberao	mh_le: i want to be able to have like exercice 1 and so on
+2024-02-08 11:27:18	biberao	good alignment
+2024-02-08 11:27:37	mh_le	biberao: let's go to #latex
+2024-02-08 11:27:55	biberao	ok
+2024-02-08 11:31:52	sigma1	PlanckWalk so T is transitive as ∅ is a subset of T
+2024-02-08 11:33:02	sigma1	and the members of {{ø}} is only {ø}, and {ø} is a subset of A
+2024-02-08 11:35:03	PlanckWalk	That's not the test for transitivity
+2024-02-08 11:35:17	machinewhore	sigma: What are the members of T?
+2024-02-08 11:35:35	sigma1	ø, {{ø}}
+2024-02-08 11:35:48	machinewhore	Correct.
+2024-02-08 11:35:57	machinewhore	Is ø a subset of T?
+2024-02-08 11:36:10	sigma1	yes
+2024-02-08 11:36:13	machinewhore	Correct.
+2024-02-08 11:36:16	machinewhore	Is {{ø}} a subset of T?
+2024-02-08 11:36:42	sigma1	yes
+2024-02-08 11:37:04	machinewhore	What is the definition of "subset'?
+2024-02-08 11:38:12	sigma1	If B is a set whose elements are included in a set A we say that B is included in A or that B subset of A
+2024-02-08 11:38:28	PlanckWalk	Let's not use the word "included".
+2024-02-08 11:38:53	PlanckWalk	Sometimes people use it to mean "element of", sometimes they use it to mean "subset of".
+2024-02-08 11:39:15	PlanckWalk	As you did!
+2024-02-08 11:39:25	machinewhore	!^
+2024-02-08 11:39:38	PlanckWalk	As in, you use it both ways.
+2024-02-08 11:39:41	PlanckWalk	used* it
+2024-02-08 11:40:45	PlanckWalk	So try again without using the word "included".
+2024-02-08 11:41:49	sigma1	'part of a set A' instead of that
+2024-02-08 11:44:04	PlanckWalk	No, let's not.
+2024-02-08 11:44:17	PlanckWalk	Try looking up a definition.
+2024-02-08 11:45:00	PlanckWalk	The one you're using is broken.
+2024-02-08 11:48:05	machinewhore42	sigma1: Are you a native English speaker?
+2024-02-08 11:50:42	sigma1	A is a subset of B, if and only if every element of A is an element of B
+2024-02-08 11:51:00	PlanckWalk	That one looks better
+2024-02-08 11:51:36	PlanckWalk	I severy element of {{ø}} an element of T?
+2024-02-08 11:53:35	sigma1	it seems so
+2024-02-08 11:53:49	PlanckWalk	What are the elements of {{ø}}?
+2024-02-08 11:54:50	sigma1	the set {ø}
+2024-02-08 11:54:58	PlanckWalk	What are the elements of T?
+2024-02-08 11:55:32	sigma1	the set {ø}  and ø
+2024-02-08 11:55:39	 *	PlanckWalk scrolls up.
+2024-02-08 11:55:42	PlanckWalk	Are you sure?
+2024-02-08 11:57:43	sigma1	err the other should be {{ø}}
+2024-02-08 11:58:36	PlanckWalk	Which other?
+2024-02-08 11:59:00	sigma1	{{ø}} and ø
+2024-02-08 11:59:19	PlanckWalk	Okay.  Is {ø} an element of T?
+2024-02-08 11:59:35	sigma1	no
+2024-02-08 12:00:06	PlanckWalk	Right, so now you can answer whether T is transitive.
+2024-02-08 12:00:34	PlanckWalk	You've checked its elements, and found one that's not a subset.
+2024-02-08 12:01:33	mh_le	Let B - i -> B' - p -> B'' be an exact sequence of left R-modules, and let A be a right R-module and consider the maps id_A (X) i and id_A (X) p then (id_A (X) p) \circ (id_A (X) i) = id_A (X) 0, but why is this the zero map?
+2024-02-08 12:01:47	mh_le	R is a ring
+2024-02-08 12:06:00	mh_le	here 0 must be the map b \mapsto i(b)\mapto p(i(b))=0 for all b in B, but the Id_A is not zero
+2024-02-08 12:06:13	mh_le	the map*
+2024-02-08 12:07:52	mh_le	wait
+2024-02-08 12:11:47	sigma1	is U\T transitive?
+2024-02-08 12:12:43	mh_le	r( a (X) b) = (ar (x) b) = (a (x) rb). so ( a (x) 0) = 0
+2024-02-08 12:13:03	mh_le	that's not right
+2024-02-08 12:20:22	--	Mode ##math [+o int-e] by ChanServ
+2024-02-08 12:20:25	--	Mode ##math [+b-o *!*@2a02:810b:4b40:2998:* int-e] by int-e
+2024-02-08 12:28:39	mh_le	so it was pretty obvious that a (x) 0 = 0
+2024-02-08 13:56:52	sigma1	the text asks me whether U \ T is transitive
+2024-02-08 13:58:57	int-e	Cool. What are U and T?
+2024-02-08 14:21:39	biberao	Z-module: ?
+2024-02-08 14:22:29	brass_	Can the sine function be achieved using finite combination of the basic operations?
+2024-02-08 14:24:34	dTal	No, sine is transcendental
+2024-02-08 14:25:40	dTal	Why do you ask?
+2024-02-08 15:33:56	paulo	https://www.wolframalpha.com/input?i=y%5E2%3D%28x%28x-9%29%28x%2B16%29%29%2C+y+%3D+3
+2024-02-08 15:34:27	paulo	why are solutions shown as complex when the line clearly intersects the graph in real space?
+2024-02-08 16:12:14	brass_	dTal Can I message you privately, I can't respond here.
+2024-02-08 16:12:50	dTal	You can't?
+2024-02-08 16:12:54	dTal	Erm, I guess...
+2024-02-08 16:13:24	brass_	?Yup ok, it's just that what I might say may sound too dumb on an elementary level.
+2024-02-08 16:27:14	ecraven	hello ;) I'm looking for a function that does the following: I know N (the number of items) and i (the index of the current pick). I'd like to go from i=0..N-1, and get back a "random" ordering (so not 0, 1, 2, ... but 5, 7, 23, 1, ...) where each number from 0 to N-1 occurs exactly once for i=0..N-1.
+2024-02-08 16:27:34	ecraven	I've tried i*K mod N with K being a coprime to N, but that .. doesn't seem to be correct.
+2024-02-08 16:30:27	Z-module	paulo: putting y = 3 in that and working with the resulting equation  x^3 + 7x^2 - 144x - 9,  I get (if I haven't made an error) the discriminant to be 13133457, which (being positive) means there are three distinct real roots. *Somehow* the particular numbers are fouling up the floating-point solvers. Notice how very minuscule all those imaginary parts are.
+2024-02-08 16:32:08	mh_le	hey all
+2024-02-08 16:34:55	ecraven	and it works fine, I just implemented it wrong ;)
+2024-02-08 17:05:51	biberao	Z-module: tell me what you think https://github.com/gitmapd/gitmapd.github.io/blob/master/limites%20nova%20ficha.pdf <- finished exercise 2 and 3
+2024-02-08 17:14:49	Z-module	Looks good, biberao
+2024-02-08 17:16:41	biberao	Z-module: ive added another thing to prove bounded for 3-2n
+2024-02-08 17:16:49	biberao	if you do f5 should have updated
+2024-02-08 17:19:43	Z-module	I think you mean 3 - 2/n
+2024-02-08 17:19:50	biberao	no
+2024-02-08 17:19:50	Z-module	(here in irc)
+2024-02-08 17:19:52	biberao	3-2n
+2024-02-08 17:19:58	Z-module	the sequence  3 - 2n   is not bounded
+2024-02-08 17:20:09	biberao	thats what i said
+2024-02-08 17:20:14	biberao	i meant to say
+2024-02-08 17:20:20	biberao	how do i prove its not bounded
+2024-02-08 17:20:39	biberao	i did lim n (3-2n) = -inf
+2024-02-08 17:20:48	biberao	thats what i meant to say
+2024-02-08 17:20:53	biberao	mawk: thanks :D
+2024-02-08 17:22:22	Z-module	Take any real r (of any sign).  Then  3 - 2n < r   iff   (3 - r)/2 < n     , so for all n > (3 - r)/2, that holds.  This is the meaning of  lim (3 - 2n) = -infty
+2024-02-08 17:23:46	biberao	ah
+2024-02-08 17:23:56	biberao	maybe i should use the delta epsilon?
+2024-02-08 17:27:48	Z-module	That's what this is, but in the form used for sequences
+2024-02-08 17:28:50	Z-module	A sequence {b_n} goes to +infty if:  Forall r   exists M   forall n > M    b_n > r         Change that last > to < and you get the form for -> -infty
+2024-02-08 17:31:04	mh_le	hi Z-module
+2024-02-08 17:33:27	Z-module	This reminds me of a very neat thing. Let g_n mean (the (n+1)st prime) - (the nth prime), the nth prime gap. It turns out we don't need really heavy analytic number theory for the following: merely the pretty basic (easier-to-prove than you might think) Chebyshev bounds suffice, and I think only one side of it is even enough:  Infinitely many n exist with  g_n < g_(n+1) > g_(n+2),  also infinitely many with  g_n > g_(n+1) < g_(n+2).
+2024-02-08 17:52:49	biberao	back
+2024-02-08 17:52:51	biberao	sorry
+2024-02-08 17:53:27	biberao	Z-module: thank you
+2024-02-08 17:56:29	theseb	Can someone tell me how they got the "observed power" on this A/B test calculator? https://abtestguide.com/calc/
+2024-02-08 17:57:02	theseb	"two proportions hypothesis testing"
+2024-02-08 18:05:45	biberao	Z-module: so for example if an = 3-2n was a monotonic increasing i could do  an > M
+2024-02-08 18:05:59	biberao	ok
+2024-02-08 18:06:01	biberao	i guess that works
+2024-02-08 18:06:03	biberao	thank you
+2024-02-08 18:06:47	Z-module	by the way, a sequence can -> +infty without being monotonic or eventually monotonic. For example: 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6 ...
+2024-02-08 18:07:09	biberao	i see
+2024-02-08 18:07:20	biberao	for this case is this right to say 1 < 3-2n < -inf
+2024-02-08 18:07:22	biberao	?
+2024-02-08 18:07:32	biberao	i dont know if its a good notation
+2024-02-08 18:07:42	Z-module	However, that prime gaps sequence {g_n}, while unbounded, does not -> infty, as we've only known with proof for around a decade.
+2024-02-08 18:08:05	Z-module	nothing is < -infty
+2024-02-08 18:08:13	Z-module	so don't write that
+2024-02-08 18:08:14	biberao	ok
+2024-02-08 18:08:20	biberao	but you understood what i meant
+2024-02-08 18:08:25	biberao	ok
+2024-02-08 18:08:28	Z-module	I didn't, nor would anyone else
+2024-02-08 18:08:29	biberao	i meant to say
+2024-02-08 18:08:32	biberao	sorry
+2024-02-08 18:08:34	biberao	i meant to say
+2024-02-08 18:08:44	biberao	-inf < 3-2n < 1
+2024-02-08 18:09:14	greenbagels	<= 1
+2024-02-08 18:09:21	Z-module	okay but  -infty < any reals you like,  so there's no point writing that. Finitely many innequalities have nothing to do with -> -infty
+2024-02-08 18:09:34	biberao	greenbagels: thank you
+2024-02-08 18:09:51	biberao	like now i understood what you taught me today
+2024-02-08 18:18:11	biberao	check my updated
+2024-02-08 18:18:17	biberao	Exercise 2 d)
+2024-02-08 18:18:19	biberao	please
+2024-02-08 18:26:08	Z-module	I don't think you need to check or mention that 1 > every a_n at all. Simply the fact that eventually all a_n are < any pre-selected number is enough to get that the sequence is not bounded. Also you shouldn't write  lim a_n = -infty    at the top like that: only write it after showing it to be true.
+2024-02-08 18:27:06	biberao	what if for example
+2024-02-08 18:27:17	Z-module	the  1 > all a_n   would be relevant if you were dealing with "unbounded only on one side" as a separate / special case of "unbounded".
+2024-02-08 18:27:21	Z-module	but you're not
+2024-02-08 18:27:40	biberao	ah so with a_n >M or a_n < M
+2024-02-08 18:27:42	biberao	works for both sides?
+2024-02-08 18:37:35	Z-module	{b_n} is "bounded" iff some positive r exists with |b_n| < r  (same as:  -r < b_n < r )   for all n.  Equivalent to saying some reals r < s exist with  r < b_n < s  for all n.      The negation of this, {b_n} unbounded, is:  EITHER:   for every r, for infinitely many n,  r < b_n   (that's unbounded above),  OR:   for every r, for infinitely many n,  r > b_n   (unbounded below).  Or both.
+2024-02-08 18:39:07	Z-module	But unbounded above is weaker than {b_n} -> +infty ; unbounded below is weaker than {b_n} -> -infty.  The sequence 0, 1, 0, 2, 0, 3, 0, 4, ...  is unbounded above, but does not -> +infty.
+2024-02-08 18:44:05	biberao	Z-module: so thats the way we did earlier then
+2024-02-08 18:44:20	biberao	b_n < M or b_n > M
+2024-02-08 18:47:45	biberao	ok gtg
+2024-02-08 18:47:47	biberao	thank you
+2024-02-08 18:48:27	greenbagels	another happy customer
+2024-02-08 19:11:13	mh_le	hi
+2024-02-08 19:11:27	mh_le	hey greenbagels
+2024-02-08 19:11:37	greenbagels	hi
+2024-02-08 19:12:17	mh_le	any progres on Wald?
+2024-02-08 19:12:37	greenbagels	realistically i dont know if i have the time for it tbh
+2024-02-08 19:12:55	mh_le	ok no problem :)
+2024-02-08 19:39:08	Simplar	I'm having issues with elementary problem. I want to find out how to prove that even divided by odd is always even if the divisor divides dividend. I know that even number has 2 among the multiples, while odd number never does, so the two won't go anywhere.
+2024-02-08 19:39:15	Simplar	But how to prove the same with subtractions?
+2024-02-08 19:57:50	Z-module	Simplar:  2m - (2n + 1) = 2(m - n) - 1 = 2(m - n - 1) + 1   and this last is odd.
+2024-02-08 20:09:22	Simplar	Z-module: I meant (2m) / (2n+1)
+2024-02-08 20:09:39	Simplar	How can we guarantee that the quotient will always be even?
+2024-02-08 20:10:06	Simplar	2m = (2n+1)q + r
+2024-02-08 20:13:59	Guest5398	Hello, sorry, If you have 7 Characters and every 1 day Chance of Birth is 1%, how can i create a function that will Tell me the amount of Characters after n days?
+2024-02-08 20:24:46	Z-module	Simplar: The question presupposes that the numerator n = 2m is an integer multiple of the denominator d where d is odd. So 2m = kd  for some k. So  2m/d = k,  and k can't be odd because then d, also being odd, would mean  kd  is also odd, not true since kd = 2m.
+2024-02-08 20:25:06	Z-module	also, note taht "difference" referes to the - operator, not the / operator
+2024-02-08 20:28:06	Z-module	Simplar: another way to put that.  2m = kd  and prime factoriation is unique (up to order), so 2 appears somewhere in the prime factorization of kd.  But it's not in d, so it must be in k. So  2m/d = k  is even.
+2024-02-08 20:33:50	Guest5398	Its Like having seven dollars and getting 1% interest? Having 7 Characters having a Baby at 1% Chance . That should be IT.
+2024-02-08 20:35:17	pavonia	Guest5398: What is the relation between characters and birth here?
+2024-02-08 20:36:21	pavonia	Or is it like characters in a game?
+2024-02-08 20:36:40	Guest5398	I mean Characters can increase by 1 at a 1% Chance per one Character per day
+2024-02-08 20:36:46	Guest5398	Yes. Sorry.
+2024-02-08 20:42:24	mahboubine	basic question: I've calculated the derivative of some function f, then I was asked to calculate f'(x) at some point c. I did this and the result was an undetermined form (5/0) where do I move from there?
+2024-02-08 20:42:49	mahboubine	I am used to facing undetermined forms in limits but I don't know how to deal with them in this case
+2024-02-08 20:43:36	pavonia	Guest5398: I guess it's a matter of definition if the chance after N days is 0.01*N or (1.01)^N
+2024-02-08 20:43:43	pavonia	...
+2024-02-08 20:46:19	serveee	why is topology so hard to understand
+2024-02-08 20:46:26	serveee	set topology that is
+2024-02-08 20:46:37	mh_le	is it?
+2024-02-08 20:46:49	serveee	maybe im just not understanding it right
+2024-02-08 20:47:02	Galois	it's a lot easier if you know real analysis well
+2024-02-08 20:47:26	serveee	how so
+2024-02-08 20:47:47	Galois	in real analysis you (are supposed to) learn about open and closed sets arising from metric spaces
+2024-02-08 20:47:52	mh_le	serveee: topology is the study of continuity
+2024-02-08 20:48:12	serveee	i should go back some steps then
+2024-02-08 20:48:23	Galois	metric spaces are already an abstraction of Euclidean space, and one which is useful in many ways, but abstracting to open and closed sets is a perfectly natural next step, and that gives you topology
+2024-02-08 20:48:32	serveee	frustrating but this isnt something im not familiar with
+2024-02-08 20:48:45	mh_le	serveee: you are welcome to ask if there is something specific that's not clear to you
+2024-02-08 21:17:11	Z-module	mahboubine: what's your f, and your c ?  f might not actually be differentiable at c
+2024-02-08 21:20:53	mh_le	Z-module: pm?
+2024-02-08 21:33:28	mahboubine	Z-module: oh forgot about this, as you said f turned out not differentiable at c
+2024-02-08 21:33:35	mahboubine	I was overthinking the whole thing
+2024-02-08 22:27:54	adder	I'm trying to do IDWDS on a three table game, but I'm not sure how. Can someone help? |  | Ann | Bob | Carla |
+2024-02-08 22:27:54	adder	| ---- | ---- | ---- | ---- |
+2024-02-08 22:27:54	adder	| Ann | (2, 0, 1) | (2, 0, 1) | (2, 0, 1) |
+2024-02-08 22:27:54	adder	| Bob | (2, 0, 1) | (0, 1, 2) | (0, 1, 2) |
+2024-02-08 22:27:54	adder	| Carla | (2, 0, 1) | (1, 2, 0) | (1, 2, 0) |
+2024-02-08 22:27:55	adder	 
+2024-02-08 22:27:55	adder	Carla votes Ann
+2024-02-08 22:27:56	adder	 
+2024-02-08 22:27:56	adder	|  | Ann | Bob | Carla |
+2024-02-08 22:27:57	adder	| ---- | ---- | ---- | ---- |
+2024-02-08 22:27:57	adder	| Ann | (2, 0, 1) | (0, 1, 2) | (2, 0, 1) |
+2024-02-08 22:27:58	adder	| Bob | (0, 1, 2) | (0, 1, 2) | (0, 1, 2) |
+2024-02-08 22:28:20	adder	Sorry.
+2024-02-08 22:28:28	b0nn	adder: FTR a paste site would have been more appropriate than posting into the channel
+2024-02-08 22:29:00	adder	I know, I just mispasted the screenshot url. I meant to paste: https://imgur.com/AM8lJ0J.png
+2024-02-08 22:29:36	adder	So what I don't get is how a three-table game reduced to a single table.
+2024-02-08 22:29:48	adder	That is, I'm not following what the text says.
+2024-02-08 22:35:18	int-e	Hmm. the label on the 2nd (or is that 4th) figure should be "Anna votes for A".
+2024-02-08 22:36:03	adder	Ah, that makes sense.
+2024-02-08 22:36:25	int-e	adder: But that seems to be the only thing wrong with it... what are you having trouble with?
+2024-02-08 22:39:10	adder	Nothing, it checks out now.
+2024-02-08 22:39:13	adder	Thanks, int-e.
+2024-02-08 22:39:20	int-e	Cool, np.

+ 53 - 10
bin/darkwallet/gui/__init__.py

@@ -309,15 +309,17 @@ def draw():
     # w
     #api.set_property_u32(layer_id, "rect", 2, int(3838/2))
     code = [["as_u32", ["/", ["load", "sw"], ["u32", 2]]]]
+    code = [["as_u32", ["load", "sw"]]]
     api.set_property_expr(layer_id, "rect", 2, code)
     # h
     code = [["as_u32", ["/", ["load", "sh"], ["u32", 2]]]]
+    code = [["as_u32", ["load", "sh"]]]
     api.set_property_expr(layer_id, "rect", 3, code)
 
     api.link_node(layer_id, win_id)
 
-    # Add a mesh to our layer
-    node_id = api.add_node("meshie", SceneNodeType.RENDER_MESH)
+    # Add a bg box to our layer
+    node_id = api.add_node("bg", SceneNodeType.RENDER_MESH)
 
     prop = Property(
         "data", PropertyType.BUFFER, PropertySubType.NULL,
@@ -331,10 +333,10 @@ def draw():
     #w, h = 0.1, 0.1
     x, y, w, h = 0, 0, 1, 1
     #x, y, w, h = -1, 1, 2, -2
-    vert1 = vertex(x,     y,     0, 0, 0, 1, 0, 0)
-    vert2 = vertex(x + w, y,     0, 0, 0, 1, 1, 0)
-    vert3 = vertex(x,     y + h, 0, 0, 0, 1, 0, 1)
-    vert4 = vertex(x + w, y + h, 0, 0, 0, 1, 1, 1)
+    vert1 = vertex(x,     y,     0, 0.1, 0, 1, 0, 0)
+    vert2 = vertex(x + w, y,     0.1, 0, 0, 1, 1, 0)
+    vert3 = vertex(x,     y + h, 0.1, 0, 0, 1, 0, 1)
+    vert4 = vertex(x + w, y + h, 0.1, 0, 0, 1, 1, 1)
 
     verts = vert1 + vert2 + vert3 + vert4
     faces = face(0, 2, 1) + face(1, 2, 3)
@@ -350,16 +352,16 @@ def draw():
     )
     api.add_property(node_id, prop)
     # x
-    api.set_property_f32(node_id, "rect", 0, 10)
+    api.set_property_f32(node_id, "rect", 0, 0)
     # y
-    api.set_property_f32(node_id, "rect", 1, 10)
+    api.set_property_f32(node_id, "rect", 1, 0)
     # w
     #api.set_property_f32(node_id, "rect", 2, 20)
-    code = [["-", ["load", "lw"], ["f32", 10]]]
+    code = [["-", ["load", "lw"], ["f32", 0]]]
     api.set_property_expr(node_id, "rect", 2, code)
     # h
     #api.set_property_str(node_id, "rect", 3, "lh - 10")
-    code = [["-", ["load", "lh"], ["f32", 10]]]
+    code = [["-", ["load", "lh"], ["f32", 0]]]
     api.set_property_expr(node_id, "rect", 3, code)
 
     prop = Property(
@@ -641,6 +643,47 @@ def draw():
 
     api.link_node(node_id, layer_id)
 
+    # ChatView
+
+    node_id = api.add_node("chatty", SceneNodeType.CHAT_VIEW)
+
+    prop = Property(
+        "rect", PropertyType.FLOAT32, PropertySubType.PIXEL,
+        None,
+        "Rectangle", "The position and size within the layer",
+        False, True, 4, None, None, []
+    )
+    api.add_property(node_id, prop)
+    api.set_property_f32(node_id, "rect", 0, 50)
+    api.set_property_f32(node_id, "rect", 1, 260)
+    code = [["-", ["load", "lw"], ["f32", 100]]]
+    api.set_property_expr(node_id, "rect", 2, code)
+    code = [["-", ["load", "lh"], ["f32", 260]]]
+    api.set_property_expr(node_id, "rect", 3, code)
+
+    prop = Property(
+        "debug", PropertyType.BOOL, PropertySubType.NULL,
+        None,
+        "Debug", "Draw debug outlines",
+        False, False, 1, None, None, []
+    )
+    api.add_property(node_id, prop)
+    api.set_property_bool(node_id, "debug", 0, True)
+
+    prop = Property(
+        "z_index", PropertyType.UINT32, PropertySubType.NULL,
+        None,
+        "Z-index", "Z-index: values greater than zero are deferred draws",
+        False, False, 1, None, None, []
+    )
+    api.add_property(node_id, prop)
+
+    arg_data = bytearray()
+    serial.write_u32(arg_data, node_id)
+    api.call_method(win_id, "create_chat_view", arg_data)
+
+    api.link_node(node_id, layer_id)
+
 def main():
     draw()
 

+ 2 - 0
bin/darkwallet/gui/print_tree.py

@@ -39,6 +39,8 @@ def print_node_info(parent_id, indent):
                 child_type = "fonts"
             case SceneNodeType.FONT:
                 child_type = "font"
+            case SceneNodeType.CHAT_VIEW:
+                child_type = "chat_view"
             case SceneNodeType.EDIT_BOX:
                 child_type = "edit_box"
 

+ 2 - 1
bin/darkwallet/pydrk/api.py

@@ -58,7 +58,8 @@ class SceneNodeType:
     FONT = 11
     PLUGINS = 14
     PLUGIN = 15
-    EDIT_BOX = 16
+    CHAT_VIEW = 16
+    EDIT_BOX = 17
 
 class PropertyType:
     NULL = 0

+ 184 - 0
bin/darkwallet/src/chatview.rs

@@ -0,0 +1,184 @@
+use atomic_float::AtomicF32;
+use miniquad::{KeyMods, UniformType, MouseButton, window};
+use std::{
+    collections::HashMap,
+    path::Path,
+    fs::File,
+    io::{BufRead, BufReader, Cursor}, sync::{Arc, atomic::{AtomicBool, Ordering}, Mutex}, time::{Instant, Duration}};
+use darkfi_serial::Decodable;
+
+use crate::{error::{Error, Result}, prop::{
+    PropertyBool, PropertyFloat32, PropertyUint32, PropertyStr, PropertyColor,
+    Property}, scene::{SceneGraph, SceneNode, SceneNodeId, Pimpl, Slot}, gfx::{Rectangle, RenderContext, COLOR_WHITE, COLOR_BLUE, COLOR_RED, COLOR_GREEN, FreetypeFace, COLOR_DARKGREY, Point}, text::{Glyph, TextShaper}, keysym::{MouseButtonAsU8, KeyCodeAsU16}};
+
+fn read_lines<P>(filename: P) -> Vec<String>
+where P: AsRef<Path>, {
+    let file = File::open(filename).unwrap();
+    BufReader::new(file).lines().map(|l| l.unwrap()).collect()
+}
+
+pub type ChatViewPtr = Arc<ChatView>;
+
+pub struct ChatView {
+    node_name: String,
+    debug: PropertyBool,
+    // Used for mouse interaction
+    world_rect: Mutex<Rectangle<f32>>,
+    mouse_pos: Mutex<Point<f32>>,
+    text_shaper: TextShaper,
+    scroll: AtomicF32,
+    lines: Vec<String>,
+    glyph_lines: Mutex<Vec<Vec<Glyph>>>,
+}
+
+impl ChatView {
+    pub fn new(scene_graph: &mut SceneGraph, node_id: SceneNodeId, font_faces: Vec<FreetypeFace>) -> Result<Pimpl> {
+        let node = scene_graph.get_node(node_id).unwrap();
+        let node_name = node.name.clone();
+        let debug = PropertyBool::wrap(node, "debug", 0)?;
+
+        let text_shaper = TextShaper {
+            font_faces
+        };
+        
+        let lines = read_lines("chat.txt");
+        let mut glyph_lines = vec![];
+        glyph_lines.resize(lines.len(), vec![]);
+
+        let self_ = Arc::new(Self{
+            node_name: node_name.clone(),
+            debug,
+            world_rect: Mutex::new(Rectangle { x: 0., y: 0., w: 0., h: 0. }),
+            mouse_pos: Mutex::new(Point { x: 0., y: 0. }),
+            text_shaper,
+            scroll: AtomicF32::new(0.),
+            lines,
+            glyph_lines: Mutex::new(glyph_lines),
+        });
+
+        let weak_self = Arc::downgrade(&self_);
+        let slot_move = Slot {
+            name: format!("{}::mouse_move", node_name),
+            func: Box::new(move |data| {
+                let mut cur = Cursor::new(&data);
+                let x = f32::decode(&mut cur).unwrap();
+                let y = f32::decode(&mut cur).unwrap();
+
+                let self_ = weak_self.upgrade();
+                if let Some(self_) = self_ {
+                    let pos = &mut *self_.mouse_pos.lock().unwrap();
+                    pos.x = x;
+                    pos.y = y;
+                }
+            }),
+        };
+
+        let weak_self = Arc::downgrade(&self_);
+        let slot_wheel = Slot {
+            name: format!("{}::mouse_wheel", node_name),
+            func: Box::new(move |data| {
+                let mut cur = Cursor::new(&data);
+                let x = f32::decode(&mut cur).unwrap();
+                let y = f32::decode(&mut cur).unwrap();
+
+                let self_ = weak_self.upgrade();
+                if let Some(self_) = self_ {
+                    self_.mouse_scroll(x, y);
+                }
+            }),
+        };
+
+        let mouse_node = 
+            scene_graph
+            .lookup_node_mut("/window/input/mouse")
+            .expect("no mouse attached!");
+        mouse_node.register("wheel", slot_wheel);
+        mouse_node.register("move", slot_move);
+
+        // Save any properties we use
+        Ok(Pimpl::ChatView(self_))
+    }
+
+    pub fn render<'a>(&self, render: &mut RenderContext<'a>, node_id: SceneNodeId, layer_rect: &Rectangle<f32>) -> Result<()> {
+        let debug = self.debug.get();
+
+        let node = render.scene_graph.get_node(node_id).unwrap();
+        let rect = RenderContext::get_dim(node, layer_rect)?;
+
+        // Used for detecting mouse clicks
+        let mut world_rect = rect.clone();
+        world_rect.x += layer_rect.x as f32;
+        world_rect.y += layer_rect.y as f32;
+        *self.world_rect.lock().unwrap() = world_rect;
+
+        let layer_w = layer_rect.w as f32;
+        let layer_h = layer_rect.h as f32;
+        let off_x = rect.x / layer_w;
+        let off_y = rect.y / layer_h;
+        // Use absolute pixel scale
+        let scale_x = 1. / layer_w;
+        let scale_y = 1. / layer_h;
+        let model = glam::Mat4::from_translation(glam::Vec3::new(off_x, off_y, 0.)) *
+            glam::Mat4::from_scale(glam::Vec3::new(scale_x, scale_y, 1.));
+
+        let mut uniforms_data = [0u8; 128];
+        let data: [u8; 64] = unsafe { std::mem::transmute_copy(&render.proj) };
+        uniforms_data[0..64].copy_from_slice(&data);
+        let data: [u8; 64] = unsafe { std::mem::transmute_copy(&model) };
+        uniforms_data[64..].copy_from_slice(&data);
+        assert_eq!(128, 2 * UniformType::Mat4.size());
+
+        render.ctx.apply_uniforms_from_bytes(uniforms_data.as_ptr(), uniforms_data.len());
+
+        let bound = Rectangle {
+            x: 0.,
+            y: 0.,
+            w: rect.w,
+            h: rect.h,
+        };
+
+        let glyph_lines = &mut self.glyph_lines.lock().unwrap();
+
+        let scroll = self.scroll.load(Ordering::Relaxed);
+        for (i, (line, glyph_line)) in self.lines.iter().zip(glyph_lines.iter_mut()).enumerate() {
+            //println!("line: {}", line);
+            if glyph_line.is_empty() {
+                *glyph_line = self.text_shaper.shape(line.clone(), 30., COLOR_WHITE);
+            }
+            let off_y = 50. * i as f32 + scroll;
+            if off_y + 50. < 0. || off_y - 50. > rect.h {
+                continue;
+            }
+            for glyph in glyph_line {
+                let x1 = glyph.pos.x;
+                let y1 = glyph.pos.y + off_y;
+                let x2 = x1 + glyph.pos.w;
+                let y2 = y1 + glyph.pos.h;
+
+                let texture = render.ctx.new_texture_from_rgba8(glyph.bmp_width, glyph.bmp_height, &glyph.bmp);
+                render.render_clipped_box_with_texture(&bound, x1, y1, x2, y2, COLOR_WHITE, texture);
+                render.ctx.delete_texture(texture);
+            }
+        }
+
+        if debug {
+            render.outline(0., 0., rect.w, rect.h, COLOR_RED, 1.);
+        }
+
+        Ok(())
+    }
+
+    fn mouse_scroll(self: Arc<Self>, _x: f32, y: f32) {
+        let mouse_pos = &*self.mouse_pos.lock().unwrap();
+        if !self.world_rect.lock().unwrap().contains(mouse_pos) {
+            return;
+        }
+        drop(mouse_pos);
+
+        self.scroll.fetch_add(y * 10., Ordering::Relaxed);
+        // y =  1 for scroll up
+        // y = -1 for scroll down
+        //println!("{}", y);
+    }
+}
+

+ 24 - 19
bin/darkwallet/src/editbox.rs

@@ -1,5 +1,5 @@
 use miniquad::{KeyMods, UniformType, MouseButton, window};
-use log::info;
+use log::{debug, info};
 use std::{
     collections::HashMap,
     io::Cursor, sync::{Arc, atomic::{AtomicBool, Ordering}, Mutex}, time::{Instant, Duration}};
@@ -78,6 +78,7 @@ impl RepeatingKeyTimer {
 pub type EditBoxPtr = Arc<EditBox>;
 
 pub struct EditBox {
+    node_name: String,
     is_active: PropertyBool,
     debug: PropertyBool,
     baseline: PropertyFloat32,
@@ -117,8 +118,8 @@ impl EditBox {
             font_faces
         };
 
-        println!("EditBox::new()");
         let self_ = Arc::new(Self{
+            node_name: node_name.clone(),
             is_active,
             debug,
             baseline,
@@ -291,21 +292,21 @@ impl EditBox {
             self.render_selected(render, &rect, glyphs)?;
         }
 
+        let bound = Rectangle {
+            x: 0.,
+            y: 0.,
+            w: rect.w,
+            h: rect.h,
+        };
+
         let mut rhs = 0.;
         for (glyph_idx, glyph) in glyphs.iter().enumerate() {
-            let texture = render.ctx.new_texture_from_rgba8(glyph.bmp_width, glyph.bmp_height, &glyph.bmp);
-
             let x1 = glyph.pos.x + scroll;
             let y1 = glyph.pos.y + baseline;
             let x2 = x1 + glyph.pos.w;
             let y2 = y1 + glyph.pos.h;
 
-            let bound = Rectangle {
-                x: 0.,
-                y: 0.,
-                w: rect.w,
-                h: rect.h,
-            };
+            let texture = render.ctx.new_texture_from_rgba8(glyph.bmp_width, glyph.bmp_height, &glyph.bmp);
             render.render_clipped_box_with_texture(&bound, x1, y1, x2, y2, COLOR_WHITE, texture);
             //render.render_box_with_texture(x1, y1, x2, y2, COLOR_WHITE, texture);
             render.ctx.delete_texture(texture);
@@ -406,6 +407,8 @@ impl EditBox {
             }
             text.push_str(&substr);
         }
+        debug!("EditBox(\"{}\")::delete_highlighted() text=\"{}\", cursor_pos={}",
+               self.node_name, text, sel_start);
         self.text.set(text);
 
         self.selected.set_null(0).unwrap();
@@ -468,12 +471,6 @@ impl EditBox {
 
     fn do_key_down(&self, key: &str, mods: &KeyMods) {
         match key {
-            "PageUp" => {
-                println!("pageup!");
-            }
-            "PageDown" => {
-                println!("pagedown!");
-            }
             "Left" => {
                 let mut cursor_pos = self.cursor_pos.get();
 
@@ -488,6 +485,8 @@ impl EditBox {
 
                 if cursor_pos > 0 {
                     cursor_pos -= 1;
+                    debug!("EditBox(\"{}\")::key_down(Left) cursor_pos={}",
+                           self.node_name, cursor_pos);
                     self.cursor_pos.set(cursor_pos);
                 }
 
@@ -511,6 +510,8 @@ impl EditBox {
                 let glyphs_len = self.glyphs.lock().unwrap().len() as u32;
                 if cursor_pos < glyphs_len {
                     cursor_pos += 1;
+                    debug!("EditBox(\"{}\")::key_down(Right) cursor_pos={}",
+                           self.node_name, cursor_pos);
                     self.cursor_pos.set(cursor_pos);
                 }
 
@@ -568,11 +569,9 @@ impl EditBox {
                         text.push_str(&substr);
                     }
                     self.text.set(text);
+                    self.cursor_pos.set(cursor_pos - 1);
                 };
-                self.cursor_pos.set(cursor_pos - 1);
                 self.regen_glyphs().unwrap();
-
-                // TODO: delete highlighted text
             }
             "C" => {
                 if mods.ctrl {
@@ -597,6 +596,7 @@ impl EditBox {
     }
 
     fn insert_char(&self, key: &str, mods: &KeyMods) {
+        // First filter for only single digit keys
         let allowed_keys =
         ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
          " ", ":", ";", "'", "-", ".", "/", "=", "(", "\\", ")", "`",
@@ -604,6 +604,11 @@ impl EditBox {
         if !allowed_keys.contains(&key) {
             return
         }
+
+        // If we want to only allow specific chars in a String here
+        //let ch = key.chars().next().unwrap();
+        // if !self.allowed_chars.chars().any(|c| c == ch) { return }
+
         let key = if mods.shift {
             key.to_string()
         } else {

+ 45 - 1
bin/darkwallet/src/gfx.rs

@@ -16,6 +16,7 @@ use std::{
 
 use crate::{
     error::{Error, Result},
+    chatview,
     editbox,
     expr::{SExprMachine, SExprVal},
     keysym::{KeyCodeAsStr, MouseButtonAsU8},
@@ -124,6 +125,7 @@ pub type FreetypeFace = ft::Face<&'static [u8]>;
 enum GraphicsMethodEvent {
     LoadTexture,
     DeleteTexture,
+    CreateChatView,
     CreateEditBox,
 }
 
@@ -256,6 +258,19 @@ impl Stage {
             )
             .unwrap();
 
+        let sender = self.method_sender.clone();
+        let method_fn = Box::new(move |arg_data, response_fn| {
+            sender.send((GraphicsMethodEvent::CreateChatView, window_id, arg_data, response_fn));
+        });
+        window
+            .add_method(
+                "create_chat_view",
+                vec![("node_id", "", PropertyType::SceneNodeId)],
+                vec![],
+                method_fn,
+            )
+            .unwrap();
+
         let sender = self.method_sender.clone();
         let method_fn = Box::new(move |arg_data, response_fn| {
             sender.send((GraphicsMethodEvent::CreateEditBox, window_id, arg_data, response_fn));
@@ -393,6 +408,24 @@ impl Stage {
         Ok(vec![])
     }
 
+    fn method_create_chatview(
+        &mut self,
+        _: SceneNodeId,
+        arg_data: Vec<u8>,
+    ) -> Result<Vec<u8>> {
+        let mut cur = Cursor::new(&arg_data);
+        let node_id = SceneNodeId::decode(&mut cur).unwrap();
+
+        let mut scene_graph = self.scene_graph.lock().unwrap();
+        let editbox = chatview::ChatView::new(&mut scene_graph, node_id, self.font_faces.clone())?;
+
+        let node = scene_graph.get_node_mut(node_id).ok_or(Error::NodeNotFound)?;
+        node.pimpl = editbox;
+
+        let mut reply = vec![];
+        Ok(reply)
+    }
+
     fn method_create_editbox(
         &mut self,
         _: SceneNodeId,
@@ -497,7 +530,7 @@ impl<'a> RenderContext<'a> {
         };
 
         let layer_children =
-            layer.get_children(&[SceneNodeType::RenderMesh, SceneNodeType::RenderText, SceneNodeType::EditBox]);
+            layer.get_children(&[SceneNodeType::RenderMesh, SceneNodeType::RenderText, SceneNodeType::EditBox, SceneNodeType::ChatView]);
         let layer_children = self.order_by_z_index(layer_children);
 
         // get the rectangle
@@ -524,6 +557,16 @@ impl<'a> RenderContext<'a> {
                         error!("error rendering text '{}': {}", child.name, err);
                     }
                 }
+                SceneNodeType::ChatView => {
+                    let node = self.scene_graph.get_node(child.id).unwrap();
+                    let chatview = match &node.pimpl {
+                        Pimpl::ChatView(e) => e.clone(),
+                        _ => panic!("wrong pimpl for editbox")
+                    };
+                    if let Err(err) = chatview.render(self, child.id, &rect) {
+                        error!("error rendering chatview '{}': {}", child.name, err);
+                    }
+                }
                 SceneNodeType::EditBox => {
                     let node = self.scene_graph.get_node(child.id).unwrap();
                     let editbox = match &node.pimpl {
@@ -1011,6 +1054,7 @@ impl EventHandler for Stage {
             let res = match event {
                 GraphicsMethodEvent::LoadTexture => self.method_load_texture(node_id, arg_data),
                 GraphicsMethodEvent::DeleteTexture => self.method_delete_texture(node_id, arg_data),
+                GraphicsMethodEvent::CreateChatView => self.method_create_chatview(node_id, arg_data),
                 GraphicsMethodEvent::CreateEditBox => self.method_create_editbox(node_id, arg_data),
             };
             response_fn(res);

+ 2 - 0
bin/darkwallet/src/main.rs

@@ -5,6 +5,8 @@ use std::{
     thread,
 };
 
+mod chatview;
+
 mod editbox;
 
 mod error;

+ 4 - 1
bin/darkwallet/src/scene.rs

@@ -11,6 +11,7 @@ use std::{
 
 use crate::{
     error::{Error, Result},
+    chatview,
     editbox,
     prop::{Property, PropertyType},
 };
@@ -35,7 +36,8 @@ pub enum SceneNodeType {
     Font = 11,
     Plugins = 14,
     Plugin = 15,
-    EditBox = 16,
+    ChatView = 16,
+    EditBox = 17,
 }
 
 pub struct ScenePath(Vec<String>);
@@ -630,5 +632,6 @@ pub struct Method {
 pub enum Pimpl {
     Null,
     EditBox(editbox::EditBoxPtr),
+    ChatView(chatview::ChatViewPtr),
 }
 

+ 7 - 1
bin/darkwallet/src/text.rs

@@ -2,6 +2,7 @@ use freetype as ft;
 
 use crate::gfx::{Rectangle, FreetypeFace};
 
+#[derive(Clone)]
 pub struct Glyph {
     // Substring this glyph corresponds to
     pub substr: String,
@@ -27,6 +28,11 @@ impl TextShaper {
         let mut current_str = String::new();
         let mut substrs = vec![];
         'next_char: for chr in text.chars() {
+            // Replace tabs with spaces
+            let chr = if chr == '\t' {
+                ' '
+            } else { chr };
+
             let idx = 'get_idx: {
                 for i in 0..self.font_faces.len() {
                     let ft_face = &self.font_faces[i];
@@ -35,7 +41,7 @@ impl TextShaper {
                     }
                 }
 
-                warn!("no font fallback for char: {}", chr);
+                warn!("no font fallback for char: '{}'", chr);
                 // Skip this char
                 continue 'next_char
             };